new changes

This commit is contained in:
Niranjan
2026-04-07 05:05:28 +05:30
parent 7c070224bd
commit a18bba15f2
29975 changed files with 3247495 additions and 2761 deletions

View File

@@ -0,0 +1,109 @@
import fs from 'fs';
import path from 'path';
import mergeFun from 'lodash.merge';
import { jsLoader, LoadConfOption } from './loader/js';
import { jsonLoader } from './loader/json';
import { yamlLoader } from './loader/yaml';
import { tomlLoader } from './loader/toml';
import { iniLoader } from './loader/ini';
import { findConfigFile } from './utils';
export * from './utils';
export * from './loader/js';
export * from './loader/json';
export * from './loader/yaml';
export * from './loader/toml';
export * from './loader/ini';
export const merge = mergeFun;
export type LoaderFunc<T> = (filepath: string, content: string, jsOption?: LoadConfOption) => T | Promise<T>;
export type Loader<T> = Record<string, LoaderFunc<T>>;
export interface AutoConfOption<T> {
searchPlaces?: string[];
/** An object that maps extensions to the loader functions responsible for loading and parsing files with those extensions. */
loaders?: Loader<T>;
/** Specify default configuration. It has the lowest priority and is applied after extending config. */
default?: T;
/** Resolve configuration from this working directory. The default is `process.cwd()` */
cwd?: string;
/** Default transform js configuration */
jsOption?: LoadConfOption;
/** @deprecated use `mustExist` instead */
ignoreLog?: boolean;
mustExist?: boolean;
}
let configPath = '';
export const getConfigPath = () => configPath;
/**
* Find and load configuration from a `package.json` property, `rc` file, or `CommonJS` module.
* @param namespace {string} Configuration base name. The default is `autoconf`.
* @param option
*/
export async function autoConf<T>(namespace: string = 'autoconf', option: AutoConfOption<T> = {}) {
const {
searchPlaces = [],
default: defaultValue = {},
cwd = process.cwd(),
ignoreLog = false,
mustExist = ignoreLog || false,
jsOption,
} = option;
const loaders: Loader<T> = {
'.yml': yamlLoader,
'.yaml': yamlLoader,
'.ini': iniLoader,
'.toml': tomlLoader,
'.json': jsonLoader,
'.json5': jsonLoader,
'.jsonc': jsonLoader,
'.js': jsLoader,
'.ts': jsLoader,
'.cjs': jsLoader,
'.mjs': jsLoader,
...(option.loaders || {}),
};
const pkgPath = path.resolve(cwd, 'package.json');
configPath = findConfigFile(namespace, cwd, searchPlaces);
let content = '';
let resultData: T;
let loaderFunc: LoaderFunc<T>;
try {
if (configPath) {
const extname = path.extname(configPath);
const basename = path.basename(configPath);
if (new RegExp(`^(.?${namespace}rc)$`).test(basename)) {
content = fs.readFileSync(configPath, 'utf-8');
loaderFunc = loaders['.json'];
} else if (loaders[extname]) {
content = fs.readFileSync(configPath, 'utf-8');
loaderFunc = loaders[extname];
}
} else if (fs.existsSync(pkgPath)) {
content = fs.readFileSync(pkgPath, 'utf-8');
const result = loaders['.json'](configPath, content);
resultData = (result as Record<string, T>)[namespace];
}
if (content && loaderFunc) {
resultData = await loaderFunc(configPath, content, jsOption);
if (typeof resultData === 'function') {
return merge(defaultValue, resultData, { default: resultData });
}
}
if (!!mustExist && !configPath && !resultData) {
return null;
}
if (resultData) {
return merge(defaultValue, resultData);
}
console.log(`AUTO_CONF:ERROR: \x1b[31;1mCan't find config file\x1b[0m`);
} catch (error) {
console.log(`AUTO_CONF:CATCH:ERROR: \x1b[31;1m${error}\x1b[0m`);
}
}
export default autoConf;

View File

@@ -0,0 +1,5 @@
import ini from 'ini';
export function iniLoader<T>(_: string, content: string): T {
return ini.parse(content) as T;
}

View File

@@ -0,0 +1,67 @@
import { createJiti } from 'jiti';
import type jiti from 'jiti';
import { transform, Options } from 'sucrase';
type Jiti = ReturnType<typeof jiti>;
type JITIOptions = Jiti['options'];
let jitiInstance: ReturnType<typeof jiti> | null = null;
function lazyJiti(option: JITIOptions = {}, transformOpt = {} as Options) {
return (
jitiInstance ??
(jitiInstance = createJiti(__filename, {
interopDefault: true,
...option,
transform: (opts) => {
return transform(opts.source, {
transforms: ['typescript', 'imports'],
...transformOpt,
});
},
}))
);
}
export interface LoadConfOption {
jiti?: boolean;
jitiOptions?: JITIOptions;
transformOption?: Options;
}
export async function loadConf<T>(path: string, option: LoadConfOption = {}): Promise<T> {
const { jiti = true, jitiOptions, transformOption } = option;
let config = await (async function () {
try {
if (jiti) {
return path ? await lazyJiti(jitiOptions, transformOption).import(path) : {};
} else {
return path ? require(path) : {};
}
} catch {
return await lazyJiti(jitiOptions, transformOption).import(path);
}
})();
// Ensure both default export and named exports are handled
if (config.default) {
if (typeof config.default === 'function') {
const defaultFunc = config.default;
Object.assign(defaultFunc, config);
return defaultFunc;
} else {
config = { ...config.default, ...config };
}
}
// ⚠️ 🚨 For some reason, the CI test default does not exist on the Windows platform.
// To ensure platform consistency, default has been removed.
if (path && path.endsWith('.cjs')) {
delete config.default;
}
return config;
}
export async function jsLoader<T>(filepath: string, content: string, option: LoadConfOption = {}): Promise<T> {
return await loadConf<T>(filepath, option);
}

View File

@@ -0,0 +1,7 @@
import type { AST } from 'jsonc-eslint-parser';
import { parseJSON, getStaticJSONValue } from 'jsonc-eslint-parser';
export function jsonLoader<T>(_: string, content: string): T {
const ast: AST.JSONProgram = parseJSON(content);
return getStaticJSONValue(ast) as T;
}

View File

@@ -0,0 +1,7 @@
import type { AST } from 'toml-eslint-parser';
import { parseTOML, getStaticTOMLValue } from 'toml-eslint-parser';
export function tomlLoader<T>(_: string, content: string): T {
const ast: AST.TOMLProgram = parseTOML(content);
return getStaticTOMLValue(ast) as T;
}

View File

@@ -0,0 +1,7 @@
import type { AST } from 'yaml-eslint-parser';
import { parseYAML, getStaticYAMLValue } from 'yaml-eslint-parser';
export function yamlLoader<T>(_: string, content: string): T {
const ast: AST.YAMLProgram = parseYAML(content);
return getStaticYAMLValue(ast) as T;
}

View File

@@ -0,0 +1,44 @@
import path from 'path';
import fs from 'fs';
export function findConfigFile(moduleName: string, root: string, searchPlaces: string[] = []) {
const data = [
...searchPlaces,
`.${moduleName}rc`,
`.${moduleName}rc.json`,
`.${moduleName}rc.json5`,
`.${moduleName}rc.jsonc`,
`.${moduleName}rc.yaml`,
`.${moduleName}rc.yml`,
`.${moduleName}rc.toml`,
`.${moduleName}rc.ini`,
`.${moduleName}rc.js`,
`.${moduleName}rc.ts`,
`.${moduleName}rc.cjs`,
`.${moduleName}rc.mjs`,
`.config/${moduleName}rc`,
`.config/${moduleName}rc.json`,
`.config/${moduleName}rc.json5`,
`.config/${moduleName}rc.jsonc`,
`.config/${moduleName}rc.yaml`,
`.config/${moduleName}rc.yml`,
`.config/${moduleName}rc.toml`,
`.config/${moduleName}rc.ini`,
`.config/${moduleName}rc.js`,
`.config/${moduleName}rc.ts`,
`.config/${moduleName}rc.cjs`,
`.config/${moduleName}rc.mjs`,
`${moduleName}.config.js`,
`${moduleName}.config.ts`,
`${moduleName}.config.cjs`,
`${moduleName}.config.mjs`,
];
for (const file of data) {
const filePath = path.resolve(root, file);
if (fs.existsSync(filePath)) {
return filePath;
}
}
return null;
}