@pagefront/lint-commerce 0.10.0 → 0.11.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.
@@ -5,9 +5,7 @@
5
5
  * boundary: callers see `SchemaError`, never Ajv's own error type.
6
6
  */
7
7
  import type { LintOptions, Report } from "@pagefront/lint-core";
8
- import type { SheetLine, SheetType } from "./sheet-type.js";
9
- /** The Layer 1 validator for a sheet type on a line. */
10
- export declare function validatorFor(sheetType: SheetType, line: SheetLine): import("ajv").ValidateFunction<unknown>;
8
+ import type { SheetType } from "./sheet-type.js";
11
9
  /**
12
10
  * One Layer 1 (JSON Schema) validation failure, in a shape this
13
11
  * package owns. `instancePath` is a JSON Pointer to the offending
@@ -27,25 +25,30 @@ export type ValidateAndLintResult = {
27
25
  report: Report;
28
26
  };
29
27
  /**
30
- * Validate a parsed-but-unvalidated document against the bundled
31
- * product JSON Schema (Layer 1), and — only if it passes — lint it
32
- * against the commerce rule catalogue (Layer 2). The engine assumes a
33
- * schema-valid Sheet, so a failing document never reaches the
34
- * catalogue; Layer 1 success is also what makes the internal cast to
35
- * `Sheet` sound (the schema requires the envelope fields).
28
+ * Layer 1 for one document: validate it against the frozen schema its
29
+ * `$schema` names, or, when it declares none, the schema its own
30
+ * statements lead to (see schema-registry.ts). Returns the errors, empty
31
+ * when the document is valid. A `$schema` naming no bundled schema is a
32
+ * Layer 1 failure of its own, reported at `/$schema` with the keyword
33
+ * `$schema`: the document is not validated against some other version.
34
+ */
35
+ export declare function schemaErrorsFor(input: unknown, sheetType?: SheetType): SchemaError[];
36
+ /**
37
+ * Validate a parsed-but-unvalidated document against a bundled JSON
38
+ * Schema (Layer 1), and — only if it passes — lint it against the
39
+ * commerce rule catalogue (Layer 2). The engine assumes a schema-valid
40
+ * Sheet, so a failing document never reaches the catalogue; Layer 1
41
+ * success is also what makes the internal cast to `Sheet` sound (the
42
+ * schema requires the envelope fields).
36
43
  *
37
- * Two lines are validated (see sheet-type.ts): a sheet carrying
38
- * `release` validates against the current sheet-spec schema for its
39
- * type, and a legacy sheet carrying `format_version` validates against
40
- * the frozen legacy schema (format 0.9). A legacy sheet declaring some
41
- * other `format_version` failing Layer 1 is the intended behavior:
42
- * there is no separate "unsupported version" outcome.
44
+ * The package bundles every schema ever published, on both lines: the
45
+ * sheet-spec versions of each release, and the legacy draft line's
46
+ * format 0.9 schemas. A document is validated against the one its
47
+ * `$schema` names. A `$schema` naming a version this package does not
48
+ * bundle fails Layer 1 with a single error saying so.
43
49
  *
44
- * Dispatches by page type (see sheet-type.ts): product sheets validate
45
- * against the product schema and lint with the product catalogue;
46
- * Commerce Organization Sheets validate against the organization
47
- * schema and lint with the organization catalogue. Detection reads the
48
- * envelope `$schema` first, falling back to data-block shape, so a
49
- * document of either type routes to its own schema's errors.
50
+ * Layer 2 dispatches by page type (see sheet-type.ts): product sheets
51
+ * lint with the product catalogue, Commerce Organization Sheets with
52
+ * the organization catalogue.
50
53
  */
51
54
  export declare function validateAndLint(input: unknown, options?: LintOptions): ValidateAndLintResult;
@@ -1,49 +1,60 @@
1
1
  import { lintSheet } from "./lint-sheet.js";
2
- import { detectSheetLine, detectSheetType } from "./sheet-type.js";
3
- import { validateProduct, validateOrganization, validateLegacyProduct, validateLegacyOrganization, } from "./schema-validators.js";
4
- /** The Layer 1 validator for a sheet type on a line. */
5
- export function validatorFor(sheetType, line) {
6
- if (line === "legacy") {
7
- return sheetType === "organization" ? validateLegacyOrganization : validateLegacyProduct;
8
- }
9
- return sheetType === "organization" ? validateOrganization : validateProduct;
10
- }
2
+ import { resolveSchema } from "./schema-registry.js";
3
+ import { VALIDATORS } from "./schema-validators.js";
11
4
  // The validators are compiled ahead of time (see schema-validators.d.ts):
12
5
  // nothing here generates code at load time, so the pipeline runs where
13
6
  // eval is unavailable, and consumers calling it in a loop pay no
14
7
  // compilation cost.
15
8
  /**
16
- * Validate a parsed-but-unvalidated document against the bundled
17
- * product JSON Schema (Layer 1), and — only if it passes — lint it
18
- * against the commerce rule catalogue (Layer 2). The engine assumes a
19
- * schema-valid Sheet, so a failing document never reaches the
20
- * catalogue; Layer 1 success is also what makes the internal cast to
21
- * `Sheet` sound (the schema requires the envelope fields).
9
+ * Layer 1 for one document: validate it against the frozen schema its
10
+ * `$schema` names, or, when it declares none, the schema its own
11
+ * statements lead to (see schema-registry.ts). Returns the errors, empty
12
+ * when the document is valid. A `$schema` naming no bundled schema is a
13
+ * Layer 1 failure of its own, reported at `/$schema` with the keyword
14
+ * `$schema`: the document is not validated against some other version.
15
+ */
16
+ export function schemaErrorsFor(input, sheetType) {
17
+ const envelope = (typeof input === "object" && input !== null ? input : {});
18
+ const resolution = resolveSchema(envelope, sheetType);
19
+ if (resolution.kind === "unknown") {
20
+ return [
21
+ {
22
+ instancePath: "/$schema",
23
+ message: `names no schema this linter bundles: ${resolution.declared}`,
24
+ keyword: "$schema",
25
+ },
26
+ ];
27
+ }
28
+ const validate = VALIDATORS[resolution.id];
29
+ if (validate(input))
30
+ return [];
31
+ return (validate.errors ?? []).map((error) => ({
32
+ instancePath: error.instancePath,
33
+ message: error.message ?? "invalid",
34
+ keyword: error.keyword,
35
+ }));
36
+ }
37
+ /**
38
+ * Validate a parsed-but-unvalidated document against a bundled JSON
39
+ * Schema (Layer 1), and — only if it passes — lint it against the
40
+ * commerce rule catalogue (Layer 2). The engine assumes a schema-valid
41
+ * Sheet, so a failing document never reaches the catalogue; Layer 1
42
+ * success is also what makes the internal cast to `Sheet` sound (the
43
+ * schema requires the envelope fields).
22
44
  *
23
- * Two lines are validated (see sheet-type.ts): a sheet carrying
24
- * `release` validates against the current sheet-spec schema for its
25
- * type, and a legacy sheet carrying `format_version` validates against
26
- * the frozen legacy schema (format 0.9). A legacy sheet declaring some
27
- * other `format_version` failing Layer 1 is the intended behavior:
28
- * there is no separate "unsupported version" outcome.
45
+ * The package bundles every schema ever published, on both lines: the
46
+ * sheet-spec versions of each release, and the legacy draft line's
47
+ * format 0.9 schemas. A document is validated against the one its
48
+ * `$schema` names. A `$schema` naming a version this package does not
49
+ * bundle fails Layer 1 with a single error saying so.
29
50
  *
30
- * Dispatches by page type (see sheet-type.ts): product sheets validate
31
- * against the product schema and lint with the product catalogue;
32
- * Commerce Organization Sheets validate against the organization
33
- * schema and lint with the organization catalogue. Detection reads the
34
- * envelope `$schema` first, falling back to data-block shape, so a
35
- * document of either type routes to its own schema's errors.
51
+ * Layer 2 dispatches by page type (see sheet-type.ts): product sheets
52
+ * lint with the product catalogue, Commerce Organization Sheets with
53
+ * the organization catalogue.
36
54
  */
37
55
  export function validateAndLint(input, options) {
38
- const envelope = (typeof input === "object" && input !== null ? input : {});
39
- const validate = validatorFor(detectSheetType(envelope), detectSheetLine(envelope));
40
- if (!validate(input)) {
41
- const schemaErrors = (validate.errors ?? []).map((error) => ({
42
- instancePath: error.instancePath,
43
- message: error.message ?? "invalid",
44
- keyword: error.keyword,
45
- }));
56
+ const schemaErrors = schemaErrorsFor(input);
57
+ if (schemaErrors.length > 0)
46
58
  return { layer: 1, schemaErrors };
47
- }
48
59
  return { layer: 2, report: lintSheet(input, options) };
49
60
  }
@@ -18,10 +18,10 @@ export type ValidateOrganizationResult = {
18
18
  schemaErrors: SchemaError[];
19
19
  };
20
20
  /**
21
- * Validate a parsed-but-unvalidated document against the bundled
22
- * Commerce Organization Sheet JSON Schema for its line: the current
23
- * sheet-spec schema for a sheet carrying `release`, the frozen legacy
24
- * schema for one carrying `format_version`, exactly as in the product
25
- * pipeline.
21
+ * Validate a parsed-but-unvalidated document against a bundled
22
+ * Commerce Organization Sheet JSON Schema: the one its `$schema` names,
23
+ * or, when it declares none, the organization schema for its line (the
24
+ * sheet-spec version its `release` bundles, or the legacy format 0.9
25
+ * schema for a sheet carrying `format_version`).
26
26
  */
27
27
  export declare function validateOrganizationSheet(input: unknown): ValidateOrganizationResult;
@@ -1,22 +1,12 @@
1
- import { detectSheetLine } from "./sheet-type.js";
2
- import { validatorFor } from "./validate-and-lint.js";
1
+ import { schemaErrorsFor } from "./validate-and-lint.js";
3
2
  /**
4
- * Validate a parsed-but-unvalidated document against the bundled
5
- * Commerce Organization Sheet JSON Schema for its line: the current
6
- * sheet-spec schema for a sheet carrying `release`, the frozen legacy
7
- * schema for one carrying `format_version`, exactly as in the product
8
- * pipeline.
3
+ * Validate a parsed-but-unvalidated document against a bundled
4
+ * Commerce Organization Sheet JSON Schema: the one its `$schema` names,
5
+ * or, when it declares none, the organization schema for its line (the
6
+ * sheet-spec version its `release` bundles, or the legacy format 0.9
7
+ * schema for a sheet carrying `format_version`).
9
8
  */
10
9
  export function validateOrganizationSheet(input) {
11
- const envelope = (typeof input === "object" && input !== null ? input : {});
12
- const validate = validatorFor("organization", detectSheetLine(envelope));
13
- if (!validate(input)) {
14
- const schemaErrors = (validate.errors ?? []).map((error) => ({
15
- instancePath: error.instancePath,
16
- message: error.message ?? "invalid",
17
- keyword: error.keyword,
18
- }));
19
- return { valid: false, schemaErrors };
20
- }
21
- return { valid: true };
10
+ const schemaErrors = schemaErrorsFor(input, "organization");
11
+ return schemaErrors.length > 0 ? { valid: false, schemaErrors } : { valid: true };
22
12
  }
package/dist/version.d.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  * (test/linter-version.test.mjs) fails when they diverge. Regenerate
6
6
  * on version bump.
7
7
  */
8
- export declare const PACKAGE_VERSION = "0.10.0";
8
+ export declare const PACKAGE_VERSION = "0.11.0";
package/dist/version.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * (test/linter-version.test.mjs) fails when they diverge. Regenerate
6
6
  * on version bump.
7
7
  */
8
- export const PACKAGE_VERSION = "0.10.0";
8
+ export const PACKAGE_VERSION = "0.11.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagefront/lint-commerce",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Pagefront commerce linter: the commerce rule catalogue and CLI, on the @pagefront/lint-core engine.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -34,7 +34,7 @@
34
34
  "access": "public"
35
35
  },
36
36
  "scripts": {
37
- "build": "tsc && node scripts/compile-validators.mjs",
37
+ "build": "node scripts/bundle-schemas.mjs && tsc && node scripts/compile-validators.mjs",
38
38
  "test": "npm run build && node --test test/*.test.mjs",
39
39
  "prepublishOnly": "npm test"
40
40
  },
@@ -1,9 +0,0 @@
1
- /**
2
- * The legacy draft line's JSON Schemas (commerce/spec/legacy/*.v0.9.json),
3
- * bundled verbatim so sheets carrying `format_version` keep validating
4
- * against the schemas their `$schema` URLs name. The files are frozen:
5
- * the schema drift test (test/schema.test.mjs) fails if a bundled copy
6
- * and its source diverge.
7
- */
8
- export declare const LEGACY_PRODUCT_SCHEMA: Record<string, unknown>;
9
- export declare const LEGACY_ORGANIZATION_SCHEMA: Record<string, unknown>;