second commit

This commit is contained in:
2024-12-27 22:31:23 +09:00
parent 2353324570
commit 10a0f110ca
8819 changed files with 1307198 additions and 28 deletions

21
node_modules/lilconfig/LICENSE generated vendored Normal file
View File

@ -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.

42
node_modules/lilconfig/package.json generated vendored Normal file
View File

@ -0,0 +1,42 @@
{
"name": "lilconfig",
"version": "3.1.3",
"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": "biome ci ./src",
"types": "tsc"
},
"keywords": [
"cosmiconfig",
"config",
"configuration",
"search"
],
"files": [
"src/index.*"
],
"repository": {
"type": "git",
"url": "https://github.com/antonk52/lilconfig"
},
"bugs": "https://github.com/antonk52/lilconfig/issues",
"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",
"jest": "^29.7.0",
"typescript": "^5.3.3",
"uvu": "^0.5.6"
},
"funding": "https://github.com/sponsors/antonk52",
"engines": {
"node": ">=14"
}
}

98
node_modules/lilconfig/readme.md generated vendored Normal file
View File

@ -0,0 +1,98 @@
# 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;
* }
*/
```
## ESM
ESM configs can be loaded with **async API only**. Specifically `js` files in projects with `"type": "module"` in `package.json` or `mjs` files.
## Difference to `cosmiconfig`
Lilconfig does not intend to be 100% compatible with `cosmiconfig` but tries to mimic it where possible. The key difference is **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.
### 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}
});
```
## Version correlation
- lilconig v1 → cosmiconfig v6
- lilconig v2 → cosmiconfig v7
- lilconig v3 → cosmiconfig v8

54
node_modules/lilconfig/src/index.d.ts generated vendored Normal file
View File

@ -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;

460
node_modules/lilconfig/src/index.js generated vendored Normal file
View File

@ -0,0 +1,460 @@
// @ts-check
const path = require('path');
const fs = require('fs');
const os = require('os');
const url = require('url');
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 fileUrl = url.pathToFileURL(id).href;
const mod = await import(/* webpackIgnore: true */ fileUrl);
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();
}
},
};
};