@ai-sdk/provider-utils 4.0.8 → 4.0.10
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 +14 -0
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -2
- package/src/handle-fetch-error.ts +33 -0
- package/src/__snapshots__/schema.test.ts.snap +0 -346
- package/src/add-additional-properties-to-json-schema.test.ts +0 -289
- package/src/convert-async-iterator-to-readable-stream.test.ts +0 -78
- package/src/convert-image-model-file-to-data-uri.test.ts +0 -85
- package/src/convert-to-form-data.test.ts +0 -167
- package/src/create-tool-name-mapping.test.ts +0 -163
- package/src/delay.test.ts +0 -212
- package/src/delayed-promise.test.ts +0 -132
- package/src/download-blob.test.ts +0 -145
- package/src/generate-id.test.ts +0 -31
- package/src/get-from-api.test.ts +0 -199
- package/src/get-runtime-environment-user-agent.test.ts +0 -47
- package/src/inject-json-instruction.test.ts +0 -404
- package/src/is-url-supported.test.ts +0 -282
- package/src/media-type-to-extension.test.ts +0 -26
- package/src/normalize-headers.test.ts +0 -64
- package/src/parse-json.test.ts +0 -191
- package/src/remove-undefined-entries.test.ts +0 -57
- package/src/resolve.test.ts +0 -125
- package/src/response-handler.test.ts +0 -89
- package/src/schema.test-d.ts +0 -11
- package/src/schema.test.ts +0 -502
- package/src/secure-json-parse.test.ts +0 -59
- package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +0 -224
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +0 -98
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +0 -51
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +0 -16
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +0 -15
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +0 -97
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +0 -54
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +0 -41
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +0 -92
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +0 -48
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +0 -102
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +0 -67
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +0 -65
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +0 -149
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +0 -147
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +0 -35
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +0 -15
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +0 -20
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +0 -108
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +0 -20
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +0 -438
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +0 -33
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +0 -226
- package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +0 -919
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +0 -862
- package/src/types/tool.test-d.ts +0 -228
- package/src/validate-types.test.ts +0 -105
- package/src/with-user-agent-suffix.test.ts +0 -84
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { mediaTypeToExtension } from './media-type-to-extension';
|
|
3
|
-
|
|
4
|
-
describe('mediaTypeToExtension()', () => {
|
|
5
|
-
it.each([
|
|
6
|
-
// most common
|
|
7
|
-
['audio/mpeg', 'mp3'],
|
|
8
|
-
['audio/mp3', 'mp3'],
|
|
9
|
-
['audio/wav', 'wav'],
|
|
10
|
-
['audio/x-wav', 'wav'],
|
|
11
|
-
['audio/webm', 'webm'],
|
|
12
|
-
['audio/ogg', 'ogg'],
|
|
13
|
-
['audio/opus', 'ogg'],
|
|
14
|
-
['audio/mp4', 'm4a'],
|
|
15
|
-
['audio/x-m4a', 'm4a'],
|
|
16
|
-
['audio/flac', 'flac'],
|
|
17
|
-
['audio/aac', 'aac'],
|
|
18
|
-
// upper case
|
|
19
|
-
['AUDIO/MPEG', 'mp3'],
|
|
20
|
-
['AUDIO/MP3', 'mp3'],
|
|
21
|
-
// invalid
|
|
22
|
-
['nope', ''],
|
|
23
|
-
])('should map %s to %s', (mediaType, expectedExtension) => {
|
|
24
|
-
expect(mediaTypeToExtension(mediaType)).toBe(expectedExtension);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { normalizeHeaders } from './normalize-headers';
|
|
4
|
-
|
|
5
|
-
describe('normalizeHeaders', () => {
|
|
6
|
-
it('returns empty object for undefined', () => {
|
|
7
|
-
expect(normalizeHeaders(undefined)).toEqual({});
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('converts Headers instance to record', () => {
|
|
11
|
-
const headers = new Headers({
|
|
12
|
-
Authorization: 'Bearer token',
|
|
13
|
-
'X-Feature': 'beta',
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
expect(normalizeHeaders(headers)).toEqual({
|
|
17
|
-
authorization: 'Bearer token',
|
|
18
|
-
'x-feature': 'beta',
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('converts tuple array', () => {
|
|
23
|
-
const headers: HeadersInit = [
|
|
24
|
-
['Authorization', 'Bearer token'],
|
|
25
|
-
['X-Feature', 'beta'],
|
|
26
|
-
['X-Ignore', undefined as unknown as string],
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
expect(normalizeHeaders(headers)).toEqual({
|
|
30
|
-
authorization: 'Bearer token',
|
|
31
|
-
'x-feature': 'beta',
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('converts plain record and filters nullish values', () => {
|
|
36
|
-
expect(
|
|
37
|
-
normalizeHeaders({
|
|
38
|
-
Authorization: 'Bearer token',
|
|
39
|
-
'X-Feature': undefined,
|
|
40
|
-
'Content-Type': 'application/json',
|
|
41
|
-
}),
|
|
42
|
-
).toEqual({
|
|
43
|
-
authorization: 'Bearer token',
|
|
44
|
-
'content-type': 'application/json',
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('handles empty Headers instance', () => {
|
|
49
|
-
const headers = new Headers();
|
|
50
|
-
expect(normalizeHeaders(headers)).toEqual({});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('converts uppercase keys to lowercase', () => {
|
|
54
|
-
expect(
|
|
55
|
-
normalizeHeaders({
|
|
56
|
-
'CONTENT-TYPE': 'application/json',
|
|
57
|
-
'X-CUSTOM-HEADER': 'test-value',
|
|
58
|
-
}),
|
|
59
|
-
).toEqual({
|
|
60
|
-
'content-type': 'application/json',
|
|
61
|
-
'x-custom-header': 'test-value',
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
package/src/parse-json.test.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { parseJSON, safeParseJSON, isParsableJson } from './parse-json';
|
|
3
|
-
import { z } from 'zod/v4';
|
|
4
|
-
import { JSONParseError, TypeValidationError } from '@ai-sdk/provider';
|
|
5
|
-
|
|
6
|
-
describe('parseJSON', () => {
|
|
7
|
-
it('should parse basic JSON without schema', async () => {
|
|
8
|
-
const result = await parseJSON({ text: '{"foo": "bar"}' });
|
|
9
|
-
expect(result).toEqual({ foo: 'bar' });
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('should parse JSON with schema validation', async () => {
|
|
13
|
-
const schema = z.object({ foo: z.string() });
|
|
14
|
-
const result = await parseJSON({ text: '{"foo": "bar"}', schema });
|
|
15
|
-
expect(result).toEqual({ foo: 'bar' });
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should throw JSONParseError for invalid JSON', async () => {
|
|
19
|
-
await expect(() => parseJSON({ text: 'invalid json' })).rejects.toThrow(
|
|
20
|
-
JSONParseError,
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should throw TypeValidationError for schema validation failures', async () => {
|
|
25
|
-
const schema = z.object({ foo: z.number() });
|
|
26
|
-
await expect(() =>
|
|
27
|
-
parseJSON({ text: '{"foo": "bar"}', schema }),
|
|
28
|
-
).rejects.toThrow(TypeValidationError);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('safeParseJSON', () => {
|
|
33
|
-
it('should safely parse basic JSON without schema and include rawValue', async () => {
|
|
34
|
-
const result = await safeParseJSON({ text: '{"foo": "bar"}' });
|
|
35
|
-
expect(result).toEqual({
|
|
36
|
-
success: true,
|
|
37
|
-
value: { foo: 'bar' },
|
|
38
|
-
rawValue: { foo: 'bar' },
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should preserve rawValue even after schema transformation', async () => {
|
|
43
|
-
const schema = z.object({
|
|
44
|
-
count: z.coerce.number(),
|
|
45
|
-
});
|
|
46
|
-
const result = await safeParseJSON({
|
|
47
|
-
text: '{"count": "42"}',
|
|
48
|
-
schema,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
expect(result).toEqual({
|
|
52
|
-
success: true,
|
|
53
|
-
value: { count: 42 },
|
|
54
|
-
rawValue: { count: '42' },
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should handle failed parsing with error details', async () => {
|
|
59
|
-
const result = await safeParseJSON({ text: 'invalid json' });
|
|
60
|
-
expect(result).toEqual({
|
|
61
|
-
success: false,
|
|
62
|
-
error: expect.any(JSONParseError),
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should handle schema validation failures', async () => {
|
|
67
|
-
const schema = z.object({ age: z.number() });
|
|
68
|
-
const result = await safeParseJSON({
|
|
69
|
-
text: '{"age": "twenty"}',
|
|
70
|
-
schema,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
expect(result).toEqual({
|
|
74
|
-
success: false,
|
|
75
|
-
error: expect.any(TypeValidationError),
|
|
76
|
-
rawValue: { age: 'twenty' },
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should handle nested objects and preserve raw values', async () => {
|
|
81
|
-
const schema = z.object({
|
|
82
|
-
user: z.object({
|
|
83
|
-
id: z.string().transform(val => parseInt(val, 10)),
|
|
84
|
-
name: z.string(),
|
|
85
|
-
}),
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const result = await safeParseJSON({
|
|
89
|
-
text: '{"user": {"id": "123", "name": "John"}}',
|
|
90
|
-
schema: schema as any,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
expect(result).toEqual({
|
|
94
|
-
success: true,
|
|
95
|
-
value: { user: { id: 123, name: 'John' } },
|
|
96
|
-
rawValue: { user: { id: '123', name: 'John' } },
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('should handle arrays and preserve raw values', async () => {
|
|
101
|
-
const schema = z.array(z.string().transform(val => val.toUpperCase()));
|
|
102
|
-
const result = await safeParseJSON({
|
|
103
|
-
text: '["hello", "world"]',
|
|
104
|
-
schema,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
expect(result).toEqual({
|
|
108
|
-
success: true,
|
|
109
|
-
value: ['HELLO', 'WORLD'],
|
|
110
|
-
rawValue: ['hello', 'world'],
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should handle discriminated unions in schema', async () => {
|
|
115
|
-
const schema = z.discriminatedUnion('type', [
|
|
116
|
-
z.object({ type: z.literal('text'), content: z.string() }),
|
|
117
|
-
z.object({ type: z.literal('number'), value: z.number() }),
|
|
118
|
-
]);
|
|
119
|
-
|
|
120
|
-
const result = await safeParseJSON({
|
|
121
|
-
text: '{"type": "text", "content": "hello"}',
|
|
122
|
-
schema,
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
expect(result).toEqual({
|
|
126
|
-
success: true,
|
|
127
|
-
value: { type: 'text', content: 'hello' },
|
|
128
|
-
rawValue: { type: 'text', content: 'hello' },
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should handle nullable fields in schema', async () => {
|
|
133
|
-
const schema = z.object({
|
|
134
|
-
id: z.string().nullish(),
|
|
135
|
-
data: z.string(),
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const result = await safeParseJSON({
|
|
139
|
-
text: '{"id": null, "data": "test"}',
|
|
140
|
-
schema,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
expect(result).toEqual({
|
|
144
|
-
success: true,
|
|
145
|
-
value: { id: null, data: 'test' },
|
|
146
|
-
rawValue: { id: null, data: 'test' },
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should handle union types in schema', async () => {
|
|
151
|
-
const schema = z.object({
|
|
152
|
-
value: z.union([z.string(), z.number()]),
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const result1 = await safeParseJSON({
|
|
156
|
-
text: '{"value": "test"}',
|
|
157
|
-
schema,
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
const result2 = await safeParseJSON({
|
|
161
|
-
text: '{"value": 123}',
|
|
162
|
-
schema,
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
expect(result1).toEqual({
|
|
166
|
-
success: true,
|
|
167
|
-
value: { value: 'test' },
|
|
168
|
-
rawValue: { value: 'test' },
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
expect(result2).toEqual({
|
|
172
|
-
success: true,
|
|
173
|
-
value: { value: 123 },
|
|
174
|
-
rawValue: { value: 123 },
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe('isParsableJson', () => {
|
|
180
|
-
it('should return true for valid JSON', () => {
|
|
181
|
-
expect(isParsableJson('{"foo": "bar"}')).toBe(true);
|
|
182
|
-
expect(isParsableJson('[1, 2, 3]')).toBe(true);
|
|
183
|
-
expect(isParsableJson('"hello"')).toBe(true);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it('should return false for invalid JSON', () => {
|
|
187
|
-
expect(isParsableJson('invalid')).toBe(false);
|
|
188
|
-
expect(isParsableJson('{foo: "bar"}')).toBe(false);
|
|
189
|
-
expect(isParsableJson('{"foo": }')).toBe(false);
|
|
190
|
-
});
|
|
191
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { expect, it } from 'vitest';
|
|
2
|
-
import { removeUndefinedEntries } from './remove-undefined-entries';
|
|
3
|
-
|
|
4
|
-
it('should remove undefined entries from record', () => {
|
|
5
|
-
const input = {
|
|
6
|
-
a: 1,
|
|
7
|
-
b: undefined,
|
|
8
|
-
c: 'test',
|
|
9
|
-
d: undefined,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
expect(removeUndefinedEntries(input)).toEqual({
|
|
13
|
-
a: 1,
|
|
14
|
-
c: 'test',
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should handle empty object', () => {
|
|
19
|
-
const input = {};
|
|
20
|
-
expect(removeUndefinedEntries(input)).toEqual({});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should handle object with all undefined values', () => {
|
|
24
|
-
const input = {
|
|
25
|
-
a: undefined,
|
|
26
|
-
b: undefined,
|
|
27
|
-
};
|
|
28
|
-
expect(removeUndefinedEntries(input)).toEqual({});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should remove null values', () => {
|
|
32
|
-
// Both null and undefined will be removed.
|
|
33
|
-
const input = {
|
|
34
|
-
a: null,
|
|
35
|
-
b: undefined,
|
|
36
|
-
c: 'test',
|
|
37
|
-
};
|
|
38
|
-
expect(removeUndefinedEntries(input)).toEqual({
|
|
39
|
-
c: 'test',
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should preserve falsy values except null and undefined', () => {
|
|
44
|
-
// Only false, 0, and '' are preserved.
|
|
45
|
-
const input = {
|
|
46
|
-
a: false,
|
|
47
|
-
b: 0,
|
|
48
|
-
c: '',
|
|
49
|
-
d: undefined,
|
|
50
|
-
e: null,
|
|
51
|
-
};
|
|
52
|
-
expect(removeUndefinedEntries(input)).toEqual({
|
|
53
|
-
a: false,
|
|
54
|
-
b: 0,
|
|
55
|
-
c: '',
|
|
56
|
-
});
|
|
57
|
-
});
|
package/src/resolve.test.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { resolve, Resolvable } from './resolve';
|
|
3
|
-
|
|
4
|
-
describe('resolve', () => {
|
|
5
|
-
// Test raw values
|
|
6
|
-
it('should resolve raw values', async () => {
|
|
7
|
-
const value: Resolvable<number> = 42;
|
|
8
|
-
expect(await resolve(value)).toBe(42);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('should resolve raw objects', async () => {
|
|
12
|
-
const value: Resolvable<object> = { foo: 'bar' };
|
|
13
|
-
expect(await resolve(value)).toEqual({ foo: 'bar' });
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// Test promises
|
|
17
|
-
it('should resolve promises', async () => {
|
|
18
|
-
const value: Resolvable<string> = Promise.resolve('hello');
|
|
19
|
-
expect(await resolve(value)).toBe('hello');
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should resolve rejected promises', async () => {
|
|
23
|
-
const value: Resolvable<string> = Promise.reject(new Error('test error'));
|
|
24
|
-
await expect(resolve(value)).rejects.toThrow('test error');
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// Test synchronous functions
|
|
28
|
-
it('should resolve synchronous functions', async () => {
|
|
29
|
-
const value: Resolvable<number> = () => 42;
|
|
30
|
-
expect(await resolve(value)).toBe(42);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should resolve synchronous functions returning objects', async () => {
|
|
34
|
-
const value: Resolvable<object> = () => ({ foo: 'bar' });
|
|
35
|
-
expect(await resolve(value)).toEqual({ foo: 'bar' });
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Test async functions
|
|
39
|
-
it('should resolve async functions', async () => {
|
|
40
|
-
const value: Resolvable<string> = async () => 'hello';
|
|
41
|
-
expect(await resolve(value)).toBe('hello');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should resolve async functions returning promises', async () => {
|
|
45
|
-
const value: Resolvable<number> = () => Promise.resolve(42);
|
|
46
|
-
expect(await resolve(value)).toBe(42);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should handle async function rejections', async () => {
|
|
50
|
-
const value: Resolvable<string> = async () => {
|
|
51
|
-
throw new Error('async error');
|
|
52
|
-
};
|
|
53
|
-
await expect(resolve(value)).rejects.toThrow('async error');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Test edge cases
|
|
57
|
-
it('should handle null', async () => {
|
|
58
|
-
const value: Resolvable<null> = null;
|
|
59
|
-
expect(await resolve(value)).toBe(null);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should handle undefined', async () => {
|
|
63
|
-
const value: Resolvable<undefined> = undefined;
|
|
64
|
-
expect(await resolve(value)).toBe(undefined);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Test with complex objects
|
|
68
|
-
it('should resolve nested objects', async () => {
|
|
69
|
-
const value: Resolvable<{ nested: { value: number } }> = {
|
|
70
|
-
nested: { value: 42 },
|
|
71
|
-
};
|
|
72
|
-
expect(await resolve(value)).toEqual({ nested: { value: 42 } });
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// Test resolving objects as frequently used in headers as a common example
|
|
76
|
-
describe('resolve headers', () => {
|
|
77
|
-
it('should resolve header objects', async () => {
|
|
78
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
79
|
-
expect(await resolve(headers)).toEqual(headers);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should resolve header functions', async () => {
|
|
83
|
-
const headers = () => ({ Authorization: 'Bearer token' });
|
|
84
|
-
expect(await resolve(headers)).toEqual({ Authorization: 'Bearer token' });
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should resolve async header functions', async () => {
|
|
88
|
-
const headers = async () => ({ 'X-Custom': 'value' });
|
|
89
|
-
expect(await resolve(headers)).toEqual({ 'X-Custom': 'value' });
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should resolve header promises', async () => {
|
|
93
|
-
const headers = Promise.resolve({ Accept: 'application/json' });
|
|
94
|
-
expect(await resolve(headers)).toEqual({ Accept: 'application/json' });
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should call async header functions each time when resolved multiple times', async () => {
|
|
98
|
-
let counter = 0;
|
|
99
|
-
const headers = async () => ({ 'X-Request-Number': String(++counter) });
|
|
100
|
-
|
|
101
|
-
// Resolve the same headers function multiple times
|
|
102
|
-
expect(await resolve(headers)).toEqual({ 'X-Request-Number': '1' });
|
|
103
|
-
expect(await resolve(headers)).toEqual({ 'X-Request-Number': '2' });
|
|
104
|
-
expect(await resolve(headers)).toEqual({ 'X-Request-Number': '3' });
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Test type inference
|
|
109
|
-
it('should maintain type information', async () => {
|
|
110
|
-
interface User {
|
|
111
|
-
id: number;
|
|
112
|
-
name: string;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const userPromise: Resolvable<User> = Promise.resolve({
|
|
116
|
-
id: 1,
|
|
117
|
-
name: 'Test User',
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const result = await resolve(userPromise);
|
|
121
|
-
// TypeScript should recognize result as User type
|
|
122
|
-
expect(result.id).toBe(1);
|
|
123
|
-
expect(result.name).toBe('Test User');
|
|
124
|
-
});
|
|
125
|
-
});
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { z } from 'zod/v4';
|
|
3
|
-
import {
|
|
4
|
-
createBinaryResponseHandler,
|
|
5
|
-
createJsonResponseHandler,
|
|
6
|
-
createStatusCodeErrorResponseHandler,
|
|
7
|
-
} from './response-handler';
|
|
8
|
-
|
|
9
|
-
describe('createJsonResponseHandler', () => {
|
|
10
|
-
it('should return both parsed value and rawValue', async () => {
|
|
11
|
-
const responseSchema = z.object({
|
|
12
|
-
name: z.string(),
|
|
13
|
-
age: z.number(),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const rawData = {
|
|
17
|
-
name: 'John',
|
|
18
|
-
age: 30,
|
|
19
|
-
extraField: 'ignored',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const response = new Response(JSON.stringify(rawData));
|
|
23
|
-
const handler = createJsonResponseHandler(responseSchema);
|
|
24
|
-
|
|
25
|
-
const result = await handler({
|
|
26
|
-
url: 'test-url',
|
|
27
|
-
requestBodyValues: {},
|
|
28
|
-
response,
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
expect(result.value).toEqual({
|
|
32
|
-
name: 'John',
|
|
33
|
-
age: 30,
|
|
34
|
-
});
|
|
35
|
-
expect(result.rawValue).toEqual(rawData);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe('createBinaryResponseHandler', () => {
|
|
40
|
-
it('should handle binary response successfully', async () => {
|
|
41
|
-
const binaryData = new Uint8Array([1, 2, 3, 4]);
|
|
42
|
-
const response = new Response(binaryData);
|
|
43
|
-
const handler = createBinaryResponseHandler();
|
|
44
|
-
|
|
45
|
-
const result = await handler({
|
|
46
|
-
url: 'test-url',
|
|
47
|
-
requestBodyValues: {},
|
|
48
|
-
response,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
expect(result.value).toBeInstanceOf(Uint8Array);
|
|
52
|
-
expect(result.value).toEqual(binaryData);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should throw APICallError when response body is null', async () => {
|
|
56
|
-
const response = new Response(null);
|
|
57
|
-
const handler = createBinaryResponseHandler();
|
|
58
|
-
|
|
59
|
-
await expect(
|
|
60
|
-
handler({
|
|
61
|
-
url: 'test-url',
|
|
62
|
-
requestBodyValues: {},
|
|
63
|
-
response,
|
|
64
|
-
}),
|
|
65
|
-
).rejects.toThrow('Response body is empty');
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('createStatusCodeErrorResponseHandler', () => {
|
|
70
|
-
it('should create error with status text and response body', async () => {
|
|
71
|
-
const response = new Response('Error message', {
|
|
72
|
-
status: 404,
|
|
73
|
-
statusText: 'Not Found',
|
|
74
|
-
});
|
|
75
|
-
const handler = createStatusCodeErrorResponseHandler();
|
|
76
|
-
|
|
77
|
-
const result = await handler({
|
|
78
|
-
url: 'test-url',
|
|
79
|
-
requestBodyValues: { some: 'data' },
|
|
80
|
-
response,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
expect(result.value.message).toBe('Not Found');
|
|
84
|
-
expect(result.value.statusCode).toBe(404);
|
|
85
|
-
expect(result.value.responseBody).toBe('Error message');
|
|
86
|
-
expect(result.value.url).toBe('test-url');
|
|
87
|
-
expect(result.value.requestBodyValues).toEqual({ some: 'data' });
|
|
88
|
-
});
|
|
89
|
-
});
|
package/src/schema.test-d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { describe, expectTypeOf, it } from 'vitest';
|
|
2
|
-
import { InferSchema, StandardSchema } from './schema';
|
|
3
|
-
|
|
4
|
-
describe('InferSchema type', () => {
|
|
5
|
-
it('should work with StandardSchema', () => {
|
|
6
|
-
type MySchema = StandardSchema<number>;
|
|
7
|
-
type Result = InferSchema<MySchema>;
|
|
8
|
-
|
|
9
|
-
expectTypeOf<Result>().toMatchTypeOf<number>();
|
|
10
|
-
});
|
|
11
|
-
});
|