@teamkeel/functions-runtime 0.366.0-audit-logs0 → 0.366.0-prerelease0
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/package.json +1 -1
- package/src/auditing.js +5 -14
- package/src/database.js +1 -1
- package/src/handleRequest.test.js +73 -0
package/package.json
CHANGED
package/src/auditing.js
CHANGED
|
@@ -44,14 +44,6 @@ class AuditContextPlugin {
|
|
|
44
44
|
this.traceIdAlias = "__keel_trace_id";
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
#setIdentityClause(value) {
|
|
48
|
-
return `set_identity_id('${value}')`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
#setTraceIdClause(value) {
|
|
52
|
-
return `set_trace_id('${value}')`;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
47
|
// Appends set_identity_id() and set_trace_id() function calls to the returning statement
|
|
56
48
|
// of INSERT, UPDATE and DELETE operations.
|
|
57
49
|
transformQuery(args) {
|
|
@@ -59,10 +51,13 @@ class AuditContextPlugin {
|
|
|
59
51
|
case "InsertQueryNode":
|
|
60
52
|
case "UpdateQueryNode":
|
|
61
53
|
case "DeleteQueryNode":
|
|
54
|
+
// Represents a RETURNING clause in a SQL statement.
|
|
62
55
|
const returning = {
|
|
63
56
|
kind: "ReturningNode",
|
|
64
57
|
selections: [],
|
|
65
58
|
};
|
|
59
|
+
|
|
60
|
+
// If the query already has a selection, then append it.
|
|
66
61
|
if (args.node.returning) {
|
|
67
62
|
returning.selections.push(...args.node.returning.selections);
|
|
68
63
|
}
|
|
@@ -71,10 +66,7 @@ class AuditContextPlugin {
|
|
|
71
66
|
const audit = getAuditContext();
|
|
72
67
|
|
|
73
68
|
if (audit.identityId) {
|
|
74
|
-
const rawNode = sql
|
|
75
|
-
.raw(
|
|
76
|
-
this.#setIdentityClause(audit.identityId, this.identityIdAlias)
|
|
77
|
-
)
|
|
69
|
+
const rawNode = sql`set_identity_id(${audit.identityId})`
|
|
78
70
|
.as(this.identityIdAlias)
|
|
79
71
|
.toOperationNode();
|
|
80
72
|
|
|
@@ -82,8 +74,7 @@ class AuditContextPlugin {
|
|
|
82
74
|
}
|
|
83
75
|
|
|
84
76
|
if (audit.traceId) {
|
|
85
|
-
const rawNode = sql
|
|
86
|
-
.raw(this.#setTraceIdClause(audit.traceId))
|
|
77
|
+
const rawNode = sql`set_trace_id(${audit.traceId})`
|
|
87
78
|
.as(this.traceIdAlias)
|
|
88
79
|
.toOperationNode();
|
|
89
80
|
|
package/src/database.js
CHANGED
|
@@ -282,4 +282,77 @@ describe("ModelAPI error handling", () => {
|
|
|
282
282
|
},
|
|
283
283
|
});
|
|
284
284
|
});
|
|
285
|
+
test("when there is a uniqueness constraint error", async () => {
|
|
286
|
+
await sql`
|
|
287
|
+
INSERT INTO post (id, title, author_id) values(${
|
|
288
|
+
KSUID.randomSync().string
|
|
289
|
+
}, 'hello', 'adam')
|
|
290
|
+
`.execute(db);
|
|
291
|
+
|
|
292
|
+
const rpcReq = createJSONRPCRequest("123", "createPost", {
|
|
293
|
+
title: "hello",
|
|
294
|
+
author_id: "something",
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
expect(await handleRequest(rpcReq, functionConfig)).toEqual({
|
|
298
|
+
id: "123",
|
|
299
|
+
jsonrpc: "2.0",
|
|
300
|
+
error: {
|
|
301
|
+
code: RuntimeErrors.UniqueConstraintError,
|
|
302
|
+
message:
|
|
303
|
+
'duplicate key value violates unique constraint "post_title_key"',
|
|
304
|
+
data: {
|
|
305
|
+
code: "23505",
|
|
306
|
+
column: "title",
|
|
307
|
+
detail: "Key (title)=(hello) already exists.",
|
|
308
|
+
table: "post",
|
|
309
|
+
value: "hello",
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test("when there is a null value in a foreign key column", async () => {
|
|
316
|
+
const rpcReq = createJSONRPCRequest("123", "createPost", { title: "123" });
|
|
317
|
+
|
|
318
|
+
expect(await handleRequest(rpcReq, functionConfig)).toEqual({
|
|
319
|
+
id: "123",
|
|
320
|
+
jsonrpc: "2.0",
|
|
321
|
+
error: {
|
|
322
|
+
code: RuntimeErrors.NotNullConstraintError,
|
|
323
|
+
message:
|
|
324
|
+
'null value in column "author_id" violates not-null constraint',
|
|
325
|
+
data: {
|
|
326
|
+
code: "23502",
|
|
327
|
+
column: "author_id",
|
|
328
|
+
detail: expect.stringContaining("Failing row contains"),
|
|
329
|
+
table: "post",
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test("when there is a foreign key constraint violation", async () => {
|
|
336
|
+
const rpcReq2 = createJSONRPCRequest("123", "createPost", {
|
|
337
|
+
title: "123",
|
|
338
|
+
author_id: "fake",
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
expect(await handleRequest(rpcReq2, functionConfig)).toEqual({
|
|
342
|
+
id: "123",
|
|
343
|
+
jsonrpc: "2.0",
|
|
344
|
+
error: {
|
|
345
|
+
code: RuntimeErrors.ForeignKeyConstraintError,
|
|
346
|
+
message:
|
|
347
|
+
'insert or update on table "post" violates foreign key constraint "post_author_id_fkey"',
|
|
348
|
+
data: {
|
|
349
|
+
code: "23503",
|
|
350
|
+
column: "author_id",
|
|
351
|
+
detail: 'Key (author_id)=(fake) is not present in table "author".',
|
|
352
|
+
table: "post",
|
|
353
|
+
value: "fake",
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
});
|
|
285
358
|
});
|