@rstackjs/load-config 0.1.1 → 1.0.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 +35 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +37 -16
- package/dist/meta.d.ts +8 -0
- package/dist/types.d.ts +19 -5
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -13,13 +13,27 @@ A config loading utility for the Rstack ecosystem, designed for loading JavaScri
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
+
# pnpm
|
|
17
|
+
pnpm add @rstackjs/load-config -D
|
|
18
|
+
# yarn
|
|
19
|
+
yarn add @rstackjs/load-config -D
|
|
20
|
+
# npm
|
|
16
21
|
npm add @rstackjs/load-config -D
|
|
22
|
+
# bun
|
|
23
|
+
bun add @rstackjs/load-config -D
|
|
17
24
|
```
|
|
18
25
|
|
|
19
26
|
[jiti](https://github.com/unjs/jiti) is an optional peer dependency. Install it only when you use the `jiti` or `auto` loaders:
|
|
20
27
|
|
|
21
28
|
```bash
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm add jiti -D
|
|
31
|
+
# yarn
|
|
32
|
+
yarn add jiti -D
|
|
33
|
+
# npm
|
|
22
34
|
npm add jiti -D
|
|
35
|
+
# bun
|
|
36
|
+
bun add jiti -D
|
|
23
37
|
```
|
|
24
38
|
|
|
25
39
|
## Usage
|
|
@@ -221,6 +235,27 @@ await loadConfig({
|
|
|
221
235
|
|
|
222
236
|
When using the `native` loader and `fresh` is enabled, `dependencies` contains absolute paths for files imported by the config file.
|
|
223
237
|
|
|
238
|
+
### withConfigMeta
|
|
239
|
+
|
|
240
|
+
Preserve the original config path and dependencies when loading through an adapter:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import { withConfigMeta } from '@rstackjs/load-config';
|
|
244
|
+
|
|
245
|
+
const config = { name: 'my-tool' };
|
|
246
|
+
|
|
247
|
+
export default withConfigMeta(config, {
|
|
248
|
+
filePath: '/project/project.config.ts',
|
|
249
|
+
dependencies: ['/project/shared.ts'],
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`loadConfig` uses the supplied `filePath` and merges `dependencies` with the adapter file and its collected dependencies, removing duplicates.
|
|
254
|
+
|
|
255
|
+
- Use absolute paths. `filePath: null` means no underlying config was found; `dependencies` is optional.
|
|
256
|
+
- The helper modifies and returns the original config object. Repeated calls replace its metadata. Frozen or non-extensible objects are not supported.
|
|
257
|
+
- Call it on the final config object: object spread and JSON serialization discard the metadata.
|
|
258
|
+
|
|
224
259
|
## License
|
|
225
260
|
|
|
226
261
|
[MIT](./LICENSE).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { LoadConfigOptions, LoadConfigResult } from './types.js';
|
|
2
|
-
export
|
|
2
|
+
export { withConfigMeta } from './meta.js';
|
|
3
|
+
export type { ConfigDefinition, ConfigFileMeta, ConfigLoader, LoadConfigOptions, LoadConfigResult, } from './types.js';
|
|
3
4
|
export declare function loadConfig<Config = unknown, Params extends unknown[] = []>({ cwd, path, configFileNames, loader, exportName, configParams, fresh, }?: LoadConfigOptions<Params>): Promise<LoadConfigResult<Config>>;
|
package/dist/index.js
CHANGED
|
@@ -37,13 +37,23 @@ const loadWithJiti = async (configPath, exportName, fresh)=>{
|
|
|
37
37
|
dependencies: []
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
|
+
const CONFIG_META = Symbol.for('@rstackjs/load-config/meta');
|
|
41
|
+
function withConfigMeta(config, meta) {
|
|
42
|
+
Object.defineProperty(config, CONFIG_META, {
|
|
43
|
+
configurable: true,
|
|
44
|
+
value: {
|
|
45
|
+
filePath: meta.filePath,
|
|
46
|
+
dependencies: [
|
|
47
|
+
...meta.dependencies ?? []
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
function getConfigMeta(config) {
|
|
54
|
+
if (null !== config && 'object' == typeof config && Object.hasOwn(config, CONFIG_META)) return config[CONFIG_META];
|
|
55
|
+
}
|
|
40
56
|
const JS_CONFIG_REGEXP = /\.(?:js|mjs|cjs)$/;
|
|
41
|
-
const tryFreshImport = async (configFileURL)=>{
|
|
42
|
-
try {
|
|
43
|
-
const { freshImport } = await import("./freshImport.js");
|
|
44
|
-
return await freshImport(configFileURL);
|
|
45
|
-
} catch {}
|
|
46
|
-
};
|
|
47
57
|
const loadWithNative = async (configPath, fresh)=>{
|
|
48
58
|
const configFileURL = pathToFileURL(configPath).href;
|
|
49
59
|
if (!fresh) {
|
|
@@ -53,7 +63,8 @@ const loadWithNative = async (configPath, fresh)=>{
|
|
|
53
63
|
dependencies: []
|
|
54
64
|
};
|
|
55
65
|
}
|
|
56
|
-
const
|
|
66
|
+
const { freshImport } = await import("./freshImport.js");
|
|
67
|
+
const freshImportResult = await freshImport(configFileURL);
|
|
57
68
|
if (freshImportResult) return {
|
|
58
69
|
configModule: freshImportResult.result,
|
|
59
70
|
dependencies: freshImportResult.dependencies.sort()
|
|
@@ -77,6 +88,7 @@ const resolveConfigPath = (root, customConfig, configFileNames = [])=>{
|
|
|
77
88
|
return null;
|
|
78
89
|
};
|
|
79
90
|
async function loadConfig({ cwd = process.cwd(), path, configFileNames = [], loader = 'auto', exportName = 'default', configParams = [], fresh = false } = {}) {
|
|
91
|
+
if (!path && 0 === configFileNames.length) throw new Error('Either `path` or at least one `configFileNames` entry must be provided.');
|
|
80
92
|
const configPath = resolveConfigPath(cwd, path, configFileNames);
|
|
81
93
|
if (!configPath) return {
|
|
82
94
|
content: {},
|
|
@@ -99,19 +111,28 @@ async function loadConfig({ cwd = process.cwd(), path, configFileNames = [], loa
|
|
|
99
111
|
}
|
|
100
112
|
if (!loadedConfig) loadedConfig = await loadWithJiti(configPath, exportName, fresh);
|
|
101
113
|
const { configExport, dependencies } = loadedConfig;
|
|
114
|
+
let content;
|
|
102
115
|
if (isConfigFunction(configExport)) {
|
|
103
116
|
const result = await configExport(...configParams);
|
|
104
117
|
if (void 0 === result) throw new Error('The config function must return a config object.');
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
content: configExport,
|
|
118
|
+
content = result;
|
|
119
|
+
} else content = configExport;
|
|
120
|
+
const meta = getConfigMeta(content);
|
|
121
|
+
const result = {
|
|
122
|
+
content,
|
|
113
123
|
filePath: configPath,
|
|
114
124
|
dependencies
|
|
115
125
|
};
|
|
126
|
+
if (meta) {
|
|
127
|
+
result.filePath = meta.filePath;
|
|
128
|
+
result.dependencies = [
|
|
129
|
+
...new Set([
|
|
130
|
+
...meta.dependencies ?? [],
|
|
131
|
+
configPath,
|
|
132
|
+
...dependencies
|
|
133
|
+
])
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
116
137
|
}
|
|
117
|
-
export { loadConfig };
|
|
138
|
+
export { loadConfig, withConfigMeta };
|
package/dist/meta.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ConfigFileMeta } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Attach file metadata in place and return the original configuration object.
|
|
4
|
+
* Repeated calls replace the metadata. Requires an extensible, unfrozen object.
|
|
5
|
+
* Call this after merging the config: object spread does not preserve metadata.
|
|
6
|
+
*/
|
|
7
|
+
export declare function withConfigMeta<Config extends object>(config: Config, meta: ConfigFileMeta): Config;
|
|
8
|
+
export declare function getConfigMeta(config: unknown): ConfigFileMeta | undefined;
|
package/dist/types.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type LoadConfigOptions<Params extends unknown[] = []> = {
|
|
|
14
14
|
path?: string;
|
|
15
15
|
/**
|
|
16
16
|
* Config file names to search in `cwd` when `path` is not provided.
|
|
17
|
-
*
|
|
17
|
+
* Required when `path` is not provided.
|
|
18
18
|
* @default []
|
|
19
19
|
*/
|
|
20
20
|
configFileNames?: string[];
|
|
@@ -43,19 +43,33 @@ export type LoadConfigOptions<Params extends unknown[] = []> = {
|
|
|
43
43
|
*/
|
|
44
44
|
fresh?: boolean;
|
|
45
45
|
};
|
|
46
|
+
export type ConfigFileMeta = {
|
|
47
|
+
/**
|
|
48
|
+
* Absolute path of the actual configuration file.
|
|
49
|
+
* Use `null` when no underlying configuration file was found.
|
|
50
|
+
*/
|
|
51
|
+
filePath: string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Absolute paths of additional configuration dependencies.
|
|
54
|
+
* These are merged with the adapter file and its collected dependencies.
|
|
55
|
+
*/
|
|
56
|
+
dependencies?: readonly string[];
|
|
57
|
+
};
|
|
46
58
|
export type LoadConfigResult<Config = unknown> = {
|
|
47
59
|
/**
|
|
48
60
|
* The loaded configuration object.
|
|
49
61
|
*/
|
|
50
62
|
content: Config;
|
|
51
63
|
/**
|
|
52
|
-
* The path to the loaded configuration file
|
|
53
|
-
*
|
|
64
|
+
* The path to the loaded configuration file, or the source set by `withConfigMeta`.
|
|
65
|
+
* Returns `null` if no configuration file was found, including an explicit
|
|
66
|
+
* `null` source set by `withConfigMeta`.
|
|
54
67
|
*/
|
|
55
68
|
filePath: string | null;
|
|
56
69
|
/**
|
|
57
|
-
* Absolute
|
|
58
|
-
*
|
|
70
|
+
* Absolute paths of collected configuration dependencies. When `withConfigMeta`
|
|
71
|
+
* is used, also includes explicit dependencies and the loaded adapter file,
|
|
72
|
+
* with duplicates removed.
|
|
59
73
|
*/
|
|
60
74
|
dependencies: string[];
|
|
61
75
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rstackjs/load-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/rstackjs/load-config"
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
"@types/node": "^24.13.2",
|
|
22
22
|
"fresh-import": "^0.2.1",
|
|
23
23
|
"jiti": "^2.7.0",
|
|
24
|
-
"
|
|
25
|
-
"rstack": "0.0.2",
|
|
24
|
+
"rstack": "^0.6.4",
|
|
26
25
|
"typescript": "^7.0.2"
|
|
27
26
|
},
|
|
28
27
|
"peerDependencies": {
|
|
@@ -39,10 +38,11 @@
|
|
|
39
38
|
},
|
|
40
39
|
"scripts": {
|
|
41
40
|
"build": "rs lib",
|
|
41
|
+
"check": "rs check --type-check",
|
|
42
42
|
"dev": "rs lib -w",
|
|
43
|
-
"
|
|
44
|
-
"lint
|
|
43
|
+
"format": "rs fmt",
|
|
44
|
+
"lint": "rs lint",
|
|
45
45
|
"test": "rs test",
|
|
46
|
-
"bump": "
|
|
46
|
+
"bump": "pnpm version -m \"release: v%s\""
|
|
47
47
|
}
|
|
48
48
|
}
|