@jxsuite/compiler 5.1.2 → 6.0.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.
Files changed (40) hide show
  1. package/dist/cli.js +218 -346
  2. package/dist/compiler.js +130 -258
  3. package/package.json +11 -10
  4. package/src/cli.ts +12 -14
  5. package/src/compiler.ts +45 -23
  6. package/src/shadow.ts +9 -8
  7. package/src/shared.ts +693 -329
  8. package/src/site/asset-mounts.ts +22 -12
  9. package/src/site/bundler.ts +38 -12
  10. package/src/site/client-runtime.ts +31 -17
  11. package/src/site/csp.ts +20 -11
  12. package/src/site/db-push.ts +38 -24
  13. package/src/site/dev-command.ts +3 -3
  14. package/src/site/format-host.ts +56 -45
  15. package/src/site/headers-emitter.ts +7 -4
  16. package/src/site/i18n.ts +20 -19
  17. package/src/site/image-cache.ts +16 -3
  18. package/src/site/image-optimizer.ts +19 -5
  19. package/src/site/image-transform.ts +56 -60
  20. package/src/site/img-loading.ts +11 -5
  21. package/src/site/layout-resolver.ts +7 -6
  22. package/src/site/link-relations.ts +10 -6
  23. package/src/site/locale-negotiation.ts +1 -1
  24. package/src/site/pages-discovery.ts +65 -47
  25. package/src/site/preview-server.ts +22 -19
  26. package/src/site/project-sections.ts +16 -3
  27. package/src/site/prototype-resolver.ts +94 -42
  28. package/src/site/schema-command.ts +26 -13
  29. package/src/site/service-worker.ts +2 -2
  30. package/src/site/site-build.ts +421 -279
  31. package/src/site/site-loader.ts +6 -3
  32. package/src/site/static-host.ts +3 -3
  33. package/src/site/validate-command.ts +64 -34
  34. package/src/site/well-known.ts +57 -12
  35. package/src/targets/compile-class.ts +17 -5
  36. package/src/targets/compile-client.ts +156 -111
  37. package/src/targets/compile-element.ts +227 -198
  38. package/src/targets/compile-server.ts +11 -5
  39. package/src/targets/compile-static.ts +57 -63
  40. package/src/types.ts +5 -6
@@ -23,10 +23,12 @@ import {
23
23
  composeProjectSchemas,
24
24
  flattenSchema,
25
25
  } from "@jxsuite/schema/project-schemas";
26
+ import { isJsonObject } from "@jxsuite/schema/guards";
26
27
  import { buildProjectExtensionRegistry } from "./format-host.ts";
27
28
  import { loadProjectConfig } from "./site-loader.ts";
28
29
  import type { ExtensionInfo } from "@jxsuite/schema/extension-registry";
29
30
  import type { SchemaJsonLoader } from "@jxsuite/schema/project-schemas";
31
+ import type { JsonObject, JsonValue } from "@jxsuite/schema/types";
30
32
 
31
33
  const CORE_PROJECT_SPECIFIER = "@jxsuite/schema/schemas/project.core.schema.json";
32
34
  const CORE_DOCUMENT_SPECIFIER = "@jxsuite/schema/schema.json";
@@ -85,7 +87,7 @@ export async function writeProjectSchemas(projectRoot: string) {
85
87
  * (workspace hoisting leaves in-repo projects without their own node_modules).
86
88
  *
87
89
  * @param {string} projectRoot - Absolute path to the project directory
88
- * @returns {Promise<{ project: Record<string, unknown>; document: Record<string, unknown> }>}
90
+ * @returns {Promise<{ project: JsonObject; document: JsonObject }>}
89
91
  */
90
92
  export async function readBundledProjectSchemas(
91
93
  projectRoot: string,
@@ -129,17 +131,31 @@ export async function readBundledProjectSchemas(
129
131
  }
130
132
 
131
133
  const loadJson = restrictedSchemaLoader(root);
132
- const projectFile =
133
- composed?.projectSchema ??
134
- (JSON.parse(readFileSync(projectSchemaPath, "utf8")) as Record<string, unknown>);
135
- const documentFile =
136
- composed?.documentSchema ??
137
- (JSON.parse(readFileSync(documentSchemaPath, "utf8")) as Record<string, unknown>);
134
+ const projectFile = composed?.projectSchema ?? readSchemaFile(projectSchemaPath);
135
+ const documentFile = composed?.documentSchema ?? readSchemaFile(documentSchemaPath);
138
136
  const project = flattenSchema(await bundleSchema(projectFile, loadJson, root));
139
137
  const document = flattenSchema(await bundleSchema(documentFile, loadJson, root));
140
138
  return { document, project };
141
139
  }
142
140
 
141
+ /**
142
+ * Read and parse one schema file.
143
+ *
144
+ * Every file this host bundles is a schema resource that `bundleSchema` gives an `$id` and embeds
145
+ * under `$defs`, and only a JSON object can be one, so anything else is refused here by name.
146
+ *
147
+ * @param {string} path - Absolute path to the schema file
148
+ * @returns {JsonObject}
149
+ */
150
+ function readSchemaFile(path: string): JsonObject {
151
+ // SAFETY: JSON.parse only ever yields JSON values; its `any` return type says nothing more.
152
+ const parsed = JSON.parse(readFileSync(path, "utf8")) as JsonValue;
153
+ if (!isJsonObject(parsed)) {
154
+ throw new TypeError(`Schema file "${path}" is not a JSON object`);
155
+ }
156
+ return parsed;
157
+ }
158
+
143
159
  /** Packages whose schemas define the Jx document contract itself, never a project's own content. */
144
160
  const FIRST_PARTY_SCHEMA_SCOPE = "@jxsuite/";
145
161
 
@@ -215,13 +231,10 @@ export function restrictedSchemaLoader(root: string): SchemaJsonLoader {
215
231
  // Noticed for six weeks, because the artifact was only ever regenerated on the machine that
216
232
  // Had the shadow.
217
233
  if (specifier !== null && isFirstPartySchema(specifier)) {
218
- return JSON.parse(readFileSync(hostResolve(specifier, path), "utf8")) as Record<
219
- string,
220
- unknown
221
- >;
234
+ return readSchemaFile(hostResolve(specifier, path));
222
235
  }
223
236
  if (existsSync(abs)) {
224
- return JSON.parse(readFileSync(abs, "utf8")) as Record<string, unknown>;
237
+ return readSchemaFile(abs);
225
238
  }
226
239
  if (specifier === null) {
227
240
  throw new Error(`Schema ref "${path}" does not exist`);
@@ -242,7 +255,7 @@ export function restrictedSchemaLoader(root: string): SchemaJsonLoader {
242
255
  );
243
256
  }
244
257
  }
245
- return JSON.parse(readFileSync(resolved, "utf8")) as Record<string, unknown>;
258
+ return readSchemaFile(resolved);
246
259
  };
247
260
  }
248
261
 
@@ -84,12 +84,12 @@ export function normalizeServiceWorker(
84
84
  * no benefit.
85
85
  */
86
86
  function configId(config: ServiceWorkerConfig): string {
87
- const shape = JSON.stringify({
87
+ const fingerprint = JSON.stringify({
88
88
  fallback: config.offlineFallback ?? null,
89
89
  precache: [...(config.precache ?? [])].toSorted(),
90
90
  scope: config.scope ?? "/",
91
91
  });
92
- return createHash("sha256").update(shape, "utf8").digest("hex").slice(0, 8);
92
+ return createHash("sha256").update(fingerprint, "utf8").digest("hex").slice(0, 8);
93
93
  }
94
94
 
95
95
  /**