@akterjs/cli 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +47 -2
- package/dist/Argument-D81dqizB.mjs +57 -0
- package/dist/Array-B4kuTQeW.mjs +2323 -0
- package/dist/Boolean-kILIvmhE.mjs +26 -0
- package/dist/ChildProcess-BCIwxPGc.mjs +577 -0
- package/dist/CliError-Cf5xqkkj.mjs +633 -0
- package/dist/Command-Dzq9KM-h.mjs +5135 -0
- package/dist/Config-B6OND9WR.mjs +854 -0
- package/dist/Console-BKHUkH6a.mjs +141 -0
- package/dist/Data-CeCULr0-.mjs +251 -0
- package/dist/Digest-CBd3uv5B.mjs +348 -0
- package/dist/Duration-EH9Vy4U6.mjs +791 -0
- package/dist/Effect-CKFpqbmw.mjs +12911 -0
- package/dist/FileSystem-4pPcEb_i.mjs +1366 -0
- package/dist/HttpClientError-BUeMWx70.mjs +303 -0
- package/dist/HttpClientResponse-D5ZKICVV.mjs +855 -0
- package/dist/Match-CGPLZYrV.mjs +434 -0
- package/dist/MutableHashMap-f8nW8AJR.mjs +376 -0
- package/dist/MutableHashSet-_HI572Ya.mjs +155 -0
- package/dist/MutableRef-D4Qv592C.mjs +107 -0
- package/dist/Number-BvkRkfc-.mjs +137 -0
- package/dist/Option-DkxSnBhp.mjs +3967 -0
- package/dist/Order-C1JC991I.mjs +481 -0
- package/dist/Path-Djdv_eF5.mjs +130 -0
- package/dist/Queue-CO5UQ6os.mjs +1394 -0
- package/dist/Redacted-RkJrG5Me.mjs +160 -0
- package/dist/Ref-BIPOxJNH.mjs +267 -0
- package/dist/Runtime-BInIAwK3.mjs +297 -0
- package/dist/Schema-MiKt5K1v.mjs +10999 -0
- package/dist/SecureRandom-B_U4ysO3.mjs +279 -0
- package/dist/Semaphore-DOVJ4ZGS.mjs +177 -0
- package/dist/Stdio-KylmOBX_.mjs +74 -0
- package/dist/Stream-bK9QIETN.mjs +4012 -0
- package/dist/String-q5dcsVe4.mjs +351 -0
- package/dist/TerminalCapabilities-w_44MAca.mjs +1769 -0
- package/dist/WebCrypto-ZI_GNVlw.mjs +33 -0
- package/dist/actor-call.service-CGM_vD9u.mjs +1269 -0
- package/dist/actor-client.adapter-Coem7gF1.mjs +3691 -0
- package/dist/akter-program.config-D8yb9xQP.mjs +7034 -0
- package/dist/akter.cli.mjs +5 -0
- package/dist/app-cli.config.mjs +49 -0
- package/dist/app-entry.pure.mjs +31 -0
- package/dist/archive/akter-archive.schema.mjs +65 -0
- package/dist/archive/akter-archive.service.mjs +309 -0
- package/dist/archive/archive-cli.config.mjs +45 -0
- package/dist/archive/archive-invalid.errors.mjs +5 -0
- package/dist/archive/archived-lineage.pure.mjs +13 -0
- package/dist/archive/tar.pure.mjs +291 -0
- package/dist/archive/zstd.adapter.mjs +46 -0
- package/dist/bench/bench-report.pure.mjs +120 -0
- package/dist/bench/bench-runner.pure.mjs +89 -0
- package/dist/bench/bench.service.mjs +301 -0
- package/dist/cli-runtime.layer-BqK2mmVL.mjs +1191 -0
- package/dist/cli-runtime.layer.mjs +1 -0
- package/dist/cloud-client.adapter-Cy1BjDbG.mjs +3186 -0
- package/dist/cloud-client.adapter-DOVMoYAj.mjs +304 -0
- package/dist/command/akter-commands.config.mjs +32 -0
- package/dist/command/akter-program.config.mjs +1 -0
- package/dist/credentials/credentials.service.mjs +226 -0
- package/dist/credentials/keychain.adapter.mjs +92 -0
- package/dist/credentials/login.config.mjs +251 -0
- package/dist/deploy/auth/api-attempt.service.mjs +30 -0
- package/dist/deploy/auth/token-refresh.errors.mjs +4 -0
- package/dist/deploy/build-bundle.adapter.mjs +133 -0
- package/dist/deploy/build-manifest.pure.mjs +44 -0
- package/dist/deploy/cloud-client.adapter.mjs +1 -0
- package/dist/deploy/cloud-url.pure.mjs +17 -0
- package/dist/deploy/deploy-failed.errors.mjs +17 -0
- package/dist/deploy/deploy.service.mjs +156 -0
- package/dist/deploy/request-failure.pure.mjs +87 -0
- package/dist/dev-runner.pure.mjs +30 -0
- package/dist/docs/doc-topics.pure.mjs +21 -0
- package/dist/docs/docs.config.mjs +1 -0
- package/dist/docs.config-D2amjsje.mjs +190 -0
- package/dist/docs.config-D3zzLzLR.mjs +190 -0
- package/dist/export/actor-export.service.mjs +267 -0
- package/dist/export/export-failed.errors.mjs +4 -0
- package/dist/export/export-failure.pure.mjs +18 -0
- package/dist/export/ordered-lines.pure.mjs +43 -0
- package/dist/export/ranged-download.pure.mjs +66 -0
- package/dist/export/snapshot-download.pure.mjs +86 -0
- package/dist/history-runner.pure.mjs +186 -0
- package/dist/history-since.pure.mjs +17 -0
- package/dist/hosted-runtime.layer-Cx3IPsEd.mjs +16358 -0
- package/dist/local/environment-cli.config.mjs +90 -0
- package/dist/local/environment-runner.pure.mjs +75 -0
- package/dist/local/local-cli.config.mjs +159 -0
- package/dist/logs/log-follow.config.mjs +21 -0
- package/dist/logs/log-follow.service.mjs +87 -0
- package/dist/logs/log-lines.pure.mjs +44 -0
- package/dist/migrate-runner.pure.mjs +28 -0
- package/dist/operation-input.pure-CS9iUhqK.mjs +1383 -0
- package/dist/operation-registry.pure-DVC8EDgj.mjs +283 -0
- package/dist/registry/actor-call.service.mjs +1 -0
- package/dist/registry/actor-commands.config.mjs +127 -0
- package/dist/registry/actor-refusal.pure.mjs +34 -0
- package/dist/registry/approval.service.mjs +80 -0
- package/dist/registry/cloud-commands.config.mjs +151 -0
- package/dist/registry/cloud-served.pure.mjs +31 -0
- package/dist/registry/operation-call.service.mjs +262 -0
- package/dist/registry/operation-input.pure.mjs +1 -0
- package/dist/registry/operation-output.pure.mjs +91 -0
- package/dist/registry/served-command.config.mjs +57 -0
- package/dist/runner-exited.errors.mjs +10 -0
- package/dist/terminal/cli-exit.errors.mjs +38 -0
- package/dist/terminal/cli-failure.pure.mjs +31 -0
- package/dist/terminal/confirm.adapter.mjs +27 -0
- package/package.json +61 -3
|
@@ -0,0 +1,1383 @@
|
|
|
1
|
+
import { L as reduce, T as join, j as map, l as filter, p as flatMap, w as isReadonlyArrayNonEmpty, y as head } from "./Array-B4kuTQeW.mjs";
|
|
2
|
+
import { W as fnUntraced, dt as map$1, ht as mapError, ln as try_ } from "./Effect-CKFpqbmw.mjs";
|
|
3
|
+
import { S as none, T as toArray, Tn as pipe, b as map$2, cn as isString, f as getOrElse, gt as assignProperty, h as isNone, i as filter$1, kt as formatPath, o as flatMap$1, w as some, x as match } from "./Option-DkxSnBhp.mjs";
|
|
4
|
+
import { $t as isUnique, Bt as isMaxProperties, Ct as isFinite, D as Null, Dn as transform, Dt as isGreaterThanOrEqualTo, E as NonEmptyString, En as passthroughSubtype, F as String$1, Fn as jsonSchemaAnnotationKeys, Ft as isLessThanOrEqualTo, Ht as isMinCodePoints, I as Struct, Jt as isPropertyNames, Kt as isMultipleOf, L as StructWithRest, M as Record, Mt as isLessThan, Pn as annotationExcludedKeys, R as Symbol, Rt as isMaxCodePoints, S as Literals, T as NonEmptyArray, U as Tuple, Ut as isMinLength, W as TupleWithRest, Wt as isMinProperties, X as Unknown, Y as Union, a as Boolean, an as optionalKey, b as JsonObject, ct as encodeOption, g as Finite, in as optional, jt as isInt, k as Number, kn as transformOptional, n as ArraySchema, on as suspend, or as fromEntries, ot as decodeUnknownOption, pr as remove, pt as fromJsonString, qt as isPattern, r as BigInt, rn as makeFilterGroup, sn as tag, sr as get, tn as make, tt as decodeEffect, ut as encodeTo, w as Never, wt as isGreaterThan, x as Literal, y as Json, yn as isJson, z as TaggedError, zt as isMaxLength } from "./Schema-MiKt5K1v.mjs";
|
|
5
|
+
import { d as replace } from "./String-q5dcsVe4.mjs";
|
|
6
|
+
import { CliExitError } from "./terminal/cli-exit.errors.mjs";
|
|
7
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/internal/jsonSchema.js
|
|
8
|
+
/** @internal */
|
|
9
|
+
function getSubschemaKind(keyword) {
|
|
10
|
+
switch (keyword) {
|
|
11
|
+
case "$defs":
|
|
12
|
+
case "properties":
|
|
13
|
+
case "patternProperties":
|
|
14
|
+
case "dependentSchemas": return "map";
|
|
15
|
+
case "allOf":
|
|
16
|
+
case "anyOf":
|
|
17
|
+
case "oneOf":
|
|
18
|
+
case "prefixItems": return "array";
|
|
19
|
+
case "not":
|
|
20
|
+
case "additionalProperties":
|
|
21
|
+
case "propertyNames":
|
|
22
|
+
case "unevaluatedProperties":
|
|
23
|
+
case "items":
|
|
24
|
+
case "contains":
|
|
25
|
+
case "unevaluatedItems":
|
|
26
|
+
case "if":
|
|
27
|
+
case "then":
|
|
28
|
+
case "else":
|
|
29
|
+
case "contentSchema": return "schema";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/JsonPointer.js
|
|
33
|
+
/**
|
|
34
|
+
* Helpers for escaping JSON Pointer path segments and converting JSON Pointer
|
|
35
|
+
* URI fragments. JSON Pointer uses `/` to separate path tokens inside a JSON
|
|
36
|
+
* document, so token text must encode literal `~` and `/` characters. URI
|
|
37
|
+
* fragments additionally apply percent-encoding after JSON Pointer escaping.
|
|
38
|
+
*
|
|
39
|
+
* @stability stable
|
|
40
|
+
* @since 4.0.0
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Escapes a JSON Pointer reference token according to RFC 6901 by encoding special characters so the token can be safely used as a segment in a JSON Pointer.
|
|
44
|
+
*
|
|
45
|
+
* **When to use**
|
|
46
|
+
*
|
|
47
|
+
* Use when you need to escape a single JSON Pointer path segment.
|
|
48
|
+
*
|
|
49
|
+
* **Details**
|
|
50
|
+
*
|
|
51
|
+
* - Returns a new escaped string
|
|
52
|
+
* - Replaces `~` (tilde) with `~0` and `/` (forward slash) with `~1`
|
|
53
|
+
* - Returns the input unchanged if it contains no special characters
|
|
54
|
+
* - Empty strings are valid and returned unchanged
|
|
55
|
+
*
|
|
56
|
+
* **Gotchas**
|
|
57
|
+
*
|
|
58
|
+
* The replacement order matters: `~` is replaced before `/` to prevent double-escaping.
|
|
59
|
+
*
|
|
60
|
+
* **Example** (Escaping special characters)
|
|
61
|
+
*
|
|
62
|
+
* ```ts import.meta.vitest
|
|
63
|
+
* import { JsonPointer } from "effect"
|
|
64
|
+
*
|
|
65
|
+
* JsonPointer.escapeToken("a/b") // => "a~1b"
|
|
66
|
+
* JsonPointer.escapeToken("c~d") // => "c~0d"
|
|
67
|
+
* JsonPointer.escapeToken("path/to~key") // => "path~1to~0key"
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @see {@link unescapeToken} The inverse operation for decoding escaped tokens
|
|
71
|
+
* @stability stable
|
|
72
|
+
* @category encoding
|
|
73
|
+
* @since 4.0.0
|
|
74
|
+
*/
|
|
75
|
+
function escapeToken(token) {
|
|
76
|
+
return token.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Decodes a JSON Pointer reference token according to RFC 6901 escaping rules.
|
|
80
|
+
*
|
|
81
|
+
* **When to use**
|
|
82
|
+
*
|
|
83
|
+
* Use when you need to decode a single escaped JSON Pointer path segment.
|
|
84
|
+
*
|
|
85
|
+
* **Details**
|
|
86
|
+
*
|
|
87
|
+
* - Returns a new unescaped string
|
|
88
|
+
* - Replaces `~1` with `/` (forward slash) and `~0` with `~` (tilde)
|
|
89
|
+
* - Returns the input unchanged if it contains no escaped sequences
|
|
90
|
+
* - Empty strings are valid and returned unchanged
|
|
91
|
+
*
|
|
92
|
+
* **Gotchas**
|
|
93
|
+
*
|
|
94
|
+
* The replacement order matters: `~1` is replaced before `~0` to prevent incorrect decoding.
|
|
95
|
+
*
|
|
96
|
+
* **Example** (Unescaping special characters)
|
|
97
|
+
*
|
|
98
|
+
* ```ts import.meta.vitest
|
|
99
|
+
* import { JsonPointer } from "effect"
|
|
100
|
+
*
|
|
101
|
+
* JsonPointer.unescapeToken("a~1b") // => "a/b"
|
|
102
|
+
* JsonPointer.unescapeToken("c~0d") // => "c~d"
|
|
103
|
+
* JsonPointer.unescapeToken("path~1to~0key") // => "path/to~key"
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @see {@link escapeToken} The inverse operation for encoding tokens
|
|
107
|
+
* @stability stable
|
|
108
|
+
* @category decoding
|
|
109
|
+
* @since 4.0.0
|
|
110
|
+
*/
|
|
111
|
+
function unescapeToken(token) {
|
|
112
|
+
return token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
113
|
+
}
|
|
114
|
+
/** @internal */
|
|
115
|
+
function decodeUriFragment(fragment) {
|
|
116
|
+
if (fragment.length === 0 || fragment === "#") return "";
|
|
117
|
+
if (!fragment.startsWith("#")) return void 0;
|
|
118
|
+
const encoded = fragment.slice(1);
|
|
119
|
+
try {
|
|
120
|
+
if (encodeURI(encoded).replace(/%25/g, "%").replace(/#/g, "%23") !== encoded) return void 0;
|
|
121
|
+
const pointer = decodeURIComponent(encoded);
|
|
122
|
+
return pointer.startsWith("/") && !/~(?:[^01]|$)/.test(pointer) ? pointer : void 0;
|
|
123
|
+
} catch {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Parses a JSON Pointer URI fragment into decoded path tokens.
|
|
129
|
+
*
|
|
130
|
+
* **When to use**
|
|
131
|
+
*
|
|
132
|
+
* Use when you need to resolve a URI fragment against a JSON document.
|
|
133
|
+
*
|
|
134
|
+
* **Details**
|
|
135
|
+
*
|
|
136
|
+
* Percent-encoding is decoded before the pointer is split into tokens, then
|
|
137
|
+
* each token is decoded with {@link unescapeToken}. The empty string and `#`
|
|
138
|
+
* both represent the document root.
|
|
139
|
+
*
|
|
140
|
+
* **Gotchas**
|
|
141
|
+
*
|
|
142
|
+
* Returns `undefined` when the input is not a URI fragment, contains characters
|
|
143
|
+
* that require percent-encoding, or contains an invalid JSON Pointer escape
|
|
144
|
+
* sequence.
|
|
145
|
+
*
|
|
146
|
+
* **Example** (Parsing URI fragments)
|
|
147
|
+
*
|
|
148
|
+
* ```ts import.meta.vitest
|
|
149
|
+
* import { JsonPointer } from "effect"
|
|
150
|
+
*
|
|
151
|
+
* JsonPointer.parseUriFragment("#/users/a~1b") // => ["users", "a/b"]
|
|
152
|
+
* JsonPointer.parseUriFragment("#/caf%C3%A9") // => ["café"]
|
|
153
|
+
* JsonPointer.parseUriFragment("#/%") // => undefined
|
|
154
|
+
* JsonPointer.parseUriFragment("#/a#b") // => undefined
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @see {@link formatUriFragment} for the inverse operation
|
|
158
|
+
* @stability stable
|
|
159
|
+
* @category decoding
|
|
160
|
+
* @since 4.0.0
|
|
161
|
+
*/
|
|
162
|
+
function parseUriFragment(fragment) {
|
|
163
|
+
const pointer = decodeUriFragment(fragment);
|
|
164
|
+
return pointer === void 0 ? void 0 : pointer.length === 0 ? [] : pointer.slice(1).split("/").map(unescapeToken);
|
|
165
|
+
}
|
|
166
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/JsonSchema.js
|
|
167
|
+
/** @internal */
|
|
168
|
+
function getReferenceKey($ref) {
|
|
169
|
+
const path = $ref.startsWith("#") ? parseUriFragment($ref) : void 0;
|
|
170
|
+
return path !== void 0 && path.length === 2 && path[0] === "$defs" ? path[1] : void 0;
|
|
171
|
+
}
|
|
172
|
+
const PRE_2020_TO_2020_COLLISIONS = [
|
|
173
|
+
"$anchor",
|
|
174
|
+
"$defs",
|
|
175
|
+
"$dynamicAnchor",
|
|
176
|
+
"$dynamicRef",
|
|
177
|
+
"$vocabulary",
|
|
178
|
+
"contentSchema",
|
|
179
|
+
"dependentRequired",
|
|
180
|
+
"dependentSchemas",
|
|
181
|
+
"maxContains",
|
|
182
|
+
"minContains",
|
|
183
|
+
"prefixItems",
|
|
184
|
+
"unevaluatedItems",
|
|
185
|
+
"unevaluatedProperties"
|
|
186
|
+
];
|
|
187
|
+
[...PRE_2020_TO_2020_COLLISIONS];
|
|
188
|
+
[...PRE_2020_TO_2020_COLLISIONS];
|
|
189
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/internal/errors.js
|
|
190
|
+
/** @internal */
|
|
191
|
+
function errorWithPath(message, path) {
|
|
192
|
+
if (path.length > 0) message += `\n at ${formatPath(path)}`;
|
|
193
|
+
return new Error(message);
|
|
194
|
+
}
|
|
195
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/internal/schema/fromRepresentation.js
|
|
196
|
+
/** @internal */
|
|
197
|
+
var ReferenceSlot = class {
|
|
198
|
+
body;
|
|
199
|
+
resolving = false;
|
|
200
|
+
wrapper;
|
|
201
|
+
constructor(key) {
|
|
202
|
+
this.wrapper = suspend(() => {
|
|
203
|
+
if (this.body === void 0) throw new Error(`Reference ${key} was evaluated before it was resolved`);
|
|
204
|
+
return this.body;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
// ../../node_modules/.pnpm/effect@4.1.2_patch_hash=0e61176203bb1256381ce1c5b488d7951983ce38ff698647d3f4617383abbf07/node_modules/effect/dist/internal/schema/fromJsonSchemaDocument.js
|
|
209
|
+
const never = {
|
|
210
|
+
_tag: "Never",
|
|
211
|
+
checks: []
|
|
212
|
+
};
|
|
213
|
+
const unknown = {
|
|
214
|
+
_tag: "Unknown",
|
|
215
|
+
checks: []
|
|
216
|
+
};
|
|
217
|
+
const string = {
|
|
218
|
+
_tag: "String",
|
|
219
|
+
checks: []
|
|
220
|
+
};
|
|
221
|
+
const primitiveSchemas = {
|
|
222
|
+
Never,
|
|
223
|
+
Null,
|
|
224
|
+
String: String$1,
|
|
225
|
+
Number,
|
|
226
|
+
Boolean
|
|
227
|
+
};
|
|
228
|
+
const unsupportedStructuredValue = "Only primitive values are supported in \"const\" and \"enum\".";
|
|
229
|
+
const jsonSchemaPatternFlags = "u";
|
|
230
|
+
function isObject(input) {
|
|
231
|
+
return typeof input === "object" && input !== null && !Array.isArray(input);
|
|
232
|
+
}
|
|
233
|
+
function makeJsonLiteral(input, path) {
|
|
234
|
+
if (input === null) return {
|
|
235
|
+
_tag: "Null",
|
|
236
|
+
checks: []
|
|
237
|
+
};
|
|
238
|
+
if (typeof input === "string" || typeof input === "number" || typeof input === "boolean") return {
|
|
239
|
+
_tag: "Literal",
|
|
240
|
+
literal: input,
|
|
241
|
+
checks: []
|
|
242
|
+
};
|
|
243
|
+
if (typeof input === "object") throw errorWithPath(unsupportedStructuredValue, path);
|
|
244
|
+
}
|
|
245
|
+
const jsonSchemaValueTypes = [
|
|
246
|
+
"null",
|
|
247
|
+
"string",
|
|
248
|
+
"number",
|
|
249
|
+
"boolean",
|
|
250
|
+
"object",
|
|
251
|
+
"array"
|
|
252
|
+
];
|
|
253
|
+
const jsonSchemaTypeSpecificKeys = [
|
|
254
|
+
"minLength",
|
|
255
|
+
"maxLength",
|
|
256
|
+
"pattern",
|
|
257
|
+
"minimum",
|
|
258
|
+
"maximum",
|
|
259
|
+
"exclusiveMinimum",
|
|
260
|
+
"exclusiveMaximum",
|
|
261
|
+
"multipleOf",
|
|
262
|
+
"properties",
|
|
263
|
+
"required",
|
|
264
|
+
"additionalProperties",
|
|
265
|
+
"patternProperties",
|
|
266
|
+
"propertyNames",
|
|
267
|
+
"minProperties",
|
|
268
|
+
"maxProperties",
|
|
269
|
+
"items",
|
|
270
|
+
"prefixItems",
|
|
271
|
+
"minItems",
|
|
272
|
+
"maxItems",
|
|
273
|
+
"uniqueItems"
|
|
274
|
+
];
|
|
275
|
+
const jsonSchemaAnnotationExcludedKeys = /*#__PURE__*/ new Set([
|
|
276
|
+
...jsonSchemaTypeSpecificKeys,
|
|
277
|
+
...jsonSchemaAnnotationKeys,
|
|
278
|
+
...annotationExcludedKeys,
|
|
279
|
+
"$schema",
|
|
280
|
+
"$id",
|
|
281
|
+
"$ref",
|
|
282
|
+
"$defs",
|
|
283
|
+
"$anchor",
|
|
284
|
+
"$dynamicRef",
|
|
285
|
+
"$dynamicAnchor",
|
|
286
|
+
"$vocabulary",
|
|
287
|
+
"$comment",
|
|
288
|
+
"type",
|
|
289
|
+
"const",
|
|
290
|
+
"enum",
|
|
291
|
+
"allOf",
|
|
292
|
+
"anyOf",
|
|
293
|
+
"oneOf",
|
|
294
|
+
"not",
|
|
295
|
+
"if",
|
|
296
|
+
"then",
|
|
297
|
+
"else",
|
|
298
|
+
"contains",
|
|
299
|
+
"minContains",
|
|
300
|
+
"maxContains",
|
|
301
|
+
"dependentRequired",
|
|
302
|
+
"dependentSchemas",
|
|
303
|
+
"unevaluatedItems",
|
|
304
|
+
"unevaluatedProperties",
|
|
305
|
+
"definitions",
|
|
306
|
+
"dependencies",
|
|
307
|
+
"additionalItems",
|
|
308
|
+
"identifier",
|
|
309
|
+
"expected",
|
|
310
|
+
"message",
|
|
311
|
+
"messageMissingKey",
|
|
312
|
+
"messageUnexpectedKey"
|
|
313
|
+
]);
|
|
314
|
+
function isImportedJsonSchemaType(input) {
|
|
315
|
+
return input === "integer" || typeof input === "string" && jsonSchemaValueTypes.some((type) => type === input);
|
|
316
|
+
}
|
|
317
|
+
function hasTypeSpecificKeywords(schema) {
|
|
318
|
+
return jsonSchemaTypeSpecificKeys.some((key) => schema[key] !== void 0);
|
|
319
|
+
}
|
|
320
|
+
function makeFilter(filter) {
|
|
321
|
+
return {
|
|
322
|
+
_tag: "Filter",
|
|
323
|
+
filter
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function addNumberCheck(checks, value, make) {
|
|
327
|
+
if (typeof value === "number") checks.push(makeFilter(make(value)));
|
|
328
|
+
}
|
|
329
|
+
function jsonSchemaAnnotations(schema, options) {
|
|
330
|
+
const annotations = {};
|
|
331
|
+
if (typeof schema.title === "string") annotations.title = schema.title;
|
|
332
|
+
if (typeof schema.description === "string") annotations.description = schema.description;
|
|
333
|
+
if (Object.hasOwn(schema, "default")) annotations.default = schema.default;
|
|
334
|
+
if (Array.isArray(schema.examples)) annotations.examples = schema.examples;
|
|
335
|
+
if (typeof schema.readOnly === "boolean") annotations.readOnly = schema.readOnly;
|
|
336
|
+
if (typeof schema.writeOnly === "boolean") annotations.writeOnly = schema.writeOnly;
|
|
337
|
+
if (typeof schema.format === "string") annotations.format = schema.format;
|
|
338
|
+
if (typeof schema.contentEncoding === "string") annotations.contentEncoding = schema.contentEncoding;
|
|
339
|
+
if (typeof schema.contentMediaType === "string") annotations.contentMediaType = schema.contentMediaType;
|
|
340
|
+
if (isJson(schema.contentSchema)) annotations.contentSchema = schema.contentSchema;
|
|
341
|
+
let customAnnotations;
|
|
342
|
+
if (options?.includeAnnotationKey !== void 0) for (const key of Object.keys(schema)) {
|
|
343
|
+
if (key.startsWith("~") || jsonSchemaAnnotationExcludedKeys.has(key) || !options.includeAnnotationKey(key)) continue;
|
|
344
|
+
const value = schema[key];
|
|
345
|
+
if (isJson(value)) assignProperty(customAnnotations ??= {}, key, value);
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
annotations: Object.keys(annotations).length === 0 ? void 0 : annotations,
|
|
349
|
+
customAnnotations
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
/** @internal */
|
|
353
|
+
function fromJsonSchemaMultiDocument(document, options, singleRoot = false) {
|
|
354
|
+
const definitionCache = /* @__PURE__ */ new Map();
|
|
355
|
+
const validatedAliases = /* @__PURE__ */ new Set();
|
|
356
|
+
const resolvingChoices = /* @__PURE__ */ new Set();
|
|
357
|
+
const references = /* @__PURE__ */ new Map();
|
|
358
|
+
let inNestedResource = false;
|
|
359
|
+
function finalize(input) {
|
|
360
|
+
const annotations = mergeAnnotations(input.annotations, input.customAnnotations);
|
|
361
|
+
if (input._tag === "Reference") {
|
|
362
|
+
if (annotations !== void 0) resolveReference(input, input.path);
|
|
363
|
+
let slot = references.get(input.$ref);
|
|
364
|
+
if (slot === void 0) {
|
|
365
|
+
slot = new ReferenceSlot(input.$ref);
|
|
366
|
+
references.set(input.$ref, slot);
|
|
367
|
+
slot.body = finalize(translateDefinition(input.$ref, input.path)).annotate({ identifier: input.$ref });
|
|
368
|
+
}
|
|
369
|
+
return annotations === void 0 ? slot.body ?? slot.wrapper : slot.wrapper.annotate(annotations);
|
|
370
|
+
}
|
|
371
|
+
let schema;
|
|
372
|
+
switch (input._tag) {
|
|
373
|
+
case "Unknown": return Json.annotate({
|
|
374
|
+
...annotations,
|
|
375
|
+
expected: "JSON value"
|
|
376
|
+
});
|
|
377
|
+
case "Never":
|
|
378
|
+
case "Null":
|
|
379
|
+
case "String":
|
|
380
|
+
case "Number":
|
|
381
|
+
case "Boolean":
|
|
382
|
+
schema = primitiveSchemas[input._tag];
|
|
383
|
+
break;
|
|
384
|
+
case "Literal":
|
|
385
|
+
schema = Literal(input.literal);
|
|
386
|
+
break;
|
|
387
|
+
case "Arrays": {
|
|
388
|
+
const elements = input.elements.map((element) => {
|
|
389
|
+
const type = finalize(element.type);
|
|
390
|
+
return element.isOptional ? optionalKey(type) : type;
|
|
391
|
+
});
|
|
392
|
+
const rest = input.rest[0] === void 0 ? void 0 : finalize(input.rest[0]);
|
|
393
|
+
schema = rest !== void 0 ? elements.length === 0 ? ArraySchema(rest) : TupleWithRest(Tuple(elements), [rest]) : Tuple(elements);
|
|
394
|
+
break;
|
|
395
|
+
}
|
|
396
|
+
case "Objects": {
|
|
397
|
+
if (input.indexSignatures[0]?.parameter === string && input.scopes.some((scope) => scope.patterns.length > 0)) throw errorWithPath("Cannot import open \"patternProperties\": unmatched keys cannot be typed correctly.", input.path);
|
|
398
|
+
const fields = {};
|
|
399
|
+
for (const property of input.propertySignatures) {
|
|
400
|
+
const type = finalize(property.type);
|
|
401
|
+
assignProperty(fields, property.name, property.isOptional ? optionalKey(type) : type);
|
|
402
|
+
}
|
|
403
|
+
const index = input.indexSignatures[0];
|
|
404
|
+
const record = index === void 0 ? void 0 : Record(finalize(index.parameter), finalize(index.type));
|
|
405
|
+
schema = record !== void 0 ? input.propertySignatures.length === 0 ? record : StructWithRest(Struct(fields), [record]) : Struct(fields);
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
case "Union": schema = Union(input.types.map(finalize), input.options);
|
|
409
|
+
}
|
|
410
|
+
if (annotations !== void 0) schema = schema.annotate(annotations);
|
|
411
|
+
const checks = input.checks.map(finalizeCheck);
|
|
412
|
+
return checks.length > 0 ? schema.check(...checks) : schema;
|
|
413
|
+
}
|
|
414
|
+
function finalizeCheck(check) {
|
|
415
|
+
if (check._tag === "FilterGroup") return makeFilterGroup(check.checks.map(finalizeCheck), check.annotations);
|
|
416
|
+
const filter = check._tag === "PropertyNames" ? isPropertyNames(finalize(check.type)) : check.filter;
|
|
417
|
+
return check.annotations === void 0 ? filter : filter.annotate(check.annotations);
|
|
418
|
+
}
|
|
419
|
+
function annotate(representation, source) {
|
|
420
|
+
if (source.annotations === void 0 && source.customAnnotations === void 0) return representation;
|
|
421
|
+
return {
|
|
422
|
+
...representation,
|
|
423
|
+
annotations: mergeAnnotations(representation.annotations, source.annotations),
|
|
424
|
+
customAnnotations: mergeAnnotations(representation.customAnnotations, source.customAnnotations)
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function translateDefinition(key, path, recursiveReferenceError) {
|
|
428
|
+
const cached = definitionCache.get(key);
|
|
429
|
+
if (cached !== void 0) {
|
|
430
|
+
if (cached === null) throw errorWithPath(recursiveReferenceError ?? `Definition ${JSON.stringify(key)} is a circular alias.`, [...path, "$ref"]);
|
|
431
|
+
return cached;
|
|
432
|
+
}
|
|
433
|
+
definitionCache.set(key, null);
|
|
434
|
+
const pointer = pointers.get(key);
|
|
435
|
+
const wasInNestedResource = inNestedResource;
|
|
436
|
+
if (pointer !== void 0) inNestedResource = pointer.crossesResource;
|
|
437
|
+
const representation = pointer === void 0 ? translateSchema(document.definitions[key], ["definitions", key]) : translateSchema(pointer.target, ["definitions", ...pointer.tokens]);
|
|
438
|
+
inNestedResource = wasInNestedResource;
|
|
439
|
+
definitionCache.set(key, representation);
|
|
440
|
+
if (pointer !== void 0) validatePointerAliases(representation, path, recursiveReferenceError);
|
|
441
|
+
return representation;
|
|
442
|
+
}
|
|
443
|
+
function validatePointerAliases(representation, path, recursiveReferenceError, visiting = /* @__PURE__ */ new Set()) {
|
|
444
|
+
if (representation._tag === "Reference") {
|
|
445
|
+
const key = representation.$ref;
|
|
446
|
+
if (validatedAliases.has(key)) return;
|
|
447
|
+
if (visiting.has(key)) throw errorWithPath(`Definition ${JSON.stringify(key)} is a circular alias.`, [...path, "$ref"]);
|
|
448
|
+
visiting.add(key);
|
|
449
|
+
validatePointerAliases(translateDefinition(key, path, recursiveReferenceError), path, recursiveReferenceError, visiting);
|
|
450
|
+
visiting.delete(key);
|
|
451
|
+
validatedAliases.add(key);
|
|
452
|
+
} else if (representation._tag === "Union") for (const type of representation.types) validatePointerAliases(type, path, recursiveReferenceError, visiting);
|
|
453
|
+
}
|
|
454
|
+
function resolveReference(reference, path, recursiveReferenceError, seen = /* @__PURE__ */ new Set()) {
|
|
455
|
+
if (seen.has(reference.$ref)) throw errorWithPath(`Definition ${JSON.stringify(reference.$ref)} is a circular alias.`, [...path, "$ref"]);
|
|
456
|
+
seen.add(reference.$ref);
|
|
457
|
+
const representation = translateDefinition(reference.$ref, path, recursiveReferenceError);
|
|
458
|
+
if (representation._tag === "Reference") return annotate(resolveReference(representation, path, recursiveReferenceError, seen), representation);
|
|
459
|
+
return representation;
|
|
460
|
+
}
|
|
461
|
+
const pointers = /* @__PURE__ */ new Map();
|
|
462
|
+
function resolvePointer($ref, path) {
|
|
463
|
+
const pointer = $ref.startsWith("#") ? parseUriFragment($ref) : void 0;
|
|
464
|
+
if (pointer === void 0 || pointer.length < 3 || pointer[0] !== "$defs") throw errorWithPath(`Unsupported $ref ${JSON.stringify($ref)}. Use "#/$defs/Name".`, [...path, "$ref"]);
|
|
465
|
+
const tokens = pointer.slice(1);
|
|
466
|
+
const key = tokens.map(escapeToken).join("/");
|
|
467
|
+
if (Object.hasOwn(document.definitions, key)) throw errorWithPath(`Pointer $ref ${JSON.stringify($ref)} conflicts with definition ${JSON.stringify(key)}.`, [...path, "$ref"]);
|
|
468
|
+
if (pointers.has(key)) return key;
|
|
469
|
+
let node = document.definitions;
|
|
470
|
+
let position = "container";
|
|
471
|
+
let crossesResource = false;
|
|
472
|
+
for (const token of tokens) {
|
|
473
|
+
if (position === "container") position = "schema";
|
|
474
|
+
else if (position === "schema" && isObject(node)) {
|
|
475
|
+
if (options?.onEnter !== void 0) node = options.onEnter(node);
|
|
476
|
+
crossesResource ||= isObject(node) && typeof node.$id === "string";
|
|
477
|
+
const kind = getSubschemaKind(token);
|
|
478
|
+
position = kind === "schema" ? "schema" : kind === void 0 ? "value" : "container";
|
|
479
|
+
} else position = "value";
|
|
480
|
+
node = typeof node === "object" && node !== null && Object.hasOwn(node, token) ? node[token] : void 0;
|
|
481
|
+
}
|
|
482
|
+
if (!isObject(node) && typeof node !== "boolean") throw errorWithPath(`Unresolvable $ref ${JSON.stringify($ref)}. Nothing exists at that location.`, [...path, "$ref"]);
|
|
483
|
+
pointers.set(key, {
|
|
484
|
+
target: node,
|
|
485
|
+
tokens,
|
|
486
|
+
crossesResource
|
|
487
|
+
});
|
|
488
|
+
return key;
|
|
489
|
+
}
|
|
490
|
+
function mergeAnnotations(left, right) {
|
|
491
|
+
if (left === void 0) return right;
|
|
492
|
+
if (right === void 0) return left;
|
|
493
|
+
return {
|
|
494
|
+
...left,
|
|
495
|
+
...right
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function annotateIntersection(representation, left, right) {
|
|
499
|
+
return annotate(annotate(representation, left), right);
|
|
500
|
+
}
|
|
501
|
+
function intersectChecks(left, right, deduplicate = []) {
|
|
502
|
+
let checks = right.checks;
|
|
503
|
+
for (const id of deduplicate) if (left.checks.some((check) => check._tag === "Filter" && check.filter.annotations?.representation?.id === id)) checks = checks.filter((check) => check._tag !== "Filter" || check.filter.annotations?.representation?.id !== id);
|
|
504
|
+
const annotations = checks.length === 0 ? mergeAnnotations(left.annotations, right.annotations) : left.annotations;
|
|
505
|
+
if (checks.length > 0 && right.annotations !== void 0) checks = checks.length === 1 && checks[0].annotations === void 0 ? [{
|
|
506
|
+
...checks[0],
|
|
507
|
+
annotations: right.annotations
|
|
508
|
+
}] : [{
|
|
509
|
+
_tag: "FilterGroup",
|
|
510
|
+
checks,
|
|
511
|
+
annotations: right.annotations
|
|
512
|
+
}];
|
|
513
|
+
return {
|
|
514
|
+
checks: [...left.checks, ...checks],
|
|
515
|
+
annotations,
|
|
516
|
+
customAnnotations: mergeAnnotations(left.customAnnotations, right.customAnnotations)
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function satisfiesPrimitiveCheck(check, value) {
|
|
520
|
+
if (check._tag === "FilterGroup") return check.checks.every((check) => satisfiesPrimitiveCheck(check, value));
|
|
521
|
+
return check._tag === "Filter" && check.filter.run(value, Unknown.ast, {}) === void 0;
|
|
522
|
+
}
|
|
523
|
+
function satisfiesLiteral(representation, literal) {
|
|
524
|
+
const value = literal.literal;
|
|
525
|
+
if (representation._tag === "String" ? typeof value !== "string" : typeof value !== "number") return false;
|
|
526
|
+
return representation.checks.every((check) => satisfiesPrimitiveCheck(check, value));
|
|
527
|
+
}
|
|
528
|
+
function intersectPrimitiveWithLiteral(primitive, literal) {
|
|
529
|
+
return (primitive._tag === "Boolean" ? typeof literal.literal === "boolean" : satisfiesLiteral(primitive, literal)) ? annotateIntersection(literal, primitive, literal) : never;
|
|
530
|
+
}
|
|
531
|
+
function intersectArrays(left, right, path) {
|
|
532
|
+
const elements = [];
|
|
533
|
+
const length = Math.max(left.elements.length, right.elements.length);
|
|
534
|
+
for (let index = 0; index < length; index++) {
|
|
535
|
+
const leftElement = left.elements[index];
|
|
536
|
+
const rightElement = right.elements[index];
|
|
537
|
+
const isOptional = leftElement?.isOptional !== false && rightElement?.isOptional !== false;
|
|
538
|
+
const leftType = leftElement?.type ?? left.rest[0];
|
|
539
|
+
const rightType = rightElement?.type ?? right.rest[0];
|
|
540
|
+
if (leftType === void 0 || rightType === void 0) return isOptional ? {
|
|
541
|
+
elements,
|
|
542
|
+
rest: []
|
|
543
|
+
} : void 0;
|
|
544
|
+
const type = intersect(leftType, rightType, [
|
|
545
|
+
...path,
|
|
546
|
+
"elements",
|
|
547
|
+
index,
|
|
548
|
+
"type"
|
|
549
|
+
]);
|
|
550
|
+
if (type._tag === "Never") return isOptional ? {
|
|
551
|
+
elements,
|
|
552
|
+
rest: []
|
|
553
|
+
} : void 0;
|
|
554
|
+
elements.push({
|
|
555
|
+
isOptional,
|
|
556
|
+
type
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
const leftRest = left.rest[0];
|
|
560
|
+
const rightRest = right.rest[0];
|
|
561
|
+
if (leftRest === void 0 || rightRest === void 0) return {
|
|
562
|
+
elements,
|
|
563
|
+
rest: []
|
|
564
|
+
};
|
|
565
|
+
const rest = intersect(leftRest, rightRest, [
|
|
566
|
+
...path,
|
|
567
|
+
"rest",
|
|
568
|
+
0
|
|
569
|
+
]);
|
|
570
|
+
return {
|
|
571
|
+
elements,
|
|
572
|
+
rest: rest._tag === "Never" ? [] : [rest]
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
function intersectAll(types, path) {
|
|
576
|
+
let out = types[0] ?? unknown;
|
|
577
|
+
for (let index = 1; index < types.length; index++) out = intersect(out, types[index], [...path, index]);
|
|
578
|
+
return out;
|
|
579
|
+
}
|
|
580
|
+
function lowerObject(scopes, checked, path) {
|
|
581
|
+
const names = /* @__PURE__ */ new Set();
|
|
582
|
+
let hasFiniteKeyDomain = false;
|
|
583
|
+
let requiresFiniteKeyDomain = false;
|
|
584
|
+
for (const scope of scopes) {
|
|
585
|
+
for (const name of scope.properties.keys()) names.add(name);
|
|
586
|
+
hasFiniteKeyDomain ||= scope.additionalProperties._tag === "Never" && scope.patterns.length === 0;
|
|
587
|
+
requiresFiniteKeyDomain ||= scope.additionalProperties._tag === "Never" || scope.additionalProperties._tag !== "Unknown" && (scope.hasProperties || scope.patterns.length > 0);
|
|
588
|
+
}
|
|
589
|
+
const closedPattern = scopes.length === 1 && names.size === 0 && scopes[0].additionalProperties._tag === "Never" && scopes[0].patterns.length === 1 ? scopes[0].patterns[0] : void 0;
|
|
590
|
+
if (!hasFiniteKeyDomain && requiresFiniteKeyDomain && closedPattern === void 0) throw errorWithPath(scopes.some((scope) => scope.additionalProperties._tag === "Never") ? "Cannot import this closed patterned object: only one pattern without properties is supported." : "Cannot combine typed \"additionalProperties\" with other property schemas: Effect index signatures also check excluded keys.", path);
|
|
591
|
+
const properties = [];
|
|
592
|
+
for (const name of names) {
|
|
593
|
+
let isOptional = true;
|
|
594
|
+
const types = [];
|
|
595
|
+
for (const scope of scopes) {
|
|
596
|
+
const property = scope.properties.get(name);
|
|
597
|
+
if (property !== void 0) {
|
|
598
|
+
if (!property.isOptional) isOptional = false;
|
|
599
|
+
if (property.type !== void 0) types.push(property.type);
|
|
600
|
+
}
|
|
601
|
+
let matches = false;
|
|
602
|
+
for (const pattern of scope.patterns) if (globalThis.RegExp(pattern.source, jsonSchemaPatternFlags).test(name)) {
|
|
603
|
+
types.push(pattern.type);
|
|
604
|
+
matches = true;
|
|
605
|
+
}
|
|
606
|
+
if (property?.type === void 0 && !matches) types.push(scope.additionalProperties);
|
|
607
|
+
}
|
|
608
|
+
const type = intersectAll(types, [
|
|
609
|
+
...path,
|
|
610
|
+
"properties",
|
|
611
|
+
name
|
|
612
|
+
]);
|
|
613
|
+
if (!isOptional && type._tag === "Never") return never;
|
|
614
|
+
properties.push({
|
|
615
|
+
name,
|
|
616
|
+
type,
|
|
617
|
+
isOptional
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
return {
|
|
621
|
+
_tag: "Objects",
|
|
622
|
+
propertySignatures: properties,
|
|
623
|
+
indexSignatures: closedPattern !== void 0 ? [{
|
|
624
|
+
parameter: closedPattern.parameter,
|
|
625
|
+
type: closedPattern.type
|
|
626
|
+
}] : !hasFiniteKeyDomain ? [{
|
|
627
|
+
parameter: string,
|
|
628
|
+
type: intersectAll(scopes.map((scope) => scope.additionalProperties), [...path, "additionalProperties"])
|
|
629
|
+
}] : properties.length === 0 ? [{
|
|
630
|
+
parameter: string,
|
|
631
|
+
type: never
|
|
632
|
+
}] : [],
|
|
633
|
+
scopes,
|
|
634
|
+
path,
|
|
635
|
+
...checked
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
const jsonRootTags = [
|
|
639
|
+
"Null",
|
|
640
|
+
"String",
|
|
641
|
+
"Number",
|
|
642
|
+
"Boolean",
|
|
643
|
+
"Objects",
|
|
644
|
+
"Arrays"
|
|
645
|
+
];
|
|
646
|
+
const allMasks = (1 << jsonRootTags.length) - 1;
|
|
647
|
+
function rootMask(representation) {
|
|
648
|
+
switch (representation._tag) {
|
|
649
|
+
case "Never": return 0;
|
|
650
|
+
case "Unknown":
|
|
651
|
+
case "Reference": return allMasks;
|
|
652
|
+
case "Literal": switch (typeof representation.literal) {
|
|
653
|
+
case "string": return 2;
|
|
654
|
+
case "number": return 4;
|
|
655
|
+
case "boolean": return 8;
|
|
656
|
+
default: return 0;
|
|
657
|
+
}
|
|
658
|
+
case "Union": {
|
|
659
|
+
let out = 0;
|
|
660
|
+
for (const type of representation.types) out |= rootMask(type);
|
|
661
|
+
return out;
|
|
662
|
+
}
|
|
663
|
+
default: return 1 << jsonRootTags.indexOf(representation._tag);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
function hasChoices(representation) {
|
|
667
|
+
switch (representation._tag) {
|
|
668
|
+
case "Reference": {
|
|
669
|
+
const key = representation.$ref;
|
|
670
|
+
const cached = definitionCache.get(key);
|
|
671
|
+
if (cached === null || resolvingChoices.has(key)) return true;
|
|
672
|
+
resolvingChoices.add(key);
|
|
673
|
+
const out = hasChoices(cached ?? translateDefinition(key, representation.path));
|
|
674
|
+
resolvingChoices.delete(key);
|
|
675
|
+
return out;
|
|
676
|
+
}
|
|
677
|
+
case "Union": return !isLiteralSet(representation) && (representation.types.length > 1 || representation.types.some(hasChoices));
|
|
678
|
+
case "Arrays": return representation.elements.some((element) => hasChoices(element.type)) || representation.rest.some(hasChoices);
|
|
679
|
+
case "Objects": return representation.propertySignatures.some((property) => hasChoices(property.type)) || representation.indexSignatures.some((indexSignature) => hasChoices(indexSignature.parameter) || hasChoices(indexSignature.type)) || representation.scopes.some((scope) => scope.patterns.some((pattern) => hasChoices(pattern.type))) || representation.checks.some(checkHasChoices);
|
|
680
|
+
default: return false;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function checkHasChoices(check) {
|
|
684
|
+
return check._tag === "FilterGroup" ? check.checks.some(checkHasChoices) : check._tag === "PropertyNames" && hasChoices(check.type);
|
|
685
|
+
}
|
|
686
|
+
function makeUnion(source, types) {
|
|
687
|
+
if (types.length === 0) return never;
|
|
688
|
+
if (types.length === 1 && source.checks.length === 0) return annotate(types[0], source);
|
|
689
|
+
return {
|
|
690
|
+
...source,
|
|
691
|
+
types
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function literalValue(representation) {
|
|
695
|
+
if (representation._tag === "Null") return null;
|
|
696
|
+
if (representation._tag !== "Literal") return void 0;
|
|
697
|
+
return representation.literal;
|
|
698
|
+
}
|
|
699
|
+
function isLiteralSet(union) {
|
|
700
|
+
return (union.options?.mode ?? "anyOf") === "anyOf" && union.types.every((type) => literalValue(type) !== void 0);
|
|
701
|
+
}
|
|
702
|
+
function intersectLiteralUnions(left, right, path) {
|
|
703
|
+
if (!isLiteralSet(left) || !isLiteralSet(right)) return void 0;
|
|
704
|
+
const rightByValue = /* @__PURE__ */ new Map();
|
|
705
|
+
for (const representation of right.types) {
|
|
706
|
+
const value = literalValue(representation);
|
|
707
|
+
const previous = rightByValue.get(value);
|
|
708
|
+
rightByValue.set(value, {
|
|
709
|
+
...representation,
|
|
710
|
+
customAnnotations: mergeAnnotations(previous?.customAnnotations, representation.customAnnotations)
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
const types = [];
|
|
714
|
+
for (const representation of left.types) {
|
|
715
|
+
const match = rightByValue.get(literalValue(representation));
|
|
716
|
+
if (match !== void 0) types.push(intersect(representation, annotate(match, right), path));
|
|
717
|
+
}
|
|
718
|
+
return makeUnion(left, types);
|
|
719
|
+
}
|
|
720
|
+
function intersectUnionWithType(union, type, path, unionOnLeft) {
|
|
721
|
+
const mask = rootMask(type);
|
|
722
|
+
const members = union.types.map((member, index) => ({
|
|
723
|
+
index,
|
|
724
|
+
type: member
|
|
725
|
+
})).filter((member) => (rootMask(member.type) & mask) !== 0);
|
|
726
|
+
if (members.length > 1 && hasChoices(type)) return unsupportedIntersection(path);
|
|
727
|
+
if (members.length === 1 && union.checks.length === 0) {
|
|
728
|
+
const member = annotate(members[0].type, union);
|
|
729
|
+
return unionOnLeft ? intersect(member, type, [
|
|
730
|
+
...path,
|
|
731
|
+
"types",
|
|
732
|
+
members[0].index
|
|
733
|
+
]) : intersect(type, member, [
|
|
734
|
+
...path,
|
|
735
|
+
"types",
|
|
736
|
+
members[0].index
|
|
737
|
+
]);
|
|
738
|
+
}
|
|
739
|
+
return makeUnion(union, members.map((member) => unionOnLeft ? intersect(member.type, type, [
|
|
740
|
+
...path,
|
|
741
|
+
"types",
|
|
742
|
+
member.index
|
|
743
|
+
]) : intersect(type, member.type, [
|
|
744
|
+
...path,
|
|
745
|
+
"types",
|
|
746
|
+
member.index
|
|
747
|
+
])).filter((type) => type._tag !== "Never"));
|
|
748
|
+
}
|
|
749
|
+
function isTypePartition(union) {
|
|
750
|
+
let mask = 0;
|
|
751
|
+
for (const type of union.types) {
|
|
752
|
+
const memberMask = rootMask(type);
|
|
753
|
+
if ((mask & memberMask) !== 0) return false;
|
|
754
|
+
mask |= memberMask;
|
|
755
|
+
}
|
|
756
|
+
return true;
|
|
757
|
+
}
|
|
758
|
+
function unsupportedIntersection(path) {
|
|
759
|
+
throw errorWithPath("Cannot intersect these \"anyOf\" or \"oneOf\" alternatives without expanding their branches.", path);
|
|
760
|
+
}
|
|
761
|
+
function intersectPartition(partition, other, path, partitionOnLeft) {
|
|
762
|
+
const partitionTypes = partition.types;
|
|
763
|
+
const otherTypes = other.types;
|
|
764
|
+
for (const type of otherTypes) {
|
|
765
|
+
const mask = rootMask(type);
|
|
766
|
+
if (partitionTypes.filter((member) => (rootMask(member) & mask) !== 0).length > 1 && hasChoices(type)) return unsupportedIntersection(path);
|
|
767
|
+
}
|
|
768
|
+
const types = [];
|
|
769
|
+
for (let index = 0; index < partitionTypes.length; index++) {
|
|
770
|
+
const member = partitionTypes[index];
|
|
771
|
+
const type = intersectUnionWithType(other, member, [
|
|
772
|
+
...path,
|
|
773
|
+
"types",
|
|
774
|
+
index
|
|
775
|
+
], !partitionOnLeft);
|
|
776
|
+
if (type._tag !== "Never") types.push(type);
|
|
777
|
+
}
|
|
778
|
+
return makeUnion(partition, types);
|
|
779
|
+
}
|
|
780
|
+
function intersectUnions(left, right, path) {
|
|
781
|
+
const literals = intersectLiteralUnions(left, right, path);
|
|
782
|
+
if (literals !== void 0) return literals;
|
|
783
|
+
if (isTypePartition(left)) return intersectPartition(left, right, path, true);
|
|
784
|
+
if (isTypePartition(right)) return intersectPartition(right, left, path, false);
|
|
785
|
+
return unsupportedIntersection(path);
|
|
786
|
+
}
|
|
787
|
+
function intersect(left, right, path) {
|
|
788
|
+
if (left._tag === "Never") return left;
|
|
789
|
+
if (right._tag === "Never") return right;
|
|
790
|
+
if (left._tag === "Unknown") return annotateIntersection(right, left, right);
|
|
791
|
+
if (right._tag === "Unknown") return annotateIntersection(left, left, right);
|
|
792
|
+
if (left._tag === "Reference") {
|
|
793
|
+
if ((left.annotations !== void 0 || left.customAnnotations !== void 0) && right._tag === "Reference" && right.annotations === void 0 && right.customAnnotations === void 0) return intersect(left, resolveReference(right, path), path);
|
|
794
|
+
return annotate(intersect(resolveReference(left, path), right, path), left);
|
|
795
|
+
}
|
|
796
|
+
if (right._tag === "Reference") return annotate(intersect(left, resolveReference(right, path), path), right);
|
|
797
|
+
if (left._tag === "Union" && right._tag === "Union") return intersectUnions(left, right, path);
|
|
798
|
+
if (left._tag === "Union") return intersectUnionWithType(left, right, path, true);
|
|
799
|
+
if (right._tag === "Union") return intersectUnionWithType(right, left, path, false);
|
|
800
|
+
switch (left._tag) {
|
|
801
|
+
case "Null": return right._tag === "Null" ? annotateIntersection({
|
|
802
|
+
_tag: "Null",
|
|
803
|
+
checks: [...left.checks, ...right.checks]
|
|
804
|
+
}, left, right) : never;
|
|
805
|
+
case "String":
|
|
806
|
+
if (right._tag === "Literal") return intersectPrimitiveWithLiteral(left, right);
|
|
807
|
+
if (right._tag !== "String") return never;
|
|
808
|
+
return {
|
|
809
|
+
_tag: "String",
|
|
810
|
+
...intersectChecks(left, right)
|
|
811
|
+
};
|
|
812
|
+
case "Number":
|
|
813
|
+
if (right._tag === "Literal") return intersectPrimitiveWithLiteral(left, right);
|
|
814
|
+
if (right._tag !== "Number") return never;
|
|
815
|
+
return {
|
|
816
|
+
_tag: "Number",
|
|
817
|
+
...intersectChecks(left, right, ["effect/schema/isFinite", "effect/schema/isInt"])
|
|
818
|
+
};
|
|
819
|
+
case "Boolean":
|
|
820
|
+
if (right._tag === "Literal") return intersectPrimitiveWithLiteral(left, right);
|
|
821
|
+
return right._tag === "Boolean" ? annotateIntersection({
|
|
822
|
+
_tag: "Boolean",
|
|
823
|
+
checks: [...left.checks, ...right.checks]
|
|
824
|
+
}, left, right) : never;
|
|
825
|
+
case "Literal":
|
|
826
|
+
if (right._tag === "Literal") return left.literal === right.literal ? annotateIntersection({
|
|
827
|
+
...left,
|
|
828
|
+
checks: [...left.checks, ...right.checks]
|
|
829
|
+
}, left, right) : never;
|
|
830
|
+
if ((right._tag === "String" || right._tag === "Number") && satisfiesLiteral(right, left) || right._tag === "Boolean" && typeof left.literal === "boolean") return annotateIntersection(left, left, right);
|
|
831
|
+
return never;
|
|
832
|
+
case "Arrays": {
|
|
833
|
+
if (right._tag !== "Arrays") return never;
|
|
834
|
+
const arrays = intersectArrays(left, right, path);
|
|
835
|
+
if (arrays === void 0) return never;
|
|
836
|
+
return {
|
|
837
|
+
_tag: "Arrays",
|
|
838
|
+
...arrays,
|
|
839
|
+
...intersectChecks(left, right, ["effect/schema/isUnique"])
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
case "Objects":
|
|
843
|
+
if (right._tag !== "Objects") return never;
|
|
844
|
+
return lowerObject([...left.scopes, ...right.scopes], intersectChecks(left, right), path);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
function translateSchema(input, path, isRoot = false) {
|
|
848
|
+
if (input === false) return never;
|
|
849
|
+
if (!isObject(input)) return unknown;
|
|
850
|
+
const schema = options?.onEnter === void 0 ? input : options.onEnter(input);
|
|
851
|
+
if (schema === void 0) return unknown;
|
|
852
|
+
if (isObject(schema.not) && Object.keys(schema.not).length === 0) return annotate(never, jsonSchemaAnnotations(schema, options));
|
|
853
|
+
const wasInNestedResource = inNestedResource;
|
|
854
|
+
inNestedResource ||= !isRoot && typeof schema.$id === "string";
|
|
855
|
+
for (const keyword of Object.keys(schema)) {
|
|
856
|
+
if (keyword === "if" && !Object.hasOwn(schema, "then") && !Object.hasOwn(schema, "else")) continue;
|
|
857
|
+
switch (keyword) {
|
|
858
|
+
case "if":
|
|
859
|
+
case "$dynamicRef":
|
|
860
|
+
case "contains":
|
|
861
|
+
case "dependentRequired":
|
|
862
|
+
case "dependentSchemas":
|
|
863
|
+
case "not":
|
|
864
|
+
case "unevaluatedItems":
|
|
865
|
+
case "unevaluatedProperties": throw errorWithPath(`Cannot import JSON Schema keyword "${keyword}": Effect has no equivalent constraint.`, [...path, keyword]);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
let representation = translateType(schema, path);
|
|
869
|
+
if (Object.hasOwn(schema, "const")) {
|
|
870
|
+
const constPath = [...path, "const"];
|
|
871
|
+
const literal = makeJsonLiteral(schema.const, constPath);
|
|
872
|
+
if (literal !== void 0) representation = intersect(representation, literal, constPath);
|
|
873
|
+
}
|
|
874
|
+
if (Array.isArray(schema.enum)) {
|
|
875
|
+
const types = schema.enum.map((value, index) => makeJsonLiteral(value, [
|
|
876
|
+
...path,
|
|
877
|
+
"enum",
|
|
878
|
+
index
|
|
879
|
+
]) ?? unknown);
|
|
880
|
+
representation = intersect(representation, types.length === 1 ? types[0] : {
|
|
881
|
+
_tag: "Union",
|
|
882
|
+
types,
|
|
883
|
+
checks: []
|
|
884
|
+
}, [...path, "enum"]);
|
|
885
|
+
}
|
|
886
|
+
if (typeof schema.$ref === "string") {
|
|
887
|
+
if (inNestedResource) throw errorWithPath("Cannot resolve $ref under a nested \"$id\". Resolve or flatten it first.", [...path, "$ref"]);
|
|
888
|
+
const key = getReferenceKey(schema.$ref);
|
|
889
|
+
if (key !== void 0 && !Object.hasOwn(document.definitions, key)) throw errorWithPath(`Missing definition ${JSON.stringify(key)} for $ref ${JSON.stringify(schema.$ref)}.`, [...path, "$ref"]);
|
|
890
|
+
const reference = {
|
|
891
|
+
_tag: "Reference",
|
|
892
|
+
$ref: key ?? resolvePointer(schema.$ref, path),
|
|
893
|
+
path
|
|
894
|
+
};
|
|
895
|
+
representation = representation._tag === "Unknown" ? reference : representation._tag === "Never" ? never : intersect(resolveReference(reference, path, `Recursive $ref ${JSON.stringify(reference.$ref)} cannot have sibling constraints.`), representation, path);
|
|
896
|
+
}
|
|
897
|
+
representation = annotate(representation, jsonSchemaAnnotations(schema, options));
|
|
898
|
+
if (Array.isArray(schema.allOf)) for (let index = 0; index < schema.allOf.length; index++) representation = intersect(representation, translateSchema(schema.allOf[index], [
|
|
899
|
+
...path,
|
|
900
|
+
"allOf",
|
|
901
|
+
index
|
|
902
|
+
]), [
|
|
903
|
+
...path,
|
|
904
|
+
"allOf",
|
|
905
|
+
index
|
|
906
|
+
]);
|
|
907
|
+
for (const mode of ["anyOf", "oneOf"]) {
|
|
908
|
+
const members = schema[mode];
|
|
909
|
+
if (Array.isArray(members)) representation = intersect({
|
|
910
|
+
_tag: "Union",
|
|
911
|
+
types: members.map((member, index) => translateSchema(member, [
|
|
912
|
+
...path,
|
|
913
|
+
mode,
|
|
914
|
+
index
|
|
915
|
+
])),
|
|
916
|
+
...mode === "oneOf" ? { options: { mode } } : {},
|
|
917
|
+
checks: []
|
|
918
|
+
}, representation, [...path, mode]);
|
|
919
|
+
}
|
|
920
|
+
inNestedResource = wasInNestedResource;
|
|
921
|
+
return representation;
|
|
922
|
+
}
|
|
923
|
+
function translateType(schema, path) {
|
|
924
|
+
const types = Array.isArray(schema.type) && schema.type.every(isImportedJsonSchemaType) ? schema.type : !isImportedJsonSchemaType(schema.type) && hasTypeSpecificKeywords(schema) ? jsonSchemaValueTypes : void 0;
|
|
925
|
+
if (types !== void 0) return {
|
|
926
|
+
_tag: "Union",
|
|
927
|
+
types: types.map((type) => translateType({
|
|
928
|
+
...schema,
|
|
929
|
+
type
|
|
930
|
+
}, path)),
|
|
931
|
+
checks: []
|
|
932
|
+
};
|
|
933
|
+
const type = isImportedJsonSchemaType(schema.type) ? schema.type : void 0;
|
|
934
|
+
switch (type) {
|
|
935
|
+
case "null": return {
|
|
936
|
+
_tag: "Null",
|
|
937
|
+
checks: []
|
|
938
|
+
};
|
|
939
|
+
case "string": return {
|
|
940
|
+
_tag: "String",
|
|
941
|
+
checks: collectStringChecks(schema, path)
|
|
942
|
+
};
|
|
943
|
+
case "number":
|
|
944
|
+
case "integer": return {
|
|
945
|
+
_tag: "Number",
|
|
946
|
+
checks: [makeFilter(type === "number" ? isFinite() : isInt()), ...collectNumberChecks(schema)]
|
|
947
|
+
};
|
|
948
|
+
case "boolean": return {
|
|
949
|
+
_tag: "Boolean",
|
|
950
|
+
checks: []
|
|
951
|
+
};
|
|
952
|
+
case "array": {
|
|
953
|
+
const prefixItems = Array.isArray(schema.prefixItems) ? schema.prefixItems : void 0;
|
|
954
|
+
const minItems = typeof schema.minItems === "number" ? schema.minItems : 0;
|
|
955
|
+
const elements = prefixItems?.map((element, index) => ({
|
|
956
|
+
isOptional: index + 1 > minItems,
|
|
957
|
+
type: translateSchema(element, [
|
|
958
|
+
...path,
|
|
959
|
+
"prefixItems",
|
|
960
|
+
index
|
|
961
|
+
])
|
|
962
|
+
})) ?? [];
|
|
963
|
+
const isTupleClosed = schema.items === false || schema.items === void 0 && prefixItems !== void 0 && schema.maxItems === prefixItems.length;
|
|
964
|
+
const isMaxItemsRedundant = isTupleClosed && typeof schema.maxItems === "number" && schema.maxItems >= elements.length;
|
|
965
|
+
return {
|
|
966
|
+
_tag: "Arrays",
|
|
967
|
+
elements,
|
|
968
|
+
rest: isTupleClosed ? [] : [schema.items === void 0 ? unknown : translateSchema(schema.items, [...path, "items"])],
|
|
969
|
+
checks: collectArrayChecks(schema, isMaxItemsRedundant)
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
case "object": return lowerObject([collectObjectScope(schema, path)], { checks: collectObjectChecks(schema, path) }, path);
|
|
973
|
+
default: return unknown;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
function importPatternCheck(pattern, path) {
|
|
977
|
+
switch (options?.patterns ?? "error") {
|
|
978
|
+
case "error": throw errorWithPath("Patterns may block validation and are disabled. Use patterns: \"apply\" for trusted schemas or \"ignore\" to discard them.", path);
|
|
979
|
+
case "ignore": return;
|
|
980
|
+
case "apply": {
|
|
981
|
+
let regex;
|
|
982
|
+
try {
|
|
983
|
+
regex = globalThis.RegExp(pattern, jsonSchemaPatternFlags);
|
|
984
|
+
} catch {
|
|
985
|
+
throw errorWithPath("Cannot import pattern using ECMAScript Unicode mode.", path);
|
|
986
|
+
}
|
|
987
|
+
return makeFilter(isPattern(regex));
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
function collectStringChecks(schema, path) {
|
|
992
|
+
const checks = [];
|
|
993
|
+
if (schema.minLength === 1) addNumberCheck(checks, schema.minLength, isMinLength);
|
|
994
|
+
else addNumberCheck(checks, schema.minLength, isMinCodePoints);
|
|
995
|
+
addNumberCheck(checks, schema.maxLength, isMaxCodePoints);
|
|
996
|
+
if (typeof schema.pattern === "string") {
|
|
997
|
+
const check = importPatternCheck(schema.pattern, [...path, "pattern"]);
|
|
998
|
+
if (check !== void 0) checks.push(check);
|
|
999
|
+
}
|
|
1000
|
+
return checks;
|
|
1001
|
+
}
|
|
1002
|
+
function collectNumberChecks(schema) {
|
|
1003
|
+
const checks = [];
|
|
1004
|
+
addNumberCheck(checks, schema.minimum, isGreaterThanOrEqualTo);
|
|
1005
|
+
addNumberCheck(checks, schema.maximum, isLessThanOrEqualTo);
|
|
1006
|
+
addNumberCheck(checks, schema.exclusiveMinimum, isGreaterThan);
|
|
1007
|
+
addNumberCheck(checks, schema.exclusiveMaximum, isLessThan);
|
|
1008
|
+
addNumberCheck(checks, schema.multipleOf, isMultipleOf);
|
|
1009
|
+
return checks;
|
|
1010
|
+
}
|
|
1011
|
+
function collectArrayChecks(schema, isMaxItemsRedundant) {
|
|
1012
|
+
const checks = [];
|
|
1013
|
+
if (!Array.isArray(schema.prefixItems) || typeof schema.minItems === "number" && schema.minItems > schema.prefixItems.length) addNumberCheck(checks, schema.minItems, isMinLength);
|
|
1014
|
+
if (!isMaxItemsRedundant) addNumberCheck(checks, schema.maxItems, isMaxLength);
|
|
1015
|
+
if (schema.uniqueItems === true) checks.push(makeFilter(isUnique()));
|
|
1016
|
+
return checks;
|
|
1017
|
+
}
|
|
1018
|
+
function collectObjectScope(schema, path) {
|
|
1019
|
+
const sourceProperties = isObject(schema.properties) ? schema.properties : {};
|
|
1020
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === "string") : []);
|
|
1021
|
+
const propertyNames = Object.keys(sourceProperties);
|
|
1022
|
+
const keys = /* @__PURE__ */ new Set([...propertyNames, ...required]);
|
|
1023
|
+
const properties = new Map(Array.from(keys, (name) => [name, {
|
|
1024
|
+
type: Object.hasOwn(sourceProperties, name) ? translateSchema(sourceProperties[name], [
|
|
1025
|
+
...path,
|
|
1026
|
+
"properties",
|
|
1027
|
+
name
|
|
1028
|
+
]) : void 0,
|
|
1029
|
+
isOptional: !required.has(name)
|
|
1030
|
+
}]));
|
|
1031
|
+
const hasProperties = propertyNames.length > 0;
|
|
1032
|
+
const patterns = [];
|
|
1033
|
+
if (isObject(schema.patternProperties)) for (const [pattern, value] of Object.entries(schema.patternProperties)) {
|
|
1034
|
+
const check = importPatternCheck(pattern, [
|
|
1035
|
+
...path,
|
|
1036
|
+
"patternProperties",
|
|
1037
|
+
pattern
|
|
1038
|
+
]);
|
|
1039
|
+
if (check === void 0) return {
|
|
1040
|
+
properties,
|
|
1041
|
+
hasProperties,
|
|
1042
|
+
patterns: [],
|
|
1043
|
+
additionalProperties: unknown
|
|
1044
|
+
};
|
|
1045
|
+
patterns.push({
|
|
1046
|
+
source: pattern,
|
|
1047
|
+
parameter: {
|
|
1048
|
+
_tag: "String",
|
|
1049
|
+
checks: [check]
|
|
1050
|
+
},
|
|
1051
|
+
type: translateSchema(value, [
|
|
1052
|
+
...path,
|
|
1053
|
+
"patternProperties",
|
|
1054
|
+
pattern
|
|
1055
|
+
])
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
return {
|
|
1059
|
+
properties,
|
|
1060
|
+
hasProperties,
|
|
1061
|
+
patterns,
|
|
1062
|
+
additionalProperties: schema.additionalProperties === false ? never : isObject(schema.additionalProperties) ? translateSchema(schema.additionalProperties, [...path, "additionalProperties"]) : unknown
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
function collectObjectChecks(schema, path) {
|
|
1066
|
+
const checks = [];
|
|
1067
|
+
addNumberCheck(checks, schema.minProperties, isMinProperties);
|
|
1068
|
+
addNumberCheck(checks, schema.maxProperties, isMaxProperties);
|
|
1069
|
+
if (schema.propertyNames !== void 0) {
|
|
1070
|
+
const propertyNamesPath = [...path, "propertyNames"];
|
|
1071
|
+
checks.push({
|
|
1072
|
+
_tag: "PropertyNames",
|
|
1073
|
+
type: intersect(string, translateSchema(schema.propertyNames, propertyNamesPath), propertyNamesPath)
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
return checks;
|
|
1077
|
+
}
|
|
1078
|
+
return document.schemas.map((schema, index) => finalize(translateSchema(schema, singleRoot ? ["schema"] : ["schemas", index], true)));
|
|
1079
|
+
}
|
|
1080
|
+
/** @internal */
|
|
1081
|
+
function fromJsonSchemaDocument$1(document, options) {
|
|
1082
|
+
return fromJsonSchemaMultiDocument({
|
|
1083
|
+
dialect: document.dialect,
|
|
1084
|
+
schemas: [document.schema],
|
|
1085
|
+
definitions: document.definitions
|
|
1086
|
+
}, options, true)[0];
|
|
1087
|
+
}
|
|
1088
|
+
const RepresentationSchema = /*#__PURE__*/ suspend(() => RepresentationUnion);
|
|
1089
|
+
const RepresentationsSchema = /*#__PURE__*/ ArraySchema(RepresentationSchema);
|
|
1090
|
+
const RepresentationAnnotationSchema = /*#__PURE__*/ Struct({
|
|
1091
|
+
id: NonEmptyString,
|
|
1092
|
+
payload: Json
|
|
1093
|
+
});
|
|
1094
|
+
const CheckRepresentationAnnotationSchema = /*#__PURE__*/ Struct({
|
|
1095
|
+
...RepresentationAnnotationSchema.fields,
|
|
1096
|
+
schemas: /*#__PURE__*/ optional(RepresentationsSchema)
|
|
1097
|
+
});
|
|
1098
|
+
function pruneAnnotations(annotations) {
|
|
1099
|
+
const out = {};
|
|
1100
|
+
for (const [key, value] of Object.entries(annotations)) if (isJson(value)) assignProperty(out, key, value);
|
|
1101
|
+
return Object.keys(out).length === 0 ? none() : some(out);
|
|
1102
|
+
}
|
|
1103
|
+
const AnnotationsSchema = /*#__PURE__*/ optional(Record(String$1, Unknown)).pipe(/*#__PURE__*/ encodeTo(/*#__PURE__*/ optionalKey(JsonObject), {
|
|
1104
|
+
decode: /*#__PURE__*/ passthroughSubtype(),
|
|
1105
|
+
encode: /*#__PURE__*/ transformOptional((annotations) => isNone(annotations) || annotations.value === void 0 ? none() : pruneAnnotations(annotations.value))
|
|
1106
|
+
}));
|
|
1107
|
+
const CheckSchema = /*#__PURE__*/ suspend(() => CheckUnion);
|
|
1108
|
+
const ChecksSchema = /*#__PURE__*/ ArraySchema(CheckSchema);
|
|
1109
|
+
const KeywordFields = {
|
|
1110
|
+
annotations: AnnotationsSchema,
|
|
1111
|
+
checks: ChecksSchema
|
|
1112
|
+
};
|
|
1113
|
+
const CheckUnion = /*#__PURE__*/ Union([/* @__PURE__ */ Struct({
|
|
1114
|
+
_tag: /*#__PURE__*/ tag("Filter"),
|
|
1115
|
+
representation: CheckRepresentationAnnotationSchema,
|
|
1116
|
+
annotations: AnnotationsSchema,
|
|
1117
|
+
aborted: Boolean
|
|
1118
|
+
}), /* @__PURE__ */ Struct({
|
|
1119
|
+
_tag: /*#__PURE__*/ tag("FilterGroup"),
|
|
1120
|
+
representation: /*#__PURE__*/ optional(CheckRepresentationAnnotationSchema),
|
|
1121
|
+
annotations: AnnotationsSchema,
|
|
1122
|
+
checks: /*#__PURE__*/ NonEmptyArray(CheckSchema)
|
|
1123
|
+
})]);
|
|
1124
|
+
function makeKeywordSchema(tag$1) {
|
|
1125
|
+
return Struct({
|
|
1126
|
+
_tag: tag(tag$1),
|
|
1127
|
+
...KeywordFields
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
const DeclarationSchema = /*#__PURE__*/ Struct({
|
|
1131
|
+
_tag: /*#__PURE__*/ tag("Declaration"),
|
|
1132
|
+
representation: RepresentationAnnotationSchema,
|
|
1133
|
+
annotations: AnnotationsSchema,
|
|
1134
|
+
typeParameters: RepresentationsSchema,
|
|
1135
|
+
checks: ChecksSchema
|
|
1136
|
+
});
|
|
1137
|
+
const SuspendSchema = /*#__PURE__*/ Struct({
|
|
1138
|
+
_tag: /*#__PURE__*/ tag("Suspend"),
|
|
1139
|
+
annotations: AnnotationsSchema,
|
|
1140
|
+
checks: /*#__PURE__*/ Tuple([]),
|
|
1141
|
+
thunk: RepresentationSchema
|
|
1142
|
+
});
|
|
1143
|
+
function makeValueSchema(type, value) {
|
|
1144
|
+
return value.pipe(encodeTo(Struct({
|
|
1145
|
+
type: tag(type),
|
|
1146
|
+
value
|
|
1147
|
+
}), {
|
|
1148
|
+
decode: transform((encoded) => encoded.value),
|
|
1149
|
+
encode: transform((value) => ({
|
|
1150
|
+
type,
|
|
1151
|
+
value
|
|
1152
|
+
}))
|
|
1153
|
+
}));
|
|
1154
|
+
}
|
|
1155
|
+
const StringValueCodec = /*#__PURE__*/ makeValueSchema("string", String$1);
|
|
1156
|
+
const NumberValueCodec = /*#__PURE__*/ makeValueSchema("number", Number);
|
|
1157
|
+
const LiteralSchema = /*#__PURE__*/ Struct({
|
|
1158
|
+
_tag: /*#__PURE__*/ tag("Literal"),
|
|
1159
|
+
...KeywordFields,
|
|
1160
|
+
literal: /*#__PURE__*/ Union([
|
|
1161
|
+
StringValueCodec,
|
|
1162
|
+
/*#__PURE__*/ makeValueSchema("number", Finite),
|
|
1163
|
+
/*#__PURE__*/ makeValueSchema("bigint", BigInt),
|
|
1164
|
+
/*#__PURE__*/ makeValueSchema("boolean", Boolean)
|
|
1165
|
+
])
|
|
1166
|
+
});
|
|
1167
|
+
const UniqueSymbolSchema = /*#__PURE__*/ Struct({
|
|
1168
|
+
_tag: /*#__PURE__*/ tag("UniqueSymbol"),
|
|
1169
|
+
...KeywordFields,
|
|
1170
|
+
symbol: Symbol
|
|
1171
|
+
});
|
|
1172
|
+
const EnumSchema = /*#__PURE__*/ Struct({
|
|
1173
|
+
_tag: /*#__PURE__*/ tag("Enum"),
|
|
1174
|
+
...KeywordFields,
|
|
1175
|
+
enums: /*#__PURE__*/ ArraySchema(/*#__PURE__*/ Tuple([String$1, /*#__PURE__*/ Union([StringValueCodec, NumberValueCodec])]))
|
|
1176
|
+
});
|
|
1177
|
+
const TemplateLiteralSchema = /*#__PURE__*/ Struct({
|
|
1178
|
+
_tag: /*#__PURE__*/ tag("TemplateLiteral"),
|
|
1179
|
+
...KeywordFields,
|
|
1180
|
+
parts: RepresentationsSchema
|
|
1181
|
+
});
|
|
1182
|
+
const ElementSchema = /*#__PURE__*/ Struct({
|
|
1183
|
+
isOptional: Boolean,
|
|
1184
|
+
type: RepresentationSchema,
|
|
1185
|
+
annotations: AnnotationsSchema
|
|
1186
|
+
});
|
|
1187
|
+
const ArraysSchema = /*#__PURE__*/ Struct({
|
|
1188
|
+
_tag: /*#__PURE__*/ tag("Arrays"),
|
|
1189
|
+
...KeywordFields,
|
|
1190
|
+
elements: /*#__PURE__*/ ArraySchema(ElementSchema),
|
|
1191
|
+
rest: RepresentationsSchema
|
|
1192
|
+
});
|
|
1193
|
+
const PropertySignatureSchema = /*#__PURE__*/ Struct({
|
|
1194
|
+
name: /*#__PURE__*/ Union([
|
|
1195
|
+
StringValueCodec,
|
|
1196
|
+
NumberValueCodec,
|
|
1197
|
+
/*#__PURE__*/ makeValueSchema("symbol", Symbol)
|
|
1198
|
+
]),
|
|
1199
|
+
type: RepresentationSchema,
|
|
1200
|
+
isOptional: Boolean,
|
|
1201
|
+
isMutable: Boolean,
|
|
1202
|
+
annotations: AnnotationsSchema
|
|
1203
|
+
});
|
|
1204
|
+
const IndexSignatureSchema = /*#__PURE__*/ Struct({
|
|
1205
|
+
parameter: RepresentationSchema,
|
|
1206
|
+
type: RepresentationSchema
|
|
1207
|
+
});
|
|
1208
|
+
const ObjectsSchema = /*#__PURE__*/ Struct({
|
|
1209
|
+
_tag: /*#__PURE__*/ tag("Objects"),
|
|
1210
|
+
...KeywordFields,
|
|
1211
|
+
propertySignatures: /*#__PURE__*/ ArraySchema(PropertySignatureSchema),
|
|
1212
|
+
indexSignatures: /*#__PURE__*/ ArraySchema(IndexSignatureSchema)
|
|
1213
|
+
});
|
|
1214
|
+
const UnionSchema = /*#__PURE__*/ Struct({
|
|
1215
|
+
_tag: /*#__PURE__*/ tag("Union"),
|
|
1216
|
+
...KeywordFields,
|
|
1217
|
+
types: RepresentationsSchema,
|
|
1218
|
+
options: /*#__PURE__*/ optionalKey(/*#__PURE__*/ Struct({ mode: /*#__PURE__*/ optionalKey(/*#__PURE__*/ Literals(["anyOf", "oneOf"])) }))
|
|
1219
|
+
});
|
|
1220
|
+
const RepresentationUnion = /*#__PURE__*/ Union([
|
|
1221
|
+
DeclarationSchema,
|
|
1222
|
+
/* @__PURE__ */ Struct({
|
|
1223
|
+
_tag: /*#__PURE__*/ tag("Reference"),
|
|
1224
|
+
$ref: NonEmptyString
|
|
1225
|
+
}),
|
|
1226
|
+
SuspendSchema,
|
|
1227
|
+
/*#__PURE__*/ makeKeywordSchema("Null"),
|
|
1228
|
+
/*#__PURE__*/ makeKeywordSchema("Undefined"),
|
|
1229
|
+
/*#__PURE__*/ makeKeywordSchema("Void"),
|
|
1230
|
+
/*#__PURE__*/ makeKeywordSchema("Never"),
|
|
1231
|
+
/*#__PURE__*/ makeKeywordSchema("Unknown"),
|
|
1232
|
+
/*#__PURE__*/ makeKeywordSchema("Any"),
|
|
1233
|
+
/*#__PURE__*/ Struct({
|
|
1234
|
+
_tag: /*#__PURE__*/ tag("String"),
|
|
1235
|
+
...KeywordFields,
|
|
1236
|
+
content: /*#__PURE__*/ optional(/*#__PURE__*/ Struct({
|
|
1237
|
+
mediaType: String$1,
|
|
1238
|
+
schema: /*#__PURE__*/ optional(RepresentationSchema)
|
|
1239
|
+
}))
|
|
1240
|
+
}),
|
|
1241
|
+
/*#__PURE__*/ makeKeywordSchema("Number"),
|
|
1242
|
+
/*#__PURE__*/ makeKeywordSchema("Boolean"),
|
|
1243
|
+
/*#__PURE__*/ makeKeywordSchema("BigInt"),
|
|
1244
|
+
/*#__PURE__*/ makeKeywordSchema("Symbol"),
|
|
1245
|
+
/*#__PURE__*/ makeKeywordSchema("ObjectKeyword"),
|
|
1246
|
+
LiteralSchema,
|
|
1247
|
+
UniqueSymbolSchema,
|
|
1248
|
+
EnumSchema,
|
|
1249
|
+
TemplateLiteralSchema,
|
|
1250
|
+
ArraysSchema,
|
|
1251
|
+
ObjectsSchema,
|
|
1252
|
+
UnionSchema
|
|
1253
|
+
]);
|
|
1254
|
+
/**
|
|
1255
|
+
* Imports a JSON Schema Draft 2020-12 document as a runtime schema.
|
|
1256
|
+
*
|
|
1257
|
+
* **When to use**
|
|
1258
|
+
*
|
|
1259
|
+
* Use when you need to validate or transform values described by an external JSON Schema document.
|
|
1260
|
+
*
|
|
1261
|
+
* **Details**
|
|
1262
|
+
*
|
|
1263
|
+
* Translates a Draft 2020-12 subset using Effect schemas and built-in checks. Validation follows those checks and the
|
|
1264
|
+
* decoder's parse options, so import and re-export do not guarantee identical accepted values or a lossless round trip.
|
|
1265
|
+
* Import errors explain the unsupported constraint or reference and include its source path.
|
|
1266
|
+
* The input is assumed to be a valid Draft 2020-12 document; this function does not validate it against the meta-schema.
|
|
1267
|
+
* Instance validation semantics assume JSON-compatible JavaScript values produced by `JSON.parse`.
|
|
1268
|
+
*
|
|
1269
|
+
* **Gotchas**
|
|
1270
|
+
*
|
|
1271
|
+
* - `{ not: {} }` imports as `Never`. Other uses of `not` are unsupported.
|
|
1272
|
+
* - When `additionalProperties` is `true`, `{}`, or omitted, additional values use `Schema.Json` and are retained.
|
|
1273
|
+
* Closed objects normally strip excess properties by default; pass `onExcessProperty: "error"` to reject them.
|
|
1274
|
+
* Closed empty objects instead use `Schema.Record(Schema.String, Schema.Never)` and reject string-keyed entries
|
|
1275
|
+
* regardless of that option.
|
|
1276
|
+
* Object keyword scopes still constrain declared properties in intersections. Combinations requiring index
|
|
1277
|
+
* signatures that exclude explicit properties or patterned keys are rejected with an explanation of the limitation.
|
|
1278
|
+
* - Property count and name checks run on the decoded object, after excess properties have been stripped.
|
|
1279
|
+
* - String `minLength` and `maxLength` checks count Unicode code points, except that `minLength: 1` uses the equivalent
|
|
1280
|
+
* UTF-16 non-empty check. `integer` uses `Schema.isInt`, which requires safe integers.
|
|
1281
|
+
* - Applied patterns use `Schema.isPattern` with the `u` flag. Patterns that cannot be compiled in Unicode mode are
|
|
1282
|
+
* rejected as unsupported translations with their source path.
|
|
1283
|
+
* - `$dynamicRef`, `contains`, `dependentRequired`, `dependentSchemas`, active `if` / `then` / `else`,
|
|
1284
|
+
* `unevaluatedItems`, and `unevaluatedProperties` are rejected with an error identifying the unsupported keyword. Inactive
|
|
1285
|
+
* conditional keywords and `minContains` / `maxContains` without `contains` have no validation effect and are ignored.
|
|
1286
|
+
* - Objects and arrays used as `const` values or `enum` members are rejected. Only strings, numbers, booleans, and null
|
|
1287
|
+
* are supported.
|
|
1288
|
+
* - Intersections of overlapping unions are limited to disjoint root-type partitions and finite primitive `anyOf`
|
|
1289
|
+
* literal sets, which may also be duplicated across branches. Other union intersections, including cases that would
|
|
1290
|
+
* duplicate any other nested choice, are rejected.
|
|
1291
|
+
* - Unknown extension keywords are ignored and their semantics are not enforced.
|
|
1292
|
+
* - Only local references to top-level definitions in the form `#/$defs/<escaped-token>` are supported, optionally
|
|
1293
|
+
* followed by a pointer below the definition. A pointer target becomes a definition keyed by its escaped tokens, such
|
|
1294
|
+
* as `Name/properties/field`, and is rejected if a top-level definition already uses that key. Root references and
|
|
1295
|
+
* external references are rejected with the supported reference format. Missing definitions are reported by name.
|
|
1296
|
+
* References reached inside nested schema resources introduced by `$id` are rejected instead of resolved against the
|
|
1297
|
+
* top-level definitions.
|
|
1298
|
+
* - Imported constraints use built-in schemas and checks.
|
|
1299
|
+
* - Pattern constraints reached during translation cause an error by default. Use `patterns: "apply"` only for trusted
|
|
1300
|
+
* documents, or `patterns: "ignore"` to skip them. Ignoring patterns can both admit invalid values and reject valid
|
|
1301
|
+
* values when `oneOf` branches start overlapping.
|
|
1302
|
+
* - `onEnter` results replace the corresponding input nodes before translation.
|
|
1303
|
+
* - Callback results are used directly, and exceptions raised by a callback pass through unchanged.
|
|
1304
|
+
*
|
|
1305
|
+
* @see {@link fromJsonSchemaMultiDocument} for multiple roots sharing definitions
|
|
1306
|
+
* @see {@link toRepresentation} for converting the result to a representation document
|
|
1307
|
+
*
|
|
1308
|
+
* @stability stable
|
|
1309
|
+
* @category constructors
|
|
1310
|
+
* @since 4.0.0
|
|
1311
|
+
*/
|
|
1312
|
+
function fromJsonSchemaDocument(document, options) {
|
|
1313
|
+
return fromJsonSchemaDocument$1(document, options);
|
|
1314
|
+
}
|
|
1315
|
+
// ../../node_modules/.pnpm/@akterjs+cloud-api@file+..+akter-cloud+packages+cloud-api_effect@4.1.2_patch_hash=0e611_59e8fdba67d150970876667b4296bdf6/node_modules/@akterjs/cloud-api/src/operations/schema-unsupported.errors.ts
|
|
1316
|
+
var SchemaUnsupportedError = class extends TaggedError()("SchemaUnsupportedError", { message: String$1 }) {};
|
|
1317
|
+
// ../../node_modules/.pnpm/@akterjs+cloud-api@file+..+akter-cloud+packages+cloud-api_effect@4.1.2_patch_hash=0e611_59e8fdba67d150970876667b4296bdf6/node_modules/@akterjs/cloud-api/src/operations/operation-request.pure.ts
|
|
1318
|
+
const Definitions = Record(String$1, JsonObject);
|
|
1319
|
+
const imported = (document) => {
|
|
1320
|
+
return fromJsonSchemaDocument({
|
|
1321
|
+
definitions: pipe(get(document, "$defs"), flatMap$1(decodeUnknownOption(Definitions)), getOrElse(() => ({}))),
|
|
1322
|
+
dialect: "draft-2020-12",
|
|
1323
|
+
schema: remove(document, "$defs")
|
|
1324
|
+
}, { patterns: "apply" });
|
|
1325
|
+
};
|
|
1326
|
+
const schemaOf = (document) => try_({
|
|
1327
|
+
catch: (cause) => SchemaUnsupportedError.make({ message: String(cause) }),
|
|
1328
|
+
try: () => imported(document)
|
|
1329
|
+
}).pipe(map$1((schema) => make(schema.ast)));
|
|
1330
|
+
const jsonText = encodeOption(fromJsonString(Json));
|
|
1331
|
+
const textOf = (value) => {
|
|
1332
|
+
if (isString(value)) return value;
|
|
1333
|
+
return getOrElse(jsonText(value), () => "");
|
|
1334
|
+
};
|
|
1335
|
+
const valuesIn = (fields, input) => flatMap(fields, (field) => {
|
|
1336
|
+
const value = get(input, field.name);
|
|
1337
|
+
return toArray(map$2(value, (found) => [field.name, found]));
|
|
1338
|
+
});
|
|
1339
|
+
const fill = (template, [name, value]) => replace(`{${name}}`, globalThis.encodeURIComponent(textOf(value)))(template);
|
|
1340
|
+
const requestOf = ({ input, operation }) => {
|
|
1341
|
+
const placed = (place) => filter(operation.fields, (field) => field.in === place);
|
|
1342
|
+
const path = reduce(valuesIn(placed("path"), input), operation.path, fill);
|
|
1343
|
+
const queryValues = valuesIn(placed("query"), input);
|
|
1344
|
+
const query = fromEntries(map(queryValues, ([name, value]) => [name, textOf(value)]));
|
|
1345
|
+
const fields = fromEntries(valuesIn(placed("body"), input));
|
|
1346
|
+
const hasBody = isReadonlyArrayNonEmpty(placed("body"));
|
|
1347
|
+
return {
|
|
1348
|
+
body: match(head(placed("payload")), {
|
|
1349
|
+
onNone: () => filter$1(some(fields), () => hasBody),
|
|
1350
|
+
onSome: (field) => get(input, field.name)
|
|
1351
|
+
}),
|
|
1352
|
+
path,
|
|
1353
|
+
query
|
|
1354
|
+
};
|
|
1355
|
+
};
|
|
1356
|
+
// src/registry/operation-input.pure.ts
|
|
1357
|
+
const InputObject = fromJsonString(JsonObject);
|
|
1358
|
+
const invalid = (message) => CliExitError.make({
|
|
1359
|
+
code: CliExitError.codes.usage,
|
|
1360
|
+
message,
|
|
1361
|
+
reason: "InvalidInput"
|
|
1362
|
+
});
|
|
1363
|
+
const unsupported = (failure) => CliExitError.make({
|
|
1364
|
+
code: CliExitError.codes.failed,
|
|
1365
|
+
message: `This CLI can't read the API's schema: ${failure.message}`,
|
|
1366
|
+
reason: "SchemaUnsupported"
|
|
1367
|
+
});
|
|
1368
|
+
const checkedSchema = (document) => mapError(schemaOf(document), unsupported);
|
|
1369
|
+
const parseInput = (text) => decodeEffect(InputObject)(text).pipe(mapError(() => invalid("--input must be one JSON object.")));
|
|
1370
|
+
const targetOf = (operation) => (input) => pipe(filter(operation.fields, (field) => field.in === "path"), flatMap((field) => toArray(get(input, field.name).pipe(map$2((value) => `${field.name} ${textOf(value)}`)))), join(", "));
|
|
1371
|
+
const validInput = fnUntraced(function* validInput({ input, operation }) {
|
|
1372
|
+
const schema = yield* checkedSchema(operation.input);
|
|
1373
|
+
const command = join(operation.command, " ");
|
|
1374
|
+
yield* decodeEffect(schema)(input).pipe(mapError((failure) => invalid(`Invalid input for akter ${command}:\n${failure.message}`)));
|
|
1375
|
+
return {
|
|
1376
|
+
input,
|
|
1377
|
+
request: requestOf({
|
|
1378
|
+
input,
|
|
1379
|
+
operation
|
|
1380
|
+
})
|
|
1381
|
+
};
|
|
1382
|
+
});
|
|
1383
|
+
export { validInput as i, parseInput as n, targetOf as r, checkedSchema as t };
|