@effected/schemastore 0.10.0 → 0.12.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.
- package/CatalogEntry.js +8 -2
- package/HostedSchema.js +230 -0
- package/README.md +67 -266
- package/SchemaPipeline.js +7 -4
- package/SchemaValidator.js +19 -88
- package/SchemaVersioning.js +44 -11
- package/SchemastoreConfig.js +178 -69
- package/StoreDocument.js +1 -0
- package/index.d.ts +385 -91
- package/index.js +3 -2
- package/package.json +2 -4
package/index.d.ts
CHANGED
|
@@ -264,6 +264,14 @@ interface StoreDocumentOptions {
|
|
|
264
264
|
* (`onExcessProperty`, `generateDescriptions`,
|
|
265
265
|
* `includeAnnotationKey`).
|
|
266
266
|
*
|
|
267
|
+
* `onExcessProperty` defaults to `"error"` here — every object is
|
|
268
|
+
* emitted closed (`additionalProperties: false`) because a published
|
|
269
|
+
* document is a contract — where core's own default has been `"ignore"`
|
|
270
|
+
* (open) since rc.113. Pass `{ onExcessProperty: "ignore" }` to reopen
|
|
271
|
+
* one document's objects. Omitting `jsonSchema` altogether reproduces
|
|
272
|
+
* byte-for-byte what the CLI writes for a target that declares none — a
|
|
273
|
+
* consumer test may call `fromSchemaResult(schema, { $id })` and compare.
|
|
274
|
+
*
|
|
267
275
|
* The declared non-standard keyword families ({@link KeywordFamilies})
|
|
268
276
|
* are **always admitted**, regardless of what a supplied
|
|
269
277
|
* `includeAnnotationKey` answers — annotate a schema node
|
|
@@ -650,6 +658,16 @@ export declare const SchemaVersion: Schema.brand<Schema.String, "SchemaVersion">
|
|
|
650
658
|
* @public
|
|
651
659
|
*/
|
|
652
660
|
export type SchemaVersion = typeof SchemaVersion.Type;
|
|
661
|
+
/**
|
|
662
|
+
* Where a versioned document sits relative to its base: `flat` is
|
|
663
|
+
* `<name>-<version>.json` (the only shape SchemaStore serves), `versioned`
|
|
664
|
+
* nests it as `<version>/<name>-<version>.json` — or, with `appendVersion`
|
|
665
|
+
* off, `<version>/<name>.json`, the directory alone carrying the label. An
|
|
666
|
+
* unversioned document is `<name>.json` under either.
|
|
667
|
+
*
|
|
668
|
+
* @public
|
|
669
|
+
*/
|
|
670
|
+
type SchemaLayout = "flat" | "versioned";
|
|
653
671
|
/**
|
|
654
672
|
* The `url`/`versions` half of a catalog entry, as assembled by
|
|
655
673
|
* {@link SchemaVersioning.catalogUrls}.
|
|
@@ -756,28 +774,51 @@ export declare class SchemaVersioning {
|
|
|
756
774
|
* the label and the ceiling rather than `SemVer.make`'s bare schema failure.
|
|
757
775
|
*/
|
|
758
776
|
static next(current: SchemaVersion, change: WriteChange): SchemaVersion;
|
|
777
|
+
/**
|
|
778
|
+
* Whether a name is a simple file base name — non-empty, no path
|
|
779
|
+
* separators, no whitespace — the rule every schema name is held to
|
|
780
|
+
* ({@link SchemaVersioning.fileName} throws on anything else; `defineConfig`
|
|
781
|
+
* rejects a schema key the same way). One predicate so the two cannot drift.
|
|
782
|
+
*/
|
|
783
|
+
static isSimpleName(name: string): boolean;
|
|
759
784
|
/**
|
|
760
785
|
* Derives the schema file name for a catalog name: `name.json`
|
|
761
|
-
* unversioned, `name-<version>.json` versioned
|
|
786
|
+
* unversioned, `name-<version>.json` versioned under the `"flat"`
|
|
787
|
+
* layout (the default and the only shape SchemaStore serves), or
|
|
788
|
+
* `<version>/name-<version>.json` under `"versioned"` — `<version>/name.json`
|
|
789
|
+
* when `appendVersion` is `false`, which only the versioned layout can
|
|
790
|
+
* carry (under `"flat"` two versions would share one file name, so that
|
|
791
|
+
* combination throws).
|
|
762
792
|
*
|
|
763
793
|
* The name must be a simple file base name (no separators, no
|
|
764
794
|
* whitespace); anything else is a wiring mistake and throws.
|
|
765
795
|
*/
|
|
766
|
-
static fileName(name: string, version?: SchemaVersion): string;
|
|
796
|
+
static fileName(name: string, version?: SchemaVersion, layout?: SchemaLayout, appendVersion?: boolean): string;
|
|
767
797
|
/**
|
|
768
798
|
* The canonical URL a schema file is hosted at: `baseUrl` joined with
|
|
769
799
|
* {@link SchemaVersioning.fileName}.
|
|
770
800
|
*/
|
|
771
|
-
static schemaUrl(baseUrl: string, name: string, version?: SchemaVersion): string;
|
|
801
|
+
static schemaUrl(baseUrl: string, name: string, version?: SchemaVersion, layout?: SchemaLayout, appendVersion?: boolean): string;
|
|
772
802
|
/**
|
|
773
803
|
* Assembles the `url`/`versions` half of a catalog entry.
|
|
774
804
|
*
|
|
775
805
|
* Omitting `versions` selects the unversioned mode (`url` only,
|
|
776
806
|
* pointing at the plain `name.json`). Providing them selects the
|
|
777
807
|
* versioned mode: the `versions` map carries every label, and `url`
|
|
778
|
-
* points at
|
|
808
|
+
* points at `current` (default: the newest label under
|
|
809
|
+
* {@link SchemaVersioning.Order}). An **empty** `versions` array is
|
|
779
810
|
* a contradiction (versioned mode with no versions) and throws — pass
|
|
780
|
-
* `undefined` for the unversioned mode.
|
|
811
|
+
* `undefined` for the unversioned mode. `current`, when given, must
|
|
812
|
+
* compare equal under {@link SchemaVersioning.Order} to a member of
|
|
813
|
+
* `versions` or this throws; `url` is built from that member's own
|
|
814
|
+
* spelling (the `versions` map's key), not from the `current` argument
|
|
815
|
+
* verbatim — so a differently-spelled equivalent (`"1.2"` matching a
|
|
816
|
+
* `"1.2.0"` member) still points `url` at the same file the map does.
|
|
817
|
+
*
|
|
818
|
+
* `layout` (default `"flat"`) and `appendVersion` (default `true`) are
|
|
819
|
+
* forwarded to every URL derivation, so `"versioned"` nests every map
|
|
820
|
+
* value and `url` under its own version directory, with or without the
|
|
821
|
+
* `-<version>` file suffix.
|
|
781
822
|
*
|
|
782
823
|
* Labels are inserted in ascending {@link SchemaVersioning.Order}; see
|
|
783
824
|
* {@link CatalogUrls.versions} for why a bare-major key's serialized
|
|
@@ -787,6 +828,9 @@ export declare class SchemaVersioning {
|
|
|
787
828
|
readonly baseUrl: string;
|
|
788
829
|
readonly name: string;
|
|
789
830
|
readonly versions?: ReadonlyArray<SchemaVersion>;
|
|
831
|
+
readonly layout?: SchemaLayout;
|
|
832
|
+
readonly appendVersion?: boolean;
|
|
833
|
+
readonly current?: SchemaVersion;
|
|
790
834
|
}): CatalogUrls;
|
|
791
835
|
}
|
|
792
836
|
//#endregion
|
|
@@ -836,7 +880,10 @@ export declare class CatalogEntry extends CatalogEntry_base {
|
|
|
836
880
|
* Assembles an entry from a catalog identity plus
|
|
837
881
|
* {@link SchemaVersioning.catalogUrls}' inputs: pass `versions` for the
|
|
838
882
|
* versioned mode (the `versions` map and latest-pointing `url` are
|
|
839
|
-
* derived), omit it for the unversioned mode.
|
|
883
|
+
* derived), omit it for the unversioned mode. `layout` (default
|
|
884
|
+
* `"flat"`), `appendVersion` (default `true`) and `current` (default: the
|
|
885
|
+
* newest label) are forwarded to {@link SchemaVersioning.catalogUrls}
|
|
886
|
+
* verbatim. Throws an `Error` naming
|
|
840
887
|
* both spellings when two labels compare equal under
|
|
841
888
|
* {@link SchemaVersioning.Order} (`1.2` and `1.2.0`): each would be its
|
|
842
889
|
* own key and URL for one document.
|
|
@@ -848,6 +895,9 @@ export declare class CatalogEntry extends CatalogEntry_base {
|
|
|
848
895
|
readonly baseUrl: string;
|
|
849
896
|
readonly fileBaseName?: string;
|
|
850
897
|
readonly versions?: ReadonlyArray<SchemaVersion>;
|
|
898
|
+
readonly layout?: SchemaLayout;
|
|
899
|
+
readonly appendVersion?: boolean;
|
|
900
|
+
readonly current?: SchemaVersion;
|
|
851
901
|
}): CatalogEntry;
|
|
852
902
|
/**
|
|
853
903
|
* The fileMatch hygiene lint over this entry's patterns — pure shape
|
|
@@ -975,6 +1025,135 @@ export declare class DriftPolicy {
|
|
|
975
1025
|
}, policy: DriftTolerance): DriftVerdict;
|
|
976
1026
|
}
|
|
977
1027
|
//#endregion
|
|
1028
|
+
//#region src/HostedSchema.d.ts
|
|
1029
|
+
/** The host SchemaStore-hosted documents declare in `$id`. @public */
|
|
1030
|
+
export declare const SCHEMASTORE_ID_BASE = "https://json.schemastore.org";
|
|
1031
|
+
/** The host SchemaStore's `catalog.json` points `url` at. @public */
|
|
1032
|
+
export declare const SCHEMASTORE_CATALOG_BASE = "https://www.schemastore.org";
|
|
1033
|
+
/**
|
|
1034
|
+
* The identity every hosted document derives from: `versions` and `current`
|
|
1035
|
+
* as `defineConfig` accepts them, minus the host, which each constructor
|
|
1036
|
+
* supplies.
|
|
1037
|
+
*
|
|
1038
|
+
* @public
|
|
1039
|
+
*/
|
|
1040
|
+
interface HostedSchemaVersionsInput {
|
|
1041
|
+
/** The schema's file base name — the key it takes in `defineConfig`'s `schemas`. */
|
|
1042
|
+
readonly name: string;
|
|
1043
|
+
/** Every version label the schema advertises; omit for an unversioned schema. */
|
|
1044
|
+
readonly versions?: ReadonlyArray<string>;
|
|
1045
|
+
/** Which of `versions` is current. Defaults to the newest under {@link SchemaVersioning.Order}. */
|
|
1046
|
+
readonly current?: string;
|
|
1047
|
+
/**
|
|
1048
|
+
* Whether a versioned file name carries the `-<version>` suffix
|
|
1049
|
+
* (`<version>/<name>-<version>.json`, SchemaStore's own convention, the
|
|
1050
|
+
* default) or the version directory alone names it
|
|
1051
|
+
* (`<version>/<name>.json`). `false` requires the `"versioned"` layout
|
|
1052
|
+
* and is rejected under `"flat"`, including SchemaStore hosting.
|
|
1053
|
+
*/
|
|
1054
|
+
readonly appendVersion?: boolean;
|
|
1055
|
+
}
|
|
1056
|
+
/** Input to {@link HostedSchema.github}. @public */
|
|
1057
|
+
interface GitHubHostedSchemaInput extends HostedSchemaVersionsInput {
|
|
1058
|
+
/** The repository, as `owner/repo`. */
|
|
1059
|
+
readonly repo: string;
|
|
1060
|
+
/** The branch (or tag) the files are served from. Defaults to `"main"`. */
|
|
1061
|
+
readonly branch?: string;
|
|
1062
|
+
/** The directory under the repository root the files live in, e.g. `"schemas"`. Defaults to the root. */
|
|
1063
|
+
readonly path?: string;
|
|
1064
|
+
/** How a versioned file nests under `path`. Defaults to `"versioned"`. */
|
|
1065
|
+
readonly layout?: SchemaLayout;
|
|
1066
|
+
}
|
|
1067
|
+
/** Input to {@link HostedSchema.custom}. @public */
|
|
1068
|
+
interface CustomHostedSchemaInput extends HostedSchemaVersionsInput {
|
|
1069
|
+
/** The `https://` directory URL the files are served under; a trailing slash is trimmed. */
|
|
1070
|
+
readonly baseUrl: string | URL;
|
|
1071
|
+
/** How a versioned file nests under `baseUrl`. Defaults to `"versioned"`. */
|
|
1072
|
+
readonly layout?: SchemaLayout;
|
|
1073
|
+
}
|
|
1074
|
+
declare const HostedSchema_base: Schema.Class<HostedSchema, Schema.Struct<{
|
|
1075
|
+
readonly name: Schema.String;
|
|
1076
|
+
readonly baseUrl: Schema.String;
|
|
1077
|
+
readonly versions: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
1078
|
+
readonly current: Schema.optionalKey<Schema.String>;
|
|
1079
|
+
readonly layout: Schema.optionalKey<Schema.Literals<readonly ["flat", "versioned"]>>;
|
|
1080
|
+
readonly appendVersion: Schema.optionalKey<Schema.Boolean>;
|
|
1081
|
+
}>, {}>;
|
|
1082
|
+
/**
|
|
1083
|
+
* Where a JSON Schema document is hosted and which version of it is current
|
|
1084
|
+
* — the one value an application derives its `$schema` URL from and hands
|
|
1085
|
+
* to `defineConfig`, so the URL the code emits and the `$id` the CLI writes
|
|
1086
|
+
* cannot disagree.
|
|
1087
|
+
*
|
|
1088
|
+
* @remarks
|
|
1089
|
+
* Build one with {@link HostedSchema.github},
|
|
1090
|
+
* {@link HostedSchema.schemastore} or
|
|
1091
|
+
* {@link HostedSchema.custom}; each validates the identity and
|
|
1092
|
+
* throws a plain `Error` naming the reason. The derivation is
|
|
1093
|
+
* {@link SchemaVersioning.schemaUrl}'s: `<base>/<name>.json` unversioned,
|
|
1094
|
+
* `<base>/<name>-<version>.json` under the `"flat"` layout and
|
|
1095
|
+
* `<base>/<version>/<name>-<version>.json` under `"versioned"` (or
|
|
1096
|
+
* `<base>/<version>/<name>.json` with `appendVersion: false`, when the
|
|
1097
|
+
* version directory alone should name the file). The raw fields are what
|
|
1098
|
+
* `defineConfig` accepts by hand (`baseUrl`, `versions`, `current`,
|
|
1099
|
+
* `layout`, `appendVersion`); the getters are the resolved identity.
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* ```ts
|
|
1103
|
+
* import { HostedSchema } from "@effected/schemastore";
|
|
1104
|
+
* import { Schema } from "effect";
|
|
1105
|
+
*
|
|
1106
|
+
* export const OutputSchema = HostedSchema.github({
|
|
1107
|
+
* repo: "savvy-web/silk-release-action",
|
|
1108
|
+
* path: "schemas",
|
|
1109
|
+
* name: "silk-release-action.output",
|
|
1110
|
+
* versions: ["5.2"],
|
|
1111
|
+
* });
|
|
1112
|
+
*
|
|
1113
|
+
* // In the application: every payload names the schema it was written against.
|
|
1114
|
+
* const Output = Schema.Struct({ $schema: Schema.Literal(OutputSchema.$id) });
|
|
1115
|
+
*
|
|
1116
|
+
* // In schemastore.config.ts: the same value, so nothing is re-derived.
|
|
1117
|
+
* // schemas: { [OutputSchema.name]: { schema: Output, hosted: OutputSchema } }
|
|
1118
|
+
* ```
|
|
1119
|
+
*
|
|
1120
|
+
* @public
|
|
1121
|
+
*/
|
|
1122
|
+
export declare class HostedSchema extends HostedSchema_base {
|
|
1123
|
+
/** A schema served raw from a GitHub repository. */
|
|
1124
|
+
static github(input: GitHubHostedSchemaInput): HostedSchema;
|
|
1125
|
+
/** A schema published to SchemaStore: `$id` on {@link SCHEMASTORE_ID_BASE}, catalog URL on {@link SCHEMASTORE_CATALOG_BASE}, flat layout. */
|
|
1126
|
+
static schemastore(input: HostedSchemaVersionsInput): HostedSchema;
|
|
1127
|
+
/** A schema served from any `https://` directory. */
|
|
1128
|
+
static custom(input: CustomHostedSchemaInput): HostedSchema;
|
|
1129
|
+
private get resolved();
|
|
1130
|
+
/** The base `$id` is derived from: {@link SCHEMASTORE_ID_BASE} under SchemaStore, else `baseUrl`. */
|
|
1131
|
+
get idBase(): string;
|
|
1132
|
+
/** The base the catalog URL is derived from: {@link SCHEMASTORE_CATALOG_BASE} under SchemaStore, else `baseUrl`. */
|
|
1133
|
+
get catalogBase(): string;
|
|
1134
|
+
/** The effective layout: `"flat"` under SchemaStore, else `layout` defaulting to `"versioned"`. */
|
|
1135
|
+
get resolvedLayout(): SchemaLayout;
|
|
1136
|
+
/** Whether versioned file names carry the `-<version>` suffix: `appendVersion` defaulting to `true`. */
|
|
1137
|
+
get resolvedAppendVersion(): boolean;
|
|
1138
|
+
/** Every advertised version, parsed; empty for an unversioned schema. */
|
|
1139
|
+
get resolvedVersions(): ReadonlyArray<SchemaVersion>;
|
|
1140
|
+
/** The current version — `current`, else the newest of `versions`; `undefined` for an unversioned schema. */
|
|
1141
|
+
get resolvedCurrent(): SchemaVersion | undefined;
|
|
1142
|
+
/** The `$id` of the current document — what an application writes as `$schema`. */
|
|
1143
|
+
get $id(): string;
|
|
1144
|
+
/** The catalog URL of the current document; equals {@link HostedSchema.$id} except under SchemaStore. */
|
|
1145
|
+
get url(): string;
|
|
1146
|
+
/** The current document's file name relative to the output directory. */
|
|
1147
|
+
get fileName(): string;
|
|
1148
|
+
/** The `$id` of the document at `version` (or the unversioned document). */
|
|
1149
|
+
idFor(version?: string): string;
|
|
1150
|
+
/** The catalog URL of the document at `version` (or the unversioned document). */
|
|
1151
|
+
urlFor(version?: string): string;
|
|
1152
|
+
/** The file name of the document at `version` (or the unversioned document), relative to the output directory. */
|
|
1153
|
+
fileNameFor(version?: string): string;
|
|
1154
|
+
private parseLabel;
|
|
1155
|
+
}
|
|
1156
|
+
//#endregion
|
|
978
1157
|
//#region src/KeywordFamilies.d.ts
|
|
979
1158
|
/**
|
|
980
1159
|
* The one owner of the declared non-standard keyword families, in two
|
|
@@ -1119,8 +1298,9 @@ export interface SchemaTarget {
|
|
|
1119
1298
|
* document's generation contract self-describing, so
|
|
1120
1299
|
* {@link SchemaPipeline} reproduces a document deterministically
|
|
1121
1300
|
* regardless of core's own default — for example, an `onExcessProperty`
|
|
1122
|
-
* setting of `
|
|
1123
|
-
*
|
|
1301
|
+
* setting of `"ignore"` reopens a document's objects, which
|
|
1302
|
+
* {@link StoreDocument.fromSchema} closes by default. See
|
|
1303
|
+
* {@link StoreDocumentOptions.jsonSchema} for that default and the
|
|
1124
1304
|
* `includeAnnotationKey` gate this option is also subject to.
|
|
1125
1305
|
*/
|
|
1126
1306
|
readonly jsonSchema?: Schema.ToJsonSchemaOptions;
|
|
@@ -1237,31 +1417,22 @@ interface SchemaValidatorShape {
|
|
|
1237
1417
|
}
|
|
1238
1418
|
declare const SchemaValidator_base: Context.ServiceClass<SchemaValidator, "@effected/schemastore/SchemaValidator", SchemaValidatorShape>;
|
|
1239
1419
|
/**
|
|
1240
|
-
*
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
*
|
|
1245
|
-
*
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
* the
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1254
|
-
*
|
|
1255
|
-
*
|
|
1256
|
-
* ajv-formats vocabulary (`date-time`, `date`, `time`, `duration`, `uri`,
|
|
1257
|
-
* `uri-reference`, `uri-template`, `url`, `email`, `hostname`, `ipv4`,
|
|
1258
|
-
* `ipv6`, `regex`, `uuid`, `json-pointer`, `relative-json-pointer`, …), so a
|
|
1259
|
-
* published document can say "this string is an ISO-8601 instant" with a
|
|
1260
|
-
* `format` instead of falling back to a `pattern` plus a runtime filter;
|
|
1261
|
-
* an UNKNOWN format string remains a strict-mode rejection. The plugin's
|
|
1262
|
-
* `formatMaximum` / `formatMinimum` limit keywords are deliberately NOT
|
|
1263
|
-
* registered — `DocumentLint` answers those as unknown keywords, and the
|
|
1264
|
-
* two verdicts must not drift.
|
|
1420
|
+
* The JSON Schema document validation contract — the engine SchemaStore's
|
|
1421
|
+
* own gate is defined in terms of, as a service the pipeline requires in
|
|
1422
|
+
* `R` and never owns.
|
|
1423
|
+
*
|
|
1424
|
+
* This package ships the contract and its doubles only: skip validation
|
|
1425
|
+
* with {@link SchemaValidator.noop}, stub it with
|
|
1426
|
+
* {@link SchemaValidator.layerTest}. The one real implementation is
|
|
1427
|
+
* `@effected/schemastore-cli`'s `AjvValidator.layer` — ajv strict mode over
|
|
1428
|
+
* the declared `KeywordFamilies` and the standard `ajv-formats`
|
|
1429
|
+
* vocabulary — which the `schemastore` command composes for you and which
|
|
1430
|
+
* that package also exports for a program that drives `SchemaPipeline`
|
|
1431
|
+
* itself. Keeping the engine there keeps `ajv` out of every application that
|
|
1432
|
+
* imports this package at runtime (to read a `HostedSchema`, say) and out of
|
|
1433
|
+
* its bundle. `DocumentLint` is the owned, engine-free structural half of the
|
|
1434
|
+
* validation story, and answers questions ajv does not (SchemaStore's own
|
|
1435
|
+
* hygiene conventions).
|
|
1265
1436
|
*
|
|
1266
1437
|
* @example
|
|
1267
1438
|
* ```ts
|
|
@@ -1273,38 +1444,20 @@ declare const SchemaValidator_base: Context.ServiceClass<SchemaValidator, "@effe
|
|
|
1273
1444
|
* return yield* validator.validate({ type: "object" });
|
|
1274
1445
|
* });
|
|
1275
1446
|
*
|
|
1276
|
-
*
|
|
1447
|
+
* // Provide the engine at the edge — the CLI does this for you:
|
|
1448
|
+
* // Effect.provide(program, AjvValidator.layer) (from @effected/schemastore-cli)
|
|
1449
|
+
* Effect.runPromise(Effect.provide(program, SchemaValidator.noop));
|
|
1277
1450
|
* // => []
|
|
1278
1451
|
* ```
|
|
1279
1452
|
*
|
|
1280
1453
|
* @public
|
|
1281
1454
|
*/
|
|
1282
1455
|
export declare class SchemaValidator extends SchemaValidator_base {
|
|
1283
|
-
/**
|
|
1284
|
-
* The shipped ajv implementation — the default a consumer provides.
|
|
1285
|
-
*
|
|
1286
|
-
* `validate` checks the document against the Draft-07 meta-schema and
|
|
1287
|
-
* then compiles it, reporting BOTH as {@link ValidationFinding} values:
|
|
1288
|
-
* meta-schema failures keep ajv's structured `instancePath` and
|
|
1289
|
-
* `keyword`, while a rejection ajv raises by *throwing* becomes a
|
|
1290
|
-
* root-pathed finding — both a strict-mode compile failure and a
|
|
1291
|
-
* declared keyword whose NAME ajv's own grammar
|
|
1292
|
-
* (`/^[a-z_$][a-z0-9_$:-]*$/i`) refuses, such as an `x-ai-*` key
|
|
1293
|
-
* carrying a dot or a space. The error channel stays reserved for the
|
|
1294
|
-
* engine failing as a mechanism.
|
|
1295
|
-
*
|
|
1296
|
-
* `strict` defaults to `true` — SchemaStore's gate. Each call builds its
|
|
1297
|
-
* own ajv instance, so documents sharing an `$id` never collide. The
|
|
1298
|
-
* standard ajv-formats vocabulary is registered on every instance, so
|
|
1299
|
-
* `format: "date-time"` (and the rest of the standard set) compiles under
|
|
1300
|
-
* strict mode instead of being rejected as an unknown format.
|
|
1301
|
-
*/
|
|
1302
|
-
static readonly layer: Layer.Layer<SchemaValidator>;
|
|
1303
1456
|
/**
|
|
1304
1457
|
* No-op: `validate` always succeeds with no findings, never consulting an
|
|
1305
1458
|
* engine. A pure `Layer.succeed`, bound to a const so the layer memoizes
|
|
1306
1459
|
* by reference. Use it to switch validation off deliberately — for the
|
|
1307
|
-
* real engine, provide
|
|
1460
|
+
* real engine, provide `AjvValidator.layer` from `@effected/schemastore-cli`.
|
|
1308
1461
|
*/
|
|
1309
1462
|
static readonly noop: Layer.Layer<SchemaValidator>;
|
|
1310
1463
|
/**
|
|
@@ -1529,15 +1682,18 @@ interface SchemaPipelineOptions {
|
|
|
1529
1682
|
* write — the loop every consumer of this package was writing by hand.
|
|
1530
1683
|
*
|
|
1531
1684
|
* Requires `SchemaFile` and `SchemaValidator` in `R`; provide
|
|
1532
|
-
* `SchemaFile.layer` and `
|
|
1533
|
-
*
|
|
1685
|
+
* `SchemaFile.layer` and an engine — `AjvValidator.layer` from
|
|
1686
|
+
* `@effected/schemastore-cli`, which is what the `schemastore` command
|
|
1687
|
+
* composes, or `SchemaValidator.noop` to skip validation — plus a platform
|
|
1688
|
+
* `FileSystem` / `Path` at the edge. Findings come back as **values**, so
|
|
1534
1689
|
* the package never chooses your log wording — but the gating decision,
|
|
1535
1690
|
* which is the part that must not silently differ between consumers, has
|
|
1536
1691
|
* one default and one override point.
|
|
1537
1692
|
*
|
|
1538
1693
|
* @example
|
|
1539
1694
|
* ```ts
|
|
1540
|
-
* import { SchemaFile, SchemaPipeline, SchemaTarget
|
|
1695
|
+
* import { SchemaFile, SchemaPipeline, SchemaTarget } from "@effected/schemastore";
|
|
1696
|
+
* import { AjvValidator } from "@effected/schemastore-cli";
|
|
1541
1697
|
* import { NodeServices } from "@effect/platform-node";
|
|
1542
1698
|
* import { Effect, Layer, Schema } from "effect";
|
|
1543
1699
|
*
|
|
@@ -1550,7 +1706,7 @@ interface SchemaPipelineOptions {
|
|
|
1550
1706
|
* ];
|
|
1551
1707
|
*
|
|
1552
1708
|
* const program = SchemaPipeline.run(targets).pipe(
|
|
1553
|
-
* Effect.provide(Layer.mergeAll(SchemaFile.layer,
|
|
1709
|
+
* Effect.provide(Layer.mergeAll(SchemaFile.layer, AjvValidator.layer)),
|
|
1554
1710
|
* Effect.provide(NodeServices.layer),
|
|
1555
1711
|
* );
|
|
1556
1712
|
* ```
|
|
@@ -1631,41 +1787,155 @@ export declare class SchemaPipeline {
|
|
|
1631
1787
|
//#region src/SchemastoreConfig.d.ts
|
|
1632
1788
|
declare const ConfigBrand: unique symbol;
|
|
1633
1789
|
/**
|
|
1634
|
-
*
|
|
1635
|
-
* `
|
|
1636
|
-
*
|
|
1637
|
-
*
|
|
1790
|
+
* The SchemaStore `catalog.json` fields a schema entry declares, minus
|
|
1791
|
+
* `url`/`versions` — those are derived from the entry's `baseUrl`, `layout`
|
|
1792
|
+
* and `versions`/`current` by {@link defineConfig}, so they cannot disagree
|
|
1793
|
+
* with the schema's own identity.
|
|
1638
1794
|
*
|
|
1639
1795
|
* @public
|
|
1640
1796
|
*/
|
|
1641
|
-
interface
|
|
1642
|
-
|
|
1797
|
+
interface CatalogInput {
|
|
1798
|
+
/** The catalog description. */
|
|
1643
1799
|
readonly description: string;
|
|
1800
|
+
/** Glob patterns editors match files against; must be non-empty. */
|
|
1644
1801
|
readonly fileMatch: ReadonlyArray<string>;
|
|
1645
|
-
readonly baseUrl: string;
|
|
1646
|
-
/** Where to write the assembled entry; relative paths are resolved by the loader against the config file's directory. */
|
|
1647
|
-
readonly path: string;
|
|
1648
1802
|
}
|
|
1649
1803
|
/**
|
|
1650
|
-
*
|
|
1651
|
-
*
|
|
1804
|
+
* One schema a `schemastore.config.ts` declares, keyed by its own file base
|
|
1805
|
+
* name in {@link SchemastoreConfigInput.schemas}. `$id`, the write `path` and
|
|
1806
|
+
* every catalog URL are derived from `outputDir`, `baseUrl` (this entry's, or
|
|
1807
|
+
* the config's default) and `layout` — never spelled out by hand.
|
|
1808
|
+
*
|
|
1809
|
+
* @public
|
|
1810
|
+
*/
|
|
1811
|
+
interface SchemaEntryInput {
|
|
1812
|
+
/** The Effect Schema source the document is generated from. */
|
|
1813
|
+
readonly schema: Schema.Constraint;
|
|
1814
|
+
/**
|
|
1815
|
+
* The schema's hosted identity, when the application already holds one
|
|
1816
|
+
* (to derive its `$schema` URL from). Supplies `baseUrl`, `versions`,
|
|
1817
|
+
* `current` and `layout`, which must then not be spelled here, and its
|
|
1818
|
+
* `name` must equal this entry's key.
|
|
1819
|
+
*/
|
|
1820
|
+
readonly hosted?: HostedSchema;
|
|
1821
|
+
/**
|
|
1822
|
+
* Every version label this schema advertises. Omit for an unversioned
|
|
1823
|
+
* schema (`<name>.json`). An empty array is rejected — omit the field
|
|
1824
|
+
* instead. Two labels that compare equal under
|
|
1825
|
+
* {@link SchemaVersioning.Order} (`"1.2"` and `"1.2.0"`) are rejected as
|
|
1826
|
+
* one version spelled twice.
|
|
1827
|
+
*/
|
|
1828
|
+
readonly versions?: ReadonlyArray<string>;
|
|
1829
|
+
/**
|
|
1830
|
+
* Which of `versions` is the one generated at this entry's `path`/`$id`;
|
|
1831
|
+
* the rest become {@link ResolvedSchema.frozen} files the CLI verifies
|
|
1832
|
+
* but does not regenerate. Defaults to the newest label under
|
|
1833
|
+
* {@link SchemaVersioning.Order}. Requires `versions`, and must name one
|
|
1834
|
+
* of them.
|
|
1835
|
+
*/
|
|
1836
|
+
readonly current?: string;
|
|
1837
|
+
/**
|
|
1838
|
+
* Whether a consumer already depends on this document at this label —
|
|
1839
|
+
* forwarded to {@link (SchemaTarget:class).(make:1)}. Defaults to `false`.
|
|
1840
|
+
*/
|
|
1841
|
+
readonly published?: boolean;
|
|
1842
|
+
/**
|
|
1843
|
+
* Where this schema is hosted: the literal `"schemastore"` (the only
|
|
1844
|
+
* value that expands `$id` to {@link SCHEMASTORE_ID_BASE} and the catalog
|
|
1845
|
+
* URL to {@link SCHEMASTORE_CATALOG_BASE}, and forces the `"flat"`
|
|
1846
|
+
* layout) or an `https://` URL used as ONE base for both `$id` and the
|
|
1847
|
+
* catalog URL. Falls back to {@link SchemastoreConfigInput.baseUrl} when
|
|
1848
|
+
* omitted; an entry with neither is rejected.
|
|
1849
|
+
*/
|
|
1850
|
+
readonly baseUrl?: string;
|
|
1851
|
+
/**
|
|
1852
|
+
* How a versioned document's path/URL nests relative to its base — see
|
|
1853
|
+
* {@link SchemaLayout}. Defaults to `"versioned"` for a custom `baseUrl`,
|
|
1854
|
+
* and is rejected outright under `baseUrl: "schemastore"`, which serves
|
|
1855
|
+
* only the flat layout.
|
|
1856
|
+
*/
|
|
1857
|
+
readonly layout?: SchemaLayout;
|
|
1858
|
+
/**
|
|
1859
|
+
* Whether a versioned file name carries the `-<version>` suffix
|
|
1860
|
+
* (`<version>/<name>-<version>.json`, the default) or the version
|
|
1861
|
+
* directory alone names it (`<version>/<name>.json`). `false` requires
|
|
1862
|
+
* the `"versioned"` layout. Owned by `hosted` when that is given.
|
|
1863
|
+
*/
|
|
1864
|
+
readonly appendVersion?: boolean;
|
|
1865
|
+
/** Overrides {@link SchemastoreConfigInput.drift} for this schema. */
|
|
1866
|
+
readonly drift?: DriftTolerance;
|
|
1867
|
+
/**
|
|
1868
|
+
* The catalog entry to assemble for this schema. Required under
|
|
1869
|
+
* `baseUrl: "schemastore"` (every SchemaStore-hosted document is
|
|
1870
|
+
* cataloged); optional under a custom host.
|
|
1871
|
+
*/
|
|
1872
|
+
readonly catalog?: CatalogInput;
|
|
1873
|
+
/** Forwarded to {@link (SchemaTarget:class).(make:1)}'s `jsonSchema`. */
|
|
1874
|
+
readonly jsonSchema?: Schema.ToJsonSchemaOptions;
|
|
1875
|
+
/** Forwarded to {@link (SchemaTarget:class).(make:1)}'s `rootAnnotations`. */
|
|
1876
|
+
readonly rootAnnotations?: Readonly<Record<string, unknown>>;
|
|
1877
|
+
}
|
|
1878
|
+
/**
|
|
1879
|
+
* What a `schemastore.config.ts` hands to {@link defineConfig}: a directory
|
|
1880
|
+
* every derived path is written under, top-level defaults for `baseUrl` and
|
|
1881
|
+
* `drift`, and the keyed set of schemas to derive.
|
|
1652
1882
|
*
|
|
1653
1883
|
* @public
|
|
1654
1884
|
*/
|
|
1655
1885
|
interface SchemastoreConfigInput {
|
|
1656
|
-
|
|
1657
|
-
readonly
|
|
1658
|
-
|
|
1886
|
+
/** The directory every derived `path` is written under; a trailing slash is trimmed. */
|
|
1887
|
+
readonly outputDir: string;
|
|
1888
|
+
/** The default {@link SchemaEntryInput.baseUrl} for an entry that declares none. */
|
|
1889
|
+
readonly baseUrl?: string;
|
|
1890
|
+
/** The default {@link SchemaEntryInput.drift} for an entry that declares none. Defaults to `"semantic"`. */
|
|
1891
|
+
readonly drift?: DriftTolerance;
|
|
1892
|
+
/** What a build does when it finds drift. Defaults to `"error"`. */
|
|
1893
|
+
readonly onDrift?: OnDrift;
|
|
1894
|
+
/** Where the assembled catalog is written. Defaults to `<outputDir>/catalog.json`. */
|
|
1895
|
+
readonly catalogPath?: string;
|
|
1896
|
+
/**
|
|
1897
|
+
* The schemas to derive, keyed by file base name — the key IS the
|
|
1898
|
+
* `name` every derived path and URL is built from, so it must be a
|
|
1899
|
+
* simple file base name (no separators, no whitespace).
|
|
1900
|
+
*/
|
|
1901
|
+
readonly schemas: Readonly<Record<string, SchemaEntryInput>>;
|
|
1659
1902
|
}
|
|
1660
1903
|
/**
|
|
1661
|
-
*
|
|
1662
|
-
*
|
|
1904
|
+
* One version of a schema that is advertised (via `versions`) but not the
|
|
1905
|
+
* one currently generated — a file the CLI verifies before any write (it
|
|
1906
|
+
* exists, and its own `$id` is the derived one — the rest of its content is
|
|
1907
|
+
* never compared), never regenerates.
|
|
1663
1908
|
*
|
|
1664
1909
|
* @public
|
|
1665
1910
|
*/
|
|
1666
|
-
interface
|
|
1667
|
-
|
|
1668
|
-
readonly
|
|
1911
|
+
interface FrozenVersion {
|
|
1912
|
+
/** The frozen version label. */
|
|
1913
|
+
readonly version: SchemaVersion;
|
|
1914
|
+
/** The path the frozen file lives at. */
|
|
1915
|
+
readonly path: string;
|
|
1916
|
+
/** The `$id` the frozen document must declare; differs from `url` only under `baseUrl: "schemastore"`. */
|
|
1917
|
+
readonly $id: string;
|
|
1918
|
+
/** The catalog URL the frozen file is hosted at. */
|
|
1919
|
+
readonly url: string;
|
|
1920
|
+
}
|
|
1921
|
+
/**
|
|
1922
|
+
* One `defineConfig` schema entry, resolved: the {@link (SchemaTarget:interface)} to
|
|
1923
|
+
* generate, its frozen predecessor versions, its effective drift tolerance,
|
|
1924
|
+
* and its assembled catalog entry, if any.
|
|
1925
|
+
*
|
|
1926
|
+
* @public
|
|
1927
|
+
*/
|
|
1928
|
+
interface ResolvedSchema {
|
|
1929
|
+
/** The schema's key in {@link SchemastoreConfigInput.schemas}. */
|
|
1930
|
+
readonly name: string;
|
|
1931
|
+
/** The target to generate at the current version (or the sole, unversioned target). */
|
|
1932
|
+
readonly target: SchemaTarget;
|
|
1933
|
+
/** Every OTHER advertised version, as a frozen file to verify. */
|
|
1934
|
+
readonly frozen: ReadonlyArray<FrozenVersion>;
|
|
1935
|
+
/** This entry's effective drift tolerance, after falling back to the config default. */
|
|
1936
|
+
readonly drift: DriftTolerance;
|
|
1937
|
+
/** The assembled catalog entry, when {@link SchemaEntryInput.catalog} was given. */
|
|
1938
|
+
readonly catalog?: CatalogEntry;
|
|
1669
1939
|
}
|
|
1670
1940
|
/**
|
|
1671
1941
|
* The validated, defaults-filled config {@link defineConfig} answers and the
|
|
@@ -1675,23 +1945,47 @@ interface CatalogTarget {
|
|
|
1675
1945
|
*/
|
|
1676
1946
|
interface SchemastoreConfig {
|
|
1677
1947
|
readonly [ConfigBrand]: true;
|
|
1678
|
-
|
|
1679
|
-
readonly
|
|
1680
|
-
|
|
1948
|
+
/** The directory every derived `path` is written under, trailing slash trimmed. */
|
|
1949
|
+
readonly outputDir: string;
|
|
1950
|
+
/** What a build does when it finds drift. */
|
|
1951
|
+
readonly onDrift: OnDrift;
|
|
1952
|
+
/** Where the assembled catalog is written. */
|
|
1953
|
+
readonly catalogPath: string;
|
|
1954
|
+
/** Every schema, resolved. */
|
|
1955
|
+
readonly schemas: ReadonlyArray<ResolvedSchema>;
|
|
1681
1956
|
}
|
|
1682
1957
|
/**
|
|
1683
1958
|
* Validate and assemble a `schemastore.config.ts` value.
|
|
1684
1959
|
*
|
|
1685
1960
|
* @remarks
|
|
1686
|
-
* Pure: no IO, no Effect.
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1689
|
-
*
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1692
|
-
*
|
|
1693
|
-
*
|
|
1694
|
-
*
|
|
1961
|
+
* Pure: no IO, no Effect. `$id`, the write `path` and every catalog URL are
|
|
1962
|
+
* derived from ONE layout (`outputDir`, `baseUrl` and `layout`) so they
|
|
1963
|
+
* cannot disagree with each other. `versions` names every label a schema
|
|
1964
|
+
* advertises; `current` (default: the newest under
|
|
1965
|
+
* {@link SchemaVersioning.Order}) is the one generated at `target`, and every
|
|
1966
|
+
* other label becomes a {@link FrozenVersion} the CLI verifies but does not
|
|
1967
|
+
* regenerate. `baseUrl: "schemastore"` expands to
|
|
1968
|
+
* {@link SCHEMASTORE_ID_BASE} for `$id` and {@link SCHEMASTORE_CATALOG_BASE}
|
|
1969
|
+
* for the catalog URL, forcing the `"flat"` layout; any other `baseUrl` is
|
|
1970
|
+
* used as one base for both, defaulting to the `"versioned"` layout.
|
|
1971
|
+
*
|
|
1972
|
+
* Throws a plain `Error` (never a raw `TypeError`) on every malformed
|
|
1973
|
+
* input. The shape is decoded once per level with a `Schema.Struct`
|
|
1974
|
+
* (`errors: "all"`, so every issue on an entry is reported at once, and
|
|
1975
|
+
* `onExcessProperty: "error"`, so a typo'd key is named rather than
|
|
1976
|
+
* dropped); the message is `defineConfig: schema "<name>" ` followed by the
|
|
1977
|
+
* decode issues (`Expected string at ["baseUrl"]`). After a shape-clean
|
|
1978
|
+
* decode the cross-field rules run: the entry's identity — its
|
|
1979
|
+
* {@link HostedSchema}, or one built from `baseUrl`/`versions`/`current`/
|
|
1980
|
+
* `layout` and the config default — is validated by `HostedSchema` itself
|
|
1981
|
+
* (a `hosted` entry must be keyed by `hosted.name` and must not spell those
|
|
1982
|
+
* four fields beside it); a schema key must be a simple file base name; a
|
|
1983
|
+
* `catalog` is required under `baseUrl: "schemastore"`; an empty `schemas`
|
|
1984
|
+
* record is rejected; and an output path (a target, a frozen file, or the
|
|
1985
|
+
* catalog path) declared twice is rejected after a lexical normalisation
|
|
1986
|
+
* (`./`, `..`, trailing `/`) — the CLI's loader re-checks on the resolved
|
|
1987
|
+
* absolute paths. Branding the result lets a loader recognise a config
|
|
1988
|
+
* module's default export via {@link isSchemastoreConfig}.
|
|
1695
1989
|
*
|
|
1696
1990
|
* @public
|
|
1697
1991
|
*/
|
|
@@ -1704,5 +1998,5 @@ export declare const defineConfig: (input: SchemastoreConfigInput) => Schemastor
|
|
|
1704
1998
|
*/
|
|
1705
1999
|
export declare const isSchemastoreConfig: (value: unknown) => value is SchemastoreConfig;
|
|
1706
2000
|
//#endregion
|
|
1707
|
-
export type { CanonicalJsonError, CanonicalJsonOptions,
|
|
2001
|
+
export type { CanonicalJsonError, CanonicalJsonOptions, CatalogInput, CatalogUrls, CheckResult, ContractChangePolicy, CustomHostedSchemaInput, DriftOptions, DriftTolerance, DriftVerdict, FrozenVersion, GitHubHostedSchemaInput, HostedSchemaVersionsInput, OnDrift, PipelineCheckResult, PipelineResult, ResolvedSchema, SchemaChange, SchemaEntryInput, SchemaFileShape, SchemaLayout, SchemaPipelineOptions, SchemaValidatorOptions, SchemaValidatorShape, SchemaWriteOptions, SchemastoreConfig, SchemastoreConfigInput, StoreDocumentOptions, WriteChange, WriteOutcome, WriteResult };
|
|
1708
2002
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -5,11 +5,12 @@ import { KeywordFamilies } from "./KeywordFamilies.js";
|
|
|
5
5
|
import { DocumentDiff } from "./DocumentDiff.js";
|
|
6
6
|
import { DocumentLint, DocumentLintFinding } from "./DocumentLint.js";
|
|
7
7
|
import { DriftPolicy } from "./DriftPolicy.js";
|
|
8
|
+
import { HostedSchema, SCHEMASTORE_CATALOG_BASE, SCHEMASTORE_ID_BASE } from "./HostedSchema.js";
|
|
8
9
|
import { SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError } from "./SchemaFile.js";
|
|
9
10
|
import { SchemaValidator, SchemaValidatorError, ValidationFinding } from "./SchemaValidator.js";
|
|
10
11
|
import { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument, UndeclaredAnnotationKeyError } from "./StoreDocument.js";
|
|
11
12
|
import { ContractChangeTarget, PipelineFinding, SchemaContractChangeError, SchemaGateError, SchemaPipeline } from "./SchemaPipeline.js";
|
|
12
|
-
import { defineConfig, isSchemastoreConfig } from "./SchemastoreConfig.js";
|
|
13
13
|
import { SchemaTarget } from "./SchemaTarget.js";
|
|
14
|
+
import { defineConfig, isSchemastoreConfig } from "./SchemastoreConfig.js";
|
|
14
15
|
|
|
15
|
-
export { CanonicalJson, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, DriftPolicy, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, UndeclaredAnnotationKeyError, ValidationFinding, defineConfig, isSchemastoreConfig };
|
|
16
|
+
export { CanonicalJson, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, DriftPolicy, HostedSchema, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SCHEMASTORE_CATALOG_BASE, SCHEMASTORE_ID_BASE, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, UndeclaredAnnotationKeyError, ValidationFinding, defineConfig, isSchemastoreConfig };
|