initial commit
This commit is contained in:
21
node_modules/c12/LICENSE
generated
vendored
Normal file
21
node_modules/c12/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Pooya Parsa <pooya@pi0.io>
|
||||
|
||||
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.
|
||||
215
node_modules/c12/README.md
generated
vendored
Normal file
215
node_modules/c12/README.md
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
# c12
|
||||
|
||||
[![npm version][npm-version-src]][npm-version-href]
|
||||
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
||||
[![Github Actions][github-actions-src]][github-actions-href]
|
||||
[![Codecov][codecov-src]][codecov-href]
|
||||
|
||||
> Smart Configuration Loader
|
||||
|
||||
## Features
|
||||
|
||||
- JSON, CJS, Typescript and ESM config loader with [unjs/jiti](https://github.com/unjs/jiti)
|
||||
- RC config support with [unjs/rc9](https://github.com/unjs/rc9)
|
||||
- Multiple sources merged with [unjs/defu](https://github.com/unjs/defu)
|
||||
- `.env` support with [dotenv](https://www.npmjs.com/package/dotenv)
|
||||
- Support extending nested configurations from multiple local or git sources
|
||||
|
||||
## Usage
|
||||
|
||||
Install package:
|
||||
|
||||
```sh
|
||||
# npm
|
||||
npm install c12
|
||||
|
||||
# yarn
|
||||
yarn add c12
|
||||
|
||||
# pnpm
|
||||
pnpm install c12
|
||||
```
|
||||
|
||||
Import:
|
||||
|
||||
```js
|
||||
// ESM
|
||||
import { loadConfig } from 'c12'
|
||||
|
||||
// CommonJS
|
||||
const { loadConfig } = require('c12')
|
||||
```
|
||||
|
||||
Load configuration:
|
||||
|
||||
```js
|
||||
// Get loaded config
|
||||
const { config } = await loadConfig({})
|
||||
|
||||
// Get resolved config and extended layers
|
||||
const { config, configFile, layers } = await loadConfig({})
|
||||
```
|
||||
|
||||
## Loading priority
|
||||
|
||||
c12 merged config sources with [unjs/defu](https://github.com/unjs/defu) by below order:
|
||||
|
||||
1. config overrides passed by options
|
||||
2. config file in CWD
|
||||
3. RC file in CWD
|
||||
4. global RC file in user's home directory
|
||||
5. default config passed by options
|
||||
6. Extended config layers
|
||||
|
||||
## Options
|
||||
|
||||
### `cwd`
|
||||
|
||||
Resolve configuration from this working directory. Default is `process.cwd()`
|
||||
|
||||
### `name`
|
||||
|
||||
Configuration base name. Default is `config`.
|
||||
|
||||
### `configName`
|
||||
|
||||
Configuration file name without extension . Default is generated from `name` (name=foo => `foo.config`).
|
||||
|
||||
Set to `false` to avoid loading config file.
|
||||
|
||||
### `rcFile`
|
||||
|
||||
RC Config file name. Default is generated from `name` (name=foo => `.foorc`).
|
||||
|
||||
Set to `false` to disable loading RC config.
|
||||
|
||||
### `globalRC`
|
||||
|
||||
Load RC config from the workspace directory and user's home directory. Only enabled when `rcFile` is provided. Set to `false` to disable this functionality.
|
||||
|
||||
### `dotenv`
|
||||
|
||||
Loads `.env` file if enabled. It is disabled by default.
|
||||
|
||||
### `defaults`
|
||||
|
||||
Specify default configuration. It has the **lowest** priority and is applied **after extending** config.
|
||||
|
||||
### `defaultConfig`
|
||||
|
||||
Specify default configuration. It is applied **before** extending config.
|
||||
|
||||
### `overides`
|
||||
|
||||
Specify override configuration. It has the **highest** priority and is applied **before extending** config.
|
||||
|
||||
### `jiti`
|
||||
|
||||
Custom [unjs/jiti](https://github.com/unjs/jiti) instance used to import configuration files.
|
||||
|
||||
### `jitiOptions`
|
||||
|
||||
Custom [unjs/jiti](https://github.com/unjs/jiti) options to import configuration files.
|
||||
|
||||
## Extending configuration
|
||||
|
||||
If resolved config contains a `extends` key, it will be used to extend configuration.
|
||||
|
||||
Extending can be nested and each layer can extend from one base or more.
|
||||
|
||||
Final config is merged result of extended options and user options with [unjs/defu](https://github.com/unjs/defu).
|
||||
|
||||
Each item in extends, is a string that can be either an absolute or relative path to current config file pointing to a config file for extending or directory containing config file.
|
||||
If it starts with either of `github:`, `gitlab:`, `bitbucket:` or `https:`, c12 autmatically clones it.
|
||||
|
||||
For custom merging strategies, you can directly access each layer with `layers` property.
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
// config.ts
|
||||
export default {
|
||||
colors: {
|
||||
primary: 'user_primary'
|
||||
},
|
||||
extends: [
|
||||
'./theme',
|
||||
'./config.dev.ts'
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// config.dev.ts
|
||||
export default {
|
||||
dev: true
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// theme/config.ts
|
||||
export default {
|
||||
extends: '../base',
|
||||
colors: {
|
||||
primary: 'theme_primary',
|
||||
secondary: 'theme_secondary'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// base/config.ts
|
||||
export default {
|
||||
colors: {
|
||||
primary: 'base_primary'
|
||||
text: 'base_text'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Loaded configuration would look like this:
|
||||
|
||||
```js
|
||||
{
|
||||
dev: true,
|
||||
colors: {
|
||||
primary: 'user_primary',
|
||||
secondary: 'theme_secondary',
|
||||
text: 'base_text'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Layers:
|
||||
|
||||
```js
|
||||
[
|
||||
{ config: /* theme config */, configFile: /* path/to/theme/config.ts */, cwd: /* path/to/theme */ },
|
||||
{ config: /* base config */, configFile: /* path/to/base/config.ts */, cwd: /* path/to/base */ },
|
||||
{ config: /* dev config */, configFile: /* path/to/config.dev.ts */, cwd: /* path/ */ },
|
||||
]
|
||||
```
|
||||
|
||||
## 💻 Development
|
||||
|
||||
- Clone this repository
|
||||
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` (use `npm i -g corepack` for Node.js < 16.10)
|
||||
- Install dependencies using `pnpm install`
|
||||
- Run interactive tests using `pnpm dev`
|
||||
|
||||
## License
|
||||
|
||||
Made with 💛 Published under [MIT License](./LICENSE).
|
||||
|
||||
<!-- Badges -->
|
||||
[npm-version-src]: https://img.shields.io/npm/v/c12?style=flat-square
|
||||
[npm-version-href]: https://npmjs.com/package/c12
|
||||
|
||||
[npm-downloads-src]: https://img.shields.io/npm/dm/c12?style=flat-square
|
||||
[npm-downloads-href]: https://npmjs.com/package/c12
|
||||
|
||||
[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/c12/ci/main?style=flat-square
|
||||
[github-actions-href]: https://github.com/unjs/c12/actions?query=workflow%3Aci
|
||||
|
||||
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/c12/main?style=flat-square
|
||||
[codecov-href]: https://codecov.io/gh/unjs/c12
|
||||
247
node_modules/c12/dist/index.cjs
generated
vendored
Normal file
247
node_modules/c12/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
'use strict';
|
||||
|
||||
const node_fs = require('node:fs');
|
||||
const pathe = require('pathe');
|
||||
const dotenv = require('dotenv');
|
||||
const promises = require('node:fs/promises');
|
||||
const node_os = require('node:os');
|
||||
const createJiti = require('jiti');
|
||||
const rc9 = require('rc9');
|
||||
const defu = require('defu');
|
||||
const pkgTypes = require('pkg-types');
|
||||
|
||||
function _interopNamespaceDefault(e) {
|
||||
const n = Object.create(null);
|
||||
if (e) {
|
||||
for (const k in e) {
|
||||
n[k] = e[k];
|
||||
}
|
||||
}
|
||||
n.default = e;
|
||||
return n;
|
||||
}
|
||||
|
||||
const dotenv__namespace = /*#__PURE__*/_interopNamespaceDefault(dotenv);
|
||||
const rc9__namespace = /*#__PURE__*/_interopNamespaceDefault(rc9);
|
||||
|
||||
async function setupDotenv(options) {
|
||||
const targetEnvironment = options.env ?? process.env;
|
||||
const environment = await loadDotenv({
|
||||
cwd: options.cwd,
|
||||
fileName: options.fileName ?? ".env",
|
||||
env: targetEnvironment,
|
||||
interpolate: options.interpolate ?? true
|
||||
});
|
||||
for (const key in environment) {
|
||||
if (!key.startsWith("_") && targetEnvironment[key] === void 0) {
|
||||
targetEnvironment[key] = environment[key];
|
||||
}
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
async function loadDotenv(options) {
|
||||
const environment = /* @__PURE__ */ Object.create(null);
|
||||
const dotenvFile = pathe.resolve(options.cwd, options.fileName);
|
||||
if (node_fs.existsSync(dotenvFile)) {
|
||||
const parsed = dotenv__namespace.parse(await node_fs.promises.readFile(dotenvFile, "utf8"));
|
||||
Object.assign(environment, parsed);
|
||||
}
|
||||
if (!options.env._applied) {
|
||||
Object.assign(environment, options.env);
|
||||
environment._applied = true;
|
||||
}
|
||||
if (options.interpolate) {
|
||||
interpolate(environment);
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
function interpolate(target, source = {}, parse = (v) => v) {
|
||||
function getValue(key) {
|
||||
return source[key] !== void 0 ? source[key] : target[key];
|
||||
}
|
||||
function interpolate2(value, parents = []) {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
const matches = value.match(/(.?\${?(?:[\w:]+)?}?)/g) || [];
|
||||
return parse(matches.reduce((newValue, match) => {
|
||||
const parts = /(.?)\${?([\w:]+)?}?/g.exec(match);
|
||||
const prefix = parts[1];
|
||||
let value2, replacePart;
|
||||
if (prefix === "\\") {
|
||||
replacePart = parts[0];
|
||||
value2 = replacePart.replace("\\$", "$");
|
||||
} else {
|
||||
const key = parts[2];
|
||||
replacePart = parts[0].slice(prefix.length);
|
||||
if (parents.includes(key)) {
|
||||
console.warn(`Please avoid recursive environment variables ( loop: ${parents.join(" > ")} > ${key} )`);
|
||||
return "";
|
||||
}
|
||||
value2 = getValue(key);
|
||||
value2 = interpolate2(value2, [...parents, key]);
|
||||
}
|
||||
return value2 !== void 0 ? newValue.replace(replacePart, value2) : newValue;
|
||||
}, value));
|
||||
}
|
||||
for (const key in target) {
|
||||
target[key] = interpolate2(getValue(key));
|
||||
}
|
||||
}
|
||||
|
||||
async function loadConfig(options) {
|
||||
options.cwd = pathe.resolve(process.cwd(), options.cwd || ".");
|
||||
options.name = options.name || "config";
|
||||
options.configFile = options.configFile ?? (options.name !== "config" ? `${options.name}.config` : "config");
|
||||
options.rcFile = options.rcFile ?? `.${options.name}rc`;
|
||||
if (options.extend !== false) {
|
||||
options.extend = {
|
||||
extendKey: "extends",
|
||||
...options.extend
|
||||
};
|
||||
}
|
||||
options.jiti = options.jiti || createJiti(void 0, {
|
||||
interopDefault: true,
|
||||
requireCache: false,
|
||||
esmResolve: true,
|
||||
...options.jitiOptions
|
||||
});
|
||||
const r = {
|
||||
config: {},
|
||||
cwd: options.cwd,
|
||||
configFile: pathe.resolve(options.cwd, options.configFile),
|
||||
layers: []
|
||||
};
|
||||
if (options.dotenv) {
|
||||
await setupDotenv({
|
||||
cwd: options.cwd,
|
||||
...options.dotenv === true ? {} : options.dotenv
|
||||
});
|
||||
}
|
||||
const { config, configFile } = await resolveConfig(".", options);
|
||||
if (configFile) {
|
||||
r.configFile = configFile;
|
||||
}
|
||||
const configRC = {};
|
||||
if (options.rcFile) {
|
||||
if (options.globalRc) {
|
||||
Object.assign(configRC, rc9__namespace.readUser({ name: options.rcFile, dir: options.cwd }));
|
||||
const workspaceDir = await pkgTypes.findWorkspaceDir(options.cwd).catch(() => {
|
||||
});
|
||||
if (workspaceDir) {
|
||||
Object.assign(configRC, rc9__namespace.read({ name: options.rcFile, dir: workspaceDir }));
|
||||
}
|
||||
}
|
||||
Object.assign(configRC, rc9__namespace.read({ name: options.rcFile, dir: options.cwd }));
|
||||
}
|
||||
r.config = defu.defu(
|
||||
options.overrides,
|
||||
config,
|
||||
configRC,
|
||||
options.defaultConfig
|
||||
);
|
||||
if (options.extend) {
|
||||
await extendConfig(r.config, options);
|
||||
r.layers = r.config._layers;
|
||||
delete r.config._layers;
|
||||
r.config = defu.defu(
|
||||
r.config,
|
||||
...r.layers.map((e) => e.config)
|
||||
);
|
||||
}
|
||||
const baseLayers = [
|
||||
options.overrides && { config: options.overrides, configFile: void 0, cwd: void 0 },
|
||||
{ config, configFile: options.configFile, cwd: options.cwd },
|
||||
options.rcFile && { config: configRC, configFile: options.rcFile }
|
||||
].filter((l) => l && l.config);
|
||||
r.layers = [
|
||||
...baseLayers,
|
||||
...r.layers
|
||||
];
|
||||
if (options.defaults) {
|
||||
r.config = defu.defu(r.config, options.defaults);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
async function extendConfig(config, options) {
|
||||
config._layers = config._layers || [];
|
||||
if (!options.extend) {
|
||||
return;
|
||||
}
|
||||
let keys = options.extend.extendKey;
|
||||
if (typeof keys === "string") {
|
||||
keys = [keys];
|
||||
}
|
||||
const extendSources = [];
|
||||
for (const key of keys) {
|
||||
extendSources.push(...(Array.isArray(config[key]) ? config[key] : [config[key]]).filter(Boolean));
|
||||
delete config[key];
|
||||
}
|
||||
for (const extendSource of extendSources) {
|
||||
if (typeof extendSource !== "string") {
|
||||
console.warn(`Cannot extend config from \`${JSON.stringify(extendSource)}\` (which should be a string) in ${options.cwd}`);
|
||||
continue;
|
||||
}
|
||||
const _config = await resolveConfig(extendSource, options);
|
||||
if (!_config.config) {
|
||||
console.warn(`Cannot extend config from \`${extendSource}\` in ${options.cwd}`);
|
||||
continue;
|
||||
}
|
||||
await extendConfig(_config.config, { ...options, cwd: _config.cwd });
|
||||
config._layers.push(_config);
|
||||
if (_config.config._layers) {
|
||||
config._layers.push(..._config.config._layers);
|
||||
delete _config.config._layers;
|
||||
}
|
||||
}
|
||||
}
|
||||
const GIT_PREFIXES = ["github:", "gitlab:", "bitbucket:", "https://"];
|
||||
const NPM_PACKAGE_RE = /^(@[\da-z~-][\d._a-z~-]*\/)?[\da-z~-][\d._a-z~-]*$/;
|
||||
async function resolveConfig(source, options) {
|
||||
if (options.resolve) {
|
||||
const res2 = await options.resolve(source, options);
|
||||
if (res2) {
|
||||
return res2;
|
||||
}
|
||||
}
|
||||
if (GIT_PREFIXES.some((prefix) => source.startsWith(prefix))) {
|
||||
const { downloadTemplate } = await import('giget');
|
||||
const url = new URL(source);
|
||||
const gitRepo = url.protocol + url.pathname.split("/").slice(0, 2).join("/");
|
||||
const name = gitRepo.replace(/[#/:@\\]/g, "_");
|
||||
const tmpDir = process.env.XDG_CACHE_HOME ? pathe.resolve(process.env.XDG_CACHE_HOME, "c12", name) : pathe.resolve(node_os.homedir(), ".cache/c12", name);
|
||||
if (node_fs.existsSync(tmpDir)) {
|
||||
await promises.rmdir(tmpDir, { recursive: true });
|
||||
}
|
||||
const clonned = await downloadTemplate(source, { dir: tmpDir });
|
||||
source = clonned.dir;
|
||||
}
|
||||
if (NPM_PACKAGE_RE.test(source)) {
|
||||
try {
|
||||
source = options.jiti.resolve(source, { paths: [options.cwd] });
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
const isDir = !pathe.extname(source);
|
||||
const cwd = pathe.resolve(options.cwd, isDir ? source : pathe.dirname(source));
|
||||
if (isDir) {
|
||||
source = options.configFile;
|
||||
}
|
||||
const res = { config: void 0, cwd };
|
||||
try {
|
||||
res.configFile = options.jiti.resolve(pathe.resolve(cwd, source), { paths: [cwd] });
|
||||
} catch {
|
||||
}
|
||||
if (!node_fs.existsSync(res.configFile)) {
|
||||
return res;
|
||||
}
|
||||
res.config = options.jiti(res.configFile);
|
||||
if (typeof res.config === "function") {
|
||||
res.config = await res.config();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
exports.loadConfig = loadConfig;
|
||||
exports.loadDotenv = loadDotenv;
|
||||
exports.setupDotenv = setupDotenv;
|
||||
73
node_modules/c12/dist/index.d.ts
generated
vendored
Normal file
73
node_modules/c12/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
import { JITI } from 'jiti';
|
||||
import { JITIOptions } from 'jiti/dist/types';
|
||||
|
||||
interface DotenvOptions {
|
||||
/**
|
||||
* The project root directory (either absolute or relative to the current working directory).
|
||||
*/
|
||||
cwd: string;
|
||||
/**
|
||||
* What file to look in for environment variables (either absolute or relative
|
||||
* to the current working directory). For example, `.env`.
|
||||
*/
|
||||
fileName?: string;
|
||||
/**
|
||||
* Whether to interpolate variables within .env.
|
||||
*
|
||||
* @example
|
||||
* ```env
|
||||
* BASE_DIR="/test"
|
||||
* # resolves to "/test/further"
|
||||
* ANOTHER_DIR="${BASE_DIR}/further"
|
||||
* ```
|
||||
*/
|
||||
interpolate?: boolean;
|
||||
/**
|
||||
* An object describing environment variables (key, value pairs).
|
||||
*/
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}
|
||||
declare type Env = typeof process.env;
|
||||
/**
|
||||
* Load and interpolate environment variables into `process.env`.
|
||||
* If you need more control (or access to the values), consider using `loadDotenv` instead
|
||||
*
|
||||
*/
|
||||
declare function setupDotenv(options: DotenvOptions): Promise<Env>;
|
||||
/** Load environment variables into an object. */
|
||||
declare function loadDotenv(options: DotenvOptions): Promise<Env>;
|
||||
|
||||
interface InputConfig extends Record<string, any> {
|
||||
}
|
||||
interface ConfigLayer<T extends InputConfig = InputConfig> {
|
||||
config: T | null;
|
||||
cwd?: string;
|
||||
configFile?: string;
|
||||
}
|
||||
interface ResolvedConfig<T extends InputConfig = InputConfig> extends ConfigLayer<T> {
|
||||
layers?: ConfigLayer<T>[];
|
||||
cwd?: string;
|
||||
}
|
||||
interface ResolveConfigOptions {
|
||||
cwd: string;
|
||||
}
|
||||
interface LoadConfigOptions<T extends InputConfig = InputConfig> {
|
||||
name?: string;
|
||||
cwd?: string;
|
||||
configFile?: string;
|
||||
rcFile?: false | string;
|
||||
globalRc?: boolean;
|
||||
dotenv?: boolean | DotenvOptions;
|
||||
defaults?: T;
|
||||
defaultConfig?: T;
|
||||
overrides?: T;
|
||||
resolve?: (id: string, options: LoadConfigOptions) => null | ResolvedConfig | Promise<ResolvedConfig | null>;
|
||||
jiti?: JITI;
|
||||
jitiOptions?: JITIOptions;
|
||||
extend?: false | {
|
||||
extendKey?: string | string[];
|
||||
};
|
||||
}
|
||||
declare function loadConfig<T extends InputConfig = InputConfig>(options: LoadConfigOptions<T>): Promise<ResolvedConfig<T>>;
|
||||
|
||||
export { ConfigLayer, DotenvOptions, Env, InputConfig, LoadConfigOptions, ResolveConfigOptions, ResolvedConfig, loadConfig, loadDotenv, setupDotenv };
|
||||
229
node_modules/c12/dist/index.mjs
generated
vendored
Normal file
229
node_modules/c12/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
import { existsSync, promises } from 'node:fs';
|
||||
import { resolve, extname, dirname } from 'pathe';
|
||||
import * as dotenv from 'dotenv';
|
||||
import { rmdir } from 'node:fs/promises';
|
||||
import { homedir } from 'node:os';
|
||||
import createJiti from 'jiti';
|
||||
import * as rc9 from 'rc9';
|
||||
import { defu } from 'defu';
|
||||
import { findWorkspaceDir } from 'pkg-types';
|
||||
|
||||
async function setupDotenv(options) {
|
||||
const targetEnvironment = options.env ?? process.env;
|
||||
const environment = await loadDotenv({
|
||||
cwd: options.cwd,
|
||||
fileName: options.fileName ?? ".env",
|
||||
env: targetEnvironment,
|
||||
interpolate: options.interpolate ?? true
|
||||
});
|
||||
for (const key in environment) {
|
||||
if (!key.startsWith("_") && targetEnvironment[key] === void 0) {
|
||||
targetEnvironment[key] = environment[key];
|
||||
}
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
async function loadDotenv(options) {
|
||||
const environment = /* @__PURE__ */ Object.create(null);
|
||||
const dotenvFile = resolve(options.cwd, options.fileName);
|
||||
if (existsSync(dotenvFile)) {
|
||||
const parsed = dotenv.parse(await promises.readFile(dotenvFile, "utf8"));
|
||||
Object.assign(environment, parsed);
|
||||
}
|
||||
if (!options.env._applied) {
|
||||
Object.assign(environment, options.env);
|
||||
environment._applied = true;
|
||||
}
|
||||
if (options.interpolate) {
|
||||
interpolate(environment);
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
function interpolate(target, source = {}, parse = (v) => v) {
|
||||
function getValue(key) {
|
||||
return source[key] !== void 0 ? source[key] : target[key];
|
||||
}
|
||||
function interpolate2(value, parents = []) {
|
||||
if (typeof value !== "string") {
|
||||
return value;
|
||||
}
|
||||
const matches = value.match(/(.?\${?(?:[\w:]+)?}?)/g) || [];
|
||||
return parse(matches.reduce((newValue, match) => {
|
||||
const parts = /(.?)\${?([\w:]+)?}?/g.exec(match);
|
||||
const prefix = parts[1];
|
||||
let value2, replacePart;
|
||||
if (prefix === "\\") {
|
||||
replacePart = parts[0];
|
||||
value2 = replacePart.replace("\\$", "$");
|
||||
} else {
|
||||
const key = parts[2];
|
||||
replacePart = parts[0].slice(prefix.length);
|
||||
if (parents.includes(key)) {
|
||||
console.warn(`Please avoid recursive environment variables ( loop: ${parents.join(" > ")} > ${key} )`);
|
||||
return "";
|
||||
}
|
||||
value2 = getValue(key);
|
||||
value2 = interpolate2(value2, [...parents, key]);
|
||||
}
|
||||
return value2 !== void 0 ? newValue.replace(replacePart, value2) : newValue;
|
||||
}, value));
|
||||
}
|
||||
for (const key in target) {
|
||||
target[key] = interpolate2(getValue(key));
|
||||
}
|
||||
}
|
||||
|
||||
async function loadConfig(options) {
|
||||
options.cwd = resolve(process.cwd(), options.cwd || ".");
|
||||
options.name = options.name || "config";
|
||||
options.configFile = options.configFile ?? (options.name !== "config" ? `${options.name}.config` : "config");
|
||||
options.rcFile = options.rcFile ?? `.${options.name}rc`;
|
||||
if (options.extend !== false) {
|
||||
options.extend = {
|
||||
extendKey: "extends",
|
||||
...options.extend
|
||||
};
|
||||
}
|
||||
options.jiti = options.jiti || createJiti(void 0, {
|
||||
interopDefault: true,
|
||||
requireCache: false,
|
||||
esmResolve: true,
|
||||
...options.jitiOptions
|
||||
});
|
||||
const r = {
|
||||
config: {},
|
||||
cwd: options.cwd,
|
||||
configFile: resolve(options.cwd, options.configFile),
|
||||
layers: []
|
||||
};
|
||||
if (options.dotenv) {
|
||||
await setupDotenv({
|
||||
cwd: options.cwd,
|
||||
...options.dotenv === true ? {} : options.dotenv
|
||||
});
|
||||
}
|
||||
const { config, configFile } = await resolveConfig(".", options);
|
||||
if (configFile) {
|
||||
r.configFile = configFile;
|
||||
}
|
||||
const configRC = {};
|
||||
if (options.rcFile) {
|
||||
if (options.globalRc) {
|
||||
Object.assign(configRC, rc9.readUser({ name: options.rcFile, dir: options.cwd }));
|
||||
const workspaceDir = await findWorkspaceDir(options.cwd).catch(() => {
|
||||
});
|
||||
if (workspaceDir) {
|
||||
Object.assign(configRC, rc9.read({ name: options.rcFile, dir: workspaceDir }));
|
||||
}
|
||||
}
|
||||
Object.assign(configRC, rc9.read({ name: options.rcFile, dir: options.cwd }));
|
||||
}
|
||||
r.config = defu(
|
||||
options.overrides,
|
||||
config,
|
||||
configRC,
|
||||
options.defaultConfig
|
||||
);
|
||||
if (options.extend) {
|
||||
await extendConfig(r.config, options);
|
||||
r.layers = r.config._layers;
|
||||
delete r.config._layers;
|
||||
r.config = defu(
|
||||
r.config,
|
||||
...r.layers.map((e) => e.config)
|
||||
);
|
||||
}
|
||||
const baseLayers = [
|
||||
options.overrides && { config: options.overrides, configFile: void 0, cwd: void 0 },
|
||||
{ config, configFile: options.configFile, cwd: options.cwd },
|
||||
options.rcFile && { config: configRC, configFile: options.rcFile }
|
||||
].filter((l) => l && l.config);
|
||||
r.layers = [
|
||||
...baseLayers,
|
||||
...r.layers
|
||||
];
|
||||
if (options.defaults) {
|
||||
r.config = defu(r.config, options.defaults);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
async function extendConfig(config, options) {
|
||||
config._layers = config._layers || [];
|
||||
if (!options.extend) {
|
||||
return;
|
||||
}
|
||||
let keys = options.extend.extendKey;
|
||||
if (typeof keys === "string") {
|
||||
keys = [keys];
|
||||
}
|
||||
const extendSources = [];
|
||||
for (const key of keys) {
|
||||
extendSources.push(...(Array.isArray(config[key]) ? config[key] : [config[key]]).filter(Boolean));
|
||||
delete config[key];
|
||||
}
|
||||
for (const extendSource of extendSources) {
|
||||
if (typeof extendSource !== "string") {
|
||||
console.warn(`Cannot extend config from \`${JSON.stringify(extendSource)}\` (which should be a string) in ${options.cwd}`);
|
||||
continue;
|
||||
}
|
||||
const _config = await resolveConfig(extendSource, options);
|
||||
if (!_config.config) {
|
||||
console.warn(`Cannot extend config from \`${extendSource}\` in ${options.cwd}`);
|
||||
continue;
|
||||
}
|
||||
await extendConfig(_config.config, { ...options, cwd: _config.cwd });
|
||||
config._layers.push(_config);
|
||||
if (_config.config._layers) {
|
||||
config._layers.push(..._config.config._layers);
|
||||
delete _config.config._layers;
|
||||
}
|
||||
}
|
||||
}
|
||||
const GIT_PREFIXES = ["github:", "gitlab:", "bitbucket:", "https://"];
|
||||
const NPM_PACKAGE_RE = /^(@[\da-z~-][\d._a-z~-]*\/)?[\da-z~-][\d._a-z~-]*$/;
|
||||
async function resolveConfig(source, options) {
|
||||
if (options.resolve) {
|
||||
const res2 = await options.resolve(source, options);
|
||||
if (res2) {
|
||||
return res2;
|
||||
}
|
||||
}
|
||||
if (GIT_PREFIXES.some((prefix) => source.startsWith(prefix))) {
|
||||
const { downloadTemplate } = await import('giget');
|
||||
const url = new URL(source);
|
||||
const gitRepo = url.protocol + url.pathname.split("/").slice(0, 2).join("/");
|
||||
const name = gitRepo.replace(/[#/:@\\]/g, "_");
|
||||
const tmpDir = process.env.XDG_CACHE_HOME ? resolve(process.env.XDG_CACHE_HOME, "c12", name) : resolve(homedir(), ".cache/c12", name);
|
||||
if (existsSync(tmpDir)) {
|
||||
await rmdir(tmpDir, { recursive: true });
|
||||
}
|
||||
const clonned = await downloadTemplate(source, { dir: tmpDir });
|
||||
source = clonned.dir;
|
||||
}
|
||||
if (NPM_PACKAGE_RE.test(source)) {
|
||||
try {
|
||||
source = options.jiti.resolve(source, { paths: [options.cwd] });
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
const isDir = !extname(source);
|
||||
const cwd = resolve(options.cwd, isDir ? source : dirname(source));
|
||||
if (isDir) {
|
||||
source = options.configFile;
|
||||
}
|
||||
const res = { config: void 0, cwd };
|
||||
try {
|
||||
res.configFile = options.jiti.resolve(resolve(cwd, source), { paths: [cwd] });
|
||||
} catch {
|
||||
}
|
||||
if (!existsSync(res.configFile)) {
|
||||
return res;
|
||||
}
|
||||
res.config = options.jiti(res.configFile);
|
||||
if (typeof res.config === "function") {
|
||||
res.config = await res.config();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export { loadConfig, loadDotenv, setupDotenv };
|
||||
49
node_modules/c12/package.json
generated
vendored
Normal file
49
node_modules/c12/package.json
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "c12",
|
||||
"version": "1.1.0",
|
||||
"description": "Smart Config Loader",
|
||||
"repository": "unjs/c12",
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.cjs",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"defu": "^6.1.1",
|
||||
"dotenv": "^16.0.3",
|
||||
"giget": "^1.0.0",
|
||||
"jiti": "^1.16.0",
|
||||
"mlly": "^1.0.0",
|
||||
"pathe": "^1.0.0",
|
||||
"pkg-types": "^1.0.1",
|
||||
"rc9": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/coverage-c8": "^0.25.2",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint-config-unjs": "^0.0.2",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^4.8.4",
|
||||
"unbuild": "^0.9.4",
|
||||
"vitest": "^0.25.2"
|
||||
},
|
||||
"packageManager": "pnpm@7.16.0",
|
||||
"scripts": {
|
||||
"build": "unbuild",
|
||||
"dev": "vitest dev",
|
||||
"lint": "eslint --ext .ts,.js,.mjs,.cjs .",
|
||||
"release": "pnpm test && standard-version && git push --follow-tags && pnpm publish",
|
||||
"test": "vitest run --coverage"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user