prostgles-server 2.0.333 → 2.0.334
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.js +4 -4
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/TableConfig.d.ts +21 -10
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js +5 -5
- package/dist/TableConfig.js.map +1 -1
- package/dist/validation.d.ts +10 -10
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +29 -27
- package/dist/validation.js.map +1 -1
- package/lib/DBSchemaBuilder.js +4 -4
- package/lib/DBSchemaBuilder.ts +3 -3
- package/lib/TableConfig.d.ts +21 -10
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.js +5 -5
- package/lib/TableConfig.ts +25 -15
- package/lib/validation.d.ts +10 -10
- package/lib/validation.d.ts.map +1 -1
- package/lib/validation.js +29 -27
- package/lib/validation.ts +113 -111
- package/package.json +1 -1
- package/tests/client/PID.txt +1 -1
- package/tests/isomorphic_queries.js +3 -3
- package/tests/isomorphic_queries.ts +3 -3
- package/tests/server/index.js +10 -10
- package/tests/server/index.ts +10 -10
- package/tests/server/package-lock.json +1 -1
- package/tests/server/server.ts +2 -2
package/lib/validation.ts
CHANGED
|
@@ -10,53 +10,55 @@ type BaseOptions = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
type SimpleType = BaseOptions & ({
|
|
13
|
-
type:
|
|
13
|
+
type:
|
|
14
14
|
| "number" | "boolean" | "integer" | "string" | "any"
|
|
15
15
|
| "number[]" | "boolean[]" | "integer[]" | "string[]" | "any[]"
|
|
16
16
|
| ValidationSchema;
|
|
17
17
|
|
|
18
18
|
} | {
|
|
19
|
-
|
|
19
|
+
enum: readonly any[];
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
export type
|
|
23
|
-
|
|
22
|
+
export type OneOf = BaseOptions & {
|
|
23
|
+
oneOf: readonly ValidationSchema[];
|
|
24
24
|
}
|
|
25
|
-
type FieldType = SimpleType |
|
|
26
|
-
|
|
27
|
-
type GetType<T extends FieldType> =
|
|
28
|
-
| T extends { type: ValidationSchema }? SchemaObject<T["type"]> :
|
|
29
|
-
| T extends { type: "number" }? number:
|
|
30
|
-
| T extends { type: "boolean" }? boolean:
|
|
31
|
-
| T extends { type: "integer" }? number:
|
|
32
|
-
| T extends { type: "string" }? string:
|
|
33
|
-
| T extends { type: "any" }? any:
|
|
34
|
-
| T extends { type: "number[]" }? number[]:
|
|
35
|
-
| T extends { type: "boolean[]" }? boolean[]:
|
|
36
|
-
| T extends { type: "integer[]" }? number[]:
|
|
37
|
-
| T extends { type: "string[]" }? string[]:
|
|
38
|
-
| T extends { type: "any[]" }? any[]:
|
|
39
|
-
| T extends {
|
|
40
|
-
|
|
41
|
-
/** This needs fixing */
|
|
42
|
-
| T extends {
|
|
43
|
-
any;
|
|
25
|
+
type FieldType = SimpleType | OneOf;
|
|
26
|
+
|
|
27
|
+
type GetType<T extends FieldType> =
|
|
28
|
+
| T extends { type: ValidationSchema } ? SchemaObject<T["type"]> :
|
|
29
|
+
| T extends { type: "number" } ? number :
|
|
30
|
+
| T extends { type: "boolean" } ? boolean :
|
|
31
|
+
| T extends { type: "integer" } ? number :
|
|
32
|
+
| T extends { type: "string" } ? string :
|
|
33
|
+
| T extends { type: "any" } ? any :
|
|
34
|
+
| T extends { type: "number[]" } ? number[] :
|
|
35
|
+
| T extends { type: "boolean[]" } ? boolean[] :
|
|
36
|
+
| T extends { type: "integer[]" } ? number[] :
|
|
37
|
+
| T extends { type: "string[]" } ? string[] :
|
|
38
|
+
| T extends { type: "any[]" } ? any[] :
|
|
39
|
+
| T extends { enum: readonly any[] } ? T["enum"][number] :
|
|
40
|
+
|
|
41
|
+
/** This needs fixing */
|
|
42
|
+
| T extends { oneOf: readonly ValidationSchema[] } ? SchemaObject<T["oneOf"][number]> :
|
|
43
|
+
any;
|
|
44
44
|
|
|
45
45
|
export type ValidationSchema = Record<string, FieldType>;
|
|
46
46
|
export type SchemaObject<S extends ValidationSchema> = ({
|
|
47
|
-
[K in keyof S as S[K]["optional"] extends true? K : never]?: GetType<S[K]>
|
|
47
|
+
[K in keyof S as S[K]["optional"] extends true ? K : never]?: GetType<S[K]>
|
|
48
48
|
} & {
|
|
49
|
-
|
|
50
|
-
});
|
|
49
|
+
[K in keyof S as S[K]["optional"] extends true ? never : K]: GetType<S[K]>
|
|
50
|
+
});
|
|
51
51
|
|
|
52
52
|
/** tests */
|
|
53
53
|
const s = {
|
|
54
54
|
a: { type: "boolean" },
|
|
55
55
|
c: { type: { c1: { type: "string" } } },
|
|
56
|
-
o: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
o: {
|
|
57
|
+
oneOf: [
|
|
58
|
+
{ z: { type: "integer" } },
|
|
59
|
+
{ z1: { type: "integer" } }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
60
62
|
} as const;
|
|
61
63
|
const ss: SchemaObject<typeof s> = {
|
|
62
64
|
a: true,
|
|
@@ -69,30 +71,30 @@ const ss: SchemaObject<typeof s> = {
|
|
|
69
71
|
export function validate<T>(obj: T, key: keyof T, validation: FieldType): boolean {
|
|
70
72
|
let err = `The provided value for ${JSON.stringify(key)} is of invalid type. Expecting `;
|
|
71
73
|
const val = obj[key];
|
|
72
|
-
if("type" in validation && validation.type){
|
|
73
|
-
if(typeof validation.type !== "string"){
|
|
74
|
+
if ("type" in validation && validation.type) {
|
|
75
|
+
if (typeof validation.type !== "string") {
|
|
74
76
|
getKeys(validation.type).forEach(subKey => {
|
|
75
77
|
validate(val, subKey as any, (validation.type as ValidationSchema)[subKey])
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
err += validation.type;
|
|
79
|
-
if(validation.type === "boolean" && typeof val !== validation.type) throw new Error(err)
|
|
80
|
-
if(validation.type === "string" && typeof val !== validation.type) throw new Error(err)
|
|
81
|
-
if(validation.type === "number" && !Number.isFinite(val)) throw new Error(err)
|
|
82
|
-
if(validation.type === "integer" && !Number.isInteger(val)) throw new Error(err)
|
|
83
|
-
} else if("
|
|
84
|
-
err += `on of: ${validation.
|
|
85
|
-
if(!validation.
|
|
81
|
+
if (validation.type === "boolean" && typeof val !== validation.type) throw new Error(err)
|
|
82
|
+
if (validation.type === "string" && typeof val !== validation.type) throw new Error(err)
|
|
83
|
+
if (validation.type === "number" && !Number.isFinite(val)) throw new Error(err)
|
|
84
|
+
if (validation.type === "integer" && !Number.isInteger(val)) throw new Error(err)
|
|
85
|
+
} else if ("enum" in validation && validation.enum) {
|
|
86
|
+
err += `on of: ${validation.enum}`;
|
|
87
|
+
if (!validation.enum.includes(val)) throw new Error(err)
|
|
86
88
|
}
|
|
87
89
|
return true
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
export function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional = false){
|
|
91
|
-
if((!schema || isEmpty(schema)) && !optional) throw new Error(`Expecting ${objName} to be defined`);
|
|
92
|
+
export function validateSchema<S extends ValidationSchema>(schema: S, obj: SchemaObject<S>, objName?: string, optional = false) {
|
|
93
|
+
if ((!schema || isEmpty(schema)) && !optional) throw new Error(`Expecting ${objName} to be defined`);
|
|
92
94
|
getKeys(schema).forEach(k => validate(obj as any, k, schema[k]));
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema |
|
|
97
|
+
export function getPGCheckConstraint(args: { escapedFieldName: string; schema: ValidationSchema | OneOf, nullable: boolean; isRootQuery?: boolean; optional?: boolean; }, depth: number): string {
|
|
96
98
|
const { schema: s, escapedFieldName, nullable, optional, isRootQuery } = args;
|
|
97
99
|
|
|
98
100
|
const jsToPGtypes = {
|
|
@@ -108,40 +110,40 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
108
110
|
const checks: string[] = [];
|
|
109
111
|
const valAsJson = `${escapedFieldName}->${asValue(k)}`;
|
|
110
112
|
const valAsText = `${escapedFieldName}->>${asValue(k)}`;
|
|
111
|
-
if(t.nullable) checks.push(`${valAsJson} IS NULL`);
|
|
112
|
-
if(t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
113
|
-
|
|
114
|
-
if("
|
|
115
|
-
checks.push(`(${t.
|
|
116
|
-
} else if("
|
|
117
|
-
if(!t.
|
|
118
|
-
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}:
|
|
113
|
+
if (t.nullable) checks.push(`${valAsJson} IS NULL`);
|
|
114
|
+
if (t.optional) checks.push(`${escapedFieldName} ? ${asValue(k)} = FALSE`);
|
|
115
|
+
|
|
116
|
+
if ("oneOf" in t) {
|
|
117
|
+
checks.push(`(${t.oneOf.map(subType => getPGCheckConstraint({ escapedFieldName: valAsJson, schema: subType, nullable, optional: t.optional }, depth + 1)).join(" OR ")})`)
|
|
118
|
+
} else if ("enum" in t) {
|
|
119
|
+
if (!t.enum.length || t.enum.some(v => v === undefined || !["number", "boolean", "string", null].includes(typeof v))) {
|
|
120
|
+
throw new Error(`Invalid ValidationSchema for property: ${k} of field ${escapedFieldName}: enum cannot be empty AND can only contain: numbers, text, boolean, null`);
|
|
119
121
|
}
|
|
120
|
-
const oneOfHasNull = t.
|
|
121
|
-
if(oneOfHasNull) checks.push(`${valAsText} IS NULL`);
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
const oneOfHasNull = t.enum.includes(null);
|
|
123
|
+
if (oneOfHasNull) checks.push(`${valAsText} IS NULL`);
|
|
124
|
+
const _enum = t.enum.filter(o => o !== null);
|
|
125
|
+
_enum.forEach(o => {
|
|
124
126
|
checks.push(`(${valAsText})${(jsToPGtypes as any)[typeof o]} = ${asValue(o)}`);
|
|
125
127
|
})
|
|
126
|
-
} else if("type" in t){
|
|
127
|
-
if(typeof t.type === "string") {
|
|
128
|
-
if(t.type.endsWith("[]")){
|
|
128
|
+
} else if ("type" in t) {
|
|
129
|
+
if (typeof t.type === "string") {
|
|
130
|
+
if (t.type.endsWith("[]")) {
|
|
129
131
|
const correctType = t.type.slice(0, -2);
|
|
130
|
-
let elemCheck = correctType === "any"? "" : `AND ('{' || right(left(${valAsText},-1),-1) || '}')${jsToPGtypes[correctType as keyof typeof jsToPGtypes]}[] IS NOT NULL`
|
|
132
|
+
let elemCheck = correctType === "any" ? "" : `AND ('{' || right(left(${valAsText},-1),-1) || '}')${jsToPGtypes[correctType as keyof typeof jsToPGtypes]}[] IS NOT NULL`
|
|
131
133
|
checks.push(`jsonb_typeof(${valAsJson}) = 'array' ${elemCheck}`)
|
|
132
134
|
} else {
|
|
133
135
|
const correctType = t.type.replace("integer", "number");
|
|
134
|
-
if(correctType !== "any"){
|
|
136
|
+
if (correctType !== "any") {
|
|
135
137
|
checks.push(`jsonb_typeof(${valAsJson}) = ${asValue(correctType)} `)
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
140
|
} else {
|
|
139
141
|
const check = getPGCheckConstraint({ escapedFieldName: valAsJson, schema: t.type, nullable: !!t.nullable, optional: !!t.optional }, depth + 1).trim();
|
|
140
|
-
if(check) checks.push(`(${check})`)
|
|
142
|
+
if (check) checks.push(`(${check})`)
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
145
|
const result = checks.join(" OR ")
|
|
144
|
-
if(!depth) return `COALESCE(${result}, false)`
|
|
146
|
+
if (!depth) return `COALESCE(${result}, false)`
|
|
145
147
|
return result
|
|
146
148
|
}
|
|
147
149
|
|
|
@@ -149,21 +151,21 @@ export function getPGCheckConstraint(args: { escapedFieldName: string; schema: V
|
|
|
149
151
|
|
|
150
152
|
const checks: string[] = [];
|
|
151
153
|
let typeChecks = "";
|
|
152
|
-
if(isOneOfTypes(s)){
|
|
153
|
-
typeChecks = s.
|
|
154
|
+
if (isOneOfTypes(s)) {
|
|
155
|
+
typeChecks = s.oneOf.map(t => `(${getSchemaChecks(t)})`).join(" OR ");
|
|
154
156
|
} else {
|
|
155
157
|
typeChecks = getSchemaChecks(s);
|
|
156
158
|
}
|
|
157
|
-
if(nullable) checks.push(` ${escapedFieldName} IS NULL `);
|
|
158
|
-
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks? ` AND (${typeChecks})` : ""
|
|
159
|
+
if (nullable) checks.push(` ${escapedFieldName} IS NULL `);
|
|
160
|
+
checks.push(`jsonb_typeof(${escapedFieldName}) = 'object' ${typeChecks ? ` AND (${typeChecks})` : ""}`);
|
|
159
161
|
return checks.join(" OR ");
|
|
160
162
|
}
|
|
161
163
|
type ColOpts = { nullable?: boolean };
|
|
162
|
-
const isOneOfTypes = (s: ValidationSchema |
|
|
164
|
+
const isOneOfTypes = (s: ValidationSchema | OneOf): s is OneOf => {
|
|
163
165
|
|
|
164
|
-
if("
|
|
165
|
-
if(!Array.isArray(s.
|
|
166
|
-
throw "Expecting
|
|
166
|
+
if ("oneOf" in s) {
|
|
167
|
+
if (!Array.isArray(s.oneOf)) {
|
|
168
|
+
throw "Expecting oneOf to be an array of types";
|
|
167
169
|
}
|
|
168
170
|
return true;
|
|
169
171
|
}
|
|
@@ -172,71 +174,71 @@ const isOneOfTypes = (s: ValidationSchema | OneOfTypes): s is OneOfTypes => {
|
|
|
172
174
|
|
|
173
175
|
export function getSchemaTSTypes(schema: ValidationSchema, leading = "", isOneOf = false): string {
|
|
174
176
|
const getFieldType = (def: FieldType) => {
|
|
175
|
-
const nullType = (def.nullable? `null | ` : "");
|
|
176
|
-
if("type" in def){
|
|
177
|
-
if(typeof def.type === "string"){
|
|
177
|
+
const nullType = (def.nullable ? `null | ` : "");
|
|
178
|
+
if ("type" in def) {
|
|
179
|
+
if (typeof def.type === "string") {
|
|
178
180
|
const correctType = def.type.replace("integer", "number")
|
|
179
181
|
return nullType + correctType
|
|
180
182
|
} else {
|
|
181
183
|
return nullType + getSchemaTSTypes(def.type, "", true)
|
|
182
184
|
}
|
|
183
|
-
} else if("
|
|
184
|
-
return nullType + def.
|
|
185
|
-
} else if("
|
|
186
|
-
return (def.nullable? `\n${leading} | null` : "") + def.
|
|
185
|
+
} else if ("enum" in def) {
|
|
186
|
+
return nullType + def.enum.map(v => asValue(v)).join(" | ")
|
|
187
|
+
} else if ("oneOf" in def) {
|
|
188
|
+
return (def.nullable ? `\n${leading} | null` : "") + def.oneOf.map(v => `\n${leading} | ` + getSchemaTSTypes(v, "", true)).join("")
|
|
187
189
|
} else throw "Unexpected getSchemaTSTypes"
|
|
188
190
|
}
|
|
189
191
|
|
|
190
|
-
let spacing = isOneOf? " " : " ";
|
|
192
|
+
let spacing = isOneOf ? " " : " ";
|
|
191
193
|
|
|
192
194
|
let res = `${leading}{ \n` + getKeys(schema).map(k => {
|
|
193
195
|
const def = schema[k];
|
|
194
|
-
return `${leading}${spacing}${k}${def.optional? "?" : ""}: ` + getFieldType(def) + ";";
|
|
195
|
-
}).join("\n") + ` \n${leading}}${isOneOf? "" : ";"}`;
|
|
196
|
-
|
|
196
|
+
return `${leading}${spacing}${k}${def.optional ? "?" : ""}: ` + getFieldType(def) + ";";
|
|
197
|
+
}).join("\n") + ` \n${leading}}${isOneOf ? "" : ";"}`;
|
|
198
|
+
|
|
197
199
|
/** Keep single line */
|
|
198
|
-
if(isOneOf) res = res.split("\n").join("")
|
|
200
|
+
if (isOneOf) res = res.split("\n").join("")
|
|
199
201
|
return res;
|
|
200
202
|
}
|
|
201
203
|
|
|
202
|
-
export function getJSONBSchemaTSTypes(schema: ValidationSchema |
|
|
203
|
-
if(isOneOfTypes(schema)){
|
|
204
|
-
return (colOpts.nullable? `\n${leading} | null` : "") + schema.
|
|
204
|
+
export function getJSONBSchemaTSTypes(schema: ValidationSchema | OneOf, colOpts: ColOpts, leading = "", isOneOf = false): string {
|
|
205
|
+
if (isOneOfTypes(schema)) {
|
|
206
|
+
return (colOpts.nullable ? `\n${leading} | null` : "") + schema.oneOf.map(s => `\n${leading} | ` + getSchemaTSTypes(s, "", true)).join("")
|
|
205
207
|
} else {
|
|
206
|
-
return (colOpts.nullable? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
208
|
+
return (colOpts.nullable ? `null | ` : "") + getSchemaTSTypes(schema, leading, isOneOf);
|
|
207
209
|
}
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
// type JSONSchema =
|
|
211
213
|
const getJSONSchemaObject = <T extends ValidationSchema>(objDef: T): Record<keyof T, any> => {
|
|
212
214
|
const resultType: Record<keyof T, any> = {} as any;
|
|
213
|
-
|
|
215
|
+
|
|
214
216
|
return getKeys(objDef).reduce((a, k) => {
|
|
215
217
|
const itemSchema: FieldType = objDef[k];
|
|
216
218
|
const { nullable, optional, description, title } = itemSchema;
|
|
217
219
|
let item = {} as any;
|
|
218
220
|
|
|
219
|
-
if("type" in itemSchema){
|
|
221
|
+
if ("type" in itemSchema) {
|
|
220
222
|
const { type } = itemSchema;
|
|
221
223
|
/**
|
|
222
224
|
* Is primitive or any
|
|
223
225
|
*/
|
|
224
|
-
if(typeof type === "string"){
|
|
225
|
-
const arrayType = type.endsWith("[]")? type.slice(0, -2) : undefined;
|
|
226
|
-
if(arrayType){
|
|
226
|
+
if (typeof type === "string") {
|
|
227
|
+
const arrayType = type.endsWith("[]") ? type.slice(0, -2) : undefined;
|
|
228
|
+
if (arrayType) {
|
|
227
229
|
item = {
|
|
228
230
|
type: "array",
|
|
229
|
-
items: { type: arrayType === "any"? {} : arrayType }
|
|
231
|
+
items: { type: arrayType === "any" ? {} : arrayType }
|
|
230
232
|
}
|
|
231
233
|
} else {
|
|
232
234
|
item = {
|
|
233
|
-
type: type === "any"? {} : type
|
|
235
|
+
type: type === "any" ? {} : type
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
238
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Is object
|
|
241
|
+
*/
|
|
240
242
|
} else {
|
|
241
243
|
item = {
|
|
242
244
|
type: "object",
|
|
@@ -245,33 +247,33 @@ const getJSONSchemaObject = <T extends ValidationSchema>(objDef: T): Record<keyo
|
|
|
245
247
|
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
} else if("
|
|
249
|
-
item = {
|
|
250
|
-
type: typeof itemSchema.
|
|
251
|
-
"enum": itemSchema.
|
|
250
|
+
} else if ("enum" in itemSchema) {
|
|
251
|
+
item = {
|
|
252
|
+
type: typeof itemSchema.enum[0]!,
|
|
253
|
+
"enum": itemSchema.enum //.concat(nullable? [null] : [])
|
|
252
254
|
}
|
|
253
|
-
} else if("
|
|
255
|
+
} else if ("oneOf" in itemSchema) {
|
|
254
256
|
item = {
|
|
255
|
-
oneOf: itemSchema.
|
|
257
|
+
oneOf: itemSchema.oneOf.map(t => getJSONSchemaObject(t))
|
|
256
258
|
}
|
|
257
259
|
} else {
|
|
258
|
-
throw new Error("Unexpected jsonbSchema itemSchema" + JSON.stringify({itemSchema, objDef}, null, 2))
|
|
260
|
+
throw new Error("Unexpected jsonbSchema itemSchema" + JSON.stringify({ itemSchema, objDef }, null, 2))
|
|
259
261
|
}
|
|
260
262
|
|
|
261
|
-
if(nullable){
|
|
263
|
+
if (nullable) {
|
|
262
264
|
const nullDef = { type: "null" }
|
|
263
|
-
if(item.oneOf) item.oneOf.push(nullDef)
|
|
265
|
+
if (item.oneOf) item.oneOf.push(nullDef)
|
|
264
266
|
else item = {
|
|
265
267
|
oneOf: [item, nullDef]
|
|
266
268
|
}
|
|
267
269
|
}
|
|
268
270
|
|
|
269
|
-
return {
|
|
271
|
+
return {
|
|
270
272
|
...a,
|
|
271
273
|
[k]: {
|
|
272
274
|
...item,
|
|
273
275
|
required: !optional,
|
|
274
|
-
description,
|
|
276
|
+
description,
|
|
275
277
|
title,
|
|
276
278
|
}
|
|
277
279
|
}
|
|
@@ -281,11 +283,11 @@ const getJSONSchemaObject = <T extends ValidationSchema>(objDef: T): Record<keyo
|
|
|
281
283
|
export function getJSONBSchemaAsJSONSchema(tableName: string, colName: string, columnConfig: BaseColumn<{ en: 1 }> & JSONBColumnDef): AnyObject {
|
|
282
284
|
|
|
283
285
|
const schema = columnConfig.jsonbSchema;
|
|
284
|
-
|
|
285
|
-
let jSchema = getJSONSchemaObject({
|
|
286
|
-
|
|
287
|
-
{ type: schema as ValidationSchema }
|
|
288
|
-
|
|
286
|
+
|
|
287
|
+
let jSchema = getJSONSchemaObject({
|
|
288
|
+
field1: isOneOfTypes(schema) ? schema as OneOf :
|
|
289
|
+
{ type: schema as ValidationSchema }
|
|
290
|
+
}).field1;
|
|
289
291
|
|
|
290
292
|
return {
|
|
291
293
|
"$id": `${tableName}.${colName}`,
|
package/package.json
CHANGED
package/tests/client/PID.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
77759
|
|
@@ -573,10 +573,10 @@ async function isomorphic(db) {
|
|
|
573
573
|
tjson: {
|
|
574
574
|
json: { jsonbSchema: {
|
|
575
575
|
a: { type: "boolean" },
|
|
576
|
-
arr: {
|
|
577
|
-
arr1: {
|
|
576
|
+
arr: { enum: ["1", "2", "3"] },
|
|
577
|
+
arr1: { enum: [1, 2, 3] },
|
|
578
578
|
arr2: { type: "integer[]" },
|
|
579
|
-
o: {
|
|
579
|
+
o: { oneOf: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true },
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
582
|
},
|
|
@@ -656,10 +656,10 @@ export default async function isomorphic(db: Required<DBHandlerServer> | Require
|
|
|
656
656
|
tjson: {
|
|
657
657
|
json: { jsonbSchema: {
|
|
658
658
|
a: { type: "boolean" },
|
|
659
|
-
arr: {
|
|
660
|
-
arr1: {
|
|
659
|
+
arr: { enum: ["1", "2", "3"] },
|
|
660
|
+
arr1: { enum: [1, 2, 3] },
|
|
661
661
|
arr2: { type: "integer[]" },
|
|
662
|
-
o: {
|
|
662
|
+
o: { oneOf: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true },
|
|
663
663
|
}
|
|
664
664
|
}
|
|
665
665
|
},
|
package/tests/server/index.js
CHANGED
|
@@ -89,11 +89,11 @@ function dd() {
|
|
|
89
89
|
columns: {
|
|
90
90
|
id: { sqlDefinition: `SERIAL PRIMARY KEY ` },
|
|
91
91
|
email: { sqlDefinition: `TEXT NOT NULL` },
|
|
92
|
-
status: {
|
|
92
|
+
status: { enum: ["active", "disabled", "pending"] },
|
|
93
93
|
preferences: { defaultValue: "{}",
|
|
94
94
|
jsonbSchema: {
|
|
95
95
|
showIntro: { type: "boolean", optional: true },
|
|
96
|
-
theme: {
|
|
96
|
+
theme: { enum: ["light", "dark", "auto"], optional: true },
|
|
97
97
|
others: { type: "any[]" }
|
|
98
98
|
}
|
|
99
99
|
},
|
|
@@ -104,18 +104,18 @@ function dd() {
|
|
|
104
104
|
columns: {
|
|
105
105
|
json: { jsonbSchema: {
|
|
106
106
|
a: { type: "boolean" },
|
|
107
|
-
arr: {
|
|
108
|
-
arr1: {
|
|
107
|
+
arr: { enum: ["1", "2", "3"] },
|
|
108
|
+
arr1: { enum: [1, 2, 3] },
|
|
109
109
|
arr2: { type: "integer[]" },
|
|
110
110
|
arrStr: { type: "string[]", optional: true, nullable: true },
|
|
111
|
-
o: {
|
|
111
|
+
o: { oneOf: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true, nullable: true },
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
|
-
colOneOf: {
|
|
114
|
+
colOneOf: { enum: ["a", "b", "c"] },
|
|
115
115
|
status: {
|
|
116
116
|
nullable: true,
|
|
117
117
|
jsonbSchema: {
|
|
118
|
-
|
|
118
|
+
oneOf: [
|
|
119
119
|
{ ok: { type: "string" } },
|
|
120
120
|
{ err: { type: "string" } },
|
|
121
121
|
{
|
|
@@ -131,10 +131,10 @@ function dd() {
|
|
|
131
131
|
jsonOneOf: {
|
|
132
132
|
nullable: true,
|
|
133
133
|
jsonbSchema: {
|
|
134
|
-
|
|
135
|
-
{ command: {
|
|
134
|
+
oneOf: [
|
|
135
|
+
{ command: { enum: ["a"] } },
|
|
136
136
|
{
|
|
137
|
-
command: {
|
|
137
|
+
command: { enum: ["b"] },
|
|
138
138
|
option: { type: "integer[]" }
|
|
139
139
|
}
|
|
140
140
|
]
|
package/tests/server/index.ts
CHANGED
|
@@ -110,11 +110,11 @@ function dd(){
|
|
|
110
110
|
columns: {
|
|
111
111
|
id: { sqlDefinition: `SERIAL PRIMARY KEY ` },
|
|
112
112
|
email: { sqlDefinition: `TEXT NOT NULL` },
|
|
113
|
-
status: {
|
|
113
|
+
status: { enum: ["active", "disabled", "pending"] },
|
|
114
114
|
preferences: { defaultValue: "{}",
|
|
115
115
|
jsonbSchema: {
|
|
116
116
|
showIntro: { type: "boolean", optional: true },
|
|
117
|
-
theme: {
|
|
117
|
+
theme: { enum: ["light", "dark", "auto"], optional: true },
|
|
118
118
|
others: { type: "any[]" }
|
|
119
119
|
}
|
|
120
120
|
},
|
|
@@ -125,18 +125,18 @@ function dd(){
|
|
|
125
125
|
columns: {
|
|
126
126
|
json: { jsonbSchema: {
|
|
127
127
|
a: { type: "boolean" },
|
|
128
|
-
arr: {
|
|
129
|
-
arr1: {
|
|
128
|
+
arr: { enum: ["1", "2", "3"] },
|
|
129
|
+
arr1: { enum: [1, 2, 3] },
|
|
130
130
|
arr2: { type: "integer[]" },
|
|
131
131
|
arrStr: { type: "string[]", optional: true, nullable: true },
|
|
132
|
-
o: {
|
|
132
|
+
o: { oneOf: [{ o1: { type: "integer" } }, { o2: { type: "boolean" } }], optional: true, nullable: true },
|
|
133
133
|
}
|
|
134
134
|
},
|
|
135
|
-
colOneOf: {
|
|
135
|
+
colOneOf: { enum: ["a", "b", "c"] },
|
|
136
136
|
status: {
|
|
137
137
|
nullable: true,
|
|
138
138
|
jsonbSchema: {
|
|
139
|
-
|
|
139
|
+
oneOf: [
|
|
140
140
|
{ ok: { type: "string" } },
|
|
141
141
|
{ err: { type: "string" } },
|
|
142
142
|
{
|
|
@@ -152,10 +152,10 @@ function dd(){
|
|
|
152
152
|
jsonOneOf: {
|
|
153
153
|
nullable: true,
|
|
154
154
|
jsonbSchema: {
|
|
155
|
-
|
|
156
|
-
{ command: {
|
|
155
|
+
oneOf: [
|
|
156
|
+
{ command: { enum: ["a"] } },
|
|
157
157
|
{
|
|
158
|
-
command: {
|
|
158
|
+
command: { enum: ["b"] },
|
|
159
159
|
option: { type: "integer[]" }
|
|
160
160
|
}
|
|
161
161
|
]
|
package/tests/server/server.ts
CHANGED
|
@@ -13,12 +13,12 @@ prostgles<DBSchemaGenerated>({
|
|
|
13
13
|
columns: {
|
|
14
14
|
id: { sqlDefinition: `SERIAL PRIMARY KEY ` },
|
|
15
15
|
email: { sqlDefinition: `TEXT NOT NULL` },
|
|
16
|
-
status: {
|
|
16
|
+
status: { enum: ["active", "disabled", "pending"] },
|
|
17
17
|
preferences: {
|
|
18
18
|
defaultValue: "{}",
|
|
19
19
|
jsonbSchema: {
|
|
20
20
|
showIntro: { type: "boolean", optional: true },
|
|
21
|
-
theme: {
|
|
21
|
+
theme: { enum: ["light", "dark"], optional: true },
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
}
|