@yongdall/load-configuration 0.6.0 → 0.6.2
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/index.d.mts +20 -1
- package/index.mjs +92 -1
- package/index.mjs.map +1 -1
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -13,5 +13,24 @@ declare function loadConfigurationWithPath<T extends object>(path: string, type?
|
|
|
13
13
|
* @returns {Promise<T | null>}
|
|
14
14
|
*/
|
|
15
15
|
declare function loadConfiguration<T extends object>(path: string, type?: "script" | "data"): Promise<T | null>;
|
|
16
|
+
/**
|
|
17
|
+
* @template {object} T
|
|
18
|
+
* @overload
|
|
19
|
+
* @param {string} root
|
|
20
|
+
* @param {string | string[]} name
|
|
21
|
+
* @param {'script' | 'data'} [type]
|
|
22
|
+
* @returns {AsyncIterableIterator<[config: T, path: string]>}
|
|
23
|
+
*/
|
|
24
|
+
declare function loadProfiles<T extends object>(root: string, name: string | string[], type?: "script" | "data" | undefined): AsyncIterableIterator<[config: T, path: string]>;
|
|
25
|
+
/**
|
|
26
|
+
* @template {object} T
|
|
27
|
+
* @overload
|
|
28
|
+
* @param {string} root
|
|
29
|
+
* @param {string | string[]} name
|
|
30
|
+
* @param {(config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>} preprocess
|
|
31
|
+
* @param {'script' | 'data'} [type]
|
|
32
|
+
* @returns {AsyncIterableIterator<T>}
|
|
33
|
+
*/
|
|
34
|
+
declare function loadProfiles<T extends object>(root: string, name: string | string[], preprocess: (config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>, type?: "script" | "data" | undefined): AsyncIterableIterator<T>;
|
|
16
35
|
//#endregion
|
|
17
|
-
export { loadConfiguration as default, loadConfigurationWithPath };
|
|
36
|
+
export { loadConfiguration as default, loadConfigurationWithPath, loadProfiles };
|
package/index.mjs
CHANGED
|
@@ -106,7 +106,98 @@ async function loadConfiguration(path, type) {
|
|
|
106
106
|
const [filepath, loader] = result;
|
|
107
107
|
return loader(filepath).then((v) => typeof v === "object" ? v : null);
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* @template {object} T
|
|
111
|
+
* @param {string} root
|
|
112
|
+
* @param {string | string[]} name
|
|
113
|
+
* @param {'script' | 'data'} [type]
|
|
114
|
+
* @returns {AsyncIterableIterator<[config: T, path: string]>}
|
|
115
|
+
*/
|
|
116
|
+
async function* loadProfileAndPaths(root, name, type) {
|
|
117
|
+
for (const n of [name].flat()) {
|
|
118
|
+
/** @type {[string, T | null] | null} */
|
|
119
|
+
const result = await loadConfigurationWithPath(pathFn.resolve(root, `${n}.yongdall`), type) || await loadConfigurationWithPath(pathFn.resolve(root, `yongdall/${n}`), type) || await loadConfigurationWithPath(pathFn.resolve(root, `${n}/yongdall`), type);
|
|
120
|
+
if (!result) return;
|
|
121
|
+
const [path, config] = result;
|
|
122
|
+
if (!config) return;
|
|
123
|
+
yield [config, path];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const scriptExtNames = [
|
|
127
|
+
".mjs",
|
|
128
|
+
".mts",
|
|
129
|
+
".cjs",
|
|
130
|
+
".cts",
|
|
131
|
+
".js",
|
|
132
|
+
".ts"
|
|
133
|
+
];
|
|
134
|
+
/**
|
|
135
|
+
* @template {object} T
|
|
136
|
+
* @param {string} root
|
|
137
|
+
* @param {string | string[]} name
|
|
138
|
+
* @param {(config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>} preprocess
|
|
139
|
+
* @param {'script' | 'data'} [type]
|
|
140
|
+
* @returns {AsyncIterableIterator<T>}
|
|
141
|
+
*/
|
|
142
|
+
async function* loadByPreprocess(root, name, preprocess, type) {
|
|
143
|
+
for await (const [config, path] of loadProfileAndPaths(root, name, type)) {
|
|
144
|
+
const basePath = pathFn.dirname(path);
|
|
145
|
+
yield* preprocess(config, path, async (path) => {
|
|
146
|
+
const index = path.indexOf("#");
|
|
147
|
+
const file = index < 0 ? path : path.slice(0, index);
|
|
148
|
+
let resolvePath = pathFn.resolve(basePath, file);
|
|
149
|
+
if (!scriptExtNames.includes(pathFn.extname(resolvePath))) for (const ext of scriptExtNames) {
|
|
150
|
+
const resolvePathWithExt = resolvePath + ext;
|
|
151
|
+
if (await fsPromises.stat(resolvePathWithExt).then((s) => s.isFile(), () => false)) {
|
|
152
|
+
resolvePath = resolvePathWithExt;
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return import(resolvePath).then((mod) => {
|
|
157
|
+
const key = index < 0 ? "" : path.slice(index + 1);
|
|
158
|
+
let val = mod;
|
|
159
|
+
for (const k of key.split(".").filter(Boolean)) {
|
|
160
|
+
if (!val || typeof val !== "object") return;
|
|
161
|
+
if (!Object.hasOwn(val, k)) return;
|
|
162
|
+
val = val[k];
|
|
163
|
+
}
|
|
164
|
+
return val;
|
|
165
|
+
}, (e) => {
|
|
166
|
+
console.error(e);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* @template {object} T
|
|
173
|
+
* @overload
|
|
174
|
+
* @param {string} root
|
|
175
|
+
* @param {string | string[]} name
|
|
176
|
+
* @param {'script' | 'data'} [type]
|
|
177
|
+
* @returns {AsyncIterableIterator<[config: T, path: string]>}
|
|
178
|
+
*/
|
|
179
|
+
/**
|
|
180
|
+
* @template {object} T
|
|
181
|
+
* @overload
|
|
182
|
+
* @param {string} root
|
|
183
|
+
* @param {string | string[]} name
|
|
184
|
+
* @param {(config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>} preprocess
|
|
185
|
+
* @param {'script' | 'data'} [type]
|
|
186
|
+
* @returns {AsyncIterableIterator<T>}
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* @template {object} T
|
|
190
|
+
* @param {string} root
|
|
191
|
+
* @param {string | string[]} name
|
|
192
|
+
* @param {((config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>) | 'script' | 'data'} [preprocess]
|
|
193
|
+
* @param {'script' | 'data'} [type]
|
|
194
|
+
* @returns {AsyncIterableIterator<[config: T, path: string] | T>}
|
|
195
|
+
*/
|
|
196
|
+
function loadProfiles(root, name, preprocess, type) {
|
|
197
|
+
if (typeof preprocess === "function") return loadByPreprocess(root, name, preprocess, type);
|
|
198
|
+
return loadProfileAndPaths(root, name, preprocess);
|
|
199
|
+
}
|
|
109
200
|
|
|
110
201
|
//#endregion
|
|
111
|
-
export { loadConfiguration as default, loadConfigurationWithPath };
|
|
202
|
+
export { loadConfiguration as default, loadConfigurationWithPath, loadProfiles };
|
|
112
203
|
//# sourceMappingURL=index.mjs.map
|
package/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../cli/load-configuration/index.mjs"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport * as pathFn from 'node:path';\nimport * as yaml from 'yaml';\nimport * as toml from 'smol-toml';\n\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadToml(path) {\n\t/** @type {any} */\n\tconst value = toml.parse(await fsPromises.readFile(path, 'utf-8'));\n\treturn value;\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadYaml(path) {\n\treturn yaml.parse(await fsPromises.readFile(path, 'utf-8'));\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadJson(path) {\n\treturn JSON.parse(await fsPromises.readFile(path, 'utf-8'));\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nfunction loadMjs(path) {\n\treturn import(path).then(v => {\n\t\tif ('default' in v) { return v.default; }\n\t\treturn v;\n\t});\n}\n/** @type {[string, <T>(path: string) => Promise<T | null>, script?: boolean][]} */\nconst loaders = [\n\t['.mjs', loadMjs, true],\n\t['.mts', loadMjs, true],\n\t['.json', loadJson],\n\t['.yml', loadYaml],\n\t['.yaml', loadYaml],\n\t['.toml', loadToml],\n];\n\nconst scriptExts = new Set(loaders.filter(v => v[2]).map(v => v[0]));\nconst dataExts = new Set(loaders.filter(v => !v[2]).map(v => v[0]));\nconst allExts = new Set(loaders.map(v => v[0]));\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<[path: string, loader: <T>(path: string) => Promise<T | null>] | null>}\n */\nasync function find(path, type) {\n\tconst exts = type === 'script' ? scriptExts : type === 'data' ? dataExts : allExts;\n\tconst stat = await fsPromises.stat(path).catch(() => null);\n\tconst ext = stat?.isFile() ? pathFn.extname(path).toLowerCase() : '';\n\tlet loader = loaders.find(v => v[0] === ext);\n\tlet loaderFn = loader && (exts.has(loader[0])) && loader[1];\n\tif (loaderFn) { return [path, loaderFn]; }\n\tfor (const [e, l, script] of loaders) {\n\t\tif (!exts.has(e)) { continue; }\n\t\tconst p = path + e;\n\t\tconst stat = await fsPromises.stat(p).catch(() => null);\n\t\tif (stat?.isFile()) {\n\t\t\treturn [p, l];\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<[string, T | null] | null>}\n */\nexport async function loadConfigurationWithPath(path, type) {\n\tconst result = await find(path, type);\n\tif (!result) { return null; }\n\tconst [filepath, loader] = result;\n\treturn Promise.all([\n\t\tfsPromises.realpath(filepath),\n\t\tloader(filepath).then(v => typeof v === 'object' ? v : null),\n\t]);\n}\n\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<T | null>}\n */\nexport default async function loadConfiguration(path, type) {\n\tconst result = await find(path, type);\n\tif (!result) { return null; }\n\tconst [filepath, loader] = result;\n\treturn loader(filepath).then(v => typeof v === 'object' ? v : null);\n}\n"],"mappings":";;;;;;;;;;;;AAWA,eAAe,SAAS,MAAM;AAG7B,QADc,KAAK,MAAM,MAAM,WAAW,SAAS,MAAM,QAAQ,CAAC;;;;;;;;AASnE,eAAe,SAAS,MAAM;AAC7B,QAAO,KAAK,MAAM,MAAM,WAAW,SAAS,MAAM,QAAQ,CAAC;;;;;;;;AAQ5D,eAAe,SAAS,MAAM;AAC7B,QAAO,KAAK,MAAM,MAAM,WAAW,SAAS,MAAM,QAAQ,CAAC;;;;;;;;AAQ5D,SAAS,QAAQ,MAAM;AACtB,QAAO,OAAO,MAAM,MAAK,MAAK;AAC7B,MAAI,aAAa,EAAK,QAAO,EAAE;AAC/B,SAAO;GACN;;;AAGH,MAAM,UAAU;CACf;EAAC;EAAQ;EAAS;EAAK;CACvB;EAAC;EAAQ;EAAS;EAAK;CACvB,CAAC,SAAS,SAAS;CACnB,CAAC,QAAQ,SAAS;CAClB,CAAC,SAAS,SAAS;CACnB,CAAC,SAAS,SAAS;CACnB;AAED,MAAM,aAAa,IAAI,IAAI,QAAQ,QAAO,MAAK,EAAE,GAAG,CAAC,KAAI,MAAK,EAAE,GAAG,CAAC;AACpE,MAAM,WAAW,IAAI,IAAI,QAAQ,QAAO,MAAK,CAAC,EAAE,GAAG,CAAC,KAAI,MAAK,EAAE,GAAG,CAAC;AACnE,MAAM,UAAU,IAAI,IAAI,QAAQ,KAAI,MAAK,EAAE,GAAG,CAAC;;;;;;;AAO/C,eAAe,KAAK,MAAM,MAAM;CAC/B,MAAM,OAAO,SAAS,WAAW,aAAa,SAAS,SAAS,WAAW;CAE3E,MAAM,OADO,MAAM,WAAW,KAAK,KAAK,CAAC,YAAY,KAAK,GACxC,QAAQ,GAAG,OAAO,QAAQ,KAAK,CAAC,aAAa,GAAG;CAClE,IAAI,SAAS,QAAQ,MAAK,MAAK,EAAE,OAAO,IAAI;CAC5C,IAAI,WAAW,UAAW,KAAK,IAAI,OAAO,GAAG,IAAK,OAAO;AACzD,KAAI,SAAY,QAAO,CAAC,MAAM,SAAS;AACvC,MAAK,MAAM,CAAC,GAAG,GAAG,WAAW,SAAS;AACrC,MAAI,CAAC,KAAK,IAAI,EAAE,CAAI;EACpB,MAAM,IAAI,OAAO;AAEjB,OADa,MAAM,WAAW,KAAK,EAAE,CAAC,YAAY,KAAK,GAC7C,QAAQ,CACjB,QAAO,CAAC,GAAG,EAAE;;AAGf,QAAO;;;;;;;;AASR,eAAsB,0BAA0B,MAAM,MAAM;CAC3D,MAAM,SAAS,MAAM,KAAK,MAAM,KAAK;AACrC,KAAI,CAAC,OAAU,QAAO;CACtB,MAAM,CAAC,UAAU,UAAU;AAC3B,QAAO,QAAQ,IAAI,CAClB,WAAW,SAAS,SAAS,EAC7B,OAAO,SAAS,CAAC,MAAK,MAAK,OAAO,MAAM,WAAW,IAAI,KAAK,CAC5D,CAAC;;;;;;;;AASH,eAA8B,kBAAkB,MAAM,MAAM;CAC3D,MAAM,SAAS,MAAM,KAAK,MAAM,KAAK;AACrC,KAAI,CAAC,OAAU,QAAO;CACtB,MAAM,CAAC,UAAU,UAAU;AAC3B,QAAO,OAAO,SAAS,CAAC,MAAK,MAAK,OAAO,MAAM,WAAW,IAAI,KAAK"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../cli/load-configuration/index.mjs"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport * as pathFn from 'node:path';\nimport * as yaml from 'yaml';\nimport * as toml from 'smol-toml';\n\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadToml(path) {\n\t/** @type {any} */\n\tconst value = toml.parse(await fsPromises.readFile(path, 'utf-8'));\n\treturn value;\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadYaml(path) {\n\treturn yaml.parse(await fsPromises.readFile(path, 'utf-8'));\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nasync function loadJson(path) {\n\treturn JSON.parse(await fsPromises.readFile(path, 'utf-8'));\n}\n/**\n * \n * @template T\n * @param {string} path\n * @returns {Promise<T>}\n */\nfunction loadMjs(path) {\n\treturn import(path).then(v => {\n\t\tif ('default' in v) { return v.default; }\n\t\treturn v;\n\t});\n}\n/** @type {[string, <T>(path: string) => Promise<T | null>, script?: boolean][]} */\nconst loaders = [\n\t['.mjs', loadMjs, true],\n\t['.mts', loadMjs, true],\n\t['.json', loadJson],\n\t['.yml', loadYaml],\n\t['.yaml', loadYaml],\n\t['.toml', loadToml],\n];\n\nconst scriptExts = new Set(loaders.filter(v => v[2]).map(v => v[0]));\nconst dataExts = new Set(loaders.filter(v => !v[2]).map(v => v[0]));\nconst allExts = new Set(loaders.map(v => v[0]));\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<[path: string, loader: <T>(path: string) => Promise<T | null>] | null>}\n */\nasync function find(path, type) {\n\tconst exts = type === 'script' ? scriptExts : type === 'data' ? dataExts : allExts;\n\tconst stat = await fsPromises.stat(path).catch(() => null);\n\tconst ext = stat?.isFile() ? pathFn.extname(path).toLowerCase() : '';\n\tlet loader = loaders.find(v => v[0] === ext);\n\tlet loaderFn = loader && (exts.has(loader[0])) && loader[1];\n\tif (loaderFn) { return [path, loaderFn]; }\n\tfor (const [e, l, script] of loaders) {\n\t\tif (!exts.has(e)) { continue; }\n\t\tconst p = path + e;\n\t\tconst stat = await fsPromises.stat(p).catch(() => null);\n\t\tif (stat?.isFile()) {\n\t\t\treturn [p, l];\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<[string, T | null] | null>}\n */\nexport async function loadConfigurationWithPath(path, type) {\n\tconst result = await find(path, type);\n\tif (!result) { return null; }\n\tconst [filepath, loader] = result;\n\treturn Promise.all([\n\t\tfsPromises.realpath(filepath),\n\t\tloader(filepath).then(v => typeof v === 'object' ? v : null),\n\t]);\n}\n\n/**\n * @template {object} T\n * @param {string} path \n * @param {'script' | 'data'} [type] \n * @returns {Promise<T | null>}\n */\nexport default async function loadConfiguration(path, type) {\n\tconst result = await find(path, type);\n\tif (!result) { return null; }\n\tconst [filepath, loader] = result;\n\treturn loader(filepath).then(v => typeof v === 'object' ? v : null);\n}\n\n\n\n\n\n\n\n/** \n * @template {object} T\n * @param {string} root\n * @param {string | string[]} name\n * @param {'script' | 'data'} [type] \n * @returns {AsyncIterableIterator<[config: T, path: string]>}\n */\nasync function* loadProfileAndPaths(root, name, type) {\n\tfor (const n of [name].flat()) {\n\t\t/** @type {[string, T | null] | null} */\n\t\tconst result = await loadConfigurationWithPath(pathFn.resolve(root, `${n}.yongdall`), type)\n\t\t\t|| await loadConfigurationWithPath(pathFn.resolve(root, `yongdall/${n}`), type)\n\t\t\t|| await loadConfigurationWithPath(pathFn.resolve(root, `${n}/yongdall`), type);\n\t\tif (!result) { return; }\n\t\tconst [path, config] = result;\n\t\tif (!config) { return; }\n\t\tyield [config, path];\n\t}\n}\n\nconst scriptExtNames = ['.mjs', '.mts', '.cjs', '.cts', '.js', '.ts'];\n\n/** \n * @template {object} T\n * @param {string} root\n * @param {string | string[]} name\n * @param {(config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>} preprocess\n * @param {'script' | 'data'} [type] \n * @returns {AsyncIterableIterator<T>}\n */\nasync function* loadByPreprocess(root, name, preprocess, type) {\n\tfor await (const [config, path] of loadProfileAndPaths(root, name, type)) {\n\t\tconst basePath = pathFn.dirname(path);\n\t\tyield* preprocess(config, path, async path => {\n\t\t\tconst index = path.indexOf('#');\n\t\t\tconst file = index < 0 ? path : path.slice(0, index);\n\t\t\tlet resolvePath = pathFn.resolve(basePath, file);\n\t\t\tif (!scriptExtNames.includes(pathFn.extname(resolvePath))) {\n\t\t\t\tfor (const ext of scriptExtNames) {\n\t\t\t\t\tconst resolvePathWithExt = resolvePath + ext;\n\t\t\t\t\tif (await fsPromises.stat(resolvePathWithExt).then(s => s.isFile(), () => false)) {\n\t\t\t\t\t\tresolvePath = resolvePathWithExt;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn import(resolvePath).then(mod => {\n\t\t\t\tconst key = index < 0 ? '' : path.slice(index + 1);\n\t\t\t\tlet val = mod;\n\t\t\t\tfor (const k of key.split('.').filter(Boolean)) {\n\t\t\t\t\tif (!val || typeof val !== 'object') { return; }\n\t\t\t\t\tif (!Object.hasOwn(val, k)) { return; }\n\t\t\t\t\tval = val[k];\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t}, (e) => {\n\t\t\t\tconsole.error(e);\n\t\t\t});\n\t\t});\n\t}\n}\n\n\n/** \n * @template {object} T\n * @overload\n * @param {string} root\n * @param {string | string[]} name\n * @param {'script' | 'data'} [type] \n * @returns {AsyncIterableIterator<[config: T, path: string]>}\n */\n/** \n * @template {object} T\n * @overload\n * @param {string} root\n * @param {string | string[]} name\n * @param {(config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>} preprocess\n * @param {'script' | 'data'} [type] \n * @returns {AsyncIterableIterator<T>}\n */\n/** \n * @template {object} T\n * @param {string} root\n * @param {string | string[]} name\n * @param {((config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>) | 'script' | 'data'} [preprocess]\n * @param {'script' | 'data'} [type] \n * @returns {AsyncIterableIterator<[config: T, path: string] | T>}\n */\nexport function loadProfiles(root, name, preprocess, type) {\n\tif (typeof preprocess === 'function') {\n\t\treturn loadByPreprocess(root, name, preprocess, type);\n\t}\n\treturn loadProfileAndPaths(root, name, preprocess);\n}\n"],"mappings":"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"}
|