prostgles-server 2.0.277 → 2.0.280
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/dist/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser.js +3 -2
- package/dist/PublishParser.js.map +1 -1
- package/dist/TableConfig.d.ts +28 -0
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +46 -4
- package/dist/TableConfig.js.map +1 -1
- package/dist/validation.d.ts +1 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +13 -8
- package/dist/validation.js.map +1 -1
- package/lib/PublishParser.d.ts.map +1 -1
- package/lib/PublishParser.js +3 -2
- package/lib/PublishParser.ts +425 -423
- package/lib/TableConfig.d.ts +28 -0
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.js +46 -4
- package/lib/TableConfig.ts +79 -4
- package/lib/validation.d.ts +1 -0
- package/lib/validation.d.ts.map +1 -1
- package/lib/validation.js +13 -8
- package/lib/validation.ts +12 -9
- package/package.json +1 -1
- package/tests/client/PID.txt +1 -1
- package/tests/server/package-lock.json +1 -1
package/lib/TableConfig.d.ts
CHANGED
|
@@ -22,6 +22,34 @@ declare type BaseTableDefinition<LANG_IDS = AnyObject> = {
|
|
|
22
22
|
};
|
|
23
23
|
dropIfExistsCascade?: boolean;
|
|
24
24
|
dropIfExists?: boolean;
|
|
25
|
+
triggers?: {
|
|
26
|
+
[triggerName: string]: {
|
|
27
|
+
type: "before" | "after" | "instead of";
|
|
28
|
+
actions: ("insert" | "update" | "delete")[];
|
|
29
|
+
forEach: "statement" | "row";
|
|
30
|
+
/**
|
|
31
|
+
* @example
|
|
32
|
+
* DECLARE
|
|
33
|
+
x_rec record;
|
|
34
|
+
BEGIN
|
|
35
|
+
raise notice '=operation: % =', TG_OP;
|
|
36
|
+
IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
|
|
37
|
+
FOR x_rec IN SELECT * FROM old_table LOOP
|
|
38
|
+
raise notice 'OLD: %', x_rec;
|
|
39
|
+
END loop;
|
|
40
|
+
END IF;
|
|
41
|
+
IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
|
|
42
|
+
FOR x_rec IN SELECT * FROM new_table LOOP
|
|
43
|
+
raise notice 'NEW: %', x_rec;
|
|
44
|
+
END loop;
|
|
45
|
+
END IF;
|
|
46
|
+
|
|
47
|
+
RETURN NULL;
|
|
48
|
+
END;
|
|
49
|
+
*/
|
|
50
|
+
query: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
25
53
|
};
|
|
26
54
|
declare type LookupTableDefinition<LANG_IDS> = {
|
|
27
55
|
isLookupTable: {
|
package/lib/TableConfig.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableConfig.d.ts","sourceRoot":"","sources":["TableConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,SAAS,EAAE,SAAS,EAAG,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAClH,OAAO,EAAiB,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,eAAe,EAAS,SAAS,EAAE,MAAM,aAAa,CAAC;AAEpE,OAAO,EAAwB,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAElF,aAAK,YAAY,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,oBAAY,WAAW,CAAC,QAAQ,IAAI;KACjC,OAAO,IAAI,MAAM,QAAQ,GAAG,MAAM;CACpC,CAAA;AAED,eAAO,MAAM,SAAS;;;;;kBAiBrB,CAAA;AAED,aAAK,mBAAmB,CAAC,QAAQ,GAAG,SAAS,IAAI;IAC/C,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;KACxC,CAAA;IACD,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TableConfig.d.ts","sourceRoot":"","sources":["TableConfig.ts"],"names":[],"mappings":"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"}
|
package/lib/TableConfig.js
CHANGED
|
@@ -125,9 +125,10 @@ class TableConfigurator {
|
|
|
125
125
|
if (!this.config || !this.prostgles.pgp)
|
|
126
126
|
throw "config or pgp missing";
|
|
127
127
|
/* Create lookup tables */
|
|
128
|
-
Object.keys(this.config).map(
|
|
129
|
-
const
|
|
130
|
-
const
|
|
128
|
+
Object.keys(this.config).map(async (tableNameRaw) => {
|
|
129
|
+
const tableName = (0, prostgles_types_1.asName)(tableNameRaw);
|
|
130
|
+
const tableConf = this.config[tableNameRaw];
|
|
131
|
+
const { dropIfExists = false, dropIfExistsCascade = false, triggers } = tableConf;
|
|
131
132
|
if (dropIfExistsCascade) {
|
|
132
133
|
queries.push(`DROP TABLE IF EXISTS ${tableName} CASCADE;`);
|
|
133
134
|
}
|
|
@@ -136,7 +137,7 @@ class TableConfigurator {
|
|
|
136
137
|
}
|
|
137
138
|
if ("isLookupTable" in tableConf && Object.keys(tableConf.isLookupTable?.values).length) {
|
|
138
139
|
const rows = Object.keys(tableConf.isLookupTable?.values).map(id => ({ id, ...(tableConf.isLookupTable?.values[id]) }));
|
|
139
|
-
if (dropIfExists || dropIfExistsCascade || !this.dbo?.[
|
|
140
|
+
if (dropIfExists || dropIfExistsCascade || !this.dbo?.[tableNameRaw]) {
|
|
140
141
|
const keys = Object.keys(rows[0]).filter(k => k !== "id");
|
|
141
142
|
queries.push(`CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
142
143
|
id TEXT PRIMARY KEY
|
|
@@ -149,6 +150,47 @@ class TableConfigurator {
|
|
|
149
150
|
// console.log("Created lookup table " + tableName)
|
|
150
151
|
}
|
|
151
152
|
}
|
|
153
|
+
if (triggers) {
|
|
154
|
+
const existingTriggers = await this.dbo.sql(`
|
|
155
|
+
SELECT event_object_table
|
|
156
|
+
,trigger_name
|
|
157
|
+
FROM information_schema.triggers
|
|
158
|
+
WHERE event_object_table = ` + "${tableName}" + `
|
|
159
|
+
ORDER BY event_object_table
|
|
160
|
+
`, { tableName: tableNameRaw }, { returnType: "rows" });
|
|
161
|
+
(0, prostgles_types_1.getKeys)(triggers).map(triggerName => {
|
|
162
|
+
const trigger = triggers[triggerName];
|
|
163
|
+
if (dropIfExists || dropIfExistsCascade) {
|
|
164
|
+
queries.push(`DROP TRIGGER IF EXISTS ${(0, prostgles_types_1.asName)(triggerName)} ON ${tableName};`);
|
|
165
|
+
}
|
|
166
|
+
if (!existingTriggers.some(t => t.trigger_name === triggerName)) {
|
|
167
|
+
const funcNameParsed = (0, prostgles_types_1.asName)(triggerName + "_func");
|
|
168
|
+
queries.push(`
|
|
169
|
+
CREATE OR REPLACE FUNCTION ${funcNameParsed}()
|
|
170
|
+
RETURNS trigger
|
|
171
|
+
LANGUAGE plpgsql
|
|
172
|
+
AS
|
|
173
|
+
$$
|
|
174
|
+
${trigger.query}
|
|
175
|
+
$$;
|
|
176
|
+
`);
|
|
177
|
+
trigger.actions.forEach(action => {
|
|
178
|
+
const triggerActionName = triggerName + "_" + action;
|
|
179
|
+
const triggerActionNameParsed = (0, prostgles_types_1.asName)(triggerActionName);
|
|
180
|
+
if (dropIfExists || dropIfExistsCascade) {
|
|
181
|
+
queries.push(`DROP TRIGGER IF EXISTS ${triggerActionNameParsed} ON ${tableName};`);
|
|
182
|
+
}
|
|
183
|
+
queries.push(`
|
|
184
|
+
CREATE TRIGGER ${triggerActionNameParsed}
|
|
185
|
+
AFTER INSERT ON ${tableName}
|
|
186
|
+
REFERENCING NEW TABLE AS new_table
|
|
187
|
+
FOR EACH STATEMENT
|
|
188
|
+
EXECUTE PROCEDURE ${funcNameParsed}();
|
|
189
|
+
`);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
152
194
|
});
|
|
153
195
|
if (queries.length) {
|
|
154
196
|
const q = queries.join("\n");
|
package/lib/TableConfig.ts
CHANGED
|
@@ -39,6 +39,34 @@ type BaseTableDefinition<LANG_IDS = AnyObject> = {
|
|
|
39
39
|
}
|
|
40
40
|
dropIfExistsCascade?: boolean;
|
|
41
41
|
dropIfExists?: boolean;
|
|
42
|
+
triggers?: {
|
|
43
|
+
[triggerName: string]: {
|
|
44
|
+
type: "before" | "after" | "instead of";
|
|
45
|
+
actions: ("insert" | "update" | "delete")[];
|
|
46
|
+
forEach: "statement" | "row";
|
|
47
|
+
/**
|
|
48
|
+
* @example
|
|
49
|
+
* DECLARE
|
|
50
|
+
x_rec record;
|
|
51
|
+
BEGIN
|
|
52
|
+
raise notice '=operation: % =', TG_OP;
|
|
53
|
+
IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
|
|
54
|
+
FOR x_rec IN SELECT * FROM old_table LOOP
|
|
55
|
+
raise notice 'OLD: %', x_rec;
|
|
56
|
+
END loop;
|
|
57
|
+
END IF;
|
|
58
|
+
IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
|
|
59
|
+
FOR x_rec IN SELECT * FROM new_table LOOP
|
|
60
|
+
raise notice 'NEW: %', x_rec;
|
|
61
|
+
END loop;
|
|
62
|
+
END IF;
|
|
63
|
+
|
|
64
|
+
RETURN NULL;
|
|
65
|
+
END;
|
|
66
|
+
*/
|
|
67
|
+
query: string;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
42
70
|
}
|
|
43
71
|
|
|
44
72
|
type LookupTableDefinition<LANG_IDS> = {
|
|
@@ -337,9 +365,10 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
337
365
|
|
|
338
366
|
if (!this.config || !this.prostgles.pgp) throw "config or pgp missing"
|
|
339
367
|
/* Create lookup tables */
|
|
340
|
-
Object.keys(this.config).map(
|
|
341
|
-
const
|
|
342
|
-
const
|
|
368
|
+
Object.keys(this.config).map(async tableNameRaw => {
|
|
369
|
+
const tableName = asName(tableNameRaw);
|
|
370
|
+
const tableConf = this.config![tableNameRaw];
|
|
371
|
+
const { dropIfExists = false, dropIfExistsCascade = false, triggers } = tableConf;
|
|
343
372
|
if (dropIfExistsCascade) {
|
|
344
373
|
queries.push(`DROP TABLE IF EXISTS ${tableName} CASCADE;`);
|
|
345
374
|
} else if (dropIfExists) {
|
|
@@ -347,7 +376,7 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
347
376
|
}
|
|
348
377
|
if ("isLookupTable" in tableConf && Object.keys(tableConf.isLookupTable?.values).length) {
|
|
349
378
|
const rows = Object.keys(tableConf.isLookupTable?.values).map(id => ({ id, ...(tableConf.isLookupTable?.values[id]) }));
|
|
350
|
-
if (dropIfExists || dropIfExistsCascade || !this.dbo?.[
|
|
379
|
+
if (dropIfExists || dropIfExistsCascade || !this.dbo?.[tableNameRaw]) {
|
|
351
380
|
const keys = Object.keys(rows[0]).filter(k => k !== "id");
|
|
352
381
|
queries.push(`CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
353
382
|
id TEXT PRIMARY KEY
|
|
@@ -361,6 +390,52 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
361
390
|
// console.log("Created lookup table " + tableName)
|
|
362
391
|
}
|
|
363
392
|
}
|
|
393
|
+
|
|
394
|
+
if(triggers){
|
|
395
|
+
|
|
396
|
+
const existingTriggers: { trigger_name: string }[] = await this.dbo.sql!(`
|
|
397
|
+
SELECT event_object_table
|
|
398
|
+
,trigger_name
|
|
399
|
+
FROM information_schema.triggers
|
|
400
|
+
WHERE event_object_table = `+ "${tableName}" + `
|
|
401
|
+
ORDER BY event_object_table
|
|
402
|
+
`,
|
|
403
|
+
{ tableName: tableNameRaw },
|
|
404
|
+
{ returnType: "rows" }) as any;
|
|
405
|
+
|
|
406
|
+
getKeys(triggers).map(triggerName => {
|
|
407
|
+
const trigger = triggers[triggerName];
|
|
408
|
+
if(dropIfExists || dropIfExistsCascade){
|
|
409
|
+
queries.push(`DROP TRIGGER IF EXISTS ${asName(triggerName)} ON ${tableName};`)
|
|
410
|
+
}
|
|
411
|
+
if(!existingTriggers.some(t => t.trigger_name === triggerName)){
|
|
412
|
+
const funcNameParsed = asName(triggerName+"_func")
|
|
413
|
+
queries.push(`
|
|
414
|
+
CREATE OR REPLACE FUNCTION ${funcNameParsed}()
|
|
415
|
+
RETURNS trigger
|
|
416
|
+
LANGUAGE plpgsql
|
|
417
|
+
AS
|
|
418
|
+
$$
|
|
419
|
+
${trigger.query}
|
|
420
|
+
$$;
|
|
421
|
+
`);
|
|
422
|
+
trigger.actions.forEach(action => {
|
|
423
|
+
const triggerActionName = triggerName+"_"+action;
|
|
424
|
+
const triggerActionNameParsed = asName(triggerActionName)
|
|
425
|
+
if(dropIfExists || dropIfExistsCascade){
|
|
426
|
+
queries.push(`DROP TRIGGER IF EXISTS ${triggerActionNameParsed} ON ${tableName};`)
|
|
427
|
+
}
|
|
428
|
+
queries.push(`
|
|
429
|
+
CREATE TRIGGER ${triggerActionNameParsed}
|
|
430
|
+
AFTER INSERT ON ${tableName}
|
|
431
|
+
REFERENCING NEW TABLE AS new_table
|
|
432
|
+
FOR EACH STATEMENT
|
|
433
|
+
EXECUTE PROCEDURE ${funcNameParsed}();
|
|
434
|
+
`)
|
|
435
|
+
})
|
|
436
|
+
}
|
|
437
|
+
})
|
|
438
|
+
}
|
|
364
439
|
});
|
|
365
440
|
|
|
366
441
|
if (queries.length) {
|
package/lib/validation.d.ts
CHANGED
package/lib/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"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"}
|
package/lib/validation.js
CHANGED
|
@@ -53,7 +53,7 @@ function validateSchema(schema, obj, objName, optional = false) {
|
|
|
53
53
|
}
|
|
54
54
|
exports.validateSchema = validateSchema;
|
|
55
55
|
function getPGCheckConstraint(args, depth) {
|
|
56
|
-
const { schema: s, escapedFieldName, nullable } = args;
|
|
56
|
+
const { schema: s, escapedFieldName, nullable, optional, isRootQuery } = args;
|
|
57
57
|
const jsToPGtypes = {
|
|
58
58
|
"integer": "::INTEGER",
|
|
59
59
|
"number": "::NUMERIC",
|
|
@@ -67,9 +67,10 @@ function getPGCheckConstraint(args, depth) {
|
|
|
67
67
|
const valAsText = `${escapedFieldName}->>${(0, PubSubManager_1.asValue)(k)}`;
|
|
68
68
|
if (t.nullable)
|
|
69
69
|
checks.push(`${valAsJson} IS NULL`);
|
|
70
|
-
|
|
70
|
+
if (t.optional)
|
|
71
|
+
checks.push(`${escapedFieldName} ? ${(0, PubSubManager_1.asValue)(k)} = FALSE`);
|
|
71
72
|
if ("oneOfTypes" in t) {
|
|
72
|
-
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable }, depth + 1)).join(" OR ")})`);
|
|
73
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable, optional: t.optional }, depth + 1)).join(" OR ")})`);
|
|
73
74
|
}
|
|
74
75
|
else if ("oneOf" in t) {
|
|
75
76
|
if (!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
@@ -95,7 +96,7 @@ function getPGCheckConstraint(args, depth) {
|
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
else {
|
|
98
|
-
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable }, depth + 1).trim();
|
|
99
|
+
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable, optional: !!t.optional }, depth + 1).trim();
|
|
99
100
|
if (check)
|
|
100
101
|
checks.push(`(${check})`);
|
|
101
102
|
}
|
|
@@ -106,14 +107,18 @@ function getPGCheckConstraint(args, depth) {
|
|
|
106
107
|
return result;
|
|
107
108
|
};
|
|
108
109
|
const getSchemaChecks = (s) => (0, prostgles_types_1.getKeys)(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ");
|
|
109
|
-
|
|
110
|
+
const checks = [];
|
|
111
|
+
let typeChecks = "";
|
|
110
112
|
if (isOneOfTypes(s)) {
|
|
111
|
-
|
|
113
|
+
typeChecks = s.oneOfTypes.map(t => `(${getSchemaChecks(t)})`).join(" OR ");
|
|
112
114
|
}
|
|
113
115
|
else {
|
|
114
|
-
|
|
116
|
+
typeChecks = getSchemaChecks(s);
|
|
115
117
|
}
|
|
116
|
-
|
|
118
|
+
if (nullable)
|
|
119
|
+
checks.push(` ${escapedFieldName} IS NULL `);
|
|
120
|
+
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks ? ` AND (${typeChecks})` : ""}`);
|
|
121
|
+
return checks.join(" OR ");
|
|
117
122
|
}
|
|
118
123
|
exports.getPGCheckConstraint = getPGCheckConstraint;
|
|
119
124
|
const isOneOfTypes = (s) => {
|
package/lib/validation.ts
CHANGED
|
@@ -87,8 +87,8 @@ export function validateSchema<S extends ValidationSchema>(schema: S, obj: Schem
|
|
|
87
87
|
getKeys(schema).forEach(k => validate(obj as any, k, schema[k]));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema | OneOfTypes, nullable: boolean; isRootQuery?: boolean; }, depth: number): string {
|
|
91
|
-
const { schema: s, escapedFieldName, nullable } = args;
|
|
90
|
+
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema | OneOfTypes, nullable: boolean; isRootQuery?: boolean; optional?: boolean; }, depth: number): string {
|
|
91
|
+
const { schema: s, escapedFieldName, nullable, optional, isRootQuery } = args;
|
|
92
92
|
|
|
93
93
|
const jsToPGtypes = {
|
|
94
94
|
"integer": "::INTEGER",
|
|
@@ -103,10 +103,10 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
103
103
|
const valAsJson = `${escapedFieldName}->${asValue(k)}`;
|
|
104
104
|
const valAsText = `${escapedFieldName}->>${asValue(k)}`;
|
|
105
105
|
if(t.nullable) checks.push(`${valAsJson} IS NULL`);
|
|
106
|
-
|
|
106
|
+
if(t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
107
107
|
|
|
108
108
|
if("oneOfTypes" in t){
|
|
109
|
-
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable }, depth + 1)).join(" OR ")})`)
|
|
109
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable, optional: t.optional }, depth + 1)).join(" OR ")})`)
|
|
110
110
|
} else if("oneOf" in t){
|
|
111
111
|
if(!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
112
112
|
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: oneOf cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
@@ -127,7 +127,7 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
127
127
|
checks.push(`jsonb_typeof(${valAsJson}) = ${asValue(correctType)} `)
|
|
128
128
|
}
|
|
129
129
|
} else {
|
|
130
|
-
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable }, depth + 1).trim();
|
|
130
|
+
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable, optional: !!t.optional }, depth + 1).trim();
|
|
131
131
|
if(check) checks.push(`(${check})`)
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -138,13 +138,16 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
138
138
|
|
|
139
139
|
const getSchemaChecks = (s: ValidationSchema) => getKeys(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ")
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
const checks: string[] = [];
|
|
142
|
+
let typeChecks = "";
|
|
142
143
|
if(isOneOfTypes(s)){
|
|
143
|
-
|
|
144
|
+
typeChecks = s.oneOfTypes.map(t => `(${getSchemaChecks(t)})` ).join(" OR ");
|
|
144
145
|
} else {
|
|
145
|
-
|
|
146
|
+
typeChecks = getSchemaChecks(s);
|
|
146
147
|
}
|
|
147
|
-
|
|
148
|
+
if(nullable) checks.push(` ${escapedFieldName} IS NULL `);
|
|
149
|
+
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks? ` AND (${typeChecks})` : "" }`);
|
|
150
|
+
return checks.join(" OR ");
|
|
148
151
|
}
|
|
149
152
|
type ColOpts = { nullable?: boolean };
|
|
150
153
|
const isOneOfTypes = (s: ValidationSchema | OneOfTypes): s is OneOfTypes => {
|
package/package.json
CHANGED
package/tests/client/PID.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
32617
|