effect 3.9.2 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Arbitrary/package.json +6 -0
- package/FastCheck/package.json +6 -0
- package/JSONSchema/package.json +6 -0
- package/ParseResult/package.json +6 -0
- package/Pretty/package.json +6 -0
- package/Schema/package.json +6 -0
- package/SchemaAST/package.json +6 -0
- package/TSubscriptionRef/package.json +6 -0
- package/dist/cjs/Arbitrary.js +490 -0
- package/dist/cjs/Arbitrary.js.map +1 -0
- package/dist/cjs/Effect.js +247 -16
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FastCheck.js +17 -0
- package/dist/cjs/FastCheck.js.map +1 -0
- package/dist/cjs/Inspectable.js +43 -3
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/JSONSchema.js +418 -0
- package/dist/cjs/JSONSchema.js.map +1 -0
- package/dist/cjs/ParseResult.js +1539 -0
- package/dist/cjs/ParseResult.js.map +1 -0
- package/dist/cjs/Predicate.js +3 -1
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Pretty.js +183 -0
- package/dist/cjs/Pretty.js.map +1 -0
- package/dist/cjs/Schema.js +5529 -0
- package/dist/cjs/Schema.js.map +1 -0
- package/dist/cjs/SchemaAST.js +2365 -0
- package/dist/cjs/SchemaAST.js.map +1 -0
- package/dist/cjs/Stream.js +17 -3
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/TPubSub.js +9 -1
- package/dist/cjs/TPubSub.js.map +1 -1
- package/dist/cjs/TQueue.js.map +1 -1
- package/dist/cjs/TRef.js.map +1 -1
- package/dist/cjs/TSubscriptionRef.js +96 -0
- package/dist/cjs/TSubscriptionRef.js.map +1 -0
- package/dist/cjs/index.js +18 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/cause.js +2 -2
- package/dist/cjs/internal/cause.js.map +1 -1
- package/dist/cjs/internal/core.js +4 -4
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +14 -12
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/logger.js +7 -6
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/redacted.js +4 -0
- package/dist/cjs/internal/redacted.js.map +1 -1
- package/dist/cjs/internal/schema/errors.js +116 -0
- package/dist/cjs/internal/schema/errors.js.map +1 -0
- package/dist/cjs/internal/schema/filters.js +41 -0
- package/dist/cjs/internal/schema/filters.js.map +1 -0
- package/dist/cjs/internal/schema/util.js +96 -0
- package/dist/cjs/internal/schema/util.js.map +1 -0
- package/dist/cjs/internal/stm/core.js +2 -3
- package/dist/cjs/internal/stm/core.js.map +1 -1
- package/dist/cjs/internal/stm/tPubSub.js.map +1 -1
- package/dist/cjs/internal/stm/tQueue.js +1 -2
- package/dist/cjs/internal/stm/tQueue.js.map +1 -1
- package/dist/cjs/internal/stm/tRef.js +6 -2
- package/dist/cjs/internal/stm/tRef.js.map +1 -1
- package/dist/cjs/internal/stm/tSubscriptionRef.js +178 -0
- package/dist/cjs/internal/stm/tSubscriptionRef.js.map +1 -0
- package/dist/cjs/internal/stream.js +36 -16
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Arbitrary.d.ts +45 -0
- package/dist/dts/Arbitrary.d.ts.map +1 -0
- package/dist/dts/Effect.d.ts +298 -30
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FastCheck.d.ts +9 -0
- package/dist/dts/FastCheck.d.ts.map +1 -0
- package/dist/dts/Inspectable.d.ts +28 -0
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts +181 -0
- package/dist/dts/JSONSchema.d.ts.map +1 -0
- package/dist/dts/ParseResult.d.ts +551 -0
- package/dist/dts/ParseResult.d.ts.map +1 -0
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/Pretty.d.ts +26 -0
- package/dist/dts/Pretty.d.ts.map +1 -0
- package/dist/dts/Schema.d.ts +4562 -0
- package/dist/dts/Schema.d.ts.map +1 -0
- package/dist/dts/SchemaAST.d.ts +1321 -0
- package/dist/dts/SchemaAST.d.ts.map +1 -0
- package/dist/dts/Stream.d.ts +67 -2
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/TPubSub.d.ts +8 -0
- package/dist/dts/TPubSub.d.ts.map +1 -1
- package/dist/dts/TQueue.d.ts +7 -7
- package/dist/dts/TQueue.d.ts.map +1 -1
- package/dist/dts/TRef.d.ts +2 -1
- package/dist/dts/TRef.d.ts.map +1 -1
- package/dist/dts/TSubscriptionRef.d.ts +251 -0
- package/dist/dts/TSubscriptionRef.d.ts.map +1 -0
- package/dist/dts/index.d.ts +32 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
- package/dist/dts/internal/schema/errors.d.ts +2 -0
- package/dist/dts/internal/schema/errors.d.ts.map +1 -0
- package/dist/dts/internal/schema/filters.d.ts +2 -0
- package/dist/dts/internal/schema/filters.d.ts.map +1 -0
- package/dist/dts/internal/schema/util.d.ts +2 -0
- package/dist/dts/internal/schema/util.d.ts.map +1 -0
- package/dist/dts/internal/stm/tRef.d.ts +3 -1
- package/dist/dts/internal/stm/tRef.d.ts.map +1 -1
- package/dist/dts/internal/stm/tSubscriptionRef.d.ts +2 -0
- package/dist/dts/internal/stm/tSubscriptionRef.d.ts.map +1 -0
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Arbitrary.js +472 -0
- package/dist/esm/Arbitrary.js.map +1 -0
- package/dist/esm/Effect.js +256 -18
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FastCheck.js +9 -0
- package/dist/esm/FastCheck.js.map +1 -0
- package/dist/esm/Inspectable.js +39 -2
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/JSONSchema.js +408 -0
- package/dist/esm/JSONSchema.js.map +1 -0
- package/dist/esm/ParseResult.js +1503 -0
- package/dist/esm/ParseResult.js.map +1 -0
- package/dist/esm/Predicate.js +2 -1
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Pretty.js +173 -0
- package/dist/esm/Pretty.js.map +1 -0
- package/dist/esm/Schema.js +5328 -0
- package/dist/esm/Schema.js.map +1 -0
- package/dist/esm/SchemaAST.js +2300 -0
- package/dist/esm/SchemaAST.js.map +1 -0
- package/dist/esm/Stream.js +14 -0
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/TPubSub.js +8 -0
- package/dist/esm/TPubSub.js.map +1 -1
- package/dist/esm/TQueue.js.map +1 -1
- package/dist/esm/TRef.js.map +1 -1
- package/dist/esm/TSubscriptionRef.js +87 -0
- package/dist/esm/TSubscriptionRef.js.map +1 -0
- package/dist/esm/index.js +32 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/cause.js +3 -3
- package/dist/esm/internal/cause.js.map +1 -1
- package/dist/esm/internal/core.js +4 -4
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +14 -12
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/logger.js +7 -6
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/redacted.js +4 -0
- package/dist/esm/internal/redacted.js.map +1 -1
- package/dist/esm/internal/schema/errors.js +87 -0
- package/dist/esm/internal/schema/errors.js.map +1 -0
- package/dist/esm/internal/schema/filters.js +35 -0
- package/dist/esm/internal/schema/filters.js.map +1 -0
- package/dist/esm/internal/schema/util.js +78 -0
- package/dist/esm/internal/schema/util.js.map +1 -0
- package/dist/esm/internal/stm/core.js +1 -2
- package/dist/esm/internal/stm/core.js.map +1 -1
- package/dist/esm/internal/stm/tPubSub.js.map +1 -1
- package/dist/esm/internal/stm/tQueue.js +1 -2
- package/dist/esm/internal/stm/tQueue.js.map +1 -1
- package/dist/esm/internal/stm/tRef.js +5 -1
- package/dist/esm/internal/stm/tRef.js.map +1 -1
- package/dist/esm/internal/stm/tSubscriptionRef.js +166 -0
- package/dist/esm/internal/stm/tSubscriptionRef.js.map +1 -0
- package/dist/esm/internal/stream.js +33 -15
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +68 -1
- package/src/Arbitrary.ts +563 -0
- package/src/Effect.ts +302 -31
- package/src/FastCheck.ts +9 -0
- package/src/Inspectable.ts +56 -2
- package/src/JSONSchema.ts +601 -0
- package/src/ParseResult.ts +2027 -0
- package/src/Predicate.ts +3 -1
- package/src/Pretty.ts +204 -0
- package/src/Schema.ts +10388 -0
- package/src/SchemaAST.ts +2827 -0
- package/src/Stream.ts +77 -9
- package/src/TPubSub.ts +9 -0
- package/src/TQueue.ts +7 -7
- package/src/TRef.ts +2 -1
- package/src/TSubscriptionRef.ts +284 -0
- package/src/index.ts +40 -0
- package/src/internal/cause.ts +3 -3
- package/src/internal/core-effect.ts +2 -2
- package/src/internal/core.ts +4 -4
- package/src/internal/fiberRuntime.ts +14 -12
- package/src/internal/logger.ts +7 -6
- package/src/internal/redacted.ts +4 -0
- package/src/internal/schema/errors.ts +189 -0
- package/src/internal/schema/filters.ts +86 -0
- package/src/internal/schema/util.ts +113 -0
- package/src/internal/stm/core.ts +1 -2
- package/src/internal/stm/tPubSub.ts +1 -0
- package/src/internal/stm/tQueue.ts +2 -2
- package/src/internal/stm/tRef.ts +7 -2
- package/src/internal/stm/tSubscriptionRef.ts +286 -0
- package/src/internal/stream.ts +97 -20
- package/src/internal/version.ts +1 -1
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 3.10.0
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as errors_ from "./internal/schema/errors.js"
|
|
6
|
+
import * as Option from "./Option.js"
|
|
7
|
+
import * as Predicate from "./Predicate.js"
|
|
8
|
+
import * as Record from "./Record.js"
|
|
9
|
+
import type * as Schema from "./Schema.js"
|
|
10
|
+
import * as AST from "./SchemaAST.js"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @category model
|
|
14
|
+
* @since 3.10.0
|
|
15
|
+
*/
|
|
16
|
+
export interface JsonSchemaAnnotations {
|
|
17
|
+
title?: string
|
|
18
|
+
description?: string
|
|
19
|
+
default?: unknown
|
|
20
|
+
examples?: Array<unknown>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @category model
|
|
25
|
+
* @since 3.10.0
|
|
26
|
+
*/
|
|
27
|
+
export interface JsonSchema7Any extends JsonSchemaAnnotations {
|
|
28
|
+
$id: "/schemas/any"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @category model
|
|
33
|
+
* @since 3.10.0
|
|
34
|
+
*/
|
|
35
|
+
export interface JsonSchema7Unknown extends JsonSchemaAnnotations {
|
|
36
|
+
$id: "/schemas/unknown"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @category model
|
|
41
|
+
* @since 3.10.0
|
|
42
|
+
*/
|
|
43
|
+
export interface JsonSchema7Void extends JsonSchemaAnnotations {
|
|
44
|
+
$id: "/schemas/void"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @category model
|
|
49
|
+
* @since 3.10.0
|
|
50
|
+
*/
|
|
51
|
+
export interface JsonSchema7object extends JsonSchemaAnnotations {
|
|
52
|
+
$id: "/schemas/object"
|
|
53
|
+
anyOf: [
|
|
54
|
+
{ type: "object" },
|
|
55
|
+
{ type: "array" }
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @category model
|
|
61
|
+
* @since 3.10.0
|
|
62
|
+
*/
|
|
63
|
+
export interface JsonSchema7empty extends JsonSchemaAnnotations {
|
|
64
|
+
$id: "/schemas/{}"
|
|
65
|
+
anyOf: [
|
|
66
|
+
{ type: "object" },
|
|
67
|
+
{ type: "array" }
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @category model
|
|
73
|
+
* @since 3.10.0
|
|
74
|
+
*/
|
|
75
|
+
export interface JsonSchema7Ref extends JsonSchemaAnnotations {
|
|
76
|
+
$ref: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @category model
|
|
81
|
+
* @since 3.10.0
|
|
82
|
+
*/
|
|
83
|
+
export interface JsonSchema7String extends JsonSchemaAnnotations {
|
|
84
|
+
type: "string"
|
|
85
|
+
minLength?: number
|
|
86
|
+
maxLength?: number
|
|
87
|
+
pattern?: string
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @category model
|
|
92
|
+
* @since 3.10.0
|
|
93
|
+
*/
|
|
94
|
+
export interface JsonSchema7Numeric extends JsonSchemaAnnotations {
|
|
95
|
+
minimum?: number
|
|
96
|
+
exclusiveMinimum?: number
|
|
97
|
+
maximum?: number
|
|
98
|
+
exclusiveMaximum?: number
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @category model
|
|
103
|
+
* @since 3.10.0
|
|
104
|
+
*/
|
|
105
|
+
export interface JsonSchema7Number extends JsonSchema7Numeric {
|
|
106
|
+
type: "number"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @category model
|
|
111
|
+
* @since 3.10.0
|
|
112
|
+
*/
|
|
113
|
+
export interface JsonSchema7Integer extends JsonSchema7Numeric {
|
|
114
|
+
type: "integer"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @category model
|
|
119
|
+
* @since 3.10.0
|
|
120
|
+
*/
|
|
121
|
+
export interface JsonSchema7Boolean extends JsonSchemaAnnotations {
|
|
122
|
+
type: "boolean"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @category model
|
|
127
|
+
* @since 3.10.0
|
|
128
|
+
*/
|
|
129
|
+
export interface JsonSchema7Array extends JsonSchemaAnnotations {
|
|
130
|
+
type: "array"
|
|
131
|
+
items?: JsonSchema7 | Array<JsonSchema7>
|
|
132
|
+
minItems?: number
|
|
133
|
+
maxItems?: number
|
|
134
|
+
additionalItems?: JsonSchema7 | boolean
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @category model
|
|
139
|
+
* @since 3.10.0
|
|
140
|
+
*/
|
|
141
|
+
export interface JsonSchema7Enum extends JsonSchemaAnnotations {
|
|
142
|
+
enum: Array<AST.LiteralValue>
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @category model
|
|
147
|
+
* @since 3.10.0
|
|
148
|
+
*/
|
|
149
|
+
export interface JsonSchema7Enums extends JsonSchemaAnnotations {
|
|
150
|
+
$comment: "/schemas/enums"
|
|
151
|
+
anyOf: Array<{
|
|
152
|
+
title: string
|
|
153
|
+
enum: [string | number]
|
|
154
|
+
}>
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @category model
|
|
159
|
+
* @since 3.10.0
|
|
160
|
+
*/
|
|
161
|
+
export interface JsonSchema7AnyOf extends JsonSchemaAnnotations {
|
|
162
|
+
anyOf: Array<JsonSchema7>
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @category model
|
|
167
|
+
* @since 3.10.0
|
|
168
|
+
*/
|
|
169
|
+
export interface JsonSchema7Object extends JsonSchemaAnnotations {
|
|
170
|
+
type: "object"
|
|
171
|
+
required: Array<string>
|
|
172
|
+
properties: Record<string, JsonSchema7>
|
|
173
|
+
additionalProperties?: boolean | JsonSchema7
|
|
174
|
+
patternProperties?: Record<string, JsonSchema7>
|
|
175
|
+
propertyNames?: JsonSchema7
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @category model
|
|
180
|
+
* @since 3.10.0
|
|
181
|
+
*/
|
|
182
|
+
export type JsonSchema7 =
|
|
183
|
+
| JsonSchema7Any
|
|
184
|
+
| JsonSchema7Unknown
|
|
185
|
+
| JsonSchema7Void
|
|
186
|
+
| JsonSchema7object
|
|
187
|
+
| JsonSchema7empty
|
|
188
|
+
| JsonSchema7Ref
|
|
189
|
+
| JsonSchema7String
|
|
190
|
+
| JsonSchema7Number
|
|
191
|
+
| JsonSchema7Integer
|
|
192
|
+
| JsonSchema7Boolean
|
|
193
|
+
| JsonSchema7Array
|
|
194
|
+
| JsonSchema7Enum
|
|
195
|
+
| JsonSchema7Enums
|
|
196
|
+
| JsonSchema7AnyOf
|
|
197
|
+
| JsonSchema7Object
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @category model
|
|
201
|
+
* @since 3.10.0
|
|
202
|
+
*/
|
|
203
|
+
export type JsonSchema7Root = JsonSchema7 & {
|
|
204
|
+
$schema?: string
|
|
205
|
+
$defs?: Record<string, JsonSchema7>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @category encoding
|
|
210
|
+
* @since 3.10.0
|
|
211
|
+
*/
|
|
212
|
+
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): JsonSchema7Root => {
|
|
213
|
+
const $defs: Record<string, any> = {}
|
|
214
|
+
const jsonSchema = go(schema.ast, $defs, true, [])
|
|
215
|
+
const out: JsonSchema7Root = {
|
|
216
|
+
$schema,
|
|
217
|
+
...jsonSchema
|
|
218
|
+
}
|
|
219
|
+
// clean up self-referencing entries
|
|
220
|
+
for (const id in $defs) {
|
|
221
|
+
if ($defs[id]["$ref"] === get$ref(id)) {
|
|
222
|
+
delete $defs[id]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (!Record.isEmptyRecord($defs)) {
|
|
226
|
+
out.$defs = $defs
|
|
227
|
+
}
|
|
228
|
+
return out
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const anyJsonSchema: JsonSchema7 = { $id: "/schemas/any" }
|
|
232
|
+
|
|
233
|
+
const unknownJsonSchema: JsonSchema7 = { $id: "/schemas/unknown" }
|
|
234
|
+
|
|
235
|
+
const voidJsonSchema: JsonSchema7 = { $id: "/schemas/void" }
|
|
236
|
+
|
|
237
|
+
const objectJsonSchema: JsonSchema7 = {
|
|
238
|
+
"$id": "/schemas/object",
|
|
239
|
+
"anyOf": [
|
|
240
|
+
{ "type": "object" },
|
|
241
|
+
{ "type": "array" }
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const empty = (): JsonSchema7 => ({
|
|
246
|
+
"$id": "/schemas/{}",
|
|
247
|
+
"anyOf": [
|
|
248
|
+
{ "type": "object" },
|
|
249
|
+
{ "type": "array" }
|
|
250
|
+
]
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
const $schema = "http://json-schema.org/draft-07/schema#"
|
|
254
|
+
|
|
255
|
+
const getJsonSchemaAnnotations = (annotated: AST.Annotated): JsonSchemaAnnotations =>
|
|
256
|
+
Record.getSomes({
|
|
257
|
+
description: AST.getDescriptionAnnotation(annotated),
|
|
258
|
+
title: AST.getTitleAnnotation(annotated),
|
|
259
|
+
examples: AST.getExamplesAnnotation(annotated),
|
|
260
|
+
default: AST.getDefaultAnnotation(annotated)
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
const removeDefaultJsonSchemaAnnotations = (
|
|
264
|
+
jsonSchemaAnnotations: JsonSchemaAnnotations,
|
|
265
|
+
ast: AST.AST
|
|
266
|
+
): JsonSchemaAnnotations => {
|
|
267
|
+
if (jsonSchemaAnnotations["title"] === ast.annotations[AST.TitleAnnotationId]) {
|
|
268
|
+
delete jsonSchemaAnnotations["title"]
|
|
269
|
+
}
|
|
270
|
+
if (jsonSchemaAnnotations["description"] === ast.annotations[AST.DescriptionAnnotationId]) {
|
|
271
|
+
delete jsonSchemaAnnotations["description"]
|
|
272
|
+
}
|
|
273
|
+
return jsonSchemaAnnotations
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const getASTJsonSchemaAnnotations = (ast: AST.AST): JsonSchemaAnnotations => {
|
|
277
|
+
const jsonSchemaAnnotations = getJsonSchemaAnnotations(ast)
|
|
278
|
+
switch (ast._tag) {
|
|
279
|
+
case "StringKeyword":
|
|
280
|
+
return removeDefaultJsonSchemaAnnotations(jsonSchemaAnnotations, AST.stringKeyword)
|
|
281
|
+
case "NumberKeyword":
|
|
282
|
+
return removeDefaultJsonSchemaAnnotations(jsonSchemaAnnotations, AST.numberKeyword)
|
|
283
|
+
case "BooleanKeyword":
|
|
284
|
+
return removeDefaultJsonSchemaAnnotations(jsonSchemaAnnotations, AST.booleanKeyword)
|
|
285
|
+
default:
|
|
286
|
+
return jsonSchemaAnnotations
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const pruneUndefinedKeyword = (ps: AST.PropertySignature): AST.AST | undefined => {
|
|
291
|
+
const type = ps.type
|
|
292
|
+
if (AST.isUnion(type) && Option.isNone(AST.getJSONSchemaAnnotation(type))) {
|
|
293
|
+
const types = type.types.filter((type) => !AST.isUndefinedKeyword(type))
|
|
294
|
+
if (types.length < type.types.length) {
|
|
295
|
+
return AST.Union.make(types, type.annotations)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** @internal */
|
|
301
|
+
export const DEFINITION_PREFIX = "#/$defs/"
|
|
302
|
+
|
|
303
|
+
const get$ref = (id: string): string => `${DEFINITION_PREFIX}${id}`
|
|
304
|
+
|
|
305
|
+
const getRefinementInnerTransformation = (ast: AST.Refinement): AST.AST | undefined => {
|
|
306
|
+
switch (ast.from._tag) {
|
|
307
|
+
case "Transformation":
|
|
308
|
+
return ast.from
|
|
309
|
+
case "Refinement":
|
|
310
|
+
return getRefinementInnerTransformation(ast.from)
|
|
311
|
+
case "Suspend": {
|
|
312
|
+
const from = ast.from.f()
|
|
313
|
+
if (AST.isRefinement(from)) {
|
|
314
|
+
return getRefinementInnerTransformation(from)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const isParseJsonTransformation = (ast: AST.AST): boolean =>
|
|
321
|
+
ast.annotations[AST.SchemaIdAnnotationId] === AST.ParseJsonSchemaId
|
|
322
|
+
|
|
323
|
+
function merge(a: JsonSchemaAnnotations, b: JsonSchema7): JsonSchema7
|
|
324
|
+
function merge(a: JsonSchema7, b: JsonSchemaAnnotations): JsonSchema7
|
|
325
|
+
function merge(a: JsonSchema7, b: JsonSchema7): JsonSchema7
|
|
326
|
+
function merge(a: object, b: object): object {
|
|
327
|
+
return { ...a, ...b }
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const isOverrideAnnotation = (jsonSchema: JsonSchema7): boolean => {
|
|
331
|
+
return ("type" in jsonSchema) || ("oneOf" in jsonSchema) || ("anyOf" in jsonSchema) || ("const" in jsonSchema) ||
|
|
332
|
+
("enum" in jsonSchema) || ("$ref" in jsonSchema)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const go = (
|
|
336
|
+
ast: AST.AST,
|
|
337
|
+
$defs: Record<string, JsonSchema7>,
|
|
338
|
+
handleIdentifier: boolean,
|
|
339
|
+
path: ReadonlyArray<PropertyKey>
|
|
340
|
+
): JsonSchema7 => {
|
|
341
|
+
const hook = AST.getJSONSchemaAnnotation(ast)
|
|
342
|
+
if (Option.isSome(hook)) {
|
|
343
|
+
const handler = hook.value as JsonSchema7
|
|
344
|
+
if (AST.isRefinement(ast)) {
|
|
345
|
+
const t = getRefinementInnerTransformation(ast)
|
|
346
|
+
if (t === undefined) {
|
|
347
|
+
try {
|
|
348
|
+
return {
|
|
349
|
+
...go(ast.from, $defs, true, path),
|
|
350
|
+
...getJsonSchemaAnnotations(ast),
|
|
351
|
+
...handler
|
|
352
|
+
}
|
|
353
|
+
} catch (e) {
|
|
354
|
+
return {
|
|
355
|
+
...getJsonSchemaAnnotations(ast),
|
|
356
|
+
...handler
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
} else if (!isOverrideAnnotation(handler)) {
|
|
360
|
+
return go(t, $defs, true, path)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return handler
|
|
364
|
+
}
|
|
365
|
+
const surrogate = AST.getSurrogateAnnotation(ast)
|
|
366
|
+
if (Option.isSome(surrogate)) {
|
|
367
|
+
return go(surrogate.value, $defs, handleIdentifier, path)
|
|
368
|
+
}
|
|
369
|
+
if (handleIdentifier && !AST.isTransformation(ast) && !AST.isRefinement(ast)) {
|
|
370
|
+
const identifier = AST.getJSONIdentifier(ast)
|
|
371
|
+
if (Option.isSome(identifier)) {
|
|
372
|
+
const id = identifier.value
|
|
373
|
+
const out = { $ref: get$ref(id) }
|
|
374
|
+
if (!Record.has($defs, id)) {
|
|
375
|
+
$defs[id] = out
|
|
376
|
+
$defs[id] = go(ast, $defs, false, path)
|
|
377
|
+
}
|
|
378
|
+
return out
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
switch (ast._tag) {
|
|
382
|
+
case "Declaration":
|
|
383
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
384
|
+
case "Literal": {
|
|
385
|
+
const literal = ast.literal
|
|
386
|
+
if (literal === null) {
|
|
387
|
+
return merge({ enum: [null] }, getJsonSchemaAnnotations(ast))
|
|
388
|
+
} else if (Predicate.isString(literal) || Predicate.isNumber(literal) || Predicate.isBoolean(literal)) {
|
|
389
|
+
return merge({ enum: [literal] }, getJsonSchemaAnnotations(ast))
|
|
390
|
+
}
|
|
391
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
392
|
+
}
|
|
393
|
+
case "UniqueSymbol":
|
|
394
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
395
|
+
case "UndefinedKeyword":
|
|
396
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
397
|
+
case "VoidKeyword":
|
|
398
|
+
return merge(voidJsonSchema, getJsonSchemaAnnotations(ast))
|
|
399
|
+
case "NeverKeyword":
|
|
400
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
401
|
+
case "UnknownKeyword":
|
|
402
|
+
return merge(unknownJsonSchema, getJsonSchemaAnnotations(ast))
|
|
403
|
+
case "AnyKeyword":
|
|
404
|
+
return merge(anyJsonSchema, getJsonSchemaAnnotations(ast))
|
|
405
|
+
case "ObjectKeyword":
|
|
406
|
+
return merge(objectJsonSchema, getJsonSchemaAnnotations(ast))
|
|
407
|
+
case "StringKeyword":
|
|
408
|
+
return { type: "string", ...getASTJsonSchemaAnnotations(ast) }
|
|
409
|
+
case "NumberKeyword":
|
|
410
|
+
return { type: "number", ...getASTJsonSchemaAnnotations(ast) }
|
|
411
|
+
case "BooleanKeyword":
|
|
412
|
+
return { type: "boolean", ...getASTJsonSchemaAnnotations(ast) }
|
|
413
|
+
case "BigIntKeyword":
|
|
414
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
415
|
+
case "SymbolKeyword":
|
|
416
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
417
|
+
case "TupleType": {
|
|
418
|
+
const elements = ast.elements.map((e, i) =>
|
|
419
|
+
merge(
|
|
420
|
+
go(e.type, $defs, true, path.concat(i)),
|
|
421
|
+
getJsonSchemaAnnotations(e)
|
|
422
|
+
)
|
|
423
|
+
)
|
|
424
|
+
const rest = ast.rest.map((annotatedAST) =>
|
|
425
|
+
merge(
|
|
426
|
+
go(annotatedAST.type, $defs, true, path),
|
|
427
|
+
getJsonSchemaAnnotations(annotatedAST)
|
|
428
|
+
)
|
|
429
|
+
)
|
|
430
|
+
const output: JsonSchema7Array = { type: "array" }
|
|
431
|
+
// ---------------------------------------------
|
|
432
|
+
// handle elements
|
|
433
|
+
// ---------------------------------------------
|
|
434
|
+
const len = ast.elements.length
|
|
435
|
+
if (len > 0) {
|
|
436
|
+
output.minItems = len - ast.elements.filter((element) => element.isOptional).length
|
|
437
|
+
output.items = elements
|
|
438
|
+
}
|
|
439
|
+
// ---------------------------------------------
|
|
440
|
+
// handle rest element
|
|
441
|
+
// ---------------------------------------------
|
|
442
|
+
const restLength = rest.length
|
|
443
|
+
if (restLength > 0) {
|
|
444
|
+
const head = rest[0]
|
|
445
|
+
const isHomogeneous = restLength === 1 && ast.elements.every((e) => e.type === ast.rest[0].type)
|
|
446
|
+
if (isHomogeneous) {
|
|
447
|
+
output.items = head
|
|
448
|
+
} else {
|
|
449
|
+
output.additionalItems = head
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ---------------------------------------------
|
|
453
|
+
// handle post rest elements
|
|
454
|
+
// ---------------------------------------------
|
|
455
|
+
if (restLength > 1) {
|
|
456
|
+
throw new Error(errors_.getJSONSchemaUnsupportedPostRestElementsErrorMessage(path))
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
if (len > 0) {
|
|
460
|
+
output.additionalItems = false
|
|
461
|
+
} else {
|
|
462
|
+
output.maxItems = 0
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return merge(output, getJsonSchemaAnnotations(ast))
|
|
467
|
+
}
|
|
468
|
+
case "TypeLiteral": {
|
|
469
|
+
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
|
|
470
|
+
return merge(empty(), getJsonSchemaAnnotations(ast))
|
|
471
|
+
}
|
|
472
|
+
let patternProperties: JsonSchema7 | undefined = undefined
|
|
473
|
+
let propertyNames: JsonSchema7 | undefined = undefined
|
|
474
|
+
for (const is of ast.indexSignatures) {
|
|
475
|
+
const parameter = is.parameter
|
|
476
|
+
switch (parameter._tag) {
|
|
477
|
+
case "StringKeyword": {
|
|
478
|
+
patternProperties = go(is.type, $defs, true, path)
|
|
479
|
+
break
|
|
480
|
+
}
|
|
481
|
+
case "TemplateLiteral": {
|
|
482
|
+
patternProperties = go(is.type, $defs, true, path)
|
|
483
|
+
propertyNames = {
|
|
484
|
+
type: "string",
|
|
485
|
+
pattern: AST.getTemplateLiteralRegExp(parameter).source
|
|
486
|
+
}
|
|
487
|
+
break
|
|
488
|
+
}
|
|
489
|
+
case "Refinement": {
|
|
490
|
+
patternProperties = go(is.type, $defs, true, path)
|
|
491
|
+
propertyNames = go(parameter, $defs, true, path)
|
|
492
|
+
break
|
|
493
|
+
}
|
|
494
|
+
case "SymbolKeyword":
|
|
495
|
+
throw new Error(errors_.getJSONSchemaUnsupportedParameterErrorMessage(path, parameter))
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
const output: JsonSchema7Object = {
|
|
499
|
+
type: "object",
|
|
500
|
+
required: [],
|
|
501
|
+
properties: {},
|
|
502
|
+
additionalProperties: false
|
|
503
|
+
}
|
|
504
|
+
// ---------------------------------------------
|
|
505
|
+
// handle property signatures
|
|
506
|
+
// ---------------------------------------------
|
|
507
|
+
for (let i = 0; i < ast.propertySignatures.length; i++) {
|
|
508
|
+
const ps = ast.propertySignatures[i]
|
|
509
|
+
const name = ps.name
|
|
510
|
+
if (Predicate.isString(name)) {
|
|
511
|
+
const pruned = pruneUndefinedKeyword(ps)
|
|
512
|
+
output.properties[name] = merge(
|
|
513
|
+
go(pruned ? pruned : ps.type, $defs, true, path.concat(ps.name)),
|
|
514
|
+
getJsonSchemaAnnotations(ps)
|
|
515
|
+
)
|
|
516
|
+
// ---------------------------------------------
|
|
517
|
+
// handle optional property signatures
|
|
518
|
+
// ---------------------------------------------
|
|
519
|
+
if (!ps.isOptional && pruned === undefined) {
|
|
520
|
+
output.required.push(name)
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
throw new Error(errors_.getJSONSchemaUnsupportedKeyErrorMessage(name, path))
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
// ---------------------------------------------
|
|
527
|
+
// handle index signatures
|
|
528
|
+
// ---------------------------------------------
|
|
529
|
+
if (patternProperties !== undefined) {
|
|
530
|
+
delete output.additionalProperties
|
|
531
|
+
output.patternProperties = { "": patternProperties }
|
|
532
|
+
}
|
|
533
|
+
if (propertyNames !== undefined) {
|
|
534
|
+
output.propertyNames = propertyNames
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return merge(output, getJsonSchemaAnnotations(ast))
|
|
538
|
+
}
|
|
539
|
+
case "Union": {
|
|
540
|
+
const enums: Array<AST.LiteralValue> = []
|
|
541
|
+
const anyOf: Array<JsonSchema7> = []
|
|
542
|
+
for (const type of ast.types) {
|
|
543
|
+
const schema = go(type, $defs, true, path)
|
|
544
|
+
if ("enum" in schema) {
|
|
545
|
+
if (Object.keys(schema).length > 1) {
|
|
546
|
+
anyOf.push(schema)
|
|
547
|
+
} else {
|
|
548
|
+
for (const e of schema.enum) {
|
|
549
|
+
enums.push(e)
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
} else {
|
|
553
|
+
anyOf.push(schema)
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (anyOf.length === 0) {
|
|
557
|
+
return merge({ enum: enums }, getJsonSchemaAnnotations(ast))
|
|
558
|
+
} else {
|
|
559
|
+
if (enums.length >= 1) {
|
|
560
|
+
anyOf.push({ enum: enums })
|
|
561
|
+
}
|
|
562
|
+
return merge({ anyOf }, getJsonSchemaAnnotations(ast))
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
case "Enums": {
|
|
566
|
+
return merge({
|
|
567
|
+
$comment: "/schemas/enums",
|
|
568
|
+
anyOf: ast.enums.map((e) => ({ title: e[0], enum: [e[1]] }))
|
|
569
|
+
}, getJsonSchemaAnnotations(ast))
|
|
570
|
+
}
|
|
571
|
+
case "Refinement": {
|
|
572
|
+
if (AST.encodedBoundAST(ast) === ast) {
|
|
573
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
574
|
+
}
|
|
575
|
+
return go(ast.from, $defs, true, path)
|
|
576
|
+
}
|
|
577
|
+
case "TemplateLiteral": {
|
|
578
|
+
const regex = AST.getTemplateLiteralRegExp(ast)
|
|
579
|
+
return merge({
|
|
580
|
+
type: "string",
|
|
581
|
+
description: "a template literal",
|
|
582
|
+
pattern: regex.source
|
|
583
|
+
}, getJsonSchemaAnnotations(ast))
|
|
584
|
+
}
|
|
585
|
+
case "Suspend": {
|
|
586
|
+
const identifier = Option.orElse(AST.getJSONIdentifier(ast), () => AST.getJSONIdentifier(ast.f()))
|
|
587
|
+
if (Option.isNone(identifier)) {
|
|
588
|
+
throw new Error(errors_.getJSONSchemaMissingIdentifierAnnotationErrorMessage(path, ast))
|
|
589
|
+
}
|
|
590
|
+
return go(ast.f(), $defs, true, path)
|
|
591
|
+
}
|
|
592
|
+
case "Transformation": {
|
|
593
|
+
// Properly handle S.parseJson transformations by focusing on
|
|
594
|
+
// the 'to' side of the AST. This approach prevents the generation of useless schemas
|
|
595
|
+
// derived from the 'from' side (type: string), ensuring the output matches the intended
|
|
596
|
+
// complex schema type.
|
|
597
|
+
const next = isParseJsonTransformation(ast.from) ? ast.to : ast.from
|
|
598
|
+
return go(next, $defs, true, path)
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|