1import * as Schema from "effect/Schema"
2import * as SchemaParser from "effect/SchemaParser"
3import * as SchemaTransformation from "effect/SchemaTransformation"
4import assert from "node:assert/strict"
5
6const size = 32
7const input = Object.fromEntries(Array.from({ length: size }, (_, index) => [`field${index}`, `value${index}`]))
8
9const makeEffectCheckedSchema = () =>
10 Schema.Struct(
11 Object.fromEntries(Array.from({ length: size }, (_, index) => [`field${index}`, Schema.NonEmptyString]))
12 )
13
14const makeEffectTemplateLiteralSchema = () =>
15 Schema.TemplateLiteral(["prefix-", Schema.String, "-middle-", Schema.Number, "-suffix"])
16
17const templateLiteral256Parts = Array.from({ length: 256 }, (_, index) => Schema.Literal(`part${index}`))
18const makeEffectTemplateLiteral256Schema = () => Schema.TemplateLiteral(templateLiteral256Parts)
19
20const makeEffectRecordSchema = () => Schema.Record(Schema.String, Schema.String)
21const makeEffectEncodedRecordSchema = () =>
22 Schema.Record(
23 Schema.String.pipe(Schema.decodeTo(Schema.Number, SchemaTransformation.passthrough())),
24 Schema.String
25 )
26
27const makeEffectObject2Schema = () =>
28 Schema.Struct({
29 name: Schema.String,
30 age: Schema.Number
31 })
32
33const makeEffectEncodedObject8Schema = () => {
34 const amount = Schema.String.pipe(Schema.decodeTo(
35 Schema.Number.check(Schema.isGreaterThanOrEqualTo(0)),
36 SchemaTransformation.numberFromString
37 ))
38 return Schema.fromJsonString(Schema.Struct({
39 id: Schema.String,
40 name: Schema.String.check(Schema.isMinLength(1)),
41 price: amount,
42 quantity: amount,
43 active: Schema.Boolean,
44 address: Schema.Struct({ city: Schema.String, country: Schema.String }),
45 tags: Schema.Array(Schema.String).check(Schema.isMinLength(1)),
46 note: Schema.optionalKey(Schema.String)
47 }))
48}
49
50const encodedObject8Value = {
51 id: "product-1",
52 name: "Product",
53 price: 12,
54 quantity: 2,
55 active: true,
56 address: { city: "Rome", country: "IT" },
57 tags: ["new"]
58}
59const encodedObject8Input = JSON.stringify({ ...encodedObject8Value, price: "12", quantity: "2" })
60
61const makeObjectFields = (size: number) =>
62 Object.fromEntries(Array.from({ length: size }, (_, index) => [`field${index}`, Schema.NonEmptyString]))
63
64const object32Fields = makeObjectFields(32)
65const object256Fields = makeObjectFields(256)
66
67const makeEffectObject32Schema = () => Schema.Struct(object32Fields)
68const makeEffectObject256Schema = () => Schema.Struct(object256Fields)
69
70const object2Input = { name: "John", age: 42 }
71
72const literalValues100 = Array.from({ length: 100 }, (_, index) => `value${index}`)
73
74const makeEffectLiteral100Schema = () => Schema.Literals(literalValues100)
75
76const makeEffectTaggedMember = (index) =>
77 Schema.Struct({
78 kind: Schema.Literal(`kind${index}`),
79 a: Schema.String,
80 b: Schema.Number,
81 c: Schema.Boolean
82 })
83
84const makeEffectTagged100Schema = () =>
85 Schema.Union(Array.from({ length: 100 }, (_, index) => makeEffectTaggedMember(index)))
86
87const taggedInput = {
88 kind: "kind99",
89 a: "a",
90 b: 1,
91 c: true
92}
93
94const makeEffectEncodingChain = (size) => {
95 let schema = Schema.FiniteFromString
96 for (let i = 1; i < size; i++) {
97 schema = Schema.String.pipe(
98 Schema.decodeTo(schema, SchemaTransformation.passthrough())
99 )
100 }
101 return schema
102}
103
104export const effectSchemaCreationTemplateLiteral = () => ({
105 run: makeEffectTemplateLiteralSchema,
106 validate: (schema) => assert.equal(schema.ast._tag, "TemplateLiteral")
107})
108
109export const effectSchemaCreationTemplateLiteral256 = () => ({
110 run: makeEffectTemplateLiteral256Schema,
111 validate: (schema) => assert.equal(schema.ast._tag, "TemplateLiteral")
112})
113
114export const effectSchemaCreationObject2 = () => ({
115 run: makeEffectObject2Schema,
116 validate: (schema) => assert.equal(schema.ast._tag, "Objects")
117})
118
119export const effectSchemaCreationObject32 = () => ({
120 run: makeEffectObject32Schema,
121 validate: (schema) => assert.equal(schema.ast._tag, "Objects")
122})
123
124export const effectSchemaCreationObject256 = () => ({
125 run: makeEffectObject256Schema,
126 validate: (schema) => assert.equal(schema.ast._tag, "Objects")
127})
128
129export const effectSchemaCreationEncodedRecord = () => ({
130 run: makeEffectEncodedRecordSchema,
131 validate: (schema) => assert.equal(schema.ast._tag, "Objects")
132})
133
134export const effectFirstMakeObject2 = () => ({
135 run: () => makeEffectObject2Schema().make(object2Input),
136 validate: (result) => assert.deepEqual(result, object2Input)
137})
138
139export const effectSchemaCreationEncodedObject8 = () => ({
140 run: makeEffectEncodedObject8Schema,
141 validate: (schema) => {
142 assert.deepEqual(Schema.decodeUnknownSync(schema)(encodedObject8Input), encodedObject8Value)
143 assert.deepEqual(schema.make(encodedObject8Value), encodedObject8Value)
144 assert.throws(() => schema.make({ ...encodedObject8Value, price: -1 }))
145 }
146})
147
148export const effectFirstMakeEncodedObject8 = () => ({
149 run: () => makeEffectEncodedObject8Schema().make(encodedObject8Value),
150 validate: (result) => assert.deepEqual(result, encodedObject8Value)
151})
152
153export const effectFirstDecodeCheckedObject32 = () => ({
154 run: () => SchemaParser.decodeUnknownExit(makeEffectCheckedSchema())(input),
155 validate: (result) => {
156 assert.equal(result._tag, "Success")
157 assert.deepEqual(result.value, input)
158 }
159})
160
161export const effectFirstDecodeTemplateLiteral = () => ({
162 run: () => SchemaParser.decodeUnknownExit(makeEffectTemplateLiteralSchema())("prefix-value-middle-123-suffix"),
163 validate: (result) => assert.equal(result._tag, "Success")
164})
165
166export const effectFirstDecodeRecord32 = () => ({
167 run: () => SchemaParser.decodeUnknownExit(makeEffectRecordSchema())(input),
168 validate: (result) => {
169 assert.equal(result._tag, "Success")
170 assert.deepEqual(result.value, input)
171 }
172})
173
174export const effectFirstDecodeLiteral100 = () => ({
175 run: () => SchemaParser.decodeUnknownExit(makeEffectLiteral100Schema())("value99"),
176 validate: (result) => {
177 assert.equal(result._tag, "Success")
178 assert.equal(result.value, "value99")
179 }
180})
181
182export const effectFirstDecodeTagged100 = () => ({
183 run: () => SchemaParser.decodeUnknownExit(makeEffectTagged100Schema())(taggedInput),
184 validate: (result) => {
185 assert.equal(result._tag, "Success")
186 assert.deepEqual(result.value, taggedInput)
187 }
188})
189
190export const effectFirstDecodeEncodingChain8 = () => ({
191 run: () => SchemaParser.decodeUnknownExit(makeEffectEncodingChain(8))("123"),
192 validate: (result) => {
193 assert.equal(result._tag, "Success")
194 assert.equal(result.value, 123)
195 }
196})