summaryrefslogtreecommitdiff
path: root/node_modules/lilconfig
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2024-08-30 17:21:18 +0800
committerlittleblack111 <littleblack11111@gmail.com>2024-08-30 17:21:18 +0800
commitefbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch)
tree2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/lilconfig
parent43acceb75957c880a5ba5a31aae221394a36d5f6 (diff)
node fixes, updates
Diffstat (limited to 'node_modules/lilconfig')
-rw-r--r--node_modules/lilconfig/package.json10
-rw-r--r--node_modules/lilconfig/src/index.d.ts54
-rw-r--r--node_modules/lilconfig/src/index.js457
3 files changed, 515 insertions, 6 deletions
diff --git a/node_modules/lilconfig/package.json b/node_modules/lilconfig/package.json
index a40f62c8..d6e23888 100644
--- a/node_modules/lilconfig/package.json
+++ b/node_modules/lilconfig/package.json
@@ -1,12 +1,12 @@
{
"name": "lilconfig",
- "version": "3.1.1",
+ "version": "3.1.2",
"description": "A zero-dependency alternative to cosmiconfig",
"main": "src/index.js",
"types": "src/index.d.ts",
"scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules ./node_modules/.bin/jest --coverage",
- "lint": "eslint ./src",
+ "lint": "biome ci ./src",
"types": "tsc"
},
"keywords": [
@@ -26,14 +26,12 @@
"author": "antonk52",
"license": "MIT",
"devDependencies": {
+ "@biomejs/biome": "^1.6.0",
"@types/jest": "^29.5.12",
"@types/node": "^14.18.63",
+ "@types/webpack-env": "^1.18.5",
"cosmiconfig": "^8.3.6",
- "eslint": "^8.56.0",
- "eslint-config-prettier": "^9.1.0",
- "eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
- "prettier": "^3.2.5",
"typescript": "^5.3.3",
"uvu": "^0.5.6"
},
diff --git a/node_modules/lilconfig/src/index.d.ts b/node_modules/lilconfig/src/index.d.ts
new file mode 100644
index 00000000..fa1146b8
--- /dev/null
+++ b/node_modules/lilconfig/src/index.d.ts
@@ -0,0 +1,54 @@
+export type LilconfigResult = null | {
+ filepath: string;
+ config: any;
+ isEmpty?: boolean;
+};
+interface OptionsBase {
+ cache?: boolean;
+ stopDir?: string;
+ searchPlaces?: string[];
+ ignoreEmptySearchPlaces?: boolean;
+ packageProp?: string | string[];
+}
+export type Transform =
+ | TransformSync
+ | ((result: LilconfigResult) => Promise<LilconfigResult>);
+export type TransformSync = (result: LilconfigResult) => LilconfigResult;
+type LoaderResult = any;
+export type LoaderSync = (filepath: string, content: string) => LoaderResult;
+export type Loader =
+ | LoaderSync
+ | ((filepath: string, content: string) => Promise<LoaderResult>);
+export type Loaders = Record<string, Loader>;
+export type LoadersSync = Record<string, LoaderSync>;
+export interface Options extends OptionsBase {
+ loaders?: Loaders;
+ transform?: Transform;
+}
+export interface OptionsSync extends OptionsBase {
+ loaders?: LoadersSync;
+ transform?: TransformSync;
+}
+export declare const defaultLoadersSync: LoadersSync;
+export declare const defaultLoaders: Loaders;
+type ClearCaches = {
+ clearLoadCache: () => void;
+ clearSearchCache: () => void;
+ clearCaches: () => void;
+};
+type AsyncSearcher = {
+ search(searchFrom?: string): Promise<LilconfigResult>;
+ load(filepath: string): Promise<LilconfigResult>;
+} & ClearCaches;
+export declare function lilconfig(
+ name: string,
+ options?: Partial<Options>,
+): AsyncSearcher;
+type SyncSearcher = {
+ search(searchFrom?: string): LilconfigResult;
+ load(filepath: string): LilconfigResult;
+} & ClearCaches;
+export declare function lilconfigSync(
+ name: string,
+ options?: OptionsSync,
+): SyncSearcher;
diff --git a/node_modules/lilconfig/src/index.js b/node_modules/lilconfig/src/index.js
new file mode 100644
index 00000000..c4d055b1
--- /dev/null
+++ b/node_modules/lilconfig/src/index.js
@@ -0,0 +1,457 @@
+// @ts-check
+const path = require('path');
+const fs = require('fs');
+const os = require('os');
+
+const fsReadFileAsync = fs.promises.readFile;
+
+/** @type {(name: string, sync: boolean) => string[]} */
+function getDefaultSearchPlaces(name, sync) {
+ return [
+ 'package.json',
+ `.${name}rc.json`,
+ `.${name}rc.js`,
+ `.${name}rc.cjs`,
+ ...(sync ? [] : [`.${name}rc.mjs`]),
+ `.config/${name}rc`,
+ `.config/${name}rc.json`,
+ `.config/${name}rc.js`,
+ `.config/${name}rc.cjs`,
+ ...(sync ? [] : [`.config/${name}rc.mjs`]),
+ `${name}.config.js`,
+ `${name}.config.cjs`,
+ ...(sync ? [] : [`${name}.config.mjs`]),
+ ];
+}
+
+/**
+ * @type {(p: string) => string}
+ *
+ * see #17
+ * On *nix, if cwd is not under homedir,
+ * the last path will be '', ('/build' -> '')
+ * but it should be '/' actually.
+ * And on Windows, this will never happen. ('C:\build' -> 'C:')
+ */
+function parentDir(p) {
+ return path.dirname(p) || path.sep;
+}
+
+/** @type {import('./index').LoaderSync} */
+const jsonLoader = (_, content) => JSON.parse(content);
+// Use plain require in webpack context for dynamic import
+const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
+/** @type {import('./index').LoadersSync} */
+const defaultLoadersSync = Object.freeze({
+ '.js': requireFunc,
+ '.json': requireFunc,
+ '.cjs': requireFunc,
+ noExt: jsonLoader,
+});
+module.exports.defaultLoadersSync = defaultLoadersSync;
+
+/** @type {import('./index').Loader} */
+const dynamicImport = async id => {
+ try {
+ const mod = await import(/* webpackIgnore: true */ id);
+
+ return mod.default;
+ } catch (e) {
+ try {
+ return requireFunc(id);
+ } catch (/** @type {any} */ requireE) {
+ if (
+ requireE.code === 'ERR_REQUIRE_ESM' ||
+ (requireE instanceof SyntaxError &&
+ requireE
+ .toString()
+ .includes('Cannot use import statement outside a module'))
+ ) {
+ throw e;
+ }
+ throw requireE;
+ }
+ }
+};
+
+/** @type {import('./index').Loaders} */
+const defaultLoaders = Object.freeze({
+ '.js': dynamicImport,
+ '.mjs': dynamicImport,
+ '.cjs': dynamicImport,
+ '.json': jsonLoader,
+ noExt: jsonLoader,
+});
+module.exports.defaultLoaders = defaultLoaders;
+
+/**
+ * @param {string} name
+ * @param {import('./index').Options | import('./index').OptionsSync} options
+ * @param {boolean} sync
+ * @returns {Required<import('./index').Options | import('./index').OptionsSync>}
+ */
+function getOptions(name, options, sync) {
+ /** @type {Required<import('./index').Options>} */
+ const conf = {
+ stopDir: os.homedir(),
+ searchPlaces: getDefaultSearchPlaces(name, sync),
+ ignoreEmptySearchPlaces: true,
+ cache: true,
+ transform: x => x,
+ packageProp: [name],
+ ...options,
+ loaders: {
+ ...(sync ? defaultLoadersSync : defaultLoaders),
+ ...options.loaders,
+ },
+ };
+ conf.searchPlaces.forEach(place => {
+ const key = path.extname(place) || 'noExt';
+ const loader = conf.loaders[key];
+ if (!loader) {
+ throw new Error(`Missing loader for extension "${place}"`);
+ }
+
+ if (typeof loader !== 'function') {
+ throw new Error(
+ `Loader for extension "${place}" is not a function: Received ${typeof loader}.`,
+ );
+ }
+ });
+
+ return conf;
+}
+
+/** @type {(props: string | string[], obj: Record<string, any>) => unknown} */
+function getPackageProp(props, obj) {
+ if (typeof props === 'string' && props in obj) return obj[props];
+ return (
+ (Array.isArray(props) ? props : props.split('.')).reduce(
+ (acc, prop) => (acc === undefined ? acc : acc[prop]),
+ obj,
+ ) || null
+ );
+}
+
+/** @param {string} filepath */
+function validateFilePath(filepath) {
+ if (!filepath) throw new Error('load must pass a non-empty string');
+}
+
+/** @type {(loader: import('./index').Loader, ext: string) => void} */
+function validateLoader(loader, ext) {
+ if (!loader) throw new Error(`No loader specified for extension "${ext}"`);
+ if (typeof loader !== 'function') throw new Error('loader is not a function');
+}
+
+/** @type {(enableCache: boolean) => <T>(c: Map<string, T>, filepath: string, res: T) => T} */
+const makeEmplace = enableCache => (c, filepath, res) => {
+ if (enableCache) c.set(filepath, res);
+ return res;
+};
+
+/** @type {import('./index').lilconfig} */
+module.exports.lilconfig = function lilconfig(name, options) {
+ const {
+ ignoreEmptySearchPlaces,
+ loaders,
+ packageProp,
+ searchPlaces,
+ stopDir,
+ transform,
+ cache,
+ } = getOptions(name, options ?? {}, false);
+ const searchCache = new Map();
+ const loadCache = new Map();
+ const emplace = makeEmplace(cache);
+
+ return {
+ async search(searchFrom = process.cwd()) {
+ /** @type {import('./index').LilconfigResult} */
+ const result = {
+ config: null,
+ filepath: '',
+ };
+
+ /** @type {Set<string>} */
+ const visited = new Set();
+ let dir = searchFrom;
+ dirLoop: while (true) {
+ if (cache) {
+ const r = searchCache.get(dir);
+ if (r !== undefined) {
+ for (const p of visited) searchCache.set(p, r);
+ return r;
+ }
+ visited.add(dir);
+ }
+
+ for (const searchPlace of searchPlaces) {
+ const filepath = path.join(dir, searchPlace);
+ try {
+ await fs.promises.access(filepath);
+ } catch {
+ continue;
+ }
+ const content = String(await fsReadFileAsync(filepath));
+ const loaderKey = path.extname(searchPlace) || 'noExt';
+ const loader = loaders[loaderKey];
+
+ // handle package.json
+ if (searchPlace === 'package.json') {
+ const pkg = await loader(filepath, content);
+ const maybeConfig = getPackageProp(packageProp, pkg);
+ if (maybeConfig != null) {
+ result.config = maybeConfig;
+ result.filepath = filepath;
+ break dirLoop;
+ }
+
+ continue;
+ }
+
+ // handle other type of configs
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces) continue;
+
+ if (isEmpty) {
+ result.isEmpty = true;
+ result.config = undefined;
+ } else {
+ validateLoader(loader, loaderKey);
+ result.config = await loader(filepath, content);
+ }
+ result.filepath = filepath;
+ break dirLoop;
+ }
+ if (dir === stopDir || dir === parentDir(dir)) break dirLoop;
+ dir = parentDir(dir);
+ }
+
+ const transformed =
+ // not found
+ result.filepath === '' && result.config === null
+ ? transform(null)
+ : transform(result);
+
+ if (cache) {
+ for (const p of visited) searchCache.set(p, transformed);
+ }
+
+ return transformed;
+ },
+ async load(filepath) {
+ validateFilePath(filepath);
+ const absPath = path.resolve(process.cwd(), filepath);
+ if (cache && loadCache.has(absPath)) {
+ return loadCache.get(absPath);
+ }
+ const {base, ext} = path.parse(absPath);
+ const loaderKey = ext || 'noExt';
+ const loader = loaders[loaderKey];
+ validateLoader(loader, loaderKey);
+ const content = String(await fsReadFileAsync(absPath));
+
+ if (base === 'package.json') {
+ const pkg = await loader(absPath, content);
+ return emplace(
+ loadCache,
+ absPath,
+ transform({
+ config: getPackageProp(packageProp, pkg),
+ filepath: absPath,
+ }),
+ );
+ }
+ /** @type {import('./index').LilconfigResult} */
+ const result = {
+ config: null,
+ filepath: absPath,
+ };
+ // handle other type of configs
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces)
+ return emplace(
+ loadCache,
+ absPath,
+ transform({
+ config: undefined,
+ filepath: absPath,
+ isEmpty: true,
+ }),
+ );
+
+ // cosmiconfig returns undefined for empty files
+ result.config = isEmpty ? undefined : await loader(absPath, content);
+
+ return emplace(
+ loadCache,
+ absPath,
+ transform(isEmpty ? {...result, isEmpty, config: undefined} : result),
+ );
+ },
+ clearLoadCache() {
+ if (cache) loadCache.clear();
+ },
+ clearSearchCache() {
+ if (cache) searchCache.clear();
+ },
+ clearCaches() {
+ if (cache) {
+ loadCache.clear();
+ searchCache.clear();
+ }
+ },
+ };
+};
+
+/** @type {import('./index').lilconfigSync} */
+module.exports.lilconfigSync = function lilconfigSync(name, options) {
+ const {
+ ignoreEmptySearchPlaces,
+ loaders,
+ packageProp,
+ searchPlaces,
+ stopDir,
+ transform,
+ cache,
+ } = getOptions(name, options ?? {}, true);
+ const searchCache = new Map();
+ const loadCache = new Map();
+ const emplace = makeEmplace(cache);
+
+ return {
+ search(searchFrom = process.cwd()) {
+ /** @type {import('./index').LilconfigResult} */
+ const result = {
+ config: null,
+ filepath: '',
+ };
+
+ /** @type {Set<string>} */
+ const visited = new Set();
+ let dir = searchFrom;
+ dirLoop: while (true) {
+ if (cache) {
+ const r = searchCache.get(dir);
+ if (r !== undefined) {
+ for (const p of visited) searchCache.set(p, r);
+ return r;
+ }
+ visited.add(dir);
+ }
+
+ for (const searchPlace of searchPlaces) {
+ const filepath = path.join(dir, searchPlace);
+ try {
+ fs.accessSync(filepath);
+ } catch {
+ continue;
+ }
+ const loaderKey = path.extname(searchPlace) || 'noExt';
+ const loader = loaders[loaderKey];
+ const content = String(fs.readFileSync(filepath));
+
+ // handle package.json
+ if (searchPlace === 'package.json') {
+ const pkg = loader(filepath, content);
+ const maybeConfig = getPackageProp(packageProp, pkg);
+ if (maybeConfig != null) {
+ result.config = maybeConfig;
+ result.filepath = filepath;
+ break dirLoop;
+ }
+
+ continue;
+ }
+
+ // handle other type of configs
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces) continue;
+
+ if (isEmpty) {
+ result.isEmpty = true;
+ result.config = undefined;
+ } else {
+ validateLoader(loader, loaderKey);
+ result.config = loader(filepath, content);
+ }
+ result.filepath = filepath;
+ break dirLoop;
+ }
+ if (dir === stopDir || dir === parentDir(dir)) break dirLoop;
+ dir = parentDir(dir);
+ }
+
+ const transformed =
+ // not found
+ result.filepath === '' && result.config === null
+ ? transform(null)
+ : transform(result);
+
+ if (cache) {
+ for (const p of visited) searchCache.set(p, transformed);
+ }
+
+ return transformed;
+ },
+ load(filepath) {
+ validateFilePath(filepath);
+ const absPath = path.resolve(process.cwd(), filepath);
+ if (cache && loadCache.has(absPath)) {
+ return loadCache.get(absPath);
+ }
+ const {base, ext} = path.parse(absPath);
+ const loaderKey = ext || 'noExt';
+ const loader = loaders[loaderKey];
+ validateLoader(loader, loaderKey);
+
+ const content = String(fs.readFileSync(absPath));
+
+ if (base === 'package.json') {
+ const pkg = loader(absPath, content);
+ return transform({
+ config: getPackageProp(packageProp, pkg),
+ filepath: absPath,
+ });
+ }
+ const result = {
+ config: null,
+ filepath: absPath,
+ };
+ // handle other type of configs
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces)
+ return emplace(
+ loadCache,
+ absPath,
+ transform({
+ filepath: absPath,
+ config: undefined,
+ isEmpty: true,
+ }),
+ );
+
+ // cosmiconfig returns undefined for empty files
+ result.config = isEmpty ? undefined : loader(absPath, content);
+
+ return emplace(
+ loadCache,
+ absPath,
+ transform(isEmpty ? {...result, isEmpty, config: undefined} : result),
+ );
+ },
+ clearLoadCache() {
+ if (cache) loadCache.clear();
+ },
+ clearSearchCache() {
+ if (cache) searchCache.clear();
+ },
+ clearCaches() {
+ if (cache) {
+ loadCache.clear();
+ searchCache.clear();
+ }
+ },
+ };
+};