prostgles-server 2.0.227 → 2.0.230
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/DBSchemaBuilder.d.ts.map +1 -1
- package/dist/DBSchemaBuilder.js +10 -1
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/FileManager.d.ts +8 -1
- package/dist/FileManager.d.ts.map +1 -1
- package/dist/FileManager.js +29 -19
- package/dist/FileManager.js.map +1 -1
- package/dist/QueryBuilder.js +1 -1
- package/dist/QueryBuilder.js.map +1 -1
- package/dist/TableConfig.d.ts +5 -1
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +8 -4
- package/dist/TableConfig.js.map +1 -1
- package/dist/validation.d.ts +50 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +135 -0
- package/dist/validation.js.map +1 -0
- package/lib/DBSchemaBuilder.d.ts.map +1 -1
- package/lib/DBSchemaBuilder.js +10 -1
- package/lib/DBSchemaBuilder.ts +10 -1
- package/lib/FileManager.d.ts +8 -1
- package/lib/FileManager.d.ts.map +1 -1
- package/lib/FileManager.js +29 -19
- package/lib/FileManager.ts +35 -20
- package/lib/QueryBuilder.js +1 -1
- package/lib/QueryBuilder.ts +1 -1
- package/lib/TableConfig.d.ts +5 -1
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.js +8 -4
- package/lib/TableConfig.ts +15 -5
- package/lib/validation.d.ts +50 -0
- package/lib/validation.d.ts.map +1 -0
- package/lib/validation.js +134 -0
- package/lib/validation.ts +157 -0
- package/package.json +2 -1
- package/tests/client/PID.txt +1 -1
- package/tests/isomorphic_queries.d.ts.map +1 -1
- package/tests/isomorphic_queries.js +25 -0
- package/tests/isomorphic_queries.ts +28 -1
- package/tests/server/DBoGenerated.d.ts +133 -114
- package/tests/server/index.js +13 -0
- package/tests/server/index.ts +13 -0
- package/tests/server/package-lock.json +3 -1
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;
|
|
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,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEtE,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;CACxB,CAAA;AAED,aAAK,qBAAqB,CAAC,QAAQ,IAAI;IACrC,aAAa,EAAE;QACb,MAAM,EAAE;YACN,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,GAAG;iBACtB,OAAO,IAAI,MAAM,QAAQ,GAAG,MAAM;aACpC,CAAA;SACF,CAAA;KACF,CAAA;CACF,CAAA;AAED,aAAK,UAAU,CAAC,QAAQ,IAAI;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IAEpB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;SAAG,OAAO,IAAI,MAAM,QAAQ,GAAG,MAAM;KAAG,CAAC,CAAC;CACpE,CAAA;AAED,aAAK,YAAY,GAAG;IAElB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,aAAK,UAAU,GAAG;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAA;AAED,aAAK,UAAU,GAAG,UAAU,GAAG;IAC7B,MAAM,EAAE,IAAI,CAAC;IACb;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAA;AAED,aAAK,cAAc,GAAG,UAAU,GAAG;IACjC,UAAU,EAAE,gBAAgB,CAAC;CAC9B,CAAA;AAED;;;GAGG;AACH,aAAK,WAAW,GAAG,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;CACvB,GAAG,CACA;IAEE;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAC/G,GACD;IACE,iBAAiB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAA;CAC1D,CACF,CAAC,CAAC;AAEL,aAAK,gBAAgB,GAAG;IAEtB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG;QAGxB,SAAS,EAAE,MAAM,CAAC;QAElB;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAA;CACF,CAAA;AAED,aAAK,OAAO,GAAG;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;CACrC,CAAA;AAED;;GAEG;AACH,aAAK,eAAe,GAAG;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB,CAAA;AAED,aAAK,YAAY,CAAC,QAAQ,GAAG;IAAE,EAAE,EAAE,CAAC,CAAA;CAAE,IAAI,eAAe,GAAG,WAAW,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,GAAG,gBAAgB,GAAG,UAAU,GAAG,cAAc,CAAC,CAAC,CAAA;AAElK,aAAK,eAAe,CAAC,QAAQ,IAAI;IAC/B,OAAO,CAAC,EAAE;QACR,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;KAC9C,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAClC,CAAC;IAEF;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,OAAO,CAAC,EAAE;QACR,CAAC,UAAU,EAAE,MAAM,GAAG;YAEpB;;eAEG;YACH,OAAO,CAAC,EAAE,OAAO,CAAC;YAElB;;;eAGG;YACH,MAAM,CAAC,EAAE,OAAO,CAAC;YAEjB;;;;eAIG;YACH,YAAY,CAAC,EAAE,OAAO,CAAC;YAEvB;;eAEG;YAGH;;eAEG;YACH,UAAU,EAAE,MAAM,CAAC;YAEnB;;;eAGG;YACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;SAC1C,CAAA;KACF,CAAA;CACF,CAAA;AAED;;GAEG;AACH,oBAAY,WAAW,CAAC,QAAQ,GAAG;IAAE,EAAE,EAAE,CAAC,CAAA;CAAE,IAAI;IAC9C,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC;CACrH,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB,CAAC,QAAQ,GAAG;IAAE,EAAE,EAAE,CAAC,CAAA;CAAE;IAEzD,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,GAAG,IAAI,eAAe,CAGzB;IACD,IAAI,EAAE,IAAI,EAAE,CAGX;IAED,SAAS,EAAE,SAAS,CAAA;gBAER,SAAS,EAAE,SAAS;IAKhC,eAAe,cAAe,MAAM,WAAW,MAAM,KAAG,YAAY,GAAG,SAAS,CAM/E;IAED,YAAY,WAAY;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAM3F;IAED,UAAU,WAAY;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,CAAC,YAAY,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAiCpH;IAED,WAAW,WAAY;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,KAAG,IAAI,CAQvE;IAED,WAAW,gBAAiB,MAAM,eAAe,MAAM,KAAG,QAAQ,GAAG,SAAS,CA2B7E;IAEK,IAAI;CA8IX"}
|
package/lib/TableConfig.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.parseI18N = void 0;
|
|
|
4
4
|
const prostgles_types_1 = require("prostgles-types");
|
|
5
5
|
const DboBuilder_1 = require("./DboBuilder");
|
|
6
6
|
const PubSubManager_1 = require("./PubSubManager");
|
|
7
|
+
const validation_1 = require("./validation");
|
|
7
8
|
const parseI18N = (params) => {
|
|
8
9
|
const { config, lang, defaultLang, defaultValue } = params;
|
|
9
10
|
if (config) {
|
|
@@ -160,13 +161,13 @@ class TableConfigurator {
|
|
|
160
161
|
if ("columns" in tableConf) {
|
|
161
162
|
const getColDef = (name, colConf) => {
|
|
162
163
|
const colNameEsc = (0, prostgles_types_1.asName)(name);
|
|
163
|
-
const
|
|
164
|
+
const getColDef = (colConf, pgType) => {
|
|
164
165
|
const { nullable, defaultValue } = colConf;
|
|
165
|
-
return
|
|
166
|
+
return `${pgType} ${!nullable ? " NOT NULL " : ""} ${defaultValue ? ` DEFAULT ${(0, PubSubManager_1.asValue)(defaultValue)} ` : ""}`;
|
|
166
167
|
};
|
|
167
168
|
if ("references" in colConf && colConf.references) {
|
|
168
169
|
const { tableName: lookupTable, columnName: lookupCol = "id" } = colConf.references;
|
|
169
|
-
return ` ${colNameEsc} ${
|
|
170
|
+
return ` ${colNameEsc} ${getColDef(colConf.references, "TEXT")} REFERENCES ${lookupTable} (${lookupCol}) `;
|
|
170
171
|
}
|
|
171
172
|
else if ("sqlDefinition" in colConf && colConf.sqlDefinition) {
|
|
172
173
|
return ` ${colNameEsc} ${colConf.sqlDefinition} `;
|
|
@@ -182,7 +183,10 @@ class TableConfigurator {
|
|
|
182
183
|
if (cArr.length) {
|
|
183
184
|
checks = `CHECK (${cArr.join(" AND ")})`;
|
|
184
185
|
}
|
|
185
|
-
return ` ${colNameEsc} ${
|
|
186
|
+
return ` ${colNameEsc} ${getColDef(colConf, "TEXT")} ${checks}`;
|
|
187
|
+
}
|
|
188
|
+
else if ("jsonSchema" in colConf && colConf.jsonSchema) {
|
|
189
|
+
return ` ${colNameEsc} ${getColDef(colConf, "JSONB")} CHECK(${(0, validation_1.getPGCheckConstraint)({ schema: colConf.jsonSchema, escapedFieldName: colNameEsc })})`;
|
|
186
190
|
}
|
|
187
191
|
else {
|
|
188
192
|
throw "Unknown column config: " + JSON.stringify(colConf);
|
package/lib/TableConfig.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { getKeys, asName, AnyObject, TableInfo, ALLOWED_EXTENSION, ALLOWED_CONT
|
|
|
2
2
|
import { isPlainObject, JoinInfo } from "./DboBuilder";
|
|
3
3
|
import { DB, DBHandlerServer, Joins, Prostgles } from "./Prostgles";
|
|
4
4
|
import { asValue } from "./PubSubManager";
|
|
5
|
+
import { getPGCheckConstraint, ValidationSchema } from "./validation";
|
|
5
6
|
|
|
6
7
|
type ColExtraInfo = {
|
|
7
8
|
min?: string | number;
|
|
@@ -85,6 +86,10 @@ type TextColumn = TextColDef & {
|
|
|
85
86
|
lowerCased?: boolean;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
type JSONBColumnDef = TextColDef & {
|
|
90
|
+
jsonSchema: ValidationSchema;
|
|
91
|
+
}
|
|
92
|
+
|
|
88
93
|
/**
|
|
89
94
|
* Allows referencing media to this table.
|
|
90
95
|
* Requires this table to have a primary key AND a valid fileTable config
|
|
@@ -138,7 +143,7 @@ type NamedJoinColumn = {
|
|
|
138
143
|
joinDef: JoinDef[];
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
type ColumnConfig<LANG_IDS = { en: 1 }> = NamedJoinColumn | MediaColumn | (BaseColumn<LANG_IDS> & (SQLDefColumn | ReferencedColumn | TextColumn))
|
|
146
|
+
type ColumnConfig<LANG_IDS = { en: 1 }> = NamedJoinColumn | MediaColumn | (BaseColumn<LANG_IDS> & (SQLDefColumn | ReferencedColumn | TextColumn | JSONBColumnDef))
|
|
142
147
|
|
|
143
148
|
type TableDefinition<LANG_IDS> = {
|
|
144
149
|
columns?: {
|
|
@@ -356,14 +361,14 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
356
361
|
if ("columns" in tableConf) {
|
|
357
362
|
const getColDef = (name: string, colConf: ColumnConfig): string => {
|
|
358
363
|
const colNameEsc = asName(name);
|
|
359
|
-
const
|
|
364
|
+
const getColDef = (colConf: TextColDef, pgType: "TEXT" | "JSONB") => {
|
|
360
365
|
const { nullable, defaultValue } = colConf;
|
|
361
|
-
return
|
|
366
|
+
return `${pgType} ${!nullable ? " NOT NULL " : ""} ${defaultValue ? ` DEFAULT ${asValue(defaultValue)} ` : ""}`
|
|
362
367
|
}
|
|
363
368
|
if ("references" in colConf && colConf.references) {
|
|
364
369
|
|
|
365
370
|
const { tableName: lookupTable, columnName: lookupCol = "id" } = colConf.references;
|
|
366
|
-
return ` ${colNameEsc} ${
|
|
371
|
+
return ` ${colNameEsc} ${getColDef(colConf.references, "TEXT")} REFERENCES ${lookupTable} (${lookupCol}) `;
|
|
367
372
|
|
|
368
373
|
} else if ("sqlDefinition" in colConf && colConf.sqlDefinition) {
|
|
369
374
|
|
|
@@ -380,7 +385,12 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
380
385
|
if (cArr.length) {
|
|
381
386
|
checks = `CHECK (${cArr.join(" AND ")})`
|
|
382
387
|
}
|
|
383
|
-
return ` ${colNameEsc} ${
|
|
388
|
+
return ` ${colNameEsc} ${getColDef(colConf, "TEXT")} ${checks}`;
|
|
389
|
+
|
|
390
|
+
} else if ("jsonSchema" in colConf && colConf.jsonSchema) {
|
|
391
|
+
|
|
392
|
+
return ` ${colNameEsc} ${getColDef(colConf, "JSONB")} CHECK(${getPGCheckConstraint({ schema: colConf.jsonSchema, escapedFieldName: colNameEsc })})`;
|
|
393
|
+
|
|
384
394
|
} else {
|
|
385
395
|
throw "Unknown column config: " + JSON.stringify(colConf);
|
|
386
396
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
declare type FieldType = ({
|
|
2
|
+
type: "number" | "boolean" | "integer" | "string" | "number[]" | "boolean[]" | "integer[]" | "string[]" | ValidationSchema;
|
|
3
|
+
} | {
|
|
4
|
+
oneOf: readonly any[];
|
|
5
|
+
} | {
|
|
6
|
+
oneOfTypes: readonly ValidationSchema[];
|
|
7
|
+
}) & {
|
|
8
|
+
optional?: boolean;
|
|
9
|
+
nullable?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare type GetType<T extends FieldType> = T extends {
|
|
12
|
+
type: ValidationSchema;
|
|
13
|
+
} ? SchemaObject<T["type"]> : T extends {
|
|
14
|
+
type: "number";
|
|
15
|
+
} ? number : T extends {
|
|
16
|
+
type: "boolean";
|
|
17
|
+
} ? boolean : T extends {
|
|
18
|
+
type: "integer";
|
|
19
|
+
} ? number : T extends {
|
|
20
|
+
type: "string";
|
|
21
|
+
} ? string : T extends {
|
|
22
|
+
type: "number[]";
|
|
23
|
+
} ? number[] : T extends {
|
|
24
|
+
type: "boolean[]";
|
|
25
|
+
} ? boolean[] : T extends {
|
|
26
|
+
type: "integer[]";
|
|
27
|
+
} ? number[] : T extends {
|
|
28
|
+
type: "string[]";
|
|
29
|
+
} ? string[] : T extends {
|
|
30
|
+
oneOf: readonly any[];
|
|
31
|
+
} ? T["oneOf"][number] :
|
|
32
|
+
/** This needs fixing */
|
|
33
|
+
T extends {
|
|
34
|
+
oneOfTypes: readonly ValidationSchema[];
|
|
35
|
+
} ? SchemaObject<T["oneOfTypes"][number]> : any;
|
|
36
|
+
export declare type ValidationSchema = Record<string, FieldType>;
|
|
37
|
+
export declare type SchemaObject<S extends ValidationSchema> = ({
|
|
38
|
+
[K in keyof S as S[K]["optional"] extends true ? K : never]?: GetType<S[K]>;
|
|
39
|
+
} & {
|
|
40
|
+
[K in keyof S as S[K]["optional"] extends true ? never : K]: GetType<S[K]>;
|
|
41
|
+
});
|
|
42
|
+
export declare function validate<T>(obj: T, key: keyof T, validation: FieldType): boolean;
|
|
43
|
+
export declare function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional?: boolean): void;
|
|
44
|
+
export declare function getPGCheckConstraint(args: {
|
|
45
|
+
escapedFieldName: string;
|
|
46
|
+
schema: ValidationSchema;
|
|
47
|
+
}): string;
|
|
48
|
+
export declare function getSchemaTSTypes(schema: ValidationSchema, leading?: string, isOneOf?: boolean): string;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSchemaTSTypes = exports.getPGCheckConstraint = exports.validateSchema = exports.validate = void 0;
|
|
4
|
+
const prostgles_types_1 = require("prostgles-types");
|
|
5
|
+
const PubSubManager_1 = require("./PubSubManager");
|
|
6
|
+
/** tests */
|
|
7
|
+
const s = {
|
|
8
|
+
a: { type: "boolean" },
|
|
9
|
+
c: { type: { c1: { type: "string" } } },
|
|
10
|
+
o: { oneOfTypes: [
|
|
11
|
+
{ z: { type: "integer" } },
|
|
12
|
+
{ z1: { type: "integer" } }
|
|
13
|
+
] }
|
|
14
|
+
};
|
|
15
|
+
const ss = {
|
|
16
|
+
a: true,
|
|
17
|
+
c: {
|
|
18
|
+
c1: ""
|
|
19
|
+
},
|
|
20
|
+
o: { z: 1, z1: 23 }
|
|
21
|
+
};
|
|
22
|
+
function validate(obj, key, validation) {
|
|
23
|
+
let err = `The provided value for ${JSON.stringify(key)} is of invalid type. Expecting `;
|
|
24
|
+
const val = obj[key];
|
|
25
|
+
if ("type" in validation && validation.type) {
|
|
26
|
+
if (typeof validation.type !== "string") {
|
|
27
|
+
(0, prostgles_types_1.getKeys)(validation.type).forEach(subKey => {
|
|
28
|
+
validate(val, subKey, validation.type[subKey]);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
err += validation.type;
|
|
32
|
+
if (validation.type === "boolean" && typeof val !== validation.type)
|
|
33
|
+
throw new Error(err);
|
|
34
|
+
if (validation.type === "string" && typeof val !== validation.type)
|
|
35
|
+
throw new Error(err);
|
|
36
|
+
if (validation.type === "number" && !Number.isFinite(val))
|
|
37
|
+
throw new Error(err);
|
|
38
|
+
if (validation.type === "integer" && !Number.isInteger(val))
|
|
39
|
+
throw new Error(err);
|
|
40
|
+
}
|
|
41
|
+
else if ("oneOf" in validation && validation.oneOf) {
|
|
42
|
+
err += `on of: ${validation.oneOf}`;
|
|
43
|
+
if (!validation.oneOf.includes(val))
|
|
44
|
+
throw new Error(err);
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
exports.validate = validate;
|
|
49
|
+
function validateSchema(schema, obj, objName, optional = false) {
|
|
50
|
+
if ((!schema || (0, prostgles_types_1.isEmpty)(schema)) && !optional)
|
|
51
|
+
throw new Error(`Expecting ${objName} to be defined`);
|
|
52
|
+
(0, prostgles_types_1.getKeys)(schema).forEach(k => validate(obj, k, schema[k]));
|
|
53
|
+
}
|
|
54
|
+
exports.validateSchema = validateSchema;
|
|
55
|
+
function getPGCheckConstraint(args) {
|
|
56
|
+
const { schema: s, escapedFieldName } = args;
|
|
57
|
+
const jsToPGtypes = {
|
|
58
|
+
"number": "::NUMERIC",
|
|
59
|
+
"boolean": "::BOOLEAN",
|
|
60
|
+
"string": "" // already a string
|
|
61
|
+
};
|
|
62
|
+
const kChecks = (k) => {
|
|
63
|
+
const t = s[k];
|
|
64
|
+
const checks = [];
|
|
65
|
+
const valAsJson = `${escapedFieldName}->${(0, PubSubManager_1.asValue)(k)}`;
|
|
66
|
+
const valAsText = `${escapedFieldName}->>${(0, PubSubManager_1.asValue)(k)}`;
|
|
67
|
+
if (t.nullable)
|
|
68
|
+
checks.push(`${valAsJson} IS NULL`);
|
|
69
|
+
if (t.optional)
|
|
70
|
+
checks.push(`${escapedFieldName} ? ${(0, PubSubManager_1.asValue)(k)} = FALSE`);
|
|
71
|
+
if ("oneOfTypes" in t) {
|
|
72
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType })).join(" OR ")})`);
|
|
73
|
+
}
|
|
74
|
+
else if ("oneOf" in t) {
|
|
75
|
+
if (!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
76
|
+
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: oneOf cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
77
|
+
}
|
|
78
|
+
const oneOfHasNull = t.oneOf.includes(null);
|
|
79
|
+
if (oneOfHasNull)
|
|
80
|
+
checks.push(`${valAsText} IS NULL`);
|
|
81
|
+
const oneOf = t.oneOf.filter(o => o !== null);
|
|
82
|
+
oneOf.forEach(o => {
|
|
83
|
+
(0, PubSubManager_1.asValue)(o.toString());
|
|
84
|
+
checks.push(`${valAsText}${jsToPGtypes[typeof o]} = ${(0, PubSubManager_1.asValue)(o)}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else if ("type" in t) {
|
|
88
|
+
if (typeof t.type === "string") {
|
|
89
|
+
const correctType = t.type.replace("integer", "number");
|
|
90
|
+
if (t.type.endsWith("[]")) {
|
|
91
|
+
/** Must add custom functions to type check each array element */
|
|
92
|
+
checks.push(`
|
|
93
|
+
jsonb_typeof(${valAsJson}) = 'array' AND
|
|
94
|
+
( jsonb_array_length(${valAsJson}) = 0 OR jsonb_typeof(jsonb_array_element(${valAsJson}, 1)) = ${(0, PubSubManager_1.asValue)(correctType.slice(0, -2))} )`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
checks.push(`jsonb_typeof(${valAsJson}) = ${(0, PubSubManager_1.asValue)(correctType)} `);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type }) + " )");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return checks.join(" OR ");
|
|
105
|
+
};
|
|
106
|
+
return (0, prostgles_types_1.getKeys)(s).map(k => "(" + kChecks(k) + ")").join(" AND ");
|
|
107
|
+
}
|
|
108
|
+
exports.getPGCheckConstraint = getPGCheckConstraint;
|
|
109
|
+
function getSchemaTSTypes(schema, leading = "", isOneOf = false) {
|
|
110
|
+
const getFieldType = (def) => {
|
|
111
|
+
if ("type" in def) {
|
|
112
|
+
if (typeof def.type === "string") {
|
|
113
|
+
const correctType = def.type.replace("integer", "number");
|
|
114
|
+
return correctType;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return getSchemaTSTypes(def.type);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if ("oneOf" in def) {
|
|
121
|
+
return def.oneOf.map(v => v).join(" | ");
|
|
122
|
+
}
|
|
123
|
+
else if ("oneOfTypes" in def) {
|
|
124
|
+
return def.oneOfTypes.map(v => getSchemaTSTypes(v, leading, true)).join(" | ");
|
|
125
|
+
}
|
|
126
|
+
else
|
|
127
|
+
throw "Unexpected getSchemaTSTypes";
|
|
128
|
+
};
|
|
129
|
+
return `${leading}{ \n` + (0, prostgles_types_1.getKeys)(schema).map(k => {
|
|
130
|
+
const def = schema[k];
|
|
131
|
+
return `${leading} ${k}${def.optional ? "?" : ""}: ${def.nullable ? " null | " : ""} ` + getFieldType(def);
|
|
132
|
+
}).join(";\n") + ` \n${leading}} ${isOneOf ? "" : ";"}`;
|
|
133
|
+
}
|
|
134
|
+
exports.getSchemaTSTypes = getSchemaTSTypes;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { asName, getKeys, isEmpty, isObject } from "prostgles-types";
|
|
2
|
+
import { asValue } from "./PubSubManager";
|
|
3
|
+
|
|
4
|
+
type FieldType = ({
|
|
5
|
+
type:
|
|
6
|
+
| "number" | "boolean" | "integer" | "string"
|
|
7
|
+
| "number[]" | "boolean[]" | "integer[]" | "string[]"
|
|
8
|
+
| ValidationSchema;
|
|
9
|
+
|
|
10
|
+
} | {
|
|
11
|
+
oneOf: readonly any[];
|
|
12
|
+
} | {
|
|
13
|
+
oneOfTypes: readonly ValidationSchema[];
|
|
14
|
+
}) & {
|
|
15
|
+
optional?: boolean;
|
|
16
|
+
nullable?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type GetType<T extends FieldType> =
|
|
20
|
+
| T extends { type: ValidationSchema }? SchemaObject<T["type"]> :
|
|
21
|
+
| T extends { type: "number" }? number:
|
|
22
|
+
| T extends { type: "boolean" }? boolean:
|
|
23
|
+
| T extends { type: "integer" }? number:
|
|
24
|
+
| T extends { type: "string" }? string:
|
|
25
|
+
| T extends { type: "number[]" }? number[]:
|
|
26
|
+
| T extends { type: "boolean[]" }? boolean[]:
|
|
27
|
+
| T extends { type: "integer[]" }? number[]:
|
|
28
|
+
| T extends { type: "string[]" }? string[]:
|
|
29
|
+
| T extends { oneOf: readonly any[] }? T["oneOf"][number] :
|
|
30
|
+
|
|
31
|
+
/** This needs fixing */
|
|
32
|
+
| T extends { oneOfTypes: readonly ValidationSchema[] }? SchemaObject<T["oneOfTypes"][number]> :
|
|
33
|
+
any;
|
|
34
|
+
|
|
35
|
+
export type ValidationSchema = Record<string, FieldType>;
|
|
36
|
+
export type SchemaObject<S extends ValidationSchema> = ({
|
|
37
|
+
[K in keyof S as S[K]["optional"] extends true? K : never]?: GetType<S[K]>
|
|
38
|
+
} & {
|
|
39
|
+
[K in keyof S as S[K]["optional"] extends true? never : K]: GetType<S[K]>
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/** tests */
|
|
43
|
+
const s = {
|
|
44
|
+
a: { type: "boolean" },
|
|
45
|
+
c: { type: { c1: { type: "string" } } },
|
|
46
|
+
o: { oneOfTypes: [
|
|
47
|
+
{ z: { type: "integer" } },
|
|
48
|
+
{ z1: { type: "integer" } }
|
|
49
|
+
] }
|
|
50
|
+
} as const;
|
|
51
|
+
const ss: SchemaObject<typeof s> = {
|
|
52
|
+
a: true,
|
|
53
|
+
c: {
|
|
54
|
+
c1: ""
|
|
55
|
+
},
|
|
56
|
+
o: { z: 1, z1: 23 }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function validate<T>(obj: T, key: keyof T, validation: FieldType): boolean {
|
|
60
|
+
let err = `The provided value for ${JSON.stringify(key)} is of invalid type. Expecting `;
|
|
61
|
+
const val = obj[key];
|
|
62
|
+
if("type" in validation && validation.type){
|
|
63
|
+
if(typeof validation.type !== "string"){
|
|
64
|
+
getKeys(validation.type).forEach(subKey => {
|
|
65
|
+
validate(val, subKey as any, (validation.type as ValidationSchema)[subKey])
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
err += validation.type;
|
|
69
|
+
if(validation.type === "boolean" && typeof val !== validation.type) throw new Error(err)
|
|
70
|
+
if(validation.type === "string" && typeof val !== validation.type) throw new Error(err)
|
|
71
|
+
if(validation.type === "number" && !Number.isFinite(val)) throw new Error(err)
|
|
72
|
+
if(validation.type === "integer" && !Number.isInteger(val)) throw new Error(err)
|
|
73
|
+
} else if("oneOf" in validation && validation.oneOf){
|
|
74
|
+
err += `on of: ${validation.oneOf}`;
|
|
75
|
+
if(!validation.oneOf.includes(val)) throw new Error(err)
|
|
76
|
+
}
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional = false){
|
|
81
|
+
if((!schema || isEmpty(schema)) && !optional) throw new Error(`Expecting ${objName} to be defined`);
|
|
82
|
+
getKeys(schema).forEach(k => validate(obj as any, k, schema[k]));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema }): string {
|
|
86
|
+
const { schema: s, escapedFieldName } = args;
|
|
87
|
+
|
|
88
|
+
const jsToPGtypes = {
|
|
89
|
+
"number": "::NUMERIC",
|
|
90
|
+
"boolean": "::BOOLEAN",
|
|
91
|
+
"string": "" // already a string
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const kChecks = (k: string) => {
|
|
95
|
+
const t = s[k];
|
|
96
|
+
const checks: string[] = [];
|
|
97
|
+
const valAsJson = `${escapedFieldName}->${asValue(k)}`;
|
|
98
|
+
const valAsText = `${escapedFieldName}->>${asValue(k)}`;
|
|
99
|
+
if(t.nullable) checks.push(`${valAsJson} IS NULL`);
|
|
100
|
+
if(t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
101
|
+
|
|
102
|
+
if("oneOfTypes" in t){
|
|
103
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType })).join(" OR ")})`)
|
|
104
|
+
} else if("oneOf" in t){
|
|
105
|
+
if(!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
106
|
+
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: oneOf cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
107
|
+
}
|
|
108
|
+
const oneOfHasNull = t.oneOf.includes(null);
|
|
109
|
+
if(oneOfHasNull) checks.push(`${valAsText} IS NULL`);
|
|
110
|
+
const oneOf = t.oneOf.filter(o => o !== null);
|
|
111
|
+
oneOf.forEach(o => {
|
|
112
|
+
asValue(o.toString())
|
|
113
|
+
checks.push(`${valAsText}${(jsToPGtypes as any)[typeof o]} = ${asValue(o)}`);
|
|
114
|
+
})
|
|
115
|
+
} else if("type" in t){
|
|
116
|
+
if(typeof t.type === "string") {
|
|
117
|
+
const correctType = t.type.replace("integer", "number")
|
|
118
|
+
if(t.type.endsWith("[]")){
|
|
119
|
+
/** Must add custom functions to type check each array element */
|
|
120
|
+
checks.push(`
|
|
121
|
+
jsonb_typeof(${valAsJson}) = 'array' AND
|
|
122
|
+
( jsonb_array_length(${valAsJson}) = 0 OR jsonb_typeof(jsonb_array_element(${valAsJson}, 1)) = ${asValue(correctType.slice(0, -2))} )`)
|
|
123
|
+
} else {
|
|
124
|
+
checks.push(`jsonb_typeof(${valAsJson}) = ${asValue(correctType)} `)
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type }) + " )")
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return checks.join(" OR ")
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return getKeys(s).map(k => "(" + kChecks(k) + ")").join(" AND ");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function getSchemaTSTypes(schema: ValidationSchema, leading = "", isOneOf = false): string {
|
|
138
|
+
const getFieldType = (def: FieldType) => {
|
|
139
|
+
if("type" in def){
|
|
140
|
+
if(typeof def.type === "string"){
|
|
141
|
+
const correctType = def.type.replace("integer", "number")
|
|
142
|
+
return correctType
|
|
143
|
+
} else {
|
|
144
|
+
return getSchemaTSTypes(def.type)
|
|
145
|
+
}
|
|
146
|
+
} else if("oneOf" in def){
|
|
147
|
+
return def.oneOf.map(v => v).join(" | ")
|
|
148
|
+
} else if("oneOfTypes" in def){
|
|
149
|
+
return def.oneOfTypes.map(v => getSchemaTSTypes(v, leading, true)).join(" | ")
|
|
150
|
+
} else throw "Unexpected getSchemaTSTypes"
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return `${leading}{ \n` + getKeys(schema).map(k => {
|
|
154
|
+
const def = schema[k];
|
|
155
|
+
return `${leading} ${k}${def.optional? "?" : ""}: ${def.nullable? " null | " : ""} ` + getFieldType(def);
|
|
156
|
+
}).join(";\n") + ` \n${leading}} ${isOneOf? "" : ";"}`;
|
|
157
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prostgles-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.230",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"@types/express": "^4.17.13",
|
|
29
29
|
"aws-sdk": "^2.1168.0",
|
|
30
30
|
"bluebird": "^3.7.2",
|
|
31
|
+
"check-disk-space": "^3.3.1",
|
|
31
32
|
"file-type": "^17.1.3",
|
|
32
33
|
"pg-promise": "^10.11.1",
|
|
33
34
|
"prostgles-types": "^1.5.169",
|
package/tests/client/PID.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
37798
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isomorphic_queries.d.ts","sourceRoot":"","sources":["isomorphic_queries.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,iBAYzE;AACD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,oBAW7F;AAED,wBAA8B,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"isomorphic_queries.d.ts","sourceRoot":"","sources":["isomorphic_queries.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,iBAYzE;AACD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,oBAW7F;AAED,wBAA8B,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,iBA2zB/F"}
|
|
@@ -544,6 +544,31 @@ async function isomorphic(db) {
|
|
|
544
544
|
const newF = await db.media.findOne({ id: original.id });
|
|
545
545
|
assert_1.strict.equal(newF.original_name, newFile.name);
|
|
546
546
|
});
|
|
547
|
+
await tryRun("jsonSchema validation", async () => {
|
|
548
|
+
/**
|
|
549
|
+
*
|
|
550
|
+
tjson: {
|
|
551
|
+
columns: {
|
|
552
|
+
json: { jsonSchema: {
|
|
553
|
+
a: { type: "boolean" },
|
|
554
|
+
arr: { oneOf: ["1", "2", "3"] }
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
*/
|
|
560
|
+
const json = { a: true, arr: "2" };
|
|
561
|
+
const fo = await db.tjson.insert({ json }, { returning: "*" });
|
|
562
|
+
assert_1.strict.deepStrictEqual(fo.json, json);
|
|
563
|
+
await db.tjson.insert({ json: { o: { o1: 2, o2: true }, a: true, arr: 1 } });
|
|
564
|
+
try {
|
|
565
|
+
await db.tjson.insert({ json: { a: true, arr: "22" } });
|
|
566
|
+
throw "Should have failed";
|
|
567
|
+
}
|
|
568
|
+
catch (e) {
|
|
569
|
+
// Perfect
|
|
570
|
+
}
|
|
571
|
+
});
|
|
547
572
|
await tryRun("Exists filter example", async () => {
|
|
548
573
|
const fo = await db.items.findOne(), f = await db.items.find();
|
|
549
574
|
assert_1.strict.deepStrictEqual(fo, { h: null, id: 1, name: 'a' }, "findOne query failed");
|
|
@@ -623,7 +623,34 @@ export default async function isomorphic(db: Partial<DBHandlerServer> | Partial<
|
|
|
623
623
|
const newF = await db.media.findOne({ id: original.id });
|
|
624
624
|
|
|
625
625
|
assert.equal(newF.original_name, newFile.name)
|
|
626
|
-
})
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
await tryRun("jsonSchema validation", async () => {
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
*
|
|
632
|
+
tjson: {
|
|
633
|
+
json: { jsonSchema: {
|
|
634
|
+
a: { type: "boolean" },
|
|
635
|
+
arr: { oneOf: ["1", "2", "3"] },
|
|
636
|
+
arr2: { type: "integer[]" },
|
|
637
|
+
o: { oneOfTypes: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true },
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
},
|
|
641
|
+
*/
|
|
642
|
+
|
|
643
|
+
const json = {a: true, arr: "2"}
|
|
644
|
+
const fo = await db.tjson.insert({ json }, { returning: "*"});
|
|
645
|
+
assert.deepStrictEqual(fo.json, json);
|
|
646
|
+
await db.tjson.insert({ json: {o: { o1: 2, o2: true }, a: true, arr: 1 } })
|
|
647
|
+
try {
|
|
648
|
+
await db.tjson.insert({ json: { a: true, arr: "22"} });
|
|
649
|
+
throw "Should have failed"
|
|
650
|
+
} catch(e){
|
|
651
|
+
// Perfect
|
|
652
|
+
}
|
|
653
|
+
});
|
|
627
654
|
|
|
628
655
|
await tryRun("Exists filter example", async () => {
|
|
629
656
|
|