Skip to content

Commit 2f08e73

Browse files
committed
Merge branch 'release/v1.0.14'
2 parents 98e9ffb + 0e63ac3 commit 2f08e73

3 files changed

Lines changed: 87 additions & 23 deletions

File tree

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "zeed",
33
"type": "module",
4-
"version": "1.0.13",
5-
"packageManager": "pnpm@10.15.1",
4+
"version": "1.0.14",
5+
"packageManager": "pnpm@10.17.0",
66
"description": "🌱 Simple foundation library",
77
"author": {
88
"name": "Dirk Holtwick",
@@ -79,17 +79,17 @@
7979
"devDependencies": {
8080
"@antfu/eslint-config": "^5.3.0",
8181
"@antfu/ni": "^25.0.0",
82-
"@types/node": "^24.3.1",
82+
"@types/node": "^24.5.2",
8383
"@vitejs/plugin-vue": "^6.0.1",
8484
"@vitest/browser": "^3.2.4",
8585
"@vitest/coverage-v8": "^3.2.4",
86-
"esbuild": "^0.25.9",
86+
"esbuild": "^0.25.10",
8787
"eslint": "^9.35.0",
8888
"playwright": "^1.55.0",
8989
"pnpm": "^10.12.1",
9090
"tsup": "^8.5.0",
9191
"typescript": "^5.9.2",
92-
"vite": "^7.1.5",
92+
"vite": "^7.1.6",
9393
"vitest": "^3.2.4"
9494
}
9595
}

src/common/schema/export-json-schema.spec.ts

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { Infer } from './schema'
21
import { schemaExportJsonSchema } from './export-json-schema'
32
import { z } from './z'
43

@@ -11,17 +10,32 @@ describe('json-schema.spec', () => {
1110
aNumber: z.number().meta({
1211
desc: 'This is a number',
1312
}),
13+
aRecord: z.record(z.number()),
14+
moreRecords: z.record(z.object({ x: z.string() })).optional(),
15+
anObject: z.object({
16+
a: z.string(),
17+
b: z.number(),
18+
}),
1419
aString: z.string(),
1520
})
1621

17-
type t = Infer<typeof schema>
18-
expectTypeOf<t>().toMatchObjectType<{
19-
fixed: 'a' | 'b' | 'c'
20-
anInt?: number | undefined
21-
aBool: boolean
22-
aNumber: number
23-
aString: string
24-
}>()
22+
// type tInfer = Infer<typeof schema>
23+
24+
// expectTypeOf<tInfer>().toMatchObjectType<{
25+
// anInt?: number | undefined
26+
// moreRecords?: Record<string, {
27+
// x: string
28+
// }> | undefined
29+
// fixed: 'a' | 'b' | 'c'
30+
// aBool: boolean
31+
// aNumber: number
32+
// aRecord: Record<string, number>
33+
// anObject: {
34+
// a: string
35+
// b: number
36+
// }
37+
// aString: string
38+
// }>()
2539

2640
const r = schemaExportJsonSchema(schema)
2741

@@ -38,13 +52,35 @@ describe('json-schema.spec', () => {
3852
"description": "This is a number",
3953
"type": "number",
4054
},
55+
"aRecord": Object {
56+
"additionalProperties": Object {
57+
"type": "number",
58+
},
59+
"type": "object",
60+
},
4161
"aString": Object {
4262
"type": "string",
4363
},
4464
"anInt": Object {
4565
"default": 0,
4666
"type": "integer",
4767
},
68+
"anObject": Object {
69+
"additionalProperties": false,
70+
"properties": Object {
71+
"a": Object {
72+
"type": "string",
73+
},
74+
"b": Object {
75+
"type": "number",
76+
},
77+
},
78+
"required": Array [
79+
"a",
80+
"b",
81+
],
82+
"type": "object",
83+
},
4884
"fixed": Object {
4985
"description": "This is a fixed value",
5086
"enum": Array [
@@ -54,11 +90,28 @@ describe('json-schema.spec', () => {
5490
],
5591
"type": "string",
5692
},
93+
"moreRecords": Object {
94+
"additionalProperties": Object {
95+
"additionalProperties": false,
96+
"properties": Object {
97+
"x": Object {
98+
"type": "string",
99+
},
100+
},
101+
"required": Array [
102+
"x",
103+
],
104+
"type": "object",
105+
},
106+
"type": "object",
107+
},
57108
},
58109
"required": Array [
59110
"fixed",
60111
"aBool",
61112
"aNumber",
113+
"aRecord",
114+
"anObject",
62115
"aString",
63116
],
64117
"type": "object",

src/common/schema/export-json-schema.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { Type } from './schema'
2-
import { assert } from '../assert'
2+
import { isEmpty } from '../data'
33
import { objectMap } from '../data/object'
4-
import { isSchemaObjectFlat } from './utils'
54

65
const _mapJsonSchemaType: Record<string, string> = {
76
string: 'string',
@@ -11,7 +10,7 @@ const _mapJsonSchemaType: Record<string, string> = {
1110
}
1211

1312
export function schemaExportJsonSchema<T>(schema: Type<T>): Record<string, any> {
14-
assert(isSchemaObjectFlat(schema), 'schema should be a flat object')
13+
// assert(isSchemaObjectFlat(schema), 'schema should be a flat object')
1514

1615
function transformSchema(schema: Type<any>): any {
1716
const type = _mapJsonSchemaType[schema.type] ?? schema.type ?? 'object'
@@ -37,25 +36,37 @@ export function schemaExportJsonSchema<T>(schema: Type<T>): Record<string, any>
3736
if (schema.type === 'array' && schema._type) {
3837
properties[key].items = transformSchema(schema._type)
3938
}
40-
if (schema.type === 'object' && schema._object) {
41-
Object.assign(properties[key], transformSchema(schema._object))
39+
else if (schema.type === 'object' && schema._object) {
40+
Object.assign(properties[key], transformSchema(schema))
41+
properties[key].additionalProperties = false
42+
}
43+
else if (schema.type === 'record' && schema._type) {
44+
properties[key].type = 'object'
45+
properties[key].additionalProperties = transformSchema(schema._type)
4246
}
4347
// Handle union types (e.g., z.union)
44-
if (schema.type === 'union' && Array.isArray(schema._union)) {
48+
else if (schema.type === 'union' && Array.isArray(schema._union)) {
4549
properties[key].type = schema._union.map((s: any) => _mapJsonSchemaType[s.type] ?? s.type) // todo complex types
4650
}
4751
})
4852

53+
if (!isEmpty(properties)) {
54+
return {
55+
type,
56+
properties,
57+
additionalProperties: false,
58+
...(required.length > 0 ? { required } : {}),
59+
}
60+
}
61+
4962
return {
5063
type,
51-
additionalProperties: false,
52-
properties,
53-
...(required.length > 0 ? { required } : {}),
5464
}
5565
}
5666

5767
return {
5868
$schema: 'http://json-schema.org/draft-07/schema#',
69+
additionalProperties: false,
5970
...transformSchema(schema),
6071
}
6172
}

0 commit comments

Comments
 (0)