postcss-load-config
Advanced tools
Comparing version 4.0.2 to 5.0.0
{ | ||
"name": "postcss-load-config", | ||
"version": "4.0.2", | ||
"version": "5.0.0", | ||
"description": "Autoload Config for PostCSS", | ||
@@ -11,3 +11,3 @@ "main": "src/index.js", | ||
"engines": { | ||
"node": ">= 14" | ||
"node": ">= 18" | ||
}, | ||
@@ -29,7 +29,7 @@ "funding": [ | ||
"peerDependencies": { | ||
"postcss": ">=8.0.9", | ||
"ts-node": ">=9.0.0" | ||
"jiti": ">=1.21.0", | ||
"postcss": ">=8.0.9" | ||
}, | ||
"peerDependenciesMeta": { | ||
"ts-node": { | ||
"jiti": { | ||
"optional": true | ||
@@ -36,0 +36,0 @@ }, |
@@ -89,3 +89,3 @@ | ||
You may need some logic within your config. | ||
In this case create JS file named: | ||
In this case create JS/TS file named: | ||
- `.postcssrc.js` | ||
@@ -95,2 +95,3 @@ - `.postcssrc.mjs` | ||
- `.postcssrc.ts` | ||
- `.postcssrc.mts` | ||
- `.postcssrc.cts` | ||
@@ -101,2 +102,3 @@ - `postcss.config.js` | ||
- `postcss.config.ts` | ||
- `postcss.config.mts` | ||
- `postcss.config.cts` | ||
@@ -108,3 +110,3 @@ | ||
|– public | ||
|- (.postcssrc|postcss.config).(js|mjs|cjs|ts|cts) | ||
|- (.postcssrc|postcss.config).(js|mjs|cjs|ts|mts|cts) | ||
|- package.json | ||
@@ -111,0 +113,0 @@ ``` |
// based on @types/postcss-load-config@2.0.1 | ||
// Type definitions for postcss-load-config 2.1 | ||
import Processor from 'postcss/lib/processor'; | ||
import { Plugin, ProcessOptions, Transformer } from 'postcss'; | ||
import { Options as ConfigOptions } from "lilconfig"; | ||
import Processor from 'postcss/lib/processor' | ||
import { Plugin, ProcessOptions, Transformer } from 'postcss' | ||
import { Options as ConfigOptions } from 'lilconfig' | ||
@@ -11,3 +11,3 @@ declare function postcssrc( | ||
options?: ConfigOptions | ||
): Promise<postcssrc.Result>; | ||
): Promise<postcssrc.Result> | ||
@@ -19,5 +19,5 @@ declare namespace postcssrc { | ||
export interface ProcessOptionsPreload { | ||
parser?: string | ProcessOptions['parser']; | ||
stringifier?: string | ProcessOptions['stringifier']; | ||
syntax?: string | ProcessOptions['syntax']; | ||
parser?: string | ProcessOptions['parser'] | ||
stringifier?: string | ProcessOptions['stringifier'] | ||
syntax?: string | ProcessOptions['syntax'] | ||
} | ||
@@ -29,8 +29,8 @@ | ||
Exclude<keyof ProcessOptions, keyof ProcessOptionsPreload> | ||
>; | ||
> | ||
// Additional context options that postcss-load-config understands. | ||
export interface Context { | ||
cwd?: string; | ||
env?: string; | ||
cwd?: string | ||
env?: string | ||
} | ||
@@ -41,29 +41,29 @@ | ||
ProcessOptionsPreload & | ||
RemainingProcessOptions; | ||
RemainingProcessOptions | ||
// Result of postcssrc is a Promise containing the filename plus the options | ||
// and plugins that are ready to pass on to postcss. | ||
export type ResultPlugin = Plugin | Transformer | Processor; | ||
export type ResultPlugin = Plugin | Transformer | Processor | ||
export interface Result { | ||
file: string; | ||
options: ProcessOptions; | ||
plugins: ResultPlugin[]; | ||
file: string | ||
options: ProcessOptions | ||
plugins: ResultPlugin[] | ||
} | ||
export type ConfigPlugin = Transformer | Plugin | Processor; | ||
export type ConfigPlugin = Transformer | Plugin | Processor | ||
export interface Config { | ||
parser?: string | ProcessOptions['parser'] | false; | ||
stringifier?: string | ProcessOptions['stringifier'] | false; | ||
syntax?: string | ProcessOptions['syntax'] | false; | ||
map?: string | false; | ||
from?: string; | ||
to?: string; | ||
plugins?: Array<ConfigPlugin | false> | Record<string, object | false>; | ||
parser?: string | ProcessOptions['parser'] | false | ||
stringifier?: string | ProcessOptions['stringifier'] | false | ||
syntax?: string | ProcessOptions['syntax'] | false | ||
map?: string | false | ||
from?: string | ||
to?: string | ||
plugins?: Array<ConfigPlugin | false> | Record<string, object | false> | ||
} | ||
export type ConfigFn = (ctx: ConfigContext) => Config | Promise<Config>; | ||
export type ConfigFn = (ctx: ConfigContext) => Config | Promise<Config> | ||
} | ||
export = postcssrc; | ||
export = postcssrc |
125
src/index.js
@@ -1,6 +0,4 @@ | ||
'use strict' | ||
// @ts-check | ||
const { resolve } = require('node:path') | ||
const resolve = require('path').resolve | ||
const url = require('url') | ||
const config = require('lilconfig') | ||
@@ -11,5 +9,6 @@ const yaml = require('yaml') | ||
const loadPlugins = require('./plugins.js') | ||
const req = require('./req.js') | ||
/* istanbul ignore next */ | ||
const interopRequireDefault = (obj) => obj && obj.__esModule ? obj : { default: obj } | ||
const interopRequireDefault = obj => | ||
obj && obj.__esModule ? obj : { default: obj } | ||
@@ -22,23 +21,25 @@ /** | ||
* | ||
* @return {Object} PostCSS Config | ||
* @return {Promise<Object>} PostCSS Config | ||
*/ | ||
const processResult = (ctx, result) => { | ||
const file = result.filepath || '' | ||
let config = interopRequireDefault(result.config).default || {} | ||
async function processResult(ctx, result) { | ||
let file = result.filepath || '' | ||
let projectConfig = interopRequireDefault(result.config).default || {} | ||
if (typeof config === 'function') { | ||
config = config(ctx) | ||
if (typeof projectConfig === 'function') { | ||
projectConfig = projectConfig(ctx) | ||
} else { | ||
config = Object.assign({}, config, ctx) | ||
projectConfig = Object.assign({}, projectConfig, ctx) | ||
} | ||
if (!config.plugins) { | ||
config.plugins = [] | ||
if (!projectConfig.plugins) { | ||
projectConfig.plugins = [] | ||
} | ||
return { | ||
plugins: loadPlugins(config, file), | ||
options: loadOptions(config, file), | ||
file | ||
let res = { | ||
file, | ||
options: await loadOptions(projectConfig, file), | ||
plugins: await loadPlugins(projectConfig, file) | ||
} | ||
delete projectConfig.plugins | ||
return res | ||
} | ||
@@ -53,3 +54,3 @@ | ||
*/ | ||
const createContext = (ctx) => { | ||
function createContext(ctx) { | ||
/** | ||
@@ -61,6 +62,9 @@ * @type {Object} | ||
*/ | ||
ctx = Object.assign({ | ||
cwd: process.cwd(), | ||
env: process.env.NODE_ENV | ||
}, ctx) | ||
ctx = Object.assign( | ||
{ | ||
cwd: process.cwd(), | ||
env: process.env.NODE_ENV | ||
}, | ||
ctx | ||
) | ||
@@ -74,12 +78,23 @@ if (!ctx.env) { | ||
const importDefault = async filepath => { | ||
const module = await import(url.pathToFileURL(filepath).href) | ||
return module.default | ||
async function loader(filepath) { | ||
return req(filepath) | ||
} | ||
const addTypeScriptLoader = (options = {}, loader) => { | ||
const moduleName = 'postcss' | ||
/** @return {import('lilconfig').Options} */ | ||
const withLoaders = (options = {}) => { | ||
let moduleName = 'postcss' | ||
return { | ||
...options, | ||
loaders: { | ||
...options.loaders, | ||
'.cjs': loader, | ||
'.cts': loader, | ||
'.js': loader, | ||
'.mjs': loader, | ||
'.mts': loader, | ||
'.ts': loader, | ||
'.yaml': (_, content) => yaml.parse(content), | ||
'.yml': (_, content) => yaml.parse(content) | ||
}, | ||
searchPlaces: [ | ||
@@ -94,2 +109,3 @@ ...(options.searchPlaces || []), | ||
`.${moduleName}rc.cts`, | ||
`.${moduleName}rc.mts`, | ||
`.${moduleName}rc.js`, | ||
@@ -100,47 +116,10 @@ `.${moduleName}rc.cjs`, | ||
`${moduleName}.config.cts`, | ||
`${moduleName}.config.mts`, | ||
`${moduleName}.config.js`, | ||
`${moduleName}.config.cjs`, | ||
`${moduleName}.config.mjs` | ||
], | ||
loaders: { | ||
...options.loaders, | ||
'.yaml': (filepath, content) => yaml.parse(content), | ||
'.yml': (filepath, content) => yaml.parse(content), | ||
'.js': importDefault, | ||
'.cjs': importDefault, | ||
'.mjs': importDefault, | ||
'.ts': loader, | ||
'.cts': loader | ||
} | ||
] | ||
} | ||
} | ||
const withTypeScriptLoader = (rcFunc) => { | ||
return (ctx, path, options) => { | ||
return rcFunc(ctx, path, addTypeScriptLoader(options, (configFile) => { | ||
let registerer = { enabled () {} } | ||
try { | ||
// Register TypeScript compiler instance | ||
registerer = require('ts-node').register({ | ||
// transpile to cjs even if compilerOptions.module in tsconfig is not Node16/NodeNext. | ||
moduleTypes: { '**/*.cts': 'cjs' } | ||
}) | ||
return require(configFile) | ||
} catch (err) { | ||
if (err.code === 'MODULE_NOT_FOUND') { | ||
throw new Error( | ||
`'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${err.message}` | ||
) | ||
} | ||
throw err | ||
} finally { | ||
registerer.enabled(false) | ||
} | ||
})) | ||
} | ||
} | ||
/** | ||
@@ -157,3 +136,3 @@ * Load Config | ||
*/ | ||
const rc = withTypeScriptLoader((ctx, path, options) => { | ||
function rc(ctx, path, options) { | ||
/** | ||
@@ -169,12 +148,12 @@ * @type {Object} The full Config Context | ||
return config.lilconfig('postcss', options) | ||
return config | ||
.lilconfig('postcss', withLoaders(options)) | ||
.search(path) | ||
.then((result) => { | ||
.then(result => { | ||
if (!result) { | ||
throw new Error(`No PostCSS Config found in: ${path}`) | ||
} | ||
return processResult(ctx, result) | ||
}) | ||
}) | ||
} | ||
@@ -181,0 +160,0 @@ /** |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
// @ts-check | ||
const req = require('./req.js') | ||
@@ -13,10 +12,12 @@ | ||
* | ||
* @return {Object} options PostCSS Options | ||
* @return {Promise<Object>} options PostCSS Options | ||
*/ | ||
const options = (config, file) => { | ||
async function options(config, file) { | ||
if (config.parser && typeof config.parser === 'string') { | ||
try { | ||
config.parser = req(config.parser, file) | ||
config.parser = await req(config.parser, file) | ||
} catch (err) { | ||
throw new Error(`Loading PostCSS Parser failed: ${err.message}\n\n(@${file})`) | ||
throw new Error( | ||
`Loading PostCSS Parser failed: ${err.message}\n\n(@${file})` | ||
) | ||
} | ||
@@ -27,5 +28,7 @@ } | ||
try { | ||
config.syntax = req(config.syntax, file) | ||
config.syntax = await req(config.syntax, file) | ||
} catch (err) { | ||
throw new Error(`Loading PostCSS Syntax failed: ${err.message}\n\n(@${file})`) | ||
throw new Error( | ||
`Loading PostCSS Syntax failed: ${err.message}\n\n(@${file})` | ||
) | ||
} | ||
@@ -36,12 +39,10 @@ } | ||
try { | ||
config.stringifier = req(config.stringifier, file) | ||
config.stringifier = await req(config.stringifier, file) | ||
} catch (err) { | ||
throw new Error(`Loading PostCSS Stringifier failed: ${err.message}\n\n(@${file})`) | ||
throw new Error( | ||
`Loading PostCSS Stringifier failed: ${err.message}\n\n(@${file})` | ||
) | ||
} | ||
} | ||
if (config.plugins) { | ||
delete config.plugins | ||
} | ||
return config | ||
@@ -48,0 +49,0 @@ } |
@@ -1,3 +0,2 @@ | ||
'use strict' | ||
// @ts-check | ||
const req = require('./req.js') | ||
@@ -14,5 +13,5 @@ | ||
* | ||
* @return {Function} PostCSS Plugin | ||
* @return {Promise<Function>} PostCSS Plugin | ||
*/ | ||
const load = (plugin, options, file) => { | ||
async function load(plugin, options, file) { | ||
try { | ||
@@ -24,8 +23,11 @@ if ( | ||
) { | ||
return req(plugin, file) | ||
return await req(plugin, file) | ||
} else { | ||
return req(plugin, file)(options) | ||
return (await req(plugin, file))(options) | ||
/* c8 ignore next */ | ||
} | ||
} catch (err) { | ||
throw new Error(`Loading PostCSS Plugin failed: ${err.message}\n\n(@${file})`) | ||
throw new Error( | ||
`Loading PostCSS Plugin failed: ${err.message}\n\n(@${file})` | ||
) | ||
} | ||
@@ -42,21 +44,22 @@ } | ||
* | ||
* @return {Array} plugins PostCSS Plugins | ||
* @return {Promise<Array>} plugins PostCSS Plugins | ||
*/ | ||
const plugins = (config, file) => { | ||
let plugins = [] | ||
async function plugins(config, file) { | ||
let list = [] | ||
if (Array.isArray(config.plugins)) { | ||
plugins = config.plugins.filter(Boolean) | ||
list = config.plugins.filter(Boolean) | ||
} else { | ||
plugins = Object.keys(config.plugins) | ||
.filter((plugin) => { | ||
return config.plugins[plugin] !== false ? plugin : '' | ||
list = Object.entries(config.plugins) | ||
.filter(([, options]) => { | ||
return options !== false | ||
}) | ||
.map((plugin) => { | ||
return load(plugin, config.plugins[plugin], file) | ||
.map(([plugin, options]) => { | ||
return load(plugin, options, file) | ||
}) | ||
list = await Promise.all(list) | ||
} | ||
if (plugins.length && plugins.length > 0) { | ||
plugins.forEach((plugin, i) => { | ||
if (list.length && list.length > 0) { | ||
list.forEach((plugin, i) => { | ||
if (plugin.default) { | ||
@@ -77,6 +80,8 @@ plugin = plugin.default | ||
(typeof plugin === 'object' && plugin.postcssPlugin) || | ||
(typeof plugin === 'function') | ||
typeof plugin === 'function' | ||
) | ||
) { | ||
throw new TypeError(`Invalid PostCSS Plugin found at: plugins[${i}]\n\n(@${file})`) | ||
throw new TypeError( | ||
`Invalid PostCSS Plugin found at: plugins[${i}]\n\n(@${file})` | ||
) | ||
} | ||
@@ -86,5 +91,5 @@ }) | ||
return plugins | ||
return list | ||
} | ||
module.exports = plugins |
@@ -1,10 +0,39 @@ | ||
// eslint-disable-next-line n/no-deprecated-api | ||
const { createRequire, createRequireFromPath } = require('module') | ||
// @ts-check | ||
const { createRequire } = require('node:module') | ||
function req (name, rootFile) { | ||
const create = createRequire || createRequireFromPath | ||
const require = create(rootFile) | ||
return require(name) | ||
const TS_EXT_RE = /\.(c|m)?ts$/ | ||
/** @type {import('jiti').default | null} */ | ||
let jiti = null | ||
/** | ||
* @param {string} name | ||
* @param {string} rootFile | ||
* @returns {Promise<any>} | ||
*/ | ||
async function req(name, rootFile = __filename) { | ||
let __require = createRequire(rootFile) | ||
let url = __require.resolve(name) | ||
try { | ||
return (await import(url)).default | ||
} catch (err) { | ||
if (!TS_EXT_RE.test(url)) { | ||
/* c8 ignore start */ | ||
throw err | ||
} | ||
if (!jiti) { | ||
try { | ||
jiti = (await import('jiti')).default | ||
} catch (jitiErr) { | ||
throw new Error( | ||
`'jiti' is required for the TypeScript configuration files. Make sure it is installed\nError: ${jitiErr.message}` | ||
) | ||
} | ||
/* c8 ignore stop */ | ||
} | ||
return jiti(rootFile, { interopDefault: true })(name) | ||
} | ||
} | ||
module.exports = req |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
21665
360
469
3