locter 2.2.0 → 3.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 +188 -6
- package/dist/index.d.mts +244 -0
- package/dist/index.mjs +688 -672
- package/dist/index.mjs.map +1 -1
- package/package.json +28 -35
- package/dist/index.cjs +0 -743
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/loader/built-in/conf/index.d.ts +0 -1
- package/dist/loader/built-in/conf/module.d.ts +0 -6
- package/dist/loader/built-in/index.d.ts +0 -3
- package/dist/loader/built-in/json/index.d.ts +0 -1
- package/dist/loader/built-in/json/module.d.ts +0 -5
- package/dist/loader/built-in/module/index.d.ts +0 -3
- package/dist/loader/built-in/module/module.d.ts +0 -15
- package/dist/loader/built-in/module/type.d.ts +0 -8
- package/dist/loader/built-in/module/utils.d.ts +0 -9
- package/dist/loader/built-in/yaml/index.d.ts +0 -1
- package/dist/loader/built-in/yaml/module.d.ts +0 -5
- package/dist/loader/constants.d.ts +0 -6
- package/dist/loader/helpers.d.ts +0 -6
- package/dist/loader/index.d.ts +0 -3
- package/dist/loader/module.d.ts +0 -18
- package/dist/loader/singleton.d.ts +0 -2
- package/dist/loader/type.d.ts +0 -8
- package/dist/locator/async.d.ts +0 -3
- package/dist/locator/index.d.ts +0 -4
- package/dist/locator/sync.d.ts +0 -3
- package/dist/locator/types.d.ts +0 -15
- package/dist/locator/utils.d.ts +0 -7
- package/dist/utils/error.d.ts +0 -1
- package/dist/utils/file-name.d.ts +0 -2
- package/dist/utils/file-path.d.ts +0 -1
- package/dist/utils/has-property.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/object.d.ts +0 -2
- package/dist/utils/runtime.d.ts +0 -2
- package/dist/utils/to-array.d.ts +0 -1
- package/dist/utils/typescript.d.ts +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,718 +1,734 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { BaseError, hasInstanceof, markInstanceof } from "@ebec/core";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { destr } from "destr";
|
|
5
|
+
import { unflatten } from "flat";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import fg from "fast-glob";
|
|
8
|
+
import { createJiti } from "jiti";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
import { parse } from "yaml";
|
|
11
|
+
//#region src/errors/base.ts
|
|
12
|
+
const LOCTER_ERROR_MARKER = Symbol.for("@locter/error");
|
|
13
|
+
var LocterError = class extends BaseError {
|
|
14
|
+
static [Symbol.hasInstance](input) {
|
|
15
|
+
return hasInstanceof(input, LOCTER_ERROR_MARKER);
|
|
16
|
+
}
|
|
17
|
+
path;
|
|
18
|
+
constructor(input = {}) {
|
|
19
|
+
if (typeof input === "string") super(input);
|
|
20
|
+
else {
|
|
21
|
+
const { path, ...rest } = input;
|
|
22
|
+
super(rest);
|
|
23
|
+
this.path = path;
|
|
24
|
+
}
|
|
25
|
+
markInstanceof(this, LOCTER_ERROR_MARKER);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/errors/load.ts
|
|
30
|
+
const LOCTER_LOAD_ERROR_MARKER = Symbol.for("@locter/load-error");
|
|
31
|
+
var LocterLoadError = class extends LocterError {
|
|
32
|
+
static [Symbol.hasInstance](input) {
|
|
33
|
+
return hasInstanceof(input, LOCTER_LOAD_ERROR_MARKER);
|
|
34
|
+
}
|
|
35
|
+
constructor(input = {}) {
|
|
36
|
+
super(input);
|
|
37
|
+
markInstanceof(this, LOCTER_LOAD_ERROR_MARKER);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/errors/not-found.ts
|
|
42
|
+
const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for("@locter/not-found-error");
|
|
43
|
+
var LocterNotFoundError = class extends LocterError {
|
|
44
|
+
static [Symbol.hasInstance](input) {
|
|
45
|
+
return hasInstanceof(input, LOCTER_NOT_FOUND_ERROR_MARKER);
|
|
46
|
+
}
|
|
47
|
+
constructor(input = {}) {
|
|
48
|
+
super(input);
|
|
49
|
+
markInstanceof(this, LOCTER_NOT_FOUND_ERROR_MARKER);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/errors/unknown-extension.ts
|
|
54
|
+
const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for("@locter/unknown-extension-error");
|
|
55
|
+
var LocterUnknownExtensionError = class extends LocterError {
|
|
56
|
+
static [Symbol.hasInstance](input) {
|
|
57
|
+
return hasInstanceof(input, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);
|
|
58
|
+
}
|
|
59
|
+
constructor(input = {}) {
|
|
60
|
+
super(input);
|
|
61
|
+
markInstanceof(this, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/utils/file-name.ts
|
|
66
|
+
function getFileNameExtension(input, allowed) {
|
|
67
|
+
const extension = path.extname(input);
|
|
68
|
+
if (extension === "" || extension === ".") return;
|
|
69
|
+
if (typeof allowed === "undefined" || allowed.includes(extension)) return extension;
|
|
70
|
+
}
|
|
71
|
+
function removeFileNameExtension(input, extensions) {
|
|
72
|
+
const extension = getFileNameExtension(input, extensions);
|
|
73
|
+
if (extension) return input.substring(0, input.length - extension.length);
|
|
74
|
+
return input;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/utils/has-property.ts
|
|
19
78
|
function hasOwnProperty(obj, prop) {
|
|
20
|
-
|
|
79
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
21
80
|
}
|
|
22
81
|
function hasStringProperty(obj, prop) {
|
|
23
|
-
|
|
82
|
+
return hasOwnProperty(obj, prop) && typeof obj[prop] === "string";
|
|
24
83
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* For the full copyright and license information,
|
|
30
|
-
* view the LICENSE file that was distributed with this source code.
|
|
31
|
-
*/ function isObject(item) {
|
|
32
|
-
return !!item && typeof item === 'object' && !Array.isArray(item);
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/utils/object.ts
|
|
86
|
+
function isObject(item) {
|
|
87
|
+
return !!item && typeof item === "object" && !Array.isArray(item);
|
|
33
88
|
}
|
|
34
89
|
function isSafeObjectKey(key) {
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function handleException(e) {
|
|
39
|
-
if (e instanceof Error) {
|
|
40
|
-
throw e;
|
|
41
|
-
}
|
|
42
|
-
const error = new Error('Can not process thrown exception.');
|
|
43
|
-
if (isObject(e)) {
|
|
44
|
-
if (hasOwnProperty(e, 'message') && typeof e.message === 'string') {
|
|
45
|
-
error.message = e.message;
|
|
46
|
-
}
|
|
47
|
-
if (hasOwnProperty(e, 'stack') && typeof e.stack === 'string') {
|
|
48
|
-
error.stack = e.stack;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
throw error;
|
|
90
|
+
return key !== "__proto__" && key !== "prototype" && key !== "constructor";
|
|
52
91
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
if (typeof allowed === 'undefined' || allowed.indexOf(extension) !== -1) {
|
|
60
|
-
return extension;
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/utils/to-array.ts
|
|
94
|
+
function toArray(input) {
|
|
95
|
+
return Array.isArray(input) ? input : [input];
|
|
63
96
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (extension) {
|
|
67
|
-
return input.substring(0, input.length - extension.length);
|
|
68
|
-
}
|
|
69
|
-
return input;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/*
|
|
73
|
-
* Copyright (c) 2022.
|
|
74
|
-
* Author Peter Placzek (tada5hi)
|
|
75
|
-
* For the full copyright and license information,
|
|
76
|
-
* view the LICENSE file that was distributed with this source code.
|
|
77
|
-
*/ function toArray(input) {
|
|
78
|
-
return Array.isArray(input) ? input : [
|
|
79
|
-
input
|
|
80
|
-
];
|
|
81
|
-
}
|
|
82
|
-
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/utils/file-path.ts
|
|
83
99
|
function isFilePath(input) {
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
const extension = path.extname(input);
|
|
101
|
+
return extension && extension !== "";
|
|
86
102
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return process.env && process.env.JEST_WORKER_ID !== undefined;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/utils/runtime.ts
|
|
105
|
+
function isJestRuntimeEnvironment() {
|
|
106
|
+
return process.env && process.env.JEST_WORKER_ID !== void 0;
|
|
107
|
+
}
|
|
108
|
+
function isVitestRuntimeEnvironment() {
|
|
109
|
+
return typeof process !== "undefined" && process.env.VITEST === "true";
|
|
95
110
|
}
|
|
96
111
|
function isTsNodeRuntimeEnvironment() {
|
|
97
|
-
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
return !!process[Symbol.for('ts-node.register.instance')];
|
|
112
|
+
return !!process[Symbol.for("ts-node.register.instance")];
|
|
100
113
|
}
|
|
101
|
-
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/utils/typescript.ts
|
|
102
116
|
function isTypeScriptError(input) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
if (!isObject(input)) return false;
|
|
118
|
+
if (typeof input.diagnosticCodes !== "undefined") return true;
|
|
119
|
+
return typeof input.message === "string" && /TS\d+/.test(input.message);
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/errors/wrap.ts
|
|
123
|
+
const NOT_FOUND_CODES = new Set([
|
|
124
|
+
"ENOENT",
|
|
125
|
+
"MODULE_NOT_FOUND",
|
|
126
|
+
"ERR_MODULE_NOT_FOUND"
|
|
127
|
+
]);
|
|
128
|
+
function wrapLoaderError(input, path) {
|
|
129
|
+
if (input instanceof LocterError) return input;
|
|
130
|
+
const code = isObject(input) && hasStringProperty(input, "code") ? input.code : void 0;
|
|
131
|
+
const message = isObject(input) && hasStringProperty(input, "message") ? input.message : `Failed to load: ${path}`;
|
|
132
|
+
if (code && NOT_FOUND_CODES.has(code)) return new LocterNotFoundError({
|
|
133
|
+
message,
|
|
134
|
+
code,
|
|
135
|
+
cause: input,
|
|
136
|
+
path
|
|
137
|
+
});
|
|
138
|
+
return new LocterLoadError({
|
|
139
|
+
message,
|
|
140
|
+
code,
|
|
141
|
+
cause: input,
|
|
142
|
+
path
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/locator/utils.ts
|
|
112
147
|
function buildLocatorPatterns(pattern) {
|
|
113
|
-
|
|
114
|
-
pattern
|
|
115
|
-
];
|
|
148
|
+
return Array.isArray(pattern) ? pattern : [pattern];
|
|
116
149
|
}
|
|
117
150
|
function buildLocatorOptions(options = {}) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
};
|
|
151
|
+
const cwd = options.cwd ? toArray(options.cwd) : [];
|
|
152
|
+
const ignore = options.ignore ? toArray(options.ignore) : [];
|
|
153
|
+
if (cwd.length === 0) cwd.push(process.cwd());
|
|
154
|
+
let onlyFiles;
|
|
155
|
+
let onlyDirectories;
|
|
156
|
+
if (options.onlyDirectories === options.onlyFiles) {
|
|
157
|
+
onlyDirectories = false;
|
|
158
|
+
onlyFiles = !options.onlyDirectories;
|
|
159
|
+
} else if (typeof options.onlyFiles === "undefined") {
|
|
160
|
+
onlyDirectories = options.onlyDirectories ?? false;
|
|
161
|
+
onlyFiles = !options.onlyDirectories;
|
|
162
|
+
} else {
|
|
163
|
+
onlyFiles = options.onlyFiles ?? true;
|
|
164
|
+
onlyDirectories = !options.onlyFiles;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
cwd,
|
|
168
|
+
ignore,
|
|
169
|
+
onlyDirectories,
|
|
170
|
+
onlyFiles,
|
|
171
|
+
dot: options.dot ?? false
|
|
172
|
+
};
|
|
141
173
|
}
|
|
142
174
|
function pathToLocatorInfo(input, skipResolve) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
175
|
+
if (!skipResolve && !path.isAbsolute(input)) input = path.resolve(process.cwd(), input);
|
|
176
|
+
const info = path.parse(input);
|
|
177
|
+
const directory = info.dir.split("/").join(path.sep);
|
|
178
|
+
const extension = info.ext ? info.ext : void 0;
|
|
179
|
+
const filePath = extension ? path.join(directory, info.name) + extension : path.join(directory, info.name);
|
|
180
|
+
return {
|
|
181
|
+
directory,
|
|
182
|
+
name: info.name,
|
|
183
|
+
extension,
|
|
184
|
+
path: filePath
|
|
185
|
+
};
|
|
152
186
|
}
|
|
153
187
|
function isLocatorInfo(input) {
|
|
154
|
-
|
|
188
|
+
return isObject(input) && typeof input.directory === "string" && typeof input.name === "string" && (typeof input.extension === "undefined" || typeof input.extension === "string") && typeof input.path === "string";
|
|
155
189
|
}
|
|
156
190
|
function buildFilePath(input) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
if (input.extension) {
|
|
161
|
-
return path.join(input.path, input.name) + input.extension;
|
|
162
|
-
}
|
|
163
|
-
return path.join(input.path, input.name);
|
|
191
|
+
if (typeof input === "string") return input;
|
|
192
|
+
return input.path;
|
|
164
193
|
}
|
|
165
194
|
function buildFilePathWithoutExtension(input) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
info = input;
|
|
171
|
-
}
|
|
172
|
-
return path.join(info.path, info.name);
|
|
195
|
+
let info;
|
|
196
|
+
if (typeof input === "string") info = pathToLocatorInfo(input);
|
|
197
|
+
else info = input;
|
|
198
|
+
return path.join(info.directory, info.name);
|
|
173
199
|
}
|
|
174
|
-
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/locator/async.ts
|
|
175
202
|
async function locateMany(pattern, options) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return items;
|
|
203
|
+
const patterns = buildLocatorPatterns(pattern);
|
|
204
|
+
const opts = buildLocatorOptions(options);
|
|
205
|
+
const items = [];
|
|
206
|
+
for (const p of patterns) for (const cwd of opts.cwd) {
|
|
207
|
+
const files = await fg(p, {
|
|
208
|
+
absolute: true,
|
|
209
|
+
cwd,
|
|
210
|
+
ignore: opts.ignore,
|
|
211
|
+
onlyFiles: opts.onlyFiles,
|
|
212
|
+
onlyDirectories: opts.onlyDirectories,
|
|
213
|
+
dot: opts.dot
|
|
214
|
+
});
|
|
215
|
+
for (const file of files) items.push(pathToLocatorInfo(file, true));
|
|
216
|
+
}
|
|
217
|
+
return items;
|
|
194
218
|
}
|
|
195
219
|
async function locate(pattern, options) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
return undefined;
|
|
214
|
-
}
|
|
215
|
-
|
|
220
|
+
const patterns = buildLocatorPatterns(pattern);
|
|
221
|
+
const opts = buildLocatorOptions(options);
|
|
222
|
+
for (const p of patterns) for (const cwd of opts.cwd) {
|
|
223
|
+
const element = (await fg(p, {
|
|
224
|
+
absolute: true,
|
|
225
|
+
cwd,
|
|
226
|
+
ignore: opts.ignore,
|
|
227
|
+
onlyFiles: opts.onlyFiles,
|
|
228
|
+
onlyDirectories: opts.onlyDirectories,
|
|
229
|
+
dot: opts.dot
|
|
230
|
+
})).shift();
|
|
231
|
+
if (element) return pathToLocatorInfo(element, true);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/locator/sync.ts
|
|
216
236
|
function locateManySync(pattern, options) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return items;
|
|
237
|
+
const patterns = buildLocatorPatterns(pattern);
|
|
238
|
+
const opts = buildLocatorOptions(options);
|
|
239
|
+
const items = [];
|
|
240
|
+
for (const p of patterns) for (const cwd of opts.cwd) {
|
|
241
|
+
const files = fg.sync(p, {
|
|
242
|
+
absolute: true,
|
|
243
|
+
cwd,
|
|
244
|
+
ignore: opts.ignore,
|
|
245
|
+
onlyFiles: opts.onlyFiles,
|
|
246
|
+
onlyDirectories: opts.onlyDirectories,
|
|
247
|
+
dot: opts.dot
|
|
248
|
+
});
|
|
249
|
+
for (const file of files) items.push(pathToLocatorInfo(file, true));
|
|
250
|
+
}
|
|
251
|
+
return items;
|
|
235
252
|
}
|
|
236
253
|
function locateSync(pattern, options) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
|
|
254
|
+
const patterns = buildLocatorPatterns(pattern);
|
|
255
|
+
const opts = buildLocatorOptions(options);
|
|
256
|
+
for (const p of patterns) for (const cwd of opts.cwd) {
|
|
257
|
+
const element = fg.sync(p, {
|
|
258
|
+
absolute: true,
|
|
259
|
+
cwd,
|
|
260
|
+
ignore: opts.ignore,
|
|
261
|
+
onlyFiles: opts.onlyFiles,
|
|
262
|
+
onlyDirectories: opts.onlyDirectories,
|
|
263
|
+
dot: opts.dot
|
|
264
|
+
}).shift();
|
|
265
|
+
if (element) return pathToLocatorInfo(element, true);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/locator/up.ts
|
|
270
|
+
function startWalk(options) {
|
|
271
|
+
const { cwd, stopAt, ...baseOptions } = options;
|
|
272
|
+
const current = path.resolve(cwd ?? process.cwd());
|
|
273
|
+
return {
|
|
274
|
+
current,
|
|
275
|
+
stopAt: stopAt ? path.resolve(current, stopAt) : path.parse(current).root,
|
|
276
|
+
baseOptions
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function nextDirectory(current, stopAt) {
|
|
280
|
+
if (current === stopAt) return;
|
|
281
|
+
const parent = path.dirname(current);
|
|
282
|
+
if (parent === current) return;
|
|
283
|
+
return parent;
|
|
284
|
+
}
|
|
285
|
+
async function locateUp(pattern, options = {}) {
|
|
286
|
+
let walk = startWalk(options);
|
|
287
|
+
while (true) {
|
|
288
|
+
const found = await locate(pattern, {
|
|
289
|
+
...walk.baseOptions,
|
|
290
|
+
cwd: walk.current
|
|
291
|
+
});
|
|
292
|
+
if (found) return found;
|
|
293
|
+
const next = nextDirectory(walk.current, walk.stopAt);
|
|
294
|
+
if (!next) return;
|
|
295
|
+
walk = {
|
|
296
|
+
...walk,
|
|
297
|
+
current: next
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function locateUpSync(pattern, options = {}) {
|
|
302
|
+
let walk = startWalk(options);
|
|
303
|
+
while (true) {
|
|
304
|
+
const found = locateSync(pattern, {
|
|
305
|
+
...walk.baseOptions,
|
|
306
|
+
cwd: walk.current
|
|
307
|
+
});
|
|
308
|
+
if (found) return found;
|
|
309
|
+
const next = nextDirectory(walk.current, walk.stopAt);
|
|
310
|
+
if (!next) return;
|
|
311
|
+
walk = {
|
|
312
|
+
...walk,
|
|
313
|
+
current: next
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/loader/built-in/conf/module.ts
|
|
319
|
+
var ConfLoader = class {
|
|
320
|
+
async execute(input) {
|
|
321
|
+
const filePath = buildFilePath(input);
|
|
322
|
+
try {
|
|
323
|
+
const file = await fs.promises.readFile(filePath, { encoding: "utf-8" });
|
|
324
|
+
return this.parse(file);
|
|
325
|
+
} catch (e) {
|
|
326
|
+
throw wrapLoaderError(e, filePath);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
executeSync(input) {
|
|
330
|
+
const filePath = buildFilePath(input);
|
|
331
|
+
try {
|
|
332
|
+
const file = fs.readFileSync(filePath, { encoding: "utf-8" });
|
|
333
|
+
return this.parse(file);
|
|
334
|
+
} catch (e) {
|
|
335
|
+
throw wrapLoaderError(e, filePath);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
parse(contents) {
|
|
339
|
+
const config = {};
|
|
340
|
+
const lines = contents.split(/\n|\r|\r\n/);
|
|
341
|
+
for (const line of lines) {
|
|
342
|
+
const match = line.match(/^\s*([^\s=]+)\s*=\s*(.*)?\s*$/);
|
|
343
|
+
if (!match) continue;
|
|
344
|
+
const key = match[1];
|
|
345
|
+
const rawValue = match[2];
|
|
346
|
+
if (!key || !isSafeObjectKey(key)) continue;
|
|
347
|
+
const value = destr(rawValue ? rawValue.trim() : "");
|
|
348
|
+
if (key.endsWith("[]")) {
|
|
349
|
+
const arrKey = key.slice(0, Math.max(0, key.length - 2));
|
|
350
|
+
config[arrKey] = (config[arrKey] || []).concat(value);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
config[key] = value;
|
|
354
|
+
}
|
|
355
|
+
return unflatten(config, { overwrite: true });
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
//#endregion
|
|
359
|
+
//#region src/loader/built-in/json/module.ts
|
|
360
|
+
var JSONLoader = class {
|
|
361
|
+
async execute(input) {
|
|
362
|
+
const filePath = buildFilePath(input);
|
|
363
|
+
try {
|
|
364
|
+
const file = await fs.promises.readFile(filePath, { encoding: "utf-8" });
|
|
365
|
+
return JSON.parse(file);
|
|
366
|
+
} catch (e) {
|
|
367
|
+
throw wrapLoaderError(e, filePath);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
executeSync(input) {
|
|
371
|
+
const filePath = buildFilePath(input);
|
|
372
|
+
try {
|
|
373
|
+
const file = fs.readFileSync(filePath, { encoding: "utf-8" });
|
|
374
|
+
return JSON.parse(file);
|
|
375
|
+
} catch (e) {
|
|
376
|
+
throw wrapLoaderError(e, filePath);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
//#endregion
|
|
381
|
+
//#region src/loader/built-in/module/utils.ts
|
|
313
382
|
function isESModule(input) {
|
|
314
|
-
|
|
315
|
-
typeof input.__esModule !== 'undefined';
|
|
383
|
+
return isObject(input) && typeof input.__esModule !== "undefined";
|
|
316
384
|
}
|
|
317
|
-
// https://2ality.com/2017/01/babel-esm-spec-mode.html
|
|
318
385
|
function toModuleRecord(data) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
descriptor = {
|
|
347
|
-
enumerable: true,
|
|
348
|
-
get () {
|
|
349
|
-
return data[key];
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
Object.defineProperty(output, key, descriptor);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
if (!hasOwnProperty(output, 'default')) {
|
|
357
|
-
Object.defineProperty(output, 'default', {
|
|
358
|
-
value: data,
|
|
359
|
-
enumerable: true
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
return Object.freeze(output);
|
|
386
|
+
if (isESModule(data)) {
|
|
387
|
+
if (isESModule(data.default) && data.default.default) return {
|
|
388
|
+
...data,
|
|
389
|
+
default: data.default.default
|
|
390
|
+
};
|
|
391
|
+
return data;
|
|
392
|
+
}
|
|
393
|
+
const output = Object.create(null, {
|
|
394
|
+
__esModule: { value: true },
|
|
395
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
396
|
+
});
|
|
397
|
+
if (isObject(data)) for (const key in data) {
|
|
398
|
+
if (hasOwnProperty(output, key)) continue;
|
|
399
|
+
let descriptor = Object.getOwnPropertyDescriptor(data, key);
|
|
400
|
+
if (!descriptor || "get" in descriptor || descriptor.writable || descriptor.configurable) descriptor = {
|
|
401
|
+
enumerable: true,
|
|
402
|
+
get() {
|
|
403
|
+
return data[key];
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
Object.defineProperty(output, key, descriptor);
|
|
407
|
+
}
|
|
408
|
+
if (!hasOwnProperty(output, "default")) Object.defineProperty(output, "default", {
|
|
409
|
+
value: data,
|
|
410
|
+
enumerable: true
|
|
411
|
+
});
|
|
412
|
+
return Object.freeze(output);
|
|
363
413
|
}
|
|
364
414
|
function getModuleExport(data, filterFn) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
}
|
|
599
|
-
let loader;
|
|
600
|
-
// built-in
|
|
601
|
-
switch(id){
|
|
602
|
-
case LoaderId.CONF:
|
|
603
|
-
{
|
|
604
|
-
loader = new ConfLoader();
|
|
605
|
-
break;
|
|
606
|
-
}
|
|
607
|
-
case LoaderId.MODULE:
|
|
608
|
-
{
|
|
609
|
-
loader = new ModuleLoader();
|
|
610
|
-
break;
|
|
611
|
-
}
|
|
612
|
-
case LoaderId.JSON:
|
|
613
|
-
{
|
|
614
|
-
loader = new JSONLoader();
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
case LoaderId.YAML:
|
|
618
|
-
{
|
|
619
|
-
loader = new YAMLLoader();
|
|
620
|
-
break;
|
|
621
|
-
}
|
|
622
|
-
/* istanbul ignore next */ default:
|
|
623
|
-
{
|
|
624
|
-
const pluginPath = this.normalizePath(id);
|
|
625
|
-
const moduleLoader = this.resolve(LoaderId.MODULE);
|
|
626
|
-
loader = moduleLoader.executeSync(pluginPath);
|
|
627
|
-
break;
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
if (typeof loader !== 'undefined') {
|
|
631
|
-
this.loaders[id] = loader;
|
|
632
|
-
return loader;
|
|
633
|
-
}
|
|
634
|
-
throw new Error(`The loader ${id} could not be resolved.`);
|
|
635
|
-
}
|
|
636
|
-
/* istanbul ignore next */ normalizePath(input) {
|
|
637
|
-
if (path.isAbsolute(input) || input.startsWith('./')) {
|
|
638
|
-
return input;
|
|
639
|
-
}
|
|
640
|
-
if (input.startsWith('module:')) {
|
|
641
|
-
return input.substring(0, 'module:'.length);
|
|
642
|
-
}
|
|
643
|
-
if (!input.startsWith('@')) {
|
|
644
|
-
return `@locter/${input}`;
|
|
645
|
-
}
|
|
646
|
-
return input;
|
|
647
|
-
}
|
|
648
|
-
constructor(){
|
|
649
|
-
this.loaders = {};
|
|
650
|
-
this.rules = [
|
|
651
|
-
{
|
|
652
|
-
test: [
|
|
653
|
-
'.js',
|
|
654
|
-
'.mjs',
|
|
655
|
-
'.mts',
|
|
656
|
-
'.cjs',
|
|
657
|
-
'.cts',
|
|
658
|
-
'.ts'
|
|
659
|
-
],
|
|
660
|
-
loader: LoaderId.MODULE
|
|
661
|
-
},
|
|
662
|
-
{
|
|
663
|
-
test: [
|
|
664
|
-
'.conf'
|
|
665
|
-
],
|
|
666
|
-
loader: LoaderId.CONF
|
|
667
|
-
},
|
|
668
|
-
{
|
|
669
|
-
test: [
|
|
670
|
-
'.json'
|
|
671
|
-
],
|
|
672
|
-
loader: LoaderId.JSON
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
test: [
|
|
676
|
-
'.yml',
|
|
677
|
-
'.yaml'
|
|
678
|
-
],
|
|
679
|
-
loader: LoaderId.YAML
|
|
680
|
-
}
|
|
681
|
-
];
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
415
|
+
const keys = Object.keys(data);
|
|
416
|
+
for (const key of keys) if (filterFn(key, data[key])) return {
|
|
417
|
+
key,
|
|
418
|
+
value: data[key]
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
//#endregion
|
|
422
|
+
//#region src/loader/built-in/module/module.ts
|
|
423
|
+
const require = createRequire(import.meta.url);
|
|
424
|
+
function originalPath(data) {
|
|
425
|
+
return typeof data === "string" ? data : buildFilePath(data);
|
|
426
|
+
}
|
|
427
|
+
function isUnrecoverableError(error) {
|
|
428
|
+
const underlying = error instanceof LocterError ? error.cause : error;
|
|
429
|
+
return underlying instanceof SyntaxError || underlying instanceof ReferenceError || isTypeScriptError(underlying);
|
|
430
|
+
}
|
|
431
|
+
var ModuleLoader = class {
|
|
432
|
+
instance;
|
|
433
|
+
loadFn;
|
|
434
|
+
loadSyncFn;
|
|
435
|
+
constructor(options = {}) {
|
|
436
|
+
this.instance = createJiti(void 0, { extensions: [
|
|
437
|
+
".js",
|
|
438
|
+
".mjs",
|
|
439
|
+
".mts",
|
|
440
|
+
".cjs",
|
|
441
|
+
".cts",
|
|
442
|
+
".ts"
|
|
443
|
+
] });
|
|
444
|
+
this.loadFn = options.load;
|
|
445
|
+
this.loadSyncFn = options.loadSync;
|
|
446
|
+
}
|
|
447
|
+
configure(options) {
|
|
448
|
+
if ("load" in options) this.loadFn = options.load;
|
|
449
|
+
if ("loadSync" in options) this.loadSyncFn = options.loadSync;
|
|
450
|
+
}
|
|
451
|
+
async execute(input) {
|
|
452
|
+
let output;
|
|
453
|
+
try {
|
|
454
|
+
output = await this.load(input);
|
|
455
|
+
} catch (e) {
|
|
456
|
+
if (isUnrecoverableError(e)) throw e;
|
|
457
|
+
if (isTsNodeRuntimeEnvironment()) output = this.loadSync(input);
|
|
458
|
+
else output = this.instance(input);
|
|
459
|
+
}
|
|
460
|
+
return toModuleRecord(output);
|
|
461
|
+
}
|
|
462
|
+
executeSync(input) {
|
|
463
|
+
let output;
|
|
464
|
+
try {
|
|
465
|
+
output = this.loadSync(input);
|
|
466
|
+
} catch (e) {
|
|
467
|
+
if (isUnrecoverableError(e)) throw e;
|
|
468
|
+
output = this.instance(input);
|
|
469
|
+
}
|
|
470
|
+
return toModuleRecord(output);
|
|
471
|
+
}
|
|
472
|
+
async load(data, options = {}) {
|
|
473
|
+
const id = this.build(data, options);
|
|
474
|
+
try {
|
|
475
|
+
if (this.loadFn) return await this.loadFn(id);
|
|
476
|
+
if (isJestRuntimeEnvironment()) return require(id);
|
|
477
|
+
return await import(id);
|
|
478
|
+
} catch (e) {
|
|
479
|
+
/* istanbul ignore next */
|
|
480
|
+
if (!options.withFilePrefix && isObject(e) && hasStringProperty(e, "code") && (e.code === "ERR_UNSUPPORTED_ESM_URL_SCHEME" || e.code === "UNSUPPORTED_ESM_URL_SCHEME")) return this.load(data, {
|
|
481
|
+
...options,
|
|
482
|
+
withFilePrefix: true
|
|
483
|
+
});
|
|
484
|
+
throw wrapLoaderError(e, originalPath(data));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
loadSync(data, options = {}) {
|
|
488
|
+
const id = this.build(data, options);
|
|
489
|
+
try {
|
|
490
|
+
if (this.loadSyncFn) return this.loadSyncFn(id);
|
|
491
|
+
return require(id);
|
|
492
|
+
} catch (e) {
|
|
493
|
+
throw wrapLoaderError(e, originalPath(data));
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
build(data, options = {}) {
|
|
497
|
+
if (isLocatorInfo(data) || isFilePath(data)) {
|
|
498
|
+
if (typeof data !== "string") data = buildFilePath(data);
|
|
499
|
+
if (options.withFilePrefix) data = pathToFileURL(data).href;
|
|
500
|
+
}
|
|
501
|
+
return data;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
//#endregion
|
|
505
|
+
//#region src/loader/built-in/yaml/module.ts
|
|
506
|
+
var YAMLLoader = class {
|
|
507
|
+
async execute(input) {
|
|
508
|
+
const filePath = buildFilePath(input);
|
|
509
|
+
try {
|
|
510
|
+
return parse(await fs.promises.readFile(filePath, { encoding: "utf-8" }));
|
|
511
|
+
} catch (e) {
|
|
512
|
+
throw wrapLoaderError(e, filePath);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
executeSync(input) {
|
|
516
|
+
const filePath = buildFilePath(input);
|
|
517
|
+
try {
|
|
518
|
+
return parse(fs.readFileSync(filePath, { encoding: "utf-8" }));
|
|
519
|
+
} catch (e) {
|
|
520
|
+
throw wrapLoaderError(e, filePath);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
//#endregion
|
|
525
|
+
//#region src/loader/module.ts
|
|
526
|
+
var LoaderManager = class {
|
|
527
|
+
loaders;
|
|
528
|
+
rules;
|
|
529
|
+
constructor() {
|
|
530
|
+
this.loaders = {};
|
|
531
|
+
this.rules = [
|
|
532
|
+
{
|
|
533
|
+
test: [
|
|
534
|
+
".js",
|
|
535
|
+
".mjs",
|
|
536
|
+
".mts",
|
|
537
|
+
".cjs",
|
|
538
|
+
".cts",
|
|
539
|
+
".ts"
|
|
540
|
+
],
|
|
541
|
+
loader: "module"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
test: [".conf"],
|
|
545
|
+
loader: "conf"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
test: [".json"],
|
|
549
|
+
loader: "json"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
test: [".yml", ".yaml"],
|
|
553
|
+
loader: "yaml"
|
|
554
|
+
}
|
|
555
|
+
];
|
|
556
|
+
}
|
|
557
|
+
register(test, loader) {
|
|
558
|
+
if (typeof loader !== "undefined") {
|
|
559
|
+
this.rules.push({
|
|
560
|
+
test,
|
|
561
|
+
loader
|
|
562
|
+
});
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
this.rules.push(test);
|
|
566
|
+
}
|
|
567
|
+
async execute(input) {
|
|
568
|
+
const id = this.findLoader(input);
|
|
569
|
+
if (!id) throw this.unknownExtensionError(input);
|
|
570
|
+
const loader = this.resolve(id);
|
|
571
|
+
try {
|
|
572
|
+
return await loader.execute(input);
|
|
573
|
+
} catch (e) {
|
|
574
|
+
throw wrapLoaderError(e, input);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
executeSync(input) {
|
|
578
|
+
const id = this.findLoader(input);
|
|
579
|
+
if (!id) throw this.unknownExtensionError(input);
|
|
580
|
+
const loader = this.resolve(id);
|
|
581
|
+
try {
|
|
582
|
+
return loader.executeSync(input);
|
|
583
|
+
} catch (e) {
|
|
584
|
+
throw wrapLoaderError(e, input);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
unknownExtensionError(input) {
|
|
588
|
+
return new LocterUnknownExtensionError({
|
|
589
|
+
message: `No loader registered for extension: ${pathToLocatorInfo(input).extension ?? "unknown"}`,
|
|
590
|
+
path: input
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
findLoader(input) {
|
|
594
|
+
if (!isFilePath(input)) return "module";
|
|
595
|
+
const info = pathToLocatorInfo(input);
|
|
596
|
+
for (const rule of this.rules) {
|
|
597
|
+
const { test } = rule;
|
|
598
|
+
if (Array.isArray(test)) {
|
|
599
|
+
if (info.extension && test.includes(info.extension)) return rule.loader;
|
|
600
|
+
} else if (test.test(buildFilePath(info))) return rule.loader;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Resolve loader by id.
|
|
605
|
+
*
|
|
606
|
+
* @param id
|
|
607
|
+
*/
|
|
608
|
+
resolve(id) {
|
|
609
|
+
if (typeof id !== "string") return id;
|
|
610
|
+
if (Object.prototype.hasOwnProperty.call(this.loaders, id)) return this.loaders[id];
|
|
611
|
+
let loader;
|
|
612
|
+
switch (id) {
|
|
613
|
+
case "conf":
|
|
614
|
+
loader = new ConfLoader();
|
|
615
|
+
break;
|
|
616
|
+
case "module":
|
|
617
|
+
loader = new ModuleLoader();
|
|
618
|
+
break;
|
|
619
|
+
case "json":
|
|
620
|
+
loader = new JSONLoader();
|
|
621
|
+
break;
|
|
622
|
+
case "yaml":
|
|
623
|
+
loader = new YAMLLoader();
|
|
624
|
+
break;
|
|
625
|
+
/* istanbul ignore next */
|
|
626
|
+
default: {
|
|
627
|
+
const pluginPath = this.normalizePath(id);
|
|
628
|
+
loader = this.resolve("module").executeSync(pluginPath);
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (typeof loader !== "undefined") {
|
|
633
|
+
this.loaders[id] = loader;
|
|
634
|
+
return loader;
|
|
635
|
+
}
|
|
636
|
+
throw new LocterError({ message: `The loader ${id} could not be resolved.` });
|
|
637
|
+
}
|
|
638
|
+
/* istanbul ignore next */
|
|
639
|
+
normalizePath(input) {
|
|
640
|
+
if (path.isAbsolute(input) || input.startsWith("./")) return input;
|
|
641
|
+
if (input.startsWith("module:")) return input.substring(0, 7);
|
|
642
|
+
if (!input.startsWith("@")) return `@locter/${input}`;
|
|
643
|
+
return input;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/loader/singleton.ts
|
|
685
648
|
let instance;
|
|
686
649
|
function useLoader() {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
instance = new LoaderManager();
|
|
691
|
-
return instance;
|
|
650
|
+
if (typeof instance !== "undefined") return instance;
|
|
651
|
+
instance = new LoaderManager();
|
|
652
|
+
return instance;
|
|
692
653
|
}
|
|
693
|
-
|
|
654
|
+
//#endregion
|
|
655
|
+
//#region src/loader/helpers.ts
|
|
694
656
|
function registerLoader(test, loader) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
657
|
+
const manager = useLoader();
|
|
658
|
+
if (typeof loader !== "undefined") {
|
|
659
|
+
manager.register(test, loader);
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
manager.register(test);
|
|
701
663
|
}
|
|
702
664
|
async function load(input) {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
}
|
|
707
|
-
return manager.execute(buildFilePath(input));
|
|
665
|
+
const manager = useLoader();
|
|
666
|
+
if (typeof input === "string") return manager.execute(input);
|
|
667
|
+
return manager.execute(buildFilePath(input));
|
|
708
668
|
}
|
|
709
669
|
function loadSync(input) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
670
|
+
const manager = useLoader();
|
|
671
|
+
if (typeof input === "string") return manager.executeSync(input);
|
|
672
|
+
return manager.executeSync(buildFilePath(input));
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Override the built-in module loader's `import` / `require` calls.
|
|
676
|
+
*
|
|
677
|
+
* Useful for test runners (e.g. Vitest) where the dynamic `import()` inside
|
|
678
|
+
* `node_modules/locter` would bypass the runner's module graph. Calling this
|
|
679
|
+
* from user code (e.g. a Vitest setup file) lets the runner rewrite the
|
|
680
|
+
* `import()` so loaded modules share identity with statically imported ones.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```ts
|
|
684
|
+
* // vitest setup file
|
|
685
|
+
* import { setModuleLoader } from 'locter';
|
|
686
|
+
*
|
|
687
|
+
* setModuleLoader({
|
|
688
|
+
* load: (id) => import(id),
|
|
689
|
+
* });
|
|
690
|
+
* ```
|
|
691
|
+
*/
|
|
692
|
+
function setModuleLoader(options) {
|
|
693
|
+
useLoader().resolve("module").configure(options);
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
696
|
+
//#region src/loader/package-field.ts
|
|
697
|
+
function extractField(pkg, field) {
|
|
698
|
+
if (!isObject(pkg) || !hasOwnProperty(pkg, field)) return;
|
|
699
|
+
return pkg[field];
|
|
700
|
+
}
|
|
701
|
+
async function loadPackageField(field, options = {}) {
|
|
702
|
+
let info;
|
|
703
|
+
if (options.walkUp) info = await locateUp("package.json", {
|
|
704
|
+
cwd: options.cwd,
|
|
705
|
+
stopAt: options.stopAt
|
|
706
|
+
});
|
|
707
|
+
else info = await locate("package.json", { cwd: options.cwd });
|
|
708
|
+
if (!info) return;
|
|
709
|
+
try {
|
|
710
|
+
return extractField(await load(info), field);
|
|
711
|
+
} catch (e) {
|
|
712
|
+
if (e instanceof LocterNotFoundError) return;
|
|
713
|
+
throw e;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
function loadPackageFieldSync(field, options = {}) {
|
|
717
|
+
let info;
|
|
718
|
+
if (options.walkUp) info = locateUpSync("package.json", {
|
|
719
|
+
cwd: options.cwd,
|
|
720
|
+
stopAt: options.stopAt
|
|
721
|
+
});
|
|
722
|
+
else info = locateSync("package.json", { cwd: options.cwd });
|
|
723
|
+
if (!info) return;
|
|
724
|
+
try {
|
|
725
|
+
return extractField(loadSync(info), field);
|
|
726
|
+
} catch (e) {
|
|
727
|
+
if (e instanceof LocterNotFoundError) return;
|
|
728
|
+
throw e;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
//#endregion
|
|
732
|
+
export { ConfLoader, JSONLoader, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LoaderManager, LocterError, LocterLoadError, LocterNotFoundError, LocterUnknownExtensionError, ModuleLoader, YAMLLoader, buildFilePath, buildFilePathWithoutExtension, buildLocatorOptions, buildLocatorPatterns, getFileNameExtension, getModuleExport, hasOwnProperty, hasStringProperty, isESModule, isFilePath, isJestRuntimeEnvironment, isLocatorInfo, isObject, isSafeObjectKey, isTsNodeRuntimeEnvironment, isTypeScriptError, isVitestRuntimeEnvironment, load, loadPackageField, loadPackageFieldSync, loadSync, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, pathToLocatorInfo, registerLoader, removeFileNameExtension, setModuleLoader, toArray, toModuleRecord, wrapLoaderError };
|
|
716
733
|
|
|
717
|
-
|
|
718
|
-
//# sourceMappingURL=index.mjs.map
|
|
734
|
+
//# sourceMappingURL=index.mjs.map
|