@smthrs/plan 0.0.0-stage → 1.0.0-rc.13
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/CHANGELOG.md +189 -0
- package/LICENSE +21 -0
- package/README.md +230 -2
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/dist/cjs/CachePolicy.d.ts +131 -0
- package/dist/cjs/CachePolicy.d.ts.map +1 -0
- package/dist/cjs/CachePolicy.js +50 -0
- package/dist/cjs/CachePolicy.js.map +7 -0
- package/dist/cjs/Effects.d.ts +258 -0
- package/dist/cjs/Effects.d.ts.map +1 -0
- package/dist/cjs/Effects.js +76 -0
- package/dist/cjs/Effects.js.map +7 -0
- package/dist/cjs/FileSet.d.ts +366 -0
- package/dist/cjs/FileSet.d.ts.map +1 -0
- package/dist/cjs/FileSet.js +196 -0
- package/dist/cjs/FileSet.js.map +7 -0
- package/dist/cjs/GraphBuildError.d.ts +120 -0
- package/dist/cjs/GraphBuildError.d.ts.map +1 -0
- package/dist/cjs/GraphBuildError.js +71 -0
- package/dist/cjs/GraphBuildError.js.map +7 -0
- package/dist/cjs/KeyMaterial.d.ts +107 -0
- package/dist/cjs/KeyMaterial.d.ts.map +1 -0
- package/dist/cjs/KeyMaterial.js +64 -0
- package/dist/cjs/KeyMaterial.js.map +7 -0
- package/dist/cjs/Node.d.ts +685 -0
- package/dist/cjs/Node.d.ts.map +1 -0
- package/dist/cjs/Node.js +230 -0
- package/dist/cjs/Node.js.map +7 -0
- package/dist/cjs/Placement.d.ts +117 -0
- package/dist/cjs/Placement.d.ts.map +1 -0
- package/dist/cjs/Placement.js +46 -0
- package/dist/cjs/Placement.js.map +7 -0
- package/dist/cjs/Plan.d.ts +489 -0
- package/dist/cjs/Plan.d.ts.map +1 -0
- package/dist/cjs/Plan.js +511 -0
- package/dist/cjs/Plan.js.map +7 -0
- package/dist/cjs/PlanDiff.d.ts +77 -0
- package/dist/cjs/PlanDiff.d.ts.map +1 -0
- package/dist/cjs/PlanDiff.js +149 -0
- package/dist/cjs/PlanDiff.js.map +7 -0
- package/dist/cjs/Planned.d.ts +121 -0
- package/dist/cjs/Planned.d.ts.map +1 -0
- package/dist/cjs/Planned.js +72 -0
- package/dist/cjs/Planned.js.map +7 -0
- package/dist/cjs/Repetition.d.ts +31 -0
- package/dist/cjs/Repetition.d.ts.map +1 -0
- package/dist/cjs/Repetition.js +36 -0
- package/dist/cjs/Repetition.js.map +7 -0
- package/dist/cjs/Scheduling.d.ts +89 -0
- package/dist/cjs/Scheduling.d.ts.map +1 -0
- package/dist/cjs/Scheduling.js +76 -0
- package/dist/cjs/Scheduling.js.map +7 -0
- package/dist/cjs/StepKey.d.ts +354 -0
- package/dist/cjs/StepKey.d.ts.map +1 -0
- package/dist/cjs/StepKey.js +313 -0
- package/dist/cjs/StepKey.js.map +7 -0
- package/dist/cjs/index.d.ts +91 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +59 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/ConflictAnnotation.d.ts +59 -0
- package/dist/cjs/internal/ConflictAnnotation.d.ts.map +1 -0
- package/dist/cjs/internal/ConflictAnnotation.js +247 -0
- package/dist/cjs/internal/ConflictAnnotation.js.map +7 -0
- package/dist/cjs/internal/EffectCandidates.d.ts +19 -0
- package/dist/cjs/internal/EffectCandidates.d.ts.map +1 -0
- package/dist/cjs/internal/EffectCandidates.js +92 -0
- package/dist/cjs/internal/EffectCandidates.js.map +7 -0
- package/dist/cjs/internal/JsonMirror.d.ts +34 -0
- package/dist/cjs/internal/JsonMirror.d.ts.map +1 -0
- package/dist/cjs/internal/JsonMirror.js +195 -0
- package/dist/cjs/internal/JsonMirror.js.map +7 -0
- package/dist/cjs/internal/SchemaIdentity.d.ts +140 -0
- package/dist/cjs/internal/SchemaIdentity.d.ts.map +1 -0
- package/dist/cjs/internal/SchemaIdentity.js +718 -0
- package/dist/cjs/internal/SchemaIdentity.js.map +7 -0
- package/dist/cjs/internal/effects.d.ts +245 -0
- package/dist/cjs/internal/effects.d.ts.map +1 -0
- package/dist/cjs/internal/effects.js +290 -0
- package/dist/cjs/internal/effects.js.map +7 -0
- package/dist/cjs/internal/node.d.ts +526 -0
- package/dist/cjs/internal/node.d.ts.map +1 -0
- package/dist/cjs/internal/node.js +313 -0
- package/dist/cjs/internal/node.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/PlanFixtures.d.ts +127 -0
- package/dist/cjs/test/PlanFixtures.d.ts.map +1 -0
- package/dist/cjs/test/PlanFixtures.js +59 -0
- package/dist/cjs/test/PlanFixtures.js.map +7 -0
- package/dist/esm/CachePolicy.d.ts +131 -0
- package/dist/esm/CachePolicy.d.ts.map +1 -0
- package/dist/esm/CachePolicy.js +117 -0
- package/dist/esm/CachePolicy.js.map +1 -0
- package/dist/esm/Effects.d.ts +258 -0
- package/dist/esm/Effects.d.ts.map +1 -0
- package/dist/esm/Effects.js +178 -0
- package/dist/esm/Effects.js.map +1 -0
- package/dist/esm/FileSet.d.ts +366 -0
- package/dist/esm/FileSet.d.ts.map +1 -0
- package/dist/esm/FileSet.js +398 -0
- package/dist/esm/FileSet.js.map +1 -0
- package/dist/esm/GraphBuildError.d.ts +120 -0
- package/dist/esm/GraphBuildError.d.ts.map +1 -0
- package/dist/esm/GraphBuildError.js +145 -0
- package/dist/esm/GraphBuildError.js.map +1 -0
- package/dist/esm/KeyMaterial.d.ts +107 -0
- package/dist/esm/KeyMaterial.d.ts.map +1 -0
- package/dist/esm/KeyMaterial.js +92 -0
- package/dist/esm/KeyMaterial.js.map +1 -0
- package/dist/esm/Node.d.ts +685 -0
- package/dist/esm/Node.d.ts.map +1 -0
- package/dist/esm/Node.js +591 -0
- package/dist/esm/Node.js.map +1 -0
- package/dist/esm/Placement.d.ts +117 -0
- package/dist/esm/Placement.d.ts.map +1 -0
- package/dist/esm/Placement.js +65 -0
- package/dist/esm/Placement.js.map +1 -0
- package/dist/esm/Plan.d.ts +489 -0
- package/dist/esm/Plan.d.ts.map +1 -0
- package/dist/esm/Plan.js +718 -0
- package/dist/esm/Plan.js.map +1 -0
- package/dist/esm/PlanDiff.d.ts +77 -0
- package/dist/esm/PlanDiff.d.ts.map +1 -0
- package/dist/esm/PlanDiff.js +205 -0
- package/dist/esm/PlanDiff.js.map +1 -0
- package/dist/esm/Planned.d.ts +121 -0
- package/dist/esm/Planned.d.ts.map +1 -0
- package/dist/esm/Planned.js +147 -0
- package/dist/esm/Planned.js.map +1 -0
- package/dist/esm/Repetition.d.ts +31 -0
- package/dist/esm/Repetition.d.ts.map +1 -0
- package/dist/esm/Repetition.js +24 -0
- package/dist/esm/Repetition.js.map +1 -0
- package/dist/esm/Scheduling.d.ts +89 -0
- package/dist/esm/Scheduling.d.ts.map +1 -0
- package/dist/esm/Scheduling.js +82 -0
- package/dist/esm/Scheduling.js.map +1 -0
- package/dist/esm/StepKey.d.ts +354 -0
- package/dist/esm/StepKey.d.ts.map +1 -0
- package/dist/esm/StepKey.js +503 -0
- package/dist/esm/StepKey.js.map +1 -0
- package/dist/esm/index.d.ts +91 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +91 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/ConflictAnnotation.d.ts +59 -0
- package/dist/esm/internal/ConflictAnnotation.d.ts.map +1 -0
- package/dist/esm/internal/ConflictAnnotation.js +332 -0
- package/dist/esm/internal/ConflictAnnotation.js.map +1 -0
- package/dist/esm/internal/EffectCandidates.d.ts +19 -0
- package/dist/esm/internal/EffectCandidates.d.ts.map +1 -0
- package/dist/esm/internal/EffectCandidates.js +86 -0
- package/dist/esm/internal/EffectCandidates.js.map +1 -0
- package/dist/esm/internal/JsonMirror.d.ts +34 -0
- package/dist/esm/internal/JsonMirror.d.ts.map +1 -0
- package/dist/esm/internal/JsonMirror.js +204 -0
- package/dist/esm/internal/JsonMirror.js.map +1 -0
- package/dist/esm/internal/SchemaIdentity.d.ts +140 -0
- package/dist/esm/internal/SchemaIdentity.d.ts.map +1 -0
- package/dist/esm/internal/SchemaIdentity.js +1002 -0
- package/dist/esm/internal/SchemaIdentity.js.map +1 -0
- package/dist/esm/internal/effects.d.ts +245 -0
- package/dist/esm/internal/effects.d.ts.map +1 -0
- package/dist/esm/internal/effects.js +459 -0
- package/dist/esm/internal/effects.js.map +1 -0
- package/dist/esm/internal/node.d.ts +526 -0
- package/dist/esm/internal/node.d.ts.map +1 -0
- package/dist/esm/internal/node.js +565 -0
- package/dist/esm/internal/node.js.map +1 -0
- package/dist/esm/test/PlanFixtures.d.ts +127 -0
- package/dist/esm/test/PlanFixtures.d.ts.map +1 -0
- package/dist/esm/test/PlanFixtures.js +60 -0
- package/dist/esm/test/PlanFixtures.js.map +1 -0
- package/docs/README.md +167 -0
- package/docs/api.md +1485 -0
- package/docs/concepts/authoring-ast.md +204 -0
- package/docs/concepts/effects-and-conflicts.md +135 -0
- package/docs/concepts/plan-value.md +168 -0
- package/docs/concepts/step-keys.md +179 -0
- package/docs/guides/author-a-node-graph.md +182 -0
- package/docs/guides/compile-a-plan.md +146 -0
- package/docs/guides/declare-file-effects.md +143 -0
- package/docs/guides/diff-two-plans.md +310 -0
- package/docs/installation.md +75 -0
- package/docs/quickstart.md +128 -0
- package/docs/testing.md +73 -0
- package/docs/troubleshooting.md +314 -0
- package/package.json +255 -3
- package/src/CachePolicy.ts +143 -0
- package/src/Effects.ts +302 -0
- package/src/FileSet.ts +493 -0
- package/src/GraphBuildError.ts +156 -0
- package/src/KeyMaterial.ts +111 -0
- package/src/Node.ts +974 -0
- package/src/Placement.ts +99 -0
- package/src/Plan.ts +911 -0
- package/src/PlanDiff.ts +244 -0
- package/src/Planned.ts +208 -0
- package/src/Repetition.ts +33 -0
- package/src/Scheduling.ts +154 -0
- package/src/StepKey.ts +736 -0
- package/src/index.ts +103 -0
- package/src/internal/ConflictAnnotation.ts +374 -0
- package/src/internal/EffectCandidates.ts +89 -0
- package/src/internal/JsonMirror.ts +255 -0
- package/src/internal/SchemaIdentity.ts +1096 -0
- package/src/internal/effects.ts +543 -0
- package/src/internal/node.ts +859 -0
- package/src/test/PlanFixtures.ts +76 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var SchemaIdentity_exports = {};
|
|
30
|
+
__export(SchemaIdentity_exports, {
|
|
31
|
+
SchemaIdentityError: () => SchemaIdentityError,
|
|
32
|
+
builtinCheckIds: () => builtinCheckIds,
|
|
33
|
+
fromRepresentation: () => fromRepresentation,
|
|
34
|
+
representationIdentity: () => representationIdentity,
|
|
35
|
+
schemaIdentity: () => schemaIdentity
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(SchemaIdentity_exports);
|
|
38
|
+
var Schema = __toESM(require("effect/Schema"), 1);
|
|
39
|
+
var SchemaRepresentation = __toESM(require("effect/SchemaRepresentation"), 1);
|
|
40
|
+
class SchemaIdentityError extends Schema.TaggedError()("@smthrs/plan/SchemaIdentityError", {
|
|
41
|
+
message: Schema.String
|
|
42
|
+
}) {
|
|
43
|
+
}
|
|
44
|
+
const invalid = (message, path) => new SchemaIdentityError({
|
|
45
|
+
message: path.length === 0 ? message : `${message}
|
|
46
|
+
at ${path.map((key) => `[${typeof key === "string" ? JSON.stringify(key) : key}]`).join("")}`
|
|
47
|
+
});
|
|
48
|
+
const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
+
const assignProperty = (target, key, value) => {
|
|
50
|
+
if (key === "__proto__") {
|
|
51
|
+
Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
|
|
52
|
+
} else {
|
|
53
|
+
target[key] = value;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const isJson = (value, path = /* @__PURE__ */ new Set()) => {
|
|
57
|
+
if (typeof value !== "object" || value === null) {
|
|
58
|
+
return value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
|
|
59
|
+
}
|
|
60
|
+
if (path.has(value)) return false;
|
|
61
|
+
const members = Array.isArray(value) ? Array.from(value) : plainValues(value);
|
|
62
|
+
if (members === void 0) return false;
|
|
63
|
+
const inner = new Set(path).add(value);
|
|
64
|
+
return members.every((member) => isJson(member, inner));
|
|
65
|
+
};
|
|
66
|
+
const plainValues = (value) => {
|
|
67
|
+
const prototype = Object.getPrototypeOf(value);
|
|
68
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null ? Object.values(value) : void 0;
|
|
69
|
+
};
|
|
70
|
+
const sameJson = (left, right) => {
|
|
71
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
72
|
+
return left.length === right.length && left.every((member, index) => sameJson(member, right[index]));
|
|
73
|
+
}
|
|
74
|
+
if (isObject(left) && isObject(right)) {
|
|
75
|
+
const keys = Object.keys(left);
|
|
76
|
+
return keys.length === Object.keys(right).length && keys.every((key) => Object.hasOwn(right, key) && sameJson(left[key], right[key]));
|
|
77
|
+
}
|
|
78
|
+
return left === right || left !== left && right !== right;
|
|
79
|
+
};
|
|
80
|
+
const escapeRegExp = (text) => text.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
81
|
+
const unescapeToken = (token) => token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
82
|
+
const definitionReference = (key) => `#/$defs/${encodeURI(key.replace(/~/g, "~0").replace(/\//g, "~1")).replace(/#/g, "%23")}`;
|
|
83
|
+
const decodeUriFragment = (fragment) => {
|
|
84
|
+
if (fragment.length === 0 || fragment === "#") return "";
|
|
85
|
+
if (!fragment.startsWith("#")) return void 0;
|
|
86
|
+
const encoded = fragment.slice(1);
|
|
87
|
+
try {
|
|
88
|
+
if (encodeURI(encoded).replace(/%25/g, "%").replace(/#/g, "%23") !== encoded) return void 0;
|
|
89
|
+
const pointer = decodeURIComponent(encoded);
|
|
90
|
+
return pointer.startsWith("/") && !/~(?:[^01]|$)/.test(pointer) ? pointer : void 0;
|
|
91
|
+
} catch {
|
|
92
|
+
return void 0;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const rewriteRefs = (node, rewrite) => {
|
|
96
|
+
const walk = (value) => isObject(value) ? rewriteRefs(value, rewrite) : value;
|
|
97
|
+
const out = {};
|
|
98
|
+
for (const key of Object.keys(node)) {
|
|
99
|
+
const value = node[key];
|
|
100
|
+
let transformed = value;
|
|
101
|
+
switch (key) {
|
|
102
|
+
case "$defs":
|
|
103
|
+
case "properties":
|
|
104
|
+
case "patternProperties":
|
|
105
|
+
case "dependentSchemas":
|
|
106
|
+
if (isObject(value)) {
|
|
107
|
+
const mapped = {};
|
|
108
|
+
for (const name of Object.keys(value)) assignProperty(mapped, name, walk(value[name]));
|
|
109
|
+
transformed = mapped;
|
|
110
|
+
}
|
|
111
|
+
break;
|
|
112
|
+
case "allOf":
|
|
113
|
+
case "anyOf":
|
|
114
|
+
case "oneOf":
|
|
115
|
+
case "prefixItems":
|
|
116
|
+
if (Array.isArray(value)) transformed = value.map(walk);
|
|
117
|
+
break;
|
|
118
|
+
case "not":
|
|
119
|
+
case "additionalProperties":
|
|
120
|
+
case "propertyNames":
|
|
121
|
+
case "unevaluatedProperties":
|
|
122
|
+
case "items":
|
|
123
|
+
case "contains":
|
|
124
|
+
case "unevaluatedItems":
|
|
125
|
+
case "if":
|
|
126
|
+
case "then":
|
|
127
|
+
case "else":
|
|
128
|
+
case "contentSchema":
|
|
129
|
+
transformed = walk(value);
|
|
130
|
+
}
|
|
131
|
+
assignProperty(out, key, transformed);
|
|
132
|
+
}
|
|
133
|
+
if (typeof out["$ref"] === "string") out["$ref"] = rewrite(out["$ref"]);
|
|
134
|
+
if (typeof out["$dynamicRef"] === "string") out["$dynamicRef"] = rewrite(out["$dynamicRef"]);
|
|
135
|
+
return out;
|
|
136
|
+
};
|
|
137
|
+
const ordinaryAnnotations = (annotations) => {
|
|
138
|
+
if (annotations === void 0) return void 0;
|
|
139
|
+
const out = {};
|
|
140
|
+
if (typeof annotations["title"] === "string") out["title"] = annotations["title"];
|
|
141
|
+
if (typeof annotations["description"] === "string") out["description"] = annotations["description"];
|
|
142
|
+
if (isJson(annotations["default"])) out["default"] = annotations["default"];
|
|
143
|
+
if (Array.isArray(annotations["examples"]) && isJson(annotations["examples"])) {
|
|
144
|
+
out["examples"] = annotations["examples"];
|
|
145
|
+
}
|
|
146
|
+
if (typeof annotations["readOnly"] === "boolean") out["readOnly"] = annotations["readOnly"];
|
|
147
|
+
if (typeof annotations["writeOnly"] === "boolean") out["writeOnly"] = annotations["writeOnly"];
|
|
148
|
+
if (typeof annotations["format"] === "string") out["format"] = annotations["format"];
|
|
149
|
+
if (typeof annotations["contentEncoding"] === "string") out["contentEncoding"] = annotations["contentEncoding"];
|
|
150
|
+
if (typeof annotations["contentMediaType"] === "string") out["contentMediaType"] = annotations["contentMediaType"];
|
|
151
|
+
if (isJson(annotations["contentSchema"])) out["contentSchema"] = annotations["contentSchema"];
|
|
152
|
+
return Object.keys(out).length === 0 ? void 0 : out;
|
|
153
|
+
};
|
|
154
|
+
const finitePattern = "[+-]?\\d*\\.?\\d+(?:[Ee][+-]?\\d+)?";
|
|
155
|
+
const stringPattern = "[\\s\\S]*?";
|
|
156
|
+
const bigIntPattern = "^-?\\d+$";
|
|
157
|
+
const symbolPattern = "^Symbol\\(([\\s\\S]*)\\)$";
|
|
158
|
+
const uuidPattern = (version) => version === null ? "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|[fF]{8}-[fF]{4}-[fF]{4}-[fF]{4}-[fF]{12})$" : `^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`;
|
|
159
|
+
const field = (id, payload, name, is) => {
|
|
160
|
+
const value = isObject(payload) ? payload[name] : void 0;
|
|
161
|
+
if (!is(value)) {
|
|
162
|
+
throw new SchemaIdentityError({
|
|
163
|
+
message: `Cannot derive a schema identity: check ${id} carries no usable "${name}" in its payload. The installed effect release describes this check differently from the releases @smthrs/plan supports.`
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return value;
|
|
167
|
+
};
|
|
168
|
+
const isNumber = (value) => typeof value === "number";
|
|
169
|
+
const isString = (value) => typeof value === "string";
|
|
170
|
+
const isVersion = (value) => value === null || typeof value === "number";
|
|
171
|
+
const isFlag = (value) => value === void 0 || typeof value === "boolean";
|
|
172
|
+
const pattern = (source) => () => ({ pattern: source });
|
|
173
|
+
const literalPattern = (name, source) => (id, payload) => ({
|
|
174
|
+
pattern: new RegExp(source(escapeRegExp(field(id, payload, name, isString)))).source
|
|
175
|
+
});
|
|
176
|
+
const bound = (keyword, name = keyword) => (id, payload) => ({
|
|
177
|
+
[keyword]: field(id, payload, name, isNumber)
|
|
178
|
+
});
|
|
179
|
+
const length = (name, array, string) => (id, payload, input) => ({
|
|
180
|
+
[input.type === "array" ? array : string]: field(id, payload, name, isNumber)
|
|
181
|
+
});
|
|
182
|
+
const empty = () => ({});
|
|
183
|
+
const builtinChecks = /* @__PURE__ */ new Map([
|
|
184
|
+
["effect/schema/isTrimmed", pattern("^\\S[\\s\\S]*\\S$|^\\S$|^$")],
|
|
185
|
+
["effect/schema/isPattern", (id, payload) => ({ pattern: field(id, payload, "source", isString) })],
|
|
186
|
+
["effect/schema/isStringFinite", pattern(`^${finitePattern}$`)],
|
|
187
|
+
["effect/schema/isStringBigInt", pattern(bigIntPattern)],
|
|
188
|
+
["effect/schema/isStringSymbol", pattern(symbolPattern)],
|
|
189
|
+
["effect/schema/isUUID", (id, payload) => ({
|
|
190
|
+
pattern: uuidPattern(field(id, payload, "version", isVersion)),
|
|
191
|
+
format: "uuid"
|
|
192
|
+
})],
|
|
193
|
+
["effect/schema/isGUID", pattern("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$")],
|
|
194
|
+
["effect/schema/isULID", pattern("^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$")],
|
|
195
|
+
["effect/schema/isBase64", pattern("^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$")],
|
|
196
|
+
["effect/schema/isBase64Url", pattern("^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$")],
|
|
197
|
+
["effect/schema/isStartingWith", literalPattern("startsWith", (escaped) => `^${escaped}`)],
|
|
198
|
+
["effect/schema/isEndingWith", literalPattern("endsWith", (escaped) => `${escaped}$`)],
|
|
199
|
+
["effect/schema/isIncluding", literalPattern("includes", (escaped) => escaped)],
|
|
200
|
+
["effect/schema/isUppercased", pattern("^[^a-z]*$")],
|
|
201
|
+
["effect/schema/isLowercased", pattern("^[^A-Z]*$")],
|
|
202
|
+
["effect/schema/isCapitalized", pattern("^(?:[^a-z][\\s\\S]*)?$")],
|
|
203
|
+
["effect/schema/isUncapitalized", pattern("^(?:[^A-Z][\\s\\S]*)?$")],
|
|
204
|
+
["effect/schema/isFinite", () => ({ type: "number" })],
|
|
205
|
+
["effect/schema/isInt", () => ({ type: "integer" })],
|
|
206
|
+
["effect/schema/isGreaterThan", bound("exclusiveMinimum")],
|
|
207
|
+
["effect/schema/isGreaterThanOrEqualTo", bound("minimum")],
|
|
208
|
+
["effect/schema/isLessThan", bound("exclusiveMaximum")],
|
|
209
|
+
["effect/schema/isLessThanOrEqualTo", bound("maximum")],
|
|
210
|
+
["effect/schema/isBetween", (id, payload) => ({
|
|
211
|
+
[field(id, payload, "exclusiveMinimum", isFlag) ? "exclusiveMinimum" : "minimum"]: field(
|
|
212
|
+
id,
|
|
213
|
+
payload,
|
|
214
|
+
"minimum",
|
|
215
|
+
isNumber
|
|
216
|
+
),
|
|
217
|
+
[field(id, payload, "exclusiveMaximum", isFlag) ? "exclusiveMaximum" : "maximum"]: field(
|
|
218
|
+
id,
|
|
219
|
+
payload,
|
|
220
|
+
"maximum",
|
|
221
|
+
isNumber
|
|
222
|
+
)
|
|
223
|
+
})],
|
|
224
|
+
["effect/schema/isMultipleOf", bound("multipleOf", "divisor")],
|
|
225
|
+
["effect/schema/isGreaterThanDate", empty],
|
|
226
|
+
["effect/schema/isGreaterThanOrEqualToDate", empty],
|
|
227
|
+
["effect/schema/isLessThanDate", empty],
|
|
228
|
+
["effect/schema/isLessThanOrEqualToDate", empty],
|
|
229
|
+
["effect/schema/isBetweenDate", empty],
|
|
230
|
+
["effect/schema/isGreaterThanBigInt", empty],
|
|
231
|
+
["effect/schema/isGreaterThanOrEqualToBigInt", empty],
|
|
232
|
+
["effect/schema/isLessThanBigInt", empty],
|
|
233
|
+
["effect/schema/isLessThanOrEqualToBigInt", empty],
|
|
234
|
+
["effect/schema/isBetweenBigInt", empty],
|
|
235
|
+
["effect/schema/isMinLength", length("minLength", "minItems", "minLength")],
|
|
236
|
+
["effect/schema/isMaxLength", length("maxLength", "maxItems", "maxLength")],
|
|
237
|
+
["effect/schema/isBetweenLength", (id, payload, input) => {
|
|
238
|
+
const minimum = field(id, payload, "minimum", isNumber);
|
|
239
|
+
const maximum = field(id, payload, "maximum", isNumber);
|
|
240
|
+
return input.type === "array" ? { allOf: [{ minItems: minimum }, { maxItems: maximum }] } : { allOf: [{ minLength: minimum }, { maxLength: maximum }] };
|
|
241
|
+
}],
|
|
242
|
+
["effect/schema/isMinCodePoints", bound("minLength", "minCodePoints")],
|
|
243
|
+
["effect/schema/isMaxCodePoints", bound("maxLength", "maxCodePoints")],
|
|
244
|
+
["effect/schema/isBetweenCodePoints", (id, payload) => ({
|
|
245
|
+
allOf: [
|
|
246
|
+
{ minLength: field(id, payload, "minimum", isNumber) },
|
|
247
|
+
{ maxLength: field(id, payload, "maximum", isNumber) }
|
|
248
|
+
]
|
|
249
|
+
})],
|
|
250
|
+
["effect/schema/isMinSize", empty],
|
|
251
|
+
["effect/schema/isMaxSize", empty],
|
|
252
|
+
["effect/schema/isBetweenSize", empty],
|
|
253
|
+
["effect/schema/isMinProperties", bound("minProperties")],
|
|
254
|
+
["effect/schema/isMaxProperties", bound("maxProperties")],
|
|
255
|
+
["effect/schema/isBetweenProperties", (id, payload) => ({
|
|
256
|
+
minProperties: field(id, payload, "minimum", isNumber),
|
|
257
|
+
maxProperties: field(id, payload, "maximum", isNumber)
|
|
258
|
+
})],
|
|
259
|
+
["effect/schema/isPropertyNames", (_id, _payload, input) => ({ propertyNames: input.schemas[0] })],
|
|
260
|
+
["effect/schema/isUnique", () => ({ uniqueItems: true })],
|
|
261
|
+
["effect/schema/isUniqueKey", null]
|
|
262
|
+
]);
|
|
263
|
+
const builtinCheckIds = [...builtinChecks.keys()];
|
|
264
|
+
const isCheckCallback = (value) => typeof value === "function";
|
|
265
|
+
const isApproximate = (output) => Array.isArray(output);
|
|
266
|
+
const fragmentSource = (check) => {
|
|
267
|
+
const representation = check.representation;
|
|
268
|
+
const builtin = representation === void 0 ? void 0 : builtinChecks.get(representation.id);
|
|
269
|
+
if (representation !== void 0 && builtin !== void 0) {
|
|
270
|
+
return builtin === null ? void 0 : (input) => builtin(representation.id, representation.payload, input);
|
|
271
|
+
}
|
|
272
|
+
const callback = check.annotations?.["toJsonSchema"];
|
|
273
|
+
if (!isCheckCallback(callback)) return void 0;
|
|
274
|
+
return (input) => {
|
|
275
|
+
const output = callback(input);
|
|
276
|
+
return isApproximate(output) ? output[0] : output;
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
const extractNumberType = (schema) => {
|
|
280
|
+
let type = schema["type"] === "number" || schema["type"] === "integer" ? schema["type"] : void 0;
|
|
281
|
+
let out = schema;
|
|
282
|
+
if (type !== void 0) {
|
|
283
|
+
out = { ...schema };
|
|
284
|
+
delete out["type"];
|
|
285
|
+
}
|
|
286
|
+
const allOf = out["allOf"];
|
|
287
|
+
if (Array.isArray(allOf)) {
|
|
288
|
+
const members = [];
|
|
289
|
+
let changed = false;
|
|
290
|
+
for (const member of allOf) {
|
|
291
|
+
const extracted = extractNumberType(member);
|
|
292
|
+
if (extracted.type !== void 0) {
|
|
293
|
+
changed = true;
|
|
294
|
+
if (type === void 0 || extracted.type === "integer") type = extracted.type;
|
|
295
|
+
}
|
|
296
|
+
if (Object.keys(extracted.schema).length > 0) members.push(extracted.schema);
|
|
297
|
+
}
|
|
298
|
+
if (changed) {
|
|
299
|
+
const { allOf: _, ...rest } = out;
|
|
300
|
+
out = members.length === 0 ? rest : { ...rest, allOf: members };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return { type, schema: out };
|
|
304
|
+
};
|
|
305
|
+
const isNumberEncoding = (schema) => {
|
|
306
|
+
const anyOf = schema["anyOf"];
|
|
307
|
+
if (!Array.isArray(anyOf) || anyOf.length !== 2 || !isObject(anyOf[0]) || anyOf[0]["type"] !== "number") return false;
|
|
308
|
+
const special = anyOf[1];
|
|
309
|
+
if (!isObject(special) || special["type"] !== "string") return false;
|
|
310
|
+
const values = special["enum"];
|
|
311
|
+
return Array.isArray(values) && values.length === 3 && values.includes("NaN") && values.includes("Infinity") && values.includes("-Infinity");
|
|
312
|
+
};
|
|
313
|
+
const inlineableCheckKeywords = "|type|format|pattern|multipleOf|minimum|maximum|exclusiveMinimum|exclusiveMaximum|minLength|maxLength|minItems|maxItems|uniqueItems|minProperties|maxProperties|propertyNames|";
|
|
314
|
+
const promotableAnnotationKeywords = "|title|description|default|examples|readOnly|writeOnly|";
|
|
315
|
+
const inlineableAnnotatedCheckKeywords = inlineableCheckKeywords + promotableAnnotationKeywords;
|
|
316
|
+
const hasOnlyKeywords = (schema, allowed) => Object.keys(schema).every((key) => allowed.includes(`|${key}|`));
|
|
317
|
+
const hasNoCollisions = (left, rightKeys) => typeof left["$ref"] !== "string" && rightKeys.every((key) => !Object.hasOwn(left, key));
|
|
318
|
+
const appendJsonSchema = (left, right, inlineCheck) => {
|
|
319
|
+
if (Object.keys(left).length === 0) return right;
|
|
320
|
+
const rightKeys = Object.keys(right);
|
|
321
|
+
if (rightKeys.length === 0) return left;
|
|
322
|
+
const leftType = left["type"] === "number" || left["type"] === "integer" ? left["type"] : void 0;
|
|
323
|
+
const numberEncoding = isNumberEncoding(left);
|
|
324
|
+
if (leftType !== void 0 || numberEncoding) {
|
|
325
|
+
const extracted = extractNumberType(right);
|
|
326
|
+
if (extracted.type !== void 0) {
|
|
327
|
+
const type = leftType === "integer" || extracted.type === "integer" ? "integer" : "number";
|
|
328
|
+
const base = { ...left, type };
|
|
329
|
+
if (numberEncoding) delete base["anyOf"];
|
|
330
|
+
const extractedKeys = Object.keys(extracted.schema);
|
|
331
|
+
if (extractedKeys.length === 0) return base;
|
|
332
|
+
return hasOnlyKeywords(extracted.schema, promotableAnnotationKeywords) && hasNoCollisions(base, extractedKeys) ? { ...base, ...extracted.schema } : appendJsonSchema(base, extracted.schema, inlineCheck);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (inlineCheck && hasNoCollisions(left, rightKeys)) return { ...left, ...right };
|
|
336
|
+
const rightAllOf = right["allOf"];
|
|
337
|
+
const members = Array.isArray(rightAllOf) && rightKeys.length === 1 ? rightAllOf : [right];
|
|
338
|
+
const leftAllOf = left["allOf"];
|
|
339
|
+
if (Array.isArray(leftAllOf)) return { ...left, allOf: [...leftAllOf, ...members] };
|
|
340
|
+
if (typeof left["$ref"] === "string") return { allOf: [left, ...members] };
|
|
341
|
+
return { ...left, allOf: members };
|
|
342
|
+
};
|
|
343
|
+
const jsonSchemaTypes = /* @__PURE__ */ new Set([
|
|
344
|
+
"string",
|
|
345
|
+
"number",
|
|
346
|
+
"boolean",
|
|
347
|
+
"array",
|
|
348
|
+
"object",
|
|
349
|
+
"null",
|
|
350
|
+
"integer"
|
|
351
|
+
]);
|
|
352
|
+
const isJsonSchemaType = (input) => jsonSchemaTypes.has(input);
|
|
353
|
+
const compactEnums = (schemas) => {
|
|
354
|
+
let sharedType = void 0;
|
|
355
|
+
const values = [];
|
|
356
|
+
for (const schema of schemas) {
|
|
357
|
+
const members = schema["enum"];
|
|
358
|
+
if (Object.keys(schema).length !== 2 || schema["type"] === void 0 || !Array.isArray(members) || members.length === 0) {
|
|
359
|
+
return void 0;
|
|
360
|
+
}
|
|
361
|
+
if (sharedType === void 0) sharedType = schema["type"];
|
|
362
|
+
else if (schema["type"] !== sharedType) return void 0;
|
|
363
|
+
for (const value of members) {
|
|
364
|
+
if (values.includes(value)) return void 0;
|
|
365
|
+
values.push(value);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return { type: sharedType, enum: values };
|
|
369
|
+
};
|
|
370
|
+
const partPattern = (part) => {
|
|
371
|
+
switch (part._tag) {
|
|
372
|
+
case "Literal":
|
|
373
|
+
return escapeRegExp(String(part.literal));
|
|
374
|
+
case "String":
|
|
375
|
+
return stringPattern;
|
|
376
|
+
case "Number":
|
|
377
|
+
return finitePattern;
|
|
378
|
+
case "TemplateLiteral":
|
|
379
|
+
return part.parts.map(partPattern).join("");
|
|
380
|
+
case "Union":
|
|
381
|
+
return `(?:${part.types.map(partPattern).join("|")})`;
|
|
382
|
+
default:
|
|
383
|
+
throw invalid("Invalid schema representation document", []);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
const neverSchema = { not: {} };
|
|
387
|
+
const unsupported = (representation, path) => {
|
|
388
|
+
throw invalid(`Unsupported schema representation ${representation._tag}`, path);
|
|
389
|
+
};
|
|
390
|
+
const fromRepresentation = (document, options) => {
|
|
391
|
+
const closed = options?.onExcessProperty === "error";
|
|
392
|
+
const references = document.references;
|
|
393
|
+
const definitionStates = /* @__PURE__ */ new Map();
|
|
394
|
+
const compiledRepresentations = /* @__PURE__ */ new WeakMap();
|
|
395
|
+
const fallbackDefinitions = /* @__PURE__ */ new Map();
|
|
396
|
+
const compileDefinition = (key, path) => {
|
|
397
|
+
const compiled = definitionStates.get(key);
|
|
398
|
+
if (compiled !== void 0) return typeof compiled === "string" ? compiled : key;
|
|
399
|
+
const representation = Object.hasOwn(references, key) ? references[key] : void 0;
|
|
400
|
+
if (representation === void 0) throw invalid(`Invalid reference ${key}`, [...path, "$ref"]);
|
|
401
|
+
definitionStates.set(key, null);
|
|
402
|
+
const schema2 = recur(representation, ["references", key]);
|
|
403
|
+
const fallback = identifierFallback(representation);
|
|
404
|
+
if (fallback !== void 0) {
|
|
405
|
+
const candidates = fallbackDefinitions.get(fallback);
|
|
406
|
+
const match = candidates?.find((candidate) => sameJson(definitionStates.get(candidate), schema2));
|
|
407
|
+
if (match === void 0) {
|
|
408
|
+
if (candidates === void 0) fallbackDefinitions.set(fallback, [key]);
|
|
409
|
+
else candidates.push(key);
|
|
410
|
+
} else {
|
|
411
|
+
definitionStates.set(key, match);
|
|
412
|
+
return match;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
definitionStates.set(key, schema2);
|
|
416
|
+
return key;
|
|
417
|
+
};
|
|
418
|
+
const finalize = (schema2) => rewriteRefs(schema2, (reference) => {
|
|
419
|
+
const pointer = decodeUriFragment(reference);
|
|
420
|
+
if (pointer === void 0) {
|
|
421
|
+
if (/^#(?:\/|%2f)/i.test(reference)) {
|
|
422
|
+
throw new SchemaIdentityError({ message: `Invalid JSON Pointer URI fragment ${JSON.stringify(reference)}` });
|
|
423
|
+
}
|
|
424
|
+
return reference;
|
|
425
|
+
}
|
|
426
|
+
if (!pointer.startsWith("/$defs/")) return reference;
|
|
427
|
+
const separator = pointer.indexOf("/", 7);
|
|
428
|
+
const canonical = definitionStates.get(unescapeToken(pointer.slice(7, separator < 0 ? void 0 : separator)));
|
|
429
|
+
if (typeof canonical !== "string") return reference;
|
|
430
|
+
return reference.replace(/^#(?:\/|%2f).*?(?:\/|%2f).*?(?=\/|%2f|$)/i, definitionReference(canonical));
|
|
431
|
+
});
|
|
432
|
+
const identifierFallback = (representation) => {
|
|
433
|
+
if (representation._tag === "Reference") return void 0;
|
|
434
|
+
const last = representation.checks.at(-1);
|
|
435
|
+
const annotations = last === void 0 ? representation.annotations : last.annotations;
|
|
436
|
+
const fallback = annotations?.["~identifier"];
|
|
437
|
+
return typeof annotations?.["identifier"] !== "string" && typeof fallback === "string" ? fallback : void 0;
|
|
438
|
+
};
|
|
439
|
+
const compileCheck = (check, type, path) => {
|
|
440
|
+
const source = fragmentSource(check);
|
|
441
|
+
if (source !== void 0) {
|
|
442
|
+
const schemas = check.representation?.schemas?.map(
|
|
443
|
+
(schema3, index) => recur(schema3, [...path, "representation", "schemas", index])
|
|
444
|
+
) ?? [];
|
|
445
|
+
const fragment = source({ type, schemas });
|
|
446
|
+
const ordinary2 = ordinaryAnnotations(check.annotations);
|
|
447
|
+
const schema2 = ordinary2 === void 0 ? fragment : { ...fragment, ...ordinary2 };
|
|
448
|
+
const allowed = ordinary2 === void 0 ? inlineableCheckKeywords : inlineableAnnotatedCheckKeywords;
|
|
449
|
+
return check._tag === "Filter" && hasOnlyKeywords(schema2, allowed) && (ordinary2 === void 0 || hasOnlyKeywords(ordinary2, promotableAnnotationKeywords)) ? [schema2, true] : [schema2];
|
|
450
|
+
}
|
|
451
|
+
if (check._tag === "Filter") return void 0;
|
|
452
|
+
const allOf = [];
|
|
453
|
+
check.checks.forEach((child, index) => {
|
|
454
|
+
const compiled = compileCheck(child, type, [...path, "checks", index]);
|
|
455
|
+
if (compiled !== void 0) allOf.push(compiled[0]);
|
|
456
|
+
});
|
|
457
|
+
if (allOf.length === 0) return void 0;
|
|
458
|
+
const ordinary = ordinaryAnnotations(check.annotations);
|
|
459
|
+
return [ordinary === void 0 ? { allOf } : { allOf, ...ordinary }];
|
|
460
|
+
};
|
|
461
|
+
const recur = (representation, path) => {
|
|
462
|
+
if (representation._tag === "Reference") {
|
|
463
|
+
return { $ref: definitionReference(compileDefinition(representation.$ref, path)) };
|
|
464
|
+
}
|
|
465
|
+
const cached = compiledRepresentations.get(representation);
|
|
466
|
+
if (cached !== void 0) return cached;
|
|
467
|
+
let output = on(representation, path);
|
|
468
|
+
const ordinary = ordinaryAnnotations(representation.annotations);
|
|
469
|
+
if (ordinary !== void 0) output = { ...output, ...ordinary };
|
|
470
|
+
representation.checks.forEach((check, index) => {
|
|
471
|
+
const compiled = compileCheck(
|
|
472
|
+
check,
|
|
473
|
+
isJsonSchemaType(output["type"]) ? output["type"] : void 0,
|
|
474
|
+
[...path, "checks", index]
|
|
475
|
+
);
|
|
476
|
+
if (compiled !== void 0) output = appendJsonSchema(output, ...compiled);
|
|
477
|
+
});
|
|
478
|
+
compiledRepresentations.set(representation, output);
|
|
479
|
+
return output;
|
|
480
|
+
};
|
|
481
|
+
const annotated = (compiled, annotations) => {
|
|
482
|
+
const ordinary = ordinaryAnnotations(annotations);
|
|
483
|
+
return ordinary === void 0 ? compiled : appendJsonSchema(compiled, ordinary);
|
|
484
|
+
};
|
|
485
|
+
const on = (representation, path) => {
|
|
486
|
+
switch (representation._tag) {
|
|
487
|
+
case "Any":
|
|
488
|
+
case "Unknown":
|
|
489
|
+
case "Declaration":
|
|
490
|
+
return {};
|
|
491
|
+
case "ObjectKeyword":
|
|
492
|
+
return { anyOf: [{ type: "object" }, { type: "array" }] };
|
|
493
|
+
case "Void":
|
|
494
|
+
case "Undefined":
|
|
495
|
+
case "Null":
|
|
496
|
+
return { type: "null" };
|
|
497
|
+
case "BigInt":
|
|
498
|
+
return { type: "string", allOf: [{ pattern: bigIntPattern }] };
|
|
499
|
+
case "Symbol":
|
|
500
|
+
return { type: "string", allOf: [{ pattern: symbolPattern }] };
|
|
501
|
+
case "UniqueSymbol":
|
|
502
|
+
return Symbol.keyFor(representation.symbol) === void 0 ? { not: {} } : { type: "string", enum: [String(representation.symbol)] };
|
|
503
|
+
case "Suspend":
|
|
504
|
+
return recur(representation.thunk, [...path, "thunk"]);
|
|
505
|
+
case "Never":
|
|
506
|
+
return { not: {} };
|
|
507
|
+
case "String":
|
|
508
|
+
return { type: "string" };
|
|
509
|
+
case "Number":
|
|
510
|
+
return { anyOf: [{ type: "number" }, { type: "string", enum: ["NaN", "Infinity", "-Infinity"] }] };
|
|
511
|
+
case "Boolean":
|
|
512
|
+
return { type: "boolean" };
|
|
513
|
+
case "Literal": {
|
|
514
|
+
const literal = representation.literal;
|
|
515
|
+
return typeof literal === "bigint" ? { type: "string", enum: [String(literal)] } : { type: typeof literal, enum: [literal] };
|
|
516
|
+
}
|
|
517
|
+
case "Enum": {
|
|
518
|
+
const types = representation.enums.map(([title, literal], index) => {
|
|
519
|
+
if (typeof literal === "number" && !Number.isFinite(literal)) {
|
|
520
|
+
throw invalid(`Invalid numeric enum value ${String(literal)}`, [...path, "enums", index, 1]);
|
|
521
|
+
}
|
|
522
|
+
return { type: typeof literal, enum: [literal], title };
|
|
523
|
+
});
|
|
524
|
+
return types.length === 0 ? { not: {} } : { anyOf: types };
|
|
525
|
+
}
|
|
526
|
+
case "TemplateLiteral":
|
|
527
|
+
return { type: "string", pattern: `^${representation.parts.map(partPattern).join("")}$` };
|
|
528
|
+
case "Arrays": {
|
|
529
|
+
const rest = representation.rest[0];
|
|
530
|
+
if (representation.rest.length > 1) {
|
|
531
|
+
throw invalid("Invalid schema representation document", [...path, "rest"]);
|
|
532
|
+
}
|
|
533
|
+
const out = { type: "array" };
|
|
534
|
+
let minItems = representation.elements.length;
|
|
535
|
+
const prefixItems = representation.elements.map((element, index) => {
|
|
536
|
+
if (element.isOptional) minItems--;
|
|
537
|
+
return annotated(recur(element.type, [...path, "elements", index, "type"]), element.annotations);
|
|
538
|
+
});
|
|
539
|
+
if (prefixItems.length > 0) {
|
|
540
|
+
out["prefixItems"] = prefixItems;
|
|
541
|
+
out["maxItems"] = representation.elements.length;
|
|
542
|
+
if (minItems > 0) out["minItems"] = minItems;
|
|
543
|
+
} else {
|
|
544
|
+
out["items"] = false;
|
|
545
|
+
}
|
|
546
|
+
if (rest !== void 0) {
|
|
547
|
+
delete out["maxItems"];
|
|
548
|
+
const items = recur(rest, [...path, "rest", 0]);
|
|
549
|
+
if (Object.keys(items).length > 0) out["items"] = items;
|
|
550
|
+
else delete out["items"];
|
|
551
|
+
}
|
|
552
|
+
return out;
|
|
553
|
+
}
|
|
554
|
+
case "Objects": {
|
|
555
|
+
if (representation.propertySignatures.length === 0 && representation.indexSignatures.length === 0) {
|
|
556
|
+
return { not: { type: "null" } };
|
|
557
|
+
}
|
|
558
|
+
const out = { type: "object" };
|
|
559
|
+
const properties = {};
|
|
560
|
+
const required = [];
|
|
561
|
+
representation.propertySignatures.forEach((property, index) => {
|
|
562
|
+
const name = property.name;
|
|
563
|
+
if (typeof name !== "string") {
|
|
564
|
+
throw invalid("Invalid schema representation document", [...path, "propertySignatures", index, "name"]);
|
|
565
|
+
}
|
|
566
|
+
assignProperty(
|
|
567
|
+
properties,
|
|
568
|
+
name,
|
|
569
|
+
annotated(recur(property.type, [...path, "propertySignatures", index, "type"]), property.annotations)
|
|
570
|
+
);
|
|
571
|
+
if (!property.isOptional) required.push(name);
|
|
572
|
+
});
|
|
573
|
+
if (representation.propertySignatures.length > 0) out["properties"] = properties;
|
|
574
|
+
if (required.length > 0) out["required"] = required;
|
|
575
|
+
const patternProperties = {};
|
|
576
|
+
const additionalPropertySchemas = [];
|
|
577
|
+
const indexValueSchemas = [];
|
|
578
|
+
let hasUnrepresentableIndexPattern = false;
|
|
579
|
+
representation.indexSignatures.forEach((signature, index) => {
|
|
580
|
+
const compiled = recur(signature.type, [...path, "indexSignatures", index, "type"]);
|
|
581
|
+
const type = sameJson(compiled, neverSchema) ? false : compiled;
|
|
582
|
+
indexValueSchemas.push(type);
|
|
583
|
+
const patterns = parameterPatterns(
|
|
584
|
+
signature.parameter,
|
|
585
|
+
[...path, "indexSignatures", index, "parameter"],
|
|
586
|
+
/* @__PURE__ */ new Set()
|
|
587
|
+
);
|
|
588
|
+
if (patterns === void 0) {
|
|
589
|
+
hasUnrepresentableIndexPattern = true;
|
|
590
|
+
} else if (patterns.length === 0) {
|
|
591
|
+
additionalPropertySchemas.push(type);
|
|
592
|
+
} else {
|
|
593
|
+
for (const key of patterns) {
|
|
594
|
+
const previous = Object.hasOwn(patternProperties, key) ? patternProperties[key] : void 0;
|
|
595
|
+
assignProperty(
|
|
596
|
+
patternProperties,
|
|
597
|
+
key,
|
|
598
|
+
previous === void 0 ? type : previous === false || type === false ? false : appendJsonSchema(previous, type)
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
const hasPatternProperties = Object.keys(patternProperties).length > 0;
|
|
604
|
+
if (hasPatternProperties) out["patternProperties"] = patternProperties;
|
|
605
|
+
const additional = additionalPropertySchemas.map((type) => ({ type: "object", additionalProperties: type }));
|
|
606
|
+
if (hasUnrepresentableIndexPattern && closed) {
|
|
607
|
+
const propertyNames = [];
|
|
608
|
+
if (representation.propertySignatures.length > 0) propertyNames.push({ enum: Object.keys(properties) });
|
|
609
|
+
representation.indexSignatures.forEach((signature, index) => {
|
|
610
|
+
propertyNames.push(recur(signature.parameter, [...path, "indexSignatures", index, "parameter"]));
|
|
611
|
+
});
|
|
612
|
+
out["propertyNames"] = propertyNames.length === 1 ? propertyNames[0] : { anyOf: propertyNames };
|
|
613
|
+
out["additionalProperties"] = indexValueSchemas.length === 1 ? indexValueSchemas[0] : { anyOf: indexValueSchemas };
|
|
614
|
+
if (additional.length > 0) out["allOf"] = additional;
|
|
615
|
+
} else if (additional.length === 0) {
|
|
616
|
+
out["additionalProperties"] = hasUnrepresentableIndexPattern || !closed;
|
|
617
|
+
} else if (additionalPropertySchemas.length === 1 && representation.propertySignatures.length === 0 && !hasPatternProperties) {
|
|
618
|
+
out["additionalProperties"] = additionalPropertySchemas[0];
|
|
619
|
+
} else {
|
|
620
|
+
out["allOf"] = additional;
|
|
621
|
+
}
|
|
622
|
+
const additionalProperties = out["additionalProperties"];
|
|
623
|
+
if (isObject(additionalProperties) && Object.keys(additionalProperties).length === 0) {
|
|
624
|
+
delete out["additionalProperties"];
|
|
625
|
+
}
|
|
626
|
+
return out;
|
|
627
|
+
}
|
|
628
|
+
case "Union": {
|
|
629
|
+
const types = representation.types.map((type, index) => recur(type, [...path, "types", index]));
|
|
630
|
+
if (types.length === 0) return { not: {} };
|
|
631
|
+
const mode = representation.options?.mode ?? "anyOf";
|
|
632
|
+
if (mode === "anyOf" && types.length > 1) {
|
|
633
|
+
const compacted = compactEnums(types);
|
|
634
|
+
if (compacted !== void 0) return compacted;
|
|
635
|
+
}
|
|
636
|
+
return mode === "anyOf" ? { anyOf: types } : { oneOf: types };
|
|
637
|
+
}
|
|
638
|
+
default:
|
|
639
|
+
return unsupported(representation, path);
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
const parameterPatterns = (parameter, path, seenReferences) => {
|
|
643
|
+
switch (parameter._tag) {
|
|
644
|
+
case "Reference": {
|
|
645
|
+
const target = Object.hasOwn(references, parameter.$ref) ? references[parameter.$ref] : void 0;
|
|
646
|
+
if (target === void 0) throw invalid(`Invalid reference ${parameter.$ref}`, [...path, "$ref"]);
|
|
647
|
+
compileDefinition(parameter.$ref, path);
|
|
648
|
+
if (seenReferences.has(parameter.$ref)) return void 0;
|
|
649
|
+
return parameterPatterns(target, ["references", parameter.$ref], new Set(seenReferences).add(parameter.$ref));
|
|
650
|
+
}
|
|
651
|
+
case "String": {
|
|
652
|
+
const check = parameter.checks[0];
|
|
653
|
+
if (check === void 0) return [];
|
|
654
|
+
if (parameter.checks.length !== 1 || check._tag !== "Filter" || fragmentSource(check) === void 0) {
|
|
655
|
+
return void 0;
|
|
656
|
+
}
|
|
657
|
+
const schema2 = recur(parameter, path);
|
|
658
|
+
const key = schema2["pattern"];
|
|
659
|
+
return schema2["type"] === "string" && typeof key === "string" && hasOnlyKeywords(schema2, "|type|pattern|title|description|default|examples|readOnly|writeOnly|") ? [key] : void 0;
|
|
660
|
+
}
|
|
661
|
+
case "TemplateLiteral":
|
|
662
|
+
return parameter.checks.length === 0 ? [`^${parameter.parts.map(partPattern).join("")}$`] : void 0;
|
|
663
|
+
case "Union": {
|
|
664
|
+
if (parameter.types.length === 0 || parameter.checks.length > 0 || parameter.options?.mode === "oneOf") {
|
|
665
|
+
return void 0;
|
|
666
|
+
}
|
|
667
|
+
const patterns = [];
|
|
668
|
+
for (const [index, member] of parameter.types.entries()) {
|
|
669
|
+
const memberPatterns = parameterPatterns(member, [...path, "types", index], seenReferences);
|
|
670
|
+
if (memberPatterns === void 0) return void 0;
|
|
671
|
+
if (memberPatterns.length === 0) return [];
|
|
672
|
+
patterns.push(...memberPatterns);
|
|
673
|
+
}
|
|
674
|
+
return patterns;
|
|
675
|
+
}
|
|
676
|
+
default:
|
|
677
|
+
throw invalid("Invalid schema representation document", path);
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
const referenceKeys = Object.keys(references);
|
|
681
|
+
for (const key of referenceKeys) compileDefinition(key, ["references", key]);
|
|
682
|
+
const schema = finalize(recur(document.representation, ["representation"]));
|
|
683
|
+
const definitions = {};
|
|
684
|
+
for (const key of referenceKeys) {
|
|
685
|
+
const compiled = definitionStates.get(key);
|
|
686
|
+
if (isObject(compiled)) assignProperty(definitions, key, finalize(compiled));
|
|
687
|
+
}
|
|
688
|
+
return { dialect: "draft-2020-12", schema, definitions };
|
|
689
|
+
};
|
|
690
|
+
const schemaIdentity = (schema, options) => fromRepresentation(Schema.toRepresentation(Schema.toCodecJson(schema)), options);
|
|
691
|
+
const rc115CheckIds = /* @__PURE__ */ new Map([
|
|
692
|
+
["effect/schema/isStartingWith", "effect/schema/isStartsWith"],
|
|
693
|
+
["effect/schema/isEndingWith", "effect/schema/isEndsWith"],
|
|
694
|
+
["effect/schema/isIncluding", "effect/schema/isIncludes"],
|
|
695
|
+
["effect/schema/isBetweenLength", "effect/schema/isLengthBetween"],
|
|
696
|
+
["effect/schema/isBetweenSize", "effect/schema/isSizeBetween"],
|
|
697
|
+
["effect/schema/isBetweenProperties", "effect/schema/isPropertiesLengthBetween"]
|
|
698
|
+
]);
|
|
699
|
+
const withRc115CheckIds = (value, isCheck = false) => {
|
|
700
|
+
if (Array.isArray(value)) return value.map((member) => withRc115CheckIds(member, isCheck));
|
|
701
|
+
if (!isObject(value)) return value;
|
|
702
|
+
const out = {};
|
|
703
|
+
for (const [key, member] of Object.entries(value)) {
|
|
704
|
+
if (key === "annotations" || key === "payload") {
|
|
705
|
+
assignProperty(out, key, member);
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
const renamed = isCheck && key === "representation" && isObject(member) && typeof member["id"] === "string" ? rc115CheckIds.get(member["id"]) : void 0;
|
|
709
|
+
assignProperty(
|
|
710
|
+
out,
|
|
711
|
+
key,
|
|
712
|
+
renamed === void 0 ? withRc115CheckIds(member, key === "checks") : withRc115CheckIds({ ...member, id: renamed })
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
return out;
|
|
716
|
+
};
|
|
717
|
+
const representationIdentity = (ast) => withRc115CheckIds(SchemaRepresentation.toJson(SchemaRepresentation.toRepresentation(ast)));
|
|
718
|
+
//# sourceMappingURL=SchemaIdentity.js.map
|