UNPKG

4.28 kBJavaScriptView Raw
1'use strict'
2
3const resolve = require('path').resolve
4
5const config = require('lilconfig')
6const yaml = require('yaml')
7
8const loadOptions = require('./options.js')
9const loadPlugins = require('./plugins.js')
10
11/* istanbul ignore next */
12const interopRequireDefault = (obj) => obj && obj.__esModule ? obj : { default: obj }
13
14/**
15 * Process the result from cosmiconfig
16 *
17 * @param {Object} ctx Config Context
18 * @param {Object} result Cosmiconfig result
19 *
20 * @return {Object} PostCSS Config
21 */
22const processResult = (ctx, result) => {
23 const file = result.filepath || ''
24 let config = interopRequireDefault(result.config).default || {}
25
26 if (typeof config === 'function') {
27 config = config(ctx)
28 } else {
29 config = Object.assign({}, config, ctx)
30 }
31
32 if (!config.plugins) {
33 config.plugins = []
34 }
35
36 return {
37 plugins: loadPlugins(config, file),
38 options: loadOptions(config, file),
39 file: file
40 }
41}
42
43/**
44 * Builds the Config Context
45 *
46 * @param {Object} ctx Config Context
47 *
48 * @return {Object} Config Context
49 */
50const createContext = (ctx) => {
51 /**
52 * @type {Object}
53 *
54 * @prop {String} cwd=process.cwd() Config search start location
55 * @prop {String} env=process.env.NODE_ENV Config Enviroment, will be set to `development` by `postcss-load-config` if `process.env.NODE_ENV` is `undefined`
56 */
57 ctx = Object.assign({
58 cwd: process.cwd(),
59 env: process.env.NODE_ENV
60 }, ctx)
61
62 if (!ctx.env) {
63 process.env.NODE_ENV = 'development'
64 }
65
66 return ctx
67}
68
69const addTypeScriptLoader = (options = {}, loader) => {
70 const moduleName = 'postcss'
71
72 return {
73 ...options,
74 searchPlaces: [
75 ...(options.searchPlaces || []),
76 'package.json',
77 `.${moduleName}rc`,
78 `.${moduleName}rc.json`,
79 `.${moduleName}rc.yaml`,
80 `.${moduleName}rc.yml`,
81 `.${moduleName}rc.ts`,
82 `.${moduleName}rc.js`,
83 `.${moduleName}rc.cjs`,
84 `${moduleName}.config.ts`,
85 `${moduleName}.config.js`,
86 `${moduleName}.config.cjs`
87 ],
88 loaders: {
89 ...options.loaders,
90 '.yaml': (filepath, content) => yaml.parse(content),
91 '.yml': (filepath, content) => yaml.parse(content),
92 '.ts': loader
93 }
94 }
95}
96
97const withTypeScriptLoader = (rcFunc) => {
98 return (ctx, path, options) => {
99 return rcFunc(ctx, path, addTypeScriptLoader(options, (configFile) => {
100 let registerer = { enabled () {} }
101
102 try {
103 // Register TypeScript compiler instance
104 registerer = require('ts-node').register()
105
106 return require(configFile)
107 } catch (err) {
108 if (err.code === 'MODULE_NOT_FOUND') {
109 throw new Error(
110 `'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${err.message}`
111 )
112 }
113
114 throw err
115 } finally {
116 registerer.enabled(false)
117 }
118 }))
119 }
120}
121
122/**
123 * Load Config
124 *
125 * @method rc
126 *
127 * @param {Object} ctx Config Context
128 * @param {String} path Config Path
129 * @param {Object} options Config Options
130 *
131 * @return {Promise} config PostCSS Config
132 */
133const rc = withTypeScriptLoader((ctx, path, options) => {
134 /**
135 * @type {Object} The full Config Context
136 */
137 ctx = createContext(ctx)
138
139 /**
140 * @type {String} `process.cwd()`
141 */
142 path = path ? resolve(path) : process.cwd()
143
144 return config.lilconfig('postcss', options)
145 .search(path)
146 .then((result) => {
147 if (!result) {
148 throw new Error(`No PostCSS Config found in: ${path}`)
149 }
150
151 return processResult(ctx, result)
152 })
153})
154
155rc.sync = withTypeScriptLoader((ctx, path, options) => {
156 /**
157 * @type {Object} The full Config Context
158 */
159 ctx = createContext(ctx)
160
161 /**
162 * @type {String} `process.cwd()`
163 */
164 path = path ? resolve(path) : process.cwd()
165
166 const result = config.lilconfigSync('postcss', options).search(path)
167
168 if (!result) {
169 throw new Error(`No PostCSS Config found in: ${path}`)
170 }
171
172 return processResult(ctx, result)
173})
174
175/**
176 * Autoload Config for PostCSS
177 *
178 * @author Michael Ciniawsky @michael-ciniawsky <michael.ciniawsky@gmail.com>
179 * @license MIT
180 *
181 * @module postcss-load-config
182 * @version 2.1.0
183 *
184 * @requires comsiconfig
185 * @requires ./options
186 * @requires ./plugins
187 */
188module.exports = rc