rastack 0.0.58 → 0.0.59
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 +9 -0
- package/README.md +190 -0
- package/dist/deploy/ci.js +2 -2
- package/dist/deploy/io.js +2 -2
- package/dist/dev/harness.d.ts +1 -1
- package/dist/dev/harness.js +1 -2
- package/dist/external/cache.d.ts +28 -0
- package/dist/external/cache.js +35 -0
- package/dist/external/envelope.d.ts +35 -0
- package/dist/external/envelope.js +48 -0
- package/dist/external/graphql.d.ts +25 -0
- package/dist/external/graphql.js +78 -0
- package/dist/external/handler.d.ts +52 -0
- package/dist/external/handler.js +139 -0
- package/dist/external/index.d.ts +19 -0
- package/dist/external/index.js +38 -0
- package/dist/external/lambda.d.ts +49 -0
- package/dist/external/lambda.js +86 -0
- package/dist/external/rest.d.ts +17 -0
- package/dist/external/rest.js +46 -0
- package/dist/external/route.d.ts +12 -0
- package/dist/external/route.js +33 -0
- package/dist/external/service.d.ts +50 -0
- package/dist/external/service.js +59 -0
- package/dist/external/types.d.ts +107 -0
- package/dist/external/types.js +22 -0
- package/dist/external/util.d.ts +16 -0
- package/dist/external/util.js +58 -0
- package/dist/rastack-dev.js +10 -0
- package/dist/rastack-wasm-build.d.ts +1 -1
- package/dist/rastack-wasm-build.js +6 -6
- package/dist/wasm/rastack_wasm_bg.wasm +0 -0
- package/external.ts +10 -0
- package/hooks/query/delete.ts +12 -11
- package/hooks/query/fetch.ts +6 -8
- package/hooks/query/interfaces.ts +1 -4
- package/hooks/query/list.ts +16 -9
- package/hooks/query/update.ts +8 -6
- package/package.json +24 -2
- package/scripts/copy-templates.js +1 -1
- package/scripts/copy-wasm.js +1 -1
- package/scripts/dev-install.mjs +63 -0
- package/src/deploy/ci.ts +2 -2
- package/src/deploy/io.ts +2 -2
- package/src/dev/harness.ts +1 -2
- package/src/external/cache.ts +53 -0
- package/src/external/envelope.ts +78 -0
- package/src/external/graphql.ts +98 -0
- package/src/external/handler.ts +207 -0
- package/src/external/index.ts +25 -0
- package/src/external/lambda.ts +108 -0
- package/src/external/rest.ts +60 -0
- package/src/external/route.ts +33 -0
- package/src/external/service.ts +86 -0
- package/src/external/types.ts +121 -0
- package/src/external/util.ts +57 -0
- package/src/rastack-dev.ts +11 -0
- package/src/rastack-wasm-build.ts +6 -6
- package/jest.config.cjs +0 -12
- package/test/auth.spec.ts +0 -207
- package/test/cache.spec.ts +0 -263
- package/test/cognito.spec.ts +0 -281
- package/test/compile.spec.ts +0 -240
- package/test/components.spec.ts +0 -524
- package/test/csv-schema.spec.ts +0 -143
- package/test/deploy.spec.ts +0 -571
- package/test/dev.spec.ts +0 -414
- package/test/entities.spec.ts +0 -597
- package/test/import.spec.ts +0 -241
- package/test/plugin.spec.ts +0 -315
- package/test/runtime-manifest.spec.ts +0 -309
- package/test/schema-entities.spec.ts +0 -688
- package/test/tokens.spec.ts +0 -302
- package/test/transitions.spec.ts +0 -372
- package/test/typed-hooks.spec.ts +0 -412
- package/test/update.spec.ts +0 -152
- package/test/validate.spec.ts +0 -319
- package/tsconfig.json +0 -27
- package/wasm/package.json +0 -4
- package/wasm/rastack_wasm.d.ts +0 -100
- package/wasm/rastack_wasm.js +0 -745
- package/wasm/rastack_wasm_bg.wasm +0 -0
- package/wasm/rastack_wasm_bg.wasm.d.ts +0 -28
|
@@ -1,688 +0,0 @@
|
|
|
1
|
-
import { PathsObject } from "@ts-stack/openapi-spec";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { generateFiles, generateFolders } from "../src/schema-entities";
|
|
5
|
-
import { removeNonModelPaths } from "../src/schema/remove-non-model-paths";
|
|
6
|
-
|
|
7
|
-
jest.mock("axios");
|
|
8
|
-
|
|
9
|
-
describe("OpenAPI Code Generation", () => {
|
|
10
|
-
const entitiesPath = join(__dirname, "entities");
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
// Create the entities directory before each test
|
|
14
|
-
mkdirSync(entitiesPath, {recursive: true});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
afterEach(() => {
|
|
18
|
-
// Clean up the entities directory after each test
|
|
19
|
-
rmSync(entitiesPath, {recursive: true, force: true});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("should filter out non model paths", () => {
|
|
23
|
-
const paths: PathsObject = {
|
|
24
|
-
"/api/pet/v1": {},
|
|
25
|
-
"/api/shop/v1/pet/{petId}": {},
|
|
26
|
-
"/api/shop/v1/pet/{petId}/food": {},
|
|
27
|
-
"/health": {},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const filteredPaths = removeNonModelPaths(paths);
|
|
31
|
-
expect(filteredPaths).toEqual({
|
|
32
|
-
"/api/shop/v1/pet/{petId}": {},
|
|
33
|
-
"/api/shop/v1/pet/{petId}/food": {},
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("should generate folders", async () => {
|
|
38
|
-
const paths: PathsObject = {
|
|
39
|
-
"/api/shop/v1/pet/{petId}": {},
|
|
40
|
-
"/api/shop/v1/meals/{petId}": {},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
await generateFolders(entitiesPath, paths);
|
|
44
|
-
expect(existsSync(join(entitiesPath, "shop"))).toBe(true);
|
|
45
|
-
expect(existsSync(join(entitiesPath, "shop", "pet"))).toBe(true);
|
|
46
|
-
expect(existsSync(join(entitiesPath, "shop", "meals"))).toBe(true);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("should generate files", async () => {
|
|
50
|
-
const paths: PathsObject = {
|
|
51
|
-
"/api/shop/v1/pet/{petId}": {
|
|
52
|
-
get: {
|
|
53
|
-
operationId: "getPetById",
|
|
54
|
-
responses: {
|
|
55
|
-
"200": {
|
|
56
|
-
description: "Successful response",
|
|
57
|
-
content: {
|
|
58
|
-
"application/json": {
|
|
59
|
-
schema: {
|
|
60
|
-
$ref: "#/components/schemas/Pet",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
// folders need to be created for the files
|
|
70
|
-
await generateFolders(entitiesPath, paths);
|
|
71
|
-
await generateFiles(entitiesPath, paths);
|
|
72
|
-
|
|
73
|
-
expect(existsSync(join(entitiesPath, "shop", "pet", "api.ts"))).toBe(true);
|
|
74
|
-
expect(existsSync(join(entitiesPath, "shop", "pet", "index.ts"))).toBe(
|
|
75
|
-
true,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const apiFileContent = readFileSync(
|
|
79
|
-
join(entitiesPath, "shop", "pet", "api.ts"),
|
|
80
|
-
"utf-8",
|
|
81
|
-
);
|
|
82
|
-
expect(apiFileContent).toContain("export function useGetPetById");
|
|
83
|
-
|
|
84
|
-
const indexFileContent = readFileSync(
|
|
85
|
-
join(entitiesPath, "shop", "pet", "index.ts"),
|
|
86
|
-
"utf-8",
|
|
87
|
-
);
|
|
88
|
-
expect(indexFileContent).toContain('export * from "./api"');
|
|
89
|
-
|
|
90
|
-
const baseIndexFileContent = readFileSync(
|
|
91
|
-
join(entitiesPath, "shop", "index.ts"),
|
|
92
|
-
"utf-8",
|
|
93
|
-
);
|
|
94
|
-
expect(baseIndexFileContent).toContain('export * from "./pet"');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should generate GET method with pagination", async () => {
|
|
98
|
-
const paths: PathsObject = {
|
|
99
|
-
"/api/shop/v1/pets": {
|
|
100
|
-
get: {
|
|
101
|
-
operationId: "listPets",
|
|
102
|
-
responses: {
|
|
103
|
-
"200": {
|
|
104
|
-
description: "Successful response",
|
|
105
|
-
content: {
|
|
106
|
-
"application/json": {
|
|
107
|
-
schema: {
|
|
108
|
-
$ref: "#/components/schemas/PaginatedPetList",
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
await generateFolders(entitiesPath, paths);
|
|
119
|
-
await generateFiles(entitiesPath, paths);
|
|
120
|
-
|
|
121
|
-
const apiFileContent = readFileSync(
|
|
122
|
-
join(entitiesPath, "shop", "pets", "api.ts"),
|
|
123
|
-
"utf-8",
|
|
124
|
-
);
|
|
125
|
-
expect(apiFileContent).toContain("export function useListPets(");
|
|
126
|
-
expect(apiFileContent).toContain(
|
|
127
|
-
"useGetPaginatedQueryList<IListPetsParams, IPet>",
|
|
128
|
-
);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("should generate GET method without pagination", async () => {
|
|
132
|
-
const paths: PathsObject = {
|
|
133
|
-
"/api/shop/v1/pet/{petId}": {
|
|
134
|
-
get: {
|
|
135
|
-
operationId: "getPetById",
|
|
136
|
-
responses: {
|
|
137
|
-
"200": {
|
|
138
|
-
description: "Successful response",
|
|
139
|
-
content: {
|
|
140
|
-
"application/json": {
|
|
141
|
-
schema: {
|
|
142
|
-
$ref: "#/components/schemas/Pet",
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
await generateFolders(entitiesPath, paths);
|
|
153
|
-
await generateFiles(entitiesPath, paths);
|
|
154
|
-
|
|
155
|
-
const apiFileContent = readFileSync(
|
|
156
|
-
join(entitiesPath, "shop", "pet", "api.ts"),
|
|
157
|
-
"utf-8",
|
|
158
|
-
);
|
|
159
|
-
expect(apiFileContent).toContain("export function useGetPetById(");
|
|
160
|
-
expect(apiFileContent).toContain(
|
|
161
|
-
"import { IGetPetByIdParams, IPet } from '@repo/schema/schema'",
|
|
162
|
-
);
|
|
163
|
-
expect(apiFileContent).toContain("useGetQuery<IGetPetByIdParams, IPet>");
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it("should generate POST method", async () => {
|
|
167
|
-
const paths: PathsObject = {
|
|
168
|
-
"/api/shop/v1/pets": {
|
|
169
|
-
post: {
|
|
170
|
-
operationId: "createPet",
|
|
171
|
-
requestBody: {
|
|
172
|
-
content: {
|
|
173
|
-
"application/json": {
|
|
174
|
-
schema: {
|
|
175
|
-
$ref: "#/components/schemas/CreatePetRequest",
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
responses: {
|
|
181
|
-
"201": {
|
|
182
|
-
description: "Successful response",
|
|
183
|
-
content: {
|
|
184
|
-
"application/json": {
|
|
185
|
-
schema: {
|
|
186
|
-
$ref: "#/components/schemas/Pet",
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
await generateFolders(entitiesPath, paths);
|
|
197
|
-
await generateFiles(entitiesPath, paths);
|
|
198
|
-
|
|
199
|
-
const apiFileContent = readFileSync(
|
|
200
|
-
join(entitiesPath, "shop", "pets", "api.ts"),
|
|
201
|
-
"utf-8",
|
|
202
|
-
);
|
|
203
|
-
expect(apiFileContent).toContain("export function usePostCreatePet()");
|
|
204
|
-
expect(apiFileContent).toContain(
|
|
205
|
-
"useUpdateQuery<ICreatePetParams, ICreatePetRequest, IPet>",
|
|
206
|
-
);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
it("should generate PUT method", async () => {
|
|
210
|
-
const paths: PathsObject = {
|
|
211
|
-
"/api/shop/v1/pets/{petId}": {
|
|
212
|
-
put: {
|
|
213
|
-
operationId: "updatePet",
|
|
214
|
-
requestBody: {
|
|
215
|
-
content: {
|
|
216
|
-
"application/json": {
|
|
217
|
-
schema: {
|
|
218
|
-
$ref: "#/components/schemas/UpdatePetRequest",
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
responses: {
|
|
224
|
-
"200": {
|
|
225
|
-
description: "Successful response",
|
|
226
|
-
content: {
|
|
227
|
-
"application/json": {
|
|
228
|
-
schema: {
|
|
229
|
-
$ref: "#/components/schemas/Pet",
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
await generateFolders(entitiesPath, paths);
|
|
240
|
-
await generateFiles(entitiesPath, paths);
|
|
241
|
-
|
|
242
|
-
const apiFileContent = readFileSync(
|
|
243
|
-
join(entitiesPath, "shop", "pets", "api.ts"),
|
|
244
|
-
"utf-8",
|
|
245
|
-
);
|
|
246
|
-
expect(apiFileContent).toContain("export function usePutUpdatePet()");
|
|
247
|
-
expect(apiFileContent).toContain(
|
|
248
|
-
"useUpdateQuery<IUpdatePetParams, IUpdatePetRequest, IPet>",
|
|
249
|
-
);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it("should generate DELETE method", async () => {
|
|
253
|
-
const paths: PathsObject = {
|
|
254
|
-
"/api/shop/v1/pets/{petId}": {
|
|
255
|
-
delete: {
|
|
256
|
-
operationId: "deletePet",
|
|
257
|
-
responses: {
|
|
258
|
-
"204": {
|
|
259
|
-
description: "Successful response",
|
|
260
|
-
},
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
await generateFolders(entitiesPath, paths);
|
|
267
|
-
await generateFiles(entitiesPath, paths);
|
|
268
|
-
|
|
269
|
-
const apiFileContent = readFileSync(
|
|
270
|
-
join(entitiesPath, "shop", "pets", "api.ts"),
|
|
271
|
-
"utf-8",
|
|
272
|
-
);
|
|
273
|
-
expect(apiFileContent).toContain("export function useDeletePet()");
|
|
274
|
-
expect(apiFileContent).toContain("useDeleteQuery");
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it("should generate useUpdateEventForm function", async () => {
|
|
278
|
-
const paths: PathsObject = {
|
|
279
|
-
"/api/shop/v1/events/{eventId}": {
|
|
280
|
-
put: {
|
|
281
|
-
operationId: "updateEvent",
|
|
282
|
-
requestBody: {
|
|
283
|
-
content: {
|
|
284
|
-
"application/json": {
|
|
285
|
-
schema: {
|
|
286
|
-
$ref: "#/components/schemas/UpdateEventRequest",
|
|
287
|
-
},
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
responses: {
|
|
292
|
-
"200": {
|
|
293
|
-
description: "Successful response",
|
|
294
|
-
content: {
|
|
295
|
-
"application/json": {
|
|
296
|
-
schema: {
|
|
297
|
-
$ref: "#/components/schemas/Event",
|
|
298
|
-
},
|
|
299
|
-
},
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
patch: {
|
|
305
|
-
operationId: "partialUpdateEvent",
|
|
306
|
-
requestBody: {
|
|
307
|
-
content: {
|
|
308
|
-
"application/json": {
|
|
309
|
-
schema: {
|
|
310
|
-
$ref: "#/components/schemas/PatchedUpdateEventRequest",
|
|
311
|
-
},
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
responses: {
|
|
316
|
-
"200": {
|
|
317
|
-
description: "Successful response",
|
|
318
|
-
content: {
|
|
319
|
-
"application/json": {
|
|
320
|
-
schema: {
|
|
321
|
-
$ref: "#/components/schemas/Event",
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
},
|
|
328
|
-
},
|
|
329
|
-
"/api/shop/v1/events/sessions/{eventId}": {
|
|
330
|
-
put: {
|
|
331
|
-
operationId: "updateEventSession",
|
|
332
|
-
requestBody: {
|
|
333
|
-
content: {
|
|
334
|
-
"application/json": {
|
|
335
|
-
schema: {
|
|
336
|
-
$ref: "#/components/schemas/UpdateEventSessionRequest",
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
responses: {
|
|
342
|
-
"200": {
|
|
343
|
-
description: "Successful response",
|
|
344
|
-
content: {
|
|
345
|
-
"application/json": {
|
|
346
|
-
schema: {
|
|
347
|
-
$ref: "#/components/schemas/EventSession",
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
},
|
|
353
|
-
},
|
|
354
|
-
patch: {
|
|
355
|
-
operationId: "partialUpdateEventSession",
|
|
356
|
-
requestBody: {
|
|
357
|
-
content: {
|
|
358
|
-
"application/json": {
|
|
359
|
-
schema: {
|
|
360
|
-
$ref: "#/components/schemas/PatchedUpdateEventSessionRequest",
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
responses: {
|
|
366
|
-
"200": {
|
|
367
|
-
description: "Successful response",
|
|
368
|
-
content: {
|
|
369
|
-
"application/json": {
|
|
370
|
-
schema: {
|
|
371
|
-
$ref: "#/components/schemas/EventSession",
|
|
372
|
-
},
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
},
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
"/api/shop/v1/events": {
|
|
380
|
-
post: {
|
|
381
|
-
operationId: "createEvent",
|
|
382
|
-
requestBody: {
|
|
383
|
-
content: {
|
|
384
|
-
"application/json": {
|
|
385
|
-
schema: {
|
|
386
|
-
$ref: "#/components/schemas/CreateEventRequest",
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
},
|
|
391
|
-
responses: {
|
|
392
|
-
"201": {
|
|
393
|
-
description: "Successful response",
|
|
394
|
-
content: {
|
|
395
|
-
"application/json": {
|
|
396
|
-
schema: {
|
|
397
|
-
$ref: "#/components/schemas/Event",
|
|
398
|
-
},
|
|
399
|
-
},
|
|
400
|
-
},
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
};
|
|
406
|
-
await generateFolders(entitiesPath, paths);
|
|
407
|
-
await generateFiles(entitiesPath, paths);
|
|
408
|
-
|
|
409
|
-
const apiFileContent = readFileSync(
|
|
410
|
-
join(entitiesPath, "shop", "events", "api.ts"),
|
|
411
|
-
"utf-8",
|
|
412
|
-
);
|
|
413
|
-
expect(apiFileContent).toContain("useUpdateEventsForm");
|
|
414
|
-
expect(apiFileContent).toContain("useUpdateEventsSessionsForm");
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
describe("Sync entity code generation", () => {
|
|
419
|
-
const entitiesPath = join(__dirname, "entities-sync");
|
|
420
|
-
|
|
421
|
-
const syncGet = (operationId: string, schema: string, sync = "local") => ({
|
|
422
|
-
operationId,
|
|
423
|
-
"x-rastack-sync": sync,
|
|
424
|
-
responses: {
|
|
425
|
-
"200": {
|
|
426
|
-
description: "Successful response",
|
|
427
|
-
content: {
|
|
428
|
-
"application/json": {
|
|
429
|
-
schema: {$ref: `#/components/schemas/${schema}`},
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
},
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
const syncPaths: PathsObject = {
|
|
437
|
-
"/api/airports/v1/flight/": {
|
|
438
|
-
get: syncGet("listFlights", "PaginatedFlightList"),
|
|
439
|
-
post: {
|
|
440
|
-
operationId: "createFlight",
|
|
441
|
-
"x-rastack-sync": "local",
|
|
442
|
-
requestBody: {
|
|
443
|
-
content: {
|
|
444
|
-
"application/json": {
|
|
445
|
-
schema: {$ref: "#/components/schemas/FlightRequest"},
|
|
446
|
-
},
|
|
447
|
-
},
|
|
448
|
-
},
|
|
449
|
-
responses: {
|
|
450
|
-
"201": {
|
|
451
|
-
description: "Created",
|
|
452
|
-
content: {
|
|
453
|
-
"application/json": {
|
|
454
|
-
schema: {$ref: "#/components/schemas/Flight"},
|
|
455
|
-
},
|
|
456
|
-
},
|
|
457
|
-
},
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
},
|
|
461
|
-
"/api/airports/v1/flight/{id}/": {
|
|
462
|
-
get: syncGet("getFlightById", "Flight"),
|
|
463
|
-
put: {
|
|
464
|
-
operationId: "updateFlight",
|
|
465
|
-
"x-rastack-sync": "confirmed",
|
|
466
|
-
requestBody: {
|
|
467
|
-
content: {
|
|
468
|
-
"application/json": {
|
|
469
|
-
schema: {$ref: "#/components/schemas/FlightRequest"},
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
},
|
|
473
|
-
responses: {
|
|
474
|
-
"200": {
|
|
475
|
-
description: "Updated",
|
|
476
|
-
content: {
|
|
477
|
-
"application/json": {
|
|
478
|
-
schema: {$ref: "#/components/schemas/Flight"},
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
},
|
|
482
|
-
},
|
|
483
|
-
},
|
|
484
|
-
delete: {
|
|
485
|
-
operationId: "deleteFlight",
|
|
486
|
-
"x-rastack-sync": "local",
|
|
487
|
-
responses: {"204": {description: "Deleted"}},
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
} as any;
|
|
491
|
-
|
|
492
|
-
beforeEach(() => {
|
|
493
|
-
mkdirSync(entitiesPath, {recursive: true});
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
afterEach(() => {
|
|
497
|
-
rmSync(entitiesPath, {recursive: true, force: true});
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it("should generate an entity descriptor and store-backed hooks", async () => {
|
|
501
|
-
await generateFolders(entitiesPath, syncPaths);
|
|
502
|
-
await generateFiles(entitiesPath, syncPaths);
|
|
503
|
-
|
|
504
|
-
const apiFileContent = readFileSync(
|
|
505
|
-
join(entitiesPath, "airports", "flight", "api.ts"),
|
|
506
|
-
"utf-8",
|
|
507
|
-
);
|
|
508
|
-
|
|
509
|
-
expect(apiFileContent).toContain("export const flightEntity = defineEntity<IFlight>({");
|
|
510
|
-
expect(apiFileContent).toContain('app: "airports"');
|
|
511
|
-
expect(apiFileContent).toContain('model: "flight"');
|
|
512
|
-
expect(apiFileContent).toContain("from 'rastack/sync'");
|
|
513
|
-
|
|
514
|
-
// reads are store-backed
|
|
515
|
-
expect(apiFileContent).toContain("export function useListFlights(");
|
|
516
|
-
expect(apiFileContent).toContain("useEntityList<IFlight>(flightEntity, options)");
|
|
517
|
-
expect(apiFileContent).toContain("export function useGetFlightById(");
|
|
518
|
-
expect(apiFileContent).toContain("useEntityRecord<IFlight>(flightEntity,");
|
|
519
|
-
|
|
520
|
-
// create is an optimistic transaction
|
|
521
|
-
expect(apiFileContent).toContain("export function usePostCreateFlight()");
|
|
522
|
-
expect(apiFileContent).toContain('op: "create"');
|
|
523
|
-
|
|
524
|
-
// delete is optimistic
|
|
525
|
-
expect(apiFileContent).toContain("export function useDeleteFlight()");
|
|
526
|
-
expect(apiFileContent).toContain("useEntityDelete(flightEntity, {");
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
it("should generate a blocking hook for confirmed operations", async () => {
|
|
530
|
-
await generateFolders(entitiesPath, syncPaths);
|
|
531
|
-
await generateFiles(entitiesPath, syncPaths);
|
|
532
|
-
|
|
533
|
-
const apiFileContent = readFileSync(
|
|
534
|
-
join(entitiesPath, "airports", "flight", "api.ts"),
|
|
535
|
-
"utf-8",
|
|
536
|
-
);
|
|
537
|
-
|
|
538
|
-
expect(apiFileContent).toContain("export function usePutUpdateFlight()");
|
|
539
|
-
expect(apiFileContent).toContain("useConfirmedMutation<IUpdateFlightParams, IFlightRequest, IFlight>({");
|
|
540
|
-
expect(apiFileContent).not.toContain('op: "update"');
|
|
541
|
-
});
|
|
542
|
-
|
|
543
|
-
it("should wire cache invalidation keys for non-sync entities", async () => {
|
|
544
|
-
const paths: PathsObject = {
|
|
545
|
-
"/api/shop/v1/pets": {
|
|
546
|
-
get: {
|
|
547
|
-
operationId: "listPets",
|
|
548
|
-
responses: {
|
|
549
|
-
"200": {
|
|
550
|
-
description: "OK",
|
|
551
|
-
content: {
|
|
552
|
-
"application/json": {
|
|
553
|
-
schema: {$ref: "#/components/schemas/PaginatedPetList"},
|
|
554
|
-
},
|
|
555
|
-
},
|
|
556
|
-
},
|
|
557
|
-
},
|
|
558
|
-
},
|
|
559
|
-
},
|
|
560
|
-
"/api/shop/v1/pets/{petId}": {
|
|
561
|
-
get: {
|
|
562
|
-
operationId: "getPetById",
|
|
563
|
-
responses: {
|
|
564
|
-
"200": {
|
|
565
|
-
description: "OK",
|
|
566
|
-
content: {
|
|
567
|
-
"application/json": {
|
|
568
|
-
schema: {$ref: "#/components/schemas/Pet"},
|
|
569
|
-
},
|
|
570
|
-
},
|
|
571
|
-
},
|
|
572
|
-
},
|
|
573
|
-
},
|
|
574
|
-
put: {
|
|
575
|
-
operationId: "updatePet",
|
|
576
|
-
requestBody: {
|
|
577
|
-
content: {
|
|
578
|
-
"application/json": {
|
|
579
|
-
schema: {$ref: "#/components/schemas/UpdatePetRequest"},
|
|
580
|
-
},
|
|
581
|
-
},
|
|
582
|
-
},
|
|
583
|
-
responses: {
|
|
584
|
-
"200": {
|
|
585
|
-
description: "OK",
|
|
586
|
-
content: {
|
|
587
|
-
"application/json": {
|
|
588
|
-
schema: {$ref: "#/components/schemas/Pet"},
|
|
589
|
-
},
|
|
590
|
-
},
|
|
591
|
-
},
|
|
592
|
-
},
|
|
593
|
-
},
|
|
594
|
-
delete: {
|
|
595
|
-
operationId: "deletePet",
|
|
596
|
-
responses: {"204": {description: "Deleted"}},
|
|
597
|
-
},
|
|
598
|
-
},
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
await generateFolders(entitiesPath, paths);
|
|
602
|
-
await generateFiles(entitiesPath, paths);
|
|
603
|
-
|
|
604
|
-
const apiFileContent = readFileSync(
|
|
605
|
-
join(entitiesPath, "shop", "pets", "api.ts"),
|
|
606
|
-
"utf-8",
|
|
607
|
-
);
|
|
608
|
-
expect(apiFileContent).toContain("listQueryCacheKey: petsQueriesKeys.listPets");
|
|
609
|
-
expect(apiFileContent).toContain("itemQueryCacheKey: petsQueriesKeys.getPetById");
|
|
610
|
-
// non-sync entities keep the async hooks untouched
|
|
611
|
-
expect(apiFileContent).not.toContain("rastack/sync");
|
|
612
|
-
});
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
describe("Lazy sync entities", () => {
|
|
616
|
-
const entitiesPath = join(__dirname, "entities-lazy");
|
|
617
|
-
|
|
618
|
-
beforeEach(() => {
|
|
619
|
-
mkdirSync(entitiesPath, {recursive: true});
|
|
620
|
-
});
|
|
621
|
-
|
|
622
|
-
afterEach(() => {
|
|
623
|
-
rmSync(entitiesPath, {recursive: true, force: true});
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
it("should mark lazy entities in the generated descriptor", async () => {
|
|
627
|
-
const paths: PathsObject = {
|
|
628
|
-
"/api/airports/v1/comment/": {
|
|
629
|
-
get: {
|
|
630
|
-
operationId: "listComments",
|
|
631
|
-
"x-rastack-sync": "local",
|
|
632
|
-
"x-rastack-sync-load": "lazy",
|
|
633
|
-
responses: {
|
|
634
|
-
"200": {
|
|
635
|
-
description: "OK",
|
|
636
|
-
content: {
|
|
637
|
-
"application/json": {
|
|
638
|
-
schema: {$ref: "#/components/schemas/PaginatedCommentList"},
|
|
639
|
-
},
|
|
640
|
-
},
|
|
641
|
-
},
|
|
642
|
-
},
|
|
643
|
-
},
|
|
644
|
-
},
|
|
645
|
-
} as any;
|
|
646
|
-
|
|
647
|
-
await generateFolders(entitiesPath, paths);
|
|
648
|
-
await generateFiles(entitiesPath, paths);
|
|
649
|
-
|
|
650
|
-
const apiFileContent = readFileSync(
|
|
651
|
-
join(entitiesPath, "airports", "comment", "api.ts"),
|
|
652
|
-
"utf-8",
|
|
653
|
-
);
|
|
654
|
-
expect(apiFileContent).toContain("lazy: true,");
|
|
655
|
-
expect(apiFileContent).toContain("export const commentEntity = defineEntity<IComment>({");
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
it("should mark client-id entities in the generated descriptor", async () => {
|
|
659
|
-
const paths: PathsObject = {
|
|
660
|
-
"/api/airports/v1/note/": {
|
|
661
|
-
get: {
|
|
662
|
-
operationId: "listNotes",
|
|
663
|
-
"x-rastack-sync": "local",
|
|
664
|
-
"x-rastack-sync-client-ids": true,
|
|
665
|
-
responses: {
|
|
666
|
-
"200": {
|
|
667
|
-
description: "OK",
|
|
668
|
-
content: {
|
|
669
|
-
"application/json": {
|
|
670
|
-
schema: {$ref: "#/components/schemas/PaginatedNoteList"},
|
|
671
|
-
},
|
|
672
|
-
},
|
|
673
|
-
},
|
|
674
|
-
},
|
|
675
|
-
},
|
|
676
|
-
},
|
|
677
|
-
} as any;
|
|
678
|
-
|
|
679
|
-
await generateFolders(entitiesPath, paths);
|
|
680
|
-
await generateFiles(entitiesPath, paths);
|
|
681
|
-
|
|
682
|
-
const apiFileContent = readFileSync(
|
|
683
|
-
join(entitiesPath, "airports", "note", "api.ts"),
|
|
684
|
-
"utf-8",
|
|
685
|
-
);
|
|
686
|
-
expect(apiFileContent).toContain("clientIds: true,");
|
|
687
|
-
});
|
|
688
|
-
});
|