@fragno-dev/core 0.1.4 → 0.1.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/.turbo/turbo-build.log +49 -45
- package/CHANGELOG.md +53 -0
- package/dist/api/api.d.ts +2 -2
- package/dist/api/fragment-builder.d.ts +3 -2
- package/dist/api/fragment-instantiation.d.ts +4 -3
- package/dist/api/fragment-instantiation.js +3 -3
- package/dist/api/route.d.ts +3 -0
- package/dist/api/route.js +3 -0
- package/dist/{api-BX90b4-D.d.ts → api-CoCkNi6h.d.ts} +20 -7
- package/dist/api-CoCkNi6h.d.ts.map +1 -0
- package/dist/api-DngJDcmO.js.map +1 -1
- package/dist/client/client.d.ts +4 -3
- package/dist/client/client.js +3 -3
- package/dist/client/client.svelte.d.ts +3 -3
- package/dist/client/client.svelte.d.ts.map +1 -1
- package/dist/client/client.svelte.js +3 -3
- package/dist/client/react.d.ts +3 -3
- package/dist/client/react.d.ts.map +1 -1
- package/dist/client/react.js +3 -3
- package/dist/client/solid.d.ts +3 -3
- package/dist/client/solid.d.ts.map +1 -1
- package/dist/client/solid.js +3 -3
- package/dist/client/vanilla.d.ts +3 -3
- package/dist/client/vanilla.d.ts.map +1 -1
- package/dist/client/vanilla.js +3 -3
- package/dist/client/vue.d.ts +3 -3
- package/dist/client/vue.d.ts.map +1 -1
- package/dist/client/vue.js +3 -3
- package/dist/{client-C6LChM0Y.js → client-DJfCJiHK.js} +81 -7
- package/dist/client-DJfCJiHK.js.map +1 -0
- package/dist/{fragment-builder-BZr2JkuW.d.ts → fragment-builder-8-tiECi5.d.ts} +75 -38
- package/dist/fragment-builder-8-tiECi5.d.ts.map +1 -0
- package/dist/{fragment-instantiation-D74OQjbn.js → fragment-instantiation-C4wvwl6V.js} +129 -6
- package/dist/fragment-instantiation-C4wvwl6V.js.map +1 -0
- package/dist/mod.d.ts +3 -2
- package/dist/mod.js +3 -3
- package/dist/{route-D1MZR6JL.js → request-output-context-CdIjwmEN.js} +22 -33
- package/dist/request-output-context-CdIjwmEN.js.map +1 -0
- package/dist/route-C5Uryylh.js +21 -0
- package/dist/route-C5Uryylh.js.map +1 -0
- package/dist/route-mGLYSUvD.d.ts +26 -0
- package/dist/route-mGLYSUvD.d.ts.map +1 -0
- package/dist/test/test.d.ts +24 -70
- package/dist/test/test.d.ts.map +1 -1
- package/dist/test/test.js +27 -115
- package/dist/test/test.js.map +1 -1
- package/package.json +6 -1
- package/src/api/api.ts +1 -0
- package/src/api/fragment-instantiation.test.ts +460 -0
- package/src/api/fragment-instantiation.ts +157 -5
- package/src/api/fragno-response.ts +132 -0
- package/src/api/request-input-context.test.ts +37 -29
- package/src/api/request-input-context.ts +16 -14
- package/src/api/request-output-context.test.ts +10 -10
- package/src/api/request-output-context.ts +3 -3
- package/src/api/route-handler-input-options.ts +15 -0
- package/src/client/client.test.ts +264 -0
- package/src/client/client.ts +65 -3
- package/src/client/internal/fetcher-merge.ts +59 -0
- package/src/test/test.test.ts +110 -165
- package/src/test/test.ts +56 -266
- package/tsdown.config.ts +1 -0
- package/dist/api-BX90b4-D.d.ts.map +0 -1
- package/dist/client-C6LChM0Y.js.map +0 -1
- package/dist/fragment-builder-BZr2JkuW.d.ts.map +0 -1
- package/dist/fragment-instantiation-D74OQjbn.js.map +0 -1
- package/dist/route-CTxjMtGZ.js +0 -10
- package/dist/route-CTxjMtGZ.js.map +0 -1
- package/dist/route-D1MZR6JL.js.map +0 -1
package/src/test/test.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
1
|
+
import { describe, it, expect, expectTypeOf } from "vitest";
|
|
2
2
|
import { createFragmentForTest } from "./test";
|
|
3
3
|
import { defineFragment } from "../api/fragment-builder";
|
|
4
4
|
import { defineRoute, defineRoutes } from "../api/route";
|
|
@@ -7,7 +7,7 @@ import { z } from "zod";
|
|
|
7
7
|
describe("createFragmentForTest", () => {
|
|
8
8
|
it("should create a test fragment with config only", () => {
|
|
9
9
|
const fragment = defineFragment<{ apiKey: string }>("test");
|
|
10
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
10
|
+
const testFragment = createFragmentForTest(fragment, [], {
|
|
11
11
|
config: { apiKey: "test-key" },
|
|
12
12
|
});
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ describe("createFragmentForTest", () => {
|
|
|
21
21
|
client: { apiKey: config.apiKey },
|
|
22
22
|
}));
|
|
23
23
|
|
|
24
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
24
|
+
const testFragment = createFragmentForTest(fragment, [], {
|
|
25
25
|
config: { apiKey: "test-key" },
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -33,7 +33,7 @@ describe("createFragmentForTest", () => {
|
|
|
33
33
|
client: { apiKey: config.apiKey },
|
|
34
34
|
}));
|
|
35
35
|
|
|
36
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
36
|
+
const testFragment = createFragmentForTest(fragment, [], {
|
|
37
37
|
config: { apiKey: "test-key" },
|
|
38
38
|
deps: { client: { apiKey: "override-key" } },
|
|
39
39
|
});
|
|
@@ -50,7 +50,7 @@ describe("createFragmentForTest", () => {
|
|
|
50
50
|
getApiKey: () => deps.client.apiKey,
|
|
51
51
|
}));
|
|
52
52
|
|
|
53
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
53
|
+
const testFragment = createFragmentForTest(fragment, [], {
|
|
54
54
|
config: { apiKey: "test-key" },
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -66,7 +66,7 @@ describe("createFragmentForTest", () => {
|
|
|
66
66
|
getApiKey: () => deps.client.apiKey,
|
|
67
67
|
}));
|
|
68
68
|
|
|
69
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
69
|
+
const testFragment = createFragmentForTest(fragment, [], {
|
|
70
70
|
config: { apiKey: "test-key" },
|
|
71
71
|
services: { getApiKey: () => "override-key" },
|
|
72
72
|
});
|
|
@@ -74,145 +74,51 @@ describe("createFragmentForTest", () => {
|
|
|
74
74
|
expect(testFragment.services.getApiKey()).toBe("override-key");
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
it("should initialize routes with fragment context", () => {
|
|
78
|
-
const fragment = defineFragment<{ multiplier: number }>("test")
|
|
79
|
-
.withDependencies(() => ({ dep: "value" }))
|
|
80
|
-
.withServices(({ config }) => ({
|
|
81
|
-
multiply: (x: number) => x * config.multiplier,
|
|
82
|
-
}));
|
|
83
|
-
|
|
84
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
85
|
-
config: { multiplier: 2 },
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const route = defineRoute({
|
|
89
|
-
method: "GET",
|
|
90
|
-
path: "/test",
|
|
91
|
-
outputSchema: z.object({ result: z.number() }),
|
|
92
|
-
handler: async (_ctx, { json }) => {
|
|
93
|
-
return json({ result: 42 });
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const routes = [route] as const;
|
|
98
|
-
const [initializedRoute] = testFragment.initRoutes(routes);
|
|
99
|
-
|
|
100
|
-
expect(initializedRoute).toBe(route);
|
|
101
|
-
expect(initializedRoute.method).toBe("GET");
|
|
102
|
-
expect(initializedRoute.path).toBe("/test");
|
|
103
|
-
});
|
|
104
|
-
|
|
105
77
|
it("should initialize route factories with fragment context", async () => {
|
|
106
|
-
|
|
78
|
+
type Config = { multiplier: number };
|
|
79
|
+
type Deps = { dep: string };
|
|
80
|
+
type Services = { multiply: (x: number) => number };
|
|
81
|
+
|
|
82
|
+
const fragment = defineFragment<Config>("test")
|
|
107
83
|
.withDependencies(() => ({ dep: "value" }))
|
|
108
84
|
.withServices(({ config }) => ({
|
|
109
85
|
multiply: (x: number) => x * config.multiplier,
|
|
110
86
|
}));
|
|
111
87
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return json({ result: services.multiply(5) });
|
|
124
|
-
},
|
|
125
|
-
}),
|
|
126
|
-
];
|
|
127
|
-
};
|
|
88
|
+
const routeFactory = defineRoutes<Config, Deps, Services>().create(({ services }) => [
|
|
89
|
+
defineRoute({
|
|
90
|
+
method: "GET",
|
|
91
|
+
path: "/multiply/:num",
|
|
92
|
+
outputSchema: z.object({ result: z.number() }),
|
|
93
|
+
handler: async ({ pathParams }, { json }) => {
|
|
94
|
+
const { num } = pathParams;
|
|
95
|
+
return json({ result: services.multiply(Number(num)) });
|
|
96
|
+
},
|
|
97
|
+
}),
|
|
98
|
+
]);
|
|
128
99
|
|
|
129
100
|
const routes = [routeFactory] as const;
|
|
130
|
-
const [multiplyRoute] = testFragment.initRoutes(routes);
|
|
131
101
|
|
|
132
|
-
|
|
133
|
-
|
|
102
|
+
const testFragment = createFragmentForTest(fragment, routes, {
|
|
103
|
+
config: { multiplier: 3 },
|
|
104
|
+
});
|
|
134
105
|
|
|
135
106
|
// Test that the route was initialized with the correct services
|
|
136
|
-
const response = await testFragment.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
expect(response.data).toEqual({ result: 15 }); // 5 * 3
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it("should allow overriding config/deps/services for specific route initialization", async () => {
|
|
144
|
-
const fragment = defineFragment<{ multiplier: number }>("test")
|
|
145
|
-
.withDependencies(() => ({ baseUrl: "https://api.example.com" }))
|
|
146
|
-
.withServices(({ config }) => ({
|
|
147
|
-
multiply: (x: number) => x * config.multiplier,
|
|
148
|
-
getMessage: (): string => "original message",
|
|
149
|
-
}));
|
|
150
|
-
|
|
151
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
152
|
-
config: { multiplier: 2 },
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const routeFactory = ({
|
|
156
|
-
config,
|
|
157
|
-
services,
|
|
158
|
-
}: {
|
|
159
|
-
config: { multiplier: number };
|
|
160
|
-
services: { multiply: (x: number) => number; getMessage: () => string };
|
|
161
|
-
}) => {
|
|
162
|
-
return [
|
|
163
|
-
defineRoute({
|
|
164
|
-
method: "GET",
|
|
165
|
-
path: "/test",
|
|
166
|
-
outputSchema: z.object({
|
|
167
|
-
result: z.number(),
|
|
168
|
-
message: z.string(),
|
|
169
|
-
multiplier: z.number(),
|
|
170
|
-
}),
|
|
171
|
-
handler: async (_ctx, { json }) => {
|
|
172
|
-
return json({
|
|
173
|
-
result: services.multiply(10),
|
|
174
|
-
message: services.getMessage(),
|
|
175
|
-
multiplier: config.multiplier,
|
|
176
|
-
});
|
|
177
|
-
},
|
|
178
|
-
}),
|
|
179
|
-
];
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const routes = [routeFactory] as const;
|
|
183
|
-
|
|
184
|
-
// Initialize with overrides - completely replace the multiply service
|
|
185
|
-
const [overriddenRoute] = testFragment.initRoutes(routes, {
|
|
186
|
-
config: { multiplier: 5 },
|
|
187
|
-
services: {
|
|
188
|
-
multiply: (x: number) => x * 5, // Mock implementation uses hardcoded multiplier
|
|
189
|
-
getMessage: (): string => "mocked message",
|
|
190
|
-
},
|
|
107
|
+
const response = await testFragment.callRoute("GET", "/multiply/:num", {
|
|
108
|
+
// ^?
|
|
109
|
+
pathParams: { num: "5" },
|
|
191
110
|
});
|
|
192
|
-
|
|
193
|
-
const response = await testFragment.handler(overriddenRoute);
|
|
194
111
|
expect(response.type).toBe("json");
|
|
195
112
|
if (response.type === "json") {
|
|
196
|
-
expect(response.data).toEqual({
|
|
197
|
-
|
|
198
|
-
message: "mocked message", // overridden service
|
|
199
|
-
multiplier: 5, // overridden config
|
|
200
|
-
});
|
|
113
|
+
expect(response.data).toEqual({ result: 15 }); // 5 * 3
|
|
114
|
+
expectTypeOf(response.data).toMatchObjectType<{ result: number }>();
|
|
201
115
|
}
|
|
202
|
-
|
|
203
|
-
// Verify original fragment config/services are unchanged
|
|
204
|
-
expect(testFragment.config.multiplier).toBe(2);
|
|
205
|
-
expect(testFragment.services.multiply(10)).toBe(20); // Original multiplier is 2
|
|
206
|
-
expect(testFragment.services.getMessage()).toBe("original message");
|
|
207
116
|
});
|
|
208
117
|
});
|
|
209
118
|
|
|
210
|
-
describe("fragment.
|
|
119
|
+
describe("fragment.callRoute", () => {
|
|
211
120
|
it("should handle JSON response", async () => {
|
|
212
121
|
const fragment = defineFragment<{ apiKey: string }>("test");
|
|
213
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
214
|
-
config: { apiKey: "test-key" },
|
|
215
|
-
});
|
|
216
122
|
|
|
217
123
|
const route = defineRoute({
|
|
218
124
|
method: "GET",
|
|
@@ -223,21 +129,23 @@ describe("fragment.handler", () => {
|
|
|
223
129
|
},
|
|
224
130
|
});
|
|
225
131
|
|
|
226
|
-
const
|
|
132
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
133
|
+
config: { apiKey: "test-key" },
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const response = await testFragment.callRoute("GET", "/test");
|
|
227
137
|
|
|
228
138
|
expect(response.type).toBe("json");
|
|
229
139
|
if (response.type === "json") {
|
|
230
140
|
expect(response.status).toBe(200);
|
|
231
141
|
expect(response.data).toEqual({ message: "hello" });
|
|
232
142
|
expect(response.headers).toBeInstanceOf(Headers);
|
|
143
|
+
expectTypeOf(response.data).toMatchObjectType<{ message: string }>();
|
|
233
144
|
}
|
|
234
145
|
});
|
|
235
146
|
|
|
236
147
|
it("should handle empty response", async () => {
|
|
237
148
|
const fragment = defineFragment<{ apiKey: string }>("test");
|
|
238
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
239
|
-
config: { apiKey: "test-key" },
|
|
240
|
-
});
|
|
241
149
|
|
|
242
150
|
const route = defineRoute({
|
|
243
151
|
method: "DELETE",
|
|
@@ -247,7 +155,11 @@ describe("fragment.handler", () => {
|
|
|
247
155
|
},
|
|
248
156
|
});
|
|
249
157
|
|
|
250
|
-
const
|
|
158
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
159
|
+
config: { apiKey: "test-key" },
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const response = await testFragment.callRoute("DELETE", "/test");
|
|
251
163
|
|
|
252
164
|
expect(response.type).toBe("empty");
|
|
253
165
|
if (response.type === "empty") {
|
|
@@ -258,9 +170,6 @@ describe("fragment.handler", () => {
|
|
|
258
170
|
|
|
259
171
|
it("should handle error response", async () => {
|
|
260
172
|
const fragment = defineFragment<{ apiKey: string }>("test");
|
|
261
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
262
|
-
config: { apiKey: "test-key" },
|
|
263
|
-
});
|
|
264
173
|
|
|
265
174
|
const route = defineRoute({
|
|
266
175
|
method: "GET",
|
|
@@ -271,7 +180,11 @@ describe("fragment.handler", () => {
|
|
|
271
180
|
},
|
|
272
181
|
});
|
|
273
182
|
|
|
274
|
-
const
|
|
183
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
184
|
+
config: { apiKey: "test-key" },
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const response = await testFragment.callRoute("GET", "/test");
|
|
275
188
|
|
|
276
189
|
expect(response.type).toBe("error");
|
|
277
190
|
if (response.type === "error") {
|
|
@@ -283,9 +196,6 @@ describe("fragment.handler", () => {
|
|
|
283
196
|
|
|
284
197
|
it("should handle JSON stream response", async () => {
|
|
285
198
|
const fragment = defineFragment<{ apiKey: string }>("test");
|
|
286
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
287
|
-
config: { apiKey: "test-key" },
|
|
288
|
-
});
|
|
289
199
|
|
|
290
200
|
const route = defineRoute({
|
|
291
201
|
method: "GET",
|
|
@@ -300,7 +210,11 @@ describe("fragment.handler", () => {
|
|
|
300
210
|
},
|
|
301
211
|
});
|
|
302
212
|
|
|
303
|
-
const
|
|
213
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
214
|
+
config: { apiKey: "test-key" },
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const response = await testFragment.callRoute("GET", "/test/stream");
|
|
304
218
|
|
|
305
219
|
expect(response.type).toBe("jsonStream");
|
|
306
220
|
if (response.type === "jsonStream") {
|
|
@@ -314,6 +228,7 @@ describe("fragment.handler", () => {
|
|
|
314
228
|
}
|
|
315
229
|
|
|
316
230
|
expect(items).toEqual([{ value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }, { value: 5 }]);
|
|
231
|
+
expectTypeOf(items[0]).toMatchObjectType<{ value: number }>();
|
|
317
232
|
}
|
|
318
233
|
});
|
|
319
234
|
|
|
@@ -323,10 +238,6 @@ describe("fragment.handler", () => {
|
|
|
323
238
|
getCount: () => 42,
|
|
324
239
|
}));
|
|
325
240
|
|
|
326
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
327
|
-
config: { apiKey: "test-key" },
|
|
328
|
-
});
|
|
329
|
-
|
|
330
241
|
type Config = { apiKey: string };
|
|
331
242
|
type Deps = {};
|
|
332
243
|
type Services = { getGreeting: (name: string) => string; getCount: () => number };
|
|
@@ -350,11 +261,12 @@ describe("fragment.handler", () => {
|
|
|
350
261
|
}),
|
|
351
262
|
]);
|
|
352
263
|
|
|
353
|
-
const
|
|
354
|
-
|
|
264
|
+
const testFragment = createFragmentForTest(fragment, [routeFactory], {
|
|
265
|
+
config: { apiKey: "test-key" },
|
|
266
|
+
});
|
|
355
267
|
|
|
356
268
|
// Test first route
|
|
357
|
-
const greetingResponse = await testFragment.
|
|
269
|
+
const greetingResponse = await testFragment.callRoute("GET", "/greeting/:name", {
|
|
358
270
|
pathParams: { name: "World" },
|
|
359
271
|
});
|
|
360
272
|
|
|
@@ -364,7 +276,7 @@ describe("fragment.handler", () => {
|
|
|
364
276
|
}
|
|
365
277
|
|
|
366
278
|
// Test second route
|
|
367
|
-
const countResponse = await testFragment.
|
|
279
|
+
const countResponse = await testFragment.callRoute("GET", "/count");
|
|
368
280
|
|
|
369
281
|
expect(countResponse.type).toBe("json");
|
|
370
282
|
if (countResponse.type === "json") {
|
|
@@ -374,9 +286,6 @@ describe("fragment.handler", () => {
|
|
|
374
286
|
|
|
375
287
|
it("should handle path parameters", async () => {
|
|
376
288
|
const fragment = defineFragment<{}>("test");
|
|
377
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
378
|
-
config: {},
|
|
379
|
-
});
|
|
380
289
|
|
|
381
290
|
const route = defineRoute({
|
|
382
291
|
method: "GET",
|
|
@@ -387,7 +296,11 @@ describe("fragment.handler", () => {
|
|
|
387
296
|
},
|
|
388
297
|
});
|
|
389
298
|
|
|
390
|
-
const
|
|
299
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
300
|
+
config: {},
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const response = await testFragment.callRoute("GET", "/users/:id", {
|
|
391
304
|
pathParams: { id: "123" },
|
|
392
305
|
});
|
|
393
306
|
|
|
@@ -399,9 +312,6 @@ describe("fragment.handler", () => {
|
|
|
399
312
|
|
|
400
313
|
it("should handle query parameters", async () => {
|
|
401
314
|
const fragment = defineFragment<{}>("test");
|
|
402
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
403
|
-
config: {},
|
|
404
|
-
});
|
|
405
315
|
|
|
406
316
|
const route = defineRoute({
|
|
407
317
|
method: "GET",
|
|
@@ -412,7 +322,11 @@ describe("fragment.handler", () => {
|
|
|
412
322
|
},
|
|
413
323
|
});
|
|
414
324
|
|
|
415
|
-
const
|
|
325
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
326
|
+
config: {},
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
const response = await testFragment.callRoute("GET", "/search", {
|
|
416
330
|
query: { q: "test" },
|
|
417
331
|
});
|
|
418
332
|
|
|
@@ -424,9 +338,6 @@ describe("fragment.handler", () => {
|
|
|
424
338
|
|
|
425
339
|
it("should handle request body", async () => {
|
|
426
340
|
const fragment = defineFragment<{}>("test");
|
|
427
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
428
|
-
config: {},
|
|
429
|
-
});
|
|
430
341
|
|
|
431
342
|
const route = defineRoute({
|
|
432
343
|
method: "POST",
|
|
@@ -442,7 +353,11 @@ describe("fragment.handler", () => {
|
|
|
442
353
|
},
|
|
443
354
|
});
|
|
444
355
|
|
|
445
|
-
const
|
|
356
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
357
|
+
config: {},
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const response = await testFragment.callRoute("POST", "/users", {
|
|
446
361
|
body: { name: "John", email: "john@example.com" },
|
|
447
362
|
});
|
|
448
363
|
|
|
@@ -452,12 +367,37 @@ describe("fragment.handler", () => {
|
|
|
452
367
|
}
|
|
453
368
|
});
|
|
454
369
|
|
|
455
|
-
it("should
|
|
370
|
+
it("should have the right types", () => {
|
|
456
371
|
const fragment = defineFragment<{}>("test");
|
|
457
|
-
|
|
372
|
+
|
|
373
|
+
const route = defineRoute({
|
|
374
|
+
method: "POST",
|
|
375
|
+
path: "/users",
|
|
376
|
+
inputSchema: z.object({ name: z.string(), email: z.string() }),
|
|
377
|
+
outputSchema: z.object({ id: z.number(), name: z.string(), email: z.string() }),
|
|
378
|
+
handler: async ({ input }, { json }) => {
|
|
379
|
+
if (input) {
|
|
380
|
+
const data = await input.valid();
|
|
381
|
+
return json({ id: 1, name: data.name, email: data.email });
|
|
382
|
+
}
|
|
383
|
+
return json({ id: 1, name: "", email: "" });
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
458
388
|
config: {},
|
|
459
389
|
});
|
|
460
390
|
|
|
391
|
+
// Check what type body is expected to have
|
|
392
|
+
type InputOptions = Parameters<typeof testFragment.callRoute<"POST", "/users">>[2];
|
|
393
|
+
type BodyType = NonNullable<NonNullable<InputOptions>["body"]>;
|
|
394
|
+
|
|
395
|
+
expectTypeOf<BodyType>().toMatchObjectType<{ name: string; email: string }>();
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it("should handle custom headers", async () => {
|
|
399
|
+
const fragment = defineFragment<{}>("test");
|
|
400
|
+
|
|
461
401
|
const route = defineRoute({
|
|
462
402
|
method: "GET",
|
|
463
403
|
path: "/test",
|
|
@@ -467,7 +407,11 @@ describe("fragment.handler", () => {
|
|
|
467
407
|
},
|
|
468
408
|
});
|
|
469
409
|
|
|
470
|
-
const
|
|
410
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
411
|
+
config: {},
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
const response = await testFragment.callRoute("GET", "/test", {
|
|
471
415
|
headers: { authorization: "Bearer token" },
|
|
472
416
|
});
|
|
473
417
|
|
|
@@ -479,9 +423,6 @@ describe("fragment.handler", () => {
|
|
|
479
423
|
|
|
480
424
|
it("should properly type path params", async () => {
|
|
481
425
|
const fragment = defineFragment<{}>("test");
|
|
482
|
-
const testFragment = createFragmentForTest(fragment, {
|
|
483
|
-
config: {},
|
|
484
|
-
});
|
|
485
426
|
|
|
486
427
|
const route = defineRoute({
|
|
487
428
|
method: "GET",
|
|
@@ -492,7 +433,11 @@ describe("fragment.handler", () => {
|
|
|
492
433
|
},
|
|
493
434
|
});
|
|
494
435
|
|
|
495
|
-
const
|
|
436
|
+
const testFragment = createFragmentForTest(fragment, [route], {
|
|
437
|
+
config: {},
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
const response = await testFragment.callRoute("GET", "/orgs/:orgId/users/:userId", {
|
|
496
441
|
pathParams: { orgId: "123", userId: "456" },
|
|
497
442
|
});
|
|
498
443
|
|