@snowtop/ent 0.0.35 → 0.1.0-alpha3
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/action/action.d.ts +14 -14
- package/action/experimental_action.d.ts +20 -20
- package/action/experimental_action.js +1 -1
- package/action/orchestrator.d.ts +9 -9
- package/action/orchestrator.js +11 -11
- package/core/base.d.ts +7 -8
- package/core/base.js +0 -16
- package/core/ent.d.ts +2 -1
- package/core/ent.js +13 -8
- package/core/privacy.js +0 -3
- package/core/query/assoc_query.js +2 -2
- package/core/query/query.d.ts +1 -1
- package/imports/index.d.ts +0 -1
- package/imports/index.js +3 -36
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +10 -2
- package/parse_schema/parse.js +32 -2
- package/schema/base_schema.js +15 -15
- package/schema/field.d.ts +25 -25
- package/schema/field.js +41 -32
- package/schema/index.d.ts +3 -1
- package/schema/index.js +2 -0
- package/schema/json_field.d.ts +6 -6
- package/schema/json_field.js +2 -2
- package/schema/schema.d.ts +10 -5
- package/schema/schema.js +18 -5
- package/schema/struct_field.d.ts +17 -0
- package/schema/struct_field.js +102 -0
- package/schema/union_field.d.ts +22 -0
- package/schema/union_field.js +61 -0
- package/scripts/custom_compiler.js +2 -19
- package/scripts/transform_schema.d.ts +1 -0
- package/scripts/transform_schema.js +288 -0
- package/testutils/builder.d.ts +13 -13
- package/testutils/db/test_db.js +9 -9
- package/testutils/fake_data/fake_contact.d.ts +2 -2
- package/testutils/fake_data/fake_contact.js +6 -13
- package/testutils/fake_data/fake_event.d.ts +2 -2
- package/testutils/fake_data/fake_event.js +8 -16
- package/testutils/fake_data/fake_user.d.ts +2 -2
- package/testutils/fake_data/fake_user.js +7 -16
- package/testutils/fake_data/user_query.d.ts +2 -2
- package/tsc/compilerOptions.d.ts +2 -0
- package/tsc/compilerOptions.js +61 -0
package/schema/field.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Field, FieldOptions, ForeignKey, PolymorphicOptions, Type } from "./schema";
|
|
1
|
+
import { Field, FieldMap, FieldOptions, ForeignKey, PolymorphicOptions, Type } from "./schema";
|
|
2
2
|
export declare abstract class BaseField {
|
|
3
3
|
name: string;
|
|
4
4
|
nullable?: boolean;
|
|
@@ -12,18 +12,18 @@ export declare abstract class BaseField {
|
|
|
12
12
|
index?: boolean;
|
|
13
13
|
foreignKey?: ForeignKey;
|
|
14
14
|
polymorphic?: boolean | PolymorphicOptions;
|
|
15
|
-
derivedFields?: Field[];
|
|
16
15
|
derivedWhenEmbedded?: boolean;
|
|
17
16
|
logValue(val: any): any;
|
|
18
17
|
}
|
|
19
18
|
export declare class UUIDField extends BaseField implements Field {
|
|
20
|
-
private options
|
|
19
|
+
private options?;
|
|
21
20
|
type: Type;
|
|
22
|
-
constructor(options
|
|
21
|
+
constructor(options?: FieldOptions | undefined);
|
|
22
|
+
getDerivedFields(fieldName: string): FieldMap;
|
|
23
23
|
private isBuilder;
|
|
24
24
|
valid(val: any): Promise<boolean>;
|
|
25
25
|
}
|
|
26
|
-
export declare function UUIDType(options
|
|
26
|
+
export declare function UUIDType(options?: FieldOptions): UUIDField;
|
|
27
27
|
export interface IntegerOptions extends FieldOptions {
|
|
28
28
|
min?: number;
|
|
29
29
|
max?: number;
|
|
@@ -40,7 +40,7 @@ export declare class IntegerField extends BaseField implements Field {
|
|
|
40
40
|
valid(val: any): boolean;
|
|
41
41
|
validate(validator: (str: number) => boolean): this;
|
|
42
42
|
}
|
|
43
|
-
export declare function IntegerType(options
|
|
43
|
+
export declare function IntegerType(options?: IntegerOptions): IntegerField;
|
|
44
44
|
export declare class BigIntegerField extends BaseField implements Field {
|
|
45
45
|
type: Type;
|
|
46
46
|
}
|
|
@@ -48,11 +48,11 @@ export declare function BigIntegerType(options: FieldOptions): BigIntegerField;
|
|
|
48
48
|
export declare class FloatField extends BaseField implements Field {
|
|
49
49
|
type: Type;
|
|
50
50
|
}
|
|
51
|
-
export declare function FloatType(options
|
|
51
|
+
export declare function FloatType(options?: FieldOptions): FloatField;
|
|
52
52
|
export declare class BooleanField extends BaseField implements Field {
|
|
53
53
|
type: Type;
|
|
54
54
|
}
|
|
55
|
-
export declare function BooleanType(options
|
|
55
|
+
export declare function BooleanType(options?: FieldOptions): BooleanField;
|
|
56
56
|
export interface StringOptions extends FieldOptions {
|
|
57
57
|
minLen?: number;
|
|
58
58
|
maxLen?: number;
|
|
@@ -88,7 +88,7 @@ export declare class StringField extends BaseField implements Field {
|
|
|
88
88
|
trimLeft(): this;
|
|
89
89
|
trimRight(): this;
|
|
90
90
|
}
|
|
91
|
-
export declare function StringType(options
|
|
91
|
+
export declare function StringType(options?: StringOptions): StringField;
|
|
92
92
|
export interface TimestampOptions extends FieldOptions {
|
|
93
93
|
withTimezone?: boolean;
|
|
94
94
|
}
|
|
@@ -98,8 +98,8 @@ export declare class TimestampField extends BaseField implements Field {
|
|
|
98
98
|
constructor(options: TimestampOptions);
|
|
99
99
|
format(val: Date): any;
|
|
100
100
|
}
|
|
101
|
-
export declare function TimestampType(options
|
|
102
|
-
export declare function TimestamptzType(options
|
|
101
|
+
export declare function TimestampType(options?: TimestampOptions): TimestampField;
|
|
102
|
+
export declare function TimestamptzType(options?: FieldOptions): TimestampField;
|
|
103
103
|
export interface TimeOptions extends FieldOptions {
|
|
104
104
|
withTimezone?: boolean;
|
|
105
105
|
precision?: number;
|
|
@@ -108,16 +108,16 @@ export declare const leftPad: (val: number) => string;
|
|
|
108
108
|
export declare class TimeField extends BaseField implements Field {
|
|
109
109
|
type: Type;
|
|
110
110
|
withTimezone?: boolean;
|
|
111
|
-
constructor(options
|
|
111
|
+
constructor(options?: TimeOptions);
|
|
112
112
|
format(val: any): any;
|
|
113
113
|
}
|
|
114
|
-
export declare function TimeType(options
|
|
115
|
-
export declare function TimetzType(options
|
|
114
|
+
export declare function TimeType(options?: TimeOptions): TimeField;
|
|
115
|
+
export declare function TimetzType(options?: FieldOptions): TimeField;
|
|
116
116
|
export declare class DateField extends BaseField implements Field {
|
|
117
117
|
type: Type;
|
|
118
118
|
format(val: any): any;
|
|
119
119
|
}
|
|
120
|
-
export declare function DateType(options
|
|
120
|
+
export declare function DateType(options?: FieldOptions): DateField;
|
|
121
121
|
declare type EnumMap = {
|
|
122
122
|
[key: string]: string;
|
|
123
123
|
};
|
|
@@ -142,27 +142,27 @@ export declare class ListField extends BaseField {
|
|
|
142
142
|
private field;
|
|
143
143
|
type: Type;
|
|
144
144
|
private validators;
|
|
145
|
-
constructor(field: Field, options
|
|
145
|
+
constructor(field: Field, options?: FieldOptions);
|
|
146
146
|
validate(validator: (val: any[]) => boolean): this;
|
|
147
147
|
valid(val: any): Promise<boolean>;
|
|
148
148
|
private postgresVal;
|
|
149
|
-
format(val: any): any;
|
|
149
|
+
format(val: any, nested?: boolean): any;
|
|
150
150
|
minLen(l: number): this;
|
|
151
151
|
maxLen(l: number): this;
|
|
152
152
|
length(l: number): this;
|
|
153
153
|
range(start: any, stop: any): this;
|
|
154
154
|
}
|
|
155
|
-
export declare function StringListType(options
|
|
155
|
+
export declare function StringListType(options?: StringOptions): ListField;
|
|
156
156
|
export declare function IntListType(options: FieldOptions): ListField;
|
|
157
|
-
export declare function IntegerListType(options
|
|
158
|
-
export declare function FloatListType(options
|
|
157
|
+
export declare function IntegerListType(options?: FieldOptions): ListField;
|
|
158
|
+
export declare function FloatListType(options?: FieldOptions): ListField;
|
|
159
159
|
export declare function BigIntegerListType(options: FieldOptions): ListField;
|
|
160
|
-
export declare function BooleanListType(options
|
|
160
|
+
export declare function BooleanListType(options?: FieldOptions): ListField;
|
|
161
161
|
export declare function TimestampListType(options: TimestampOptions): ListField;
|
|
162
|
-
export declare function TimestamptzListType(options
|
|
163
|
-
export declare function TimeListType(options
|
|
162
|
+
export declare function TimestamptzListType(options?: TimestampOptions): ListField;
|
|
163
|
+
export declare function TimeListType(options?: TimeOptions): ListField;
|
|
164
164
|
export declare function TimetzListType(options: TimeOptions): ListField;
|
|
165
|
-
export declare function DateListType(options
|
|
165
|
+
export declare function DateListType(options?: FieldOptions): ListField;
|
|
166
166
|
export declare function EnumListType(options: EnumOptions): ListField;
|
|
167
|
-
export declare function UUIDListType(options
|
|
167
|
+
export declare function UUIDListType(options?: FieldOptions): ListField;
|
|
168
168
|
export {};
|
package/schema/field.js
CHANGED
|
@@ -40,19 +40,25 @@ class UUIDField extends BaseField {
|
|
|
40
40
|
super();
|
|
41
41
|
this.options = options;
|
|
42
42
|
this.type = { dbType: schema_1.DBType.UUID };
|
|
43
|
-
|
|
43
|
+
if (options?.fieldEdge?.enforceSchema &&
|
|
44
|
+
!options.fieldEdge.getLoaderInfoFromSchema) {
|
|
45
|
+
throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
getDerivedFields(fieldName) {
|
|
49
|
+
const polymorphic = this.options?.polymorphic;
|
|
44
50
|
if (polymorphic) {
|
|
45
51
|
let name = "";
|
|
46
|
-
if (
|
|
47
|
-
let idx =
|
|
48
|
-
name =
|
|
52
|
+
if (fieldName.endsWith("_id")) {
|
|
53
|
+
let idx = fieldName.indexOf("_id");
|
|
54
|
+
name = fieldName.substring(0, idx) + "_type";
|
|
49
55
|
}
|
|
50
|
-
else if (
|
|
51
|
-
let idx =
|
|
52
|
-
name =
|
|
56
|
+
else if (fieldName.endsWith("ID")) {
|
|
57
|
+
let idx = fieldName.indexOf("ID");
|
|
58
|
+
name = fieldName.substring(0, idx) + "Type";
|
|
53
59
|
}
|
|
54
60
|
else {
|
|
55
|
-
throw new Error(`unsupported id polymorhpic type ${
|
|
61
|
+
throw new Error(`unsupported id polymorhpic type ${fieldName}`);
|
|
56
62
|
}
|
|
57
63
|
// polymorphic field automatically hidden from GraphQL
|
|
58
64
|
// can be made visible with custom fields if user wants to change this behavior
|
|
@@ -60,38 +66,33 @@ class UUIDField extends BaseField {
|
|
|
60
66
|
// intentionally not made private as it doesn't seem like it needs to be hidden
|
|
61
67
|
if (typeof polymorphic === "object" && polymorphic.types) {
|
|
62
68
|
// an enum with types validated here
|
|
63
|
-
|
|
64
|
-
EnumType({
|
|
65
|
-
name,
|
|
69
|
+
return {
|
|
70
|
+
[name]: EnumType({
|
|
66
71
|
values: polymorphic.types,
|
|
67
72
|
hideFromGraphQL: true,
|
|
68
73
|
derivedWhenEmbedded: true,
|
|
69
|
-
nullable: options
|
|
74
|
+
nullable: this.options?.nullable,
|
|
70
75
|
}),
|
|
71
|
-
|
|
76
|
+
};
|
|
72
77
|
}
|
|
73
78
|
else {
|
|
74
79
|
// just a string field...
|
|
75
|
-
|
|
76
|
-
StringType({
|
|
77
|
-
name,
|
|
80
|
+
return {
|
|
81
|
+
[name]: StringType({
|
|
78
82
|
hideFromGraphQL: true,
|
|
79
83
|
derivedWhenEmbedded: true,
|
|
80
|
-
nullable: options
|
|
84
|
+
nullable: this.options?.nullable,
|
|
81
85
|
}),
|
|
82
|
-
|
|
86
|
+
};
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
|
-
|
|
86
|
-
!options.fieldEdge.getLoaderInfoFromSchema) {
|
|
87
|
-
throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
|
|
88
|
-
}
|
|
89
|
+
return {};
|
|
89
90
|
}
|
|
90
91
|
isBuilder(val) {
|
|
91
92
|
return val.placeholderID !== undefined;
|
|
92
93
|
}
|
|
93
94
|
async valid(val) {
|
|
94
|
-
if (!this.options
|
|
95
|
+
if (!this.options?.fieldEdge?.enforceSchema) {
|
|
95
96
|
return true;
|
|
96
97
|
}
|
|
97
98
|
const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema;
|
|
@@ -119,7 +120,7 @@ class IntegerField extends BaseField {
|
|
|
119
120
|
super();
|
|
120
121
|
this.type = { dbType: schema_1.DBType.Int };
|
|
121
122
|
this.validators = [];
|
|
122
|
-
this.options = {
|
|
123
|
+
this.options = {};
|
|
123
124
|
// for legacy callers
|
|
124
125
|
this.handleOptions(options || this.options);
|
|
125
126
|
}
|
|
@@ -206,9 +207,9 @@ class StringField extends BaseField {
|
|
|
206
207
|
this.type = { dbType: schema_1.DBType.String };
|
|
207
208
|
this.validators = [];
|
|
208
209
|
this.formatters = [];
|
|
209
|
-
this.options = {
|
|
210
|
+
this.options = {};
|
|
210
211
|
// for legacy callers
|
|
211
|
-
this.handleOptions(options || {
|
|
212
|
+
this.handleOptions(options || {});
|
|
212
213
|
}
|
|
213
214
|
getOptions() {
|
|
214
215
|
return this.options;
|
|
@@ -347,7 +348,7 @@ class TimestampField extends BaseField {
|
|
|
347
348
|
}
|
|
348
349
|
exports.TimestampField = TimestampField;
|
|
349
350
|
function TimestampType(options) {
|
|
350
|
-
let result = new TimestampField(options);
|
|
351
|
+
let result = new TimestampField({ ...options });
|
|
351
352
|
return Object.assign(result, options);
|
|
352
353
|
}
|
|
353
354
|
exports.TimestampType = TimestampType;
|
|
@@ -374,7 +375,7 @@ class TimeField extends BaseField {
|
|
|
374
375
|
constructor(options) {
|
|
375
376
|
super();
|
|
376
377
|
this.type = { dbType: schema_1.DBType.Time };
|
|
377
|
-
if (options
|
|
378
|
+
if (options?.withTimezone) {
|
|
378
379
|
this.type = {
|
|
379
380
|
dbType: schema_1.DBType.Timetz,
|
|
380
381
|
};
|
|
@@ -451,8 +452,8 @@ class EnumField extends BaseField {
|
|
|
451
452
|
dbType: options.createEnumType ? schema_1.DBType.Enum : schema_1.DBType.StringEnum,
|
|
452
453
|
values: options.values,
|
|
453
454
|
enumMap: options.map,
|
|
454
|
-
type: options.tsType
|
|
455
|
-
graphQLType: options.graphQLType
|
|
455
|
+
type: options.tsType,
|
|
456
|
+
graphQLType: options.graphQLType,
|
|
456
457
|
};
|
|
457
458
|
if (!options.foreignKey) {
|
|
458
459
|
if (!options.values && !options.map) {
|
|
@@ -596,13 +597,17 @@ class ListField extends BaseField {
|
|
|
596
597
|
}
|
|
597
598
|
return JSON.stringify(val);
|
|
598
599
|
}
|
|
599
|
-
format(val) {
|
|
600
|
+
format(val, nested) {
|
|
600
601
|
if (!Array.isArray(val)) {
|
|
601
602
|
throw new Error(`need an array to format`);
|
|
602
603
|
}
|
|
603
604
|
const elemDBType = this.type.listElemType.dbType;
|
|
604
605
|
const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
|
|
605
|
-
|
|
606
|
+
// postgres ish doesn't apply when nested
|
|
607
|
+
const postgres = !nested && db_1.default.getDialect() === db_1.Dialect.Postgres;
|
|
608
|
+
if (nested && !this.field.format) {
|
|
609
|
+
return val;
|
|
610
|
+
}
|
|
606
611
|
if (!postgres && !this.field.format) {
|
|
607
612
|
return JSON.stringify(val);
|
|
608
613
|
}
|
|
@@ -628,6 +633,10 @@ class ListField extends BaseField {
|
|
|
628
633
|
if (postgres) {
|
|
629
634
|
return postgresRet + "}";
|
|
630
635
|
}
|
|
636
|
+
// don't JSON.stringify if nested
|
|
637
|
+
if (nested) {
|
|
638
|
+
return ret;
|
|
639
|
+
}
|
|
631
640
|
return JSON.stringify(ret);
|
|
632
641
|
}
|
|
633
642
|
minLen(l) {
|
package/schema/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import Schema from "./schema";
|
|
2
2
|
export { Schema };
|
|
3
|
-
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, ActionOperation, Action, EdgeAction, NoFields, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
|
7
|
+
export * from "./struct_field";
|
|
8
|
+
export * from "./union_field";
|
package/schema/index.js
CHANGED
|
@@ -26,3 +26,5 @@ Object.defineProperty(exports, "BaseEntSchema", { enumerable: true, get: functio
|
|
|
26
26
|
Object.defineProperty(exports, "BaseEntSchemaWithTZ", { enumerable: true, get: function () { return base_schema_1.BaseEntSchemaWithTZ; } });
|
|
27
27
|
__exportStar(require("./field"), exports);
|
|
28
28
|
__exportStar(require("./json_field"), exports);
|
|
29
|
+
__exportStar(require("./struct_field"), exports);
|
|
30
|
+
__exportStar(require("./union_field"), exports);
|
package/schema/json_field.d.ts
CHANGED
|
@@ -5,13 +5,13 @@ export interface JSONOptions extends FieldOptions {
|
|
|
5
5
|
importType?: ImportType;
|
|
6
6
|
}
|
|
7
7
|
export declare class JSONField extends BaseField implements Field {
|
|
8
|
-
private options
|
|
8
|
+
private options?;
|
|
9
9
|
type: Type;
|
|
10
|
-
constructor(jsonb: boolean, options
|
|
10
|
+
constructor(jsonb: boolean, options?: JSONOptions | undefined);
|
|
11
11
|
format(val: any): string;
|
|
12
12
|
valid(val: any): boolean;
|
|
13
13
|
}
|
|
14
|
-
export declare function JSONType(options
|
|
15
|
-
export declare function JSONBType(options
|
|
16
|
-
export declare function JSONBListType(options
|
|
17
|
-
export declare function JSONListType(options
|
|
14
|
+
export declare function JSONType(options?: JSONOptions): JSONField;
|
|
15
|
+
export declare function JSONBType(options?: JSONOptions): JSONField;
|
|
16
|
+
export declare function JSONBListType(options?: JSONOptions): ListField;
|
|
17
|
+
export declare function JSONListType(options?: JSONOptions): ListField;
|
package/schema/json_field.js
CHANGED
|
@@ -13,7 +13,7 @@ class JSONField extends field_1.BaseField {
|
|
|
13
13
|
if (jsonb) {
|
|
14
14
|
this.type.dbType = schema_1.DBType.JSONB;
|
|
15
15
|
}
|
|
16
|
-
if (options
|
|
16
|
+
if (options?.importType) {
|
|
17
17
|
this.type.importType = options.importType;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -21,7 +21,7 @@ class JSONField extends field_1.BaseField {
|
|
|
21
21
|
return JSON.stringify(val);
|
|
22
22
|
}
|
|
23
23
|
valid(val) {
|
|
24
|
-
if (this.options
|
|
24
|
+
if (this.options?.validator) {
|
|
25
25
|
return this.options.validator(val);
|
|
26
26
|
}
|
|
27
27
|
return true;
|
package/schema/schema.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Data, Ent, LoaderInfo } from "../core/base";
|
|
2
2
|
import { Builder } from "../action/action";
|
|
3
|
+
export declare type FieldMap = {
|
|
4
|
+
[key: string]: Field;
|
|
5
|
+
};
|
|
3
6
|
export default interface Schema {
|
|
4
|
-
fields: Field[];
|
|
7
|
+
fields: FieldMap | Field[];
|
|
5
8
|
tableName?: string;
|
|
6
9
|
patterns?: Pattern[];
|
|
7
10
|
edges?: Edge[];
|
|
@@ -57,7 +60,7 @@ export interface AssocEdgeGroup {
|
|
|
57
60
|
export declare type Edge = AssocEdge;
|
|
58
61
|
export interface Pattern {
|
|
59
62
|
name: string;
|
|
60
|
-
fields: Field[];
|
|
63
|
+
fields: FieldMap | Field[];
|
|
61
64
|
edges?: Edge[];
|
|
62
65
|
}
|
|
63
66
|
export declare enum DBType {
|
|
@@ -94,6 +97,8 @@ export interface Type {
|
|
|
94
97
|
values?: string[];
|
|
95
98
|
enumMap?: EnumMap;
|
|
96
99
|
importType?: ImportType;
|
|
100
|
+
subFields?: FieldMap;
|
|
101
|
+
unionFields?: FieldMap;
|
|
97
102
|
}
|
|
98
103
|
export interface ForeignKey {
|
|
99
104
|
schema: string;
|
|
@@ -117,7 +122,6 @@ export interface FieldEdge {
|
|
|
117
122
|
disableBuilderType?: boolean;
|
|
118
123
|
}
|
|
119
124
|
export interface FieldOptions {
|
|
120
|
-
name: string;
|
|
121
125
|
nullable?: boolean;
|
|
122
126
|
storageKey?: string;
|
|
123
127
|
serverDefault?: any;
|
|
@@ -136,7 +140,8 @@ export interface FieldOptions {
|
|
|
136
140
|
defaultValueOnEdit?(builder: Builder<Ent>, input: Data): any;
|
|
137
141
|
derivedWhenEmbedded?: boolean;
|
|
138
142
|
polymorphic?: boolean | PolymorphicOptions;
|
|
139
|
-
|
|
143
|
+
getDerivedFields?(name: string): FieldMap;
|
|
144
|
+
[x: string]: any;
|
|
140
145
|
}
|
|
141
146
|
export interface PolymorphicOptions {
|
|
142
147
|
types?: string[];
|
|
@@ -146,7 +151,7 @@ export interface PolymorphicOptions {
|
|
|
146
151
|
export interface Field extends FieldOptions {
|
|
147
152
|
type: Type;
|
|
148
153
|
valid?(val: any): Promise<boolean> | boolean;
|
|
149
|
-
format?(val: any): any;
|
|
154
|
+
format?(val: any, nested?: boolean): any;
|
|
150
155
|
logValue(val: any): any;
|
|
151
156
|
}
|
|
152
157
|
export interface SchemaConstructor {
|
package/schema/schema.js
CHANGED
|
@@ -37,12 +37,25 @@ function getFields(value) {
|
|
|
37
37
|
schema = new value();
|
|
38
38
|
}
|
|
39
39
|
function addFields(fields) {
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
if (Array.isArray(fields)) {
|
|
41
|
+
for (const field of fields) {
|
|
42
|
+
const name = field.name;
|
|
43
|
+
if (!name) {
|
|
44
|
+
throw new Error(`name required`);
|
|
45
|
+
}
|
|
46
|
+
if (field.getDerivedFields !== undefined) {
|
|
47
|
+
addFields(field.getDerivedFields(name));
|
|
48
|
+
}
|
|
49
|
+
m.set(name, field);
|
|
44
50
|
}
|
|
45
|
-
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
for (const name in fields) {
|
|
54
|
+
const field = fields[name];
|
|
55
|
+
if (field.getDerivedFields !== undefined) {
|
|
56
|
+
addFields(field.getDerivedFields(name));
|
|
57
|
+
}
|
|
58
|
+
m.set(name, field);
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
61
|
let m = new Map();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseField, ListField } from "./field";
|
|
2
|
+
import { FieldOptions, Field, Type, FieldMap } from "./schema";
|
|
3
|
+
export interface StructOptions extends FieldOptions {
|
|
4
|
+
tsType: string;
|
|
5
|
+
fields: FieldMap;
|
|
6
|
+
graphQLType?: string;
|
|
7
|
+
jsonNotJSONB?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class StructField extends BaseField implements Field {
|
|
10
|
+
private options;
|
|
11
|
+
type: Type;
|
|
12
|
+
constructor(options: StructOptions);
|
|
13
|
+
format(obj: any, nested?: boolean): string | Object;
|
|
14
|
+
valid(obj: any): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
export declare function StructType(options: StructOptions): StructField & StructOptions;
|
|
17
|
+
export declare function StructListType(options: StructOptions): ListField;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StructListType = exports.StructType = exports.StructField = void 0;
|
|
4
|
+
const field_1 = require("./field");
|
|
5
|
+
const schema_1 = require("./schema");
|
|
6
|
+
const camel_case_1 = require("camel-case");
|
|
7
|
+
class StructField extends field_1.BaseField {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super();
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.type = {
|
|
12
|
+
dbType: schema_1.DBType.JSONB,
|
|
13
|
+
};
|
|
14
|
+
this.type.subFields = options.fields;
|
|
15
|
+
this.type.type = options.tsType;
|
|
16
|
+
this.type.graphQLType = options.graphQLType || options.tsType;
|
|
17
|
+
if (options.jsonNotJSONB) {
|
|
18
|
+
this.type.dbType = schema_1.DBType.JSON;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// right now, we store things in the db in lowerCase format
|
|
22
|
+
// this will lead to issues if field changes.
|
|
23
|
+
// TODO: use storageKey and convert back...
|
|
24
|
+
format(obj, nested) {
|
|
25
|
+
if (!(obj instanceof Object)) {
|
|
26
|
+
throw new Error("valid was not called");
|
|
27
|
+
}
|
|
28
|
+
let ret = {};
|
|
29
|
+
for (const k in this.options.fields) {
|
|
30
|
+
// TODO more #510
|
|
31
|
+
let dbKey = (0, camel_case_1.camelCase)(k);
|
|
32
|
+
let val = obj[dbKey];
|
|
33
|
+
// for tests with snake_case
|
|
34
|
+
if (val === undefined && obj[k] !== undefined) {
|
|
35
|
+
val = obj[k];
|
|
36
|
+
dbKey = k;
|
|
37
|
+
}
|
|
38
|
+
if (val === undefined) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const field = this.options.fields[k];
|
|
42
|
+
if (field.format) {
|
|
43
|
+
// indicate nested so this isn't JSON stringified
|
|
44
|
+
ret[dbKey] = field.format(val, true);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
ret[dbKey] = val;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// don't json.stringify if nested
|
|
51
|
+
if (nested) {
|
|
52
|
+
return ret;
|
|
53
|
+
}
|
|
54
|
+
return JSON.stringify(ret);
|
|
55
|
+
}
|
|
56
|
+
async valid(obj) {
|
|
57
|
+
if (!(obj instanceof Object)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
let promises = [];
|
|
61
|
+
// TODO probably need to support optional fields...
|
|
62
|
+
let valid = true;
|
|
63
|
+
for (const k in this.options.fields) {
|
|
64
|
+
const field = this.options.fields[k];
|
|
65
|
+
// TODO more #510
|
|
66
|
+
let dbKey = (0, camel_case_1.camelCase)(k);
|
|
67
|
+
let val = obj[dbKey];
|
|
68
|
+
// for tests with snake_case
|
|
69
|
+
if (val === undefined && obj[k] !== undefined) {
|
|
70
|
+
val = obj[k];
|
|
71
|
+
dbKey = k;
|
|
72
|
+
}
|
|
73
|
+
if (val === undefined || val === null) {
|
|
74
|
+
// nullable, nothing to do here
|
|
75
|
+
if (field.nullable) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
valid = false;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (!field.valid) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
promises.push(field.valid(val));
|
|
85
|
+
}
|
|
86
|
+
if (!valid) {
|
|
87
|
+
return valid;
|
|
88
|
+
}
|
|
89
|
+
const ret = await Promise.all(promises);
|
|
90
|
+
return ret.every((v) => v);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.StructField = StructField;
|
|
94
|
+
function StructType(options) {
|
|
95
|
+
let result = new StructField(options);
|
|
96
|
+
return Object.assign(result, options);
|
|
97
|
+
}
|
|
98
|
+
exports.StructType = StructType;
|
|
99
|
+
function StructListType(options) {
|
|
100
|
+
return new field_1.ListField(StructType(options), options);
|
|
101
|
+
}
|
|
102
|
+
exports.StructListType = StructListType;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { StructField } from "./struct_field";
|
|
2
|
+
import { FieldOptions, Type } from "./schema";
|
|
3
|
+
import { BaseField, ListField } from "./field";
|
|
4
|
+
export declare type StructMap = {
|
|
5
|
+
[key: string]: StructField;
|
|
6
|
+
};
|
|
7
|
+
export interface UnionOptions extends FieldOptions {
|
|
8
|
+
tsType: string;
|
|
9
|
+
fields: StructMap;
|
|
10
|
+
graphQLType?: string;
|
|
11
|
+
jsonNotJSONB?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class UnionField extends BaseField implements FieldOptions {
|
|
14
|
+
private options;
|
|
15
|
+
type: Type;
|
|
16
|
+
m: Map<Object, string>;
|
|
17
|
+
constructor(options: UnionOptions);
|
|
18
|
+
format(obj: any, nested?: boolean): string | Object;
|
|
19
|
+
valid(obj: any): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
export declare function UnionType(options: UnionOptions): UnionField & UnionOptions;
|
|
22
|
+
export declare function UnionListType(options: UnionOptions): ListField;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnionListType = exports.UnionType = exports.UnionField = void 0;
|
|
4
|
+
const schema_1 = require("./schema");
|
|
5
|
+
const field_1 = require("./field");
|
|
6
|
+
class UnionField extends field_1.BaseField {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
super();
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.type = {
|
|
11
|
+
dbType: schema_1.DBType.JSONB,
|
|
12
|
+
};
|
|
13
|
+
this.m = new Map();
|
|
14
|
+
this.type.unionFields = options.fields;
|
|
15
|
+
this.type.type = options.tsType;
|
|
16
|
+
this.type.graphQLType = options.graphQLType || options.tsType;
|
|
17
|
+
// TODO should throw if not nested?
|
|
18
|
+
if (options.jsonNotJSONB) {
|
|
19
|
+
this.type.dbType = schema_1.DBType.JSON;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
format(obj, nested) {
|
|
23
|
+
if (!(obj instanceof Object)) {
|
|
24
|
+
throw new Error("valid was not called");
|
|
25
|
+
}
|
|
26
|
+
for (const k in this.options.fields) {
|
|
27
|
+
const field = this.options.fields[k];
|
|
28
|
+
const fmt = field.format(obj, nested);
|
|
29
|
+
if (fmt !== "{}") {
|
|
30
|
+
return fmt;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// TODO need better logic here
|
|
34
|
+
// maybe add something ignored to the objec that indicates which key?
|
|
35
|
+
// or store in map
|
|
36
|
+
throw new Error(`couldn't format union`);
|
|
37
|
+
}
|
|
38
|
+
async valid(obj) {
|
|
39
|
+
if (!(obj instanceof Object)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
let promises = [];
|
|
43
|
+
for (const k in this.options.fields) {
|
|
44
|
+
const field = this.options.fields[k];
|
|
45
|
+
promises.push(field.valid(obj));
|
|
46
|
+
}
|
|
47
|
+
const ret = await Promise.all(promises);
|
|
48
|
+
// only 1 should be valid
|
|
49
|
+
return ret.filter((v) => v).length === 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.UnionField = UnionField;
|
|
53
|
+
function UnionType(options) {
|
|
54
|
+
let result = new UnionField(options);
|
|
55
|
+
return Object.assign(result, options);
|
|
56
|
+
}
|
|
57
|
+
exports.UnionType = UnionType;
|
|
58
|
+
function UnionListType(options) {
|
|
59
|
+
return new field_1.ListField(UnionType(options), options);
|
|
60
|
+
}
|
|
61
|
+
exports.UnionListType = UnionListType;
|