zarr-metadata 0.1.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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/common.d.ts +35 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +10 -0
- package/dist/common.js.map +1 -0
- package/dist/errors.d.ts +88 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +80 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +39 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +22 -0
- package/dist/keys.js.map +1 -0
- package/dist/schemas.d.ts +31 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +43 -0
- package/dist/schemas.js.map +1 -0
- package/dist/standard-schema.d.ts +65 -0
- package/dist/standard-schema.d.ts.map +1 -0
- package/dist/standard-schema.js +11 -0
- package/dist/standard-schema.js.map +1 -0
- package/dist/v2.d.ts +104 -0
- package/dist/v2.d.ts.map +1 -0
- package/dist/v2.js +41 -0
- package/dist/v2.js.map +1 -0
- package/dist/v3.d.ts +89 -0
- package/dist/v3.d.ts.map +1 -0
- package/dist/v3.js +44 -0
- package/dist/v3.js.map +1 -0
- package/dist/validation.d.ts +136 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +784 -0
- package/dist/validation.js.map +1 -0
- package/package.json +51 -0
- package/src/common.ts +39 -0
- package/src/errors.ts +142 -0
- package/src/index.ts +27 -0
- package/src/keys.ts +45 -0
- package/src/schemas.ts +96 -0
- package/src/standard-schema.ts +78 -0
- package/src/v2.ts +126 -0
- package/src/v3.ts +111 -0
- package/src/validation.ts +937 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Davis Bennett
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# zarr-metadata (TypeScript)
|
|
2
|
+
|
|
3
|
+
Spec-defined metadata types and structural validators for
|
|
4
|
+
[Zarr](https://zarr.dev) v2 and v3, in TypeScript. A port of the Python
|
|
5
|
+
[`zarr-metadata`](https://pypi.org/project/zarr-metadata/) package (the
|
|
6
|
+
reference implementation), kept in lockstep by a shared conformance corpus.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import {
|
|
10
|
+
validateMetadataV3,
|
|
11
|
+
safeParseArrayMetadataV2,
|
|
12
|
+
isEmptyTree,
|
|
13
|
+
flattenTree,
|
|
14
|
+
} from "zarr-metadata";
|
|
15
|
+
|
|
16
|
+
// Validation produces a tree of errors mirroring the document's shape;
|
|
17
|
+
// an empty tree means the document is valid.
|
|
18
|
+
const errors = validateMetadataV3(JSON.parse(text));
|
|
19
|
+
if (!isEmptyTree(errors)) {
|
|
20
|
+
errors.children.get("codecs"); // the subtree of codec problems
|
|
21
|
+
flattenTree(errors); // the flat view, for diagnostics:
|
|
22
|
+
// [{ path: ["codecs"], kind: "invalid_value", message: "expected at least one codec" }]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Or the discriminated-union form:
|
|
26
|
+
const result = safeParseArrayMetadataV2(JSON.parse(zarrayText));
|
|
27
|
+
if (result.success) {
|
|
28
|
+
result.value.shape; // typed as ZarrV2ArrayMetadataJSON
|
|
29
|
+
} else {
|
|
30
|
+
result.errors; // the ErrorTree
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Each document kind gets four entry points:
|
|
35
|
+
|
|
36
|
+
- `validate*(value)` → `ErrorTree` (empty tree means valid)
|
|
37
|
+
- `safeParse*(value)` → `{ success: true, value } | { success: false, errors }`
|
|
38
|
+
- `is*(value)` → type guard
|
|
39
|
+
- `parse*(value)` → narrowed document or throws `MetadataValidationError`
|
|
40
|
+
(which carries the tree as `.errors` and its flat view as `.issues`)
|
|
41
|
+
|
|
42
|
+
## Standard Schema
|
|
43
|
+
|
|
44
|
+
Every document kind is also exported as a
|
|
45
|
+
[Standard Schema](https://standardschema.dev) — the interop contract
|
|
46
|
+
implemented by Zod, Valibot, and ArkType — so the validators plug directly
|
|
47
|
+
into anything that accepts standard schemas (tRPC, form libraries, ...):
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { metadataV3Schema, type StandardSchemaV1 } from "zarr-metadata";
|
|
51
|
+
|
|
52
|
+
const result = await metadataV3Schema["~standard"].validate(JSON.parse(text));
|
|
53
|
+
if (result.issues === undefined) {
|
|
54
|
+
result.value; // ZarrV3ArrayMetadataJSON | ZarrV3GroupMetadataJSON
|
|
55
|
+
}
|
|
56
|
+
type Doc = StandardSchemaV1.InferOutput<typeof metadataV3Schema>;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Validation is synchronous; each issue keeps its machine-readable `kind` as
|
|
60
|
+
a spec-permitted extension. The schemas are `jsonValueSchema`,
|
|
61
|
+
`metadataFieldV3Schema`, `{array,group,consolidated}MetadataV3Schema`,
|
|
62
|
+
`metadataV3Schema` (the `zarr.json` dispatcher), and
|
|
63
|
+
`{array,group,consolidated}MetadataV2Schema`. The spec types are vendored
|
|
64
|
+
(the package stays dependency-free); the test suite pins them against the
|
|
65
|
+
official `@standard-schema/spec` package.
|
|
66
|
+
|
|
67
|
+
Covered documents: v3 array/group (`zarr.json`, including inline
|
|
68
|
+
`consolidated_metadata`), v2 array/group merged forms (`.zarray` /
|
|
69
|
+
`.zgroup` + `.zattrs`), and v2 consolidated metadata (`.zmetadata`).
|
|
70
|
+
The `MetadataV3` family dispatches on `node_type` for consumers handed an
|
|
71
|
+
arbitrary `zarr.json`.
|
|
72
|
+
|
|
73
|
+
The error-tree shape follows TypeScript validation-library convention
|
|
74
|
+
(compare Zod's `treeifyError` and `safeParse`) rather than the Python
|
|
75
|
+
package's flat problem lists; `flattenTree`/`treeOf` convert between the
|
|
76
|
+
two, and the flat path+kind form remains the cross-language interchange
|
|
77
|
+
format the conformance corpus asserts on.
|
|
78
|
+
|
|
79
|
+
Validation is structural (key presence, value shapes, fixed literals), not
|
|
80
|
+
domain-level: extension points (codecs, chunk grids, data types) are never
|
|
81
|
+
interpreted, matching the Python package's layering.
|
|
82
|
+
|
|
83
|
+
Consumers include the
|
|
84
|
+
[Zarr Metadata VS Code extension](https://github.com/d-v-b/vscode-zarr).
|
|
85
|
+
|
|
86
|
+
## How correctness is maintained
|
|
87
|
+
|
|
88
|
+
The [conformance corpus](conformance/) is the contract with the Python
|
|
89
|
+
reference implementation: shared JSON fixtures asserting the exact problem
|
|
90
|
+
set (loc + kind) each document must produce. Both test suites run every
|
|
91
|
+
case; a spec change updates the corpus first, turning both implementations
|
|
92
|
+
red until each is fixed.
|
|
93
|
+
|
|
94
|
+
## Development
|
|
95
|
+
|
|
96
|
+
Development verbs live in the [justfile](justfile) (needs
|
|
97
|
+
[`just`](https://github.com/casey/just), plus `uv` for the conformance
|
|
98
|
+
recipe); `just` with no arguments lists them:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
just install # npm install
|
|
102
|
+
just build # tsc → dist/
|
|
103
|
+
just test # vitest: conformance corpus + unit tests
|
|
104
|
+
just typecheck # sources and tests, including type-level assertions
|
|
105
|
+
just conformance # corpus vs the Python reference (PyPI by default)
|
|
106
|
+
just check # everything CI runs
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`just conformance ../zarr-python/packages/zarr-metadata` runs the corpus
|
|
110
|
+
against a local zarr-python checkout instead of the released PyPI package.
|
|
111
|
+
Each recipe wraps a plain npm/uv command, so `just` itself is optional.
|
|
112
|
+
|
|
113
|
+
Releases are changeset-driven; see [RELEASING.md](RELEASING.md).
|
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-version primitives for Zarr metadata.
|
|
3
|
+
*
|
|
4
|
+
* This package is a TypeScript port of the Python `zarr-metadata` package
|
|
5
|
+
* (https://pypi.org/project/zarr-metadata/), which is the reference
|
|
6
|
+
* implementation. The two are kept in lockstep by a shared conformance
|
|
7
|
+
* corpus; see `conformance/` at the repository root.
|
|
8
|
+
*/
|
|
9
|
+
/** A JSON-encodable value. */
|
|
10
|
+
export type JSONValue = string | number | boolean | null | JSONValue[] | {
|
|
11
|
+
[key: string]: JSONValue;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Externally-tagged union member for a v3 metadata field.
|
|
15
|
+
*
|
|
16
|
+
* The optional `configuration` mapping holds arbitrary JSON-encodable
|
|
17
|
+
* values. `must_understand` is implicitly true when absent.
|
|
18
|
+
*/
|
|
19
|
+
export type ZarrV3NamedConfigJSON = {
|
|
20
|
+
name: string;
|
|
21
|
+
configuration?: {
|
|
22
|
+
[key: string]: JSONValue;
|
|
23
|
+
};
|
|
24
|
+
must_understand?: boolean;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The JSON shape of any v3 metadata extension-point entry: either a bare
|
|
28
|
+
* short-hand name string or a `{name, configuration, must_understand}`
|
|
29
|
+
* envelope.
|
|
30
|
+
*
|
|
31
|
+
* Used for `data_type`, `chunk_grid`, `chunk_key_encoding`, individual
|
|
32
|
+
* codec entries, and `storage_transformers` in v3 array metadata.
|
|
33
|
+
*/
|
|
34
|
+
export type ZarrV3MetadataFieldJSON = string | ZarrV3NamedConfigJSON;
|
|
35
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,8BAA8B;AAC9B,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC7C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,qBAAqB,CAAC"}
|
package/dist/common.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-version primitives for Zarr metadata.
|
|
3
|
+
*
|
|
4
|
+
* This package is a TypeScript port of the Python `zarr-metadata` package
|
|
5
|
+
* (https://pypi.org/project/zarr-metadata/), which is the reference
|
|
6
|
+
* implementation. The two are kept in lockstep by a shared conformance
|
|
7
|
+
* corpus; see `conformance/` at the repository root.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error vocabulary: validation produces a tree of issues mirroring the
|
|
3
|
+
* document's shape, and an empty tree means the document is valid.
|
|
4
|
+
*
|
|
5
|
+
* This shape is native to TypeScript validation libraries (compare Zod's
|
|
6
|
+
* `treeifyError` and `safeParse`) rather than ported from the Python
|
|
7
|
+
* reference implementation, which returns a flat list of loc-tagged
|
|
8
|
+
* problems. The two are isomorphic: `flattenTree` produces the flat
|
|
9
|
+
* path+kind form — the interchange format the cross-language conformance
|
|
10
|
+
* corpus asserts on, and the form editor tooling needs to place a
|
|
11
|
+
* diagnostic at a document location — and `treeOf` rebuilds a tree from it.
|
|
12
|
+
*
|
|
13
|
+
* Invariant: a subtree exists only on the path to at least one issue, so
|
|
14
|
+
* `isEmptyTree` never has to search — an empty root IS the success case.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Machine-readable classification of an issue.
|
|
18
|
+
*
|
|
19
|
+
* - `missing_key`: a required key (document key or store key) is absent.
|
|
20
|
+
* - `invalid_type`: a value has the wrong structural type (e.g. a string
|
|
21
|
+
* where a mapping is required).
|
|
22
|
+
* - `invalid_value`: a value has an acceptable type but invalid content
|
|
23
|
+
* (e.g. `zarr_format: 2` in a v3 document, `order: "Q"`).
|
|
24
|
+
* - `invalid_json`: bytes/text that do not decode as JSON.
|
|
25
|
+
*/
|
|
26
|
+
export type IssueKind = "missing_key" | "invalid_type" | "invalid_value" | "invalid_json";
|
|
27
|
+
/** One problem, attached to the tree node whose document location it describes. */
|
|
28
|
+
export interface Issue {
|
|
29
|
+
readonly kind: IssueKind;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The path from the document root to a value: object keys and array
|
|
34
|
+
* indices, e.g. `["codecs", 0, "name"]`. Empty means the document itself.
|
|
35
|
+
*/
|
|
36
|
+
export type IssuePath = ReadonlyArray<string | number>;
|
|
37
|
+
/** An issue paired with its full path — the flat view of a tree entry. */
|
|
38
|
+
export interface PathedIssue extends Issue {
|
|
39
|
+
readonly path: IssuePath;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Every problem found in a document, arranged as a tree mirroring the
|
|
43
|
+
* document's own shape: `issues` holds the problems at this location, and
|
|
44
|
+
* `children` (keyed by object key or array index) holds the problems below
|
|
45
|
+
* it. An empty tree — no issues, no children — means validation succeeded.
|
|
46
|
+
*
|
|
47
|
+
* `children` is a `Map` so array indices keep their number identity
|
|
48
|
+
* instead of collapsing into string keys.
|
|
49
|
+
*/
|
|
50
|
+
export interface ErrorTree {
|
|
51
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
52
|
+
readonly children: ReadonlyMap<string | number, ErrorTree>;
|
|
53
|
+
}
|
|
54
|
+
/** Whether `tree` holds no issues anywhere — the success verdict. */
|
|
55
|
+
export declare function isEmptyTree(tree: ErrorTree): boolean;
|
|
56
|
+
/** Build an `ErrorTree` from flat pathed issues (the inverse of `flattenTree`). */
|
|
57
|
+
export declare function treeOf(issues: ReadonlyArray<PathedIssue>): ErrorTree;
|
|
58
|
+
/**
|
|
59
|
+
* The flat view of `tree`: every issue with its full path, parents before
|
|
60
|
+
* children. This is the interchange form — what the conformance corpus
|
|
61
|
+
* asserts on, and what a consumer placing diagnostics in a text document
|
|
62
|
+
* wants.
|
|
63
|
+
*/
|
|
64
|
+
export declare function flattenTree(tree: ErrorTree): PathedIssue[];
|
|
65
|
+
/** Render `tree` as one human-readable line per issue (`"path.to.value: message"`). */
|
|
66
|
+
export declare function formatTree(tree: ErrorTree): string;
|
|
67
|
+
/**
|
|
68
|
+
* The result of a `safeParse*` function: the narrowed document on success,
|
|
69
|
+
* the error tree on failure.
|
|
70
|
+
*/
|
|
71
|
+
export type ParseResult<T> = {
|
|
72
|
+
readonly success: true;
|
|
73
|
+
readonly value: T;
|
|
74
|
+
} | {
|
|
75
|
+
readonly success: false;
|
|
76
|
+
readonly errors: ErrorTree;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Thrown by `parse*` functions and the store entry points when a value
|
|
80
|
+
* fails validation. Carries the complete error tree (not just the first
|
|
81
|
+
* problem) as `.errors`, with `.issues` as its flat view.
|
|
82
|
+
*/
|
|
83
|
+
export declare class MetadataValidationError extends Error {
|
|
84
|
+
readonly errors: ErrorTree;
|
|
85
|
+
readonly issues: ReadonlyArray<PathedIssue>;
|
|
86
|
+
constructor(errors: ErrorTree);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,eAAe,GAAG,cAAc,CAAC;AAE1F,mFAAmF;AACnF,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,WAAW,WAAY,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC;CAC5D;AAED,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAEpD;AAOD,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,SAAS,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CAY1D;AAOD,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAElD;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC7C;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5D;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;gBAEhC,MAAM,EAAE,SAAS;CAO9B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The error vocabulary: validation produces a tree of issues mirroring the
|
|
3
|
+
* document's shape, and an empty tree means the document is valid.
|
|
4
|
+
*
|
|
5
|
+
* This shape is native to TypeScript validation libraries (compare Zod's
|
|
6
|
+
* `treeifyError` and `safeParse`) rather than ported from the Python
|
|
7
|
+
* reference implementation, which returns a flat list of loc-tagged
|
|
8
|
+
* problems. The two are isomorphic: `flattenTree` produces the flat
|
|
9
|
+
* path+kind form — the interchange format the cross-language conformance
|
|
10
|
+
* corpus asserts on, and the form editor tooling needs to place a
|
|
11
|
+
* diagnostic at a document location — and `treeOf` rebuilds a tree from it.
|
|
12
|
+
*
|
|
13
|
+
* Invariant: a subtree exists only on the path to at least one issue, so
|
|
14
|
+
* `isEmptyTree` never has to search — an empty root IS the success case.
|
|
15
|
+
*/
|
|
16
|
+
/** Whether `tree` holds no issues anywhere — the success verdict. */
|
|
17
|
+
export function isEmptyTree(tree) {
|
|
18
|
+
return tree.issues.length === 0 && tree.children.size === 0;
|
|
19
|
+
}
|
|
20
|
+
/** Build an `ErrorTree` from flat pathed issues (the inverse of `flattenTree`). */
|
|
21
|
+
export function treeOf(issues) {
|
|
22
|
+
const root = { issues: [], children: new Map() };
|
|
23
|
+
for (const { path, kind, message } of issues) {
|
|
24
|
+
let node = root;
|
|
25
|
+
for (const part of path) {
|
|
26
|
+
let child = node.children.get(part);
|
|
27
|
+
if (child === undefined) {
|
|
28
|
+
child = { issues: [], children: new Map() };
|
|
29
|
+
node.children.set(part, child);
|
|
30
|
+
}
|
|
31
|
+
node = child;
|
|
32
|
+
}
|
|
33
|
+
node.issues.push({ kind, message });
|
|
34
|
+
}
|
|
35
|
+
return root;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The flat view of `tree`: every issue with its full path, parents before
|
|
39
|
+
* children. This is the interchange form — what the conformance corpus
|
|
40
|
+
* asserts on, and what a consumer placing diagnostics in a text document
|
|
41
|
+
* wants.
|
|
42
|
+
*/
|
|
43
|
+
export function flattenTree(tree) {
|
|
44
|
+
const out = [];
|
|
45
|
+
const walk = (node, path) => {
|
|
46
|
+
for (const issue of node.issues) {
|
|
47
|
+
out.push({ path, kind: issue.kind, message: issue.message });
|
|
48
|
+
}
|
|
49
|
+
for (const [part, child] of node.children) {
|
|
50
|
+
walk(child, [...path, part]);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
walk(tree, []);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
function formatPathedIssue(issue) {
|
|
57
|
+
const location = issue.path.length > 0 ? issue.path.join(".") : "<root>";
|
|
58
|
+
return `${location}: ${issue.message}`;
|
|
59
|
+
}
|
|
60
|
+
/** Render `tree` as one human-readable line per issue (`"path.to.value: message"`). */
|
|
61
|
+
export function formatTree(tree) {
|
|
62
|
+
return flattenTree(tree).map(formatPathedIssue).join("\n");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Thrown by `parse*` functions and the store entry points when a value
|
|
66
|
+
* fails validation. Carries the complete error tree (not just the first
|
|
67
|
+
* problem) as `.errors`, with `.issues` as its flat view.
|
|
68
|
+
*/
|
|
69
|
+
export class MetadataValidationError extends Error {
|
|
70
|
+
errors;
|
|
71
|
+
issues;
|
|
72
|
+
constructor(errors) {
|
|
73
|
+
const issues = flattenTree(errors);
|
|
74
|
+
super(issues.map(formatPathedIssue).join("\n"));
|
|
75
|
+
this.name = "MetadataValidationError";
|
|
76
|
+
this.errors = errors;
|
|
77
|
+
this.issues = issues;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zarr-metadata: spec-defined metadata types and validators for Zarr v2 and
|
|
3
|
+
* v3, in TypeScript.
|
|
4
|
+
*
|
|
5
|
+
* A port of the Python `zarr-metadata` package (the reference
|
|
6
|
+
* implementation), kept in lockstep by a shared conformance corpus.
|
|
7
|
+
*/
|
|
8
|
+
export type { JSONValue, ZarrV3MetadataFieldJSON, ZarrV3NamedConfigJSON } from "./common.js";
|
|
9
|
+
export { flattenTree, formatTree, isEmptyTree, MetadataValidationError, treeOf, type ErrorTree, type Issue, type IssueKind, type IssuePath, type ParseResult, type PathedIssue, } from "./errors.js";
|
|
10
|
+
export * from "./schemas.js";
|
|
11
|
+
export type { StandardSchemaV1 } from "./standard-schema.js";
|
|
12
|
+
export * from "./v2.js";
|
|
13
|
+
export * from "./v3.js";
|
|
14
|
+
export * from "./validation.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,SAAS,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,uBAAuB,EACvB,MAAM,EACN,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AACrB,cAAc,cAAc,CAAC;AAC7B,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zarr-metadata: spec-defined metadata types and validators for Zarr v2 and
|
|
3
|
+
* v3, in TypeScript.
|
|
4
|
+
*
|
|
5
|
+
* A port of the Python `zarr-metadata` package (the reference
|
|
6
|
+
* implementation), kept in lockstep by a shared conformance corpus.
|
|
7
|
+
*/
|
|
8
|
+
export { flattenTree, formatTree, isEmptyTree, MetadataValidationError, treeOf, } from "./errors.js";
|
|
9
|
+
export * from "./schemas.js";
|
|
10
|
+
export * from "./v2.js";
|
|
11
|
+
export * from "./v3.js";
|
|
12
|
+
export * from "./validation.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,uBAAuB,EACvB,MAAM,GAOP,MAAM,aAAa,CAAC;AACrB,cAAc,cAAc,CAAC;AAE7B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC"}
|
package/dist/keys.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time machinery tying the runtime key arrays to the document types.
|
|
3
|
+
*
|
|
4
|
+
* The validators need key names at runtime, and TypeScript types are erased,
|
|
5
|
+
* so the arrays in v2.ts / v3.ts cannot be derived from the types the way
|
|
6
|
+
* the Python package derives its key sets from `__required_keys__`. What the
|
|
7
|
+
* type system CAN do is the reverse: prove each array is exactly the set of
|
|
8
|
+
* required (or optional) keys declared by the document type, so the two can
|
|
9
|
+
* never drift.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The declared properties of `T`, with index signatures stripped.
|
|
13
|
+
*
|
|
14
|
+
* The v3 document types carry a `[key: string]: ...` index signature for
|
|
15
|
+
* extension fields; without stripping it, `keyof` collapses to `string` and
|
|
16
|
+
* the per-key extraction below would be meaningless.
|
|
17
|
+
*/
|
|
18
|
+
type Known<T> = {
|
|
19
|
+
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
|
|
20
|
+
};
|
|
21
|
+
/** The union of `T`'s required declared keys. */
|
|
22
|
+
export type RequiredKeysOf<T> = {
|
|
23
|
+
[K in keyof Known<T>]-?: {} extends Pick<Known<T>, K> ? never : K;
|
|
24
|
+
}[keyof Known<T>];
|
|
25
|
+
/** The union of `T`'s optional declared keys. */
|
|
26
|
+
export type OptionalKeysOf<T> = {
|
|
27
|
+
[K in keyof Known<T>]-?: {} extends Pick<Known<T>, K> ? K : never;
|
|
28
|
+
}[keyof Known<T>];
|
|
29
|
+
/**
|
|
30
|
+
* Identity for a readonly tuple of keys, statically checked to be EXACTLY
|
|
31
|
+
* the union `U`: the element constraint rejects keys outside `U`, and the
|
|
32
|
+
* intersected conditional rejects the tuple when any member of `U` is
|
|
33
|
+
* missing (surfacing as a "not assignable" error on the argument).
|
|
34
|
+
*
|
|
35
|
+
* Usage: `exactKeys<RequiredKeysOf<Doc>>()(["a", "b"])`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function exactKeys<U extends PropertyKey>(): <const A extends readonly U[]>(keys: A & ([U] extends [A[number]] ? unknown : never)) => A;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;GAMG;AACH,KAAK,KAAK,CAAC,CAAC,IAAI;KACb,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChF,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAC7B,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;CAClE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAElB,iDAAiD;AACjD,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAC7B,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAClE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAElB;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,WAAW,MACrC,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,EAAE,EAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,GAAG,KAAK,CAAC,KACpD,CAAC,CACL"}
|
package/dist/keys.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time machinery tying the runtime key arrays to the document types.
|
|
3
|
+
*
|
|
4
|
+
* The validators need key names at runtime, and TypeScript types are erased,
|
|
5
|
+
* so the arrays in v2.ts / v3.ts cannot be derived from the types the way
|
|
6
|
+
* the Python package derives its key sets from `__required_keys__`. What the
|
|
7
|
+
* type system CAN do is the reverse: prove each array is exactly the set of
|
|
8
|
+
* required (or optional) keys declared by the document type, so the two can
|
|
9
|
+
* never drift.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Identity for a readonly tuple of keys, statically checked to be EXACTLY
|
|
13
|
+
* the union `U`: the element constraint rejects keys outside `U`, and the
|
|
14
|
+
* intersected conditional rejects the tuple when any member of `U` is
|
|
15
|
+
* missing (surfacing as a "not assignable" error on the argument).
|
|
16
|
+
*
|
|
17
|
+
* Usage: `exactKeys<RequiredKeysOf<Doc>>()(["a", "b"])`.
|
|
18
|
+
*/
|
|
19
|
+
export function exactKeys() {
|
|
20
|
+
return (keys) => keys;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=keys.js.map
|
package/dist/keys.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuBH;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,CACL,IAAqD,EAClD,EAAE,CAAC,IAAI,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard Schema (https://standardschema.dev) objects for every document
|
|
3
|
+
* kind, so the validators plug into anything that accepts standard schemas
|
|
4
|
+
* (tRPC, form libraries, ...).
|
|
5
|
+
*
|
|
6
|
+
* Each schema wraps the corresponding `safeParse*` function: validation is
|
|
7
|
+
* synchronous, success carries the narrowed document, and failure carries
|
|
8
|
+
* the flattened error tree as standard issues. Every issue additionally
|
|
9
|
+
* keeps its machine-readable `kind` (an extension the standard permits);
|
|
10
|
+
* consumers wanting the full `ErrorTree` should use `validate*` directly.
|
|
11
|
+
*/
|
|
12
|
+
import { type IssueKind } from "./errors.js";
|
|
13
|
+
import type { JSONValue, ZarrV3MetadataFieldJSON } from "./common.js";
|
|
14
|
+
import type { StandardSchemaV1 } from "./standard-schema.js";
|
|
15
|
+
import type { ZarrV2ArrayMetadataJSON, ZarrV2ConsolidatedMetadataJSON, ZarrV2GroupMetadataJSON } from "./v2.js";
|
|
16
|
+
import type { ZarrV3ArrayMetadataJSON, ZarrV3ConsolidatedMetadataJSON, ZarrV3GroupMetadataJSON, ZarrV3MetadataJSON } from "./v3.js";
|
|
17
|
+
/** A standard issue that also keeps zarr-metadata's machine-readable kind. */
|
|
18
|
+
export interface StandardIssue extends StandardSchemaV1.Issue {
|
|
19
|
+
readonly kind: IssueKind;
|
|
20
|
+
}
|
|
21
|
+
export declare const jsonValueSchema: StandardSchemaV1<unknown, JSONValue>;
|
|
22
|
+
export declare const metadataFieldV3Schema: StandardSchemaV1<unknown, ZarrV3MetadataFieldJSON>;
|
|
23
|
+
export declare const arrayMetadataV3Schema: StandardSchemaV1<unknown, ZarrV3ArrayMetadataJSON>;
|
|
24
|
+
export declare const groupMetadataV3Schema: StandardSchemaV1<unknown, ZarrV3GroupMetadataJSON>;
|
|
25
|
+
export declare const consolidatedMetadataV3Schema: StandardSchemaV1<unknown, ZarrV3ConsolidatedMetadataJSON>;
|
|
26
|
+
/** The complete `zarr.json` grammar, dispatching on `node_type`. */
|
|
27
|
+
export declare const metadataV3Schema: StandardSchemaV1<unknown, ZarrV3MetadataJSON>;
|
|
28
|
+
export declare const arrayMetadataV2Schema: StandardSchemaV1<unknown, ZarrV2ArrayMetadataJSON>;
|
|
29
|
+
export declare const groupMetadataV2Schema: StandardSchemaV1<unknown, ZarrV2GroupMetadataJSON>;
|
|
30
|
+
export declare const consolidatedMetadataV2Schema: StandardSchemaV1<unknown, ZarrV2ConsolidatedMetadataJSON>;
|
|
31
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAe,KAAK,SAAS,EAAsC,MAAM,aAAa,CAAC;AAC9F,OAAO,KAAK,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAY7D,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACxB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,8EAA8E;AAC9E,MAAM,WAAW,aAAc,SAAQ,gBAAgB,CAAC,KAAK;IAC3D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAyBD,eAAO,MAAM,eAAe,EAAE,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAA2B,CAAC;AAE7F,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CACjD,CAAC;AAErC,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CACjD,CAAC;AAErC,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CACjD,CAAC;AAErC,eAAO,MAAM,4BAA4B,EAAE,gBAAgB,CACzD,OAAO,EACP,8BAA8B,CACa,CAAC;AAE9C,oEAAoE;AACpE,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,CAC5C,CAAC;AAEhC,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CACjD,CAAC;AAErC,eAAO,MAAM,qBAAqB,EAAE,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,CACjD,CAAC;AAErC,eAAO,MAAM,4BAA4B,EAAE,gBAAgB,CACzD,OAAO,EACP,8BAA8B,CACa,CAAC"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard Schema (https://standardschema.dev) objects for every document
|
|
3
|
+
* kind, so the validators plug into anything that accepts standard schemas
|
|
4
|
+
* (tRPC, form libraries, ...).
|
|
5
|
+
*
|
|
6
|
+
* Each schema wraps the corresponding `safeParse*` function: validation is
|
|
7
|
+
* synchronous, success carries the narrowed document, and failure carries
|
|
8
|
+
* the flattened error tree as standard issues. Every issue additionally
|
|
9
|
+
* keeps its machine-readable `kind` (an extension the standard permits);
|
|
10
|
+
* consumers wanting the full `ErrorTree` should use `validate*` directly.
|
|
11
|
+
*/
|
|
12
|
+
import { flattenTree } from "./errors.js";
|
|
13
|
+
import { safeParseArrayMetadataV2, safeParseArrayMetadataV3, safeParseConsolidatedMetadataV2, safeParseConsolidatedMetadataV3, safeParseGroupMetadataV2, safeParseGroupMetadataV3, safeParseJson, safeParseMetadataFieldV3, safeParseMetadataV3, } from "./validation.js";
|
|
14
|
+
function toStandardIssue(issue) {
|
|
15
|
+
return issue.path.length === 0
|
|
16
|
+
? { message: issue.message, kind: issue.kind }
|
|
17
|
+
: { message: issue.message, path: [...issue.path], kind: issue.kind };
|
|
18
|
+
}
|
|
19
|
+
function schemaOf(safeParse) {
|
|
20
|
+
return {
|
|
21
|
+
"~standard": {
|
|
22
|
+
version: 1,
|
|
23
|
+
vendor: "zarr-metadata",
|
|
24
|
+
validate: (value) => {
|
|
25
|
+
const result = safeParse(value);
|
|
26
|
+
return result.success
|
|
27
|
+
? { value: result.value }
|
|
28
|
+
: { issues: flattenTree(result.errors).map(toStandardIssue) };
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export const jsonValueSchema = schemaOf(safeParseJson);
|
|
34
|
+
export const metadataFieldV3Schema = schemaOf(safeParseMetadataFieldV3);
|
|
35
|
+
export const arrayMetadataV3Schema = schemaOf(safeParseArrayMetadataV3);
|
|
36
|
+
export const groupMetadataV3Schema = schemaOf(safeParseGroupMetadataV3);
|
|
37
|
+
export const consolidatedMetadataV3Schema = schemaOf(safeParseConsolidatedMetadataV3);
|
|
38
|
+
/** The complete `zarr.json` grammar, dispatching on `node_type`. */
|
|
39
|
+
export const metadataV3Schema = schemaOf(safeParseMetadataV3);
|
|
40
|
+
export const arrayMetadataV2Schema = schemaOf(safeParseArrayMetadataV2);
|
|
41
|
+
export const groupMetadataV2Schema = schemaOf(safeParseGroupMetadataV2);
|
|
42
|
+
export const consolidatedMetadataV2Schema = schemaOf(safeParseConsolidatedMetadataV2);
|
|
43
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,WAAW,EAAsD,MAAM,aAAa,CAAC;AAG9F,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,+BAA+B,EAC/B,+BAA+B,EAC/B,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAkBzB,SAAS,eAAe,CAAC,KAAkB;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAC5B,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;QAC9C,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAC1E,CAAC;AAED,SAAS,QAAQ,CACf,SAA6C;IAE7C,OAAO;QACL,WAAW,EAAE;YACX,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,eAAe;YACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;gBAChC,OAAO,MAAM,CAAC,OAAO;oBACnB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;oBACzB,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAClE,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAyC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAE7F,MAAM,CAAC,MAAM,qBAAqB,GAChC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,qBAAqB,GAChC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,qBAAqB,GAChC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,4BAA4B,GAGrC,QAAQ,CAAC,+BAA+B,CAAC,CAAC;AAE9C,oEAAoE;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,qBAAqB,GAChC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,qBAAqB,GAChC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,4BAA4B,GAGrC,QAAQ,CAAC,+BAA+B,CAAC,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Standard Schema V1 interface (https://standardschema.dev), vendored.
|
|
3
|
+
*
|
|
4
|
+
* Standard Schema is the interoperability contract implemented by Zod,
|
|
5
|
+
* Valibot, ArkType, and consumed by tRPC, form libraries, and others. The
|
|
6
|
+
* spec is designed to be copied into implementing libraries so they stay
|
|
7
|
+
* dependency-free; the test suite checks this copy against the official
|
|
8
|
+
* `@standard-schema/spec` types (a devDependency) so it cannot drift.
|
|
9
|
+
*/
|
|
10
|
+
/** The Standard Schema interface. */
|
|
11
|
+
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
12
|
+
/** The Standard Schema properties. */
|
|
13
|
+
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
|
14
|
+
}
|
|
15
|
+
export declare namespace StandardSchemaV1 {
|
|
16
|
+
/** The Standard Schema properties interface. */
|
|
17
|
+
interface Props<Input = unknown, Output = Input> {
|
|
18
|
+
/** The version number of the standard. */
|
|
19
|
+
readonly version: 1;
|
|
20
|
+
/** The vendor name of the schema library. */
|
|
21
|
+
readonly vendor: string;
|
|
22
|
+
/** Validates unknown input values. */
|
|
23
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
24
|
+
/** Inferred types associated with the schema. */
|
|
25
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
26
|
+
}
|
|
27
|
+
/** The result interface of the validate function. */
|
|
28
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
29
|
+
/** The result interface if validation succeeds. */
|
|
30
|
+
interface SuccessResult<Output> {
|
|
31
|
+
/** The typed output value. */
|
|
32
|
+
readonly value: Output;
|
|
33
|
+
/** The non-existent issues. */
|
|
34
|
+
readonly issues?: undefined;
|
|
35
|
+
}
|
|
36
|
+
/** The result interface if validation fails. */
|
|
37
|
+
interface FailureResult {
|
|
38
|
+
/** The issues of failed validation. */
|
|
39
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
40
|
+
}
|
|
41
|
+
/** The issue interface of the failure output. */
|
|
42
|
+
interface Issue {
|
|
43
|
+
/** The error message of the issue. */
|
|
44
|
+
readonly message: string;
|
|
45
|
+
/** The path of the issue, if any. */
|
|
46
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** The path segment interface of the issue. */
|
|
49
|
+
interface PathSegment {
|
|
50
|
+
/** The key representing a path segment. */
|
|
51
|
+
readonly key: PropertyKey;
|
|
52
|
+
}
|
|
53
|
+
/** The Standard Schema types interface. */
|
|
54
|
+
interface Types<Input = unknown, Output = Input> {
|
|
55
|
+
/** The input type of the schema. */
|
|
56
|
+
readonly input: Input;
|
|
57
|
+
/** The output type of the schema. */
|
|
58
|
+
readonly output: Output;
|
|
59
|
+
}
|
|
60
|
+
/** Infers the input type of a Standard Schema. */
|
|
61
|
+
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
|
|
62
|
+
/** Infers the output type of a Standard Schema. */
|
|
63
|
+
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=standard-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qCAAqC;AACrC,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,sCAAsC;IACtC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,gDAAgD;IAChD,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,0CAA0C;QAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,6CAA6C;QAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,sCAAsC;QACtC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAChF,iDAAiD;QACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KACnD;IAED,qDAAqD;IACrD,KAAY,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;IAEnE,mDAAmD;IACnD,UAAiB,aAAa,CAAC,MAAM;QACnC,8BAA8B;QAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,+BAA+B;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;KAC7B;IAED,gDAAgD;IAChD,UAAiB,aAAa;QAC5B,uCAAuC;QACvC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;KACvC;IAED,iDAAiD;IACjD,UAAiB,KAAK;QACpB,sCAAsC;QACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,qCAAqC;QACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,SAAS,CAAC;KACtE;IAED,+CAA+C;IAC/C,UAAiB,WAAW;QAC1B,2CAA2C;QAC3C,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;KAC3B;IAED,2CAA2C;IAC3C,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,oCAAoC;QACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,qCAAqC;QACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB;IAED,kDAAkD;IAClD,KAAY,UAAU,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CACnE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,OAAO,CAAC,CAAC;IAEX,mDAAmD;IACnD,KAAY,WAAW,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CACpE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,QAAQ,CAAC,CAAC;CACb"}
|