@ai-sdk/provider-utils 4.0.5 → 4.0.6
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/CHANGELOG.md +8 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -2
- package/src/__snapshots__/schema.test.ts.snap +346 -0
- package/src/add-additional-properties-to-json-schema.test.ts +289 -0
- package/src/add-additional-properties-to-json-schema.ts +53 -0
- package/src/combine-headers.ts +11 -0
- package/src/convert-async-iterator-to-readable-stream.test.ts +78 -0
- package/src/convert-async-iterator-to-readable-stream.ts +47 -0
- package/src/convert-image-model-file-to-data-uri.test.ts +85 -0
- package/src/convert-image-model-file-to-data-uri.ts +19 -0
- package/src/convert-to-form-data.test.ts +167 -0
- package/src/convert-to-form-data.ts +61 -0
- package/src/create-tool-name-mapping.test.ts +163 -0
- package/src/create-tool-name-mapping.ts +66 -0
- package/src/delay.test.ts +212 -0
- package/src/delay.ts +47 -0
- package/src/delayed-promise.test.ts +132 -0
- package/src/delayed-promise.ts +61 -0
- package/src/download-blob.test.ts +145 -0
- package/src/download-blob.ts +31 -0
- package/src/download-error.ts +39 -0
- package/src/extract-response-headers.ts +9 -0
- package/src/fetch-function.ts +4 -0
- package/src/generate-id.test.ts +31 -0
- package/src/generate-id.ts +57 -0
- package/src/get-error-message.ts +15 -0
- package/src/get-from-api.test.ts +199 -0
- package/src/get-from-api.ts +97 -0
- package/src/get-runtime-environment-user-agent.test.ts +47 -0
- package/src/get-runtime-environment-user-agent.ts +24 -0
- package/src/handle-fetch-error.ts +39 -0
- package/src/index.ts +67 -0
- package/src/inject-json-instruction.test.ts +404 -0
- package/src/inject-json-instruction.ts +63 -0
- package/src/is-abort-error.ts +8 -0
- package/src/is-async-iterable.ts +3 -0
- package/src/is-non-nullable.ts +12 -0
- package/src/is-url-supported.test.ts +282 -0
- package/src/is-url-supported.ts +40 -0
- package/src/load-api-key.ts +45 -0
- package/src/load-optional-setting.ts +30 -0
- package/src/load-setting.ts +62 -0
- package/src/maybe-promise-like.ts +3 -0
- package/src/media-type-to-extension.test.ts +26 -0
- package/src/media-type-to-extension.ts +22 -0
- package/src/normalize-headers.test.ts +64 -0
- package/src/normalize-headers.ts +38 -0
- package/src/parse-json-event-stream.ts +33 -0
- package/src/parse-json.test.ts +191 -0
- package/src/parse-json.ts +122 -0
- package/src/parse-provider-options.ts +32 -0
- package/src/post-to-api.ts +166 -0
- package/src/provider-tool-factory.ts +125 -0
- package/src/remove-undefined-entries.test.ts +57 -0
- package/src/remove-undefined-entries.ts +12 -0
- package/src/resolve.test.ts +125 -0
- package/src/resolve.ts +17 -0
- package/src/response-handler.test.ts +89 -0
- package/src/response-handler.ts +187 -0
- package/src/schema.test-d.ts +11 -0
- package/src/schema.test.ts +502 -0
- package/src/schema.ts +267 -0
- package/src/secure-json-parse.test.ts +59 -0
- package/src/secure-json-parse.ts +92 -0
- package/src/test/convert-array-to-async-iterable.ts +9 -0
- package/src/test/convert-array-to-readable-stream.ts +15 -0
- package/src/test/convert-async-iterable-to-array.ts +9 -0
- package/src/test/convert-readable-stream-to-array.ts +14 -0
- package/src/test/convert-response-stream-to-array.ts +9 -0
- package/src/test/index.ts +7 -0
- package/src/test/is-node-version.ts +4 -0
- package/src/test/mock-id.ts +8 -0
- package/src/to-json-schema/zod3-to-json-schema/LICENSE +16 -0
- package/src/to-json-schema/zod3-to-json-schema/README.md +24 -0
- package/src/to-json-schema/zod3-to-json-schema/get-relative-path.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/index.ts +1 -0
- package/src/to-json-schema/zod3-to-json-schema/options.ts +98 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +224 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-def.ts +109 -0
- package/src/to-json-schema/zod3-to-json-schema/parse-types.ts +57 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/any.ts +5 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +98 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.ts +38 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +51 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.ts +44 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/boolean.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +16 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +15 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +97 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +64 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +54 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.ts +14 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +41 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.ts +14 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/enum.ts +13 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +92 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +52 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/literal.ts +29 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +48 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.ts +47 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +102 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.ts +31 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/never.ts +9 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/null.ts +9 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +67 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.ts +42 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +65 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.ts +44 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +149 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.ts +88 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +147 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.ts +23 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +35 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipeline.ts +29 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +15 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.ts +11 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +20 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +108 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +71 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +20 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.ts +35 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +438 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.ts +426 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +33 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.ts +61 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/undefined.ts +11 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +226 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.ts +144 -0
- package/src/to-json-schema/zod3-to-json-schema/parsers/unknown.ts +7 -0
- package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +919 -0
- package/src/to-json-schema/zod3-to-json-schema/refs.ts +39 -0
- package/src/to-json-schema/zod3-to-json-schema/select-parser.ts +115 -0
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +862 -0
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.ts +93 -0
- package/src/types/assistant-model-message.ts +39 -0
- package/src/types/content-part.ts +379 -0
- package/src/types/data-content.ts +4 -0
- package/src/types/execute-tool.ts +27 -0
- package/src/types/index.ts +40 -0
- package/src/types/model-message.ts +14 -0
- package/src/types/provider-options.ts +9 -0
- package/src/types/system-model-message.ts +20 -0
- package/src/types/tool-approval-request.ts +16 -0
- package/src/types/tool-approval-response.ts +27 -0
- package/src/types/tool-call.ts +31 -0
- package/src/types/tool-model-message.ts +23 -0
- package/src/types/tool-result.ts +35 -0
- package/src/types/tool.test-d.ts +193 -0
- package/src/types/tool.ts +324 -0
- package/src/types/user-model-message.ts +22 -0
- package/src/uint8-utils.ts +26 -0
- package/src/validate-types.test.ts +105 -0
- package/src/validate-types.ts +81 -0
- package/src/version.ts +6 -0
- package/src/with-user-agent-suffix.test.ts +84 -0
- package/src/with-user-agent-suffix.ts +27 -0
- package/src/without-trailing-slash.ts +3 -0
- package/LICENSE +0 -13
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod/v3';
|
|
3
|
+
import { parsePipelineDef } from './pipeline';
|
|
4
|
+
import { getRefs } from '../refs';
|
|
5
|
+
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
6
|
+
|
|
7
|
+
describe('pipe', () => {
|
|
8
|
+
it('Should create an allOf schema with all its inner schemas represented', () => {
|
|
9
|
+
const schema = z.number().pipe(z.number().int());
|
|
10
|
+
|
|
11
|
+
expect(parsePipelineDef(schema._def, getRefs())).toStrictEqual({
|
|
12
|
+
allOf: [{ type: 'number' }, { type: 'integer' }],
|
|
13
|
+
} satisfies JSONSchema7);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('Should parse the input schema if that strategy is selected', () => {
|
|
17
|
+
const schema = z.number().pipe(z.number().int());
|
|
18
|
+
|
|
19
|
+
expect(
|
|
20
|
+
parsePipelineDef(schema._def, getRefs({ pipeStrategy: 'input' })),
|
|
21
|
+
).toStrictEqual({
|
|
22
|
+
type: 'number',
|
|
23
|
+
} satisfies JSONSchema7);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('Should parse the output schema (last schema in pipe) if that strategy is selected', () => {
|
|
27
|
+
const schema = z.string().pipe(z.date()).pipe(z.number().int());
|
|
28
|
+
|
|
29
|
+
expect(
|
|
30
|
+
parsePipelineDef(schema._def, getRefs({ pipeStrategy: 'output' })),
|
|
31
|
+
).toStrictEqual({
|
|
32
|
+
type: 'integer',
|
|
33
|
+
} satisfies JSONSchema7);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ZodPipelineDef } from 'zod/v3';
|
|
2
|
+
import { parseDef } from '../parse-def';
|
|
3
|
+
import { JsonSchema7Type } from '../parse-types';
|
|
4
|
+
import { Refs } from '../refs';
|
|
5
|
+
import { JsonSchema7AllOfType } from './intersection';
|
|
6
|
+
|
|
7
|
+
export const parsePipelineDef = (
|
|
8
|
+
def: ZodPipelineDef<any, any>,
|
|
9
|
+
refs: Refs,
|
|
10
|
+
): JsonSchema7AllOfType | JsonSchema7Type | undefined => {
|
|
11
|
+
if (refs.pipeStrategy === 'input') {
|
|
12
|
+
return parseDef(def.in._def, refs);
|
|
13
|
+
} else if (refs.pipeStrategy === 'output') {
|
|
14
|
+
return parseDef(def.out._def, refs);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const a = parseDef(def.in._def, {
|
|
18
|
+
...refs,
|
|
19
|
+
currentPath: [...refs.currentPath, 'allOf', '0'],
|
|
20
|
+
});
|
|
21
|
+
const b = parseDef(def.out._def, {
|
|
22
|
+
...refs,
|
|
23
|
+
currentPath: [...refs.currentPath, 'allOf', a ? '1' : '0'],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
allOf: [a, b].filter((x): x is JsonSchema7Type => x !== undefined),
|
|
28
|
+
};
|
|
29
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod/v3';
|
|
3
|
+
import { parsePromiseDef } from './promise';
|
|
4
|
+
import { getRefs } from '../refs';
|
|
5
|
+
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
6
|
+
|
|
7
|
+
describe('promise', () => {
|
|
8
|
+
it('should be possible to use promise', () => {
|
|
9
|
+
const parsedSchema = parsePromiseDef(z.promise(z.string())._def, getRefs());
|
|
10
|
+
|
|
11
|
+
expect(parsedSchema).toStrictEqual({
|
|
12
|
+
type: 'string',
|
|
13
|
+
} satisfies JSONSchema7);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ZodPromiseDef } from 'zod/v3';
|
|
2
|
+
import { parseDef } from '../parse-def';
|
|
3
|
+
import { JsonSchema7Type } from '../parse-types';
|
|
4
|
+
import { Refs } from '../refs';
|
|
5
|
+
|
|
6
|
+
export function parsePromiseDef(
|
|
7
|
+
def: ZodPromiseDef,
|
|
8
|
+
refs: Refs,
|
|
9
|
+
): JsonSchema7Type | undefined {
|
|
10
|
+
return parseDef(def.type._def, refs);
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod/v3';
|
|
3
|
+
import { parseReadonlyDef } from './readonly';
|
|
4
|
+
import { getRefs } from '../refs';
|
|
5
|
+
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
6
|
+
|
|
7
|
+
describe('readonly', () => {
|
|
8
|
+
it('should be possible to use readonly', () => {
|
|
9
|
+
const parsedSchema = parseReadonlyDef(
|
|
10
|
+
z.object({}).readonly()._def,
|
|
11
|
+
getRefs(),
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(parsedSchema).toStrictEqual({
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {},
|
|
17
|
+
additionalProperties: false,
|
|
18
|
+
} satisfies JSONSchema7);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod/v3';
|
|
3
|
+
import { parseRecordDef } from './record';
|
|
4
|
+
import { getRefs } from '../refs';
|
|
5
|
+
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
6
|
+
|
|
7
|
+
describe('record', () => {
|
|
8
|
+
it('should be possible to describe a simple record', () => {
|
|
9
|
+
const schema = z.record(z.number());
|
|
10
|
+
|
|
11
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
12
|
+
|
|
13
|
+
expect(parsedSchema).toStrictEqual({
|
|
14
|
+
type: 'object',
|
|
15
|
+
additionalProperties: {
|
|
16
|
+
type: 'number',
|
|
17
|
+
},
|
|
18
|
+
} satisfies JSONSchema7);
|
|
19
|
+
});
|
|
20
|
+
it('should be possible to describe a simple record with a branded key', () => {
|
|
21
|
+
const schema = z.record(z.string().brand('MyBrand'), z.number());
|
|
22
|
+
|
|
23
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
24
|
+
|
|
25
|
+
expect(parsedSchema).toStrictEqual({
|
|
26
|
+
type: 'object',
|
|
27
|
+
additionalProperties: {
|
|
28
|
+
type: 'number',
|
|
29
|
+
},
|
|
30
|
+
} satisfies JSONSchema7);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should be possible to describe a complex record with checks', () => {
|
|
34
|
+
const schema = z.record(
|
|
35
|
+
z.object({ foo: z.number().min(2) }).catchall(z.string().cuid()),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
39
|
+
|
|
40
|
+
expect(parsedSchema).toStrictEqual({
|
|
41
|
+
type: 'object',
|
|
42
|
+
additionalProperties: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
foo: {
|
|
46
|
+
type: 'number',
|
|
47
|
+
minimum: 2,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ['foo'],
|
|
51
|
+
additionalProperties: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
pattern: '^[cC][^\\s-]{8,}$',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
} satisfies JSONSchema7);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should be possible to describe a key schema', () => {
|
|
60
|
+
const schema = z.record(z.string().uuid(), z.number());
|
|
61
|
+
|
|
62
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
63
|
+
|
|
64
|
+
expect(parsedSchema).toStrictEqual({
|
|
65
|
+
type: 'object',
|
|
66
|
+
additionalProperties: {
|
|
67
|
+
type: 'number',
|
|
68
|
+
},
|
|
69
|
+
propertyNames: {
|
|
70
|
+
format: 'uuid',
|
|
71
|
+
},
|
|
72
|
+
} satisfies JSONSchema7);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should be possible to describe a branded key schema', () => {
|
|
76
|
+
const schema = z.record(
|
|
77
|
+
z.string().regex(/.+/).brand('MyBrandedThingo'),
|
|
78
|
+
z.number(),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
82
|
+
|
|
83
|
+
expect(parsedSchema).toStrictEqual({
|
|
84
|
+
type: 'object',
|
|
85
|
+
additionalProperties: {
|
|
86
|
+
type: 'number',
|
|
87
|
+
},
|
|
88
|
+
propertyNames: {
|
|
89
|
+
pattern: '.+',
|
|
90
|
+
},
|
|
91
|
+
} satisfies JSONSchema7);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should be possible to describe a key with an enum', () => {
|
|
95
|
+
const schema = z.record(z.enum(['foo', 'bar']), z.number());
|
|
96
|
+
const parsedSchema = parseRecordDef(schema._def, getRefs());
|
|
97
|
+
|
|
98
|
+
expect(parsedSchema).toStrictEqual({
|
|
99
|
+
type: 'object',
|
|
100
|
+
additionalProperties: {
|
|
101
|
+
type: 'number',
|
|
102
|
+
},
|
|
103
|
+
propertyNames: {
|
|
104
|
+
enum: ['foo', 'bar'],
|
|
105
|
+
},
|
|
106
|
+
} satisfies JSONSchema7);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ZodFirstPartyTypeKind,
|
|
3
|
+
ZodMapDef,
|
|
4
|
+
ZodRecordDef,
|
|
5
|
+
ZodTypeAny,
|
|
6
|
+
} from 'zod/v3';
|
|
7
|
+
import { parseDef } from '../parse-def';
|
|
8
|
+
import { JsonSchema7Type } from '../parse-types';
|
|
9
|
+
import { Refs } from '../refs';
|
|
10
|
+
import { parseBrandedDef } from './branded';
|
|
11
|
+
import { JsonSchema7EnumType } from './enum';
|
|
12
|
+
import { JsonSchema7StringType, parseStringDef } from './string';
|
|
13
|
+
|
|
14
|
+
type JsonSchema7RecordPropertyNamesType =
|
|
15
|
+
| Omit<JsonSchema7StringType, 'type'>
|
|
16
|
+
| Omit<JsonSchema7EnumType, 'type'>;
|
|
17
|
+
|
|
18
|
+
export type JsonSchema7RecordType = {
|
|
19
|
+
type: 'object';
|
|
20
|
+
additionalProperties?: JsonSchema7Type | true;
|
|
21
|
+
propertyNames?: JsonSchema7RecordPropertyNamesType;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function parseRecordDef(
|
|
25
|
+
def: ZodRecordDef<ZodTypeAny, ZodTypeAny> | ZodMapDef,
|
|
26
|
+
refs: Refs,
|
|
27
|
+
): JsonSchema7RecordType {
|
|
28
|
+
const schema: JsonSchema7RecordType = {
|
|
29
|
+
type: 'object',
|
|
30
|
+
additionalProperties:
|
|
31
|
+
parseDef(def.valueType._def, {
|
|
32
|
+
...refs,
|
|
33
|
+
currentPath: [...refs.currentPath, 'additionalProperties'],
|
|
34
|
+
}) ?? refs.allowedAdditionalProperties,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (
|
|
38
|
+
def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodString &&
|
|
39
|
+
def.keyType._def.checks?.length
|
|
40
|
+
) {
|
|
41
|
+
const { type, ...keyType } = parseStringDef(def.keyType._def, refs);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
...schema,
|
|
45
|
+
propertyNames: keyType,
|
|
46
|
+
};
|
|
47
|
+
} else if (def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) {
|
|
48
|
+
return {
|
|
49
|
+
...schema,
|
|
50
|
+
propertyNames: {
|
|
51
|
+
enum: def.keyType._def.values,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
} else if (
|
|
55
|
+
def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodBranded &&
|
|
56
|
+
def.keyType._def.type._def.typeName === ZodFirstPartyTypeKind.ZodString &&
|
|
57
|
+
def.keyType._def.type._def.checks?.length
|
|
58
|
+
) {
|
|
59
|
+
const { type, ...keyType } = parseBrandedDef(
|
|
60
|
+
def.keyType._def,
|
|
61
|
+
refs,
|
|
62
|
+
) as JsonSchema7StringType;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
...schema,
|
|
66
|
+
propertyNames: keyType,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return schema;
|
|
71
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
3
|
+
import { z } from 'zod/v3';
|
|
4
|
+
import { getRefs } from '../refs';
|
|
5
|
+
import { parseSetDef } from './set';
|
|
6
|
+
|
|
7
|
+
describe('set', () => {
|
|
8
|
+
it('should map set', () => {
|
|
9
|
+
const zodSchema = z.set(z.any()).min(5).max(10);
|
|
10
|
+
const jsonParsedSchema = parseSetDef(zodSchema._def, getRefs());
|
|
11
|
+
|
|
12
|
+
expect(jsonParsedSchema).toStrictEqual({
|
|
13
|
+
type: 'array',
|
|
14
|
+
minItems: 5,
|
|
15
|
+
maxItems: 10,
|
|
16
|
+
uniqueItems: true,
|
|
17
|
+
items: {},
|
|
18
|
+
} satisfies JSONSchema7);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ZodSetDef } from 'zod/v3';
|
|
2
|
+
import { parseDef } from '../parse-def';
|
|
3
|
+
import { JsonSchema7Type } from '../parse-types';
|
|
4
|
+
import { Refs } from '../refs';
|
|
5
|
+
|
|
6
|
+
export type JsonSchema7SetType = {
|
|
7
|
+
type: 'array';
|
|
8
|
+
uniqueItems: true;
|
|
9
|
+
items?: JsonSchema7Type;
|
|
10
|
+
minItems?: number;
|
|
11
|
+
maxItems?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function parseSetDef(def: ZodSetDef, refs: Refs): JsonSchema7SetType {
|
|
15
|
+
const items = parseDef(def.valueType._def, {
|
|
16
|
+
...refs,
|
|
17
|
+
currentPath: [...refs.currentPath, 'items'],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const schema: JsonSchema7SetType = {
|
|
21
|
+
type: 'array',
|
|
22
|
+
uniqueItems: true,
|
|
23
|
+
items,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (def.minSize) {
|
|
27
|
+
schema.minItems = def.minSize.value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (def.maxSize) {
|
|
31
|
+
schema.maxItems = def.maxSize.value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return schema;
|
|
35
|
+
}
|