@mokup/server 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +161 -8
- package/dist/index.d.cts +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +162 -9
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -141,6 +141,20 @@ function matchesFilter(file, include, exclude) {
|
|
|
141
141
|
}
|
|
142
142
|
return true;
|
|
143
143
|
}
|
|
144
|
+
function normalizeIgnorePrefix(value, fallback = ["."]) {
|
|
145
|
+
const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
|
|
146
|
+
return list.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
147
|
+
}
|
|
148
|
+
function hasIgnoredPrefix(file, rootDir, prefixes) {
|
|
149
|
+
if (prefixes.length === 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const relativePath = toPosix(pathe.relative(rootDir, file));
|
|
153
|
+
const segments = relativePath.split("/");
|
|
154
|
+
return segments.some(
|
|
155
|
+
(segment) => prefixes.some((prefix) => segment.startsWith(prefix))
|
|
156
|
+
);
|
|
157
|
+
}
|
|
144
158
|
function delay(ms) {
|
|
145
159
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
146
160
|
}
|
|
@@ -372,6 +386,20 @@ function resolveGroupRoot(dirs, serverRoot) {
|
|
|
372
386
|
}
|
|
373
387
|
return common;
|
|
374
388
|
}
|
|
389
|
+
const disabledReasonSet = /* @__PURE__ */ new Set([
|
|
390
|
+
"disabled",
|
|
391
|
+
"disabled-dir",
|
|
392
|
+
"exclude",
|
|
393
|
+
"ignore-prefix",
|
|
394
|
+
"include",
|
|
395
|
+
"unknown"
|
|
396
|
+
]);
|
|
397
|
+
function normalizeDisabledReason(reason) {
|
|
398
|
+
if (reason && disabledReasonSet.has(reason)) {
|
|
399
|
+
return reason;
|
|
400
|
+
}
|
|
401
|
+
return "unknown";
|
|
402
|
+
}
|
|
375
403
|
function formatRouteFile(file, root) {
|
|
376
404
|
if (!root) {
|
|
377
405
|
return toPosixPath(file);
|
|
@@ -432,6 +460,17 @@ function toPlaygroundRoute(route, root, groups) {
|
|
|
432
460
|
group: matchedGroup?.label
|
|
433
461
|
};
|
|
434
462
|
}
|
|
463
|
+
function toPlaygroundDisabledRoute(route, root, groups) {
|
|
464
|
+
const matchedGroup = resolveRouteGroup(route.file, groups);
|
|
465
|
+
return {
|
|
466
|
+
file: formatRouteFile(route.file, root),
|
|
467
|
+
reason: normalizeDisabledReason(route.reason),
|
|
468
|
+
method: route.method,
|
|
469
|
+
url: route.url,
|
|
470
|
+
groupKey: matchedGroup?.key,
|
|
471
|
+
group: matchedGroup?.label
|
|
472
|
+
};
|
|
473
|
+
}
|
|
435
474
|
function registerPlaygroundRoutes(params) {
|
|
436
475
|
if (!params.config.enabled) {
|
|
437
476
|
return;
|
|
@@ -469,7 +508,8 @@ function registerPlaygroundRoutes(params) {
|
|
|
469
508
|
root: baseRoot,
|
|
470
509
|
count: params.routes.length,
|
|
471
510
|
groups: groups.map((group) => ({ key: group.key, label: group.label })),
|
|
472
|
-
routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups))
|
|
511
|
+
routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups)),
|
|
512
|
+
disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups))
|
|
473
513
|
});
|
|
474
514
|
});
|
|
475
515
|
params.app.get(`${playgroundPath}/*`, async (c) => {
|
|
@@ -736,6 +776,15 @@ async function resolveDirectoryConfig(params) {
|
|
|
736
776
|
if (typeof config.enabled === "boolean") {
|
|
737
777
|
merged.enabled = config.enabled;
|
|
738
778
|
}
|
|
779
|
+
if (typeof config.ignorePrefix !== "undefined") {
|
|
780
|
+
merged.ignorePrefix = config.ignorePrefix;
|
|
781
|
+
}
|
|
782
|
+
if (typeof config.include !== "undefined") {
|
|
783
|
+
merged.include = config.include;
|
|
784
|
+
}
|
|
785
|
+
if (typeof config.exclude !== "undefined") {
|
|
786
|
+
merged.exclude = config.exclude;
|
|
787
|
+
}
|
|
739
788
|
const normalized = normalizeMiddlewares(config.middleware, configPath, logger);
|
|
740
789
|
if (normalized.length > 0) {
|
|
741
790
|
merged.middlewares.push(...normalized);
|
|
@@ -867,19 +916,44 @@ async function loadRules(file, logger) {
|
|
|
867
916
|
return [value];
|
|
868
917
|
}
|
|
869
918
|
|
|
919
|
+
const silentLogger = {
|
|
920
|
+
info: () => {
|
|
921
|
+
},
|
|
922
|
+
warn: () => {
|
|
923
|
+
},
|
|
924
|
+
error: () => {
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
function resolveSkipRoute(params) {
|
|
928
|
+
const derived = params.derived ?? deriveRouteFromFile(params.file, params.rootDir, silentLogger);
|
|
929
|
+
if (!derived?.method) {
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
const resolved = resolveRule({
|
|
933
|
+
rule: { handler: null },
|
|
934
|
+
derivedTemplate: derived.template,
|
|
935
|
+
derivedMethod: derived.method,
|
|
936
|
+
prefix: params.prefix,
|
|
937
|
+
file: params.file,
|
|
938
|
+
logger: silentLogger
|
|
939
|
+
});
|
|
940
|
+
if (!resolved) {
|
|
941
|
+
return null;
|
|
942
|
+
}
|
|
943
|
+
return {
|
|
944
|
+
method: resolved.method,
|
|
945
|
+
url: resolved.template
|
|
946
|
+
};
|
|
947
|
+
}
|
|
870
948
|
async function scanRoutes(params) {
|
|
871
949
|
const routes = [];
|
|
872
950
|
const seen = /* @__PURE__ */ new Set();
|
|
873
951
|
const files = await collectFiles(params.dirs);
|
|
952
|
+
const globalIgnorePrefix = normalizeIgnorePrefix(params.ignorePrefix);
|
|
874
953
|
const configCache = /* @__PURE__ */ new Map();
|
|
875
954
|
const fileCache = /* @__PURE__ */ new Map();
|
|
955
|
+
const shouldCollectSkip = typeof params.onSkip === "function";
|
|
876
956
|
for (const fileInfo of files) {
|
|
877
|
-
if (!isSupportedFile(fileInfo.file)) {
|
|
878
|
-
continue;
|
|
879
|
-
}
|
|
880
|
-
if (!matchesFilter(fileInfo.file, params.include, params.exclude)) {
|
|
881
|
-
continue;
|
|
882
|
-
}
|
|
883
957
|
const config = await resolveDirectoryConfig({
|
|
884
958
|
file: fileInfo.file,
|
|
885
959
|
rootDir: fileInfo.rootDir,
|
|
@@ -888,6 +962,58 @@ async function scanRoutes(params) {
|
|
|
888
962
|
fileCache
|
|
889
963
|
});
|
|
890
964
|
if (config.enabled === false) {
|
|
965
|
+
if (shouldCollectSkip && isSupportedFile(fileInfo.file)) {
|
|
966
|
+
const resolved = resolveSkipRoute({
|
|
967
|
+
file: fileInfo.file,
|
|
968
|
+
rootDir: fileInfo.rootDir,
|
|
969
|
+
prefix: params.prefix
|
|
970
|
+
});
|
|
971
|
+
params.onSkip?.({
|
|
972
|
+
file: fileInfo.file,
|
|
973
|
+
reason: "disabled-dir",
|
|
974
|
+
method: resolved?.method,
|
|
975
|
+
url: resolved?.url
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
|
|
981
|
+
if (hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
|
|
982
|
+
if (shouldCollectSkip && isSupportedFile(fileInfo.file)) {
|
|
983
|
+
const resolved = resolveSkipRoute({
|
|
984
|
+
file: fileInfo.file,
|
|
985
|
+
rootDir: fileInfo.rootDir,
|
|
986
|
+
prefix: params.prefix
|
|
987
|
+
});
|
|
988
|
+
params.onSkip?.({
|
|
989
|
+
file: fileInfo.file,
|
|
990
|
+
reason: "ignore-prefix",
|
|
991
|
+
method: resolved?.method,
|
|
992
|
+
url: resolved?.url
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
if (!isSupportedFile(fileInfo.file)) {
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
const effectiveInclude = typeof config.include !== "undefined" ? config.include : params.include;
|
|
1001
|
+
const effectiveExclude = typeof config.exclude !== "undefined" ? config.exclude : params.exclude;
|
|
1002
|
+
if (!matchesFilter(fileInfo.file, effectiveInclude, effectiveExclude)) {
|
|
1003
|
+
if (shouldCollectSkip) {
|
|
1004
|
+
const resolved = resolveSkipRoute({
|
|
1005
|
+
file: fileInfo.file,
|
|
1006
|
+
rootDir: fileInfo.rootDir,
|
|
1007
|
+
prefix: params.prefix
|
|
1008
|
+
});
|
|
1009
|
+
const reason = effectiveExclude && matchesFilter(fileInfo.file, void 0, effectiveExclude) ? "exclude" : "include";
|
|
1010
|
+
params.onSkip?.({
|
|
1011
|
+
file: fileInfo.file,
|
|
1012
|
+
reason,
|
|
1013
|
+
method: resolved?.method,
|
|
1014
|
+
url: resolved?.url
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
891
1017
|
continue;
|
|
892
1018
|
}
|
|
893
1019
|
const derived = deriveRouteFromFile(fileInfo.file, fileInfo.rootDir, params.logger);
|
|
@@ -899,6 +1025,23 @@ async function scanRoutes(params) {
|
|
|
899
1025
|
if (!rule || typeof rule !== "object") {
|
|
900
1026
|
continue;
|
|
901
1027
|
}
|
|
1028
|
+
if (rule.enabled === false) {
|
|
1029
|
+
if (shouldCollectSkip) {
|
|
1030
|
+
const resolved2 = resolveSkipRoute({
|
|
1031
|
+
file: fileInfo.file,
|
|
1032
|
+
rootDir: fileInfo.rootDir,
|
|
1033
|
+
prefix: params.prefix,
|
|
1034
|
+
derived
|
|
1035
|
+
});
|
|
1036
|
+
params.onSkip?.({
|
|
1037
|
+
file: fileInfo.file,
|
|
1038
|
+
reason: "disabled",
|
|
1039
|
+
method: resolved2?.method,
|
|
1040
|
+
url: resolved2?.url
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
902
1045
|
const ruleValue = rule;
|
|
903
1046
|
const unsupportedKeys = ["response", "url", "method"].filter(
|
|
904
1047
|
(key2) => key2 in ruleValue
|
|
@@ -999,6 +1142,7 @@ function buildApp(params) {
|
|
|
999
1142
|
registerPlaygroundRoutes({
|
|
1000
1143
|
app,
|
|
1001
1144
|
routes: params.routes,
|
|
1145
|
+
disabledRoutes: params.disabledRoutes,
|
|
1002
1146
|
dirs: params.dirs,
|
|
1003
1147
|
logger: params.logger,
|
|
1004
1148
|
config: params.playground,
|
|
@@ -1162,8 +1306,10 @@ async function createFetchServer(options = {}) {
|
|
|
1162
1306
|
}
|
|
1163
1307
|
}
|
|
1164
1308
|
let routes = [];
|
|
1309
|
+
let disabledRoutes = [];
|
|
1165
1310
|
let app = buildApp({
|
|
1166
1311
|
routes,
|
|
1312
|
+
disabledRoutes,
|
|
1167
1313
|
dirs,
|
|
1168
1314
|
playground: playgroundConfig,
|
|
1169
1315
|
root,
|
|
@@ -1174,11 +1320,13 @@ async function createFetchServer(options = {}) {
|
|
|
1174
1320
|
const refreshRoutes = async () => {
|
|
1175
1321
|
try {
|
|
1176
1322
|
const collected = [];
|
|
1323
|
+
const collectedDisabled = [];
|
|
1177
1324
|
for (const entry of optionList) {
|
|
1178
1325
|
const scanParams = {
|
|
1179
1326
|
dirs: resolveDirs(entry.dir, root),
|
|
1180
1327
|
prefix: entry.prefix ?? "",
|
|
1181
|
-
logger
|
|
1328
|
+
logger,
|
|
1329
|
+
onSkip: (info) => collectedDisabled.push(info)
|
|
1182
1330
|
};
|
|
1183
1331
|
if (entry.include) {
|
|
1184
1332
|
scanParams.include = entry.include;
|
|
@@ -1186,13 +1334,18 @@ async function createFetchServer(options = {}) {
|
|
|
1186
1334
|
if (entry.exclude) {
|
|
1187
1335
|
scanParams.exclude = entry.exclude;
|
|
1188
1336
|
}
|
|
1337
|
+
if (typeof entry.ignorePrefix !== "undefined") {
|
|
1338
|
+
scanParams.ignorePrefix = entry.ignorePrefix;
|
|
1339
|
+
}
|
|
1189
1340
|
const scanned = await scanRoutes(scanParams);
|
|
1190
1341
|
collected.push(...scanned);
|
|
1191
1342
|
}
|
|
1192
1343
|
const resolvedRoutes = sortRoutes(collected);
|
|
1193
1344
|
routes = resolvedRoutes;
|
|
1345
|
+
disabledRoutes = collectedDisabled;
|
|
1194
1346
|
app = buildApp({
|
|
1195
1347
|
routes,
|
|
1348
|
+
disabledRoutes,
|
|
1196
1349
|
dirs,
|
|
1197
1350
|
playground: playgroundConfig,
|
|
1198
1351
|
root,
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createRuntime, compareRouteScore, parseRouteTemplate } from '@mokup/run
|
|
|
2
2
|
import { t as toRuntimeOptions, a as toRuntimeRequestFromNode, b as applyRuntimeResultToNode, d as toBinaryBody, c as createFetchHandler } from './shared/server.Dje1y79O.mjs';
|
|
3
3
|
import { cwd } from 'node:process';
|
|
4
4
|
import { Hono, PatternRouter } from '@mokup/shared/hono';
|
|
5
|
-
import { resolve, isAbsolute, join, normalize, extname, dirname,
|
|
5
|
+
import { resolve, isAbsolute, relative, join, normalize, extname, dirname, basename } from '@mokup/shared/pathe';
|
|
6
6
|
import { promises } from 'node:fs';
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
8
8
|
import { Buffer } from 'node:buffer';
|
|
@@ -138,6 +138,20 @@ function matchesFilter(file, include, exclude) {
|
|
|
138
138
|
}
|
|
139
139
|
return true;
|
|
140
140
|
}
|
|
141
|
+
function normalizeIgnorePrefix(value, fallback = ["."]) {
|
|
142
|
+
const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
|
|
143
|
+
return list.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
144
|
+
}
|
|
145
|
+
function hasIgnoredPrefix(file, rootDir, prefixes) {
|
|
146
|
+
if (prefixes.length === 0) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const relativePath = toPosix(relative(rootDir, file));
|
|
150
|
+
const segments = relativePath.split("/");
|
|
151
|
+
return segments.some(
|
|
152
|
+
(segment) => prefixes.some((prefix) => segment.startsWith(prefix))
|
|
153
|
+
);
|
|
154
|
+
}
|
|
141
155
|
function delay(ms) {
|
|
142
156
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
143
157
|
}
|
|
@@ -369,6 +383,20 @@ function resolveGroupRoot(dirs, serverRoot) {
|
|
|
369
383
|
}
|
|
370
384
|
return common;
|
|
371
385
|
}
|
|
386
|
+
const disabledReasonSet = /* @__PURE__ */ new Set([
|
|
387
|
+
"disabled",
|
|
388
|
+
"disabled-dir",
|
|
389
|
+
"exclude",
|
|
390
|
+
"ignore-prefix",
|
|
391
|
+
"include",
|
|
392
|
+
"unknown"
|
|
393
|
+
]);
|
|
394
|
+
function normalizeDisabledReason(reason) {
|
|
395
|
+
if (reason && disabledReasonSet.has(reason)) {
|
|
396
|
+
return reason;
|
|
397
|
+
}
|
|
398
|
+
return "unknown";
|
|
399
|
+
}
|
|
372
400
|
function formatRouteFile(file, root) {
|
|
373
401
|
if (!root) {
|
|
374
402
|
return toPosixPath(file);
|
|
@@ -429,6 +457,17 @@ function toPlaygroundRoute(route, root, groups) {
|
|
|
429
457
|
group: matchedGroup?.label
|
|
430
458
|
};
|
|
431
459
|
}
|
|
460
|
+
function toPlaygroundDisabledRoute(route, root, groups) {
|
|
461
|
+
const matchedGroup = resolveRouteGroup(route.file, groups);
|
|
462
|
+
return {
|
|
463
|
+
file: formatRouteFile(route.file, root),
|
|
464
|
+
reason: normalizeDisabledReason(route.reason),
|
|
465
|
+
method: route.method,
|
|
466
|
+
url: route.url,
|
|
467
|
+
groupKey: matchedGroup?.key,
|
|
468
|
+
group: matchedGroup?.label
|
|
469
|
+
};
|
|
470
|
+
}
|
|
432
471
|
function registerPlaygroundRoutes(params) {
|
|
433
472
|
if (!params.config.enabled) {
|
|
434
473
|
return;
|
|
@@ -466,7 +505,8 @@ function registerPlaygroundRoutes(params) {
|
|
|
466
505
|
root: baseRoot,
|
|
467
506
|
count: params.routes.length,
|
|
468
507
|
groups: groups.map((group) => ({ key: group.key, label: group.label })),
|
|
469
|
-
routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups))
|
|
508
|
+
routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups)),
|
|
509
|
+
disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups))
|
|
470
510
|
});
|
|
471
511
|
});
|
|
472
512
|
params.app.get(`${playgroundPath}/*`, async (c) => {
|
|
@@ -733,6 +773,15 @@ async function resolveDirectoryConfig(params) {
|
|
|
733
773
|
if (typeof config.enabled === "boolean") {
|
|
734
774
|
merged.enabled = config.enabled;
|
|
735
775
|
}
|
|
776
|
+
if (typeof config.ignorePrefix !== "undefined") {
|
|
777
|
+
merged.ignorePrefix = config.ignorePrefix;
|
|
778
|
+
}
|
|
779
|
+
if (typeof config.include !== "undefined") {
|
|
780
|
+
merged.include = config.include;
|
|
781
|
+
}
|
|
782
|
+
if (typeof config.exclude !== "undefined") {
|
|
783
|
+
merged.exclude = config.exclude;
|
|
784
|
+
}
|
|
736
785
|
const normalized = normalizeMiddlewares(config.middleware, configPath, logger);
|
|
737
786
|
if (normalized.length > 0) {
|
|
738
787
|
merged.middlewares.push(...normalized);
|
|
@@ -864,19 +913,44 @@ async function loadRules(file, logger) {
|
|
|
864
913
|
return [value];
|
|
865
914
|
}
|
|
866
915
|
|
|
916
|
+
const silentLogger = {
|
|
917
|
+
info: () => {
|
|
918
|
+
},
|
|
919
|
+
warn: () => {
|
|
920
|
+
},
|
|
921
|
+
error: () => {
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
function resolveSkipRoute(params) {
|
|
925
|
+
const derived = params.derived ?? deriveRouteFromFile(params.file, params.rootDir, silentLogger);
|
|
926
|
+
if (!derived?.method) {
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
const resolved = resolveRule({
|
|
930
|
+
rule: { handler: null },
|
|
931
|
+
derivedTemplate: derived.template,
|
|
932
|
+
derivedMethod: derived.method,
|
|
933
|
+
prefix: params.prefix,
|
|
934
|
+
file: params.file,
|
|
935
|
+
logger: silentLogger
|
|
936
|
+
});
|
|
937
|
+
if (!resolved) {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
return {
|
|
941
|
+
method: resolved.method,
|
|
942
|
+
url: resolved.template
|
|
943
|
+
};
|
|
944
|
+
}
|
|
867
945
|
async function scanRoutes(params) {
|
|
868
946
|
const routes = [];
|
|
869
947
|
const seen = /* @__PURE__ */ new Set();
|
|
870
948
|
const files = await collectFiles(params.dirs);
|
|
949
|
+
const globalIgnorePrefix = normalizeIgnorePrefix(params.ignorePrefix);
|
|
871
950
|
const configCache = /* @__PURE__ */ new Map();
|
|
872
951
|
const fileCache = /* @__PURE__ */ new Map();
|
|
952
|
+
const shouldCollectSkip = typeof params.onSkip === "function";
|
|
873
953
|
for (const fileInfo of files) {
|
|
874
|
-
if (!isSupportedFile(fileInfo.file)) {
|
|
875
|
-
continue;
|
|
876
|
-
}
|
|
877
|
-
if (!matchesFilter(fileInfo.file, params.include, params.exclude)) {
|
|
878
|
-
continue;
|
|
879
|
-
}
|
|
880
954
|
const config = await resolveDirectoryConfig({
|
|
881
955
|
file: fileInfo.file,
|
|
882
956
|
rootDir: fileInfo.rootDir,
|
|
@@ -885,6 +959,58 @@ async function scanRoutes(params) {
|
|
|
885
959
|
fileCache
|
|
886
960
|
});
|
|
887
961
|
if (config.enabled === false) {
|
|
962
|
+
if (shouldCollectSkip && isSupportedFile(fileInfo.file)) {
|
|
963
|
+
const resolved = resolveSkipRoute({
|
|
964
|
+
file: fileInfo.file,
|
|
965
|
+
rootDir: fileInfo.rootDir,
|
|
966
|
+
prefix: params.prefix
|
|
967
|
+
});
|
|
968
|
+
params.onSkip?.({
|
|
969
|
+
file: fileInfo.file,
|
|
970
|
+
reason: "disabled-dir",
|
|
971
|
+
method: resolved?.method,
|
|
972
|
+
url: resolved?.url
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
const effectiveIgnorePrefix = typeof config.ignorePrefix !== "undefined" ? normalizeIgnorePrefix(config.ignorePrefix, []) : globalIgnorePrefix;
|
|
978
|
+
if (hasIgnoredPrefix(fileInfo.file, fileInfo.rootDir, effectiveIgnorePrefix)) {
|
|
979
|
+
if (shouldCollectSkip && isSupportedFile(fileInfo.file)) {
|
|
980
|
+
const resolved = resolveSkipRoute({
|
|
981
|
+
file: fileInfo.file,
|
|
982
|
+
rootDir: fileInfo.rootDir,
|
|
983
|
+
prefix: params.prefix
|
|
984
|
+
});
|
|
985
|
+
params.onSkip?.({
|
|
986
|
+
file: fileInfo.file,
|
|
987
|
+
reason: "ignore-prefix",
|
|
988
|
+
method: resolved?.method,
|
|
989
|
+
url: resolved?.url
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
continue;
|
|
993
|
+
}
|
|
994
|
+
if (!isSupportedFile(fileInfo.file)) {
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
const effectiveInclude = typeof config.include !== "undefined" ? config.include : params.include;
|
|
998
|
+
const effectiveExclude = typeof config.exclude !== "undefined" ? config.exclude : params.exclude;
|
|
999
|
+
if (!matchesFilter(fileInfo.file, effectiveInclude, effectiveExclude)) {
|
|
1000
|
+
if (shouldCollectSkip) {
|
|
1001
|
+
const resolved = resolveSkipRoute({
|
|
1002
|
+
file: fileInfo.file,
|
|
1003
|
+
rootDir: fileInfo.rootDir,
|
|
1004
|
+
prefix: params.prefix
|
|
1005
|
+
});
|
|
1006
|
+
const reason = effectiveExclude && matchesFilter(fileInfo.file, void 0, effectiveExclude) ? "exclude" : "include";
|
|
1007
|
+
params.onSkip?.({
|
|
1008
|
+
file: fileInfo.file,
|
|
1009
|
+
reason,
|
|
1010
|
+
method: resolved?.method,
|
|
1011
|
+
url: resolved?.url
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
888
1014
|
continue;
|
|
889
1015
|
}
|
|
890
1016
|
const derived = deriveRouteFromFile(fileInfo.file, fileInfo.rootDir, params.logger);
|
|
@@ -896,6 +1022,23 @@ async function scanRoutes(params) {
|
|
|
896
1022
|
if (!rule || typeof rule !== "object") {
|
|
897
1023
|
continue;
|
|
898
1024
|
}
|
|
1025
|
+
if (rule.enabled === false) {
|
|
1026
|
+
if (shouldCollectSkip) {
|
|
1027
|
+
const resolved2 = resolveSkipRoute({
|
|
1028
|
+
file: fileInfo.file,
|
|
1029
|
+
rootDir: fileInfo.rootDir,
|
|
1030
|
+
prefix: params.prefix,
|
|
1031
|
+
derived
|
|
1032
|
+
});
|
|
1033
|
+
params.onSkip?.({
|
|
1034
|
+
file: fileInfo.file,
|
|
1035
|
+
reason: "disabled",
|
|
1036
|
+
method: resolved2?.method,
|
|
1037
|
+
url: resolved2?.url
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
899
1042
|
const ruleValue = rule;
|
|
900
1043
|
const unsupportedKeys = ["response", "url", "method"].filter(
|
|
901
1044
|
(key2) => key2 in ruleValue
|
|
@@ -996,6 +1139,7 @@ function buildApp(params) {
|
|
|
996
1139
|
registerPlaygroundRoutes({
|
|
997
1140
|
app,
|
|
998
1141
|
routes: params.routes,
|
|
1142
|
+
disabledRoutes: params.disabledRoutes,
|
|
999
1143
|
dirs: params.dirs,
|
|
1000
1144
|
logger: params.logger,
|
|
1001
1145
|
config: params.playground,
|
|
@@ -1159,8 +1303,10 @@ async function createFetchServer(options = {}) {
|
|
|
1159
1303
|
}
|
|
1160
1304
|
}
|
|
1161
1305
|
let routes = [];
|
|
1306
|
+
let disabledRoutes = [];
|
|
1162
1307
|
let app = buildApp({
|
|
1163
1308
|
routes,
|
|
1309
|
+
disabledRoutes,
|
|
1164
1310
|
dirs,
|
|
1165
1311
|
playground: playgroundConfig,
|
|
1166
1312
|
root,
|
|
@@ -1171,11 +1317,13 @@ async function createFetchServer(options = {}) {
|
|
|
1171
1317
|
const refreshRoutes = async () => {
|
|
1172
1318
|
try {
|
|
1173
1319
|
const collected = [];
|
|
1320
|
+
const collectedDisabled = [];
|
|
1174
1321
|
for (const entry of optionList) {
|
|
1175
1322
|
const scanParams = {
|
|
1176
1323
|
dirs: resolveDirs(entry.dir, root),
|
|
1177
1324
|
prefix: entry.prefix ?? "",
|
|
1178
|
-
logger
|
|
1325
|
+
logger,
|
|
1326
|
+
onSkip: (info) => collectedDisabled.push(info)
|
|
1179
1327
|
};
|
|
1180
1328
|
if (entry.include) {
|
|
1181
1329
|
scanParams.include = entry.include;
|
|
@@ -1183,13 +1331,18 @@ async function createFetchServer(options = {}) {
|
|
|
1183
1331
|
if (entry.exclude) {
|
|
1184
1332
|
scanParams.exclude = entry.exclude;
|
|
1185
1333
|
}
|
|
1334
|
+
if (typeof entry.ignorePrefix !== "undefined") {
|
|
1335
|
+
scanParams.ignorePrefix = entry.ignorePrefix;
|
|
1336
|
+
}
|
|
1186
1337
|
const scanned = await scanRoutes(scanParams);
|
|
1187
1338
|
collected.push(...scanned);
|
|
1188
1339
|
}
|
|
1189
1340
|
const resolvedRoutes = sortRoutes(collected);
|
|
1190
1341
|
routes = resolvedRoutes;
|
|
1342
|
+
disabledRoutes = collectedDisabled;
|
|
1191
1343
|
app = buildApp({
|
|
1192
1344
|
routes,
|
|
1345
|
+
disabledRoutes,
|
|
1193
1346
|
dirs,
|
|
1194
1347
|
playground: playgroundConfig,
|
|
1195
1348
|
root,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mokup/server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.4",
|
|
5
5
|
"description": "Server adapters for @mokup/runtime.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://mokup.icebreaker.top",
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@hono/node-server": "^1.19.9",
|
|
41
41
|
"@hono/node-ws": "^1.1.1",
|
|
42
|
+
"@mokup/playground": "0.0.8",
|
|
42
43
|
"@mokup/runtime": "1.0.0",
|
|
43
|
-
"@mokup/playground": "0.0.7",
|
|
44
44
|
"@mokup/shared": "1.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@types/node": "^25.0.
|
|
47
|
+
"@types/node": "^25.0.10",
|
|
48
48
|
"typescript": "^5.9.3",
|
|
49
49
|
"unbuild": "^3.6.1"
|
|
50
50
|
},
|