c12 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -10
- package/dist/index.cjs +53 -42
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +52 -42
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# ⚙️ c12
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](https://npmjs.com/package/c12)
|
|
6
|
+
[](https://npmjs.com/package/c12)
|
|
7
|
+
[](https://codecov.io/gh/unjs/c12)
|
|
8
|
+
|
|
9
|
+
<!-- /automd -->
|
|
7
10
|
|
|
8
11
|
c12 (pronounced as /siːtwelv/, like c-twelve) is a smart configuration loader.
|
|
9
12
|
|
|
10
|
-
## Features
|
|
13
|
+
## ✅ Features
|
|
11
14
|
|
|
12
|
-
- `.js`, `.ts`, `.cjs`, `.
|
|
13
|
-
- `.
|
|
15
|
+
- `.js`, `.ts`, `.mjs`, `.cjs`, `.mts`, `.cts` `.json` config loader with [unjs/jiti](https://jiti.unjs.io)
|
|
16
|
+
- `.jsonc`, `.json5`, `.yaml`, `.yml`, `.toml` config loader with [unjs/confbox](https://confbox.unjs.io)
|
|
17
|
+
- `.config/` directory support following [config dir proposal](https://github.com/pi0/config-dir)
|
|
14
18
|
- `.rc` config support with [unjs/rc9](https://github.com/unjs/rc9)
|
|
15
19
|
- `.env` support with [dotenv](https://www.npmjs.com/package/dotenv)
|
|
16
20
|
- Multiple sources merged with [unjs/defu](https://github.com/unjs/defu)
|
|
@@ -19,21 +23,40 @@ c12 (pronounced as /siːtwelv/, like c-twelve) is a smart configuration loader.
|
|
|
19
23
|
- Overwrite with [environment-specific configuration](#environment-specific-configuration)
|
|
20
24
|
- Config watcher with auto-reload and HMR support
|
|
21
25
|
|
|
26
|
+
## 🦴 Used by
|
|
27
|
+
|
|
28
|
+
- [Nuxt](https://nuxt.com/)
|
|
29
|
+
- [Nitro](https://nitro.unjs.io/)
|
|
30
|
+
- [Unbuild](https://unbuild.unjs.io)
|
|
31
|
+
- [Automd](https://automd.unjs.io)
|
|
32
|
+
- [Changelogen](https://changelogen.unjs.io)
|
|
33
|
+
- [RemixKit](https://github.com/jrestall/remix-kit)
|
|
34
|
+
|
|
22
35
|
## Usage
|
|
23
36
|
|
|
24
37
|
Install package:
|
|
25
38
|
|
|
39
|
+
<!-- automd:pm-install -->
|
|
40
|
+
|
|
26
41
|
```sh
|
|
42
|
+
# ✨ Auto-detect
|
|
43
|
+
npx nypm i c12@^1.7.0
|
|
44
|
+
|
|
27
45
|
# npm
|
|
28
|
-
npm install c12
|
|
46
|
+
npm install c12@^1.7.0
|
|
29
47
|
|
|
30
48
|
# yarn
|
|
31
|
-
yarn add c12
|
|
49
|
+
yarn add c12@^1.7.0
|
|
32
50
|
|
|
33
51
|
# pnpm
|
|
34
|
-
pnpm install c12
|
|
52
|
+
pnpm install c12@^1.7.0
|
|
53
|
+
|
|
54
|
+
# bun
|
|
55
|
+
bun install c12@^1.7.0
|
|
35
56
|
```
|
|
36
57
|
|
|
58
|
+
<!-- /automd -->
|
|
59
|
+
|
|
37
60
|
Import:
|
|
38
61
|
|
|
39
62
|
```js
|
package/dist/index.cjs
CHANGED
|
@@ -10,7 +10,6 @@ const rc9 = require('rc9');
|
|
|
10
10
|
const defu = require('defu');
|
|
11
11
|
const ohash = require('ohash');
|
|
12
12
|
const pkgTypes = require('pkg-types');
|
|
13
|
-
const chokidar = require('chokidar');
|
|
14
13
|
const perfectDebounce = require('perfect-debounce');
|
|
15
14
|
|
|
16
15
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -104,6 +103,29 @@ function interpolate(target, source = {}, parse = (v) => v) {
|
|
|
104
103
|
}
|
|
105
104
|
|
|
106
105
|
const _normalize = (p) => p?.replace(/\\/g, "/");
|
|
106
|
+
const ASYNC_LOADERS = {
|
|
107
|
+
".yaml": () => import('confbox/yaml').then((r) => r.parseYAML),
|
|
108
|
+
".yml": () => import('confbox/yaml').then((r) => r.parseYAML),
|
|
109
|
+
".jsonc": () => import('confbox/jsonc').then((r) => r.parseJSONC),
|
|
110
|
+
".json5": () => import('confbox/json5').then((r) => r.parseJSON5),
|
|
111
|
+
".toml": () => import('confbox/toml').then((r) => r.parseTOML)
|
|
112
|
+
};
|
|
113
|
+
const SUPPORTED_EXTENSIONS = [
|
|
114
|
+
// with jiti
|
|
115
|
+
".js",
|
|
116
|
+
".ts",
|
|
117
|
+
".mjs",
|
|
118
|
+
".cjs",
|
|
119
|
+
".mts",
|
|
120
|
+
".cts",
|
|
121
|
+
".json",
|
|
122
|
+
// with confbox
|
|
123
|
+
".jsonc",
|
|
124
|
+
".json5",
|
|
125
|
+
".yaml",
|
|
126
|
+
".yml",
|
|
127
|
+
".toml"
|
|
128
|
+
];
|
|
107
129
|
async function loadConfig(options) {
|
|
108
130
|
options.cwd = pathe.resolve(process.cwd(), options.cwd || ".");
|
|
109
131
|
options.name = options.name || "config";
|
|
@@ -120,17 +142,7 @@ async function loadConfig(options) {
|
|
|
120
142
|
interopDefault: true,
|
|
121
143
|
requireCache: false,
|
|
122
144
|
esmResolve: true,
|
|
123
|
-
extensions: [
|
|
124
|
-
".js",
|
|
125
|
-
".mjs",
|
|
126
|
-
".cjs",
|
|
127
|
-
".ts",
|
|
128
|
-
".mts",
|
|
129
|
-
".cts",
|
|
130
|
-
".json",
|
|
131
|
-
".jsonc",
|
|
132
|
-
".json5"
|
|
133
|
-
],
|
|
145
|
+
extensions: [...SUPPORTED_EXTENSIONS],
|
|
134
146
|
...options.jitiOptions
|
|
135
147
|
});
|
|
136
148
|
const r = {
|
|
@@ -151,24 +163,17 @@ async function loadConfig(options) {
|
|
|
151
163
|
}
|
|
152
164
|
const configRC = {};
|
|
153
165
|
if (options.rcFile) {
|
|
166
|
+
const rcSources = [];
|
|
167
|
+
rcSources.push(rc9__namespace.read({ name: options.rcFile, dir: options.cwd }));
|
|
154
168
|
if (options.globalRc) {
|
|
155
|
-
Object.assign(
|
|
156
|
-
configRC,
|
|
157
|
-
rc9__namespace.readUser({ name: options.rcFile, dir: options.cwd })
|
|
158
|
-
);
|
|
159
169
|
const workspaceDir = await pkgTypes.findWorkspaceDir(options.cwd).catch(() => {
|
|
160
170
|
});
|
|
161
171
|
if (workspaceDir) {
|
|
162
|
-
|
|
163
|
-
configRC,
|
|
164
|
-
rc9__namespace.read({ name: options.rcFile, dir: workspaceDir })
|
|
165
|
-
);
|
|
172
|
+
rcSources.push(rc9__namespace.read({ name: options.rcFile, dir: workspaceDir }));
|
|
166
173
|
}
|
|
174
|
+
rcSources.push(rc9__namespace.readUser({ name: options.rcFile, dir: options.cwd }));
|
|
167
175
|
}
|
|
168
|
-
Object.assign(
|
|
169
|
-
configRC,
|
|
170
|
-
rc9__namespace.read({ name: options.rcFile, dir: options.cwd })
|
|
171
|
-
);
|
|
176
|
+
Object.assign(configRC, defu.defu({}, ...rcSources));
|
|
172
177
|
}
|
|
173
178
|
const pkgJson = {};
|
|
174
179
|
if (options.packageJson) {
|
|
@@ -309,11 +314,14 @@ async function resolveConfig(source, options, sourceOptions = {}) {
|
|
|
309
314
|
});
|
|
310
315
|
source = cloned.dir;
|
|
311
316
|
}
|
|
312
|
-
|
|
317
|
+
const tryResolve = (id) => {
|
|
313
318
|
try {
|
|
314
|
-
|
|
319
|
+
return options.jiti.resolve(id, { paths: [options.cwd] });
|
|
315
320
|
} catch {
|
|
316
321
|
}
|
|
322
|
+
};
|
|
323
|
+
if (NPM_PACKAGE_RE.test(source)) {
|
|
324
|
+
source = tryResolve(source) || source;
|
|
317
325
|
}
|
|
318
326
|
const ext = pathe.extname(source);
|
|
319
327
|
const isDir = !ext || ext === pathe.basename(source);
|
|
@@ -323,25 +331,20 @@ async function resolveConfig(source, options, sourceOptions = {}) {
|
|
|
323
331
|
}
|
|
324
332
|
const res = {
|
|
325
333
|
config: void 0,
|
|
334
|
+
configFile: void 0,
|
|
326
335
|
cwd,
|
|
327
336
|
source,
|
|
328
337
|
sourceOptions
|
|
329
338
|
};
|
|
330
|
-
|
|
331
|
-
res.configFile = options.jiti.resolve(pathe.resolve(cwd, source), {
|
|
332
|
-
paths: [cwd]
|
|
333
|
-
});
|
|
334
|
-
} catch {
|
|
335
|
-
}
|
|
339
|
+
res.configFile = tryResolve(pathe.resolve(cwd, source)) || tryResolve(pathe.resolve(cwd, ".config", source.replace(/\.config$/, ""))) || tryResolve(pathe.resolve(cwd, ".config", source)) || source;
|
|
336
340
|
if (!node_fs.existsSync(res.configFile)) {
|
|
337
341
|
return res;
|
|
338
342
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
res.config = parse(await promises.readFile(res.configFile, "utf8"));
|
|
343
|
+
const configFileExt = pathe.extname(res.configFile) || "";
|
|
344
|
+
if (configFileExt in ASYNC_LOADERS) {
|
|
345
|
+
const asyncLoader = await ASYNC_LOADERS[configFileExt]();
|
|
346
|
+
const contents = await promises.readFile(res.configFile, "utf8");
|
|
347
|
+
res.config = asyncLoader(contents);
|
|
345
348
|
} else {
|
|
346
349
|
res.config = options.jiti(res.configFile);
|
|
347
350
|
}
|
|
@@ -383,9 +386,15 @@ async function watchConfig(options) {
|
|
|
383
386
|
const watchingFiles = [
|
|
384
387
|
...new Set(
|
|
385
388
|
(config.layers || []).filter((l) => l.cwd).flatMap((l) => [
|
|
386
|
-
...
|
|
387
|
-
|
|
388
|
-
|
|
389
|
+
...SUPPORTED_EXTENSIONS.flatMap((ext) => [
|
|
390
|
+
pathe.resolve(l.cwd, configFileName + ext),
|
|
391
|
+
pathe.resolve(l.cwd, ".config", configFileName + ext),
|
|
392
|
+
pathe.resolve(
|
|
393
|
+
l.cwd,
|
|
394
|
+
".config",
|
|
395
|
+
configFileName.replace(/\.config$/, "") + ext
|
|
396
|
+
)
|
|
397
|
+
]),
|
|
389
398
|
l.source && pathe.resolve(l.cwd, l.source),
|
|
390
399
|
// TODO: Support watching rc from home and workspace
|
|
391
400
|
options.rcFile && pathe.resolve(
|
|
@@ -396,7 +405,8 @@ async function watchConfig(options) {
|
|
|
396
405
|
]).filter(Boolean)
|
|
397
406
|
)
|
|
398
407
|
];
|
|
399
|
-
const
|
|
408
|
+
const watch = await import('chokidar').then((r) => r.watch || r.default || r);
|
|
409
|
+
const _fswatcher = watch(watchingFiles, {
|
|
400
410
|
ignoreInitial: true,
|
|
401
411
|
...options.chokidarOptions
|
|
402
412
|
});
|
|
@@ -450,6 +460,7 @@ async function watchConfig(options) {
|
|
|
450
460
|
});
|
|
451
461
|
}
|
|
452
462
|
|
|
463
|
+
exports.SUPPORTED_EXTENSIONS = SUPPORTED_EXTENSIONS;
|
|
453
464
|
exports.createDefineConfig = createDefineConfig;
|
|
454
465
|
exports.loadConfig = loadConfig;
|
|
455
466
|
exports.loadDotenv = loadDotenv;
|
package/dist/index.d.cts
CHANGED
|
@@ -96,6 +96,7 @@ interface LoadConfigOptions<T extends UserInputConfig = UserInputConfig, MT exte
|
|
|
96
96
|
type DefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = (input: InputConfig<T, MT>) => InputConfig<T, MT>;
|
|
97
97
|
declare function createDefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(): DefineConfig<T, MT>;
|
|
98
98
|
|
|
99
|
+
declare const SUPPORTED_EXTENSIONS: readonly [".js", ".ts", ".mjs", ".cjs", ".mts", ".cts", ".json", ".jsonc", ".json5", ".yaml", ".yml", ".toml"];
|
|
99
100
|
declare function loadConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: LoadConfigOptions<T, MT>): Promise<ResolvedConfig<T, MT>>;
|
|
100
101
|
|
|
101
102
|
type ConfigWatcher<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = ResolvedConfig<T, MT> & {
|
|
@@ -122,4 +123,4 @@ interface WatchConfigOptions<T extends UserInputConfig = UserInputConfig, MT ext
|
|
|
122
123
|
}
|
|
123
124
|
declare function watchConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: WatchConfigOptions<T, MT>): Promise<ConfigWatcher<T, MT>>;
|
|
124
125
|
|
|
125
|
-
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
|
126
|
+
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, SUPPORTED_EXTENSIONS, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
package/dist/index.d.mts
CHANGED
|
@@ -96,6 +96,7 @@ interface LoadConfigOptions<T extends UserInputConfig = UserInputConfig, MT exte
|
|
|
96
96
|
type DefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = (input: InputConfig<T, MT>) => InputConfig<T, MT>;
|
|
97
97
|
declare function createDefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(): DefineConfig<T, MT>;
|
|
98
98
|
|
|
99
|
+
declare const SUPPORTED_EXTENSIONS: readonly [".js", ".ts", ".mjs", ".cjs", ".mts", ".cts", ".json", ".jsonc", ".json5", ".yaml", ".yml", ".toml"];
|
|
99
100
|
declare function loadConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: LoadConfigOptions<T, MT>): Promise<ResolvedConfig<T, MT>>;
|
|
100
101
|
|
|
101
102
|
type ConfigWatcher<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = ResolvedConfig<T, MT> & {
|
|
@@ -122,4 +123,4 @@ interface WatchConfigOptions<T extends UserInputConfig = UserInputConfig, MT ext
|
|
|
122
123
|
}
|
|
123
124
|
declare function watchConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: WatchConfigOptions<T, MT>): Promise<ConfigWatcher<T, MT>>;
|
|
124
125
|
|
|
125
|
-
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
|
126
|
+
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, SUPPORTED_EXTENSIONS, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -96,6 +96,7 @@ interface LoadConfigOptions<T extends UserInputConfig = UserInputConfig, MT exte
|
|
|
96
96
|
type DefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = (input: InputConfig<T, MT>) => InputConfig<T, MT>;
|
|
97
97
|
declare function createDefineConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(): DefineConfig<T, MT>;
|
|
98
98
|
|
|
99
|
+
declare const SUPPORTED_EXTENSIONS: readonly [".js", ".ts", ".mjs", ".cjs", ".mts", ".cts", ".json", ".jsonc", ".json5", ".yaml", ".yml", ".toml"];
|
|
99
100
|
declare function loadConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: LoadConfigOptions<T, MT>): Promise<ResolvedConfig<T, MT>>;
|
|
100
101
|
|
|
101
102
|
type ConfigWatcher<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta> = ResolvedConfig<T, MT> & {
|
|
@@ -122,4 +123,4 @@ interface WatchConfigOptions<T extends UserInputConfig = UserInputConfig, MT ext
|
|
|
122
123
|
}
|
|
123
124
|
declare function watchConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: WatchConfigOptions<T, MT>): Promise<ConfigWatcher<T, MT>>;
|
|
124
125
|
|
|
125
|
-
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
|
126
|
+
export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvedConfig, SUPPORTED_EXTENSIONS, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -8,7 +8,6 @@ import * as rc9 from 'rc9';
|
|
|
8
8
|
import { defu } from 'defu';
|
|
9
9
|
import { hash, diff } from 'ohash';
|
|
10
10
|
import { findWorkspaceDir, readPackageJSON } from 'pkg-types';
|
|
11
|
-
import { watch } from 'chokidar';
|
|
12
11
|
import { debounce } from 'perfect-debounce';
|
|
13
12
|
|
|
14
13
|
async function setupDotenv(options) {
|
|
@@ -84,6 +83,29 @@ function interpolate(target, source = {}, parse = (v) => v) {
|
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
const _normalize = (p) => p?.replace(/\\/g, "/");
|
|
86
|
+
const ASYNC_LOADERS = {
|
|
87
|
+
".yaml": () => import('confbox/yaml').then((r) => r.parseYAML),
|
|
88
|
+
".yml": () => import('confbox/yaml').then((r) => r.parseYAML),
|
|
89
|
+
".jsonc": () => import('confbox/jsonc').then((r) => r.parseJSONC),
|
|
90
|
+
".json5": () => import('confbox/json5').then((r) => r.parseJSON5),
|
|
91
|
+
".toml": () => import('confbox/toml').then((r) => r.parseTOML)
|
|
92
|
+
};
|
|
93
|
+
const SUPPORTED_EXTENSIONS = [
|
|
94
|
+
// with jiti
|
|
95
|
+
".js",
|
|
96
|
+
".ts",
|
|
97
|
+
".mjs",
|
|
98
|
+
".cjs",
|
|
99
|
+
".mts",
|
|
100
|
+
".cts",
|
|
101
|
+
".json",
|
|
102
|
+
// with confbox
|
|
103
|
+
".jsonc",
|
|
104
|
+
".json5",
|
|
105
|
+
".yaml",
|
|
106
|
+
".yml",
|
|
107
|
+
".toml"
|
|
108
|
+
];
|
|
87
109
|
async function loadConfig(options) {
|
|
88
110
|
options.cwd = resolve(process.cwd(), options.cwd || ".");
|
|
89
111
|
options.name = options.name || "config";
|
|
@@ -100,17 +122,7 @@ async function loadConfig(options) {
|
|
|
100
122
|
interopDefault: true,
|
|
101
123
|
requireCache: false,
|
|
102
124
|
esmResolve: true,
|
|
103
|
-
extensions: [
|
|
104
|
-
".js",
|
|
105
|
-
".mjs",
|
|
106
|
-
".cjs",
|
|
107
|
-
".ts",
|
|
108
|
-
".mts",
|
|
109
|
-
".cts",
|
|
110
|
-
".json",
|
|
111
|
-
".jsonc",
|
|
112
|
-
".json5"
|
|
113
|
-
],
|
|
125
|
+
extensions: [...SUPPORTED_EXTENSIONS],
|
|
114
126
|
...options.jitiOptions
|
|
115
127
|
});
|
|
116
128
|
const r = {
|
|
@@ -131,24 +143,17 @@ async function loadConfig(options) {
|
|
|
131
143
|
}
|
|
132
144
|
const configRC = {};
|
|
133
145
|
if (options.rcFile) {
|
|
146
|
+
const rcSources = [];
|
|
147
|
+
rcSources.push(rc9.read({ name: options.rcFile, dir: options.cwd }));
|
|
134
148
|
if (options.globalRc) {
|
|
135
|
-
Object.assign(
|
|
136
|
-
configRC,
|
|
137
|
-
rc9.readUser({ name: options.rcFile, dir: options.cwd })
|
|
138
|
-
);
|
|
139
149
|
const workspaceDir = await findWorkspaceDir(options.cwd).catch(() => {
|
|
140
150
|
});
|
|
141
151
|
if (workspaceDir) {
|
|
142
|
-
|
|
143
|
-
configRC,
|
|
144
|
-
rc9.read({ name: options.rcFile, dir: workspaceDir })
|
|
145
|
-
);
|
|
152
|
+
rcSources.push(rc9.read({ name: options.rcFile, dir: workspaceDir }));
|
|
146
153
|
}
|
|
154
|
+
rcSources.push(rc9.readUser({ name: options.rcFile, dir: options.cwd }));
|
|
147
155
|
}
|
|
148
|
-
Object.assign(
|
|
149
|
-
configRC,
|
|
150
|
-
rc9.read({ name: options.rcFile, dir: options.cwd })
|
|
151
|
-
);
|
|
156
|
+
Object.assign(configRC, defu({}, ...rcSources));
|
|
152
157
|
}
|
|
153
158
|
const pkgJson = {};
|
|
154
159
|
if (options.packageJson) {
|
|
@@ -289,11 +294,14 @@ async function resolveConfig(source, options, sourceOptions = {}) {
|
|
|
289
294
|
});
|
|
290
295
|
source = cloned.dir;
|
|
291
296
|
}
|
|
292
|
-
|
|
297
|
+
const tryResolve = (id) => {
|
|
293
298
|
try {
|
|
294
|
-
|
|
299
|
+
return options.jiti.resolve(id, { paths: [options.cwd] });
|
|
295
300
|
} catch {
|
|
296
301
|
}
|
|
302
|
+
};
|
|
303
|
+
if (NPM_PACKAGE_RE.test(source)) {
|
|
304
|
+
source = tryResolve(source) || source;
|
|
297
305
|
}
|
|
298
306
|
const ext = extname(source);
|
|
299
307
|
const isDir = !ext || ext === basename(source);
|
|
@@ -303,25 +311,20 @@ async function resolveConfig(source, options, sourceOptions = {}) {
|
|
|
303
311
|
}
|
|
304
312
|
const res = {
|
|
305
313
|
config: void 0,
|
|
314
|
+
configFile: void 0,
|
|
306
315
|
cwd,
|
|
307
316
|
source,
|
|
308
317
|
sourceOptions
|
|
309
318
|
};
|
|
310
|
-
|
|
311
|
-
res.configFile = options.jiti.resolve(resolve(cwd, source), {
|
|
312
|
-
paths: [cwd]
|
|
313
|
-
});
|
|
314
|
-
} catch {
|
|
315
|
-
}
|
|
319
|
+
res.configFile = tryResolve(resolve(cwd, source)) || tryResolve(resolve(cwd, ".config", source.replace(/\.config$/, ""))) || tryResolve(resolve(cwd, ".config", source)) || source;
|
|
316
320
|
if (!existsSync(res.configFile)) {
|
|
317
321
|
return res;
|
|
318
322
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
res.config = parse(await readFile(res.configFile, "utf8"));
|
|
323
|
+
const configFileExt = extname(res.configFile) || "";
|
|
324
|
+
if (configFileExt in ASYNC_LOADERS) {
|
|
325
|
+
const asyncLoader = await ASYNC_LOADERS[configFileExt]();
|
|
326
|
+
const contents = await readFile(res.configFile, "utf8");
|
|
327
|
+
res.config = asyncLoader(contents);
|
|
325
328
|
} else {
|
|
326
329
|
res.config = options.jiti(res.configFile);
|
|
327
330
|
}
|
|
@@ -363,9 +366,15 @@ async function watchConfig(options) {
|
|
|
363
366
|
const watchingFiles = [
|
|
364
367
|
...new Set(
|
|
365
368
|
(config.layers || []).filter((l) => l.cwd).flatMap((l) => [
|
|
366
|
-
...
|
|
367
|
-
|
|
368
|
-
|
|
369
|
+
...SUPPORTED_EXTENSIONS.flatMap((ext) => [
|
|
370
|
+
resolve(l.cwd, configFileName + ext),
|
|
371
|
+
resolve(l.cwd, ".config", configFileName + ext),
|
|
372
|
+
resolve(
|
|
373
|
+
l.cwd,
|
|
374
|
+
".config",
|
|
375
|
+
configFileName.replace(/\.config$/, "") + ext
|
|
376
|
+
)
|
|
377
|
+
]),
|
|
369
378
|
l.source && resolve(l.cwd, l.source),
|
|
370
379
|
// TODO: Support watching rc from home and workspace
|
|
371
380
|
options.rcFile && resolve(
|
|
@@ -376,6 +385,7 @@ async function watchConfig(options) {
|
|
|
376
385
|
]).filter(Boolean)
|
|
377
386
|
)
|
|
378
387
|
];
|
|
388
|
+
const watch = await import('chokidar').then((r) => r.watch || r.default || r);
|
|
379
389
|
const _fswatcher = watch(watchingFiles, {
|
|
380
390
|
ignoreInitial: true,
|
|
381
391
|
...options.chokidarOptions
|
|
@@ -430,4 +440,4 @@ async function watchConfig(options) {
|
|
|
430
440
|
});
|
|
431
441
|
}
|
|
432
442
|
|
|
433
|
-
export { createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
|
443
|
+
export { SUPPORTED_EXTENSIONS, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c12",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Smart Config Loader",
|
|
5
5
|
"repository": "unjs/c12",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,12 +31,11 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"chokidar": "^3.5.3",
|
|
34
|
+
"confbox": "^0.1.3",
|
|
34
35
|
"defu": "^6.1.4",
|
|
35
36
|
"dotenv": "^16.3.2",
|
|
36
37
|
"giget": "^1.2.1",
|
|
37
38
|
"jiti": "^1.21.0",
|
|
38
|
-
"json5": "^2.2.3",
|
|
39
|
-
"jsonc-parser": "^3.2.1",
|
|
40
39
|
"mlly": "^1.5.0",
|
|
41
40
|
"ohash": "^1.1.3",
|
|
42
41
|
"pathe": "^1.1.2",
|
|
@@ -47,6 +46,7 @@
|
|
|
47
46
|
"devDependencies": {
|
|
48
47
|
"@types/node": "^20.11.5",
|
|
49
48
|
"@vitest/coverage-v8": "^1.2.1",
|
|
49
|
+
"automd": "^0.2.0",
|
|
50
50
|
"changelogen": "^0.5.5",
|
|
51
51
|
"eslint": "^8.56.0",
|
|
52
52
|
"eslint-config-unjs": "^0.2.1",
|