@teamkeel/functions-runtime 0.337.0 → 0.339.0
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/.env.test +2 -0
- package/package.json +1 -1
- package/pnpm-lock.yaml +738 -328
- package/src/ModelAPI.js +2 -5
- package/src/ModelAPI.test.js +87 -41
- package/src/database.js +43 -12
- package/src/handleRequest.js +2 -2
- package/src/handleRequest.test.js +12 -20
- package/src/permissions.test.js +0 -3
- package/vite.config.js +7 -0
package/src/ModelAPI.js
CHANGED
|
@@ -44,11 +44,10 @@ class DatabaseError extends Error {
|
|
|
44
44
|
class ModelAPI {
|
|
45
45
|
/**
|
|
46
46
|
* @param {string} tableName The name of the table this API is for
|
|
47
|
-
* @param {Function}
|
|
47
|
+
* @param {Function} _ Used to be a function that returns the default values for a row in this table. No longer used.
|
|
48
48
|
* @param {TableConfigMap} tableConfigMap
|
|
49
49
|
*/
|
|
50
|
-
constructor(tableName,
|
|
51
|
-
this._defaultValues = defaultValues;
|
|
50
|
+
constructor(tableName, _, tableConfigMap = {}) {
|
|
52
51
|
this._tableName = tableName;
|
|
53
52
|
this._tableConfigMap = tableConfigMap;
|
|
54
53
|
this._modelName = upperCamelCase(this._tableName);
|
|
@@ -60,12 +59,10 @@ class ModelAPI {
|
|
|
60
59
|
|
|
61
60
|
return tracing.withSpan(name, async (span) => {
|
|
62
61
|
try {
|
|
63
|
-
const defaults = this._defaultValues();
|
|
64
62
|
const query = db
|
|
65
63
|
.insertInto(this._tableName)
|
|
66
64
|
.values(
|
|
67
65
|
snakeCaseObject({
|
|
68
|
-
...defaults,
|
|
69
66
|
...values,
|
|
70
67
|
})
|
|
71
68
|
)
|
package/src/ModelAPI.test.js
CHANGED
|
@@ -4,9 +4,6 @@ const { sql } = require("kysely");
|
|
|
4
4
|
const { useDatabase } = require("./database");
|
|
5
5
|
const KSUID = require("ksuid");
|
|
6
6
|
|
|
7
|
-
process.env.KEEL_DB_CONN_TYPE = "pg";
|
|
8
|
-
process.env.KEEL_DB_CONN = `postgresql://postgres:postgres@localhost:5432/functions-runtime`;
|
|
9
|
-
|
|
10
7
|
let personAPI;
|
|
11
8
|
let postAPI;
|
|
12
9
|
let authorAPI;
|
|
@@ -54,47 +51,22 @@ beforeEach(async () => {
|
|
|
54
51
|
},
|
|
55
52
|
};
|
|
56
53
|
|
|
57
|
-
personAPI = new ModelAPI(
|
|
58
|
-
"person",
|
|
59
|
-
() => {
|
|
60
|
-
return {
|
|
61
|
-
id: KSUID.randomSync().string,
|
|
62
|
-
date: new Date("2022-01-01"),
|
|
63
|
-
};
|
|
64
|
-
},
|
|
65
|
-
tableConfigMap
|
|
66
|
-
);
|
|
54
|
+
personAPI = new ModelAPI("person", undefined, tableConfigMap);
|
|
67
55
|
|
|
68
|
-
postAPI = new ModelAPI(
|
|
69
|
-
"post",
|
|
70
|
-
() => {
|
|
71
|
-
return {
|
|
72
|
-
id: KSUID.randomSync().string,
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
tableConfigMap
|
|
76
|
-
);
|
|
56
|
+
postAPI = new ModelAPI("post", undefined, tableConfigMap);
|
|
77
57
|
|
|
78
|
-
authorAPI = new ModelAPI(
|
|
79
|
-
"author",
|
|
80
|
-
() => {
|
|
81
|
-
return {
|
|
82
|
-
id: KSUID.randomSync().string,
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
tableConfigMap
|
|
86
|
-
);
|
|
58
|
+
authorAPI = new ModelAPI("author", undefined, tableConfigMap);
|
|
87
59
|
});
|
|
88
60
|
|
|
89
61
|
test("ModelAPI.create", async () => {
|
|
90
62
|
const row = await personAPI.create({
|
|
63
|
+
id: KSUID.randomSync().string,
|
|
91
64
|
name: "Jim",
|
|
92
65
|
married: false,
|
|
93
66
|
favouriteNumber: 10,
|
|
94
67
|
});
|
|
95
68
|
expect(row.name).toEqual("Jim");
|
|
96
69
|
expect(row.married).toEqual(false);
|
|
97
|
-
expect(row.date).toEqual(new Date("2022-01-01"));
|
|
98
70
|
expect(row.favouriteNumber).toEqual(10);
|
|
99
71
|
expect(KSUID.parse(row.id).string).toEqual(row.id);
|
|
100
72
|
});
|
|
@@ -102,6 +74,7 @@ test("ModelAPI.create", async () => {
|
|
|
102
74
|
test("ModelAPI.create - throws if not not null constraint violation", async () => {
|
|
103
75
|
await expect(
|
|
104
76
|
authorAPI.create({
|
|
77
|
+
id: KSUID.randomSync().string,
|
|
105
78
|
name: null,
|
|
106
79
|
})
|
|
107
80
|
).rejects.toThrow('null value in column "name" violates not-null constraint');
|
|
@@ -109,11 +82,13 @@ test("ModelAPI.create - throws if not not null constraint violation", async () =
|
|
|
109
82
|
|
|
110
83
|
test("ModelAPI.create - throws if database constraint fails", async () => {
|
|
111
84
|
const row = await personAPI.create({
|
|
85
|
+
id: KSUID.randomSync().string,
|
|
112
86
|
name: "Jim",
|
|
113
87
|
married: false,
|
|
114
88
|
favouriteNumber: 10,
|
|
115
89
|
});
|
|
116
90
|
const promise = personAPI.create({
|
|
91
|
+
id: KSUID.randomSync().string,
|
|
117
92
|
id: row.id,
|
|
118
93
|
name: "Jim",
|
|
119
94
|
married: false,
|
|
@@ -126,6 +101,7 @@ test("ModelAPI.create - throws if database constraint fails", async () => {
|
|
|
126
101
|
|
|
127
102
|
test("ModelAPI.findOne", async () => {
|
|
128
103
|
const created = await personAPI.create({
|
|
104
|
+
id: KSUID.randomSync().string,
|
|
129
105
|
name: "Jim",
|
|
130
106
|
married: false,
|
|
131
107
|
favouriteNumber: 10,
|
|
@@ -138,11 +114,13 @@ test("ModelAPI.findOne", async () => {
|
|
|
138
114
|
|
|
139
115
|
test("ModelAPI.findOne - relationships - one to many", async () => {
|
|
140
116
|
const person = await personAPI.create({
|
|
117
|
+
id: KSUID.randomSync().string,
|
|
141
118
|
name: "Jim",
|
|
142
119
|
married: false,
|
|
143
120
|
favouriteNumber: 10,
|
|
144
121
|
});
|
|
145
122
|
const post = await postAPI.create({
|
|
123
|
+
id: KSUID.randomSync().string,
|
|
146
124
|
title: "My Post",
|
|
147
125
|
authorId: person.id,
|
|
148
126
|
});
|
|
@@ -164,16 +142,19 @@ test("ModelAPI.findOne - return null if not found", async () => {
|
|
|
164
142
|
|
|
165
143
|
test("ModelAPI.findMany", async () => {
|
|
166
144
|
await personAPI.create({
|
|
145
|
+
id: KSUID.randomSync().string,
|
|
167
146
|
name: "Jim",
|
|
168
147
|
married: false,
|
|
169
148
|
favouriteNumber: 10,
|
|
170
149
|
});
|
|
171
150
|
const bob = await personAPI.create({
|
|
151
|
+
id: KSUID.randomSync().string,
|
|
172
152
|
name: "Bob",
|
|
173
153
|
married: true,
|
|
174
154
|
favouriteNumber: 11,
|
|
175
155
|
});
|
|
176
156
|
const sally = await personAPI.create({
|
|
157
|
+
id: KSUID.randomSync().string,
|
|
177
158
|
name: "Sally",
|
|
178
159
|
married: true,
|
|
179
160
|
favouriteNumber: 12,
|
|
@@ -189,9 +170,11 @@ test("ModelAPI.findMany", async () => {
|
|
|
189
170
|
|
|
190
171
|
test("ModelAPI.findMany - no where conditions", async () => {
|
|
191
172
|
await personAPI.create({
|
|
173
|
+
id: KSUID.randomSync().string,
|
|
192
174
|
name: "Jim",
|
|
193
175
|
});
|
|
194
176
|
await personAPI.create({
|
|
177
|
+
id: KSUID.randomSync().string,
|
|
195
178
|
name: "Bob",
|
|
196
179
|
});
|
|
197
180
|
|
|
@@ -202,9 +185,11 @@ test("ModelAPI.findMany - no where conditions", async () => {
|
|
|
202
185
|
|
|
203
186
|
test("ModelAPI.findMany - startsWith", async () => {
|
|
204
187
|
const jim = await personAPI.create({
|
|
188
|
+
id: KSUID.randomSync().string,
|
|
205
189
|
name: "Jim",
|
|
206
190
|
});
|
|
207
191
|
await personAPI.create({
|
|
192
|
+
id: KSUID.randomSync().string,
|
|
208
193
|
name: "Bob",
|
|
209
194
|
});
|
|
210
195
|
const rows = await personAPI.findMany({
|
|
@@ -220,9 +205,11 @@ test("ModelAPI.findMany - startsWith", async () => {
|
|
|
220
205
|
|
|
221
206
|
test("ModelAPI.findMany - endsWith", async () => {
|
|
222
207
|
const jim = await personAPI.create({
|
|
208
|
+
id: KSUID.randomSync().string,
|
|
223
209
|
name: "Jim",
|
|
224
210
|
});
|
|
225
211
|
await personAPI.create({
|
|
212
|
+
id: KSUID.randomSync().string,
|
|
226
213
|
name: "Bob",
|
|
227
214
|
});
|
|
228
215
|
const rows = await personAPI.findMany({
|
|
@@ -238,12 +225,15 @@ test("ModelAPI.findMany - endsWith", async () => {
|
|
|
238
225
|
|
|
239
226
|
test("ModelAPI.findMany - contains", async () => {
|
|
240
227
|
const billy = await personAPI.create({
|
|
228
|
+
id: KSUID.randomSync().string,
|
|
241
229
|
name: "Billy",
|
|
242
230
|
});
|
|
243
231
|
const sally = await personAPI.create({
|
|
232
|
+
id: KSUID.randomSync().string,
|
|
244
233
|
name: "Sally",
|
|
245
234
|
});
|
|
246
235
|
await personAPI.create({
|
|
236
|
+
id: KSUID.randomSync().string,
|
|
247
237
|
name: "Jim",
|
|
248
238
|
});
|
|
249
239
|
const rows = await personAPI.findMany({
|
|
@@ -259,12 +249,15 @@ test("ModelAPI.findMany - contains", async () => {
|
|
|
259
249
|
|
|
260
250
|
test("ModelAPI.findMany - oneOf", async () => {
|
|
261
251
|
const billy = await personAPI.create({
|
|
252
|
+
id: KSUID.randomSync().string,
|
|
262
253
|
name: "Billy",
|
|
263
254
|
});
|
|
264
255
|
const sally = await personAPI.create({
|
|
256
|
+
id: KSUID.randomSync().string,
|
|
265
257
|
name: "Sally",
|
|
266
258
|
});
|
|
267
259
|
await personAPI.create({
|
|
260
|
+
id: KSUID.randomSync().string,
|
|
268
261
|
name: "Jim",
|
|
269
262
|
});
|
|
270
263
|
const rows = await personAPI.findMany({
|
|
@@ -280,9 +273,11 @@ test("ModelAPI.findMany - oneOf", async () => {
|
|
|
280
273
|
|
|
281
274
|
test("ModelAPI.findMany - greaterThan", async () => {
|
|
282
275
|
await personAPI.create({
|
|
276
|
+
id: KSUID.randomSync().string,
|
|
283
277
|
favouriteNumber: 1,
|
|
284
278
|
});
|
|
285
279
|
const p = await personAPI.create({
|
|
280
|
+
id: KSUID.randomSync().string,
|
|
286
281
|
favouriteNumber: 2,
|
|
287
282
|
});
|
|
288
283
|
const rows = await personAPI.findMany({
|
|
@@ -298,12 +293,15 @@ test("ModelAPI.findMany - greaterThan", async () => {
|
|
|
298
293
|
|
|
299
294
|
test("ModelAPI.findMany - greaterThanOrEquals", async () => {
|
|
300
295
|
await personAPI.create({
|
|
296
|
+
id: KSUID.randomSync().string,
|
|
301
297
|
favouriteNumber: 1,
|
|
302
298
|
});
|
|
303
299
|
const p = await personAPI.create({
|
|
300
|
+
id: KSUID.randomSync().string,
|
|
304
301
|
favouriteNumber: 2,
|
|
305
302
|
});
|
|
306
303
|
const p2 = await personAPI.create({
|
|
304
|
+
id: KSUID.randomSync().string,
|
|
307
305
|
favouriteNumber: 3,
|
|
308
306
|
});
|
|
309
307
|
const rows = await personAPI.findMany({
|
|
@@ -319,9 +317,11 @@ test("ModelAPI.findMany - greaterThanOrEquals", async () => {
|
|
|
319
317
|
|
|
320
318
|
test("ModelAPI.findMany - lessThan", async () => {
|
|
321
319
|
const p = await personAPI.create({
|
|
320
|
+
id: KSUID.randomSync().string,
|
|
322
321
|
favouriteNumber: 1,
|
|
323
322
|
});
|
|
324
323
|
await personAPI.create({
|
|
324
|
+
id: KSUID.randomSync().string,
|
|
325
325
|
favouriteNumber: 2,
|
|
326
326
|
});
|
|
327
327
|
const rows = await personAPI.findMany({
|
|
@@ -337,12 +337,15 @@ test("ModelAPI.findMany - lessThan", async () => {
|
|
|
337
337
|
|
|
338
338
|
test("ModelAPI.findMany - lessThanOrEquals", async () => {
|
|
339
339
|
const p = await personAPI.create({
|
|
340
|
+
id: KSUID.randomSync().string,
|
|
340
341
|
favouriteNumber: 1,
|
|
341
342
|
});
|
|
342
343
|
const p2 = await personAPI.create({
|
|
344
|
+
id: KSUID.randomSync().string,
|
|
343
345
|
favouriteNumber: 2,
|
|
344
346
|
});
|
|
345
347
|
await personAPI.create({
|
|
348
|
+
id: KSUID.randomSync().string,
|
|
346
349
|
favouriteNumber: 3,
|
|
347
350
|
});
|
|
348
351
|
const rows = await personAPI.findMany({
|
|
@@ -358,9 +361,11 @@ test("ModelAPI.findMany - lessThanOrEquals", async () => {
|
|
|
358
361
|
|
|
359
362
|
test("ModelAPI.findMany - before", async () => {
|
|
360
363
|
const p = await personAPI.create({
|
|
364
|
+
id: KSUID.randomSync().string,
|
|
361
365
|
date: new Date("2022-01-01"),
|
|
362
366
|
});
|
|
363
367
|
await personAPI.create({
|
|
368
|
+
id: KSUID.randomSync().string,
|
|
364
369
|
date: new Date("2022-01-02"),
|
|
365
370
|
});
|
|
366
371
|
const rows = await personAPI.findMany({
|
|
@@ -376,10 +381,12 @@ test("ModelAPI.findMany - before", async () => {
|
|
|
376
381
|
|
|
377
382
|
test("ModelAPI.findMany - empty where", async () => {
|
|
378
383
|
const p = await personAPI.create({
|
|
384
|
+
id: KSUID.randomSync().string,
|
|
379
385
|
date: new Date("2022-01-01"),
|
|
380
386
|
});
|
|
381
387
|
|
|
382
388
|
const p2 = await personAPI.create({
|
|
389
|
+
id: KSUID.randomSync().string,
|
|
383
390
|
date: new Date("2022-01-02"),
|
|
384
391
|
});
|
|
385
392
|
|
|
@@ -398,12 +405,15 @@ test("ModelAPI.findMany - empty where", async () => {
|
|
|
398
405
|
|
|
399
406
|
test("ModelAPI.findMany - onOrBefore", async () => {
|
|
400
407
|
const p = await personAPI.create({
|
|
408
|
+
id: KSUID.randomSync().string,
|
|
401
409
|
date: new Date("2022-01-01"),
|
|
402
410
|
});
|
|
403
411
|
const p2 = await personAPI.create({
|
|
412
|
+
id: KSUID.randomSync().string,
|
|
404
413
|
date: new Date("2022-01-02"),
|
|
405
414
|
});
|
|
406
415
|
await personAPI.create({
|
|
416
|
+
id: KSUID.randomSync().string,
|
|
407
417
|
date: new Date("2022-01-03"),
|
|
408
418
|
});
|
|
409
419
|
const rows = await personAPI.findMany({
|
|
@@ -419,19 +429,19 @@ test("ModelAPI.findMany - onOrBefore", async () => {
|
|
|
419
429
|
|
|
420
430
|
test("ModelAPI.findMany - limit", async () => {
|
|
421
431
|
await personAPI.create({
|
|
422
|
-
id:
|
|
432
|
+
id: KSUID.randomSync().string,
|
|
423
433
|
name: "Jim",
|
|
424
434
|
married: false,
|
|
425
435
|
favouriteNumber: 10,
|
|
426
436
|
});
|
|
427
437
|
await personAPI.create({
|
|
428
|
-
id:
|
|
438
|
+
id: KSUID.randomSync().string,
|
|
429
439
|
name: "Bob",
|
|
430
440
|
married: true,
|
|
431
441
|
favouriteNumber: 11,
|
|
432
442
|
});
|
|
433
443
|
await personAPI.create({
|
|
434
|
-
id:
|
|
444
|
+
id: KSUID.randomSync().string,
|
|
435
445
|
name: "Sally",
|
|
436
446
|
married: true,
|
|
437
447
|
favouriteNumber: 12,
|
|
@@ -439,6 +449,9 @@ test("ModelAPI.findMany - limit", async () => {
|
|
|
439
449
|
|
|
440
450
|
const rows = await personAPI.findMany({
|
|
441
451
|
limit: 2,
|
|
452
|
+
orderBy: {
|
|
453
|
+
favouriteNumber: "asc",
|
|
454
|
+
},
|
|
442
455
|
});
|
|
443
456
|
|
|
444
457
|
expect(rows.map((r) => r.name)).toEqual(["Jim", "Bob"]);
|
|
@@ -446,21 +459,21 @@ test("ModelAPI.findMany - limit", async () => {
|
|
|
446
459
|
|
|
447
460
|
test("ModelAPI.findMany - orderBy", async () => {
|
|
448
461
|
await personAPI.create({
|
|
449
|
-
id:
|
|
462
|
+
id: KSUID.randomSync().string,
|
|
450
463
|
name: "Jim",
|
|
451
464
|
married: false,
|
|
452
465
|
favouriteNumber: 10,
|
|
453
466
|
date: new Date(2023, 12, 29),
|
|
454
467
|
});
|
|
455
468
|
await personAPI.create({
|
|
456
|
-
id:
|
|
469
|
+
id: KSUID.randomSync().string,
|
|
457
470
|
name: "Bob",
|
|
458
471
|
married: true,
|
|
459
472
|
favouriteNumber: 11,
|
|
460
473
|
date: new Date(2023, 12, 30),
|
|
461
474
|
});
|
|
462
475
|
await personAPI.create({
|
|
463
|
-
id:
|
|
476
|
+
id: KSUID.randomSync().string,
|
|
464
477
|
name: "Sally",
|
|
465
478
|
married: true,
|
|
466
479
|
favouriteNumber: 12,
|
|
@@ -506,21 +519,21 @@ test("ModelAPI.findMany - orderBy", async () => {
|
|
|
506
519
|
|
|
507
520
|
test("ModelAPI.findMany - offset", async () => {
|
|
508
521
|
await personAPI.create({
|
|
509
|
-
id:
|
|
522
|
+
id: KSUID.randomSync().string,
|
|
510
523
|
name: "Jim",
|
|
511
524
|
married: false,
|
|
512
525
|
favouriteNumber: 10,
|
|
513
526
|
date: new Date(2023, 12, 29),
|
|
514
527
|
});
|
|
515
528
|
await personAPI.create({
|
|
516
|
-
id:
|
|
529
|
+
id: KSUID.randomSync().string,
|
|
517
530
|
name: "Bob",
|
|
518
531
|
married: true,
|
|
519
532
|
favouriteNumber: 11,
|
|
520
533
|
date: new Date(2023, 12, 30),
|
|
521
534
|
});
|
|
522
535
|
await personAPI.create({
|
|
523
|
-
id:
|
|
536
|
+
id: KSUID.randomSync().string,
|
|
524
537
|
name: "Sally",
|
|
525
538
|
married: true,
|
|
526
539
|
favouriteNumber: 12,
|
|
@@ -559,9 +572,11 @@ test("ModelAPI.findMany - offset", async () => {
|
|
|
559
572
|
|
|
560
573
|
test("ModelAPI.findMany - after", async () => {
|
|
561
574
|
await personAPI.create({
|
|
575
|
+
id: KSUID.randomSync().string,
|
|
562
576
|
date: new Date("2022-01-01"),
|
|
563
577
|
});
|
|
564
578
|
const p = await personAPI.create({
|
|
579
|
+
id: KSUID.randomSync().string,
|
|
565
580
|
date: new Date("2022-01-02"),
|
|
566
581
|
});
|
|
567
582
|
const rows = await personAPI.findMany({
|
|
@@ -577,12 +592,15 @@ test("ModelAPI.findMany - after", async () => {
|
|
|
577
592
|
|
|
578
593
|
test("ModelAPI.findMany - onOrAfter", async () => {
|
|
579
594
|
await personAPI.create({
|
|
595
|
+
id: KSUID.randomSync().string,
|
|
580
596
|
date: new Date("2022-01-01"),
|
|
581
597
|
});
|
|
582
598
|
const p = await personAPI.create({
|
|
599
|
+
id: KSUID.randomSync().string,
|
|
583
600
|
date: new Date("2022-01-02"),
|
|
584
601
|
});
|
|
585
602
|
const p2 = await personAPI.create({
|
|
603
|
+
id: KSUID.randomSync().string,
|
|
586
604
|
date: new Date("2022-01-03"),
|
|
587
605
|
});
|
|
588
606
|
const rows = await personAPI.findMany({
|
|
@@ -598,9 +616,11 @@ test("ModelAPI.findMany - onOrAfter", async () => {
|
|
|
598
616
|
|
|
599
617
|
test("ModelAPI.findMany - equals", async () => {
|
|
600
618
|
const p = await personAPI.create({
|
|
619
|
+
id: KSUID.randomSync().string,
|
|
601
620
|
name: "Jim",
|
|
602
621
|
});
|
|
603
622
|
await personAPI.create({
|
|
623
|
+
id: KSUID.randomSync().string,
|
|
604
624
|
name: "Sally",
|
|
605
625
|
});
|
|
606
626
|
const rows = await personAPI.findMany({
|
|
@@ -616,9 +636,11 @@ test("ModelAPI.findMany - equals", async () => {
|
|
|
616
636
|
|
|
617
637
|
test("ModelAPI.findMany - notEquals", async () => {
|
|
618
638
|
const p = await personAPI.create({
|
|
639
|
+
id: KSUID.randomSync().string,
|
|
619
640
|
name: "Jim",
|
|
620
641
|
});
|
|
621
642
|
await personAPI.create({
|
|
643
|
+
id: KSUID.randomSync().string,
|
|
622
644
|
name: "Sally",
|
|
623
645
|
});
|
|
624
646
|
const rows = await personAPI.findMany({
|
|
@@ -634,16 +656,19 @@ test("ModelAPI.findMany - notEquals", async () => {
|
|
|
634
656
|
|
|
635
657
|
test("ModelAPI.findMany - complex query", async () => {
|
|
636
658
|
const p = await personAPI.create({
|
|
659
|
+
id: KSUID.randomSync().string,
|
|
637
660
|
name: "Jake",
|
|
638
661
|
favouriteNumber: 8,
|
|
639
662
|
date: new Date("2021-12-31"),
|
|
640
663
|
});
|
|
641
664
|
await personAPI.create({
|
|
665
|
+
id: KSUID.randomSync().string,
|
|
642
666
|
name: "Jane",
|
|
643
667
|
favouriteNumber: 12,
|
|
644
668
|
date: new Date("2022-01-11"),
|
|
645
669
|
});
|
|
646
670
|
const p2 = await personAPI.create({
|
|
671
|
+
id: KSUID.randomSync().string,
|
|
647
672
|
name: "Billy",
|
|
648
673
|
favouriteNumber: 16,
|
|
649
674
|
date: new Date("2022-01-05"),
|
|
@@ -674,20 +699,25 @@ test("ModelAPI.findMany - complex query", async () => {
|
|
|
674
699
|
|
|
675
700
|
test("ModelAPI.findMany - relationships - one to many", async () => {
|
|
676
701
|
const person = await personAPI.create({
|
|
702
|
+
id: KSUID.randomSync().string,
|
|
677
703
|
name: "Jim",
|
|
678
704
|
});
|
|
679
705
|
const person2 = await personAPI.create({
|
|
706
|
+
id: KSUID.randomSync().string,
|
|
680
707
|
name: "Bob",
|
|
681
708
|
});
|
|
682
709
|
const post1 = await postAPI.create({
|
|
710
|
+
id: KSUID.randomSync().string,
|
|
683
711
|
title: "My First Post",
|
|
684
712
|
authorId: person.id,
|
|
685
713
|
});
|
|
686
714
|
const post2 = await postAPI.create({
|
|
715
|
+
id: KSUID.randomSync().string,
|
|
687
716
|
title: "My Second Post",
|
|
688
717
|
authorId: person.id,
|
|
689
718
|
});
|
|
690
719
|
await postAPI.create({
|
|
720
|
+
id: KSUID.randomSync().string,
|
|
691
721
|
title: "My Third Post",
|
|
692
722
|
authorId: person2.id,
|
|
693
723
|
});
|
|
@@ -705,17 +735,21 @@ test("ModelAPI.findMany - relationships - one to many", async () => {
|
|
|
705
735
|
|
|
706
736
|
test("ModelAPI.findMany - relationships - many to one", async () => {
|
|
707
737
|
const person = await personAPI.create({
|
|
738
|
+
id: KSUID.randomSync().string,
|
|
708
739
|
name: "Jim",
|
|
709
740
|
});
|
|
710
741
|
await postAPI.create({
|
|
742
|
+
id: KSUID.randomSync().string,
|
|
711
743
|
title: "My First Post",
|
|
712
744
|
authorId: person.id,
|
|
713
745
|
});
|
|
714
746
|
await postAPI.create({
|
|
747
|
+
id: KSUID.randomSync().string,
|
|
715
748
|
title: "My Second Post",
|
|
716
749
|
authorId: person.id,
|
|
717
750
|
});
|
|
718
751
|
await postAPI.create({
|
|
752
|
+
id: KSUID.randomSync().string,
|
|
719
753
|
title: "My Second Post",
|
|
720
754
|
authorId: person.id,
|
|
721
755
|
});
|
|
@@ -740,16 +774,20 @@ test("ModelAPI.findMany - relationships - many to one", async () => {
|
|
|
740
774
|
|
|
741
775
|
test("ModelAPI.findMany - relationships - duplicate joins handled", async () => {
|
|
742
776
|
const person = await personAPI.create({
|
|
777
|
+
id: KSUID.randomSync().string,
|
|
743
778
|
name: "Jim",
|
|
744
779
|
});
|
|
745
780
|
const person2 = await personAPI.create({
|
|
781
|
+
id: KSUID.randomSync().string,
|
|
746
782
|
name: "Bob",
|
|
747
783
|
});
|
|
748
784
|
const post1 = await postAPI.create({
|
|
785
|
+
id: KSUID.randomSync().string,
|
|
749
786
|
title: "My First Post",
|
|
750
787
|
authorId: person.id,
|
|
751
788
|
});
|
|
752
789
|
const post2 = await postAPI.create({
|
|
790
|
+
id: KSUID.randomSync().string,
|
|
753
791
|
title: "My Second Post",
|
|
754
792
|
authorId: person2.id,
|
|
755
793
|
});
|
|
@@ -773,11 +811,13 @@ test("ModelAPI.findMany - relationships - duplicate joins handled", async () =>
|
|
|
773
811
|
|
|
774
812
|
test("ModelAPI.update", async () => {
|
|
775
813
|
let jim = await personAPI.create({
|
|
814
|
+
id: KSUID.randomSync().string,
|
|
776
815
|
name: "Jim",
|
|
777
816
|
married: false,
|
|
778
817
|
favouriteNumber: 10,
|
|
779
818
|
});
|
|
780
819
|
let bob = await personAPI.create({
|
|
820
|
+
id: KSUID.randomSync().string,
|
|
781
821
|
name: "Bob",
|
|
782
822
|
married: false,
|
|
783
823
|
favouriteNumber: 11,
|
|
@@ -811,6 +851,7 @@ test("ModelAPI.update - throws if not found", async () => {
|
|
|
811
851
|
|
|
812
852
|
test("ModelAPI.update - throws if not not null constraint violation", async () => {
|
|
813
853
|
const jim = await authorAPI.create({
|
|
854
|
+
id: KSUID.randomSync().string,
|
|
814
855
|
name: "jim",
|
|
815
856
|
});
|
|
816
857
|
|
|
@@ -830,6 +871,7 @@ test("ModelAPI.update - throws if not not null constraint violation", async () =
|
|
|
830
871
|
|
|
831
872
|
test("ModelAPI.delete", async () => {
|
|
832
873
|
const jim = await personAPI.create({
|
|
874
|
+
id: KSUID.randomSync().string,
|
|
833
875
|
name: "Jim",
|
|
834
876
|
});
|
|
835
877
|
const id = jim.id;
|
|
@@ -843,15 +885,19 @@ test("ModelAPI.delete", async () => {
|
|
|
843
885
|
|
|
844
886
|
test("ModelAPI chained findMany with offset/limit/order by", async () => {
|
|
845
887
|
await postAPI.create({
|
|
888
|
+
id: KSUID.randomSync().string,
|
|
846
889
|
title: "adam",
|
|
847
890
|
});
|
|
848
891
|
await postAPI.create({
|
|
892
|
+
id: KSUID.randomSync().string,
|
|
849
893
|
title: "dave",
|
|
850
894
|
});
|
|
851
895
|
const three = await postAPI.create({
|
|
896
|
+
id: KSUID.randomSync().string,
|
|
852
897
|
title: "jon",
|
|
853
898
|
});
|
|
854
899
|
const four = await postAPI.create({
|
|
900
|
+
id: KSUID.randomSync().string,
|
|
855
901
|
title: "jon bretman",
|
|
856
902
|
});
|
|
857
903
|
|
package/src/database.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Kysely, PostgresDialect } = require("kysely");
|
|
1
|
+
const { Kysely, PostgresDialect, CamelCasePlugin } = require("kysely");
|
|
2
2
|
const { AsyncLocalStorage } = require("async_hooks");
|
|
3
3
|
const pg = require("pg");
|
|
4
4
|
const { PROTO_ACTION_TYPES } = require("./consts");
|
|
@@ -35,24 +35,51 @@ async function withDatabase(db, actionType, cb) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
let db = null;
|
|
38
|
+
|
|
38
39
|
const dbInstance = new AsyncLocalStorage();
|
|
39
40
|
|
|
40
41
|
// useDatabase will retrieve the database client set by withDatabase from the local storage
|
|
41
42
|
function useDatabase() {
|
|
43
|
+
// retrieve the instance of the database client from the store which is aware of
|
|
44
|
+
// which context the current connection to the db is running in - e.g does the context
|
|
45
|
+
// require a transaction or not?
|
|
42
46
|
let fromStore = dbInstance.getStore();
|
|
43
47
|
if (fromStore) {
|
|
44
48
|
return fromStore;
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
// if the NODE_ENV is 'test' then we know we are inside of the vitest environment
|
|
52
|
+
// which covers any test files ending in *.test.ts. Custom function code runs in a different node process which will not have this environment variable. Tests written using our testing
|
|
53
|
+
// framework call actions (and in turn custom function code) over http using the ActionExecutor class
|
|
54
|
+
if ("NODE_ENV" in process.env && process.env.NODE_ENV == "test") {
|
|
55
|
+
return getDatabaseClient();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// If we've gotten to this point, then we know that we are in a custom function runtime server
|
|
59
|
+
// context and we haven't been able to retrieve the in-context instance of Kysely, which means we should throw an error.
|
|
60
|
+
throw new Error("useDatabase must be called within a function");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// getDatabaseClient will return a brand new instance of Kysely. Every instance of Kysely
|
|
64
|
+
// represents an individual connection to the database.
|
|
65
|
+
// not to be exported externally from our sdk - consumers should use useDatabase
|
|
66
|
+
function getDatabaseClient() {
|
|
67
|
+
// 'db' represents the singleton connection to the database which is stored
|
|
68
|
+
// as a module scope variable.
|
|
47
69
|
if (db) {
|
|
48
70
|
return db;
|
|
49
71
|
}
|
|
50
72
|
|
|
51
|
-
// todo: ideally we wouldn't want to give you a fresh Kysely instance here if nothing
|
|
52
|
-
// has been found in the context, but the @teamkeel/testing package needs some restructuring
|
|
53
|
-
// to allow for the database client to be set in the store so that this method can throw an error at this line instead of returning a fresh kysely instance.
|
|
54
73
|
db = new Kysely({
|
|
55
74
|
dialect: getDialect(),
|
|
75
|
+
plugins: [
|
|
76
|
+
// allows users to query using camelCased versions of the database column names, which
|
|
77
|
+
// should match the names we use in our schema.
|
|
78
|
+
// https://kysely-org.github.io/kysely/classes/CamelCasePlugin.html
|
|
79
|
+
// If they don't, then we can create a custom implementation of the plugin where we control
|
|
80
|
+
// the casing behaviour (see url above for example)
|
|
81
|
+
new CamelCasePlugin(),
|
|
82
|
+
],
|
|
56
83
|
log(event) {
|
|
57
84
|
if ("DEBUG" in process.env) {
|
|
58
85
|
if (event.level === "query") {
|
|
@@ -66,14 +93,6 @@ function useDatabase() {
|
|
|
66
93
|
return db;
|
|
67
94
|
}
|
|
68
95
|
|
|
69
|
-
function mustEnv(key) {
|
|
70
|
-
const v = process.env[key];
|
|
71
|
-
if (!v) {
|
|
72
|
-
throw new Error(`expected environment variable ${key} to be set`);
|
|
73
|
-
}
|
|
74
|
-
return v;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
96
|
class InstrumentedPool extends pg.Pool {
|
|
78
97
|
async connect(...args) {
|
|
79
98
|
const _super = super.connect.bind(this);
|
|
@@ -127,5 +146,17 @@ function getDialect() {
|
|
|
127
146
|
}
|
|
128
147
|
}
|
|
129
148
|
|
|
149
|
+
function mustEnv(key) {
|
|
150
|
+
const v = process.env[key];
|
|
151
|
+
if (!v) {
|
|
152
|
+
throw new Error(`expected environment variable ${key} to be set`);
|
|
153
|
+
}
|
|
154
|
+
return v;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// initialise the database client at module scope level so the db variable is set
|
|
158
|
+
getDatabaseClient();
|
|
159
|
+
|
|
160
|
+
module.exports.getDatabaseClient = getDatabaseClient;
|
|
130
161
|
module.exports.useDatabase = useDatabase;
|
|
131
162
|
module.exports.withDatabase = withDatabase;
|
package/src/handleRequest.js
CHANGED
|
@@ -3,7 +3,7 @@ const {
|
|
|
3
3
|
createJSONRPCSuccessResponse,
|
|
4
4
|
JSONRPCErrorCode,
|
|
5
5
|
} = require("json-rpc-2.0");
|
|
6
|
-
const {
|
|
6
|
+
const { getDatabaseClient } = require("./database");
|
|
7
7
|
const { tryExecuteFunction } = require("./tryExecuteFunction");
|
|
8
8
|
const { errorToJSONRPCResponse, RuntimeErrors } = require("./errors");
|
|
9
9
|
const opentelemetry = require("@opentelemetry/api");
|
|
@@ -57,7 +57,7 @@ async function handleRequest(request, config) {
|
|
|
57
57
|
? true
|
|
58
58
|
: null;
|
|
59
59
|
|
|
60
|
-
const db =
|
|
60
|
+
const db = getDatabaseClient();
|
|
61
61
|
const customFunction = functions[request.method];
|
|
62
62
|
|
|
63
63
|
const result = await tryExecuteFunction(
|