c12 1.6.1 → 1.8.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 CHANGED
@@ -1,38 +1,62 @@
1
1
  # ⚙️ c12
2
2
 
3
- [![npm version][npm-version-src]][npm-version-href]
4
- [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
- [![Codecov][codecov-src]][codecov-href]
6
- [![License][license-src]][license-href]
3
+ <!-- automd:badges color=yellow codecov -->
4
+
5
+ [![npm version](https://img.shields.io/npm/v/c12?color=yellow)](https://npmjs.com/package/c12)
6
+ [![npm downloads](https://img.shields.io/npm/dm/c12?color=yellow)](https://npmjs.com/package/c12)
7
+ [![codecov](https://img.shields.io/codecov/c/gh/unjs/c12?color=yellow)](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
- - JSON, CJS, Typescript, and ESM config loader with [unjs/jiti](https://github.com/unjs/jiti)
13
- - RC config support with [unjs/rc9](https://github.com/unjs/rc9)
14
- - Multiple sources merged with [unjs/defu](https://github.com/unjs/defu)
15
+ - `.js`, `.ts`, `.cjs`, `.mjs` config loader with [unjs/jiti](https://github.com/unjs/jiti)
16
+ - `.json`, `.json5` and `.jsonc` config support
17
+ - `.config/` directory support following [config dir proposal](https://github.com/pi0/config-dir)
18
+ - `.rc` config support with [unjs/rc9](https://github.com/unjs/rc9)
15
19
  - `.env` support with [dotenv](https://www.npmjs.com/package/dotenv)
20
+ - Multiple sources merged with [unjs/defu](https://github.com/unjs/defu)
16
21
  - Reads config from the nearest `package.json` file
17
22
  - [Extends configurations](https://github.com/unjs/c12#extending-configuration) from multiple local or git sources
18
23
  - Overwrite with [environment-specific configuration](#environment-specific-configuration)
19
24
  - Config watcher with auto-reload and HMR support
20
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
+
21
35
  ## Usage
22
36
 
23
37
  Install package:
24
38
 
39
+ <!-- automd:pm-install -->
40
+
25
41
  ```sh
42
+ # ✨ Auto-detect
43
+ npx nypm i c12@^1.7.0
44
+
26
45
  # npm
27
- npm install c12
46
+ npm install c12@^1.7.0
28
47
 
29
48
  # yarn
30
- yarn add c12
49
+ yarn add c12@^1.7.0
31
50
 
32
51
  # pnpm
33
- pnpm install c12
52
+ pnpm install c12@^1.7.0
53
+
54
+ # bun
55
+ bun install c12@^1.7.0
34
56
  ```
35
57
 
58
+ <!-- /automd -->
59
+
36
60
  Import:
37
61
 
38
62
  ```js
package/dist/index.cjs CHANGED
@@ -120,6 +120,17 @@ async function loadConfig(options) {
120
120
  interopDefault: true,
121
121
  requireCache: false,
122
122
  esmResolve: true,
123
+ extensions: [
124
+ ".js",
125
+ ".mjs",
126
+ ".cjs",
127
+ ".ts",
128
+ ".mts",
129
+ ".cts",
130
+ ".json",
131
+ ".jsonc",
132
+ ".json5"
133
+ ],
123
134
  ...options.jitiOptions
124
135
  });
125
136
  const r = {
@@ -298,11 +309,14 @@ async function resolveConfig(source, options, sourceOptions = {}) {
298
309
  });
299
310
  source = cloned.dir;
300
311
  }
301
- if (NPM_PACKAGE_RE.test(source)) {
312
+ const tryResolve = (id) => {
302
313
  try {
303
- source = options.jiti.resolve(source, { paths: [options.cwd] });
314
+ return options.jiti.resolve(id, { paths: [options.cwd] });
304
315
  } catch {
305
316
  }
317
+ };
318
+ if (NPM_PACKAGE_RE.test(source)) {
319
+ source = tryResolve(source) || source;
306
320
  }
307
321
  const ext = pathe.extname(source);
308
322
  const isDir = !ext || ext === pathe.basename(source);
@@ -312,20 +326,26 @@ async function resolveConfig(source, options, sourceOptions = {}) {
312
326
  }
313
327
  const res = {
314
328
  config: void 0,
329
+ configFile: void 0,
315
330
  cwd,
316
331
  source,
317
332
  sourceOptions
318
333
  };
319
- try {
320
- res.configFile = options.jiti.resolve(pathe.resolve(cwd, source), {
321
- paths: [cwd]
322
- });
323
- } catch {
324
- }
334
+ res.configFile = tryResolve(pathe.resolve(cwd, source)) || tryResolve(pathe.resolve(cwd, ".config", source.replace(/\.config$/, ""))) || tryResolve(pathe.resolve(cwd, ".config", source)) || source;
325
335
  if (!node_fs.existsSync(res.configFile)) {
326
336
  return res;
327
337
  }
328
- res.config = options.jiti(res.configFile);
338
+ if (res.configFile.endsWith(".jsonc")) {
339
+ const { parse } = await import('jsonc-parser');
340
+ res.config = parse(await promises.readFile(res.configFile, "utf8"));
341
+ } else if (res.configFile.endsWith(".json5")) {
342
+ const parse = await import('json5').then(
343
+ (m) => m.parse || m.default?.parse || m.default
344
+ );
345
+ res.config = parse(await promises.readFile(res.configFile, "utf8"));
346
+ } else {
347
+ res.config = options.jiti(res.configFile);
348
+ }
329
349
  if (res.config instanceof Function) {
330
350
  res.config = await res.config();
331
351
  }
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { existsSync, promises } from 'node:fs';
2
2
  import { resolve, dirname, basename, join, extname } from 'pathe';
3
3
  import * as dotenv from 'dotenv';
4
- import { rm } from 'node:fs/promises';
4
+ import { rm, readFile } from 'node:fs/promises';
5
5
  import { homedir } from 'node:os';
6
6
  import createJiti from 'jiti';
7
7
  import * as rc9 from 'rc9';
@@ -100,6 +100,17 @@ async function loadConfig(options) {
100
100
  interopDefault: true,
101
101
  requireCache: false,
102
102
  esmResolve: true,
103
+ extensions: [
104
+ ".js",
105
+ ".mjs",
106
+ ".cjs",
107
+ ".ts",
108
+ ".mts",
109
+ ".cts",
110
+ ".json",
111
+ ".jsonc",
112
+ ".json5"
113
+ ],
103
114
  ...options.jitiOptions
104
115
  });
105
116
  const r = {
@@ -278,11 +289,14 @@ async function resolveConfig(source, options, sourceOptions = {}) {
278
289
  });
279
290
  source = cloned.dir;
280
291
  }
281
- if (NPM_PACKAGE_RE.test(source)) {
292
+ const tryResolve = (id) => {
282
293
  try {
283
- source = options.jiti.resolve(source, { paths: [options.cwd] });
294
+ return options.jiti.resolve(id, { paths: [options.cwd] });
284
295
  } catch {
285
296
  }
297
+ };
298
+ if (NPM_PACKAGE_RE.test(source)) {
299
+ source = tryResolve(source) || source;
286
300
  }
287
301
  const ext = extname(source);
288
302
  const isDir = !ext || ext === basename(source);
@@ -292,20 +306,26 @@ async function resolveConfig(source, options, sourceOptions = {}) {
292
306
  }
293
307
  const res = {
294
308
  config: void 0,
309
+ configFile: void 0,
295
310
  cwd,
296
311
  source,
297
312
  sourceOptions
298
313
  };
299
- try {
300
- res.configFile = options.jiti.resolve(resolve(cwd, source), {
301
- paths: [cwd]
302
- });
303
- } catch {
304
- }
314
+ res.configFile = tryResolve(resolve(cwd, source)) || tryResolve(resolve(cwd, ".config", source.replace(/\.config$/, ""))) || tryResolve(resolve(cwd, ".config", source)) || source;
305
315
  if (!existsSync(res.configFile)) {
306
316
  return res;
307
317
  }
308
- res.config = options.jiti(res.configFile);
318
+ if (res.configFile.endsWith(".jsonc")) {
319
+ const { parse } = await import('jsonc-parser');
320
+ res.config = parse(await readFile(res.configFile, "utf8"));
321
+ } else if (res.configFile.endsWith(".json5")) {
322
+ const parse = await import('json5').then(
323
+ (m) => m.parse || m.default?.parse || m.default
324
+ );
325
+ res.config = parse(await readFile(res.configFile, "utf8"));
326
+ } else {
327
+ res.config = options.jiti(res.configFile);
328
+ }
309
329
  if (res.config instanceof Function) {
310
330
  res.config = await res.config();
311
331
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c12",
3
- "version": "1.6.1",
3
+ "version": "1.8.0",
4
4
  "description": "Smart Config Loader",
5
5
  "repository": "unjs/c12",
6
6
  "license": "MIT",
@@ -31,28 +31,31 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "chokidar": "^3.5.3",
34
- "defu": "^6.1.3",
35
- "dotenv": "^16.3.1",
34
+ "defu": "^6.1.4",
35
+ "dotenv": "^16.3.2",
36
36
  "giget": "^1.2.1",
37
37
  "jiti": "^1.21.0",
38
- "mlly": "^1.4.2",
38
+ "json5": "^2.2.3",
39
+ "jsonc-parser": "^3.2.1",
40
+ "mlly": "^1.5.0",
39
41
  "ohash": "^1.1.3",
40
- "pathe": "^1.1.1",
42
+ "pathe": "^1.1.2",
41
43
  "perfect-debounce": "^1.0.0",
42
44
  "pkg-types": "^1.0.3",
43
45
  "rc9": "^2.1.1"
44
46
  },
45
47
  "devDependencies": {
46
- "@types/node": "^20.10.5",
47
- "@vitest/coverage-v8": "^1.1.0",
48
+ "@types/node": "^20.11.5",
49
+ "@vitest/coverage-v8": "^1.2.1",
50
+ "automd": "^0.2.0",
48
51
  "changelogen": "^0.5.5",
49
52
  "eslint": "^8.56.0",
50
53
  "eslint-config-unjs": "^0.2.1",
51
54
  "expect-type": "^0.17.3",
52
- "prettier": "^3.1.1",
55
+ "prettier": "^3.2.4",
53
56
  "typescript": "^5.3.3",
54
57
  "unbuild": "^2.0.0",
55
- "vitest": "^1.1.0"
58
+ "vitest": "^1.2.1"
56
59
  },
57
- "packageManager": "pnpm@8.13.1"
60
+ "packageManager": "pnpm@8.14.1"
58
61
  }