@mokup/server 1.1.6 → 1.2.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.
@@ -3,11 +3,14 @@
3
3
  const pathe = require('@mokup/shared/pathe');
4
4
  const node_fs = require('node:fs');
5
5
  const node_module = require('node:module');
6
- const process = require('node:process');
6
+ const playgroundGrouping = require('@mokup/shared/playground-grouping');
7
7
  const runtime = require('@mokup/runtime');
8
+ const pathUtils = require('@mokup/shared/path-utils');
9
+ const timing = require('@mokup/shared/timing');
8
10
  const node_buffer = require('node:buffer');
9
11
  const node_url = require('node:url');
10
12
  const esbuild = require('@mokup/shared/esbuild');
13
+ const process = require('node:process');
11
14
  const jsoncParser = require('@mokup/shared/jsonc-parser');
12
15
  const hono = require('@mokup/shared/hono');
13
16
 
@@ -117,92 +120,6 @@ async function readPlaygroundAsset(distDir, relPath) {
117
120
  return new Response(content, { headers: { "Content-Type": contentType } });
118
121
  }
119
122
 
120
- function toPosixPath(value) {
121
- return value.replace(/\\/g, "/");
122
- }
123
- function normalizePath(value) {
124
- return toPosixPath(pathe.normalize(value));
125
- }
126
- function isAncestor(parent, child) {
127
- const normalizedParent = normalizePath(parent).replace(/\/$/, "");
128
- const normalizedChild = normalizePath(child);
129
- return normalizedChild === normalizedParent || normalizedChild.startsWith(`${normalizedParent}/`);
130
- }
131
- function resolveGroupRoot(dirs, serverRoot) {
132
- if (!dirs || dirs.length === 0) {
133
- return serverRoot ?? process.cwd();
134
- }
135
- if (serverRoot) {
136
- const normalizedRoot = normalizePath(serverRoot);
137
- const canUseRoot = dirs.every((dir) => isAncestor(normalizedRoot, dir));
138
- if (canUseRoot) {
139
- return normalizedRoot;
140
- }
141
- }
142
- if (dirs.length === 1) {
143
- return normalizePath(pathe.dirname(dirs[0]));
144
- }
145
- let common = normalizePath(dirs[0]);
146
- for (const dir of dirs.slice(1)) {
147
- const normalizedDir = normalizePath(dir);
148
- while (common && !isAncestor(common, normalizedDir)) {
149
- const parent = normalizePath(pathe.dirname(common));
150
- if (parent === common) {
151
- break;
152
- }
153
- common = parent;
154
- }
155
- }
156
- if (!common || common === "/") {
157
- return serverRoot ?? process.cwd();
158
- }
159
- return common;
160
- }
161
- function resolveGroups(dirs, root) {
162
- const groups = [];
163
- const seen = /* @__PURE__ */ new Set();
164
- for (const dir of dirs) {
165
- const normalized = normalizePath(dir);
166
- if (seen.has(normalized)) {
167
- continue;
168
- }
169
- seen.add(normalized);
170
- const rel = toPosixPath(pathe.relative(root, normalized));
171
- const label = rel && !rel.startsWith("..") ? rel : normalized;
172
- groups.push({
173
- key: normalized,
174
- label,
175
- path: normalized
176
- });
177
- }
178
- return groups;
179
- }
180
- function resolveRouteGroup(routeFile, groups) {
181
- if (groups.length === 0) {
182
- return void 0;
183
- }
184
- const normalizedFile = toPosixPath(pathe.normalize(routeFile));
185
- let matched;
186
- for (const group of groups) {
187
- if (normalizedFile === group.path || normalizedFile.startsWith(`${group.path}/`)) {
188
- if (!matched || group.path.length > matched.path.length) {
189
- matched = group;
190
- }
191
- }
192
- }
193
- return matched;
194
- }
195
- function formatRouteFile(file, root) {
196
- if (!root) {
197
- return toPosixPath(file);
198
- }
199
- const rel = toPosixPath(pathe.relative(root, file));
200
- if (!rel || rel.startsWith("..")) {
201
- return toPosixPath(file);
202
- }
203
- return rel;
204
- }
205
-
206
123
  const disabledReasonSet = /* @__PURE__ */ new Set([
207
124
  "disabled",
208
125
  "disabled-dir",
@@ -229,10 +146,10 @@ function normalizeIgnoredReason(reason) {
229
146
  return "unknown";
230
147
  }
231
148
  function toPlaygroundRoute(route, root, groups) {
232
- const matchedGroup = resolveRouteGroup(route.file, groups);
233
- const preSources = route.middlewares?.filter((entry) => entry.position === "pre").map((entry) => formatRouteFile(entry.source, root)) ?? [];
234
- const postSources = route.middlewares?.filter((entry) => entry.position === "post").map((entry) => formatRouteFile(entry.source, root)) ?? [];
235
- const normalSources = route.middlewares?.filter((entry) => entry.position !== "pre" && entry.position !== "post").map((entry) => formatRouteFile(entry.source, root)) ?? [];
149
+ const matchedGroup = playgroundGrouping.resolveRouteGroup(route.file, groups);
150
+ const preSources = route.middlewares?.filter((entry) => entry.position === "pre").map((entry) => playgroundGrouping.formatRouteFile(entry.source, root)) ?? [];
151
+ const postSources = route.middlewares?.filter((entry) => entry.position === "post").map((entry) => playgroundGrouping.formatRouteFile(entry.source, root)) ?? [];
152
+ const normalSources = route.middlewares?.filter((entry) => entry.position !== "pre" && entry.position !== "post").map((entry) => playgroundGrouping.formatRouteFile(entry.source, root)) ?? [];
236
153
  const combinedSources = [
237
154
  ...preSources,
238
155
  ...normalSources,
@@ -241,7 +158,7 @@ function toPlaygroundRoute(route, root, groups) {
241
158
  return {
242
159
  method: route.method,
243
160
  url: route.template,
244
- file: formatRouteFile(route.file, root),
161
+ file: playgroundGrouping.formatRouteFile(route.file, root),
245
162
  type: typeof route.handler === "function" ? "handler" : "static",
246
163
  status: route.status,
247
164
  delay: route.delay,
@@ -258,9 +175,9 @@ function toPlaygroundRoute(route, root, groups) {
258
175
  };
259
176
  }
260
177
  function toPlaygroundDisabledRoute(route, root, groups) {
261
- const matchedGroup = resolveRouteGroup(route.file, groups);
178
+ const matchedGroup = playgroundGrouping.resolveRouteGroup(route.file, groups);
262
179
  const disabled = {
263
- file: formatRouteFile(route.file, root),
180
+ file: playgroundGrouping.formatRouteFile(route.file, root),
264
181
  reason: normalizeDisabledReason(route.reason)
265
182
  };
266
183
  if (typeof route.method !== "undefined") {
@@ -276,9 +193,9 @@ function toPlaygroundDisabledRoute(route, root, groups) {
276
193
  return disabled;
277
194
  }
278
195
  function toPlaygroundIgnoredRoute(route, root, groups) {
279
- const matchedGroup = resolveRouteGroup(route.file, groups);
196
+ const matchedGroup = playgroundGrouping.resolveRouteGroup(route.file, groups);
280
197
  const ignored = {
281
- file: formatRouteFile(route.file, root),
198
+ file: playgroundGrouping.formatRouteFile(route.file, root),
282
199
  reason: normalizeIgnoredReason(route.reason)
283
200
  };
284
201
  if (matchedGroup) {
@@ -288,9 +205,9 @@ function toPlaygroundIgnoredRoute(route, root, groups) {
288
205
  return ignored;
289
206
  }
290
207
  function toPlaygroundConfigFile(entry, root, groups) {
291
- const matchedGroup = resolveRouteGroup(entry.file, groups);
208
+ const matchedGroup = playgroundGrouping.resolveRouteGroup(entry.file, groups);
292
209
  const configFile = {
293
- file: formatRouteFile(entry.file, root)
210
+ file: playgroundGrouping.formatRouteFile(entry.file, root)
294
211
  };
295
212
  if (matchedGroup) {
296
213
  configFile.groupKey = matchedGroup.key;
@@ -327,8 +244,8 @@ function registerPlaygroundRoutes(params) {
327
244
  params.app.get(`${playgroundPath}/`, () => serveIndex());
328
245
  params.app.get(`${playgroundPath}/index.html`, () => serveIndex());
329
246
  params.app.get(`${playgroundPath}/routes`, (c) => {
330
- const baseRoot = resolveGroupRoot(params.dirs, params.root);
331
- const groups = resolveGroups(params.dirs, baseRoot);
247
+ const baseRoot = playgroundGrouping.resolveGroupRoot(params.dirs, params.root);
248
+ const groups = playgroundGrouping.resolveGroups(params.dirs, baseRoot);
332
249
  return c.json({
333
250
  basePath: playgroundPath,
334
251
  root: baseRoot,
@@ -394,59 +311,10 @@ function resolveDirs(dir, root) {
394
311
  );
395
312
  return Array.from(new Set(normalized));
396
313
  }
397
- function createDebouncer(delayMs, fn) {
398
- let timer = null;
399
- return () => {
400
- if (timer) {
401
- clearTimeout(timer);
402
- }
403
- timer = setTimeout(() => {
404
- timer = null;
405
- fn();
406
- }, delayMs);
407
- };
408
- }
409
- function toPosix(value) {
410
- return value.replace(/\\/g, "/");
411
- }
412
- function isInDirs(file, dirs) {
413
- const normalized = toPosix(file);
414
- return dirs.some((dir) => {
415
- const normalizedDir = toPosix(dir).replace(/\/$/, "");
416
- return normalized === normalizedDir || normalized.startsWith(`${normalizedDir}/`);
417
- });
418
- }
419
- function testPatterns(patterns, value) {
420
- const list = Array.isArray(patterns) ? patterns : [patterns];
421
- return list.some((pattern) => pattern.test(value));
422
- }
423
- function matchesFilter(file, include, exclude) {
424
- const normalized = toPosix(file);
425
- if (exclude && testPatterns(exclude, normalized)) {
426
- return false;
427
- }
428
- if (include) {
429
- return testPatterns(include, normalized);
430
- }
431
- return true;
432
- }
433
314
  function normalizeIgnorePrefix(value, fallback = ["."]) {
434
315
  const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
435
316
  return list.filter((entry) => typeof entry === "string" && entry.length > 0);
436
317
  }
437
- function hasIgnoredPrefix(file, rootDir, prefixes) {
438
- if (prefixes.length === 0) {
439
- return false;
440
- }
441
- const relativePath = toPosix(pathe.relative(rootDir, file));
442
- const segments = relativePath.split("/");
443
- return segments.some(
444
- (segment) => prefixes.some((prefix) => segment.startsWith(prefix))
445
- );
446
- }
447
- function delay(ms) {
448
- return new Promise((resolve2) => setTimeout(resolve2, ms));
449
- }
450
318
 
451
319
  const jsonExtensions = /* @__PURE__ */ new Set([".json", ".jsonc"]);
452
320
  function resolveTemplate(template, prefix) {
@@ -482,7 +350,7 @@ function stripMethodSuffix(base) {
482
350
  };
483
351
  }
484
352
  function deriveRouteFromFile(file, rootDir, logger) {
485
- const rel = toPosix(pathe.relative(rootDir, file));
353
+ const rel = pathUtils.toPosix(pathe.relative(rootDir, file));
486
354
  const ext = pathe.extname(rel);
487
355
  const withoutExt = rel.slice(0, rel.length - ext.length);
488
356
  const dir = pathe.dirname(withoutExt);
@@ -498,7 +366,7 @@ function deriveRouteFromFile(file, rootDir, logger) {
498
366
  return null;
499
367
  }
500
368
  const joined = dir === "." ? name : pathe.join(dir, name);
501
- const segments = toPosix(joined).split("/");
369
+ const segments = pathUtils.toPosix(joined).split("/");
502
370
  if (segments.at(-1) === "index") {
503
371
  segments.pop();
504
372
  }
@@ -681,12 +549,16 @@ async function loadConfig(file, logger) {
681
549
  if (!mod) {
682
550
  return null;
683
551
  }
684
- const value = mod?.default ?? mod;
552
+ const raw = mod?.default ?? mod;
553
+ const value = isPromise(raw) ? await raw : raw;
685
554
  if (!value || typeof value !== "object") {
686
555
  return null;
687
556
  }
688
557
  return value;
689
558
  }
559
+ function isPromise(value) {
560
+ return !!value && typeof value.then === "function";
561
+ }
690
562
  function normalizeMiddlewares(value, source, logger, position) {
691
563
  if (!value) {
692
564
  return [];
@@ -854,26 +726,26 @@ async function collectFiles(dirs) {
854
726
  }
855
727
  return files;
856
728
  }
857
- function isSupportedFile(file) {
729
+ function isConfigFile(file) {
858
730
  if (file.endsWith(".d.ts")) {
859
731
  return false;
860
732
  }
861
- if (isConfigFile(file)) {
733
+ const base = pathe.basename(file);
734
+ if (!base.startsWith("index.config.")) {
862
735
  return false;
863
736
  }
864
737
  const ext = pathe.extname(file).toLowerCase();
865
- return supportedExtensions.has(ext);
738
+ return configExtensions.includes(ext);
866
739
  }
867
- function isConfigFile(file) {
740
+ function isSupportedFile(file) {
868
741
  if (file.endsWith(".d.ts")) {
869
742
  return false;
870
743
  }
871
- const base = pathe.basename(file);
872
- if (!base.startsWith("index.config.")) {
744
+ if (isConfigFile(file)) {
873
745
  return false;
874
746
  }
875
747
  const ext = pathe.extname(file).toLowerCase();
876
- return configExtensions.includes(ext);
748
+ return supportedExtensions.has(ext);
877
749
  }
878
750
 
879
751
  function isUnknownFileExtensionError(error) {
@@ -1062,7 +934,7 @@ async function scanRoutes(params) {
1062
934
  continue;
1063
935
  }
1064
936
  const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
1065
- if (hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
937
+ if (pathUtils.hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
1066
938
  if (shouldCollectSkip && isSupportedFile(fileInfo.file)) {
1067
939
  const resolved = resolveSkipRoute({
1068
940
  file: fileInfo.file,
@@ -1081,14 +953,14 @@ async function scanRoutes(params) {
1081
953
  }
1082
954
  const effectiveInclude = typeof config.include !== "undefined" ? config.include : params.include;
1083
955
  const effectiveExclude = typeof config.exclude !== "undefined" ? config.exclude : params.exclude;
1084
- if (!matchesFilter(fileInfo.file, effectiveInclude, effectiveExclude)) {
956
+ if (!pathUtils.matchesFilter(fileInfo.file, effectiveInclude, effectiveExclude)) {
1085
957
  if (shouldCollectSkip) {
1086
958
  const resolved = resolveSkipRoute({
1087
959
  file: fileInfo.file,
1088
960
  rootDir: fileInfo.rootDir,
1089
961
  prefix: params.prefix
1090
962
  });
1091
- const reason = effectiveExclude && matchesFilter(fileInfo.file, void 0, effectiveExclude) ? "exclude" : "include";
963
+ const reason = effectiveExclude && pathUtils.matchesFilter(fileInfo.file, void 0, effectiveExclude) ? "exclude" : "include";
1092
964
  params.onSkip?.(buildSkipInfo(fileInfo.file, reason, resolved));
1093
965
  }
1094
966
  continue;
@@ -1259,7 +1131,7 @@ function createFinalizeMiddleware(route, onResponse) {
1259
1131
  const response = await next();
1260
1132
  const resolved = resolveResponse(response, c.res);
1261
1133
  if (route.delay && route.delay > 0) {
1262
- await delay(route.delay);
1134
+ await timing.delay(route.delay);
1263
1135
  }
1264
1136
  const overridden = applyRouteOverrides(resolved, route);
1265
1137
  c.res = overridden;
@@ -1495,17 +1367,17 @@ async function createChokidarWatcher(params) {
1495
1367
  const { default: chokidar } = await import('@mokup/shared/chokidar');
1496
1368
  const watcher = chokidar.watch(params.dirs, { ignoreInitial: true });
1497
1369
  watcher.on("add", (file) => {
1498
- if (isInDirs(file, params.dirs)) {
1370
+ if (pathUtils.isInDirs(file, params.dirs)) {
1499
1371
  params.onChange();
1500
1372
  }
1501
1373
  });
1502
1374
  watcher.on("change", (file) => {
1503
- if (isInDirs(file, params.dirs)) {
1375
+ if (pathUtils.isInDirs(file, params.dirs)) {
1504
1376
  params.onChange();
1505
1377
  }
1506
1378
  });
1507
1379
  watcher.on("unlink", (file) => {
1508
- if (isInDirs(file, params.dirs)) {
1380
+ if (pathUtils.isInDirs(file, params.dirs)) {
1509
1381
  params.onChange();
1510
1382
  }
1511
1383
  });
@@ -1629,7 +1501,7 @@ async function createFetchServer(options = {}) {
1629
1501
  if (wsHandler && playgroundConfig.enabled) {
1630
1502
  app.get(`${playgroundConfig.path}/ws`, wsHandler);
1631
1503
  }
1632
- const scheduleRefresh = createDebouncer(80, () => {
1504
+ const scheduleRefresh = timing.createDebouncer(80, () => {
1633
1505
  void refreshRoutes();
1634
1506
  });
1635
1507
  const watcher = await createWatcher({
@@ -1,4 +1,4 @@
1
- import { d as RouteTable } from './shared/server.CyVIKPsp.cjs';
1
+ import { d as RouteTable } from './shared/server.DLPB_I9q.cjs';
2
2
  import { MockEntryOptions, PlaygroundOptionsInput } from '@mokup/shared';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared/hono';
@@ -1,4 +1,4 @@
1
- import { d as RouteTable } from './shared/server.CyVIKPsp.mjs';
1
+ import { d as RouteTable } from './shared/server.DLPB_I9q.mjs';
2
2
  import { MockEntryOptions, PlaygroundOptionsInput } from '@mokup/shared';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared/hono';
@@ -1,4 +1,4 @@
1
- import { d as RouteTable } from './shared/server.CyVIKPsp.js';
1
+ import { d as RouteTable } from './shared/server.DLPB_I9q.js';
2
2
  import { MockEntryOptions, PlaygroundOptionsInput } from '@mokup/shared';
3
3
  import '@mokup/runtime';
4
4
  import '@mokup/shared/hono';
@@ -1,11 +1,14 @@
1
- import { join, normalize, extname, dirname, relative, resolve, isAbsolute, basename } from '@mokup/shared/pathe';
1
+ import { join, normalize, extname, resolve, isAbsolute, relative, dirname, basename } from '@mokup/shared/pathe';
2
2
  import { promises } from 'node:fs';
3
3
  import { createRequire } from 'node:module';
4
- import process, { cwd } from 'node:process';
4
+ import { resolveRouteGroup, formatRouteFile, resolveGroupRoot, resolveGroups } from '@mokup/shared/playground-grouping';
5
5
  import { compareRouteScore, parseRouteTemplate } from '@mokup/runtime';
6
+ import { toPosix, hasIgnoredPrefix, matchesFilter, isInDirs } from '@mokup/shared/path-utils';
7
+ import { delay, createDebouncer } from '@mokup/shared/timing';
6
8
  import { Buffer } from 'node:buffer';
7
9
  import { pathToFileURL } from 'node:url';
8
10
  import { build } from '@mokup/shared/esbuild';
11
+ import process, { cwd } from 'node:process';
9
12
  import { parse } from '@mokup/shared/jsonc-parser';
10
13
  import { Hono, PatternRouter } from '@mokup/shared/hono';
11
14
 
@@ -110,92 +113,6 @@ async function readPlaygroundAsset(distDir, relPath) {
110
113
  return new Response(content, { headers: { "Content-Type": contentType } });
111
114
  }
112
115
 
113
- function toPosixPath(value) {
114
- return value.replace(/\\/g, "/");
115
- }
116
- function normalizePath(value) {
117
- return toPosixPath(normalize(value));
118
- }
119
- function isAncestor(parent, child) {
120
- const normalizedParent = normalizePath(parent).replace(/\/$/, "");
121
- const normalizedChild = normalizePath(child);
122
- return normalizedChild === normalizedParent || normalizedChild.startsWith(`${normalizedParent}/`);
123
- }
124
- function resolveGroupRoot(dirs, serverRoot) {
125
- if (!dirs || dirs.length === 0) {
126
- return serverRoot ?? cwd();
127
- }
128
- if (serverRoot) {
129
- const normalizedRoot = normalizePath(serverRoot);
130
- const canUseRoot = dirs.every((dir) => isAncestor(normalizedRoot, dir));
131
- if (canUseRoot) {
132
- return normalizedRoot;
133
- }
134
- }
135
- if (dirs.length === 1) {
136
- return normalizePath(dirname(dirs[0]));
137
- }
138
- let common = normalizePath(dirs[0]);
139
- for (const dir of dirs.slice(1)) {
140
- const normalizedDir = normalizePath(dir);
141
- while (common && !isAncestor(common, normalizedDir)) {
142
- const parent = normalizePath(dirname(common));
143
- if (parent === common) {
144
- break;
145
- }
146
- common = parent;
147
- }
148
- }
149
- if (!common || common === "/") {
150
- return serverRoot ?? cwd();
151
- }
152
- return common;
153
- }
154
- function resolveGroups(dirs, root) {
155
- const groups = [];
156
- const seen = /* @__PURE__ */ new Set();
157
- for (const dir of dirs) {
158
- const normalized = normalizePath(dir);
159
- if (seen.has(normalized)) {
160
- continue;
161
- }
162
- seen.add(normalized);
163
- const rel = toPosixPath(relative(root, normalized));
164
- const label = rel && !rel.startsWith("..") ? rel : normalized;
165
- groups.push({
166
- key: normalized,
167
- label,
168
- path: normalized
169
- });
170
- }
171
- return groups;
172
- }
173
- function resolveRouteGroup(routeFile, groups) {
174
- if (groups.length === 0) {
175
- return void 0;
176
- }
177
- const normalizedFile = toPosixPath(normalize(routeFile));
178
- let matched;
179
- for (const group of groups) {
180
- if (normalizedFile === group.path || normalizedFile.startsWith(`${group.path}/`)) {
181
- if (!matched || group.path.length > matched.path.length) {
182
- matched = group;
183
- }
184
- }
185
- }
186
- return matched;
187
- }
188
- function formatRouteFile(file, root) {
189
- if (!root) {
190
- return toPosixPath(file);
191
- }
192
- const rel = toPosixPath(relative(root, file));
193
- if (!rel || rel.startsWith("..")) {
194
- return toPosixPath(file);
195
- }
196
- return rel;
197
- }
198
-
199
116
  const disabledReasonSet = /* @__PURE__ */ new Set([
200
117
  "disabled",
201
118
  "disabled-dir",
@@ -387,59 +304,10 @@ function resolveDirs(dir, root) {
387
304
  );
388
305
  return Array.from(new Set(normalized));
389
306
  }
390
- function createDebouncer(delayMs, fn) {
391
- let timer = null;
392
- return () => {
393
- if (timer) {
394
- clearTimeout(timer);
395
- }
396
- timer = setTimeout(() => {
397
- timer = null;
398
- fn();
399
- }, delayMs);
400
- };
401
- }
402
- function toPosix(value) {
403
- return value.replace(/\\/g, "/");
404
- }
405
- function isInDirs(file, dirs) {
406
- const normalized = toPosix(file);
407
- return dirs.some((dir) => {
408
- const normalizedDir = toPosix(dir).replace(/\/$/, "");
409
- return normalized === normalizedDir || normalized.startsWith(`${normalizedDir}/`);
410
- });
411
- }
412
- function testPatterns(patterns, value) {
413
- const list = Array.isArray(patterns) ? patterns : [patterns];
414
- return list.some((pattern) => pattern.test(value));
415
- }
416
- function matchesFilter(file, include, exclude) {
417
- const normalized = toPosix(file);
418
- if (exclude && testPatterns(exclude, normalized)) {
419
- return false;
420
- }
421
- if (include) {
422
- return testPatterns(include, normalized);
423
- }
424
- return true;
425
- }
426
307
  function normalizeIgnorePrefix(value, fallback = ["."]) {
427
308
  const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
428
309
  return list.filter((entry) => typeof entry === "string" && entry.length > 0);
429
310
  }
430
- function hasIgnoredPrefix(file, rootDir, prefixes) {
431
- if (prefixes.length === 0) {
432
- return false;
433
- }
434
- const relativePath = toPosix(relative(rootDir, file));
435
- const segments = relativePath.split("/");
436
- return segments.some(
437
- (segment) => prefixes.some((prefix) => segment.startsWith(prefix))
438
- );
439
- }
440
- function delay(ms) {
441
- return new Promise((resolve2) => setTimeout(resolve2, ms));
442
- }
443
311
 
444
312
  const jsonExtensions = /* @__PURE__ */ new Set([".json", ".jsonc"]);
445
313
  function resolveTemplate(template, prefix) {
@@ -674,12 +542,16 @@ async function loadConfig(file, logger) {
674
542
  if (!mod) {
675
543
  return null;
676
544
  }
677
- const value = mod?.default ?? mod;
545
+ const raw = mod?.default ?? mod;
546
+ const value = isPromise(raw) ? await raw : raw;
678
547
  if (!value || typeof value !== "object") {
679
548
  return null;
680
549
  }
681
550
  return value;
682
551
  }
552
+ function isPromise(value) {
553
+ return !!value && typeof value.then === "function";
554
+ }
683
555
  function normalizeMiddlewares(value, source, logger, position) {
684
556
  if (!value) {
685
557
  return [];
@@ -847,26 +719,26 @@ async function collectFiles(dirs) {
847
719
  }
848
720
  return files;
849
721
  }
850
- function isSupportedFile(file) {
722
+ function isConfigFile(file) {
851
723
  if (file.endsWith(".d.ts")) {
852
724
  return false;
853
725
  }
854
- if (isConfigFile(file)) {
726
+ const base = basename(file);
727
+ if (!base.startsWith("index.config.")) {
855
728
  return false;
856
729
  }
857
730
  const ext = extname(file).toLowerCase();
858
- return supportedExtensions.has(ext);
731
+ return configExtensions.includes(ext);
859
732
  }
860
- function isConfigFile(file) {
733
+ function isSupportedFile(file) {
861
734
  if (file.endsWith(".d.ts")) {
862
735
  return false;
863
736
  }
864
- const base = basename(file);
865
- if (!base.startsWith("index.config.")) {
737
+ if (isConfigFile(file)) {
866
738
  return false;
867
739
  }
868
740
  const ext = extname(file).toLowerCase();
869
- return configExtensions.includes(ext);
741
+ return supportedExtensions.has(ext);
870
742
  }
871
743
 
872
744
  function isUnknownFileExtensionError(error) {