@mokup/cli 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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 jsoncParser = require('@mokup/shared/jsonc-parser');
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,263 +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$1(file);
83
+ const mod = await moduleLoader.loadModule(file);
131
84
  if (!mod) {
132
85
  return null;
133
86
  }
134
87
  const raw = mod?.default ?? mod;
135
- const value = isPromise$1(raw) ? await raw : raw;
88
+ const value = configUtils.isPromise(raw) ? await raw : raw;
136
89
  if (!value || typeof value !== "object") {
137
90
  return null;
138
91
  }
139
92
  return value;
140
93
  }
141
- function isPromise$1(value) {
142
- return !!value && typeof value.then === "function";
143
- }
144
- function normalizeMiddlewares(value, source, log, position) {
145
- if (!value) {
146
- return [];
147
- }
148
- const list = Array.isArray(value) ? value : [value];
149
- const middlewares = [];
150
- list.forEach((entry, index) => {
151
- if (typeof entry !== "function") {
152
- log?.(`Invalid middleware in ${source}`);
153
- return;
154
- }
155
- middlewares.push({ file: source, index, position });
156
- });
157
- return middlewares;
158
- }
159
- function readMiddlewareMeta(config) {
160
- const value = config[middlewareSymbol$1];
161
- if (!value || typeof value !== "object") {
162
- return null;
163
- }
164
- const meta = value;
165
- return {
166
- pre: Array.isArray(meta.pre) ? meta.pre : [],
167
- normal: Array.isArray(meta.normal) ? meta.normal : [],
168
- post: Array.isArray(meta.post) ? meta.post : []
169
- };
170
- }
171
94
  async function resolveDirectoryConfig(params) {
172
95
  const { file, rootDir, log, configCache, fileCache } = params;
173
- const resolvedRoot = pathe.normalize(rootDir);
174
- const resolvedFileDir = pathe.normalize(pathe.dirname(file));
175
- const chain = [];
176
- let current = resolvedFileDir;
177
- while (true) {
178
- chain.push(current);
179
- if (current === resolvedRoot) {
180
- break;
181
- }
182
- const parent = pathe.dirname(current);
183
- if (parent === current) {
184
- break;
185
- }
186
- current = parent;
187
- }
188
- chain.reverse();
189
- const merged = {};
190
- const preMiddlewares = [];
191
- const normalMiddlewares = [];
192
- const postMiddlewares = [];
193
- for (const dir of chain) {
194
- const configPath = await findConfigFile(dir, fileCache);
195
- if (!configPath) {
196
- continue;
197
- }
198
- let config = configCache.get(configPath);
199
- if (config === void 0) {
200
- config = await loadConfig(configPath);
201
- configCache.set(configPath, config);
202
- }
203
- if (!config) {
204
- log?.(`Invalid config in ${configPath}`);
205
- continue;
206
- }
207
- if (config.headers) {
208
- merged.headers = { ...merged.headers ?? {}, ...config.headers };
209
- }
210
- if (typeof config.status === "number") {
211
- merged.status = config.status;
212
- }
213
- if (typeof config.delay === "number") {
214
- merged.delay = config.delay;
215
- }
216
- if (typeof config.enabled === "boolean") {
217
- merged.enabled = config.enabled;
218
- }
219
- if (typeof config.ignorePrefix !== "undefined") {
220
- merged.ignorePrefix = config.ignorePrefix;
221
- }
222
- if (typeof config.include !== "undefined") {
223
- merged.include = config.include;
224
- }
225
- if (typeof config.exclude !== "undefined") {
226
- merged.exclude = config.exclude;
227
- }
228
- const meta = readMiddlewareMeta(config);
229
- const normalizedPre = normalizeMiddlewares(
230
- meta?.pre,
231
- configPath,
232
- log,
233
- "pre"
234
- );
235
- const normalizedNormal = normalizeMiddlewares(
236
- meta?.normal,
237
- configPath,
238
- log,
239
- "normal"
240
- );
241
- const normalizedLegacy = normalizeMiddlewares(
242
- config.middleware,
243
- configPath,
244
- log,
245
- "normal"
246
- );
247
- const normalizedPost = normalizeMiddlewares(
248
- meta?.post,
249
- configPath,
250
- log,
251
- "post"
252
- );
253
- if (normalizedPre.length > 0) {
254
- preMiddlewares.push(...normalizedPre);
255
- }
256
- if (normalizedNormal.length > 0) {
257
- normalMiddlewares.push(...normalizedNormal);
258
- }
259
- if (normalizedLegacy.length > 0) {
260
- normalMiddlewares.push(...normalizedLegacy);
261
- }
262
- if (normalizedPost.length > 0) {
263
- postMiddlewares.push(...normalizedPost);
264
- }
265
- }
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
+ });
266
110
  return {
267
- ...merged,
268
- middlewares: [...preMiddlewares, ...normalMiddlewares, ...postMiddlewares]
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
269
119
  };
270
120
  }
271
121
 
272
- const supportedExtensions = /* @__PURE__ */ new Set([
273
- ".json",
274
- ".jsonc",
275
- ".ts",
276
- ".js",
277
- ".mjs",
278
- ".cjs"
279
- ]);
280
- async function exists(path) {
281
- try {
282
- await node_fs.promises.stat(path);
283
- return true;
284
- } catch {
285
- return false;
286
- }
287
- }
288
- async function walkDir(dir, rootDir, files) {
289
- const entries = await node_fs.promises.readdir(dir, { withFileTypes: true });
290
- for (const entry of entries) {
291
- if (entry.name === "node_modules" || entry.name === ".git") {
292
- continue;
293
- }
294
- const fullPath = pathe.join(dir, entry.name);
295
- if (entry.isDirectory()) {
296
- await walkDir(fullPath, rootDir, files);
297
- continue;
298
- }
299
- if (entry.isFile()) {
300
- files.push({ file: fullPath, rootDir });
301
- }
302
- }
303
- }
304
- async function collectFiles(dirs) {
305
- const files = [];
306
- for (const dir of dirs) {
307
- if (!await exists(dir)) {
308
- continue;
309
- }
310
- await walkDir(dir, dir, files);
311
- }
312
- return files;
313
- }
314
122
  function resolveDirs(dir, root) {
315
- const raw = dir;
316
- const resolved = Array.isArray(raw) ? raw : raw ? [raw] : ["mock"];
317
- const normalized = resolved.map(
318
- (entry) => pathe.isAbsolute(entry) ? entry : pathe.resolve(root, entry)
319
- );
320
- return Array.from(new Set(normalized));
321
- }
322
- function normalizeIgnorePrefix(value, fallback = ["."]) {
323
- const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
324
- return list.filter((entry) => typeof entry === "string" && entry.length > 0);
325
- }
326
- function isSupportedFile(file) {
327
- if (file.endsWith(".d.ts")) {
328
- return false;
329
- }
330
- if (pathe.basename(file).startsWith("index.config.")) {
331
- return false;
332
- }
333
- const ext = pathe.extname(file).toLowerCase();
334
- return supportedExtensions.has(ext);
123
+ return scanUtils.resolveDirs(dir, root);
335
124
  }
336
125
 
337
126
  function getHandlerModulePath(file, handlersDir, root) {
@@ -433,119 +222,28 @@ async function bundleHandlers(files, root, handlersDir) {
433
222
  });
434
223
  }
435
224
 
436
- const methodSet = /* @__PURE__ */ new Set([
437
- "GET",
438
- "POST",
439
- "PUT",
440
- "PATCH",
441
- "DELETE",
442
- "OPTIONS",
443
- "HEAD"
444
- ]);
445
- const methodSuffixSet = new Set(
446
- Array.from(methodSet, (method) => method.toLowerCase())
447
- );
448
- const jsonExtensions = /* @__PURE__ */ new Set([".json", ".jsonc"]);
449
- function normalizePrefix(prefix) {
450
- if (!prefix) {
451
- return "";
452
- }
453
- const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
454
- return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
455
- }
456
- function resolveTemplate(template, prefix) {
457
- const normalized = template.startsWith("/") ? template : `/${template}`;
458
- if (!prefix) {
459
- return normalized;
460
- }
461
- const normalizedPrefix = normalizePrefix(prefix);
462
- if (!normalizedPrefix) {
463
- return normalized;
464
- }
465
- if (normalized === normalizedPrefix || normalized.startsWith(`${normalizedPrefix}/`)) {
466
- return normalized;
467
- }
468
- if (normalized === "/") {
469
- return `${normalizedPrefix}/`;
470
- }
471
- return `${normalizedPrefix}${normalized}`;
472
- }
473
- function stripMethodSuffix(base) {
474
- const segments = base.split(".");
475
- const last = segments.at(-1);
476
- if (last && methodSuffixSet.has(last.toLowerCase())) {
477
- segments.pop();
478
- return {
479
- name: segments.join("."),
480
- method: last.toUpperCase()
481
- };
482
- }
483
- return {
484
- name: base,
485
- method: void 0
486
- };
487
- }
225
+ const routeUtils = routeUtils$1.createRouteUtils({
226
+ parseRouteTemplate: runtime.parseRouteTemplate,
227
+ compareRouteScore: runtime.compareRouteScore
228
+ });
488
229
  function deriveRouteFromFile(file, rootDir, log) {
489
- const rel = pathUtils.toPosix(pathe.relative(rootDir, file));
490
- const ext = pathe.extname(rel);
491
- const withoutExt = rel.slice(0, rel.length - ext.length);
492
- const dir = pathe.dirname(withoutExt);
493
- const base = pathe.basename(withoutExt);
494
- const { name, method } = stripMethodSuffix(base);
495
- const resolvedMethod = method ?? (jsonExtensions.has(ext) ? "GET" : void 0);
496
- if (!resolvedMethod) {
497
- log?.(`Skip mock without method suffix: ${file}`);
498
- return null;
499
- }
500
- if (!name) {
501
- log?.(`Skip mock with empty route name: ${file}`);
502
- return null;
503
- }
504
- const joined = dir === "." ? name : pathe.join(dir, name);
505
- const segments = pathUtils.toPosix(joined).split("/");
506
- if (segments.at(-1) === "index") {
507
- segments.pop();
508
- }
509
- const template = segments.length === 0 ? "/" : `/${segments.join("/")}`;
510
- const parsed = runtime.parseRouteTemplate(template);
511
- if (parsed.errors.length > 0) {
512
- for (const error of parsed.errors) {
513
- log?.(`${error} in ${file}`);
514
- }
515
- return null;
516
- }
517
- for (const warning of parsed.warnings) {
518
- log?.(`${warning} in ${file}`);
519
- }
520
- return {
521
- template: parsed.template,
522
- method: resolvedMethod,
523
- tokens: parsed.tokens,
524
- score: parsed.score
525
- };
230
+ return routeUtils.deriveRouteFromFile(file, rootDir, log);
526
231
  }
527
232
  function resolveRule(params) {
528
- const method = params.derivedMethod;
529
- if (!method) {
530
- return null;
531
- }
532
- const template = resolveTemplate(params.derivedTemplate, params.prefix);
533
- const parsed = runtime.parseRouteTemplate(template);
534
- if (parsed.errors.length > 0) {
535
- for (const error of parsed.errors) {
536
- params.log?.(`${error} in ${params.file}`);
537
- }
538
- return null;
539
- }
540
- for (const warning of parsed.warnings) {
541
- params.log?.(`${warning} in ${params.file}`);
542
- }
543
- return {
544
- method,
545
- template: parsed.template,
546
- tokens: parsed.tokens,
547
- score: parsed.score
548
- };
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
+ });
549
247
  }
550
248
  function sortRoutes(routes) {
551
249
  return routes.sort((a, b) => {
@@ -556,80 +254,8 @@ function sortRoutes(routes) {
556
254
  });
557
255
  }
558
256
 
559
- async function readJsonFile(file) {
560
- try {
561
- const content = await node_fs.promises.readFile(file, "utf8");
562
- const errors = [];
563
- const data = jsoncParser.parse(content, errors, {
564
- allowTrailingComma: true,
565
- disallowComments: false
566
- });
567
- if (errors.length > 0) {
568
- return void 0;
569
- }
570
- return data;
571
- } catch {
572
- return void 0;
573
- }
574
- }
575
- async function loadModule(file) {
576
- const ext = pathe.extname(file).toLowerCase();
577
- if (ext === ".cjs") {
578
- 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)));
579
- delete require$1.cache[file];
580
- return require$1(file);
581
- }
582
- if (ext === ".js" || ext === ".mjs") {
583
- return import(`${node_url.pathToFileURL(file).href}?t=${Date.now()}`);
584
- }
585
- if (ext === ".ts") {
586
- const result = await esbuild.build({
587
- entryPoints: [file],
588
- bundle: true,
589
- format: "esm",
590
- platform: "node",
591
- sourcemap: "inline",
592
- target: "es2020",
593
- write: false
594
- });
595
- const output = result.outputFiles[0];
596
- const code = output?.text ?? "";
597
- const dataUrl = `data:text/javascript;base64,${node_buffer.Buffer.from(code).toString(
598
- "base64"
599
- )}`;
600
- return import(`${dataUrl}#${Date.now()}`);
601
- }
602
- return null;
603
- }
604
257
  async function loadRules(file) {
605
- const ext = pathe.extname(file).toLowerCase();
606
- if (ext === ".json" || ext === ".jsonc") {
607
- const json = await readJsonFile(file);
608
- if (typeof json === "undefined") {
609
- return [];
610
- }
611
- return [
612
- {
613
- handler: json
614
- }
615
- ];
616
- }
617
- const mod = await loadModule(file);
618
- const value = mod?.default ?? mod;
619
- if (!value) {
620
- return [];
621
- }
622
- if (Array.isArray(value)) {
623
- return value;
624
- }
625
- if (typeof value === "function") {
626
- return [
627
- {
628
- handler: value
629
- }
630
- ];
631
- }
632
- return [value];
258
+ return loadRules$1.loadRules(file, { loadModule: moduleLoader.loadModule });
633
259
  }
634
260
 
635
261
  async function buildManifest(options = {}) {
@@ -637,14 +263,14 @@ async function buildManifest(options = {}) {
637
263
  const outDir = pathe.resolve(root, options.outDir ?? ".mokup");
638
264
  const handlersDir = pathe.join(outDir, "mokup-handlers");
639
265
  const dirs = resolveDirs(options.dir, root);
640
- const files = await collectFiles(dirs);
266
+ const files = await mockFiles.collectFiles(dirs);
641
267
  const routes = [];
642
268
  const seen = /* @__PURE__ */ new Set();
643
269
  const handlerSources = /* @__PURE__ */ new Set();
644
270
  const handlerModuleMap = /* @__PURE__ */ new Map();
645
271
  const configCache = /* @__PURE__ */ new Map();
646
272
  const configFileCache = /* @__PURE__ */ new Map();
647
- const globalIgnorePrefix = normalizeIgnorePrefix(options.ignorePrefix);
273
+ const globalIgnorePrefix = scanUtils.normalizeIgnorePrefix(options.ignorePrefix);
648
274
  for (const fileInfo of files) {
649
275
  const configParams = {
650
276
  file: fileInfo.file,
@@ -659,11 +285,11 @@ async function buildManifest(options = {}) {
659
285
  if (config.enabled === false) {
660
286
  continue;
661
287
  }
662
- const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
288
+ const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? scanUtils.normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
663
289
  if (pathUtils.hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
664
290
  continue;
665
291
  }
666
- if (!isSupportedFile(fileInfo.file)) {
292
+ if (!mockFiles.isSupportedFile(fileInfo.file)) {
667
293
  continue;
668
294
  }
669
295
  const effectiveInclude = typeof config.include !== "undefined" ? config.include : options.include;
@@ -793,165 +419,12 @@ async function buildManifest(options = {}) {
793
419
  };
794
420
  }
795
421
 
796
- const middlewareSymbol = Symbol.for("mokup.config.middlewares");
797
- const contextStack = [];
798
- function getActiveContext() {
799
- const context = contextStack[contextStack.length - 1];
800
- if (!context) {
801
- throw new Error("onBeforeAll/onAfterAll must be called inside defineConfig()");
802
- }
803
- return context;
804
- }
805
- function runWithContext(context, fn) {
806
- contextStack.push(context);
807
- try {
808
- const result = fn();
809
- if (isPromise(result)) {
810
- return result.finally(() => {
811
- contextStack.pop();
812
- });
813
- }
814
- contextStack.pop();
815
- return result;
816
- } catch (error) {
817
- contextStack.pop();
818
- throw error;
819
- }
820
- }
821
- function isPromise(value) {
822
- return !!value && typeof value.then === "function";
823
- }
824
- function normalizeHookError(policy) {
825
- if (policy === "throw" || policy === "silent") {
826
- return policy;
827
- }
828
- return "warn";
829
- }
830
- function reportHookError(error, policy) {
831
- if (policy === "silent") {
832
- return;
833
- }
834
- if (policy === "warn") {
835
- console.warn("[@mokup/cli] defineConfig hook failed:", error);
836
- }
837
- }
838
- function runHookSequence(stage, hooks, policy, setStage) {
839
- if (hooks.length === 0) {
840
- return;
841
- }
842
- setStage(stage);
843
- let chain = null;
844
- const runHook = (hook) => {
845
- try {
846
- const result = hook();
847
- if (isPromise(result)) {
848
- return result.catch((error) => {
849
- if (policy === "throw") {
850
- throw error;
851
- }
852
- reportHookError(error, policy);
853
- });
854
- }
855
- return void 0;
856
- } catch (error) {
857
- if (policy === "throw") {
858
- throw error;
859
- }
860
- reportHookError(error, policy);
861
- return void 0;
862
- }
863
- };
864
- for (const hook of hooks) {
865
- if (chain) {
866
- chain = chain.then(() => runHook(hook));
867
- continue;
868
- }
869
- const result = runHook(hook);
870
- if (isPromise(result)) {
871
- chain = result;
872
- }
873
- }
874
- if (!chain) {
875
- setStage("normal");
876
- return;
877
- }
878
- return chain.finally(() => {
879
- setStage("normal");
880
- });
881
- }
882
- function attachMetadata(config, meta) {
883
- Object.defineProperty(config, middlewareSymbol, {
884
- value: meta,
885
- enumerable: false
886
- });
887
- return config;
888
- }
889
- function normalizeConfig(value) {
890
- return value && typeof value === "object" ? value : {};
891
- }
892
- function onBeforeAll(handler) {
893
- if (typeof handler !== "function") {
894
- throw new TypeError("onBeforeAll expects a function");
895
- }
896
- const context = getActiveContext();
897
- context.hooks.pre.push(handler);
898
- }
899
- function onAfterAll(handler) {
900
- if (typeof handler !== "function") {
901
- throw new TypeError("onAfterAll expects a function");
902
- }
903
- const context = getActiveContext();
904
- context.hooks.post.push(handler);
905
- }
906
- function defineConfig(input) {
907
- if (typeof input === "function") {
908
- const pre = [];
909
- const normal = [];
910
- const post = [];
911
- let stage = "normal";
912
- const app = {
913
- use: (...handlers) => {
914
- if (stage === "pre") {
915
- pre.push(...handlers);
916
- return;
917
- }
918
- if (stage === "post") {
919
- post.push(...handlers);
920
- return;
921
- }
922
- normal.push(...handlers);
923
- }
924
- };
925
- const context = {
926
- app,
927
- hooks: { pre: [], post: [] },
928
- setStage: (next) => {
929
- stage = next;
930
- }
931
- };
932
- const result = runWithContext(context, () => input({ app }));
933
- const finalize = (value) => {
934
- const config2 = normalizeConfig(value);
935
- const policy = normalizeHookError(config2.hookError);
936
- const preResult = runHookSequence("pre", context.hooks.pre, policy, context.setStage);
937
- const runPost = () => runHookSequence("post", context.hooks.post, policy, context.setStage);
938
- if (isPromise(preResult)) {
939
- return preResult.then(runPost).then(() => attachMetadata(config2, { pre, normal, post }));
940
- }
941
- const postResult = runPost();
942
- if (isPromise(postResult)) {
943
- return postResult.then(() => attachMetadata(config2, { pre, normal, post }));
944
- }
945
- return attachMetadata(config2, { pre, normal, post });
946
- };
947
- if (isPromise(result)) {
948
- return result.then(finalize);
949
- }
950
- return finalize(result);
951
- }
952
- const config = normalizeConfig(input);
953
- return attachMetadata(config, { pre: [], normal: [], post: [] });
954
- }
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;
955
428
 
956
429
  const logger = logger$1.createLogger();
957
430
  function collectValues(value, previous) {