@yongdall/load-configuration 0.6.1 → 0.6.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/index.d.mts +11 -15
- package/index.mjs +91 -46
- package/index.mjs.map +1 -1
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
//#region cli/load-configuration/index.d.mts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
declare function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* @param {'script' | 'data'} [type]
|
|
13
|
-
* @returns {Promise<T | null>}
|
|
14
|
-
*/
|
|
15
|
-
declare function loadConfiguration<T extends object>(path: string, type?: "script" | "data"): Promise<T | null>;
|
|
2
|
+
declare function loadConfigurationWithPath<T extends object>(path: string, type?: 'script' | 'data'): Promise<[string, T | null] | null>;
|
|
3
|
+
declare function loadConfiguration<T extends object>(path: string, type?: 'script' | 'data'): Promise<T | null>;
|
|
4
|
+
interface ProfileFinder<T extends object = object> {
|
|
5
|
+
find?(data: T): Iterable<string> | AsyncIterable<string> | PromiseLike<Iterable<string> | AsyncIterable<string>>;
|
|
6
|
+
type?: 'script' | 'data';
|
|
7
|
+
}
|
|
8
|
+
declare function findProfiles(root: string, finders: Record<string, ProfileFinder>): AsyncGenerator<[path: string, ext?: string]>;
|
|
9
|
+
declare function loadProfiles<T extends object>(root: string | string[], name: string | string[], type?: 'script' | 'data'): AsyncIterableIterator<[config: T, path: string]>;
|
|
10
|
+
declare function loadProfiles<T extends object>(root: string | string[], name: string | string[], preprocess?: (config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>, type?: 'script' | 'data'): AsyncIterableIterator<T>;
|
|
11
|
+
declare function loadProfiles<T extends object>(root: string | string[], name: string | string[], preprocess?: ((config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>) | 'script' | 'data', type?: 'script' | 'data'): AsyncIterableIterator<[config: T, path: string] | T>;
|
|
16
12
|
//#endregion
|
|
17
|
-
export { loadConfiguration as default, loadConfigurationWithPath };
|
|
13
|
+
export { ProfileFinder, loadConfiguration as default, findProfiles, loadConfigurationWithPath, loadProfiles };
|
package/index.mjs
CHANGED
|
@@ -3,47 +3,23 @@ import * as pathFn from "node:path";
|
|
|
3
3
|
import * as yaml from "yaml";
|
|
4
4
|
import * as toml from "smol-toml";
|
|
5
5
|
|
|
6
|
-
//#region cli/load-configuration/index.
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
9
|
-
* @template T
|
|
10
|
-
* @param {string} path
|
|
11
|
-
* @returns {Promise<T>}
|
|
12
|
-
*/
|
|
6
|
+
//#region cli/load-configuration/index.mts
|
|
13
7
|
async function loadToml(path) {
|
|
14
8
|
return toml.parse(await fsPromises.readFile(path, "utf-8"));
|
|
15
9
|
}
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @template T
|
|
19
|
-
* @param {string} path
|
|
20
|
-
* @returns {Promise<T>}
|
|
21
|
-
*/
|
|
22
10
|
async function loadYaml(path) {
|
|
23
11
|
return yaml.parse(await fsPromises.readFile(path, "utf-8"));
|
|
24
12
|
}
|
|
25
|
-
/**
|
|
26
|
-
*
|
|
27
|
-
* @template T
|
|
28
|
-
* @param {string} path
|
|
29
|
-
* @returns {Promise<T>}
|
|
30
|
-
*/
|
|
31
13
|
async function loadJson(path) {
|
|
32
14
|
return JSON.parse(await fsPromises.readFile(path, "utf-8"));
|
|
33
15
|
}
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* @template T
|
|
37
|
-
* @param {string} path
|
|
38
|
-
* @returns {Promise<T>}
|
|
39
|
-
*/
|
|
40
16
|
function loadMjs(path) {
|
|
41
17
|
return import(path).then((v) => {
|
|
42
|
-
|
|
18
|
+
const keys = Object.keys(v);
|
|
19
|
+
if (keys.length === 1 && keys[0] === "default") return v.default;
|
|
43
20
|
return v;
|
|
44
21
|
});
|
|
45
22
|
}
|
|
46
|
-
/** @type {[string, <T>(path: string) => Promise<T | null>, script?: boolean][]} */
|
|
47
23
|
const loaders = [
|
|
48
24
|
[
|
|
49
25
|
".mjs",
|
|
@@ -63,12 +39,6 @@ const loaders = [
|
|
|
63
39
|
const scriptExts = new Set(loaders.filter((v) => v[2]).map((v) => v[0]));
|
|
64
40
|
const dataExts = new Set(loaders.filter((v) => !v[2]).map((v) => v[0]));
|
|
65
41
|
const allExts = new Set(loaders.map((v) => v[0]));
|
|
66
|
-
/**
|
|
67
|
-
* @template {object} T
|
|
68
|
-
* @param {string} path
|
|
69
|
-
* @param {'script' | 'data'} [type]
|
|
70
|
-
* @returns {Promise<[path: string, loader: <T>(path: string) => Promise<T | null>] | null>}
|
|
71
|
-
*/
|
|
72
42
|
async function find(path, type) {
|
|
73
43
|
const exts = type === "script" ? scriptExts : type === "data" ? dataExts : allExts;
|
|
74
44
|
const ext = (await fsPromises.stat(path).catch(() => null))?.isFile() ? pathFn.extname(path).toLowerCase() : "";
|
|
@@ -82,31 +52,106 @@ async function find(path, type) {
|
|
|
82
52
|
}
|
|
83
53
|
return null;
|
|
84
54
|
}
|
|
85
|
-
/**
|
|
86
|
-
* @template {object} T
|
|
87
|
-
* @param {string} path
|
|
88
|
-
* @param {'script' | 'data'} [type]
|
|
89
|
-
* @returns {Promise<[string, T | null] | null>}
|
|
90
|
-
*/
|
|
91
55
|
async function loadConfigurationWithPath(path, type) {
|
|
92
56
|
const result = await find(path, type);
|
|
93
57
|
if (!result) return null;
|
|
94
58
|
const [filepath, loader] = result;
|
|
95
59
|
return Promise.all([fsPromises.realpath(filepath), loader(filepath).then((v) => typeof v === "object" ? v : null)]);
|
|
96
60
|
}
|
|
97
|
-
/**
|
|
98
|
-
* @template {object} T
|
|
99
|
-
* @param {string} path
|
|
100
|
-
* @param {'script' | 'data'} [type]
|
|
101
|
-
* @returns {Promise<T | null>}
|
|
102
|
-
*/
|
|
103
61
|
async function loadConfiguration(path, type) {
|
|
104
62
|
const result = await find(path, type);
|
|
105
63
|
if (!result) return null;
|
|
106
64
|
const [filepath, loader] = result;
|
|
107
65
|
return loader(filepath).then((v) => typeof v === "object" ? v : null);
|
|
108
66
|
}
|
|
67
|
+
async function* loadProfileAndPaths(root, name, type) {
|
|
68
|
+
for (const r of [root].flat()) for (const n of [name].flat()) {
|
|
69
|
+
const result = await loadConfigurationWithPath(pathFn.resolve(r, `${n}.yongdall`), type) || await loadConfigurationWithPath(pathFn.resolve(r, `yongdall/${n}`), type) || await loadConfigurationWithPath(pathFn.resolve(r, `${n}/yongdall`), type);
|
|
70
|
+
if (!result) continue;
|
|
71
|
+
const [path, config] = result;
|
|
72
|
+
if (!config) continue;
|
|
73
|
+
yield [config, path];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const mergedPattern = "{*/yongdall,yongdall/*,*.yongdall}.{mjs,mts,yml,yaml,json,toml}";
|
|
77
|
+
async function* findProfiles(root, finders) {
|
|
78
|
+
for await (const file of fsPromises.glob(mergedPattern, { cwd: root })) {
|
|
79
|
+
if (!await fsPromises.stat(pathFn.join(root, file)).then((s) => s.isFile(), () => false)) continue;
|
|
80
|
+
const ext = pathFn.extname(file);
|
|
81
|
+
const filename = file.slice(0, -ext.length);
|
|
82
|
+
const dir = pathFn.dirname(filename) || ".";
|
|
83
|
+
const key = (dir === "." ? filename.slice(0, Math.max(filename.lastIndexOf("."), 0)) : dir === "yongdall" ? pathFn.basename(filename) : dir).replace(/@.*/, "");
|
|
84
|
+
const profile = Object.hasOwn(finders, key) ? finders[key] : null;
|
|
85
|
+
if (!profile) continue;
|
|
86
|
+
if (!(profile.type === "script" ? scriptExts : profile.type === "data" ? dataExts : allExts).has(ext)) continue;
|
|
87
|
+
if (scriptExts.has(ext)) yield [filename, ext];
|
|
88
|
+
else yield [file];
|
|
89
|
+
const find = profile.find;
|
|
90
|
+
if (typeof find !== "function") continue;
|
|
91
|
+
const loaderFn = loaders.find((v) => v[0] === ext)?.[1];
|
|
92
|
+
if (typeof loaderFn !== "function") continue;
|
|
93
|
+
const data = await loaderFn(pathFn.resolve(root, file));
|
|
94
|
+
if (!data || typeof data !== "object") continue;
|
|
95
|
+
for await (const file of await find(data)) {
|
|
96
|
+
if (!file) continue;
|
|
97
|
+
const path = pathFn.join(".", pathFn.join("/", dir, file));
|
|
98
|
+
if (!path || path[0] === "." || ["\\", "/"].includes(path[path.length - 1])) continue;
|
|
99
|
+
const ext = pathFn.extname(file);
|
|
100
|
+
if (scriptExts.has(ext)) {
|
|
101
|
+
yield [path.slice(0, -ext.length), ext];
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (scriptExtNames.includes(ext)) continue;
|
|
105
|
+
for (const ext of scriptExts) {
|
|
106
|
+
if (!await fsPromises.stat(pathFn.join(root, path + ext)).then((s) => s.isFile(), () => false)) continue;
|
|
107
|
+
yield [path, ext];
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const scriptExtNames = [
|
|
114
|
+
".mjs",
|
|
115
|
+
".mts",
|
|
116
|
+
".cjs",
|
|
117
|
+
".cts",
|
|
118
|
+
".js",
|
|
119
|
+
".ts"
|
|
120
|
+
];
|
|
121
|
+
async function* loadByPreprocess(root, name, preprocess, type) {
|
|
122
|
+
for await (const [config, path] of loadProfileAndPaths(root, name, type)) {
|
|
123
|
+
const basePath = pathFn.dirname(path);
|
|
124
|
+
yield* preprocess(config, path, async (path) => {
|
|
125
|
+
const index = path.indexOf("#");
|
|
126
|
+
const file = index < 0 ? path : path.slice(0, index);
|
|
127
|
+
let resolvePath = pathFn.resolve(basePath, file);
|
|
128
|
+
if (!scriptExtNames.includes(pathFn.extname(resolvePath))) for (const ext of scriptExtNames) {
|
|
129
|
+
const resolvePathWithExt = resolvePath + ext;
|
|
130
|
+
if (await fsPromises.stat(resolvePathWithExt).then((s) => s.isFile(), () => false)) {
|
|
131
|
+
resolvePath = resolvePathWithExt;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return import(resolvePath).then((mod) => {
|
|
136
|
+
const key = index < 0 ? "" : path.slice(index + 1);
|
|
137
|
+
let val = mod;
|
|
138
|
+
for (const k of key.split(".").filter(Boolean)) {
|
|
139
|
+
if (!val || typeof val !== "object") return;
|
|
140
|
+
if (!Object.hasOwn(val, k)) return;
|
|
141
|
+
val = val[k];
|
|
142
|
+
}
|
|
143
|
+
return val;
|
|
144
|
+
}, (e) => {
|
|
145
|
+
console.error(e);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function loadProfiles(root, name, preprocess, type) {
|
|
151
|
+
if (typeof preprocess === "function") return loadByPreprocess(root, name, preprocess, type);
|
|
152
|
+
return loadProfileAndPaths(root, name, preprocess);
|
|
153
|
+
}
|
|
109
154
|
|
|
110
155
|
//#endregion
|
|
111
|
-
export { loadConfiguration as default, loadConfigurationWithPath };
|
|
156
|
+
export { loadConfiguration as default, findProfiles, loadConfigurationWithPath, loadProfiles };
|
|
112
157
|
//# 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.mts"],"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\nasync function loadToml<T>(path: string): Promise<T> {\n\tconst value: any = toml.parse(await fsPromises.readFile(path, 'utf-8'));\n\treturn value;\n}\nasync function loadYaml<T>(path: string): Promise<T> {\n\treturn yaml.parse(await fsPromises.readFile(path, 'utf-8'));\n}\nasync function loadJson<T>(path: string): Promise<T> {\n\treturn JSON.parse(await fsPromises.readFile(path, 'utf-8'));\n}\n\nfunction loadMjs<T>(path: string): Promise<T> {\n\treturn import(path).then(v => {\n\t\tconst keys = Object.keys(v);\n\t\tif (keys.length === 1 && keys[0] === 'default') { return v.default; }\n\t\treturn v;\n\t});\n}\nconst loaders: [string, <T>(path: string) => Promise<T | null>, script?: boolean][] = [\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\nasync function find<T extends object>(\n\tpath: string,\n\ttype?: 'script' | 'data',\n): Promise<[path: string, loader: <T>(path: string) => Promise<T | null>] | null> {\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\nexport async function loadConfigurationWithPath<T extends object>(\n\tpath: string,\n\ttype?: 'script' | 'data',\n): Promise<[string, T | null] | null> {\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<T>(filepath).then(v => typeof v === 'object' ? v : null),\n\t]);\n}\n\nexport default async function loadConfiguration<T extends object>(\n\tpath: string,\n\ttype?: 'script' | 'data',\n): Promise<T | null> {\n\tconst result = await find(path, type);\n\tif (!result) { return null; }\n\tconst [filepath, loader] = result;\n\treturn loader<T>(filepath).then(v => typeof v === 'object' ? v : null);\n}\n\n\n\n\n\n\nasync function* loadProfileAndPaths<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<[config: T, path: string]> {\n\tfor (const r of [root].flat()) {\n\t\tfor (const n of [name].flat()) {\n\t\t\tconst result: [string, T | null] | null\n\t\t\t\t= await loadConfigurationWithPath(pathFn.resolve(r, `${n}.yongdall`), type)\n\t\t\t\t|| await loadConfigurationWithPath(pathFn.resolve(r, `yongdall/${n}`), type)\n\t\t\t\t|| await loadConfigurationWithPath(pathFn.resolve(r, `${n}/yongdall`), type);\n\t\t\tif (!result) { continue; }\n\t\t\tconst [path, config] = result;\n\t\t\tif (!config) { continue; }\n\t\t\tyield [config, path];\n\t\t}\n\t}\n}\nconst mergedPattern = '{*/yongdall,yongdall/*,*.yongdall}.{mjs,mts,yml,yaml,json,toml}';\n\n\nexport interface ProfileFinder<T extends object = object> {\n\tfind?(data: T): Iterable<string> | AsyncIterable<string> | PromiseLike<Iterable<string> | AsyncIterable<string>>;\n\ttype?: 'script' | 'data';\n}\nexport async function* findProfiles(\n\troot: string,\n\tfinders: Record<string, ProfileFinder>,\n): AsyncGenerator<[path: string, ext?: string]> {\n\tfor await (const file of fsPromises.glob(mergedPattern, { cwd: root })) {\n\t\tif (!await fsPromises.stat(pathFn.join(root, file)).then(s => s.isFile(), () => false)) { continue; }\n\t\tconst ext = pathFn.extname(file);\n\t\tconst filename = file.slice(0, -ext.length);\n\t\tconst dir = pathFn.dirname(filename) || '.';\n\t\tconst name = dir === '.'\n\t\t\t? filename.slice(0, Math.max(filename.lastIndexOf('.'), 0))\n\t\t\t: dir === 'yongdall' ? pathFn.basename(filename) : dir;\n\t\tconst key = name.replace(/@.*/, '');\n\t\tconst profile = Object.hasOwn(finders, key) ? finders[key] : null;\n\t\tif (!profile) { continue; }\n\n\t\tconst exts = profile.type === 'script' ? scriptExts : profile.type === 'data' ? dataExts : allExts;\n\t\tif (!exts.has(ext)) { continue; }\n\t\tif (scriptExts.has(ext)) {\n\t\t\tyield [filename, ext];\n\t\t} else {\n\t\t\tyield [file];\n\t\t}\n\t\tconst find = profile.find;\n\t\tif (typeof find !== 'function') { continue; }\n\t\tconst loaderFn = loaders.find(v => v[0] === ext)?.[1];\n\t\tif (typeof loaderFn !== 'function') { continue; }\n\t\tconst data = await loaderFn(pathFn.resolve(root, file));\n\t\tif (!data || typeof data !== 'object') { continue; }\n\n\t\tfor await (const file of await find(data)) {\n\t\t\tif (!file) { continue; }\n\t\t\tconst path = pathFn.join('.', pathFn.join('/', dir, file));\n\t\t\tif (!path || path[0] === '.' || ['\\\\', '/'].includes(path[path.length - 1])) { continue }\n\t\t\tconst ext = pathFn.extname(file);\n\t\t\tif (scriptExts.has(ext)) {\n\t\t\t\tyield [path.slice(0, -ext.length), ext];\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (scriptExtNames.includes(ext)) { continue; }\n\t\t\tfor (const ext of scriptExts) {\n\t\t\t\tif (!await fsPromises.stat(pathFn.join(root, path + ext)).then(s => s.isFile(), () => false)) { continue; }\n\t\t\t\tyield [path, ext];\n\t\t\t\tbreak;\n\n\t\t\t}\n\t\t}\n\t}\n}\n\nconst scriptExtNames = ['.mjs', '.mts', '.cjs', '.cts', '.js', '.ts'];\n\nasync function* loadByPreprocess<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\tpreprocess: (config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>,\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<T> {\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\nexport function loadProfiles<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<[config: T, path: string]>\nexport function loadProfiles<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\tpreprocess?: (config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>,\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<T>\n\nexport function loadProfiles<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\tpreprocess?: ((config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>) | 'script' | 'data',\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<[config: T, path: string] | T>\nexport function loadProfiles<T extends object>(\n\troot: string | string[],\n\tname: string | string[],\n\tpreprocess?: ((config: any, path: string, load: (path: string) => Promise<any>) => Iterable<T> | AsyncIterable<T>) | 'script' | 'data',\n\ttype?: 'script' | 'data',\n): AsyncIterableIterator<[config: T, path: string] | T> {\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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"}
|