@mokup/server 1.1.0 → 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 CHANGED
@@ -93,6 +93,7 @@ const supportedExtensions = /* @__PURE__ */ new Set([
93
93
  ".mjs",
94
94
  ".cjs"
95
95
  ]);
96
+ const configExtensions = [".ts", ".js", ".mjs", ".cjs"];
96
97
 
97
98
  function normalizePrefix(prefix) {
98
99
  if (!prefix) {
@@ -398,12 +399,23 @@ const disabledReasonSet = /* @__PURE__ */ new Set([
398
399
  "include",
399
400
  "unknown"
400
401
  ]);
402
+ const ignoredReasonSet = /* @__PURE__ */ new Set([
403
+ "unsupported",
404
+ "invalid-route",
405
+ "unknown"
406
+ ]);
401
407
  function normalizeDisabledReason(reason) {
402
408
  if (reason && disabledReasonSet.has(reason)) {
403
409
  return reason;
404
410
  }
405
411
  return "unknown";
406
412
  }
413
+ function normalizeIgnoredReason(reason) {
414
+ if (reason && ignoredReasonSet.has(reason)) {
415
+ return reason;
416
+ }
417
+ return "unknown";
418
+ }
407
419
  function formatRouteFile(file, root) {
408
420
  if (!root) {
409
421
  return toPosixPath(file);
@@ -482,6 +494,29 @@ function toPlaygroundDisabledRoute(route, root, groups) {
482
494
  }
483
495
  return disabled;
484
496
  }
497
+ function toPlaygroundIgnoredRoute(route, root, groups) {
498
+ const matchedGroup = resolveRouteGroup(route.file, groups);
499
+ const ignored = {
500
+ file: formatRouteFile(route.file, root),
501
+ reason: normalizeIgnoredReason(route.reason)
502
+ };
503
+ if (matchedGroup) {
504
+ ignored.groupKey = matchedGroup.key;
505
+ ignored.group = matchedGroup.label;
506
+ }
507
+ return ignored;
508
+ }
509
+ function toPlaygroundConfigFile(entry, root, groups) {
510
+ const matchedGroup = resolveRouteGroup(entry.file, groups);
511
+ const configFile = {
512
+ file: formatRouteFile(entry.file, root)
513
+ };
514
+ if (matchedGroup) {
515
+ configFile.groupKey = matchedGroup.key;
516
+ configFile.group = matchedGroup.label;
517
+ }
518
+ return configFile;
519
+ }
485
520
  function registerPlaygroundRoutes(params) {
486
521
  if (!params.config.enabled) {
487
522
  return;
@@ -520,7 +555,12 @@ function registerPlaygroundRoutes(params) {
520
555
  count: params.routes.length,
521
556
  groups: groups.map((group) => ({ key: group.key, label: group.label })),
522
557
  routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups)),
523
- disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups))
558
+ disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups)),
559
+ ignored: (params.ignoredRoutes ?? []).map((route) => toPlaygroundIgnoredRoute(route, baseRoot, groups)),
560
+ configs: (params.configFiles ?? []).map((entry) => toPlaygroundConfigFile(entry, baseRoot, groups)),
561
+ disabledConfigs: (params.disabledConfigFiles ?? []).map(
562
+ (entry) => toPlaygroundConfigFile(entry, baseRoot, groups)
563
+ )
524
564
  });
525
565
  });
526
566
  params.app.get(`${playgroundPath}/*`, async (c) => {
@@ -697,7 +737,6 @@ async function ensureTsxRegister(logger) {
697
737
  return registerPromise;
698
738
  }
699
739
 
700
- const configExtensions = [".ts", ".js", ".mjs", ".cjs"];
701
740
  function isUnknownFileExtensionError$1(error) {
702
741
  if (!error || typeof error !== "object") {
703
742
  return false;
@@ -899,12 +938,23 @@ function isSupportedFile(file) {
899
938
  if (file.endsWith(".d.ts")) {
900
939
  return false;
901
940
  }
902
- if (pathe.basename(file).startsWith("index.config.")) {
941
+ if (isConfigFile(file)) {
903
942
  return false;
904
943
  }
905
944
  const ext = pathe.extname(file).toLowerCase();
906
945
  return supportedExtensions.has(ext);
907
946
  }
947
+ function isConfigFile(file) {
948
+ if (file.endsWith(".d.ts")) {
949
+ return false;
950
+ }
951
+ const base = pathe.basename(file);
952
+ if (!base.startsWith("index.config.")) {
953
+ return false;
954
+ }
955
+ const ext = pathe.extname(file).toLowerCase();
956
+ return configExtensions.includes(ext);
957
+ }
908
958
 
909
959
  function isUnknownFileExtensionError(error) {
910
960
  if (!error || typeof error !== "object") {
@@ -1055,7 +1105,22 @@ async function scanRoutes(params) {
1055
1105
  const configCache = /* @__PURE__ */ new Map();
1056
1106
  const fileCache = /* @__PURE__ */ new Map();
1057
1107
  const shouldCollectSkip = typeof params.onSkip === "function";
1108
+ const shouldCollectIgnore = typeof params.onIgnore === "function";
1109
+ const shouldCollectConfig = typeof params.onConfig === "function";
1058
1110
  for (const fileInfo of files) {
1111
+ if (isConfigFile(fileInfo.file)) {
1112
+ if (shouldCollectConfig) {
1113
+ const config2 = await resolveDirectoryConfig({
1114
+ file: fileInfo.file,
1115
+ rootDir: fileInfo.rootDir,
1116
+ logger: params.logger,
1117
+ configCache,
1118
+ fileCache
1119
+ });
1120
+ params.onConfig?.({ file: fileInfo.file, enabled: config2.enabled !== false });
1121
+ }
1122
+ continue;
1123
+ }
1059
1124
  const config = await resolveDirectoryConfig({
1060
1125
  file: fileInfo.file,
1061
1126
  rootDir: fileInfo.rootDir,
@@ -1087,6 +1152,9 @@ async function scanRoutes(params) {
1087
1152
  continue;
1088
1153
  }
1089
1154
  if (!isSupportedFile(fileInfo.file)) {
1155
+ if (shouldCollectIgnore) {
1156
+ params.onIgnore?.({ file: fileInfo.file, reason: "unsupported" });
1157
+ }
1090
1158
  continue;
1091
1159
  }
1092
1160
  const effectiveInclude = typeof config.include !== "undefined" ? config.include : params.include;
@@ -1105,6 +1173,9 @@ async function scanRoutes(params) {
1105
1173
  }
1106
1174
  const derived = deriveRouteFromFile(fileInfo.file, fileInfo.rootDir, params.logger);
1107
1175
  if (!derived) {
1176
+ if (shouldCollectIgnore) {
1177
+ params.onIgnore?.({ file: fileInfo.file, reason: "invalid-route" });
1178
+ }
1108
1179
  continue;
1109
1180
  }
1110
1181
  const rules = await loadRules(fileInfo.file, params.logger);
@@ -1225,6 +1296,9 @@ function buildApp(params) {
1225
1296
  app,
1226
1297
  routes: params.routes,
1227
1298
  disabledRoutes: params.disabledRoutes,
1299
+ ignoredRoutes: params.ignoredRoutes,
1300
+ configFiles: params.configFiles,
1301
+ disabledConfigFiles: params.disabledConfigFiles,
1228
1302
  dirs: params.dirs,
1229
1303
  logger: params.logger,
1230
1304
  config: params.playground,
@@ -1390,9 +1464,15 @@ async function createFetchServer(options = {}) {
1390
1464
  }
1391
1465
  let routes = [];
1392
1466
  let disabledRoutes = [];
1467
+ let ignoredRoutes = [];
1468
+ let configFiles = [];
1469
+ let disabledConfigFiles = [];
1393
1470
  let app = buildApp({
1394
1471
  routes,
1395
1472
  disabledRoutes,
1473
+ ignoredRoutes,
1474
+ configFiles,
1475
+ disabledConfigFiles,
1396
1476
  dirs,
1397
1477
  playground: playgroundConfig,
1398
1478
  root,
@@ -1404,12 +1484,16 @@ async function createFetchServer(options = {}) {
1404
1484
  try {
1405
1485
  const collected = [];
1406
1486
  const collectedDisabled = [];
1487
+ const collectedIgnored = [];
1488
+ const collectedConfigs = [];
1407
1489
  for (const entry of optionList) {
1408
1490
  const scanParams = {
1409
1491
  dirs: resolveDirs(entry.dir, root),
1410
1492
  prefix: entry.prefix ?? "",
1411
1493
  logger,
1412
- onSkip: (info) => collectedDisabled.push(info)
1494
+ onSkip: (info) => collectedDisabled.push(info),
1495
+ onIgnore: (info) => collectedIgnored.push(info),
1496
+ onConfig: (info) => collectedConfigs.push(info)
1413
1497
  };
1414
1498
  if (entry.include) {
1415
1499
  scanParams.include = entry.include;
@@ -1426,9 +1510,17 @@ async function createFetchServer(options = {}) {
1426
1510
  const resolvedRoutes = sortRoutes(collected);
1427
1511
  routes = resolvedRoutes;
1428
1512
  disabledRoutes = collectedDisabled;
1513
+ ignoredRoutes = collectedIgnored;
1514
+ const configMap = new Map(collectedConfigs.map((entry) => [entry.file, entry]));
1515
+ const resolvedConfigs = Array.from(configMap.values());
1516
+ configFiles = resolvedConfigs.filter((entry) => entry.enabled);
1517
+ disabledConfigFiles = resolvedConfigs.filter((entry) => !entry.enabled);
1429
1518
  app = buildApp({
1430
1519
  routes,
1431
1520
  disabledRoutes,
1521
+ ignoredRoutes,
1522
+ configFiles,
1523
+ disabledConfigFiles,
1432
1524
  dirs,
1433
1525
  playground: playgroundConfig,
1434
1526
  root,
package/dist/index.d.cts CHANGED
@@ -41,8 +41,10 @@ declare function createFastifyPlugin(options: ServerOptions): (instance: Fastify
41
41
  declare function createFetchHandler(options: ServerOptions): FetchHandler;
42
42
 
43
43
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
44
- type RequestHandler = (context: Context) => Response | Promise<Response> | unknown;
45
- type RouteResponse = unknown | RequestHandler;
44
+ type RouteStaticResponse = string | number | boolean | bigint | symbol | null | undefined | object;
45
+ type RouteHandlerResult = RouteStaticResponse | Response;
46
+ type RequestHandler = (context: Context) => RouteHandlerResult | Promise<RouteHandlerResult>;
47
+ type RouteResponse = RouteStaticResponse | RequestHandler;
46
48
  interface ResolvedMiddleware {
47
49
  handle: MiddlewareHandler;
48
50
  source: string;
package/dist/index.d.mts CHANGED
@@ -41,8 +41,10 @@ declare function createFastifyPlugin(options: ServerOptions): (instance: Fastify
41
41
  declare function createFetchHandler(options: ServerOptions): FetchHandler;
42
42
 
43
43
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
44
- type RequestHandler = (context: Context) => Response | Promise<Response> | unknown;
45
- type RouteResponse = unknown | RequestHandler;
44
+ type RouteStaticResponse = string | number | boolean | bigint | symbol | null | undefined | object;
45
+ type RouteHandlerResult = RouteStaticResponse | Response;
46
+ type RequestHandler = (context: Context) => RouteHandlerResult | Promise<RouteHandlerResult>;
47
+ type RouteResponse = RouteStaticResponse | RequestHandler;
46
48
  interface ResolvedMiddleware {
47
49
  handle: MiddlewareHandler;
48
50
  source: string;
package/dist/index.d.ts CHANGED
@@ -41,8 +41,10 @@ declare function createFastifyPlugin(options: ServerOptions): (instance: Fastify
41
41
  declare function createFetchHandler(options: ServerOptions): FetchHandler;
42
42
 
43
43
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
44
- type RequestHandler = (context: Context) => Response | Promise<Response> | unknown;
45
- type RouteResponse = unknown | RequestHandler;
44
+ type RouteStaticResponse = string | number | boolean | bigint | symbol | null | undefined | object;
45
+ type RouteHandlerResult = RouteStaticResponse | Response;
46
+ type RequestHandler = (context: Context) => RouteHandlerResult | Promise<RouteHandlerResult>;
47
+ type RouteResponse = RouteStaticResponse | RequestHandler;
46
48
  interface ResolvedMiddleware {
47
49
  handle: MiddlewareHandler;
48
50
  source: string;
package/dist/index.mjs CHANGED
@@ -86,6 +86,7 @@ const supportedExtensions = /* @__PURE__ */ new Set([
86
86
  ".mjs",
87
87
  ".cjs"
88
88
  ]);
89
+ const configExtensions = [".ts", ".js", ".mjs", ".cjs"];
89
90
 
90
91
  function normalizePrefix(prefix) {
91
92
  if (!prefix) {
@@ -391,12 +392,23 @@ const disabledReasonSet = /* @__PURE__ */ new Set([
391
392
  "include",
392
393
  "unknown"
393
394
  ]);
395
+ const ignoredReasonSet = /* @__PURE__ */ new Set([
396
+ "unsupported",
397
+ "invalid-route",
398
+ "unknown"
399
+ ]);
394
400
  function normalizeDisabledReason(reason) {
395
401
  if (reason && disabledReasonSet.has(reason)) {
396
402
  return reason;
397
403
  }
398
404
  return "unknown";
399
405
  }
406
+ function normalizeIgnoredReason(reason) {
407
+ if (reason && ignoredReasonSet.has(reason)) {
408
+ return reason;
409
+ }
410
+ return "unknown";
411
+ }
400
412
  function formatRouteFile(file, root) {
401
413
  if (!root) {
402
414
  return toPosixPath(file);
@@ -475,6 +487,29 @@ function toPlaygroundDisabledRoute(route, root, groups) {
475
487
  }
476
488
  return disabled;
477
489
  }
490
+ function toPlaygroundIgnoredRoute(route, root, groups) {
491
+ const matchedGroup = resolveRouteGroup(route.file, groups);
492
+ const ignored = {
493
+ file: formatRouteFile(route.file, root),
494
+ reason: normalizeIgnoredReason(route.reason)
495
+ };
496
+ if (matchedGroup) {
497
+ ignored.groupKey = matchedGroup.key;
498
+ ignored.group = matchedGroup.label;
499
+ }
500
+ return ignored;
501
+ }
502
+ function toPlaygroundConfigFile(entry, root, groups) {
503
+ const matchedGroup = resolveRouteGroup(entry.file, groups);
504
+ const configFile = {
505
+ file: formatRouteFile(entry.file, root)
506
+ };
507
+ if (matchedGroup) {
508
+ configFile.groupKey = matchedGroup.key;
509
+ configFile.group = matchedGroup.label;
510
+ }
511
+ return configFile;
512
+ }
478
513
  function registerPlaygroundRoutes(params) {
479
514
  if (!params.config.enabled) {
480
515
  return;
@@ -513,7 +548,12 @@ function registerPlaygroundRoutes(params) {
513
548
  count: params.routes.length,
514
549
  groups: groups.map((group) => ({ key: group.key, label: group.label })),
515
550
  routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups)),
516
- disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups))
551
+ disabled: (params.disabledRoutes ?? []).map((route) => toPlaygroundDisabledRoute(route, baseRoot, groups)),
552
+ ignored: (params.ignoredRoutes ?? []).map((route) => toPlaygroundIgnoredRoute(route, baseRoot, groups)),
553
+ configs: (params.configFiles ?? []).map((entry) => toPlaygroundConfigFile(entry, baseRoot, groups)),
554
+ disabledConfigs: (params.disabledConfigFiles ?? []).map(
555
+ (entry) => toPlaygroundConfigFile(entry, baseRoot, groups)
556
+ )
517
557
  });
518
558
  });
519
559
  params.app.get(`${playgroundPath}/*`, async (c) => {
@@ -690,7 +730,6 @@ async function ensureTsxRegister(logger) {
690
730
  return registerPromise;
691
731
  }
692
732
 
693
- const configExtensions = [".ts", ".js", ".mjs", ".cjs"];
694
733
  function isUnknownFileExtensionError$1(error) {
695
734
  if (!error || typeof error !== "object") {
696
735
  return false;
@@ -892,12 +931,23 @@ function isSupportedFile(file) {
892
931
  if (file.endsWith(".d.ts")) {
893
932
  return false;
894
933
  }
895
- if (basename(file).startsWith("index.config.")) {
934
+ if (isConfigFile(file)) {
896
935
  return false;
897
936
  }
898
937
  const ext = extname(file).toLowerCase();
899
938
  return supportedExtensions.has(ext);
900
939
  }
940
+ function isConfigFile(file) {
941
+ if (file.endsWith(".d.ts")) {
942
+ return false;
943
+ }
944
+ const base = basename(file);
945
+ if (!base.startsWith("index.config.")) {
946
+ return false;
947
+ }
948
+ const ext = extname(file).toLowerCase();
949
+ return configExtensions.includes(ext);
950
+ }
901
951
 
902
952
  function isUnknownFileExtensionError(error) {
903
953
  if (!error || typeof error !== "object") {
@@ -1048,7 +1098,22 @@ async function scanRoutes(params) {
1048
1098
  const configCache = /* @__PURE__ */ new Map();
1049
1099
  const fileCache = /* @__PURE__ */ new Map();
1050
1100
  const shouldCollectSkip = typeof params.onSkip === "function";
1101
+ const shouldCollectIgnore = typeof params.onIgnore === "function";
1102
+ const shouldCollectConfig = typeof params.onConfig === "function";
1051
1103
  for (const fileInfo of files) {
1104
+ if (isConfigFile(fileInfo.file)) {
1105
+ if (shouldCollectConfig) {
1106
+ const config2 = await resolveDirectoryConfig({
1107
+ file: fileInfo.file,
1108
+ rootDir: fileInfo.rootDir,
1109
+ logger: params.logger,
1110
+ configCache,
1111
+ fileCache
1112
+ });
1113
+ params.onConfig?.({ file: fileInfo.file, enabled: config2.enabled !== false });
1114
+ }
1115
+ continue;
1116
+ }
1052
1117
  const config = await resolveDirectoryConfig({
1053
1118
  file: fileInfo.file,
1054
1119
  rootDir: fileInfo.rootDir,
@@ -1080,6 +1145,9 @@ async function scanRoutes(params) {
1080
1145
  continue;
1081
1146
  }
1082
1147
  if (!isSupportedFile(fileInfo.file)) {
1148
+ if (shouldCollectIgnore) {
1149
+ params.onIgnore?.({ file: fileInfo.file, reason: "unsupported" });
1150
+ }
1083
1151
  continue;
1084
1152
  }
1085
1153
  const effectiveInclude = typeof config.include !== "undefined" ? config.include : params.include;
@@ -1098,6 +1166,9 @@ async function scanRoutes(params) {
1098
1166
  }
1099
1167
  const derived = deriveRouteFromFile(fileInfo.file, fileInfo.rootDir, params.logger);
1100
1168
  if (!derived) {
1169
+ if (shouldCollectIgnore) {
1170
+ params.onIgnore?.({ file: fileInfo.file, reason: "invalid-route" });
1171
+ }
1101
1172
  continue;
1102
1173
  }
1103
1174
  const rules = await loadRules(fileInfo.file, params.logger);
@@ -1218,6 +1289,9 @@ function buildApp(params) {
1218
1289
  app,
1219
1290
  routes: params.routes,
1220
1291
  disabledRoutes: params.disabledRoutes,
1292
+ ignoredRoutes: params.ignoredRoutes,
1293
+ configFiles: params.configFiles,
1294
+ disabledConfigFiles: params.disabledConfigFiles,
1221
1295
  dirs: params.dirs,
1222
1296
  logger: params.logger,
1223
1297
  config: params.playground,
@@ -1383,9 +1457,15 @@ async function createFetchServer(options = {}) {
1383
1457
  }
1384
1458
  let routes = [];
1385
1459
  let disabledRoutes = [];
1460
+ let ignoredRoutes = [];
1461
+ let configFiles = [];
1462
+ let disabledConfigFiles = [];
1386
1463
  let app = buildApp({
1387
1464
  routes,
1388
1465
  disabledRoutes,
1466
+ ignoredRoutes,
1467
+ configFiles,
1468
+ disabledConfigFiles,
1389
1469
  dirs,
1390
1470
  playground: playgroundConfig,
1391
1471
  root,
@@ -1397,12 +1477,16 @@ async function createFetchServer(options = {}) {
1397
1477
  try {
1398
1478
  const collected = [];
1399
1479
  const collectedDisabled = [];
1480
+ const collectedIgnored = [];
1481
+ const collectedConfigs = [];
1400
1482
  for (const entry of optionList) {
1401
1483
  const scanParams = {
1402
1484
  dirs: resolveDirs(entry.dir, root),
1403
1485
  prefix: entry.prefix ?? "",
1404
1486
  logger,
1405
- onSkip: (info) => collectedDisabled.push(info)
1487
+ onSkip: (info) => collectedDisabled.push(info),
1488
+ onIgnore: (info) => collectedIgnored.push(info),
1489
+ onConfig: (info) => collectedConfigs.push(info)
1406
1490
  };
1407
1491
  if (entry.include) {
1408
1492
  scanParams.include = entry.include;
@@ -1419,9 +1503,17 @@ async function createFetchServer(options = {}) {
1419
1503
  const resolvedRoutes = sortRoutes(collected);
1420
1504
  routes = resolvedRoutes;
1421
1505
  disabledRoutes = collectedDisabled;
1506
+ ignoredRoutes = collectedIgnored;
1507
+ const configMap = new Map(collectedConfigs.map((entry) => [entry.file, entry]));
1508
+ const resolvedConfigs = Array.from(configMap.values());
1509
+ configFiles = resolvedConfigs.filter((entry) => entry.enabled);
1510
+ disabledConfigFiles = resolvedConfigs.filter((entry) => !entry.enabled);
1422
1511
  app = buildApp({
1423
1512
  routes,
1424
1513
  disabledRoutes,
1514
+ ignoredRoutes,
1515
+ configFiles,
1516
+ disabledConfigFiles,
1425
1517
  dirs,
1426
1518
  playground: playgroundConfig,
1427
1519
  root,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mokup/server",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "description": "Server adapters for @mokup/runtime.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://mokup.icebreaker.top",
@@ -40,8 +40,8 @@
40
40
  "@hono/node-server": "^1.19.9",
41
41
  "@hono/node-ws": "^1.1.1",
42
42
  "tsx": "^4.21.0",
43
- "@mokup/playground": "0.0.9",
44
- "@mokup/runtime": "1.0.0",
43
+ "@mokup/playground": "0.0.10",
44
+ "@mokup/runtime": "1.0.1",
45
45
  "@mokup/shared": "1.0.0"
46
46
  },
47
47
  "devDependencies": {