Skip to content

Commit 8d48b83

Browse files
committed
feat: 🎸 bump dependency and add fixtures
1 parent 4e41c9c commit 8d48b83

File tree

3 files changed

+217
-6
lines changed

3 files changed

+217
-6
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"@jsonjoy.com/buffers": "^1.0.0",
6060
"@jsonjoy.com/codegen": "^1.0.0",
6161
"@jsonjoy.com/json-expression": "^1.1.0",
62-
"@jsonjoy.com/json-pack": "^1.9.0",
62+
"@jsonjoy.com/json-pack": "^1.9.1",
6363
"@jsonjoy.com/json-random": "^1.2.0",
6464
"@jsonjoy.com/util": "^1.9.0",
6565
"sonic-forest": "^1.2.1",

src/__tests__/fixtures.ts

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import {s} from '../schema';
8+
import {t} from '../type';
89
import {genRandomExample} from '@jsonjoy.com/json-random/lib/examples';
910
import {RandomJson} from '@jsonjoy.com/json-random';
1011

@@ -76,3 +77,213 @@ export const schemaCategories = {
7677
composites: compositeSchemas,
7778
all: allSchemas,
7879
} as const;
80+
81+
/**
82+
* User profile schema with nested objects and optional fields
83+
*/
84+
export const User = t
85+
.object({
86+
id: t.str,
87+
name: t.object({
88+
first: t.str,
89+
last: t.str,
90+
}),
91+
email: t.String({format: 'ascii'}),
92+
age: t.Number({gte: 0, lte: 150}),
93+
verified: t.bool,
94+
})
95+
.opt('avatar', t.String({format: 'ascii'}));
96+
97+
/**
98+
* Product catalog schema with arrays and formatted numbers
99+
*/
100+
export const Product = t.Object(
101+
t.prop('id', t.String({format: 'ascii'})),
102+
t.prop('name', t.String({min: 1, max: 100})),
103+
t.prop('price', t.Number({format: 'f64', gte: 0})),
104+
t.prop('inStock', t.bool),
105+
t.prop('categories', t.Array(t.str, {min: 1})),
106+
t.prop('tags', t.Array(t.str)),
107+
t.propOpt('description', t.String({max: 1000})),
108+
t.propOpt('discount', t.Number({gte: 0, lte: 1})),
109+
);
110+
111+
/**
112+
* Blog post schema with timestamps and rich content
113+
*/
114+
export const BlogPost = t.Object(
115+
t.prop('id', t.str),
116+
t.prop('title', t.String({min: 1, max: 200})),
117+
t.prop('content', t.str),
118+
t.prop('author', t.Ref<typeof User>('User')),
119+
t.prop('publishedAt', t.Number({format: 'u64'})),
120+
t.prop('status', t.enum('draft', 'published', 'archived')),
121+
t.propOpt('updatedAt', t.Number({format: 'u64'})),
122+
t.propOpt('tags', t.Array(t.str)),
123+
);
124+
125+
/**
126+
* API response schema with discriminated unions
127+
*/
128+
export const ApiResponse = t.Or(
129+
t.object({
130+
success: t.Const(true),
131+
data: t.any,
132+
timestamp: t.Number({format: 'u64'}),
133+
}),
134+
t.object({
135+
success: t.Const(false),
136+
error: t.object({
137+
code: t.String({format: 'ascii'}),
138+
message: t.str,
139+
}),
140+
timestamp: t.Number({format: 'u64'}),
141+
}),
142+
);
143+
144+
/**
145+
* File metadata schema with binary data
146+
*/
147+
export const FileMetadata = t.Object(
148+
t.prop('name', t.str),
149+
t.prop('size', t.Number({format: 'u64', gte: 0})),
150+
t.prop('mimeType', t.str),
151+
t.prop('data', t.Binary(t.any)),
152+
t.prop('checksum', t.String({format: 'ascii', min: 64, max: 64})),
153+
t.prop('uploadedAt', t.Number({format: 'u64'})),
154+
t.propOpt('metadata', t.Map(t.str)),
155+
);
156+
157+
/**
158+
* Configuration schema with maps and default values
159+
*/
160+
export const Configuration = t.Object(
161+
t.prop('environment', t.enum('development', 'staging', 'production')),
162+
t.prop(
163+
'database',
164+
t.object({
165+
host: t.str,
166+
port: t.Number({format: 'u16', gte: 1, lte: 65535}),
167+
name: t.str,
168+
}),
169+
),
170+
t.prop('features', t.Map(t.bool)),
171+
t.prop('secrets', t.Map(t.str)),
172+
t.propOpt(
173+
'logging',
174+
t.object({
175+
level: t.enum('debug', 'info', 'warn', 'error'),
176+
output: t.str,
177+
}),
178+
),
179+
);
180+
181+
/**
182+
* Event data schema with tuples and coordinates
183+
*/
184+
export const Event = t.Object(
185+
t.prop('id', t.String({format: 'ascii'})),
186+
t.prop('type', t.enum('click', 'view', 'purchase', 'signup')),
187+
t.prop('timestamp', t.Number({format: 'u64'})),
188+
t.prop('userId', t.maybe(t.str)),
189+
t.prop('location', t.Tuple([t.Number({format: 'f64'}), t.Number({format: 'f64'})])),
190+
t.prop('metadata', t.Map(t.Or(t.str, t.num, t.bool))),
191+
t.propOpt('sessionId', t.str),
192+
);
193+
194+
/**
195+
* Contact information schema with formatted strings
196+
*/
197+
export const ContactInfo = t.Object(
198+
t.prop(
199+
'name',
200+
t.object({
201+
first: t.String({min: 1}),
202+
last: t.String({min: 1}),
203+
}),
204+
),
205+
t.prop('emails', t.Array(t.String({format: 'ascii'}), {min: 1})),
206+
t.prop('phones', t.Array(t.tuple(t.enum('home', 'work', 'mobile'), t.str))),
207+
t.propOpt(
208+
'address',
209+
t.object({
210+
street: t.str,
211+
city: t.str,
212+
country: t.String({format: 'ascii', min: 2, max: 2}),
213+
postalCode: t.str,
214+
}),
215+
),
216+
t.propOpt('socialMedia', t.Map(t.String({format: 'ascii'}))),
217+
);
218+
219+
/**
220+
* Database record schema with references
221+
*/
222+
export const DatabaseRecord = t.Object(
223+
t.prop('id', t.String({format: 'ascii'})),
224+
t.prop('createdAt', t.Number({format: 'u64'})),
225+
t.prop('updatedAt', t.Number({format: 'u64'})),
226+
t.prop('version', t.Number({format: 'u32', gte: 1})),
227+
t.prop('createdBy', t.Ref<typeof User>('User')),
228+
t.propOpt('updatedBy', t.Ref<typeof User>('User')),
229+
t.propOpt('deletedAt', t.Number({format: 'u64'})),
230+
);
231+
232+
/**
233+
* Function type schema
234+
*/
235+
export const UserValidator = t.Function(
236+
t.object({
237+
userData: t.any,
238+
strict: t.bool,
239+
}),
240+
t.object({
241+
valid: t.bool,
242+
errors: t.Array(t.str),
243+
}),
244+
{title: 'User Validation Function'},
245+
);
246+
247+
/**
248+
* Streaming API schema
249+
*/
250+
export const EventStream = t.Function$(
251+
t.object({
252+
filter: t.maybe(t.str),
253+
limit: t.maybe(t.Number({format: 'u32'})),
254+
}),
255+
t.Ref<typeof Event>('Event'),
256+
{title: 'Event Streaming Function'},
257+
);
258+
259+
/**
260+
* Complex nested schema
261+
*/
262+
export const ComplexNested = t.Object(
263+
t.prop(
264+
'data',
265+
t.Map(
266+
t.Or(
267+
t.str,
268+
t.num,
269+
t.Array(
270+
t.Map(
271+
t.object({
272+
key: t.str,
273+
value: t.Or(t.str, t.num, t.bool, t.nil),
274+
nested: t.maybe(t.Map(t.any)),
275+
}),
276+
),
277+
),
278+
),
279+
),
280+
),
281+
t.prop(
282+
'metadata',
283+
t.object({
284+
version: t.str,
285+
schema: t.String({format: 'ascii'}),
286+
checksum: t.String({format: 'ascii'}),
287+
}),
288+
),
289+
);

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -829,9 +829,9 @@ __metadata:
829829
languageName: node
830830
linkType: hard
831831

832-
"@jsonjoy.com/json-pack@npm:^1.9.0":
833-
version: 1.9.0
834-
resolution: "@jsonjoy.com/json-pack@npm:1.9.0"
832+
"@jsonjoy.com/json-pack@npm:^1.9.1":
833+
version: 1.9.1
834+
resolution: "@jsonjoy.com/json-pack@npm:1.9.1"
835835
dependencies:
836836
"@jsonjoy.com/base64": "npm:^1.1.2"
837837
"@jsonjoy.com/buffers": "npm:^1.0.0"
@@ -842,7 +842,7 @@ __metadata:
842842
thingies: "npm:^2.5.0"
843843
peerDependencies:
844844
tslib: 2
845-
checksum: 10c0/df3c348eef05727adb64bb68e9ad92efe72c6c7d60927b0302d2919f54b4a5e4a5a416cf778c3cddf1c1c4f7720606f4b0c910128127bf567ee734782021264d
845+
checksum: 10c0/af57a3863dada6762b413e8a745e17e95a7b84cef5e778320b5451cad2bca516e863ced4c934e2c7d2a5e5d0a6c8e08850579ac07ebad7be43b6ce31d93dd5d0
846846
languageName: node
847847
linkType: hard
848848

@@ -887,7 +887,7 @@ __metadata:
887887
"@jsonjoy.com/buffers": "npm:^1.0.0"
888888
"@jsonjoy.com/codegen": "npm:^1.0.0"
889889
"@jsonjoy.com/json-expression": "npm:^1.1.0"
890-
"@jsonjoy.com/json-pack": "npm:^1.9.0"
890+
"@jsonjoy.com/json-pack": "npm:^1.9.1"
891891
"@jsonjoy.com/json-random": "npm:^1.2.0"
892892
"@jsonjoy.com/util": "npm:^1.9.0"
893893
"@types/benchmark": "npm:^2.1.5"

0 commit comments

Comments
 (0)