c12 3.0.2 → 3.0.4

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
@@ -109,8 +109,6 @@ Configuration base name. The default is `config`.
109
109
 
110
110
  Configuration file name without extension. Default is generated from `name` (f.e., if `name` is `foo`, the config file will be => `foo.config`).
111
111
 
112
- Set to `false` to avoid loading the config file.
113
-
114
112
  ### `rcFile`
115
113
 
116
114
  RC Config file name. Default is generated from `name` (name=foo => `.foorc`).
@@ -173,6 +171,11 @@ Environment name used for [environment specific configuration](#environment-spec
173
171
 
174
172
  The default is `process.env.NODE_ENV`. You can set `envName` to `false` or an empty string to disable the feature.
175
173
 
174
+ ### `resolve`
175
+
176
+ You can define a custom function that resolves the config.
177
+
178
+
176
179
  ## Extending configuration
177
180
 
178
181
  If resolved config contains a `extends` key, it will be used to extend the configuration.
package/dist/index.d.mts CHANGED
@@ -38,6 +38,9 @@ type Env = typeof process.env;
38
38
  declare function setupDotenv(options: DotenvOptions): Promise<Env>;
39
39
  /** Load environment variables into an object. */
40
40
  declare function loadDotenv(options: DotenvOptions): Promise<Env>;
41
+ declare global {
42
+ var __c12_dotenv_vars__: Map<Record<string, any>, Set<string>>;
43
+ }
41
44
 
42
45
  interface ConfigLayerMeta {
43
46
  name?: string;
@@ -148,4 +151,5 @@ interface WatchConfigOptions<T extends UserInputConfig = UserInputConfig, MT ext
148
151
  }
149
152
  declare function watchConfig<T extends UserInputConfig = UserInputConfig, MT extends ConfigLayerMeta = ConfigLayerMeta>(options: WatchConfigOptions<T, MT>): Promise<ConfigWatcher<T, MT>>;
150
153
 
151
- export { type C12InputConfig, type ConfigLayer, type ConfigLayerMeta, type ConfigWatcher, type DefineConfig, type DotenvOptions, type Env, type InputConfig, type LoadConfigOptions, type ResolvableConfig, type ResolvableConfigContext, type ResolvedConfig, SUPPORTED_EXTENSIONS, type SourceOptions, type UserInputConfig, type WatchConfigOptions, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
154
+ export { SUPPORTED_EXTENSIONS, createDefineConfig, loadConfig, loadDotenv, setupDotenv, watchConfig };
155
+ export type { C12InputConfig, ConfigLayer, ConfigLayerMeta, ConfigWatcher, DefineConfig, DotenvOptions, Env, InputConfig, LoadConfigOptions, ResolvableConfig, ResolvableConfigContext, ResolvedConfig, SourceOptions, UserInputConfig, WatchConfigOptions };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { l as loadConfig, S as SUPPORTED_EXTENSIONS } from './shared/c12.X4pJ8kft.mjs';
2
- export { a as loadDotenv, s as setupDotenv } from './shared/c12.X4pJ8kft.mjs';
1
+ import { l as loadConfig, S as SUPPORTED_EXTENSIONS } from './shared/c12.CEGFwQZa.mjs';
2
+ export { a as loadDotenv, s as setupDotenv } from './shared/c12.CEGFwQZa.mjs';
3
3
  import { debounce } from 'perfect-debounce';
4
4
  import { resolve } from 'pathe';
5
5
  import 'node:fs';
@@ -66,10 +66,15 @@ async function watchConfig(options) {
66
66
  });
67
67
  }
68
68
  const oldConfig = config;
69
- const newConfig = await loadConfig(options);
70
- config = newConfig;
69
+ try {
70
+ config = await loadConfig(options);
71
+ } catch (error) {
72
+ console.warn(`Failed to load config ${path}
73
+ ${error}`);
74
+ return;
75
+ }
71
76
  const changeCtx = {
72
- newConfig,
77
+ newConfig: config,
73
78
  oldConfig,
74
79
  getDiff: () => diff(oldConfig.config, config.config)
75
80
  };
@@ -1,4 +1,4 @@
1
- import { existsSync, promises } from 'node:fs';
1
+ import { statSync, promises, existsSync } from 'node:fs';
2
2
  import { rm, readFile } from 'node:fs/promises';
3
3
  import { pathToFileURL } from 'node:url';
4
4
  import { homedir } from 'node:os';
@@ -18,8 +18,12 @@ async function setupDotenv(options) {
18
18
  env: targetEnvironment,
19
19
  interpolate: options.interpolate ?? true
20
20
  });
21
+ const dotenvVars = getDotEnvVars(targetEnvironment);
21
22
  for (const key in environment) {
22
- if (!key.startsWith("_") && targetEnvironment[key] === void 0) {
23
+ if (key.startsWith("_")) {
24
+ continue;
25
+ }
26
+ if (targetEnvironment[key] === void 0 || dotenvVars.has(key)) {
23
27
  targetEnvironment[key] = environment[key];
24
28
  }
25
29
  }
@@ -28,13 +32,17 @@ async function setupDotenv(options) {
28
32
  async function loadDotenv(options) {
29
33
  const environment = /* @__PURE__ */ Object.create(null);
30
34
  const dotenvFile = resolve(options.cwd, options.fileName);
31
- if (existsSync(dotenvFile)) {
35
+ const dotenvVars = getDotEnvVars(options.env || {});
36
+ Object.assign(environment, options.env);
37
+ if (statSync(dotenvFile, { throwIfNoEntry: false })?.isFile()) {
32
38
  const parsed = dotenv.parse(await promises.readFile(dotenvFile, "utf8"));
33
- Object.assign(environment, parsed);
34
- }
35
- if (!options.env?._applied) {
36
- Object.assign(environment, options.env);
37
- environment._applied = true;
39
+ for (const key in parsed) {
40
+ if (key in environment && !dotenvVars.has(key)) {
41
+ continue;
42
+ }
43
+ environment[key] = parsed[key];
44
+ dotenvVars.add(key);
45
+ }
38
46
  }
39
47
  if (options.interpolate) {
40
48
  interpolate(environment);
@@ -81,6 +89,13 @@ function interpolate(target, source = {}, parse = (v) => v) {
81
89
  target[key] = interpolate2(getValue(key));
82
90
  }
83
91
  }
92
+ function getDotEnvVars(targetEnvironment) {
93
+ const globalRegistry = globalThis.__c12_dotenv_vars__ ||= /* @__PURE__ */ new Map();
94
+ if (!globalRegistry.has(targetEnvironment)) {
95
+ globalRegistry.set(targetEnvironment, /* @__PURE__ */ new Set());
96
+ }
97
+ return globalRegistry.get(targetEnvironment);
98
+ }
84
99
 
85
100
  const _normalize = (p) => p?.replace(/\\/g, "/");
86
101
  const ASYNC_LOADERS = {
package/dist/update.d.mts CHANGED
@@ -49,4 +49,5 @@ interface UpdateConfigOptions {
49
49
  }) => MaybePromise<string | boolean>;
50
50
  }
51
51
 
52
- export { type UpdateConfigOptions, type UpdateConfigResult, updateConfig };
52
+ export { updateConfig };
53
+ export type { UpdateConfigOptions, UpdateConfigResult };
package/dist/update.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { resolveModulePath } from 'exsolve';
2
- import { S as SUPPORTED_EXTENSIONS } from './shared/c12.X4pJ8kft.mjs';
2
+ import { S as SUPPORTED_EXTENSIONS } from './shared/c12.CEGFwQZa.mjs';
3
3
  import { join, normalize } from 'pathe';
4
4
  import { mkdir, writeFile, readFile } from 'node:fs/promises';
5
5
  import { dirname, extname } from 'node:path';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c12",
3
- "version": "3.0.2",
3
+ "version": "3.0.4",
4
4
  "description": "Smart Config Loader",
5
5
  "repository": "unjs/c12",
6
6
  "license": "MIT",
@@ -32,31 +32,31 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "chokidar": "^4.0.3",
35
- "confbox": "^0.1.8",
35
+ "confbox": "^0.2.2",
36
36
  "defu": "^6.1.4",
37
- "dotenv": "^16.4.7",
38
- "exsolve": "^1.0.0",
37
+ "dotenv": "^16.5.0",
38
+ "exsolve": "^1.0.5",
39
39
  "giget": "^2.0.0",
40
40
  "jiti": "^2.4.2",
41
- "ohash": "^2.0.5",
41
+ "ohash": "^2.0.11",
42
42
  "pathe": "^2.0.3",
43
43
  "perfect-debounce": "^1.0.0",
44
- "pkg-types": "^2.0.0",
44
+ "pkg-types": "^2.1.0",
45
45
  "rc9": "^2.1.2"
46
46
  },
47
47
  "devDependencies": {
48
- "@types/node": "^22.13.5",
49
- "@vitest/coverage-v8": "^3.0.7",
48
+ "@types/node": "^22.15.18",
49
+ "@vitest/coverage-v8": "^3.1.3",
50
50
  "automd": "^0.4.0",
51
- "changelogen": "^0.6.0",
52
- "eslint": "^9.21.0",
51
+ "changelogen": "^0.6.1",
52
+ "eslint": "^9.27.0",
53
53
  "eslint-config-unjs": "^0.4.2",
54
- "expect-type": "^1.1.0",
54
+ "expect-type": "^1.2.1",
55
55
  "magicast": "^0.3.5",
56
- "prettier": "^3.5.2",
57
- "typescript": "^5.7.3",
56
+ "prettier": "^3.5.3",
57
+ "typescript": "^5.8.3",
58
58
  "unbuild": "^3.5.0",
59
- "vitest": "^3.0.7"
59
+ "vitest": "^3.1.3"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "magicast": "^0.3.5"
@@ -66,5 +66,5 @@
66
66
  "optional": true
67
67
  }
68
68
  },
69
- "packageManager": "pnpm@10.5.1"
69
+ "packageManager": "pnpm@10.11.0"
70
70
  }