@antelopejs/dms-frontend 0.9.3 → 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 (116) 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/derived-outputs.js +3 -3
  8. package/dist/discovery.js +17 -6
  9. package/dist/entry-weight.js +15 -0
  10. package/dist/fs-sync.js +7 -4
  11. package/dist/index.js +2 -1
  12. package/dist/internal/built-workspace.d.ts +4 -0
  13. package/dist/internal/built-workspace.js +43 -0
  14. package/dist/internal/ensure.d.ts +1 -0
  15. package/dist/internal/ensure.js +8 -0
  16. package/dist/internal/locale-catalogs.d.ts +8 -3
  17. package/dist/internal/locale-catalogs.js +16 -6
  18. package/dist/internal/manifest-decoder.d.ts +7 -0
  19. package/dist/internal/manifest-decoder.js +81 -0
  20. package/dist/internal/own-release.d.ts +5 -0
  21. package/dist/internal/own-release.js +20 -0
  22. package/dist/internal/plain-object.d.ts +1 -0
  23. package/dist/internal/plain-object.js +6 -0
  24. package/dist/internal/text-list.d.ts +1 -0
  25. package/dist/internal/text-list.js +10 -0
  26. package/dist/internal/vite-manifest.d.ts +6 -0
  27. package/dist/internal/vite-manifest.js +24 -0
  28. package/dist/layer-watch.js +25 -24
  29. package/dist/layers.d.ts +1 -1
  30. package/dist/layers.js +3 -1
  31. package/dist/locale-files.d.ts +2 -1
  32. package/dist/locale-files.js +4 -0
  33. package/dist/manifest.d.ts +1 -1
  34. package/dist/manifest.js +44 -31
  35. package/dist/materialize.js +6 -2
  36. package/dist/module-set.js +2 -1
  37. package/dist/node-options.d.ts +1 -0
  38. package/dist/node-options.js +8 -0
  39. package/dist/output.d.ts +15 -9
  40. package/dist/output.js +30 -18
  41. package/dist/private-values.d.ts +1 -1
  42. package/dist/private-values.js +5 -3
  43. package/dist/project-modules.js +13 -8
  44. package/dist/renderer-range.js +5 -3
  45. package/dist/server-process.js +1 -1
  46. package/dist/verify-source-build.js +10 -2
  47. package/dist/verify-source-client-bundle.d.ts +1 -0
  48. package/dist/verify-source-client-bundle.js +30 -0
  49. package/dist/verify-source-runner.js +44 -60
  50. package/dist/verify-source-sources.js +49 -11
  51. package/dist/workspace-setup.js +1 -1
  52. package/package.json +6 -4
  53. package/skills/dms-frontend/SKILL.md +1 -1
  54. package/templates/vue/app-runtime.ts +2 -9
  55. package/templates/vue/client-server-guard.mjs +16 -0
  56. package/templates/vue/compress-assets.mjs +9 -1
  57. package/templates/vue/entry-weight.mjs +22 -0
  58. package/templates/vue/frontend-module.ts +1 -0
  59. package/templates/vue/frontend-runtime/module-registration.ts +2 -2
  60. package/templates/vue/frontend-runtime/state.ts +2 -2
  61. package/templates/vue/frontend-runtime/types.ts +8 -2
  62. package/templates/vue/head-order.mjs +7 -0
  63. package/templates/vue/icon-scan.mjs +4 -0
  64. package/templates/vue/server/auth/backend.mjs +41 -4
  65. package/templates/vue/server/auth/client-ip.mjs +52 -4
  66. package/templates/vue/server/auth/establish-endpoints.mjs +10 -6
  67. package/templates/vue/server/auth/session.mjs +81 -2
  68. package/templates/vue/server/auth-hooks.mjs +15 -5
  69. package/templates/vue/server/backend-proxies.mjs +65 -9
  70. package/templates/vue/server/backend-request.mjs +61 -0
  71. package/templates/vue/server/backend-response.mjs +23 -6
  72. package/templates/vue/server/built-files.mjs +7 -0
  73. package/templates/vue/server/cli-report.mjs +53 -11
  74. package/templates/vue/server/client-manifest.mjs +23 -1
  75. package/templates/vue/server/content.mjs +18 -1
  76. package/templates/vue/server/dev-private-files.mjs +17 -1
  77. package/templates/vue/server/dev-styles.mjs +38 -0
  78. package/templates/vue/server/email.mjs +9 -3
  79. package/templates/vue/server/favicon.mjs +3 -0
  80. package/templates/vue/server/generated-files.mjs +211 -0
  81. package/templates/vue/server/homepage.mjs +21 -9
  82. package/templates/vue/server/html-tag.mjs +4 -0
  83. package/templates/vue/server/icons.mjs +80 -7
  84. package/templates/vue/server/in-place-render.mjs +35 -0
  85. package/templates/vue/server/inertia.mjs +61 -2
  86. package/templates/vue/server/module-event.mjs +98 -17
  87. package/templates/vue/server/module-route-types.mjs +78 -0
  88. package/templates/vue/server/module-routes.mjs +138 -31
  89. package/templates/vue/server/module-server.mjs +98 -27
  90. package/templates/vue/server/module-testing.mjs +14 -5
  91. package/templates/vue/server/page-props.mjs +92 -2
  92. package/templates/vue/server/page-redirects.mjs +37 -0
  93. package/templates/vue/server/path-patterns.mjs +13 -1
  94. package/templates/vue/server/proxy-compression.mjs +22 -0
  95. package/templates/vue/server/proxy-headers.mjs +11 -1
  96. package/templates/vue/server/proxy-redirects.mjs +20 -5
  97. package/templates/vue/server/proxy-request.mjs +57 -0
  98. package/templates/vue/server/proxy-transfers.mjs +33 -5
  99. package/templates/vue/server/public-endpoints.mjs +138 -23
  100. package/templates/vue/server/public-options.mjs +20 -6
  101. package/templates/vue/server/request-failure.mjs +23 -0
  102. package/templates/vue/server/request-routing.mjs +26 -9
  103. package/templates/vue/server/request-target.mjs +9 -3
  104. package/templates/vue/server/route-rules.mjs +39 -15
  105. package/templates/vue/server/ssr-module.mjs +32 -0
  106. package/templates/vue/server/static-files.mjs +24 -1
  107. package/templates/vue/server/type-guards.mjs +71 -0
  108. package/templates/vue/server/vite-errors.mjs +32 -5
  109. package/templates/vue/server/web-body.mjs +3 -0
  110. package/templates/vue/server-module.ts +10 -1
  111. package/templates/vue/server.mjs +132 -148
  112. package/templates/vue/sfc-global-types.mjs +112 -13
  113. package/templates/vue/ssr-renderer.ts +2 -2
  114. package/templates/vue/ui-inertia-page.mjs +16 -1
  115. package/templates/vue/ui-kbd.mjs +2 -1
  116. package/templates/vue/ui-request-state.mjs +2 -1
@@ -5,6 +5,8 @@ import { extname } from "node:path";
5
5
  * What a build or a module's `public/` directory may hold. A type missing
6
6
  * here went out as `application/octet-stream`: fonts among them, which a
7
7
  * browser then reports as a mismatch against the `font/woff2` it preloaded.
8
+ *
9
+ * @type {Record<string, string | undefined>}
8
10
  */
9
11
  const MIME_TYPES = {
10
12
  ".avif": "image/avif",
@@ -46,9 +48,15 @@ const IMMUTABLE_CACHE = "public, max-age=31536000, immutable";
46
48
  */
47
49
  const REVALIDATED_CACHE = "no-cache";
48
50
 
51
+ /** @param {string} path */
49
52
  const isFile = (path) => existsSync(path) && statSync(path).isFile();
50
53
 
51
- /** The precompressed variant of `file` the client accepts, if the build wrote one. */
54
+ /**
55
+ * The precompressed variant of `file` the client accepts, if the build wrote one.
56
+ *
57
+ * @param {string} file
58
+ * @param {import("node:http").IncomingMessage} request
59
+ */
52
60
  function acceptedVariant(file, request) {
53
61
  const accepted = request.headers["accept-encoding"] ?? "";
54
62
  if (accepted.includes("br") && isFile(`${file}.br`))
@@ -61,17 +69,26 @@ function acceptedVariant(file, request) {
61
69
  /**
62
70
  * Weak, as the bytes of one representation are not compared: the size and
63
71
  * modification time of the file sent, so each encoding has its own.
72
+ *
73
+ * @param {import("node:fs").Stats} stats
74
+ * @returns {string}
64
75
  */
65
76
  function entityTag(stats) {
66
77
  return `W/"${stats.size.toString(16)}-${Math.floor(stats.mtimeMs).toString(16)}"`;
67
78
  }
68
79
 
80
+ /** @param {string} tag */
69
81
  const opaqueTag = (tag) => tag.trim().replace(/^W\//, "");
70
82
 
71
83
  /**
72
84
  * RFC 9110 §13.1.2 and §13.1.3: `If-None-Match` first, the date otherwise.
73
85
  *
74
86
  * The header has a one-second resolution.
87
+ *
88
+ * @param {import("node:http").IncomingMessage} request
89
+ * @param {string} tag
90
+ * @param {import("node:fs").Stats} stats
91
+ * @returns {boolean}
75
92
  */
76
93
  function isNotModified(request, tag, stats) {
77
94
  const noneMatch = request.headers["if-none-match"];
@@ -92,11 +109,17 @@ function isNotModified(request, tag, stats) {
92
109
  * Send `file`, a file the caller already resolved and checked (see
93
110
  * `publicBuildFile`), as the variant the client accepts, or answer 304 when the
94
111
  * client's copy is current. `immutable` for a file named after its content.
112
+ *
113
+ * @param {string} file
114
+ * @param {import("node:http").IncomingMessage} request
115
+ * @param {import("node:http").ServerResponse} response
116
+ * @param {{ immutable: boolean }} options
95
117
  */
96
118
  export function serveStaticFile(file, request, response, { immutable }) {
97
119
  const selected = acceptedVariant(file, request);
98
120
  const stats = statSync(selected.file);
99
121
  const tag = entityTag(stats);
122
+ /** @type {import("node:http").OutgoingHttpHeaders} */
100
123
  const headers = {
101
124
  "cache-control": immutable ? IMMUTABLE_CACHE : REVALIDATED_CACHE,
102
125
  etag: tag,
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Whether `value` is a string primitive, a boxed `String` excluded.
3
+ *
4
+ * @param {unknown} value The value to test
5
+ * @returns {value is string} Whether `typeof value` is `"string"`
6
+ */
7
+ export function isString(value) {
8
+ return typeof value === "string";
9
+ }
10
+
11
+ /**
12
+ * Whether `value` is a number primitive, `NaN` and the infinities included.
13
+ *
14
+ * @param {unknown} value The value to test
15
+ * @returns {value is number} Whether `typeof value` is `"number"`
16
+ */
17
+ export function isNumber(value) {
18
+ return typeof value === "number";
19
+ }
20
+
21
+ /**
22
+ * Whether `value` is a boolean primitive.
23
+ *
24
+ * @param {unknown} value The value to test
25
+ * @returns {value is boolean} Whether `typeof value` is `"boolean"`
26
+ */
27
+ export function isBoolean(value) {
28
+ return typeof value === "boolean";
29
+ }
30
+
31
+ /**
32
+ * Whether `value` is callable: a function, an arrow, a class or a method.
33
+ *
34
+ * @param {unknown} value The value to test
35
+ * @returns {value is Function} Whether `typeof value` is `"function"`
36
+ */
37
+ export function isFunction(value) {
38
+ return typeof value === "function";
39
+ }
40
+
41
+ /**
42
+ * Whether `value` is an object other than `null`: arrays are objects.
43
+ *
44
+ * @param {unknown} value The value to test
45
+ * @returns {value is object} Whether `typeof value` is `"object"` and `value` is not `null`
46
+ */
47
+ export function isNonNullObject(value) {
48
+ return typeof value === "object" && value !== null;
49
+ }
50
+
51
+ /**
52
+ * Whether `value` can carry properties a caller reads: an object or a
53
+ * function, `null` excluded. Every property read through it is `unknown`.
54
+ *
55
+ * @param {unknown} value The value to test
56
+ * @returns {value is Record<string, unknown>} Whether `value` is an object or a function
57
+ */
58
+ export function isObjectLike(value) {
59
+ return isNonNullObject(value) || isFunction(value);
60
+ }
61
+
62
+ /**
63
+ * Whether `value` is an object other than `null`, read by its properties:
64
+ * arrays are objects, functions are not.
65
+ *
66
+ * @param {unknown} value The value to test
67
+ * @returns {value is Record<string, unknown>} Whether `typeof value` is `"object"` and `value` is not `null`
68
+ */
69
+ export function isRecord(value) {
70
+ return isNonNullObject(value);
71
+ }
@@ -2,12 +2,26 @@ const INTERNAL_ERROR_STATUS = 500;
2
2
  const ERROR_CONTENT_TYPE = "text/plain; charset=utf-8";
3
3
  const VITE_ERROR = Symbol("dms.viteError");
4
4
 
5
+ /**
6
+ * A request that carries the error Vite's middlewares failed with.
7
+ *
8
+ * @typedef {import("node:http").IncomingMessage & { [VITE_ERROR]?: unknown }} ViteRequest
9
+ */
10
+
11
+ /**
12
+ * What Vite's middlewares did with a request.
13
+ *
14
+ * @typedef {{ status: "handled" } | { status: "unhandled" } | { status: "failed", error: unknown }} ViteMiddlewareResult
15
+ */
16
+
5
17
  /**
6
18
  * In middleware mode, Vite's own error middleware logs an error, sends it to
7
19
  * the client overlay, then passes the request on with no error: a module that
8
20
  * fails to transform would fall through to page handling and answer 404. This
9
21
  * plugin runs just before it, keeps the error on the request and hands it on,
10
22
  * so Vite still logs it and shows the overlay.
23
+ *
24
+ * @returns {import("vite").Plugin}
11
25
  */
12
26
  export function captureViteErrors() {
13
27
  return {
@@ -15,10 +29,18 @@ export function captureViteErrors() {
15
29
  apply: "serve",
16
30
  configureServer(server) {
17
31
  return () =>
18
- server.middlewares.use((error, request, _response, next) => {
19
- request[VITE_ERROR] = error;
20
- next(error);
21
- });
32
+ server.middlewares.use(
33
+ /**
34
+ * @param {unknown} error
35
+ * @param {ViteRequest} request
36
+ * @param {import("node:http").ServerResponse} _response
37
+ * @param {(error?: unknown) => void} next
38
+ */
39
+ (error, request, _response, next) => {
40
+ request[VITE_ERROR] = error;
41
+ next(error);
42
+ },
43
+ );
22
44
  },
23
45
  };
24
46
  }
@@ -27,10 +49,15 @@ export function captureViteErrors() {
27
49
  * Hands a request to Vite's middlewares. Resolves `handled` once Vite answered
28
50
  * it, `unhandled` when Vite passed it on, and `failed` with the error when a
29
51
  * Vite middleware failed on it.
52
+ *
53
+ * @param {import("vite").ViteDevServer} devServer
54
+ * @param {ViteRequest} request
55
+ * @param {import("node:http").ServerResponse} response
56
+ * @returns {Promise<ViteMiddlewareResult>}
30
57
  */
31
58
  export function runViteMiddlewares(devServer, request, response) {
32
59
  return new Promise((resolve) => {
33
- devServer.middlewares(request, response, (error) => {
60
+ devServer.middlewares(request, response, (/** @type {unknown} */ error) => {
34
61
  const failure = error ?? request[VITE_ERROR];
35
62
  resolve(
36
63
  failure
@@ -11,6 +11,9 @@ import { pipeline } from "node:stream/promises";
11
11
  *
12
12
  * Writes a Web-standard body, a backend answer above all, to a Node response.
13
13
  * It lives apart from the proxy and the module routes, which both send one.
14
+ *
15
+ * @param {import("node:stream/web").ReadableStream} body
16
+ * @param {...import("node:stream").Writable} streams
14
17
  */
15
18
  export async function pipeWebBody(body, ...streams) {
16
19
  const response = streams.at(-1);
@@ -101,7 +101,16 @@ export interface DmsServerEvent {
101
101
  * overwrites another's, and naming a `dms_*` cookie throws.
102
102
  */
103
103
  cookies: {
104
- readSealed<T = unknown>(name: string): T | undefined;
104
+ /**
105
+ * The value a sealed cookie holds, when `accepts` takes it. A cookie that
106
+ * is absent, does not open, or holds a value `accepts` refuses reads as
107
+ * `undefined`. `accepts` receives the JSON the cookie was written from and
108
+ * is never called for an absent or unreadable cookie.
109
+ */
110
+ readSealed<T>(
111
+ name: string,
112
+ accepts: (value: unknown) => value is T,
113
+ ): T | undefined;
105
114
  writeSealed(
106
115
  name: string,
107
116
  value: unknown,