summaryrefslogtreecommitdiff
path: root/node_modules/lilconfig
diff options
context:
space:
mode:
authorPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:54:57 +0100
committerPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:57:48 +0100
commitb1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c (patch)
tree49d360fd6cbc6a2754efe93524ac47ff0fbe0f7d /node_modules/lilconfig
Docs
Diffstat (limited to 'node_modules/lilconfig')
-rw-r--r--node_modules/lilconfig/LICENSE21
-rw-r--r--node_modules/lilconfig/dist/index.d.ts38
-rw-r--r--node_modules/lilconfig/dist/index.js251
-rw-r--r--node_modules/lilconfig/package.json48
-rw-r--r--node_modules/lilconfig/readme.md118
5 files changed, 476 insertions, 0 deletions
diff --git a/node_modules/lilconfig/LICENSE b/node_modules/lilconfig/LICENSE
new file mode 100644
index 0000000..fd866f4
--- /dev/null
+++ b/node_modules/lilconfig/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Anton Kastritskiy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/lilconfig/dist/index.d.ts b/node_modules/lilconfig/dist/index.d.ts
new file mode 100644
index 0000000..766c58c
--- /dev/null
+++ b/node_modules/lilconfig/dist/index.d.ts
@@ -0,0 +1,38 @@
+export declare type LilconfigResult = null | {
+ filepath: string;
+ config: any;
+ isEmpty?: boolean;
+};
+interface OptionsBase {
+ stopDir?: string;
+ searchPlaces?: string[];
+ ignoreEmptySearchPlaces?: boolean;
+ packageProp?: string | string[];
+}
+export declare type Transform = TransformSync | ((result: LilconfigResult) => Promise<LilconfigResult>);
+export declare type TransformSync = (result: LilconfigResult) => LilconfigResult;
+declare type LoaderResult = any;
+export declare type LoaderSync = (filepath: string, content: string) => LoaderResult;
+export declare type Loader = LoaderSync | ((filepath: string, content: string) => Promise<LoaderResult>);
+export declare type Loaders = Record<string, Loader>;
+export declare 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 defaultLoaders: LoadersSync;
+declare type AsyncSearcher = {
+ search(searchFrom?: string): Promise<LilconfigResult>;
+ load(filepath: string): Promise<LilconfigResult>;
+};
+export declare function lilconfig(name: string, options?: Partial<Options>): AsyncSearcher;
+declare type SyncSearcher = {
+ search(searchFrom?: string): LilconfigResult;
+ load(filepath: string): LilconfigResult;
+};
+export declare function lilconfigSync(name: string, options?: OptionsSync): SyncSearcher;
+export {};
diff --git a/node_modules/lilconfig/dist/index.js b/node_modules/lilconfig/dist/index.js
new file mode 100644
index 0000000..13cca57
--- /dev/null
+++ b/node_modules/lilconfig/dist/index.js
@@ -0,0 +1,251 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.lilconfigSync = exports.lilconfig = exports.defaultLoaders = void 0;
+const path = require("path");
+const fs = require("fs");
+const os = require("os");
+const fsReadFileAsync = fs.promises.readFile;
+function getDefaultSearchPlaces(name) {
+ return [
+ 'package.json',
+ `.${name}rc.json`,
+ `.${name}rc.js`,
+ `.${name}rc.cjs`,
+ `.config/${name}rc`,
+ `.config/${name}rc.json`,
+ `.config/${name}rc.js`,
+ `.config/${name}rc.cjs`,
+ `${name}.config.js`,
+ `${name}.config.cjs`,
+ ];
+}
+function getSearchPaths(startDir, stopDir) {
+ return startDir
+ .split(path.sep)
+ .reduceRight((acc, _, ind, arr) => {
+ const currentPath = arr.slice(0, ind + 1).join(path.sep);
+ if (!acc.passedStopDir)
+ acc.searchPlaces.push(currentPath || path.sep);
+ if (currentPath === stopDir)
+ acc.passedStopDir = true;
+ return acc;
+ }, { searchPlaces: [], passedStopDir: false }).searchPlaces;
+}
+exports.defaultLoaders = Object.freeze({
+ '.js': require,
+ '.json': require,
+ '.cjs': require,
+ noExt(_, content) {
+ return JSON.parse(content);
+ },
+});
+function getExtDesc(ext) {
+ return ext === 'noExt' ? 'files without extensions' : `extension "${ext}"`;
+}
+function getOptions(name, options = {}) {
+ const conf = {
+ stopDir: os.homedir(),
+ searchPlaces: getDefaultSearchPlaces(name),
+ ignoreEmptySearchPlaces: true,
+ transform: (x) => x,
+ packageProp: [name],
+ ...options,
+ loaders: { ...exports.defaultLoaders, ...options.loaders },
+ };
+ conf.searchPlaces.forEach(place => {
+ const key = path.extname(place) || 'noExt';
+ const loader = conf.loaders[key];
+ if (!loader) {
+ throw new Error(`No loader specified for ${getExtDesc(key)}, so searchPlaces item "${place}" is invalid`);
+ }
+ if (typeof loader !== 'function') {
+ throw new Error(`loader for ${getExtDesc(key)} is not a function (type provided: "${typeof loader}"), so searchPlaces item "${place}" is invalid`);
+ }
+ });
+ return conf;
+}
+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);
+}
+function getSearchItems(searchPlaces, searchPaths) {
+ return searchPaths.reduce((acc, searchPath) => {
+ searchPlaces.forEach(sp => acc.push({
+ searchPlace: sp,
+ filepath: path.join(searchPath, sp),
+ loaderKey: path.extname(sp) || 'noExt',
+ }));
+ return acc;
+ }, []);
+}
+function validateFilePath(filepath) {
+ if (!filepath)
+ throw new Error('load must pass a non-empty string');
+}
+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');
+}
+function lilconfig(name, options) {
+ const { ignoreEmptySearchPlaces, loaders, packageProp, searchPlaces, stopDir, transform, } = getOptions(name, options);
+ return {
+ async search(searchFrom = process.cwd()) {
+ const searchPaths = getSearchPaths(searchFrom, stopDir);
+ const result = {
+ config: null,
+ filepath: '',
+ };
+ const searchItems = getSearchItems(searchPlaces, searchPaths);
+ for (const { searchPlace, filepath, loaderKey } of searchItems) {
+ try {
+ await fs.promises.access(filepath);
+ }
+ catch (_a) {
+ continue;
+ }
+ const content = String(await fsReadFileAsync(filepath));
+ const loader = loaders[loaderKey];
+ 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;
+ }
+ continue;
+ }
+ 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;
+ }
+ if (result.filepath === '' && result.config === null)
+ return transform(null);
+ return transform(result);
+ },
+ async load(filepath) {
+ validateFilePath(filepath);
+ const absPath = path.resolve(process.cwd(), filepath);
+ 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 transform({
+ config: getPackageProp(packageProp, pkg),
+ filepath: absPath,
+ });
+ }
+ const result = {
+ config: null,
+ filepath: absPath,
+ };
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces)
+ return transform({
+ config: undefined,
+ filepath: absPath,
+ isEmpty: true,
+ });
+ result.config = isEmpty
+ ? undefined
+ : await loader(absPath, content);
+ return transform(isEmpty ? { ...result, isEmpty, config: undefined } : result);
+ },
+ };
+}
+exports.lilconfig = lilconfig;
+function lilconfigSync(name, options) {
+ const { ignoreEmptySearchPlaces, loaders, packageProp, searchPlaces, stopDir, transform, } = getOptions(name, options);
+ return {
+ search(searchFrom = process.cwd()) {
+ const searchPaths = getSearchPaths(searchFrom, stopDir);
+ const result = {
+ config: null,
+ filepath: '',
+ };
+ const searchItems = getSearchItems(searchPlaces, searchPaths);
+ for (const { searchPlace, filepath, loaderKey } of searchItems) {
+ try {
+ fs.accessSync(filepath);
+ }
+ catch (_a) {
+ continue;
+ }
+ const loader = loaders[loaderKey];
+ const content = String(fs.readFileSync(filepath));
+ if (searchPlace === 'package.json') {
+ const pkg = loader(filepath, content);
+ const maybeConfig = getPackageProp(packageProp, pkg);
+ if (maybeConfig != null) {
+ result.config = maybeConfig;
+ result.filepath = filepath;
+ break;
+ }
+ continue;
+ }
+ 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;
+ }
+ if (result.filepath === '' && result.config === null)
+ return transform(null);
+ return transform(result);
+ },
+ load(filepath) {
+ validateFilePath(filepath);
+ const absPath = path.resolve(process.cwd(), filepath);
+ 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,
+ };
+ const isEmpty = content.trim() === '';
+ if (isEmpty && ignoreEmptySearchPlaces)
+ return transform({
+ filepath: absPath,
+ config: undefined,
+ isEmpty: true,
+ });
+ result.config = isEmpty ? undefined : loader(absPath, content);
+ return transform(isEmpty ? { ...result, isEmpty, config: undefined } : result);
+ },
+ };
+}
+exports.lilconfigSync = lilconfigSync;
diff --git a/node_modules/lilconfig/package.json b/node_modules/lilconfig/package.json
new file mode 100644
index 0000000..8e06d1f
--- /dev/null
+++ b/node_modules/lilconfig/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "lilconfig",
+ "version": "2.1.0",
+ "description": "A zero-dependency alternative to cosmiconfig",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "scripts": {
+ "prebuild": "npm run clean",
+ "build": "tsc --declaration",
+ "postbuild": "du -h ./dist/*",
+ "clean": "rm -rf ./dist",
+ "test": "jest --coverage",
+ "lint": "eslint ./src/*.ts"
+ },
+ "keywords": [
+ "cosmiconfig",
+ "config",
+ "configuration",
+ "search"
+ ],
+ "files": [
+ "dist/*"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/antonk52/lilconfig"
+ },
+ "bugs": "https://github.com/antonk52/lilconfig/issues",
+ "author": "antonk52",
+ "license": "MIT",
+ "devDependencies": {
+ "@types/jest": "^27.0.2",
+ "@types/node": "^14.18.36",
+ "@typescript-eslint/eslint-plugin": "^5.54.0",
+ "@typescript-eslint/parser": "^5.54.0",
+ "cosmiconfig": "^7.1.0",
+ "eslint": "^8.35.0",
+ "eslint-config-prettier": "^8.6.0",
+ "eslint-plugin-prettier": "^4.2.1",
+ "jest": "^27.3.1",
+ "prettier": "^2.8.4",
+ "ts-jest": "27.0.7",
+ "typescript": "4.4.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+}
diff --git a/node_modules/lilconfig/readme.md b/node_modules/lilconfig/readme.md
new file mode 100644
index 0000000..7b6610d
--- /dev/null
+++ b/node_modules/lilconfig/readme.md
@@ -0,0 +1,118 @@
+# Lilconfig ⚙️
+[![npm version](https://badge.fury.io/js/lilconfig.svg)](https://badge.fury.io/js/lilconfig)
+[![install size](https://packagephobia.now.sh/badge?p=lilconfig)](https://packagephobia.now.sh/result?p=lilconfig)
+[![Coverage Status](https://coveralls.io/repos/github/antonk52/lilconfig/badge.svg)](https://coveralls.io/github/antonk52/lilconfig)
+
+A zero-dependency alternative to [cosmiconfig](https://www.npmjs.com/package/cosmiconfig) with the same API.
+
+## Installation
+
+```sh
+npm install lilconfig
+```
+
+## Usage
+
+```js
+import {lilconfig, lilconfigSync} from 'lilconfig';
+
+// all keys are optional
+const options = {
+ stopDir: '/Users/you/some/dir',
+ searchPlaces: ['package.json', 'myapp.conf.js'],
+ ignoreEmptySearchPlaces: false
+}
+
+lilconfig(
+ 'myapp',
+ options // optional
+).search() // Promise<LilconfigResult>
+
+lilconfigSync(
+ 'myapp',
+ options // optional
+).load(pathToConfig) // LilconfigResult
+
+/**
+ * LilconfigResult
+ * {
+ * config: any; // your config
+ * filepath: string;
+ * }
+ */
+```
+
+## Difference to `cosmiconfig`
+Lilconfig does not intend to be 100% compatible with `cosmiconfig` but tries to mimic it where possible. The key differences are:
+- **no** support for yaml files out of the box(`lilconfig` attempts to parse files with no extension as JSON instead of YAML). You can still add the support for YAML files by providing a loader, see an [example](#yaml-loader) below.
+- **no** cache
+
+### Options difference between the two.
+
+|cosmiconfig option | lilconfig |
+|------------------------|-----------|
+|cache | ❌ |
+|loaders | ✅ |
+|ignoreEmptySearchPlaces | ✅ |
+|packageProp | ✅ |
+|searchPlaces | ✅ |
+|stopDir | ✅ |
+|transform | ✅ |
+
+## Loaders examples
+
+### Yaml loader
+
+If you need the YAML support you can provide your own loader
+
+```js
+import {lilconfig} from 'lilconfig';
+import yaml from 'yaml';
+
+function loadYaml(filepath, content) {
+ return yaml.parse(content);
+}
+
+const options = {
+ loaders: {
+ '.yaml': loadYaml,
+ '.yml': loadYaml,
+ // loader for files with no extension
+ noExt: loadYaml
+ }
+};
+
+lilconfig('myapp', options)
+ .search()
+ .then(result => {
+ result // {config, filepath}
+ });
+```
+
+### ESM loader
+
+Lilconfig v2 does not support ESM modules out of the box. However, you can support it with a custom a loader. Note that this will only work with the async `lilconfig` function and won't work with the sync `lilconfigSync`.
+
+```js
+import {lilconfig} from 'lilconfig';
+
+const loadEsm = filepath => import(filepath);
+
+lilconfig('myapp', {
+ loaders: {
+ '.js': loadEsm,
+ '.mjs': loadEsm,
+ }
+})
+ .search()
+ .then(result => {
+ result // {config, filepath}
+
+ result.config.default // if config uses `export default`
+ });
+```
+
+## Version correlation
+
+- lilconig v1 → cosmiconfig v6
+- lilconig v2 → cosmiconfig v7