@mokup/cli 1.0.11 → 1.1.1
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/dist/index.cjs +67 -461
- package/dist/index.d.cts +16 -35
- package/dist/index.d.mts +16 -35
- package/dist/index.d.ts +16 -35
- package/dist/index.mjs +64 -459
- package/package.json +6 -10
package/dist/index.cjs
CHANGED
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
const node_fs = require('node:fs');
|
|
4
4
|
const process = require('node:process');
|
|
5
5
|
const pathe = require('@mokup/shared/pathe');
|
|
6
|
+
const configUtils = require('@mokup/shared/config-utils');
|
|
7
|
+
const moduleLoader = require('@mokup/shared/module-loader');
|
|
8
|
+
const routeConstants = require('@mokup/shared/route-constants');
|
|
9
|
+
const mockFiles = require('@mokup/shared/mock-files');
|
|
10
|
+
const scanUtils = require('@mokup/shared/scan-utils');
|
|
11
|
+
const pathUtils = require('@mokup/shared/path-utils');
|
|
6
12
|
const node_buffer = require('node:buffer');
|
|
7
|
-
const node_module = require('node:module');
|
|
8
|
-
const node_url = require('node:url');
|
|
9
13
|
const esbuild = require('@mokup/shared/esbuild');
|
|
10
|
-
const pathUtils = require('@mokup/shared/path-utils');
|
|
11
14
|
const runtime = require('@mokup/runtime');
|
|
12
|
-
const
|
|
15
|
+
const routeUtils$1 = require('@mokup/shared/route-utils');
|
|
16
|
+
const loadRules$1 = require('@mokup/shared/load-rules');
|
|
17
|
+
const defineConfig$1 = require('@mokup/shared/define-config');
|
|
13
18
|
const node = require('@mokup/server/node');
|
|
14
19
|
const logger$1 = require('@mokup/shared/logger');
|
|
15
20
|
const commander = require('commander');
|
|
16
21
|
|
|
17
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
18
22
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
19
23
|
|
|
20
24
|
const process__default = /*#__PURE__*/_interopDefaultCompat(process);
|
|
@@ -75,259 +79,48 @@ async function writeManifestModule(outDir, manifest) {
|
|
|
75
79
|
await node_fs.promises.writeFile(pathe.join(outDir, "mokup.manifest.d.mts"), dts.join("\n"), "utf8");
|
|
76
80
|
}
|
|
77
81
|
|
|
78
|
-
const configExtensions = [".ts", ".js", ".mjs", ".cjs"];
|
|
79
|
-
const middlewareSymbol$1 = Symbol.for("mokup.config.middlewares");
|
|
80
|
-
async function loadModule$1(file) {
|
|
81
|
-
const ext = configExtensions.find((extension) => file.endsWith(extension));
|
|
82
|
-
if (ext === ".cjs") {
|
|
83
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
84
|
-
delete require$1.cache[file];
|
|
85
|
-
return require$1(file);
|
|
86
|
-
}
|
|
87
|
-
if (ext === ".js" || ext === ".mjs") {
|
|
88
|
-
return import(`${node_url.pathToFileURL(file).href}?t=${Date.now()}`);
|
|
89
|
-
}
|
|
90
|
-
if (ext === ".ts") {
|
|
91
|
-
const result = await esbuild.build({
|
|
92
|
-
entryPoints: [file],
|
|
93
|
-
bundle: true,
|
|
94
|
-
format: "esm",
|
|
95
|
-
platform: "node",
|
|
96
|
-
sourcemap: "inline",
|
|
97
|
-
target: "es2020",
|
|
98
|
-
write: false
|
|
99
|
-
});
|
|
100
|
-
const output = result.outputFiles[0];
|
|
101
|
-
const code = output?.text ?? "";
|
|
102
|
-
const dataUrl = `data:text/javascript;base64,${node_buffer.Buffer.from(code).toString(
|
|
103
|
-
"base64"
|
|
104
|
-
)}`;
|
|
105
|
-
return import(`${dataUrl}#${Date.now()}`);
|
|
106
|
-
}
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
function getConfigFileCandidates(dir) {
|
|
110
|
-
return configExtensions.map((extension) => pathe.join(dir, `index.config${extension}`));
|
|
111
|
-
}
|
|
112
|
-
async function findConfigFile(dir, cache) {
|
|
113
|
-
const cached = cache.get(dir);
|
|
114
|
-
if (cached !== void 0) {
|
|
115
|
-
return cached;
|
|
116
|
-
}
|
|
117
|
-
for (const candidate of getConfigFileCandidates(dir)) {
|
|
118
|
-
try {
|
|
119
|
-
await node_fs.promises.stat(candidate);
|
|
120
|
-
cache.set(dir, candidate);
|
|
121
|
-
return candidate;
|
|
122
|
-
} catch {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
cache.set(dir, null);
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
82
|
async function loadConfig(file) {
|
|
130
|
-
const mod = await loadModule
|
|
83
|
+
const mod = await moduleLoader.loadModule(file);
|
|
131
84
|
if (!mod) {
|
|
132
85
|
return null;
|
|
133
86
|
}
|
|
134
|
-
const
|
|
87
|
+
const raw = mod?.default ?? mod;
|
|
88
|
+
const value = configUtils.isPromise(raw) ? await raw : raw;
|
|
135
89
|
if (!value || typeof value !== "object") {
|
|
136
90
|
return null;
|
|
137
91
|
}
|
|
138
92
|
return value;
|
|
139
93
|
}
|
|
140
|
-
function normalizeMiddlewares(value, source, log, position) {
|
|
141
|
-
if (!value) {
|
|
142
|
-
return [];
|
|
143
|
-
}
|
|
144
|
-
const list = Array.isArray(value) ? value : [value];
|
|
145
|
-
const middlewares = [];
|
|
146
|
-
list.forEach((entry, index) => {
|
|
147
|
-
if (typeof entry !== "function") {
|
|
148
|
-
log?.(`Invalid middleware in ${source}`);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
middlewares.push({ file: source, index, position });
|
|
152
|
-
});
|
|
153
|
-
return middlewares;
|
|
154
|
-
}
|
|
155
|
-
function readMiddlewareMeta(config) {
|
|
156
|
-
const value = config[middlewareSymbol$1];
|
|
157
|
-
if (!value || typeof value !== "object") {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
const meta = value;
|
|
161
|
-
return {
|
|
162
|
-
pre: Array.isArray(meta.pre) ? meta.pre : [],
|
|
163
|
-
normal: Array.isArray(meta.normal) ? meta.normal : [],
|
|
164
|
-
post: Array.isArray(meta.post) ? meta.post : []
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
94
|
async function resolveDirectoryConfig(params) {
|
|
168
95
|
const { file, rootDir, log, configCache, fileCache } = params;
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
chain.reverse();
|
|
185
|
-
const merged = {};
|
|
186
|
-
const preMiddlewares = [];
|
|
187
|
-
const normalMiddlewares = [];
|
|
188
|
-
const postMiddlewares = [];
|
|
189
|
-
for (const dir of chain) {
|
|
190
|
-
const configPath = await findConfigFile(dir, fileCache);
|
|
191
|
-
if (!configPath) {
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
let config = configCache.get(configPath);
|
|
195
|
-
if (config === void 0) {
|
|
196
|
-
config = await loadConfig(configPath);
|
|
197
|
-
configCache.set(configPath, config);
|
|
198
|
-
}
|
|
199
|
-
if (!config) {
|
|
200
|
-
log?.(`Invalid config in ${configPath}`);
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
if (config.headers) {
|
|
204
|
-
merged.headers = { ...merged.headers ?? {}, ...config.headers };
|
|
205
|
-
}
|
|
206
|
-
if (typeof config.status === "number") {
|
|
207
|
-
merged.status = config.status;
|
|
208
|
-
}
|
|
209
|
-
if (typeof config.delay === "number") {
|
|
210
|
-
merged.delay = config.delay;
|
|
211
|
-
}
|
|
212
|
-
if (typeof config.enabled === "boolean") {
|
|
213
|
-
merged.enabled = config.enabled;
|
|
214
|
-
}
|
|
215
|
-
if (typeof config.ignorePrefix !== "undefined") {
|
|
216
|
-
merged.ignorePrefix = config.ignorePrefix;
|
|
217
|
-
}
|
|
218
|
-
if (typeof config.include !== "undefined") {
|
|
219
|
-
merged.include = config.include;
|
|
220
|
-
}
|
|
221
|
-
if (typeof config.exclude !== "undefined") {
|
|
222
|
-
merged.exclude = config.exclude;
|
|
223
|
-
}
|
|
224
|
-
const meta = readMiddlewareMeta(config);
|
|
225
|
-
const normalizedPre = normalizeMiddlewares(
|
|
226
|
-
meta?.pre,
|
|
227
|
-
configPath,
|
|
228
|
-
log,
|
|
229
|
-
"pre"
|
|
230
|
-
);
|
|
231
|
-
const normalizedNormal = normalizeMiddlewares(
|
|
232
|
-
meta?.normal,
|
|
233
|
-
configPath,
|
|
234
|
-
log,
|
|
235
|
-
"normal"
|
|
236
|
-
);
|
|
237
|
-
const normalizedLegacy = normalizeMiddlewares(
|
|
238
|
-
config.middleware,
|
|
239
|
-
configPath,
|
|
240
|
-
log,
|
|
241
|
-
"normal"
|
|
242
|
-
);
|
|
243
|
-
const normalizedPost = normalizeMiddlewares(
|
|
244
|
-
meta?.post,
|
|
245
|
-
configPath,
|
|
246
|
-
log,
|
|
247
|
-
"post"
|
|
248
|
-
);
|
|
249
|
-
if (normalizedPre.length > 0) {
|
|
250
|
-
preMiddlewares.push(...normalizedPre);
|
|
251
|
-
}
|
|
252
|
-
if (normalizedNormal.length > 0) {
|
|
253
|
-
normalMiddlewares.push(...normalizedNormal);
|
|
254
|
-
}
|
|
255
|
-
if (normalizedLegacy.length > 0) {
|
|
256
|
-
normalMiddlewares.push(...normalizedLegacy);
|
|
257
|
-
}
|
|
258
|
-
if (normalizedPost.length > 0) {
|
|
259
|
-
postMiddlewares.push(...normalizedPost);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
96
|
+
const resolved = await configUtils.resolveDirectoryConfig({
|
|
97
|
+
file,
|
|
98
|
+
rootDir,
|
|
99
|
+
configExtensions: routeConstants.configExtensions,
|
|
100
|
+
configCache,
|
|
101
|
+
fileCache,
|
|
102
|
+
loadConfig,
|
|
103
|
+
warn: log,
|
|
104
|
+
mapMiddleware: (_handler, index, position, source) => ({
|
|
105
|
+
file: source,
|
|
106
|
+
index,
|
|
107
|
+
position
|
|
108
|
+
})
|
|
109
|
+
});
|
|
262
110
|
return {
|
|
263
|
-
|
|
264
|
-
|
|
111
|
+
headers: resolved.headers,
|
|
112
|
+
status: resolved.status,
|
|
113
|
+
delay: resolved.delay,
|
|
114
|
+
enabled: resolved.enabled,
|
|
115
|
+
ignorePrefix: resolved.ignorePrefix,
|
|
116
|
+
include: resolved.include,
|
|
117
|
+
exclude: resolved.exclude,
|
|
118
|
+
middlewares: resolved.middlewares
|
|
265
119
|
};
|
|
266
120
|
}
|
|
267
121
|
|
|
268
|
-
const supportedExtensions = /* @__PURE__ */ new Set([
|
|
269
|
-
".json",
|
|
270
|
-
".jsonc",
|
|
271
|
-
".ts",
|
|
272
|
-
".js",
|
|
273
|
-
".mjs",
|
|
274
|
-
".cjs"
|
|
275
|
-
]);
|
|
276
|
-
async function exists(path) {
|
|
277
|
-
try {
|
|
278
|
-
await node_fs.promises.stat(path);
|
|
279
|
-
return true;
|
|
280
|
-
} catch {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
async function walkDir(dir, rootDir, files) {
|
|
285
|
-
const entries = await node_fs.promises.readdir(dir, { withFileTypes: true });
|
|
286
|
-
for (const entry of entries) {
|
|
287
|
-
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
const fullPath = pathe.join(dir, entry.name);
|
|
291
|
-
if (entry.isDirectory()) {
|
|
292
|
-
await walkDir(fullPath, rootDir, files);
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
if (entry.isFile()) {
|
|
296
|
-
files.push({ file: fullPath, rootDir });
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
async function collectFiles(dirs) {
|
|
301
|
-
const files = [];
|
|
302
|
-
for (const dir of dirs) {
|
|
303
|
-
if (!await exists(dir)) {
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
await walkDir(dir, dir, files);
|
|
307
|
-
}
|
|
308
|
-
return files;
|
|
309
|
-
}
|
|
310
122
|
function resolveDirs(dir, root) {
|
|
311
|
-
|
|
312
|
-
const resolved = Array.isArray(raw) ? raw : raw ? [raw] : ["mock"];
|
|
313
|
-
const normalized = resolved.map(
|
|
314
|
-
(entry) => pathe.isAbsolute(entry) ? entry : pathe.resolve(root, entry)
|
|
315
|
-
);
|
|
316
|
-
return Array.from(new Set(normalized));
|
|
317
|
-
}
|
|
318
|
-
function normalizeIgnorePrefix(value, fallback = ["."]) {
|
|
319
|
-
const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
|
|
320
|
-
return list.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
321
|
-
}
|
|
322
|
-
function isSupportedFile(file) {
|
|
323
|
-
if (file.endsWith(".d.ts")) {
|
|
324
|
-
return false;
|
|
325
|
-
}
|
|
326
|
-
if (pathe.basename(file).startsWith("index.config.")) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
const ext = pathe.extname(file).toLowerCase();
|
|
330
|
-
return supportedExtensions.has(ext);
|
|
123
|
+
return scanUtils.resolveDirs(dir, root);
|
|
331
124
|
}
|
|
332
125
|
|
|
333
126
|
function getHandlerModulePath(file, handlersDir, root) {
|
|
@@ -429,119 +222,28 @@ async function bundleHandlers(files, root, handlersDir) {
|
|
|
429
222
|
});
|
|
430
223
|
}
|
|
431
224
|
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
"PATCH",
|
|
437
|
-
"DELETE",
|
|
438
|
-
"OPTIONS",
|
|
439
|
-
"HEAD"
|
|
440
|
-
]);
|
|
441
|
-
const methodSuffixSet = new Set(
|
|
442
|
-
Array.from(methodSet, (method) => method.toLowerCase())
|
|
443
|
-
);
|
|
444
|
-
const jsonExtensions = /* @__PURE__ */ new Set([".json", ".jsonc"]);
|
|
445
|
-
function normalizePrefix(prefix) {
|
|
446
|
-
if (!prefix) {
|
|
447
|
-
return "";
|
|
448
|
-
}
|
|
449
|
-
const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
450
|
-
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
|
|
451
|
-
}
|
|
452
|
-
function resolveTemplate(template, prefix) {
|
|
453
|
-
const normalized = template.startsWith("/") ? template : `/${template}`;
|
|
454
|
-
if (!prefix) {
|
|
455
|
-
return normalized;
|
|
456
|
-
}
|
|
457
|
-
const normalizedPrefix = normalizePrefix(prefix);
|
|
458
|
-
if (!normalizedPrefix) {
|
|
459
|
-
return normalized;
|
|
460
|
-
}
|
|
461
|
-
if (normalized === normalizedPrefix || normalized.startsWith(`${normalizedPrefix}/`)) {
|
|
462
|
-
return normalized;
|
|
463
|
-
}
|
|
464
|
-
if (normalized === "/") {
|
|
465
|
-
return `${normalizedPrefix}/`;
|
|
466
|
-
}
|
|
467
|
-
return `${normalizedPrefix}${normalized}`;
|
|
468
|
-
}
|
|
469
|
-
function stripMethodSuffix(base) {
|
|
470
|
-
const segments = base.split(".");
|
|
471
|
-
const last = segments.at(-1);
|
|
472
|
-
if (last && methodSuffixSet.has(last.toLowerCase())) {
|
|
473
|
-
segments.pop();
|
|
474
|
-
return {
|
|
475
|
-
name: segments.join("."),
|
|
476
|
-
method: last.toUpperCase()
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
return {
|
|
480
|
-
name: base,
|
|
481
|
-
method: void 0
|
|
482
|
-
};
|
|
483
|
-
}
|
|
225
|
+
const routeUtils = routeUtils$1.createRouteUtils({
|
|
226
|
+
parseRouteTemplate: runtime.parseRouteTemplate,
|
|
227
|
+
compareRouteScore: runtime.compareRouteScore
|
|
228
|
+
});
|
|
484
229
|
function deriveRouteFromFile(file, rootDir, log) {
|
|
485
|
-
|
|
486
|
-
const ext = pathe.extname(rel);
|
|
487
|
-
const withoutExt = rel.slice(0, rel.length - ext.length);
|
|
488
|
-
const dir = pathe.dirname(withoutExt);
|
|
489
|
-
const base = pathe.basename(withoutExt);
|
|
490
|
-
const { name, method } = stripMethodSuffix(base);
|
|
491
|
-
const resolvedMethod = method ?? (jsonExtensions.has(ext) ? "GET" : void 0);
|
|
492
|
-
if (!resolvedMethod) {
|
|
493
|
-
log?.(`Skip mock without method suffix: ${file}`);
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
if (!name) {
|
|
497
|
-
log?.(`Skip mock with empty route name: ${file}`);
|
|
498
|
-
return null;
|
|
499
|
-
}
|
|
500
|
-
const joined = dir === "." ? name : pathe.join(dir, name);
|
|
501
|
-
const segments = pathUtils.toPosix(joined).split("/");
|
|
502
|
-
if (segments.at(-1) === "index") {
|
|
503
|
-
segments.pop();
|
|
504
|
-
}
|
|
505
|
-
const template = segments.length === 0 ? "/" : `/${segments.join("/")}`;
|
|
506
|
-
const parsed = runtime.parseRouteTemplate(template);
|
|
507
|
-
if (parsed.errors.length > 0) {
|
|
508
|
-
for (const error of parsed.errors) {
|
|
509
|
-
log?.(`${error} in ${file}`);
|
|
510
|
-
}
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
for (const warning of parsed.warnings) {
|
|
514
|
-
log?.(`${warning} in ${file}`);
|
|
515
|
-
}
|
|
516
|
-
return {
|
|
517
|
-
template: parsed.template,
|
|
518
|
-
method: resolvedMethod,
|
|
519
|
-
tokens: parsed.tokens,
|
|
520
|
-
score: parsed.score
|
|
521
|
-
};
|
|
230
|
+
return routeUtils.deriveRouteFromFile(file, rootDir, log);
|
|
522
231
|
}
|
|
523
232
|
function resolveRule(params) {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
return {
|
|
540
|
-
method,
|
|
541
|
-
template: parsed.template,
|
|
542
|
-
tokens: parsed.tokens,
|
|
543
|
-
score: parsed.score
|
|
544
|
-
};
|
|
233
|
+
return routeUtils.resolveRule({
|
|
234
|
+
rule: params.rule,
|
|
235
|
+
derivedTemplate: params.derivedTemplate,
|
|
236
|
+
derivedMethod: params.derivedMethod,
|
|
237
|
+
prefix: params.prefix,
|
|
238
|
+
file: params.file,
|
|
239
|
+
warn: params.log,
|
|
240
|
+
build: (base) => ({
|
|
241
|
+
method: base.method,
|
|
242
|
+
template: base.template,
|
|
243
|
+
tokens: base.tokens,
|
|
244
|
+
score: base.score
|
|
245
|
+
})
|
|
246
|
+
});
|
|
545
247
|
}
|
|
546
248
|
function sortRoutes(routes) {
|
|
547
249
|
return routes.sort((a, b) => {
|
|
@@ -552,80 +254,8 @@ function sortRoutes(routes) {
|
|
|
552
254
|
});
|
|
553
255
|
}
|
|
554
256
|
|
|
555
|
-
async function readJsonFile(file) {
|
|
556
|
-
try {
|
|
557
|
-
const content = await node_fs.promises.readFile(file, "utf8");
|
|
558
|
-
const errors = [];
|
|
559
|
-
const data = jsoncParser.parse(content, errors, {
|
|
560
|
-
allowTrailingComma: true,
|
|
561
|
-
disallowComments: false
|
|
562
|
-
});
|
|
563
|
-
if (errors.length > 0) {
|
|
564
|
-
return void 0;
|
|
565
|
-
}
|
|
566
|
-
return data;
|
|
567
|
-
} catch {
|
|
568
|
-
return void 0;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
async function loadModule(file) {
|
|
572
|
-
const ext = pathe.extname(file).toLowerCase();
|
|
573
|
-
if (ext === ".cjs") {
|
|
574
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
575
|
-
delete require$1.cache[file];
|
|
576
|
-
return require$1(file);
|
|
577
|
-
}
|
|
578
|
-
if (ext === ".js" || ext === ".mjs") {
|
|
579
|
-
return import(`${node_url.pathToFileURL(file).href}?t=${Date.now()}`);
|
|
580
|
-
}
|
|
581
|
-
if (ext === ".ts") {
|
|
582
|
-
const result = await esbuild.build({
|
|
583
|
-
entryPoints: [file],
|
|
584
|
-
bundle: true,
|
|
585
|
-
format: "esm",
|
|
586
|
-
platform: "node",
|
|
587
|
-
sourcemap: "inline",
|
|
588
|
-
target: "es2020",
|
|
589
|
-
write: false
|
|
590
|
-
});
|
|
591
|
-
const output = result.outputFiles[0];
|
|
592
|
-
const code = output?.text ?? "";
|
|
593
|
-
const dataUrl = `data:text/javascript;base64,${node_buffer.Buffer.from(code).toString(
|
|
594
|
-
"base64"
|
|
595
|
-
)}`;
|
|
596
|
-
return import(`${dataUrl}#${Date.now()}`);
|
|
597
|
-
}
|
|
598
|
-
return null;
|
|
599
|
-
}
|
|
600
257
|
async function loadRules(file) {
|
|
601
|
-
|
|
602
|
-
if (ext === ".json" || ext === ".jsonc") {
|
|
603
|
-
const json = await readJsonFile(file);
|
|
604
|
-
if (typeof json === "undefined") {
|
|
605
|
-
return [];
|
|
606
|
-
}
|
|
607
|
-
return [
|
|
608
|
-
{
|
|
609
|
-
handler: json
|
|
610
|
-
}
|
|
611
|
-
];
|
|
612
|
-
}
|
|
613
|
-
const mod = await loadModule(file);
|
|
614
|
-
const value = mod?.default ?? mod;
|
|
615
|
-
if (!value) {
|
|
616
|
-
return [];
|
|
617
|
-
}
|
|
618
|
-
if (Array.isArray(value)) {
|
|
619
|
-
return value;
|
|
620
|
-
}
|
|
621
|
-
if (typeof value === "function") {
|
|
622
|
-
return [
|
|
623
|
-
{
|
|
624
|
-
handler: value
|
|
625
|
-
}
|
|
626
|
-
];
|
|
627
|
-
}
|
|
628
|
-
return [value];
|
|
258
|
+
return loadRules$1.loadRules(file, { loadModule: moduleLoader.loadModule });
|
|
629
259
|
}
|
|
630
260
|
|
|
631
261
|
async function buildManifest(options = {}) {
|
|
@@ -633,14 +263,14 @@ async function buildManifest(options = {}) {
|
|
|
633
263
|
const outDir = pathe.resolve(root, options.outDir ?? ".mokup");
|
|
634
264
|
const handlersDir = pathe.join(outDir, "mokup-handlers");
|
|
635
265
|
const dirs = resolveDirs(options.dir, root);
|
|
636
|
-
const files = await collectFiles(dirs);
|
|
266
|
+
const files = await mockFiles.collectFiles(dirs);
|
|
637
267
|
const routes = [];
|
|
638
268
|
const seen = /* @__PURE__ */ new Set();
|
|
639
269
|
const handlerSources = /* @__PURE__ */ new Set();
|
|
640
270
|
const handlerModuleMap = /* @__PURE__ */ new Map();
|
|
641
271
|
const configCache = /* @__PURE__ */ new Map();
|
|
642
272
|
const configFileCache = /* @__PURE__ */ new Map();
|
|
643
|
-
const globalIgnorePrefix = normalizeIgnorePrefix(options.ignorePrefix);
|
|
273
|
+
const globalIgnorePrefix = scanUtils.normalizeIgnorePrefix(options.ignorePrefix);
|
|
644
274
|
for (const fileInfo of files) {
|
|
645
275
|
const configParams = {
|
|
646
276
|
file: fileInfo.file,
|
|
@@ -655,11 +285,11 @@ async function buildManifest(options = {}) {
|
|
|
655
285
|
if (config.enabled === false) {
|
|
656
286
|
continue;
|
|
657
287
|
}
|
|
658
|
-
const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
|
|
288
|
+
const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? scanUtils.normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
|
|
659
289
|
if (pathUtils.hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
|
|
660
290
|
continue;
|
|
661
291
|
}
|
|
662
|
-
if (!isSupportedFile(fileInfo.file)) {
|
|
292
|
+
if (!mockFiles.isSupportedFile(fileInfo.file)) {
|
|
663
293
|
continue;
|
|
664
294
|
}
|
|
665
295
|
const effectiveInclude = typeof config.include !== "undefined" ? config.include : options.include;
|
|
@@ -789,38 +419,12 @@ async function buildManifest(options = {}) {
|
|
|
789
419
|
};
|
|
790
420
|
}
|
|
791
421
|
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
function attachMetadata(config, meta) {
|
|
801
|
-
Object.defineProperty(config, middlewareSymbol, {
|
|
802
|
-
value: meta,
|
|
803
|
-
enumerable: false
|
|
804
|
-
});
|
|
805
|
-
return config;
|
|
806
|
-
}
|
|
807
|
-
function defineConfig(input) {
|
|
808
|
-
if (typeof input === "function") {
|
|
809
|
-
const pre = [];
|
|
810
|
-
const normal = [];
|
|
811
|
-
const post = [];
|
|
812
|
-
const context = {
|
|
813
|
-
pre: createRegistry(pre),
|
|
814
|
-
normal: createRegistry(normal),
|
|
815
|
-
post: createRegistry(post)
|
|
816
|
-
};
|
|
817
|
-
const result = input(context);
|
|
818
|
-
const config2 = result && typeof result === "object" ? result : {};
|
|
819
|
-
return attachMetadata(config2, { pre, normal, post });
|
|
820
|
-
}
|
|
821
|
-
const config = input && typeof input === "object" ? input : {};
|
|
822
|
-
return attachMetadata(config, { pre: [], normal: [], post: [] });
|
|
823
|
-
}
|
|
422
|
+
const shared = defineConfig$1.createDefineConfig({
|
|
423
|
+
logPrefix: "[@mokup/cli]"
|
|
424
|
+
});
|
|
425
|
+
const defineConfig = shared.defineConfig;
|
|
426
|
+
const onBeforeAll = shared.onBeforeAll;
|
|
427
|
+
const onAfterAll = shared.onAfterAll;
|
|
824
428
|
|
|
825
429
|
const logger = logger$1.createLogger();
|
|
826
430
|
function collectValues(value, previous) {
|
|
@@ -965,4 +569,6 @@ async function runCli(argv = process__default.argv) {
|
|
|
965
569
|
exports.buildManifest = buildManifest;
|
|
966
570
|
exports.createCli = createCli;
|
|
967
571
|
exports.defineConfig = defineConfig;
|
|
572
|
+
exports.onAfterAll = onAfterAll;
|
|
573
|
+
exports.onBeforeAll = onBeforeAll;
|
|
968
574
|
exports.runCli = runCli;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Manifest } from '@mokup/runtime';
|
|
2
2
|
import { MiddlewareHandler } from '@mokup/shared/hono';
|
|
3
|
+
import * as _mokup_shared_define_config from '@mokup/shared/define-config';
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -164,6 +165,12 @@ interface RouteDirectoryConfig {
|
|
|
164
165
|
* @default undefined
|
|
165
166
|
*/
|
|
166
167
|
middleware?: MiddlewareHandler | MiddlewareHandler[];
|
|
168
|
+
/**
|
|
169
|
+
* Error handling policy for defineConfig hooks.
|
|
170
|
+
*
|
|
171
|
+
* @default "warn"
|
|
172
|
+
*/
|
|
173
|
+
hookError?: HookErrorPolicy;
|
|
167
174
|
}
|
|
168
175
|
/**
|
|
169
176
|
* Middleware execution position.
|
|
@@ -174,6 +181,10 @@ interface RouteDirectoryConfig {
|
|
|
174
181
|
* const position: MiddlewarePosition = 'pre'
|
|
175
182
|
*/
|
|
176
183
|
type MiddlewarePosition = 'pre' | 'normal' | 'post';
|
|
184
|
+
/**
|
|
185
|
+
* Error handling policy for config hooks.
|
|
186
|
+
*/
|
|
187
|
+
type HookErrorPolicy = 'throw' | 'warn' | 'silent';
|
|
177
188
|
/**
|
|
178
189
|
* Middleware registry used by defineConfig.
|
|
179
190
|
*
|
|
@@ -202,39 +213,9 @@ declare function buildManifest(options?: BuildOptions): Promise<{
|
|
|
202
213
|
manifestPath: string;
|
|
203
214
|
}>;
|
|
204
215
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
post: MiddlewareRegistry;
|
|
209
|
-
}) => RouteDirectoryConfig | void;
|
|
210
|
-
/**
|
|
211
|
-
* Define a directory config with Hono-style middleware registration.
|
|
212
|
-
*
|
|
213
|
-
* @param input - Config object or factory callback.
|
|
214
|
-
* @returns Route directory config with middleware metadata.
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* import { defineConfig } from '@mokup/cli'
|
|
218
|
-
*
|
|
219
|
-
* export default defineConfig(({ pre, normal, post }) => {
|
|
220
|
-
* pre.use(async (c, next) => {
|
|
221
|
-
* c.header('x-before', '1')
|
|
222
|
-
* await next()
|
|
223
|
-
* })
|
|
224
|
-
*
|
|
225
|
-
* normal.use(async (_c, next) => {
|
|
226
|
-
* await next()
|
|
227
|
-
* })
|
|
228
|
-
*
|
|
229
|
-
* post.use(async (c, next) => {
|
|
230
|
-
* await next()
|
|
231
|
-
* c.header('x-after', '1')
|
|
232
|
-
* })
|
|
233
|
-
*
|
|
234
|
-
* return { delay: 120 }
|
|
235
|
-
* })
|
|
236
|
-
*/
|
|
237
|
-
declare function defineConfig(input: RouteDirectoryConfig | DefineConfigFactory): RouteDirectoryConfig;
|
|
216
|
+
declare const defineConfig: (input: RouteDirectoryConfig | _mokup_shared_define_config.DefineConfigFactory<RouteDirectoryConfig, MiddlewareHandler>) => RouteDirectoryConfig | Promise<RouteDirectoryConfig>;
|
|
217
|
+
declare const onBeforeAll: (handler: _mokup_shared_define_config.HookHandler) => void;
|
|
218
|
+
declare const onAfterAll: (handler: _mokup_shared_define_config.HookHandler) => void;
|
|
238
219
|
|
|
239
220
|
/**
|
|
240
221
|
* Create the mokup CLI program instance.
|
|
@@ -260,5 +241,5 @@ declare function createCli(): Command;
|
|
|
260
241
|
*/
|
|
261
242
|
declare function runCli(argv?: string[]): Promise<void>;
|
|
262
243
|
|
|
263
|
-
export { buildManifest, createCli, defineConfig, runCli };
|
|
264
|
-
export type { BuildOptions, MiddlewarePosition, MiddlewareRegistry, RouteDirectoryConfig, RouteRule };
|
|
244
|
+
export { buildManifest, createCli, defineConfig, onAfterAll, onBeforeAll, runCli };
|
|
245
|
+
export type { BuildOptions, HookErrorPolicy, MiddlewarePosition, MiddlewareRegistry, RouteDirectoryConfig, RouteRule };
|