prostgles-server 3.0.87 → 3.0.89
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/.eslintignore +5 -0
- package/.eslintrc.json +30 -0
- package/dist/DBEventsManager.js +1 -1
- package/dist/DBEventsManager.js.map +1 -1
- package/dist/DBSchemaBuilder.d.ts.map +1 -1
- package/dist/DBSchemaBuilder.js +6 -6
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions.js +9 -9
- package/dist/DboBuilder/QueryBuilder/Functions.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +8 -7
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/makeSelectQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/makeSelectQuery.js +4 -4
- package/dist/DboBuilder/QueryBuilder/makeSelectQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler.js +18 -20
- package/dist/DboBuilder/TableHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler.d.ts +0 -10
- package/dist/DboBuilder/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler.js +50 -63
- package/dist/DboBuilder/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/delete.js +0 -1
- package/dist/DboBuilder/delete.js.map +1 -1
- package/dist/DboBuilder/getColumns.js +5 -4
- package/dist/DboBuilder/getColumns.js.map +1 -1
- package/dist/DboBuilder/getCondition.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.js +6 -6
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/insert.js +15 -16
- package/dist/DboBuilder/insert.js.map +1 -1
- package/dist/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/dist/DboBuilder/insertDataParse.js +9 -10
- package/dist/DboBuilder/insertDataParse.js.map +1 -1
- package/dist/DboBuilder/parseUpdateRules.js +2 -2
- package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
- package/dist/DboBuilder/runSQL.d.ts.map +1 -1
- package/dist/DboBuilder/runSQL.js +5 -5
- package/dist/DboBuilder/runSQL.js.map +1 -1
- package/dist/DboBuilder/subscribe.js +3 -3
- package/dist/DboBuilder/subscribe.js.map +1 -1
- package/dist/DboBuilder/update.js +5 -6
- package/dist/DboBuilder/update.js.map +1 -1
- package/dist/DboBuilder/uploadFile.d.ts.map +1 -1
- package/dist/DboBuilder/uploadFile.js +1 -1
- package/dist/DboBuilder/uploadFile.js.map +1 -1
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +13 -14
- package/dist/DboBuilder.js.map +1 -1
- package/dist/FileManager.d.ts.map +1 -1
- package/dist/FileManager.js +3 -5
- package/dist/FileManager.js.map +1 -1
- package/dist/Filtering.js +7 -7
- package/dist/Filtering.js.map +1 -1
- package/dist/JSONBValidation/validate_jsonb_schema_sql.d.ts +3 -0
- package/dist/JSONBValidation/validate_jsonb_schema_sql.d.ts.map +1 -0
- package/dist/JSONBValidation/validate_jsonb_schema_sql.js +295 -0
- package/dist/JSONBValidation/validate_jsonb_schema_sql.js.map +1 -0
- package/dist/JSONBValidation/validation.d.ts +108 -0
- package/dist/JSONBValidation/validation.d.ts.map +1 -0
- package/dist/JSONBValidation/validation.js +222 -0
- package/dist/JSONBValidation/validation.js.map +1 -0
- package/dist/PostgresNotifListenManager.js +1 -1
- package/dist/PostgresNotifListenManager.js.map +1 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +20 -20
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/initPubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/initPubSubManager.js +10 -7
- package/dist/PubSubManager/initPubSubManager.js.map +1 -1
- package/dist/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser.js +122 -125
- package/dist/PublishParser.js.map +1 -1
- package/dist/SyncReplication.d.ts.map +1 -1
- package/dist/SyncReplication.js +19 -16
- package/dist/SyncReplication.js.map +1 -1
- package/dist/TableConfig.d.ts +9 -5
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +33 -12
- package/dist/TableConfig.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/shortestPath.js +11 -11
- package/dist/shortestPath.js.map +1 -1
- package/dist/validation.d.ts +50 -24
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +177 -53
- package/dist/validation.js.map +1 -1
- package/lib/AuthHandler.d.ts +11 -11
- package/lib/AuthHandler.d.ts.map +1 -1
- package/lib/DBEventsManager.js +1 -1
- package/lib/DBEventsManager.ts +1 -1
- package/lib/DBSchemaBuilder.d.ts +3 -3
- package/lib/DBSchemaBuilder.d.ts.map +1 -1
- package/lib/DBSchemaBuilder.js +6 -6
- package/lib/DBSchemaBuilder.ts +10 -12
- package/lib/DboBuilder/QueryBuilder/Functions.d.ts +3 -3
- package/lib/DboBuilder/QueryBuilder/Functions.d.ts.map +1 -1
- package/lib/DboBuilder/QueryBuilder/Functions.js +9 -9
- package/lib/DboBuilder/QueryBuilder/Functions.ts +13 -13
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.d.ts +3 -3
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.js +8 -7
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +12 -12
- package/lib/DboBuilder/QueryBuilder/makeSelectQuery.d.ts.map +1 -1
- package/lib/DboBuilder/QueryBuilder/makeSelectQuery.js +4 -4
- package/lib/DboBuilder/QueryBuilder/makeSelectQuery.ts +5 -5
- package/lib/DboBuilder/TableHandler.d.ts +1 -1
- package/lib/DboBuilder/TableHandler.d.ts.map +1 -1
- package/lib/DboBuilder/TableHandler.js +18 -20
- package/lib/DboBuilder/TableHandler.ts +21 -20
- package/lib/DboBuilder/ViewHandler.d.ts +1 -11
- package/lib/DboBuilder/ViewHandler.d.ts.map +1 -1
- package/lib/DboBuilder/ViewHandler.js +50 -63
- package/lib/DboBuilder/ViewHandler.ts +68 -97
- package/lib/DboBuilder/delete.js +0 -1
- package/lib/DboBuilder/delete.ts +1 -1
- package/lib/DboBuilder/getColumns.js +5 -4
- package/lib/DboBuilder/getColumns.ts +5 -5
- package/lib/DboBuilder/getCondition.d.ts.map +1 -1
- package/lib/DboBuilder/getCondition.js +6 -6
- package/lib/DboBuilder/getCondition.ts +7 -7
- package/lib/DboBuilder/insert.js +15 -16
- package/lib/DboBuilder/insert.ts +18 -18
- package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/lib/DboBuilder/insertDataParse.js +9 -10
- package/lib/DboBuilder/insertDataParse.ts +42 -43
- package/lib/DboBuilder/parseUpdateRules.js +2 -2
- package/lib/DboBuilder/parseUpdateRules.ts +2 -2
- package/lib/DboBuilder/runSQL.d.ts.map +1 -1
- package/lib/DboBuilder/runSQL.js +5 -5
- package/lib/DboBuilder/runSQL.ts +6 -6
- package/lib/DboBuilder/subscribe.d.ts +1 -1
- package/lib/DboBuilder/subscribe.d.ts.map +1 -1
- package/lib/DboBuilder/subscribe.js +3 -3
- package/lib/DboBuilder/subscribe.ts +3 -3
- package/lib/DboBuilder/update.js +5 -6
- package/lib/DboBuilder/update.ts +6 -6
- package/lib/DboBuilder/uploadFile.d.ts.map +1 -1
- package/lib/DboBuilder/uploadFile.js +1 -1
- package/lib/DboBuilder/uploadFile.ts +2 -2
- package/lib/DboBuilder.d.ts +22 -22
- package/lib/DboBuilder.d.ts.map +1 -1
- package/lib/DboBuilder.js +13 -14
- package/lib/DboBuilder.ts +19 -19
- package/lib/FileManager.d.ts +6 -6
- package/lib/FileManager.d.ts.map +1 -1
- package/lib/FileManager.js +3 -5
- package/lib/FileManager.ts +7 -6
- package/lib/Filtering.d.ts +1 -1
- package/lib/Filtering.d.ts.map +1 -1
- package/lib/Filtering.js +7 -7
- package/lib/Filtering.ts +7 -7
- package/lib/JSONBValidation/validate_jsonb_schema_sql.d.ts +3 -0
- package/lib/JSONBValidation/validate_jsonb_schema_sql.d.ts.map +1 -0
- package/lib/JSONBValidation/validate_jsonb_schema_sql.js +294 -0
- package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +293 -0
- package/lib/JSONBValidation/validation.d.ts +108 -0
- package/lib/JSONBValidation/validation.d.ts.map +1 -0
- package/lib/JSONBValidation/validation.js +221 -0
- package/lib/JSONBValidation/validation.ts +332 -0
- package/lib/PostgresNotifListenManager.d.ts +1 -1
- package/lib/PostgresNotifListenManager.d.ts.map +1 -1
- package/lib/PostgresNotifListenManager.js +1 -1
- package/lib/PostgresNotifListenManager.ts +1 -1
- package/lib/Prostgles.d.ts +14 -14
- package/lib/Prostgles.d.ts.map +1 -1
- package/lib/Prostgles.js +20 -20
- package/lib/Prostgles.ts +22 -21
- package/lib/PubSubManager/PubSubManager.d.ts +7 -7
- package/lib/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/lib/PubSubManager/initPubSubManager.d.ts.map +1 -1
- package/lib/PubSubManager/initPubSubManager.js +10 -7
- package/lib/PubSubManager/initPubSubManager.ts +12 -7
- package/lib/PublishParser.d.ts +32 -32
- package/lib/PublishParser.d.ts.map +1 -1
- package/lib/PublishParser.js +121 -124
- package/lib/PublishParser.ts +125 -127
- package/lib/SchemaWatch.d.ts +1 -1
- package/lib/SchemaWatch.d.ts.map +1 -1
- package/lib/SyncReplication.d.ts +5 -5
- package/lib/SyncReplication.d.ts.map +1 -1
- package/lib/SyncReplication.js +19 -16
- package/lib/SyncReplication.ts +470 -471
- package/lib/TableConfig.d.ts +28 -24
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.js +33 -12
- package/lib/TableConfig.ts +55 -21
- package/lib/index.js +1 -1
- package/lib/index.ts +1 -1
- package/lib/shortestPath.d.ts +1 -1
- package/lib/shortestPath.d.ts.map +1 -1
- package/lib/shortestPath.js +11 -11
- package/lib/shortestPath.ts +11 -11
- package/package.json +10 -6
- package/tests/client/PID.txt +1 -1
- package/tests/client/package-lock.json +53 -31
- package/tests/client/package.json +4 -1
- package/tests/isomorphic_queries.d.ts +4 -1
- package/tests/isomorphic_queries.d.ts.map +1 -1
- package/tests/isomorphic_queries.js +38 -30
- package/tests/isomorphic_queries.ts +40 -33
- package/tests/server/DBoGenerated.d.ts +1 -1
- package/tests/server/index.js +8 -7
- package/tests/server/index.ts +10 -8
- package/tests/server/package-lock.json +76 -58
- package/tests/server/package.json +2 -2
- package/tests/server/server.ts +2 -3
- package/lib/validation.d.ts +0 -100
- package/lib/validation.d.ts.map +0 -1
- package/lib/validation.js +0 -280
- package/lib/validation.ts +0 -360
package/lib/validation.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getJSONBSchemaAsJSONSchema = exports.getJSONBSchemaTSTypes = exports.getSchemaTSTypes = exports.getPGCheckConstraint = exports.validateSchema = exports.validate = void 0;
|
|
4
|
-
const prostgles_types_1 = require("prostgles-types");
|
|
5
|
-
const PubSubManager_1 = require("./PubSubManager/PubSubManager");
|
|
6
|
-
/** tests */
|
|
7
|
-
const s = {
|
|
8
|
-
a: { type: "boolean" },
|
|
9
|
-
c: { type: { c1: { type: "string" } } },
|
|
10
|
-
o: {
|
|
11
|
-
oneOf: [
|
|
12
|
-
{ z: { type: "integer" } },
|
|
13
|
-
{ z1: { type: "integer" } }
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
const ss = {
|
|
18
|
-
a: true,
|
|
19
|
-
c: {
|
|
20
|
-
c1: ""
|
|
21
|
-
},
|
|
22
|
-
o: { z: 1, z1: 23 }
|
|
23
|
-
};
|
|
24
|
-
function validate(obj, key, validation) {
|
|
25
|
-
let err = `The provided value for ${JSON.stringify(key)} is of invalid type. Expecting `;
|
|
26
|
-
const val = obj[key];
|
|
27
|
-
if ("type" in validation && validation.type) {
|
|
28
|
-
if (typeof validation.type !== "string") {
|
|
29
|
-
(0, prostgles_types_1.getKeys)(validation.type).forEach(subKey => {
|
|
30
|
-
validate(val, subKey, validation.type[subKey]);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
err += validation.type;
|
|
34
|
-
if (validation.type === "boolean" && typeof val !== validation.type)
|
|
35
|
-
throw new Error(err);
|
|
36
|
-
if (validation.type === "string" && typeof val !== validation.type)
|
|
37
|
-
throw new Error(err);
|
|
38
|
-
if (validation.type === "number" && !Number.isFinite(val))
|
|
39
|
-
throw new Error(err);
|
|
40
|
-
if (validation.type === "integer" && !Number.isInteger(val))
|
|
41
|
-
throw new Error(err);
|
|
42
|
-
}
|
|
43
|
-
else if ("enum" in validation && validation.enum) {
|
|
44
|
-
err += `on of: ${validation.enum}`;
|
|
45
|
-
if (!validation.enum.includes(val))
|
|
46
|
-
throw new Error(err);
|
|
47
|
-
}
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
exports.validate = validate;
|
|
51
|
-
function validateSchema(schema, obj, objName, optional = false) {
|
|
52
|
-
if ((!schema || (0, prostgles_types_1.isEmpty)(schema)) && !optional)
|
|
53
|
-
throw new Error(`Expecting ${objName} to be defined`);
|
|
54
|
-
(0, prostgles_types_1.getKeys)(schema).forEach(k => validate(obj, k, schema[k]));
|
|
55
|
-
}
|
|
56
|
-
exports.validateSchema = validateSchema;
|
|
57
|
-
function getPGCheckConstraint(args, depth) {
|
|
58
|
-
const { schema: s, escapedFieldName, nullable, optional, isRootQuery } = args;
|
|
59
|
-
const jsToPGtypes = {
|
|
60
|
-
"integer": "::INTEGER",
|
|
61
|
-
"number": "::NUMERIC",
|
|
62
|
-
"boolean": "::BOOLEAN",
|
|
63
|
-
"string": "::TEXT",
|
|
64
|
-
"any": "::JSONB"
|
|
65
|
-
};
|
|
66
|
-
const kChecks = (k, s) => {
|
|
67
|
-
const t = s[k];
|
|
68
|
-
const checks = [];
|
|
69
|
-
const valAsJson = `${escapedFieldName}->${(0, PubSubManager_1.asValue)(k)}`;
|
|
70
|
-
const valAsText = `${escapedFieldName}->>${(0, PubSubManager_1.asValue)(k)}`;
|
|
71
|
-
if (t.nullable)
|
|
72
|
-
checks.push(`${valAsJson} IS NULL`);
|
|
73
|
-
if (t.optional)
|
|
74
|
-
checks.push(`${escapedFieldName} ? ${(0, PubSubManager_1.asValue)(k)} = FALSE`);
|
|
75
|
-
if ("oneOf" in t) {
|
|
76
|
-
checks.push(`(${t.oneOf.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable, optional: t.optional }, depth + 1)).join(" OR ")})`);
|
|
77
|
-
}
|
|
78
|
-
else if ("enum" in t) {
|
|
79
|
-
if (!t.enum.length || t.enum.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
80
|
-
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: enum cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
81
|
-
}
|
|
82
|
-
checks.push(`array_position(${(0, PubSubManager_1.asValue)(t.enum)}::text[], ${valAsText}::text) IS NOT NULL`);
|
|
83
|
-
}
|
|
84
|
-
else if ("type" in t) {
|
|
85
|
-
if (typeof t.type === "string") {
|
|
86
|
-
if (t.type.endsWith("[]")) {
|
|
87
|
-
const correctType = t.type.slice(0, -2);
|
|
88
|
-
let elemCheck = correctType === "any" ? "" : `AND ('{' || right(left(${valAsText},-1),-1) || '}')${jsToPGtypes[correctType]}[] IS NOT NULL`;
|
|
89
|
-
checks.push(`jsonb_typeof(${valAsJson}) = 'array' ${elemCheck}`);
|
|
90
|
-
if (t.allowedValues) {
|
|
91
|
-
const types = Array.from(new Set(t.allowedValues.map(v => typeof v)));
|
|
92
|
-
const allowedTypes = ["boolean", "number", "string"];
|
|
93
|
-
if (types.length !== 1 || !allowedTypes.includes(types[0])) {
|
|
94
|
-
throw new Error(`Invalid allowedValues (${t.allowedValues}). Must be a non empty array with elements of same type. Allowed types: ${allowedTypes}`);
|
|
95
|
-
}
|
|
96
|
-
const type = types[0];
|
|
97
|
-
checks.push(`(${valAsText})${jsToPGtypes[type]}[] <@ ${(0, PubSubManager_1.asValue)(t.allowedValues)}`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
const correctType = t.type.replace("integer", "number");
|
|
102
|
-
if (correctType !== "any") {
|
|
103
|
-
checks.push(`jsonb_typeof(${valAsJson}) = ${(0, PubSubManager_1.asValue)(correctType)} `);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable, optional: !!t.optional }, depth + 1).trim();
|
|
109
|
-
if (check)
|
|
110
|
-
checks.push(`(${check})`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
const result = checks.join(" OR ");
|
|
114
|
-
if (!depth)
|
|
115
|
-
return `COALESCE(${result}, false)`;
|
|
116
|
-
return result;
|
|
117
|
-
};
|
|
118
|
-
const getSchemaChecks = (s) => (0, prostgles_types_1.getKeys)(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ");
|
|
119
|
-
const checks = [];
|
|
120
|
-
let typeChecks = "";
|
|
121
|
-
if (isOneOfTypes(s)) {
|
|
122
|
-
typeChecks = s.oneOf.map(t => `(${getSchemaChecks(t)})`).join(" OR ");
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
typeChecks = getSchemaChecks(s);
|
|
126
|
-
}
|
|
127
|
-
if (nullable)
|
|
128
|
-
checks.push(` ${escapedFieldName} IS NULL `);
|
|
129
|
-
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks ? ` AND (${typeChecks})` : ""}`);
|
|
130
|
-
return checks.join(" OR ");
|
|
131
|
-
}
|
|
132
|
-
exports.getPGCheckConstraint = getPGCheckConstraint;
|
|
133
|
-
const isOneOfTypes = (s) => {
|
|
134
|
-
if ("oneOf" in s) {
|
|
135
|
-
if (!Array.isArray(s.oneOf)) {
|
|
136
|
-
throw "Expecting oneOf to be an array of types";
|
|
137
|
-
}
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
return false;
|
|
141
|
-
};
|
|
142
|
-
function getSchemaTSTypes(schema, leading = "", isOneOf = false) {
|
|
143
|
-
const getFieldType = (def) => {
|
|
144
|
-
const nullType = (def.nullable ? `null | ` : "");
|
|
145
|
-
if ("type" in def) {
|
|
146
|
-
if (typeof def.type === "string") {
|
|
147
|
-
const correctType = def.type.replace("integer", "number");
|
|
148
|
-
if (def.allowedValues && def.type.endsWith("[]")) {
|
|
149
|
-
return nullType + ` (${def.allowedValues.map(v => JSON.stringify(v)).join(" | ")})[]`;
|
|
150
|
-
}
|
|
151
|
-
return nullType + correctType;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
return nullType + getSchemaTSTypes(def.type, "", true);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else if ("enum" in def) {
|
|
158
|
-
return nullType + def.enum.map(v => (0, PubSubManager_1.asValue)(v)).join(" | ");
|
|
159
|
-
}
|
|
160
|
-
else if ("oneOf" in def) {
|
|
161
|
-
return (def.nullable ? `\n${leading} | null` : "") + def.oneOf.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("");
|
|
162
|
-
}
|
|
163
|
-
else
|
|
164
|
-
throw "Unexpected getSchemaTSTypes";
|
|
165
|
-
};
|
|
166
|
-
let spacing = isOneOf ? " " : " ";
|
|
167
|
-
let res = `${leading}{ \n` + (0, prostgles_types_1.getKeys)(schema).map(k => {
|
|
168
|
-
const def = schema[k];
|
|
169
|
-
return `${leading}${spacing}${k}${def.optional ? "?" : ""}: ` + getFieldType(def) + ";";
|
|
170
|
-
}).join("\n") + ` \n${leading}}${isOneOf ? "" : ";"}`;
|
|
171
|
-
/** Keep single line */
|
|
172
|
-
if (isOneOf)
|
|
173
|
-
res = res.split("\n").join("");
|
|
174
|
-
return res;
|
|
175
|
-
}
|
|
176
|
-
exports.getSchemaTSTypes = getSchemaTSTypes;
|
|
177
|
-
function getJSONBSchemaTSTypes(schema, colOpts, leading = "", isOneOf = false) {
|
|
178
|
-
if (isOneOfTypes(schema)) {
|
|
179
|
-
return (colOpts.nullable ? `\n${leading} | null` : "") + schema.oneOf.map(s => `\n${leading} | ` + getSchemaTSTypes(s, "", true)).join("");
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
return (colOpts.nullable ? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
exports.getJSONBSchemaTSTypes = getJSONBSchemaTSTypes;
|
|
186
|
-
const getJSONSchemaObject = (objDef) => {
|
|
187
|
-
const resultType = {
|
|
188
|
-
type: "object",
|
|
189
|
-
properties: (0, prostgles_types_1.getKeys)(objDef).reduce((a, k) => {
|
|
190
|
-
const itemSchema = objDef[k];
|
|
191
|
-
const { nullable, optional, description, title } = itemSchema;
|
|
192
|
-
let item = {};
|
|
193
|
-
if ("type" in itemSchema) {
|
|
194
|
-
const { type } = itemSchema;
|
|
195
|
-
/**
|
|
196
|
-
* Is primitive or any
|
|
197
|
-
*/
|
|
198
|
-
if (typeof type === "string") {
|
|
199
|
-
const arrayType = type.endsWith("[]") ? type.slice(0, -2) : undefined;
|
|
200
|
-
if (arrayType) {
|
|
201
|
-
item = {
|
|
202
|
-
type: "array",
|
|
203
|
-
items: itemSchema.allowedValues ? {
|
|
204
|
-
enum: itemSchema.allowedValues
|
|
205
|
-
} : {
|
|
206
|
-
type: arrayType === "any" ? {} : arrayType
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
item = {
|
|
212
|
-
type: type === "any" ? {} : type
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Is object
|
|
217
|
-
*/
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
item = getJSONSchemaObject(type);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
else if ("enum" in itemSchema) {
|
|
224
|
-
item = {
|
|
225
|
-
type: typeof itemSchema.enum[0],
|
|
226
|
-
"enum": itemSchema.enum //.concat(nullable? [null] : [])
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
else if ("oneOf" in itemSchema) {
|
|
230
|
-
item = {
|
|
231
|
-
type: "object",
|
|
232
|
-
oneOf: itemSchema.oneOf.map(t => getJSONSchemaObject(t))
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
throw new Error("Unexpected jsonbSchema itemSchema" + JSON.stringify({ itemSchema, objDef }, null, 2));
|
|
237
|
-
}
|
|
238
|
-
if (nullable) {
|
|
239
|
-
const nullDef = { type: "null" };
|
|
240
|
-
if (item.oneOf) {
|
|
241
|
-
item.oneOf.push(nullDef);
|
|
242
|
-
}
|
|
243
|
-
else if (item.enum) {
|
|
244
|
-
item.enum.push(null);
|
|
245
|
-
}
|
|
246
|
-
else
|
|
247
|
-
item = {
|
|
248
|
-
type: 'object',
|
|
249
|
-
oneOf: [item, nullDef]
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
return {
|
|
253
|
-
...a,
|
|
254
|
-
[k]: {
|
|
255
|
-
...item,
|
|
256
|
-
required: !optional,
|
|
257
|
-
...(!!description && { description }),
|
|
258
|
-
...(!!title && { title }),
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
}, {})
|
|
262
|
-
};
|
|
263
|
-
return resultType;
|
|
264
|
-
};
|
|
265
|
-
function getJSONBSchemaAsJSONSchema(tableName, colName, columnConfig) {
|
|
266
|
-
const schema = columnConfig.jsonbSchema;
|
|
267
|
-
let jSchema = getJSONSchemaObject({
|
|
268
|
-
field1: isOneOfTypes(schema) ? schema :
|
|
269
|
-
{ type: schema }
|
|
270
|
-
}).properties.field1;
|
|
271
|
-
return {
|
|
272
|
-
"$id": `${tableName}.${colName}`,
|
|
273
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
274
|
-
...jSchema,
|
|
275
|
-
"title": columnConfig.label ?? colName,
|
|
276
|
-
...(!!columnConfig.info?.hint && { description: columnConfig.info?.hint }),
|
|
277
|
-
required: !columnConfig.nullable
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
exports.getJSONBSchemaAsJSONSchema = getJSONBSchemaAsJSONSchema;
|
package/lib/validation.ts
DELETED
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import { AnyObject, asName, getKeys, isEmpty, isObject } from "prostgles-types";
|
|
2
|
-
import { asValue } from "./PubSubManager/PubSubManager";
|
|
3
|
-
import { BaseColumn, ColumnConfig, JSONBColumnDef } from "./TableConfig";
|
|
4
|
-
|
|
5
|
-
type BaseOptions = {
|
|
6
|
-
optional?: boolean;
|
|
7
|
-
nullable?: boolean;
|
|
8
|
-
description?: string;
|
|
9
|
-
allowedValues?: any[];
|
|
10
|
-
title?: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type SimpleType = BaseOptions & ({
|
|
15
|
-
type:
|
|
16
|
-
| "number" | "boolean" | "integer" | "string"
|
|
17
|
-
| "number[]" | "boolean[]" | "integer[]" | "string[]"
|
|
18
|
-
| "any[]"
|
|
19
|
-
| "any"
|
|
20
|
-
| ValidationSchema;
|
|
21
|
-
} | {
|
|
22
|
-
enum: readonly any[];
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
export type OneOf = BaseOptions & {
|
|
26
|
-
oneOf: readonly ValidationSchema[];
|
|
27
|
-
}
|
|
28
|
-
type FieldType = SimpleType | OneOf;
|
|
29
|
-
|
|
30
|
-
type GetType<T extends FieldType> =
|
|
31
|
-
| T extends { type: ValidationSchema } ? SchemaObject<T["type"]> :
|
|
32
|
-
| T extends { type: "number" } ? number :
|
|
33
|
-
| T extends { type: "boolean" } ? boolean :
|
|
34
|
-
| T extends { type: "integer" } ? number :
|
|
35
|
-
| T extends { type: "string" } ? string :
|
|
36
|
-
| T extends { type: "any" } ? any :
|
|
37
|
-
| T extends { type: "number[]" } ? number[] :
|
|
38
|
-
| T extends { type: "boolean[]" } ? boolean[] :
|
|
39
|
-
| T extends { type: "integer[]" } ? number[] :
|
|
40
|
-
| T extends { type: "string[]" } ? string[] :
|
|
41
|
-
| T extends { type: "any[]" } ? any[] :
|
|
42
|
-
| T extends { enum: readonly any[] } ? T["enum"][number] :
|
|
43
|
-
|
|
44
|
-
/** This needs fixing */
|
|
45
|
-
| T extends { oneOf: readonly ValidationSchema[] } ? SchemaObject<T["oneOf"][number]> :
|
|
46
|
-
any;
|
|
47
|
-
|
|
48
|
-
export type ValidationSchema = Record<string, FieldType>;
|
|
49
|
-
export type SchemaObject<S extends ValidationSchema> = ({
|
|
50
|
-
[K in keyof S as S[K]["optional"] extends true ? K : never]?: GetType<S[K]>
|
|
51
|
-
} & {
|
|
52
|
-
[K in keyof S as S[K]["optional"] extends true ? never : K]: GetType<S[K]>
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
/** tests */
|
|
56
|
-
const s = {
|
|
57
|
-
a: { type: "boolean" },
|
|
58
|
-
c: { type: { c1: { type: "string" } } },
|
|
59
|
-
o: {
|
|
60
|
-
oneOf: [
|
|
61
|
-
{ z: { type: "integer" } },
|
|
62
|
-
{ z1: { type: "integer" } }
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
} as const;
|
|
66
|
-
const ss: SchemaObject<typeof s> = {
|
|
67
|
-
a: true,
|
|
68
|
-
c: {
|
|
69
|
-
c1: ""
|
|
70
|
-
},
|
|
71
|
-
o: { z: 1, z1: 23 }
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function validate<T>(obj: T, key: keyof T, validation: FieldType): boolean {
|
|
75
|
-
let err = `The provided value for ${JSON.stringify(key)} is of invalid type. Expecting `;
|
|
76
|
-
const val = obj[key];
|
|
77
|
-
if ("type" in validation && validation.type) {
|
|
78
|
-
if (typeof validation.type !== "string") {
|
|
79
|
-
getKeys(validation.type).forEach(subKey => {
|
|
80
|
-
validate(val, subKey as any, (validation.type as ValidationSchema)[subKey])
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
err += validation.type;
|
|
84
|
-
if (validation.type === "boolean" && typeof val !== validation.type) throw new Error(err)
|
|
85
|
-
if (validation.type === "string" && typeof val !== validation.type) throw new Error(err)
|
|
86
|
-
if (validation.type === "number" && !Number.isFinite(val)) throw new Error(err)
|
|
87
|
-
if (validation.type === "integer" && !Number.isInteger(val)) throw new Error(err)
|
|
88
|
-
} else if ("enum" in validation && validation.enum) {
|
|
89
|
-
err += `on of: ${validation.enum}`;
|
|
90
|
-
if (!validation.enum.includes(val)) throw new Error(err)
|
|
91
|
-
}
|
|
92
|
-
return true
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional = false) {
|
|
96
|
-
if ((!schema || isEmpty(schema)) && !optional) throw new Error(`Expecting ${objName} to be defined`);
|
|
97
|
-
getKeys(schema).forEach(k => validate(obj as any, k, schema[k]));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema | OneOf, nullable: boolean; isRootQuery?: boolean; optional?: boolean; }, depth: number): string {
|
|
101
|
-
const { schema: s, escapedFieldName, nullable, optional, isRootQuery } = args;
|
|
102
|
-
|
|
103
|
-
const jsToPGtypes = {
|
|
104
|
-
"integer": "::INTEGER",
|
|
105
|
-
"number": "::NUMERIC",
|
|
106
|
-
"boolean": "::BOOLEAN",
|
|
107
|
-
"string": "::TEXT",
|
|
108
|
-
"any": "::JSONB"
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const kChecks = (k: string, s: ValidationSchema) => {
|
|
112
|
-
const t = s[k];
|
|
113
|
-
const checks: string[] = [];
|
|
114
|
-
const valAsJson = `${escapedFieldName}->${asValue(k)}`;
|
|
115
|
-
const valAsText = `${escapedFieldName}->>${asValue(k)}`;
|
|
116
|
-
if (t.nullable) checks.push(`${valAsJson} IS NULL`);
|
|
117
|
-
if (t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
118
|
-
|
|
119
|
-
if ("oneOf" in t) {
|
|
120
|
-
checks.push(`(${t.oneOf.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable, optional: t.optional }, depth + 1)).join(" OR ")})`)
|
|
121
|
-
} else if ("enum" in t) {
|
|
122
|
-
if (!t.enum.length || t.enum.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
123
|
-
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: enum cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
checks.push(`array_position(${asValue(t.enum)}::text[], ${valAsText}::text) IS NOT NULL`)
|
|
127
|
-
} else if ("type" in t) {
|
|
128
|
-
if (typeof t.type === "string") {
|
|
129
|
-
if (t.type.endsWith("[]")) {
|
|
130
|
-
const correctType = t.type.slice(0, -2);
|
|
131
|
-
let elemCheck = correctType === "any" ? "" : `AND ('{' || right(left(${valAsText},-1),-1) || '}')${jsToPGtypes[correctType as keyof typeof jsToPGtypes]}[] IS NOT NULL`
|
|
132
|
-
checks.push(`jsonb_typeof(${valAsJson}) = 'array' ${elemCheck}`);
|
|
133
|
-
if(t.allowedValues){
|
|
134
|
-
const types = Array.from(new Set(t.allowedValues.map(v => typeof v)));
|
|
135
|
-
const allowedTypes = ["boolean", "number", "string"] as const;
|
|
136
|
-
if(types.length !== 1 || !allowedTypes.includes(types[0] as any)){
|
|
137
|
-
throw new Error(`Invalid allowedValues (${t.allowedValues}). Must be a non empty array with elements of same type. Allowed types: ${allowedTypes}`)
|
|
138
|
-
}
|
|
139
|
-
const type = types[0] as typeof allowedTypes[number];
|
|
140
|
-
checks.push(`(${valAsText})${jsToPGtypes[type]}[] <@ ${asValue(t.allowedValues)}`)
|
|
141
|
-
}
|
|
142
|
-
} else {
|
|
143
|
-
const correctType = t.type.replace("integer", "number");
|
|
144
|
-
if (correctType !== "any") {
|
|
145
|
-
checks.push(`jsonb_typeof(${valAsJson}) = ${asValue(correctType)} `)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable, optional: !!t.optional }, depth + 1).trim();
|
|
150
|
-
if (check) checks.push(`(${check})`)
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const result = checks.join(" OR ")
|
|
154
|
-
if (!depth) return `COALESCE(${result}, false)`
|
|
155
|
-
return result
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const getSchemaChecks = (s: ValidationSchema) => getKeys(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ")
|
|
159
|
-
|
|
160
|
-
const checks: string[] = [];
|
|
161
|
-
let typeChecks = "";
|
|
162
|
-
if (isOneOfTypes(s)) {
|
|
163
|
-
typeChecks = s.oneOf.map(t => `(${getSchemaChecks(t)})`).join(" OR ");
|
|
164
|
-
} else {
|
|
165
|
-
typeChecks = getSchemaChecks(s);
|
|
166
|
-
}
|
|
167
|
-
if (nullable) checks.push(` ${escapedFieldName} IS NULL `);
|
|
168
|
-
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks ? ` AND (${typeChecks})` : ""}`);
|
|
169
|
-
return checks.join(" OR ");
|
|
170
|
-
}
|
|
171
|
-
type ColOpts = { nullable?: boolean };
|
|
172
|
-
const isOneOfTypes = (s: ValidationSchema | OneOf): s is OneOf => {
|
|
173
|
-
|
|
174
|
-
if ("oneOf" in s) {
|
|
175
|
-
if (!Array.isArray(s.oneOf)) {
|
|
176
|
-
throw "Expecting oneOf to be an array of types";
|
|
177
|
-
}
|
|
178
|
-
return true;
|
|
179
|
-
}
|
|
180
|
-
return false;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export function getSchemaTSTypes(schema: ValidationSchema, leading = "", isOneOf = false): string {
|
|
184
|
-
const getFieldType = (def: FieldType) => {
|
|
185
|
-
const nullType = (def.nullable ? `null | ` : "");
|
|
186
|
-
if ("type" in def) {
|
|
187
|
-
if (typeof def.type === "string") {
|
|
188
|
-
const correctType = def.type.replace("integer", "number");
|
|
189
|
-
if(def.allowedValues && def.type.endsWith("[]")){
|
|
190
|
-
return nullType + ` (${def.allowedValues.map(v => JSON.stringify(v)).join(" | ")})[]`
|
|
191
|
-
}
|
|
192
|
-
return nullType + correctType
|
|
193
|
-
} else {
|
|
194
|
-
return nullType + getSchemaTSTypes(def.type, "", true)
|
|
195
|
-
}
|
|
196
|
-
} else if ("enum" in def) {
|
|
197
|
-
return nullType + def.enum.map(v => asValue(v)).join(" | ")
|
|
198
|
-
} else if ("oneOf" in def) {
|
|
199
|
-
return (def.nullable ? `\n${leading} | null` : "") + def.oneOf.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("")
|
|
200
|
-
} else throw "Unexpected getSchemaTSTypes"
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
let spacing = isOneOf ? " " : " ";
|
|
204
|
-
|
|
205
|
-
let res = `${leading}{ \n` + getKeys(schema).map(k => {
|
|
206
|
-
const def = schema[k];
|
|
207
|
-
return `${leading}${spacing}${k}${def.optional ? "?" : ""}: ` + getFieldType(def) + ";";
|
|
208
|
-
}).join("\n") + ` \n${leading}}${isOneOf ? "" : ";"}`;
|
|
209
|
-
|
|
210
|
-
/** Keep single line */
|
|
211
|
-
if (isOneOf) res = res.split("\n").join("")
|
|
212
|
-
return res;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export function getJSONBSchemaTSTypes(schema: ValidationSchema | OneOf, colOpts: ColOpts, leading = "", isOneOf = false): string {
|
|
216
|
-
if (isOneOfTypes(schema)) {
|
|
217
|
-
return (colOpts.nullable ? `\n${leading} | null` : "") + schema.oneOf.map(s => `\n${leading} | ` + getSchemaTSTypes(s, "", true)).join("")
|
|
218
|
-
} else {
|
|
219
|
-
return (colOpts.nullable ? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
namespace JSTypes {
|
|
224
|
-
type Base = {
|
|
225
|
-
$id?: string;
|
|
226
|
-
$schema?: string;
|
|
227
|
-
title?: string;
|
|
228
|
-
description?: string;
|
|
229
|
-
required?: boolean;
|
|
230
|
-
// nullable?: boolean;
|
|
231
|
-
// optional?: boolean;
|
|
232
|
-
}
|
|
233
|
-
export type Any = {};
|
|
234
|
-
|
|
235
|
-
export type Object<T extends AnyObject = AnyObject> = Base & {
|
|
236
|
-
type: "object";
|
|
237
|
-
properties: Record<keyof T, Schema>;
|
|
238
|
-
}
|
|
239
|
-
export type Enum = Base & {
|
|
240
|
-
type: "string" | "number";
|
|
241
|
-
enum: (string | number)[]
|
|
242
|
-
}
|
|
243
|
-
export type Array = Base & {
|
|
244
|
-
type: "array";
|
|
245
|
-
items: (string | number)[]
|
|
246
|
-
}
|
|
247
|
-
export type OneOf = {
|
|
248
|
-
oneOf: (Any | Object | Enum | Array)[]
|
|
249
|
-
}
|
|
250
|
-
export type Schema =
|
|
251
|
-
| Any
|
|
252
|
-
| Object
|
|
253
|
-
| Enum
|
|
254
|
-
| Array
|
|
255
|
-
| OneOf;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
type JSONSchema = JSTypes.Schema
|
|
259
|
-
|
|
260
|
-
const getJSONSchemaObject = <T extends ValidationSchema>(objDef: T): JSTypes.Object<T> => {
|
|
261
|
-
const resultType: JSONSchema = {
|
|
262
|
-
type: "object",
|
|
263
|
-
properties: getKeys(objDef).reduce((a, k) => {
|
|
264
|
-
const itemSchema: FieldType = objDef[k];
|
|
265
|
-
const { nullable, optional, description, title } = itemSchema;
|
|
266
|
-
let item = {} as any;
|
|
267
|
-
|
|
268
|
-
if ("type" in itemSchema) {
|
|
269
|
-
const { type } = itemSchema;
|
|
270
|
-
/**
|
|
271
|
-
* Is primitive or any
|
|
272
|
-
*/
|
|
273
|
-
if (typeof type === "string") {
|
|
274
|
-
const arrayType = type.endsWith("[]") ? type.slice(0, -2) : undefined;
|
|
275
|
-
if (arrayType) {
|
|
276
|
-
item = {
|
|
277
|
-
type: "array",
|
|
278
|
-
items: itemSchema.allowedValues? {
|
|
279
|
-
enum: itemSchema.allowedValues
|
|
280
|
-
} : {
|
|
281
|
-
type: arrayType === "any" ? {} : arrayType
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
} else {
|
|
286
|
-
item = {
|
|
287
|
-
type: type === "any" ? {} : type
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Is object
|
|
293
|
-
*/
|
|
294
|
-
} else {
|
|
295
|
-
item = getJSONSchemaObject(type)
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
} else if ("enum" in itemSchema) {
|
|
300
|
-
item = {
|
|
301
|
-
type: typeof itemSchema.enum[0]!,
|
|
302
|
-
"enum": itemSchema.enum //.concat(nullable? [null] : [])
|
|
303
|
-
}
|
|
304
|
-
} else if ("oneOf" in itemSchema) {
|
|
305
|
-
item = {
|
|
306
|
-
type: "object",
|
|
307
|
-
oneOf: itemSchema.oneOf.map(t => getJSONSchemaObject(t))
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
throw new Error("Unexpected jsonbSchema itemSchema" + JSON.stringify({ itemSchema, objDef }, null, 2))
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (nullable) {
|
|
314
|
-
const nullDef = { type: "null" }
|
|
315
|
-
if (item.oneOf){
|
|
316
|
-
item.oneOf.push(nullDef)
|
|
317
|
-
} else if(item.enum){
|
|
318
|
-
item.enum.push(null)
|
|
319
|
-
|
|
320
|
-
} else item = {
|
|
321
|
-
type: 'object',
|
|
322
|
-
oneOf: [item, nullDef]
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
return {
|
|
327
|
-
...a,
|
|
328
|
-
[k]: {
|
|
329
|
-
...item,
|
|
330
|
-
required: !optional,
|
|
331
|
-
...(!!description && {description}),
|
|
332
|
-
...(!!title && {title}),
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}, {} as Record<string, JSTypes.Schema>)
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return resultType as any;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
export function getJSONBSchemaAsJSONSchema(tableName: string, colName: string, columnConfig: BaseColumn<{ en: 1 }> & JSONBColumnDef): JSONSchema {
|
|
342
|
-
|
|
343
|
-
const schema = columnConfig.jsonbSchema;
|
|
344
|
-
|
|
345
|
-
let jSchema: JSONSchema = getJSONSchemaObject({
|
|
346
|
-
field1:
|
|
347
|
-
isOneOfTypes(schema) ? schema :
|
|
348
|
-
{ type: schema as ValidationSchema }
|
|
349
|
-
}).properties.field1;
|
|
350
|
-
|
|
351
|
-
return {
|
|
352
|
-
"$id": `${tableName}.${colName}`,
|
|
353
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
354
|
-
...jSchema,
|
|
355
|
-
"title": columnConfig.label ?? colName,
|
|
356
|
-
...(!!columnConfig.info?.hint && { description: columnConfig.info?.hint }),
|
|
357
|
-
required: !columnConfig.nullable
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
}
|