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.
Files changed (202) hide show
  1. package/Arbitrary/package.json +6 -0
  2. package/FastCheck/package.json +6 -0
  3. package/JSONSchema/package.json +6 -0
  4. package/ParseResult/package.json +6 -0
  5. package/Pretty/package.json +6 -0
  6. package/Schema/package.json +6 -0
  7. package/SchemaAST/package.json +6 -0
  8. package/TSubscriptionRef/package.json +6 -0
  9. package/dist/cjs/Arbitrary.js +490 -0
  10. package/dist/cjs/Arbitrary.js.map +1 -0
  11. package/dist/cjs/Effect.js +247 -16
  12. package/dist/cjs/Effect.js.map +1 -1
  13. package/dist/cjs/FastCheck.js +17 -0
  14. package/dist/cjs/FastCheck.js.map +1 -0
  15. package/dist/cjs/Inspectable.js +43 -3
  16. package/dist/cjs/Inspectable.js.map +1 -1
  17. package/dist/cjs/JSONSchema.js +418 -0
  18. package/dist/cjs/JSONSchema.js.map +1 -0
  19. package/dist/cjs/ParseResult.js +1539 -0
  20. package/dist/cjs/ParseResult.js.map +1 -0
  21. package/dist/cjs/Predicate.js +3 -1
  22. package/dist/cjs/Predicate.js.map +1 -1
  23. package/dist/cjs/Pretty.js +183 -0
  24. package/dist/cjs/Pretty.js.map +1 -0
  25. package/dist/cjs/Schema.js +5529 -0
  26. package/dist/cjs/Schema.js.map +1 -0
  27. package/dist/cjs/SchemaAST.js +2365 -0
  28. package/dist/cjs/SchemaAST.js.map +1 -0
  29. package/dist/cjs/Stream.js +17 -3
  30. package/dist/cjs/Stream.js.map +1 -1
  31. package/dist/cjs/TPubSub.js +9 -1
  32. package/dist/cjs/TPubSub.js.map +1 -1
  33. package/dist/cjs/TQueue.js.map +1 -1
  34. package/dist/cjs/TRef.js.map +1 -1
  35. package/dist/cjs/TSubscriptionRef.js +96 -0
  36. package/dist/cjs/TSubscriptionRef.js.map +1 -0
  37. package/dist/cjs/index.js +18 -2
  38. package/dist/cjs/index.js.map +1 -1
  39. package/dist/cjs/internal/cause.js +2 -2
  40. package/dist/cjs/internal/cause.js.map +1 -1
  41. package/dist/cjs/internal/core.js +4 -4
  42. package/dist/cjs/internal/core.js.map +1 -1
  43. package/dist/cjs/internal/fiberRuntime.js +14 -12
  44. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  45. package/dist/cjs/internal/logger.js +7 -6
  46. package/dist/cjs/internal/logger.js.map +1 -1
  47. package/dist/cjs/internal/redacted.js +4 -0
  48. package/dist/cjs/internal/redacted.js.map +1 -1
  49. package/dist/cjs/internal/schema/errors.js +116 -0
  50. package/dist/cjs/internal/schema/errors.js.map +1 -0
  51. package/dist/cjs/internal/schema/filters.js +41 -0
  52. package/dist/cjs/internal/schema/filters.js.map +1 -0
  53. package/dist/cjs/internal/schema/util.js +96 -0
  54. package/dist/cjs/internal/schema/util.js.map +1 -0
  55. package/dist/cjs/internal/stm/core.js +2 -3
  56. package/dist/cjs/internal/stm/core.js.map +1 -1
  57. package/dist/cjs/internal/stm/tPubSub.js.map +1 -1
  58. package/dist/cjs/internal/stm/tQueue.js +1 -2
  59. package/dist/cjs/internal/stm/tQueue.js.map +1 -1
  60. package/dist/cjs/internal/stm/tRef.js +6 -2
  61. package/dist/cjs/internal/stm/tRef.js.map +1 -1
  62. package/dist/cjs/internal/stm/tSubscriptionRef.js +178 -0
  63. package/dist/cjs/internal/stm/tSubscriptionRef.js.map +1 -0
  64. package/dist/cjs/internal/stream.js +36 -16
  65. package/dist/cjs/internal/stream.js.map +1 -1
  66. package/dist/cjs/internal/version.js +1 -1
  67. package/dist/cjs/internal/version.js.map +1 -1
  68. package/dist/dts/Arbitrary.d.ts +45 -0
  69. package/dist/dts/Arbitrary.d.ts.map +1 -0
  70. package/dist/dts/Effect.d.ts +298 -30
  71. package/dist/dts/Effect.d.ts.map +1 -1
  72. package/dist/dts/FastCheck.d.ts +9 -0
  73. package/dist/dts/FastCheck.d.ts.map +1 -0
  74. package/dist/dts/Inspectable.d.ts +28 -0
  75. package/dist/dts/Inspectable.d.ts.map +1 -1
  76. package/dist/dts/JSONSchema.d.ts +181 -0
  77. package/dist/dts/JSONSchema.d.ts.map +1 -0
  78. package/dist/dts/ParseResult.d.ts +551 -0
  79. package/dist/dts/ParseResult.d.ts.map +1 -0
  80. package/dist/dts/Predicate.d.ts.map +1 -1
  81. package/dist/dts/Pretty.d.ts +26 -0
  82. package/dist/dts/Pretty.d.ts.map +1 -0
  83. package/dist/dts/Schema.d.ts +4562 -0
  84. package/dist/dts/Schema.d.ts.map +1 -0
  85. package/dist/dts/SchemaAST.d.ts +1321 -0
  86. package/dist/dts/SchemaAST.d.ts.map +1 -0
  87. package/dist/dts/Stream.d.ts +67 -2
  88. package/dist/dts/Stream.d.ts.map +1 -1
  89. package/dist/dts/TPubSub.d.ts +8 -0
  90. package/dist/dts/TPubSub.d.ts.map +1 -1
  91. package/dist/dts/TQueue.d.ts +7 -7
  92. package/dist/dts/TQueue.d.ts.map +1 -1
  93. package/dist/dts/TRef.d.ts +2 -1
  94. package/dist/dts/TRef.d.ts.map +1 -1
  95. package/dist/dts/TSubscriptionRef.d.ts +251 -0
  96. package/dist/dts/TSubscriptionRef.d.ts.map +1 -0
  97. package/dist/dts/index.d.ts +32 -0
  98. package/dist/dts/index.d.ts.map +1 -1
  99. package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
  100. package/dist/dts/internal/schema/errors.d.ts +2 -0
  101. package/dist/dts/internal/schema/errors.d.ts.map +1 -0
  102. package/dist/dts/internal/schema/filters.d.ts +2 -0
  103. package/dist/dts/internal/schema/filters.d.ts.map +1 -0
  104. package/dist/dts/internal/schema/util.d.ts +2 -0
  105. package/dist/dts/internal/schema/util.d.ts.map +1 -0
  106. package/dist/dts/internal/stm/tRef.d.ts +3 -1
  107. package/dist/dts/internal/stm/tRef.d.ts.map +1 -1
  108. package/dist/dts/internal/stm/tSubscriptionRef.d.ts +2 -0
  109. package/dist/dts/internal/stm/tSubscriptionRef.d.ts.map +1 -0
  110. package/dist/dts/internal/stream.d.ts.map +1 -1
  111. package/dist/esm/Arbitrary.js +472 -0
  112. package/dist/esm/Arbitrary.js.map +1 -0
  113. package/dist/esm/Effect.js +256 -18
  114. package/dist/esm/Effect.js.map +1 -1
  115. package/dist/esm/FastCheck.js +9 -0
  116. package/dist/esm/FastCheck.js.map +1 -0
  117. package/dist/esm/Inspectable.js +39 -2
  118. package/dist/esm/Inspectable.js.map +1 -1
  119. package/dist/esm/JSONSchema.js +408 -0
  120. package/dist/esm/JSONSchema.js.map +1 -0
  121. package/dist/esm/ParseResult.js +1503 -0
  122. package/dist/esm/ParseResult.js.map +1 -0
  123. package/dist/esm/Predicate.js +2 -1
  124. package/dist/esm/Predicate.js.map +1 -1
  125. package/dist/esm/Pretty.js +173 -0
  126. package/dist/esm/Pretty.js.map +1 -0
  127. package/dist/esm/Schema.js +5328 -0
  128. package/dist/esm/Schema.js.map +1 -0
  129. package/dist/esm/SchemaAST.js +2300 -0
  130. package/dist/esm/SchemaAST.js.map +1 -0
  131. package/dist/esm/Stream.js +14 -0
  132. package/dist/esm/Stream.js.map +1 -1
  133. package/dist/esm/TPubSub.js +8 -0
  134. package/dist/esm/TPubSub.js.map +1 -1
  135. package/dist/esm/TQueue.js.map +1 -1
  136. package/dist/esm/TRef.js.map +1 -1
  137. package/dist/esm/TSubscriptionRef.js +87 -0
  138. package/dist/esm/TSubscriptionRef.js.map +1 -0
  139. package/dist/esm/index.js +32 -0
  140. package/dist/esm/index.js.map +1 -1
  141. package/dist/esm/internal/cause.js +3 -3
  142. package/dist/esm/internal/cause.js.map +1 -1
  143. package/dist/esm/internal/core.js +4 -4
  144. package/dist/esm/internal/core.js.map +1 -1
  145. package/dist/esm/internal/fiberRuntime.js +14 -12
  146. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  147. package/dist/esm/internal/logger.js +7 -6
  148. package/dist/esm/internal/logger.js.map +1 -1
  149. package/dist/esm/internal/redacted.js +4 -0
  150. package/dist/esm/internal/redacted.js.map +1 -1
  151. package/dist/esm/internal/schema/errors.js +87 -0
  152. package/dist/esm/internal/schema/errors.js.map +1 -0
  153. package/dist/esm/internal/schema/filters.js +35 -0
  154. package/dist/esm/internal/schema/filters.js.map +1 -0
  155. package/dist/esm/internal/schema/util.js +78 -0
  156. package/dist/esm/internal/schema/util.js.map +1 -0
  157. package/dist/esm/internal/stm/core.js +1 -2
  158. package/dist/esm/internal/stm/core.js.map +1 -1
  159. package/dist/esm/internal/stm/tPubSub.js.map +1 -1
  160. package/dist/esm/internal/stm/tQueue.js +1 -2
  161. package/dist/esm/internal/stm/tQueue.js.map +1 -1
  162. package/dist/esm/internal/stm/tRef.js +5 -1
  163. package/dist/esm/internal/stm/tRef.js.map +1 -1
  164. package/dist/esm/internal/stm/tSubscriptionRef.js +166 -0
  165. package/dist/esm/internal/stm/tSubscriptionRef.js.map +1 -0
  166. package/dist/esm/internal/stream.js +33 -15
  167. package/dist/esm/internal/stream.js.map +1 -1
  168. package/dist/esm/internal/version.js +1 -1
  169. package/dist/esm/internal/version.js.map +1 -1
  170. package/package.json +68 -1
  171. package/src/Arbitrary.ts +563 -0
  172. package/src/Effect.ts +302 -31
  173. package/src/FastCheck.ts +9 -0
  174. package/src/Inspectable.ts +56 -2
  175. package/src/JSONSchema.ts +601 -0
  176. package/src/ParseResult.ts +2027 -0
  177. package/src/Predicate.ts +3 -1
  178. package/src/Pretty.ts +204 -0
  179. package/src/Schema.ts +10388 -0
  180. package/src/SchemaAST.ts +2827 -0
  181. package/src/Stream.ts +77 -9
  182. package/src/TPubSub.ts +9 -0
  183. package/src/TQueue.ts +7 -7
  184. package/src/TRef.ts +2 -1
  185. package/src/TSubscriptionRef.ts +284 -0
  186. package/src/index.ts +40 -0
  187. package/src/internal/cause.ts +3 -3
  188. package/src/internal/core-effect.ts +2 -2
  189. package/src/internal/core.ts +4 -4
  190. package/src/internal/fiberRuntime.ts +14 -12
  191. package/src/internal/logger.ts +7 -6
  192. package/src/internal/redacted.ts +4 -0
  193. package/src/internal/schema/errors.ts +189 -0
  194. package/src/internal/schema/filters.ts +86 -0
  195. package/src/internal/schema/util.ts +113 -0
  196. package/src/internal/stm/core.ts +1 -2
  197. package/src/internal/stm/tPubSub.ts +1 -0
  198. package/src/internal/stm/tQueue.ts +2 -2
  199. package/src/internal/stm/tRef.ts +7 -2
  200. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  201. package/src/internal/stream.ts +97 -20
  202. 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
+ }