@antelopejs/dms-frontend 0.9.2 → 0.10.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.
Files changed (123) hide show
  1. package/README.md +18 -24
  2. package/dist/commands/build-action.js +3 -2
  3. package/dist/commands/dev-action.js +2 -1
  4. package/dist/commands/prepare-action.js +1 -1
  5. package/dist/commands/start-action.js +3 -24
  6. package/dist/commands/workspace-task.js +2 -1
  7. package/dist/config.js +3 -0
  8. package/dist/derived-outputs.js +3 -3
  9. package/dist/discovery.js +17 -6
  10. package/dist/entry-weight.js +15 -0
  11. package/dist/fs-sync.js +7 -4
  12. package/dist/index.js +2 -1
  13. package/dist/internal/built-workspace.d.ts +4 -0
  14. package/dist/internal/built-workspace.js +43 -0
  15. package/dist/internal/ensure.d.ts +1 -0
  16. package/dist/internal/ensure.js +8 -0
  17. package/dist/internal/locale-catalogs.d.ts +8 -3
  18. package/dist/internal/locale-catalogs.js +16 -6
  19. package/dist/internal/manifest-decoder.d.ts +7 -0
  20. package/dist/internal/manifest-decoder.js +81 -0
  21. package/dist/internal/own-release.d.ts +5 -0
  22. package/dist/internal/own-release.js +20 -0
  23. package/dist/internal/plain-object.d.ts +1 -0
  24. package/dist/internal/plain-object.js +6 -0
  25. package/dist/internal/text-list.d.ts +1 -0
  26. package/dist/internal/text-list.js +10 -0
  27. package/dist/internal/vite-manifest.d.ts +6 -0
  28. package/dist/internal/vite-manifest.js +24 -0
  29. package/dist/layer-watch.js +25 -24
  30. package/dist/layers.d.ts +1 -1
  31. package/dist/layers.js +3 -1
  32. package/dist/locale-files.d.ts +2 -1
  33. package/dist/locale-files.js +4 -0
  34. package/dist/manifest.d.ts +1 -1
  35. package/dist/manifest.js +44 -31
  36. package/dist/materialize.js +6 -2
  37. package/dist/module-set.js +2 -1
  38. package/dist/node-options.d.ts +1 -0
  39. package/dist/node-options.js +8 -0
  40. package/dist/output.d.ts +15 -9
  41. package/dist/output.js +30 -18
  42. package/dist/private-values.d.ts +1 -1
  43. package/dist/private-values.js +5 -3
  44. package/dist/project-modules.js +13 -8
  45. package/dist/renderer-range.js +5 -3
  46. package/dist/server-process.js +1 -1
  47. package/dist/verify-source-build.js +10 -2
  48. package/dist/verify-source-client-bundle.d.ts +1 -0
  49. package/dist/verify-source-client-bundle.js +30 -0
  50. package/dist/verify-source-runner.js +44 -60
  51. package/dist/verify-source-sources.js +49 -11
  52. package/dist/workspace-setup.js +1 -1
  53. package/package.json +6 -4
  54. package/skills/dms-frontend/SKILL.md +1 -1
  55. package/templates/vue/app-runtime.ts +90 -16
  56. package/templates/vue/client-server-guard.mjs +16 -0
  57. package/templates/vue/compress-assets.mjs +9 -1
  58. package/templates/vue/entry-weight.mjs +22 -0
  59. package/templates/vue/frontend-module.ts +1 -0
  60. package/templates/vue/frontend-runtime/module-registration.ts +2 -2
  61. package/templates/vue/frontend-runtime/state.ts +2 -2
  62. package/templates/vue/frontend-runtime/types.ts +8 -2
  63. package/templates/vue/globals.d.ts +5 -0
  64. package/templates/vue/head-order.mjs +7 -0
  65. package/templates/vue/icon-bundle.ts +31 -0
  66. package/templates/vue/icon-scan.mjs +4 -0
  67. package/templates/vue/message-subset.ts +65 -0
  68. package/templates/vue/network-error.ts +4 -0
  69. package/templates/vue/server/auth/backend.mjs +41 -4
  70. package/templates/vue/server/auth/client-ip.mjs +52 -4
  71. package/templates/vue/server/auth/establish-endpoints.mjs +10 -6
  72. package/templates/vue/server/auth/session.mjs +81 -2
  73. package/templates/vue/server/auth-hooks.mjs +15 -5
  74. package/templates/vue/server/backend-proxies.mjs +65 -9
  75. package/templates/vue/server/backend-request.mjs +61 -0
  76. package/templates/vue/server/backend-response.mjs +23 -6
  77. package/templates/vue/server/built-files.mjs +7 -0
  78. package/templates/vue/server/cli-report.mjs +53 -11
  79. package/templates/vue/server/client-manifest.mjs +23 -1
  80. package/templates/vue/server/content.mjs +18 -1
  81. package/templates/vue/server/dev-private-files.mjs +17 -1
  82. package/templates/vue/server/dev-styles.mjs +38 -0
  83. package/templates/vue/server/email.mjs +9 -3
  84. package/templates/vue/server/favicon.mjs +3 -0
  85. package/templates/vue/server/generated-files.mjs +211 -0
  86. package/templates/vue/server/homepage.mjs +21 -9
  87. package/templates/vue/server/html-tag.mjs +4 -0
  88. package/templates/vue/server/icons.mjs +80 -7
  89. package/templates/vue/server/in-place-render.mjs +35 -0
  90. package/templates/vue/server/inertia.mjs +61 -2
  91. package/templates/vue/server/module-event.mjs +98 -17
  92. package/templates/vue/server/module-route-types.mjs +78 -0
  93. package/templates/vue/server/module-routes.mjs +138 -31
  94. package/templates/vue/server/module-server.mjs +98 -27
  95. package/templates/vue/server/module-testing.mjs +14 -5
  96. package/templates/vue/server/page-props.mjs +92 -2
  97. package/templates/vue/server/page-redirects.mjs +37 -0
  98. package/templates/vue/server/path-patterns.mjs +13 -1
  99. package/templates/vue/server/proxy-compression.mjs +22 -0
  100. package/templates/vue/server/proxy-headers.mjs +11 -1
  101. package/templates/vue/server/proxy-redirects.mjs +20 -5
  102. package/templates/vue/server/proxy-request.mjs +57 -0
  103. package/templates/vue/server/proxy-transfers.mjs +33 -5
  104. package/templates/vue/server/public-endpoints.mjs +138 -23
  105. package/templates/vue/server/public-options.mjs +20 -6
  106. package/templates/vue/server/request-failure.mjs +23 -0
  107. package/templates/vue/server/request-routing.mjs +26 -9
  108. package/templates/vue/server/request-target.mjs +9 -3
  109. package/templates/vue/server/route-rules.mjs +39 -15
  110. package/templates/vue/server/ssr-module.mjs +32 -0
  111. package/templates/vue/server/static-files.mjs +24 -1
  112. package/templates/vue/server/type-guards.mjs +71 -0
  113. package/templates/vue/server/vite-errors.mjs +32 -5
  114. package/templates/vue/server/web-body.mjs +3 -0
  115. package/templates/vue/server-module.ts +10 -1
  116. package/templates/vue/server.mjs +132 -148
  117. package/templates/vue/sfc-global-types.mjs +112 -13
  118. package/templates/vue/ssr-renderer.ts +12 -3
  119. package/templates/vue/ui-inertia-page.mjs +16 -1
  120. package/templates/vue/ui-kbd.mjs +2 -1
  121. package/templates/vue/ui-lazy-icons.mjs +44 -0
  122. package/templates/vue/ui-request-state.mjs +2 -1
  123. package/templates/vue/vite.config.ts +2 -0
@@ -0,0 +1,78 @@
1
+ export {};
2
+
3
+ /** @typedef {import("../server-module.ts").DmsServerMethod} ServerMethod */
4
+ /**
5
+ * What `registerAuth` declared. The hooks are read as plain functions, as the
6
+ * server calls them.
7
+ *
8
+ * @typedef {object} AuthDeclaration
9
+ * @property {string} [signInPath]
10
+ * @property {readonly string[]} [signInExempt]
11
+ * @property {(event: import("../server-module.ts").DmsServerEvent, session: import("../server-module.ts").DmsSession) => Promise<import("../server-module.ts").DmsSession | undefined>} [refreshSession]
12
+ * @property {(session: import("../server-module.ts").DmsSession) => import("../server-module.ts").DmsPublicSession} [publicSession]
13
+ */
14
+ /** @typedef {import("../server-module.ts").DmsRouteRule} RouteRule */
15
+ /**
16
+ * A module that has a `dms.server.ts`.
17
+ *
18
+ * @typedef {object} ServerModuleDeclaration
19
+ * @property {string} id
20
+ * @property {number} [priority]
21
+ * @property {import("../server-module.ts").DmsServerSetup} setup
22
+ */
23
+ /**
24
+ * One `registerRoute` call.
25
+ *
26
+ * @typedef {object} RouteRegistration
27
+ * @property {ServerMethod | readonly ServerMethod[]} method
28
+ * @property {string} path
29
+ * @property {import("../server-module.ts").DmsServerHandler} handler
30
+ * @property {import("../server-module.ts").DmsServerRouteOptions} [options]
31
+ */
32
+ /**
33
+ * What a module's setup declared, by kind, in declaration order.
34
+ *
35
+ * @typedef {object} ModuleDeclared
36
+ * @property {RouteRegistration[]} routes
37
+ * @property {AuthDeclaration[]} auth
38
+ * @property {Readonly<Record<string, RouteRule>>[]} rules
39
+ * @property {{ pattern: string, options?: import("./backend-proxies.mjs").ProxyOptions }[]} proxies
40
+ */
41
+ /** @typedef {ServerModuleDeclaration & { declared: ModuleDeclared }} DeclaredModule */
42
+ /**
43
+ * A route a module serves, one per method.
44
+ *
45
+ * @typedef {object} ServerRoute
46
+ * @property {string} path The normalized path
47
+ * @property {string} pathIdentity The path with its parameters made anonymous
48
+ * @property {string[]} params The parameter names, in path order
49
+ * @property {RegExp} matcher
50
+ * @property {string} id The serving module
51
+ * @property {number} priority
52
+ * @property {number} order The declaration's rank in its module
53
+ * @property {string} method
54
+ * @property {import("../server-module.ts").DmsServerHandler} handler
55
+ * @property {boolean} sameOrigin
56
+ * @property {number} bodyLimit
57
+ * @property {boolean} overridesBackend
58
+ */
59
+ /**
60
+ * The auth hooks of the module that provides them.
61
+ *
62
+ * @typedef {object} AuthProvider
63
+ * @property {string} id
64
+ * @property {number} priority
65
+ * @property {string} [signInPath]
66
+ * @property {import("./path-patterns.mjs").CompiledPathPattern[]} [signInExempt]
67
+ * @property {AuthDeclaration["refreshSession"]} refreshSession
68
+ * @property {AuthDeclaration["publicSession"]} publicSession
69
+ */
70
+ /**
71
+ * What the modules declared, ready to serve.
72
+ *
73
+ * @typedef {object} ServerDeclarations
74
+ * @property {ServerRoute[]} routes
75
+ * @property {AuthProvider | undefined} auth
76
+ * @property {import("./route-rules.mjs").ResolvedRouteRule[]} rules
77
+ * @property {import("./backend-proxies.mjs").BackendProxy[]} proxies
78
+ */
@@ -2,6 +2,21 @@ import { resolveBackendProxies } from "./backend-proxies.mjs";
2
2
  import { compilePathPattern } from "./path-patterns.mjs";
3
3
  import { matchPublicEndpoint } from "./public-endpoints.mjs";
4
4
  import { ruleRejection } from "./route-rules.mjs";
5
+ import {
6
+ isBoolean,
7
+ isFunction,
8
+ isNonNullObject,
9
+ isString,
10
+ } from "./type-guards.mjs";
11
+
12
+ /** @typedef {(message: string) => void} Warn */
13
+ /**
14
+ * @import {
15
+ * AuthProvider, DeclaredModule, ModuleDeclared, RouteRegistration,
16
+ * ServerDeclarations, ServerModuleDeclaration, ServerRoute
17
+ * } from "./module-route-types.mjs"
18
+ * @import { PublicEndpoint } from "./public-endpoints.mjs"
19
+ */
5
20
 
6
21
  const METHODS = new Set([
7
22
  "GET",
@@ -29,6 +44,8 @@ const MODULE_API_PREFIX = /^\/api\/_[A-Za-z0-9-]+(?:\/|$)/;
29
44
  * Whether `pathname` names one of the files the renderer serves: Vite's URLs,
30
45
  * the built assets and the dependencies. No server route is ever there, and a
31
46
  * development page requests hundreds of them.
47
+ *
48
+ * @param {string} pathname
32
49
  */
33
50
  export function isRendererFilePath(pathname) {
34
51
  return ["/@", "/assets/", "/node_modules/"].some((prefix) =>
@@ -36,20 +53,25 @@ export function isRendererFilePath(pathname) {
36
53
  );
37
54
  }
38
55
 
39
- /** Whether a module route may serve `pathname`: never the renderer's own. */
56
+ /**
57
+ * Whether a module route may serve `pathname`: never the renderer's own.
58
+ *
59
+ * @param {string} pathname
60
+ */
40
61
  export function mayHaveModuleRoute(pathname) {
41
62
  return !RESERVED_PREFIXES.some(
42
63
  (prefix) => pathname === prefix.slice(0, -1) || pathname.startsWith(prefix),
43
64
  );
44
65
  }
45
66
 
67
+ /** @param {string} path */
46
68
  function normalizedPath(path) {
47
69
  return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
48
70
  }
49
71
 
72
+ /** @param {string} path */
50
73
  function pathRejection(path) {
51
- if (typeof path !== "string" || !path.startsWith("/"))
52
- return "a path starts with /";
74
+ if (!isString(path) || !path.startsWith("/")) return "a path starts with /";
53
75
  const normalized = normalizedPath(path);
54
76
  if (!mayHaveModuleRoute(normalized))
55
77
  return `${RESERVED_PREFIXES.join(", ")} are the renderer's own paths`;
@@ -71,14 +93,11 @@ function pathRejection(path) {
71
93
  return undefined;
72
94
  }
73
95
 
96
+ /** @param {RouteRegistration["options"]} options */
74
97
  function optionsRejection(options) {
75
98
  if (options === undefined) return undefined;
76
- if (typeof options !== "object" || options === null)
77
- return "its options are not an object";
78
- if (
79
- options.sameOrigin !== undefined &&
80
- typeof options.sameOrigin !== "boolean"
81
- )
99
+ if (!isNonNullObject(options)) return "its options are not an object";
100
+ if (options.sameOrigin !== undefined && !isBoolean(options.sameOrigin))
82
101
  return "sameOrigin is not a boolean";
83
102
  if (
84
103
  options.bodyLimit !== undefined &&
@@ -90,11 +109,14 @@ function optionsRejection(options) {
90
109
 
91
110
  /**
92
111
  * Two declarations of one path whatever their parameters are named share a
93
- * shape.
112
+ * path identity.
113
+ *
114
+ * @param {string} path
94
115
  */
95
116
  function compilePath(path) {
96
117
  const normalized = normalizedPath(path);
97
118
  const segments = normalized === "/" ? [] : normalized.slice(1).split("/");
119
+ /** @type {string[]} */
98
120
  const params = [];
99
121
  const pattern = segments
100
122
  .map((segment) => {
@@ -106,7 +128,7 @@ function compilePath(path) {
106
128
  .join("");
107
129
  return {
108
130
  path: normalized,
109
- shape: segments
131
+ pathIdentity: segments
110
132
  .map((segment) => (PARAM_SEGMENT.test(segment) ? ":" : segment))
111
133
  .join("/"),
112
134
  params,
@@ -114,8 +136,14 @@ function compilePath(path) {
114
136
  };
115
137
  }
116
138
 
117
- /** What a module's setup declares, by kind, in declaration order. */
139
+ /**
140
+ * What a module's setup declares, by kind, in declaration order.
141
+ *
142
+ * @param {ServerModuleDeclaration["setup"]} setup
143
+ * @returns {ModuleDeclared}
144
+ */
118
145
  function collectDeclarations(setup) {
146
+ /** @type {ModuleDeclared} */
119
147
  const declared = { routes: [], auth: [], rules: [], proxies: [] };
120
148
  setup({
121
149
  registerRoute: (method, path, handler, options) =>
@@ -128,27 +156,37 @@ function collectDeclarations(setup) {
128
156
  return declared;
129
157
  }
130
158
 
159
+ /** @param {unknown} method */
131
160
  function methodsOf(method) {
161
+ /** @type {readonly unknown[]} */
132
162
  const methods = Array.isArray(method) ? method : [method];
133
163
  return methods.length && methods.every((name) => METHODS.has(name))
134
164
  ? methods
135
165
  : undefined;
136
166
  }
137
167
 
168
+ /** @param {RouteRegistration} registration */
138
169
  function registrationRejection(registration) {
139
170
  if (!methodsOf(registration.method))
140
171
  return `the method is not one of ${[...METHODS].join(", ")}`;
141
- if (typeof registration.handler !== "function")
142
- return "its handler is not a function";
172
+ if (!isFunction(registration.handler)) return "its handler is not a function";
143
173
  return (
144
174
  pathRejection(registration.path) ?? optionsRejection(registration.options)
145
175
  );
146
176
  }
147
177
 
178
+ /**
179
+ * @param {RouteRegistration["method"]} method
180
+ * @param {string} path
181
+ */
148
182
  function describeRoute(method, path) {
149
183
  return `"${[method].flat().join(", ")} ${path}"`;
150
184
  }
151
185
 
186
+ /**
187
+ * @param {string} id
188
+ * @param {ServerRoute} route
189
+ */
152
190
  function backendShadowWarning(id, route) {
153
191
  if (
154
192
  !BACKEND_PREFIX.test(route.path) ||
@@ -163,6 +201,11 @@ function backendShadowWarning(id, route) {
163
201
  );
164
202
  }
165
203
 
204
+ /**
205
+ * @param {string} id
206
+ * @param {ServerRoute} route
207
+ * @param {PublicEndpoint[]} publicEndpoints
208
+ */
166
209
  function publicEndpointWarning(id, route, publicEndpoints) {
167
210
  const sample = route.path.replaceAll(/\/:[^/]+/g, "/x");
168
211
  if (!matchPublicEndpoint(route.method, sample, publicEndpoints))
@@ -173,7 +216,12 @@ function publicEndpointWarning(id, route, publicEndpoints) {
173
216
  );
174
217
  }
175
218
 
176
- /** Runs a module's setup; a setup that throws declares nothing. */
219
+ /**
220
+ * Runs a module's setup; a setup that throws declares nothing.
221
+ *
222
+ * @param {ServerModuleDeclaration} declaration
223
+ * @param {Warn} warn
224
+ */
177
225
  function declarationsOfModule(declaration, warn) {
178
226
  try {
179
227
  return collectDeclarations(declaration.setup);
@@ -185,6 +233,11 @@ function declarationsOfModule(declaration, warn) {
185
233
  }
186
234
  }
187
235
 
236
+ /**
237
+ * @param {DeclaredModule} module
238
+ * @param {Warn} warn
239
+ * @returns {ServerRoute[]}
240
+ */
188
241
  function routesOfModule(module, warn) {
189
242
  const { id, priority = 0 } = module;
190
243
  return module.declared.routes.flatMap((registration, order) => {
@@ -210,6 +263,10 @@ function routesOfModule(module, warn) {
210
263
  });
211
264
  }
212
265
 
266
+ /**
267
+ * @param {{ id: string, priority?: number }} left
268
+ * @param {{ id: string, priority?: number }} right
269
+ */
213
270
  function byPriority(left, right) {
214
271
  return (
215
272
  (right.priority ?? 0) - (left.priority ?? 0) ||
@@ -217,6 +274,10 @@ function byPriority(left, right) {
217
274
  );
218
275
  }
219
276
 
277
+ /**
278
+ * @param {ServerRoute} kept
279
+ * @param {ServerRoute} shadowed
280
+ */
220
281
  function shadowWarning(kept, shadowed) {
221
282
  const settled =
222
283
  kept.priority === shadowed.priority
@@ -228,6 +289,7 @@ function shadowWarning(kept, shadowed) {
228
289
  );
229
290
  }
230
291
 
292
+ /** @param {ServerRoute} route */
231
293
  function parameterCount(route) {
232
294
  return route.params.length;
233
295
  }
@@ -235,10 +297,15 @@ function parameterCount(route) {
235
297
  /**
236
298
  * Whether one request path can match both routes: as many segments, and at
237
299
  * each position the same literal or a parameter on either side.
300
+ *
301
+ * @param {ServerRoute} left
302
+ * @param {ServerRoute} right
238
303
  */
239
304
  function routesOverlap(left, right) {
240
- const leftSegments = left.shape === "" ? [] : left.shape.split("/");
241
- const rightSegments = right.shape === "" ? [] : right.shape.split("/");
305
+ const leftSegments =
306
+ left.pathIdentity === "" ? [] : left.pathIdentity.split("/");
307
+ const rightSegments =
308
+ right.pathIdentity === "" ? [] : right.pathIdentity.split("/");
242
309
  return (
243
310
  leftSegments.length === rightSegments.length &&
244
311
  leftSegments.every(
@@ -250,7 +317,12 @@ function routesOverlap(left, right) {
250
317
  );
251
318
  }
252
319
 
253
- /** `first` is tried before `second`: it answers what both can match. */
320
+ /**
321
+ * `first` is tried before `second`: it answers what both can match.
322
+ *
323
+ * @param {ServerRoute} first
324
+ * @param {ServerRoute} second
325
+ */
254
326
  function overlapWarning(first, second) {
255
327
  const settled =
256
328
  parameterCount(first) < parameterCount(second)
@@ -265,6 +337,7 @@ function overlapWarning(first, second) {
265
337
  );
266
338
  }
267
339
 
340
+ /** @param {ServerRoute} route */
268
341
  function rootParameterWarning(route) {
269
342
  return (
270
343
  `Frontend module ${route.id} serves ${describeRoute(route.method, route.path)}, whose first ` +
@@ -276,10 +349,13 @@ function rootParameterWarning(route) {
276
349
  /**
277
350
  * Reports what the order of `routes` settles silently: two modules' routes
278
351
  * that can match one request, and a route that catches every first segment.
352
+ *
353
+ * @param {ServerRoute[]} routes
354
+ * @param {Warn} warn
279
355
  */
280
356
  function warnOverlaps(routes, warn) {
281
357
  for (const [index, route] of routes.entries()) {
282
- if (route.shape.startsWith(":")) warn(rootParameterWarning(route));
358
+ if (route.pathIdentity.startsWith(":")) warn(rootParameterWarning(route));
283
359
  for (const later of routes.slice(index + 1))
284
360
  if (
285
361
  later.method === route.method &&
@@ -290,11 +366,17 @@ function warnOverlaps(routes, warn) {
290
366
  }
291
367
  }
292
368
 
369
+ /**
370
+ * @param {DeclaredModule[]} modules
371
+ * @param {Warn} warn
372
+ * @param {PublicEndpoint[]} publicEndpoints
373
+ */
293
374
  function resolveRoutes(modules, warn, publicEndpoints) {
375
+ /** @type {Map<string, ServerRoute>} */
294
376
  const kept = new Map();
295
377
  for (const module of modules) {
296
378
  for (const route of routesOfModule(module, warn)) {
297
- const key = `${route.method} ${route.shape}`;
379
+ const key = `${route.method} ${route.pathIdentity}`;
298
380
  const current = kept.get(key);
299
381
  if (current) {
300
382
  warn(shadowWarning(current, route));
@@ -319,14 +401,15 @@ function resolveRoutes(modules, warn, publicEndpoints) {
319
401
 
320
402
  const AUTH_HOOKS = ["refreshSession", "publicSession"];
321
403
 
404
+ /** @param {unknown} auth */
322
405
  function authRejection(auth) {
323
- if (typeof auth !== "object" || auth === null) return "it is not an object";
406
+ if (!isNonNullObject(auth)) return "it is not an object";
324
407
  for (const hook of AUTH_HOOKS)
325
- if (auth[hook] !== undefined && typeof auth[hook] !== "function")
408
+ if (auth[hook] !== undefined && !isFunction(auth[hook]))
326
409
  return `${hook} is not a function`;
327
410
  if (
328
411
  auth.signInPath !== undefined &&
329
- (typeof auth.signInPath !== "string" ||
412
+ (!isString(auth.signInPath) ||
330
413
  !compilePathPattern(auth.signInPath) ||
331
414
  auth.signInPath.includes("*"))
332
415
  )
@@ -345,8 +428,12 @@ function authRejection(auth) {
345
428
  /**
346
429
  * The auth hooks: those of the highest-priority module that registers them.
347
430
  * A module registering them twice, or after another one, is reported.
431
+ *
432
+ * @param {DeclaredModule[]} modules
433
+ * @param {Warn} warn
348
434
  */
349
435
  function resolveAuth(modules, warn) {
436
+ /** @type {AuthProvider | undefined} */
350
437
  let provider;
351
438
  for (const module of modules) {
352
439
  for (const auth of module.declared.auth) {
@@ -379,12 +466,16 @@ function resolveAuth(modules, warn) {
379
466
  /**
380
467
  * The route rules: of two declarations of the same pattern, the module of
381
468
  * higher priority keeps it, with a warning.
469
+ *
470
+ * @param {DeclaredModule[]} modules
471
+ * @param {Warn} warn
382
472
  */
383
473
  function resolveRules(modules, warn) {
474
+ /** @type {Map<string, import("./route-rules.mjs").ResolvedRouteRule>} */
384
475
  const kept = new Map();
385
476
  for (const module of modules) {
386
477
  for (const rules of module.declared.rules) {
387
- if (typeof rules !== "object" || rules === null) {
478
+ if (!isNonNullObject(rules)) {
388
479
  warn(
389
480
  `Frontend module ${module.id} declares route rules that are ignored: they are not an object.`,
390
481
  );
@@ -435,12 +526,13 @@ function resolveRules(modules, warn) {
435
526
  * request reaches. Pure: the server hands it the declarations it loaded, and
436
527
  * `module-event.mjs` runs the handler a request reaches.
437
528
  *
438
- * @param declarations `{ id, priority, setup }` per module with a dms.server.ts
439
- * @param warn Reports a declaration problem
440
- * @param publicEndpoints The deployment's public endpoints (#108), to report a
529
+ * @param {readonly ServerModuleDeclaration[]} declarations `{ id, priority, setup }` per module with a dms.server.ts
530
+ * @param {Warn} warn Reports a declaration problem
531
+ * @param {PublicEndpoint[]} [publicEndpoints] The deployment's public endpoints (#108), to report a
441
532
  * module route answering one
442
- * @param manifestProxies `{ module, path, auth? }`, the backend proxies the
533
+ * @param {readonly import("./backend-proxies.mjs").ManifestProxy[]} [manifestProxies] `{ module, path, auth? }`, the backend proxies the
443
534
  * backend modules declare in the manifest
535
+ * @returns {ServerDeclarations}
444
536
  */
445
537
  export function resolveServerDeclarations(
446
538
  declarations,
@@ -466,7 +558,12 @@ export function resolveServerDeclarations(
466
558
  };
467
559
  }
468
560
 
561
+ /**
562
+ * @param {ServerRoute} route
563
+ * @param {RegExpExecArray} match
564
+ */
469
565
  function decodedParams(route, match) {
566
+ /** @type {Record<string, string>} */
470
567
  const params = {};
471
568
  for (const [index, name] of route.params.entries()) {
472
569
  try {
@@ -483,9 +580,9 @@ function decodedParams(route, match) {
483
580
  *
484
581
  * A `HEAD` no route declares is the `GET`'s, without its body.
485
582
  *
486
- * @param routes What `resolveServerDeclarations` returned
487
- * @param method The request's method
488
- * @param pathname The request's normalized path, without its query string
583
+ * @param {ServerRoute[]} routes What `resolveServerDeclarations` returned
584
+ * @param {string} method The request's method
585
+ * @param {string} pathname The request's normalized path, without its query string
489
586
  */
490
587
  export function matchModuleRoute(routes, method, pathname) {
491
588
  const reached = matchMethod(routes, method, pathname);
@@ -493,6 +590,12 @@ export function matchModuleRoute(routes, method, pathname) {
493
590
  return matchMethod(routes, "GET", pathname);
494
591
  }
495
592
 
593
+ /**
594
+ * @param {ServerRoute[]} routes
595
+ * @param {string} method
596
+ * @param {string} pathname
597
+ * @returns {{ route: ServerRoute, params: Record<string, string> } | undefined}
598
+ */
496
599
  function matchMethod(routes, method, pathname) {
497
600
  for (const route of routes) {
498
601
  if (route.method !== method) continue;
@@ -507,8 +610,12 @@ function matchMethod(routes, method, pathname) {
507
610
  /**
508
611
  * The methods the module routes answer on `pathname`: a path a module route
509
612
  * serves is that module's for every method, the others answered `405`.
613
+ *
614
+ * @param {ServerRoute[]} routes
615
+ * @param {string} pathname
510
616
  */
511
617
  export function moduleRouteMethods(routes, pathname) {
618
+ /** @type {Set<string>} */
512
619
  const methods = new Set();
513
620
  for (const route of routes)
514
621
  if (route.matcher.test(pathname)) methods.add(route.method);