prostgles-server 2.0.234 → 2.0.237
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 +4 -2
- package/dist/DBSchemaBuilder.d.ts.map +1 -1
- package/dist/DBSchemaBuilder.js +54 -47
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/DboBuilder.d.ts +6 -6
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/Prostgles.d.ts +1 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/TableConfig.d.ts +2 -2
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +1 -1
- package/dist/TableConfig.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/validation.d.ts +15 -6
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +38 -11
- package/dist/validation.js.map +1 -1
- package/lib/DBSchemaBuilder.d.ts +4 -2
- package/lib/DBSchemaBuilder.d.ts.map +1 -1
- package/lib/DBSchemaBuilder.js +54 -47
- package/lib/DBSchemaBuilder.ts +95 -83
- package/lib/DboBuilder.d.ts +6 -6
- package/lib/DboBuilder.d.ts.map +1 -1
- package/lib/DboBuilder.ts +7 -7
- package/lib/Prostgles.d.ts +1 -1
- package/lib/Prostgles.d.ts.map +1 -1
- package/lib/TableConfig.d.ts +2 -2
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.js +1 -1
- package/lib/TableConfig.ts +3 -3
- package/lib/index.d.ts +1 -1
- package/lib/validation.d.ts +15 -6
- package/lib/validation.d.ts.map +1 -1
- package/lib/validation.js +38 -11
- package/lib/validation.ts +50 -17
- package/package.json +2 -2
- package/tests/client/PID.txt +1 -1
- package/tests/isomorphic_queries.js +1 -1
- package/tests/isomorphic_queries.ts +1 -1
- package/tests/server/DBoGenerated.d.ts +13 -7
- package/tests/server/index.js +18 -1
- package/tests/server/index.ts +19 -2
- package/tests/server/package-lock.json +3 -3
package/lib/TableConfig.ts
CHANGED
|
@@ -2,7 +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
|
+
import { getPGCheckConstraint, OneOfTypes, ValidationSchema } from "./validation";
|
|
6
6
|
|
|
7
7
|
type ColExtraInfo = {
|
|
8
8
|
min?: string | number;
|
|
@@ -87,7 +87,7 @@ type TextColumn = TextColDef & {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
type JSONBColumnDef = TextColDef & {
|
|
90
|
-
jsonbSchema: ValidationSchema
|
|
90
|
+
jsonbSchema: ValidationSchema | Pick<OneOfTypes, "oneOfTypes">;
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* If the new schema CHECK fails old rows the update old rows using this function
|
|
@@ -394,7 +394,7 @@ export default class TableConfigurator<LANG_IDS = { en: 1 }> {
|
|
|
394
394
|
|
|
395
395
|
} else if ("jsonbSchema" in colConf && colConf.jsonbSchema) {
|
|
396
396
|
|
|
397
|
-
return ` ${colNameEsc} ${getColDef(colConf, "JSONB")} CHECK(${getPGCheckConstraint({ schema: colConf.jsonbSchema, escapedFieldName: colNameEsc }, 0)})`;
|
|
397
|
+
return ` ${colNameEsc} ${getColDef(colConf, "JSONB")} CHECK(${getPGCheckConstraint({ schema: colConf.jsonbSchema, escapedFieldName: colNameEsc, nullable: !!colConf.nullable }, 0)})`;
|
|
398
398
|
|
|
399
399
|
} else {
|
|
400
400
|
throw "Unknown column config: " + JSON.stringify(colConf);
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ProstglesInitOptions } from "./Prostgles";
|
|
2
2
|
declare function prostgles<S = void>(params: ProstglesInitOptions<S>): Promise<{
|
|
3
|
-
db: import("./DboBuilder").DBHandlerServer
|
|
3
|
+
db: import("./DboBuilder").DBHandlerServer<import("./DboBuilder").TableHandlers>;
|
|
4
4
|
_db: import("./Prostgles").DB;
|
|
5
5
|
pgp: import("./Prostgles").PGP;
|
|
6
6
|
io?: any;
|
package/lib/validation.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
declare type
|
|
1
|
+
declare type BaseOptions = {
|
|
2
|
+
optional?: boolean;
|
|
3
|
+
nullable?: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare type SimpleType = BaseOptions & ({
|
|
2
6
|
type: "number" | "boolean" | "integer" | "string" | "number[]" | "boolean[]" | "integer[]" | "string[]" | ValidationSchema;
|
|
3
7
|
} | {
|
|
4
8
|
oneOf: readonly any[];
|
|
5
|
-
}
|
|
9
|
+
});
|
|
10
|
+
export declare type OneOfTypes = BaseOptions & {
|
|
6
11
|
oneOfTypes: readonly ValidationSchema[];
|
|
7
|
-
}) & {
|
|
8
|
-
optional?: boolean;
|
|
9
|
-
nullable?: boolean;
|
|
10
12
|
};
|
|
13
|
+
declare type FieldType = SimpleType | OneOfTypes;
|
|
11
14
|
declare type GetType<T extends FieldType> = T extends {
|
|
12
15
|
type: ValidationSchema;
|
|
13
16
|
} ? SchemaObject<T["type"]> : T extends {
|
|
@@ -43,8 +46,14 @@ export declare function validate<T>(obj: T, key: keyof T, validation: FieldType)
|
|
|
43
46
|
export declare function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional?: boolean): void;
|
|
44
47
|
export declare function getPGCheckConstraint(args: {
|
|
45
48
|
escapedFieldName: string;
|
|
46
|
-
schema: ValidationSchema;
|
|
49
|
+
schema: ValidationSchema | OneOfTypes;
|
|
50
|
+
nullable: boolean;
|
|
51
|
+
isRootQuery?: boolean;
|
|
47
52
|
}, depth: number): string;
|
|
53
|
+
declare type ColOpts = {
|
|
54
|
+
nullable?: boolean;
|
|
55
|
+
};
|
|
48
56
|
export declare function getSchemaTSTypes(schema: ValidationSchema, leading?: string, isOneOf?: boolean): string;
|
|
57
|
+
export declare function getJSONBSchemaTSTypes(schema: ValidationSchema | OneOfTypes, colOpts: ColOpts, leading?: string, isOneOf?: boolean): string;
|
|
49
58
|
export {};
|
|
50
59
|
//# sourceMappingURL=validation.d.ts.map
|
package/lib/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"AAGA,aAAK,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"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"}
|
package/lib/validation.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSchemaTSTypes = exports.getPGCheckConstraint = exports.validateSchema = exports.validate = void 0;
|
|
3
|
+
exports.getJSONBSchemaTSTypes = exports.getSchemaTSTypes = exports.getPGCheckConstraint = exports.validateSchema = exports.validate = void 0;
|
|
4
4
|
const prostgles_types_1 = require("prostgles-types");
|
|
5
5
|
const PubSubManager_1 = require("./PubSubManager");
|
|
6
6
|
/** tests */
|
|
@@ -53,14 +53,14 @@ 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 } = args;
|
|
56
|
+
const { schema: s, escapedFieldName, nullable } = args;
|
|
57
57
|
const jsToPGtypes = {
|
|
58
58
|
"integer": "::INTEGER",
|
|
59
59
|
"number": "::NUMERIC",
|
|
60
60
|
"boolean": "::BOOLEAN",
|
|
61
61
|
"string": "::TEXT"
|
|
62
62
|
};
|
|
63
|
-
const kChecks = (k) => {
|
|
63
|
+
const kChecks = (k, s) => {
|
|
64
64
|
const t = s[k];
|
|
65
65
|
const checks = [];
|
|
66
66
|
const valAsJson = `${escapedFieldName}->${(0, PubSubManager_1.asValue)(k)}`;
|
|
@@ -70,7 +70,7 @@ function getPGCheckConstraint(args, depth) {
|
|
|
70
70
|
if (t.optional)
|
|
71
71
|
checks.push(`${escapedFieldName} ? ${(0, PubSubManager_1.asValue)(k)} = FALSE`);
|
|
72
72
|
if ("oneOfTypes" in t) {
|
|
73
|
-
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType }, depth + 1)).join(" OR ")})`);
|
|
73
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable }, depth + 1)).join(" OR ")})`);
|
|
74
74
|
}
|
|
75
75
|
else if ("oneOf" in t) {
|
|
76
76
|
if (!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
@@ -96,7 +96,7 @@ function getPGCheckConstraint(args, depth) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
else {
|
|
99
|
-
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type }, depth + 1) + " )");
|
|
99
|
+
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable }, depth + 1) + " )");
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
const result = checks.join(" OR ");
|
|
@@ -104,25 +104,43 @@ function getPGCheckConstraint(args, depth) {
|
|
|
104
104
|
return `COALESCE(${result}, false)`;
|
|
105
105
|
return result;
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
const getSchemaChecks = (s) => (0, prostgles_types_1.getKeys)(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ");
|
|
108
|
+
let q = "";
|
|
109
|
+
if (isOneOfTypes(s)) {
|
|
110
|
+
q = s.oneOfTypes.map(t => `(${getSchemaChecks(t)})`).join(" OR ");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
q = getSchemaChecks(s);
|
|
114
|
+
}
|
|
115
|
+
return nullable ? ` ${escapedFieldName} IS NULL OR (${q})` : q;
|
|
108
116
|
}
|
|
109
117
|
exports.getPGCheckConstraint = getPGCheckConstraint;
|
|
118
|
+
const isOneOfTypes = (s) => {
|
|
119
|
+
if ("oneOfTypes" in s) {
|
|
120
|
+
if (!Array.isArray(s.oneOfTypes)) {
|
|
121
|
+
throw "Expecting oneOfTypes to be an array of types";
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
};
|
|
110
127
|
function getSchemaTSTypes(schema, leading = "", isOneOf = false) {
|
|
111
128
|
const getFieldType = (def) => {
|
|
129
|
+
const nullType = (def.nullable ? `null | ` : "");
|
|
112
130
|
if ("type" in def) {
|
|
113
131
|
if (typeof def.type === "string") {
|
|
114
132
|
const correctType = def.type.replace("integer", "number");
|
|
115
|
-
return correctType;
|
|
133
|
+
return nullType + correctType;
|
|
116
134
|
}
|
|
117
135
|
else {
|
|
118
|
-
return getSchemaTSTypes(def.type);
|
|
136
|
+
return nullType + getSchemaTSTypes(def.type);
|
|
119
137
|
}
|
|
120
138
|
}
|
|
121
139
|
else if ("oneOf" in def) {
|
|
122
|
-
return def.oneOf.map(v => (0, PubSubManager_1.asValue)(v)).join(" | ");
|
|
140
|
+
return nullType + def.oneOf.map(v => (0, PubSubManager_1.asValue)(v)).join(" | ");
|
|
123
141
|
}
|
|
124
142
|
else if ("oneOfTypes" in def) {
|
|
125
|
-
return def.oneOfTypes.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("");
|
|
143
|
+
return (def.nullable ? `\n${leading} | null` : "") + def.oneOfTypes.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("");
|
|
126
144
|
}
|
|
127
145
|
else
|
|
128
146
|
throw "Unexpected getSchemaTSTypes";
|
|
@@ -130,7 +148,7 @@ function getSchemaTSTypes(schema, leading = "", isOneOf = false) {
|
|
|
130
148
|
let spacing = isOneOf ? " " : " ";
|
|
131
149
|
let res = `${leading}{ \n` + (0, prostgles_types_1.getKeys)(schema).map(k => {
|
|
132
150
|
const def = schema[k];
|
|
133
|
-
return `${leading}${spacing}${k}${def.optional ? "?" : ""}:
|
|
151
|
+
return `${leading}${spacing}${k}${def.optional ? "?" : ""}: ` + getFieldType(def) + ";";
|
|
134
152
|
}).join("\n") + ` \n${leading}}${isOneOf ? "" : ";"}`;
|
|
135
153
|
/** Keep single line */
|
|
136
154
|
if (isOneOf)
|
|
@@ -138,3 +156,12 @@ function getSchemaTSTypes(schema, leading = "", isOneOf = false) {
|
|
|
138
156
|
return res;
|
|
139
157
|
}
|
|
140
158
|
exports.getSchemaTSTypes = getSchemaTSTypes;
|
|
159
|
+
function getJSONBSchemaTSTypes(schema, colOpts, leading = "", isOneOf = false) {
|
|
160
|
+
if (isOneOfTypes(schema)) {
|
|
161
|
+
return (colOpts.nullable ? `\n${leading} | null` : "") + schema.oneOfTypes.map(s => `\n${leading} | ` + getSchemaTSTypes(s, "", true)).join("");
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return (colOpts.nullable ? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.getJSONBSchemaTSTypes = getJSONBSchemaTSTypes;
|
package/lib/validation.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { asName, getKeys, isEmpty, isObject } from "prostgles-types";
|
|
2
2
|
import { asValue } from "./PubSubManager";
|
|
3
3
|
|
|
4
|
-
type
|
|
4
|
+
type BaseOptions = {
|
|
5
|
+
optional?: boolean;
|
|
6
|
+
nullable?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type SimpleType = BaseOptions & ({
|
|
5
10
|
type:
|
|
6
11
|
| "number" | "boolean" | "integer" | "string"
|
|
7
12
|
| "number[]" | "boolean[]" | "integer[]" | "string[]"
|
|
@@ -9,12 +14,12 @@ type FieldType = ({
|
|
|
9
14
|
|
|
10
15
|
} | {
|
|
11
16
|
oneOf: readonly any[];
|
|
12
|
-
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export type OneOfTypes = BaseOptions & {
|
|
13
20
|
oneOfTypes: readonly ValidationSchema[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
nullable?: boolean;
|
|
17
|
-
};
|
|
21
|
+
}
|
|
22
|
+
type FieldType = SimpleType | OneOfTypes;
|
|
18
23
|
|
|
19
24
|
type GetType<T extends FieldType> =
|
|
20
25
|
| T extends { type: ValidationSchema }? SchemaObject<T["type"]> :
|
|
@@ -82,8 +87,8 @@ export function validateSchema<S extends ValidationSchema>(schema: S, obj: Schem
|
|
|
82
87
|
getKeys(schema).forEach(k => validate(obj as any, k, schema[k]));
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema }, depth: number): string {
|
|
86
|
-
const { schema: s, escapedFieldName } = args;
|
|
90
|
+
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema | OneOfTypes, nullable: boolean; isRootQuery?: boolean; }, depth: number): string {
|
|
91
|
+
const { schema: s, escapedFieldName, nullable } = args;
|
|
87
92
|
|
|
88
93
|
const jsToPGtypes = {
|
|
89
94
|
"integer": "::INTEGER",
|
|
@@ -92,7 +97,7 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
92
97
|
"string": "::TEXT"
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
const kChecks = (k: string) => {
|
|
100
|
+
const kChecks = (k: string, s: ValidationSchema) => {
|
|
96
101
|
const t = s[k];
|
|
97
102
|
const checks: string[] = [];
|
|
98
103
|
const valAsJson = `${escapedFieldName}->${asValue(k)}`;
|
|
@@ -101,7 +106,7 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
101
106
|
if(t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
102
107
|
|
|
103
108
|
if("oneOfTypes" in t){
|
|
104
|
-
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType }, depth + 1)).join(" OR ")})`)
|
|
109
|
+
checks.push(`(${t.oneOfTypes.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable }, depth + 1)).join(" OR ")})`)
|
|
105
110
|
} else if("oneOf" in t){
|
|
106
111
|
if(!t.oneOf.length || t.oneOf.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
107
112
|
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: oneOf cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
@@ -122,7 +127,7 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
122
127
|
checks.push(`jsonb_typeof(${valAsJson}) = ${asValue(correctType)} `)
|
|
123
128
|
}
|
|
124
129
|
} else {
|
|
125
|
-
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type }, depth + 1) + " )")
|
|
130
|
+
checks.push("( " + getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable }, depth + 1) + " )")
|
|
126
131
|
}
|
|
127
132
|
}
|
|
128
133
|
const result = checks.join(" OR ")
|
|
@@ -130,22 +135,42 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
130
135
|
return result
|
|
131
136
|
}
|
|
132
137
|
|
|
133
|
-
|
|
138
|
+
const getSchemaChecks = (s: ValidationSchema) => getKeys(s).map(k => "(" + kChecks(k, s) + ")").join(" AND ")
|
|
139
|
+
|
|
140
|
+
let q = "";
|
|
141
|
+
if(isOneOfTypes(s)){
|
|
142
|
+
q = s.oneOfTypes.map(t => `(${getSchemaChecks(t)})` ).join(" OR ");
|
|
143
|
+
} else {
|
|
144
|
+
q = getSchemaChecks(s);
|
|
145
|
+
}
|
|
146
|
+
return nullable? ` ${escapedFieldName} IS NULL OR (${q})` : q
|
|
147
|
+
}
|
|
148
|
+
type ColOpts = { nullable?: boolean };
|
|
149
|
+
const isOneOfTypes = (s: ValidationSchema | OneOfTypes): s is OneOfTypes => {
|
|
150
|
+
|
|
151
|
+
if("oneOfTypes" in s){
|
|
152
|
+
if(!Array.isArray(s.oneOfTypes)){
|
|
153
|
+
throw "Expecting oneOfTypes to be an array of types";
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
134
158
|
}
|
|
135
159
|
|
|
136
160
|
export function getSchemaTSTypes(schema: ValidationSchema, leading = "", isOneOf = false): string {
|
|
137
161
|
const getFieldType = (def: FieldType) => {
|
|
162
|
+
const nullType = (def.nullable? `null | ` : "");
|
|
138
163
|
if("type" in def){
|
|
139
164
|
if(typeof def.type === "string"){
|
|
140
165
|
const correctType = def.type.replace("integer", "number")
|
|
141
|
-
return correctType
|
|
166
|
+
return nullType + correctType
|
|
142
167
|
} else {
|
|
143
|
-
return getSchemaTSTypes(def.type)
|
|
168
|
+
return nullType + getSchemaTSTypes(def.type)
|
|
144
169
|
}
|
|
145
170
|
} else if("oneOf" in def){
|
|
146
|
-
return def.oneOf.map(v => asValue(v)).join(" | ")
|
|
171
|
+
return nullType + def.oneOf.map(v => asValue(v)).join(" | ")
|
|
147
172
|
} else if("oneOfTypes" in def){
|
|
148
|
-
return def.oneOfTypes.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("")
|
|
173
|
+
return (def.nullable? `\n${leading} | null` : "") + def.oneOfTypes.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("")
|
|
149
174
|
} else throw "Unexpected getSchemaTSTypes"
|
|
150
175
|
}
|
|
151
176
|
|
|
@@ -153,10 +178,18 @@ export function getSchemaTSTypes(schema: ValidationSchema, leading = "", isOneOf
|
|
|
153
178
|
|
|
154
179
|
let res = `${leading}{ \n` + getKeys(schema).map(k => {
|
|
155
180
|
const def = schema[k];
|
|
156
|
-
return `${leading}${spacing}${k}${def.optional? "?" : ""}:
|
|
181
|
+
return `${leading}${spacing}${k}${def.optional? "?" : ""}: ` + getFieldType(def) + ";";
|
|
157
182
|
}).join("\n") + ` \n${leading}}${isOneOf? "" : ";"}`;
|
|
158
183
|
|
|
159
184
|
/** Keep single line */
|
|
160
185
|
if(isOneOf) res = res.split("\n").join("")
|
|
161
186
|
return res;
|
|
162
187
|
}
|
|
188
|
+
|
|
189
|
+
export function getJSONBSchemaTSTypes(schema: ValidationSchema | OneOfTypes, colOpts: ColOpts, leading = "", isOneOf = false): string {
|
|
190
|
+
if(isOneOfTypes(schema)){
|
|
191
|
+
return (colOpts.nullable? `\n${leading} | null` : "") + schema.oneOfTypes.map(s => `\n${leading} | ` + getSchemaTSTypes(s, "", true)).join("")
|
|
192
|
+
} else {
|
|
193
|
+
return (colOpts.nullable? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
194
|
+
}
|
|
195
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prostgles-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.237",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"aws-sdk": "^2.1168.0",
|
|
30
30
|
"bluebird": "^3.7.2",
|
|
31
31
|
"check-disk-space": "^3.3.1",
|
|
32
|
-
"file-type": "^17.1.
|
|
32
|
+
"file-type": "^17.1.4",
|
|
33
33
|
"pg-promise": "^10.11.1",
|
|
34
34
|
"prostgles-types": "^1.5.169",
|
|
35
35
|
"sharp": "^0.30.7"
|
package/tests/client/PID.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
77079
|
|
@@ -558,7 +558,7 @@ async function isomorphic(db) {
|
|
|
558
558
|
}
|
|
559
559
|
},
|
|
560
560
|
*/
|
|
561
|
-
const json = { a: true, arr: "2", arr1: 3, arr2: [1] };
|
|
561
|
+
const json = { a: true, arr: "2", arr1: 3, arr2: [1], arrStr: ["1123.string"] };
|
|
562
562
|
const fo = await db.tjson.insert({ json }, { returning: "*" });
|
|
563
563
|
// assert.deepStrictEqual(fo.json, json);
|
|
564
564
|
await db.tjson.insert({ json: { ...json, o: { o1: 2, o2: true } } });
|
|
@@ -641,7 +641,7 @@ export default async function isomorphic(db: Partial<DBHandlerServer> | Partial<
|
|
|
641
641
|
},
|
|
642
642
|
*/
|
|
643
643
|
|
|
644
|
-
const json = {a: true, arr: "2", arr1: 3, arr2: [1] }
|
|
644
|
+
const json = {a: true, arr: "2", arr1: 3, arr2: [1], arrStr: ["1123.string"] }
|
|
645
645
|
const fo = await db.tjson.insert({ json }, { returning: "*"});
|
|
646
646
|
// assert.deepStrictEqual(fo.json, json);
|
|
647
647
|
await db.tjson.insert({ json: {...json, o: { o1: 2, o2: true } } })
|
|
@@ -336,14 +336,20 @@ export type DBSchemaGenerated = {
|
|
|
336
336
|
delete: true;
|
|
337
337
|
columns: {
|
|
338
338
|
json: {
|
|
339
|
-
a:
|
|
340
|
-
arr:
|
|
341
|
-
arr1:
|
|
342
|
-
arr2:
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
|
339
|
+
a: boolean;
|
|
340
|
+
arr: '1' | '2' | '3';
|
|
341
|
+
arr1: 1 | 2 | 3;
|
|
342
|
+
arr2: number[];
|
|
343
|
+
arrStr?: null | string[];
|
|
344
|
+
o?:
|
|
345
|
+
| null
|
|
346
|
+
| { o1: number; }
|
|
347
|
+
| { o2: boolean; };
|
|
346
348
|
};
|
|
349
|
+
jsonOneOf?:
|
|
350
|
+
| null
|
|
351
|
+
| { command: 'a'; }
|
|
352
|
+
| { command: 'b'; option: number[]; }
|
|
347
353
|
};
|
|
348
354
|
};
|
|
349
355
|
tr1: {
|
package/tests/server/index.js
CHANGED
|
@@ -72,7 +72,24 @@ function dd() {
|
|
|
72
72
|
arr: { oneOf: ["1", "2", "3"] },
|
|
73
73
|
arr1: { oneOf: [1, 2, 3] },
|
|
74
74
|
arr2: { type: "integer[]" },
|
|
75
|
-
|
|
75
|
+
arrStr: { type: "string[]", optional: true, nullable: true },
|
|
76
|
+
o: { oneOfTypes: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true, nullable: true },
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
jsonOneOf: { nullable: true, jsonbSchema: {
|
|
80
|
+
oneOfTypes: [
|
|
81
|
+
{ command: { oneOf: ["a"] } },
|
|
82
|
+
{
|
|
83
|
+
command: { oneOf: ["b"] },
|
|
84
|
+
option: { type: "integer[]" }
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
// a: { type: "boolean" },
|
|
88
|
+
// arr: { oneOf: ["1", "2", "3"] },
|
|
89
|
+
// arr1: { oneOf: [1, 2, 3] },
|
|
90
|
+
// arr2: { type: "integer[]" },
|
|
91
|
+
// arrStr: { type: "string[]", optional: true },
|
|
92
|
+
// o: { oneOfTypes: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true },
|
|
76
93
|
}
|
|
77
94
|
}
|
|
78
95
|
}
|
package/tests/server/index.ts
CHANGED
|
@@ -93,9 +93,26 @@ function dd(){
|
|
|
93
93
|
arr: { oneOf: ["1", "2", "3"] },
|
|
94
94
|
arr1: { oneOf: [1, 2, 3] },
|
|
95
95
|
arr2: { type: "integer[]" },
|
|
96
|
-
|
|
96
|
+
arrStr: { type: "string[]", optional: true, nullable: true },
|
|
97
|
+
o: { oneOfTypes: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true, nullable: true },
|
|
97
98
|
}
|
|
98
|
-
}
|
|
99
|
+
},
|
|
100
|
+
jsonOneOf: { nullable: true, jsonbSchema: {
|
|
101
|
+
oneOfTypes: [
|
|
102
|
+
{ command: { oneOf: ["a"] } },
|
|
103
|
+
{
|
|
104
|
+
command: { oneOf: ["b"] },
|
|
105
|
+
option: { type: "integer[]" }
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
// a: { type: "boolean" },
|
|
109
|
+
// arr: { oneOf: ["1", "2", "3"] },
|
|
110
|
+
// arr1: { oneOf: [1, 2, 3] },
|
|
111
|
+
// arr2: { type: "integer[]" },
|
|
112
|
+
// arrStr: { type: "string[]", optional: true },
|
|
113
|
+
// o: { oneOfTypes: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true },
|
|
114
|
+
}
|
|
115
|
+
}
|
|
99
116
|
}
|
|
100
117
|
},
|
|
101
118
|
lookup_col1: {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"../..": {
|
|
23
23
|
"name": "prostgles-server",
|
|
24
|
-
"version": "2.0.
|
|
24
|
+
"version": "2.0.236",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@aws-sdk/client-s3": "^3.121.0",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"aws-sdk": "^2.1168.0",
|
|
30
30
|
"bluebird": "^3.7.2",
|
|
31
31
|
"check-disk-space": "^3.3.1",
|
|
32
|
-
"file-type": "^17.1.
|
|
32
|
+
"file-type": "^17.1.4",
|
|
33
33
|
"pg-promise": "^10.11.1",
|
|
34
34
|
"prostgles-types": "^1.5.169",
|
|
35
35
|
"sharp": "^0.30.7"
|
|
@@ -1373,7 +1373,7 @@
|
|
|
1373
1373
|
"aws-sdk": "^2.1168.0",
|
|
1374
1374
|
"bluebird": "^3.7.2",
|
|
1375
1375
|
"check-disk-space": "^3.3.1",
|
|
1376
|
-
"file-type": "^17.1.
|
|
1376
|
+
"file-type": "^17.1.4",
|
|
1377
1377
|
"pg-promise": "^10.11.1",
|
|
1378
1378
|
"prostgles-types": "^1.5.169",
|
|
1379
1379
|
"sharp": "^0.30.7",
|