@snowtop/ent 0.0.2 → 0.0.3-5.alpha.2
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 +6 -6
- package/action/action.js +2 -2
- package/action/executor.d.ts +7 -12
- package/action/executor.js +39 -33
- package/action/experimental_action.d.ts +4 -2
- package/action/experimental_action.js +27 -2
- package/action/index.d.ts +1 -1
- package/action/orchestrator.d.ts +14 -6
- package/action/orchestrator.js +188 -99
- package/action/privacy.js +4 -4
- package/auth/auth.js +2 -2
- package/core/base.d.ts +6 -0
- package/core/base.js +12 -9
- package/core/clause.d.ts +1 -0
- package/core/clause.js +6 -2
- package/core/config.d.ts +20 -0
- package/core/config.js +2 -2
- package/core/context.js +3 -3
- package/core/convert.d.ts +4 -0
- package/core/convert.js +25 -2
- package/core/db.d.ts +18 -1
- package/core/db.js +4 -7
- package/core/ent.d.ts +17 -10
- package/core/ent.js +38 -15
- package/core/loaders/assoc_count_loader.js +5 -5
- package/core/loaders/assoc_edge_loader.js +10 -10
- package/core/loaders/loader.js +3 -3
- package/core/loaders/object_loader.js +6 -6
- package/core/loaders/query_loader.js +7 -7
- package/core/loaders/raw_count_loader.js +4 -4
- package/core/logger.js +2 -2
- package/core/privacy.d.ts +21 -1
- package/core/privacy.js +91 -47
- package/core/query/assoc_query.d.ts +12 -12
- package/core/query/assoc_query.js +86 -51
- package/core/query/custom_query.d.ts +10 -7
- package/core/query/custom_query.js +29 -3
- package/core/query/query.d.ts +24 -8
- package/core/query/query.js +41 -4
- package/core/query/shared_assoc_test.js +257 -13
- package/core/query/shared_test.d.ts +1 -1
- package/core/query/shared_test.js +11 -11
- package/core/viewer.js +1 -0
- package/graphql/builtins/connection.js +4 -3
- package/graphql/builtins/edge.js +3 -2
- package/graphql/builtins/node.js +2 -1
- package/graphql/graphql.d.ts +2 -0
- package/graphql/graphql.js +83 -61
- package/graphql/index.d.ts +1 -1
- package/graphql/index.js +2 -1
- package/graphql/node_resolver.d.ts +1 -0
- package/graphql/node_resolver.js +14 -1
- package/graphql/query/connection_type.d.ts +5 -4
- package/graphql/query/connection_type.js +6 -6
- package/graphql/query/edge_connection.d.ts +7 -7
- package/graphql/query/page_info.js +5 -4
- package/graphql/query/shared_assoc_test.js +9 -9
- package/graphql/query/shared_edge_connection.d.ts +1 -1
- package/graphql/query/shared_edge_connection.js +4 -4
- package/graphql/scalars/time.js +1 -1
- package/imports/dataz/example1/_auth.js +8 -8
- package/imports/dataz/example1/_viewer.js +4 -4
- package/imports/index.d.ts +1 -1
- package/imports/index.js +3 -5
- package/index.d.ts +2 -1
- package/index.js +6 -2
- package/package.json +17 -10
- package/parse_schema/parse.d.ts +48 -0
- package/parse_schema/parse.js +160 -0
- package/schema/base_schema.d.ts +2 -0
- package/schema/base_schema.js +17 -7
- package/schema/field.d.ts +52 -15
- package/schema/field.js +234 -47
- package/schema/index.d.ts +1 -0
- package/schema/index.js +1 -0
- package/schema/json_field.d.ts +17 -0
- package/schema/json_field.js +48 -0
- package/schema/schema.d.ts +39 -4
- package/schema/schema.js +2 -0
- package/scripts/custom_compiler.js +8 -10
- package/scripts/custom_graphql.js +45 -10
- package/scripts/read_schema.js +6 -108
- package/testutils/builder.d.ts +6 -3
- package/testutils/builder.js +31 -15
- package/testutils/db/test_db.d.ts +16 -8
- package/testutils/db/test_db.js +65 -9
- package/testutils/db_mock.js +5 -5
- package/testutils/ent-graphql-tests/index.d.ts +1 -0
- package/testutils/ent-graphql-tests/index.js +13 -13
- package/testutils/fake_comms.d.ts +1 -0
- package/testutils/fake_comms.js +4 -0
- package/testutils/fake_data/const.d.ts +5 -1
- package/testutils/fake_data/const.js +19 -1
- package/testutils/fake_data/events_query.d.ts +16 -11
- package/testutils/fake_data/events_query.js +15 -0
- package/testutils/fake_data/fake_contact.js +9 -9
- package/testutils/fake_data/fake_event.js +14 -14
- package/testutils/fake_data/fake_user.js +12 -10
- package/testutils/fake_data/test_helpers.d.ts +5 -1
- package/testutils/fake_data/test_helpers.js +49 -16
- package/testutils/fake_data/user_query.d.ts +25 -9
- package/testutils/fake_data/user_query.js +52 -5
- package/testutils/parse_sql.js +19 -3
- package/testutils/write.js +6 -6
package/schema/field.js
CHANGED
|
@@ -19,11 +19,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.EnumListType = exports.DateListType = exports.TimetzListType = exports.TimeListType = exports.TimestamptzListType = exports.TimestampListType = exports.BooleanListType = exports.FloatListType = exports.IntListType = exports.StringListType = exports.ListField = exports.EnumType = exports.EnumField = exports.DateType = exports.DateField = exports.TimetzType = exports.TimeType = exports.TimeField = exports.leftPad = exports.TimestamptzType = exports.TimestampType = exports.TimestampField = exports.StringType = exports.StringField = exports.BooleanType = exports.BooleanField = exports.FloatType = exports.FloatField = exports.IntegerType = exports.IntegerField = exports.UUIDType = exports.UUIDField = exports.BaseField = void 0;
|
|
23
|
-
const schema_1 = require("./schema");
|
|
24
|
-
const snake_case_1 = require("snake-case");
|
|
22
|
+
exports.UUIDListType = exports.EnumListType = exports.DateListType = exports.TimetzListType = exports.TimeListType = exports.TimestamptzListType = exports.TimestampListType = exports.BooleanListType = exports.BigIntegerListType = exports.FloatListType = exports.IntegerListType = exports.IntListType = exports.StringListType = exports.ListField = exports.EnumType = exports.EnumField = exports.DateType = exports.DateField = exports.TimetzType = exports.TimeType = exports.TimeField = exports.leftPad = exports.TimestamptzType = exports.TimestampType = exports.TimestampField = exports.StringType = exports.StringField = exports.BooleanType = exports.BooleanField = exports.FloatType = exports.FloatField = exports.BigIntegerType = exports.BigIntegerField = exports.IntegerType = exports.IntegerField = exports.UUIDType = exports.UUIDField = exports.BaseField = void 0;
|
|
25
23
|
const luxon_1 = require("luxon");
|
|
24
|
+
const snake_case_1 = require("snake-case");
|
|
26
25
|
const db_1 = __importStar(require("../core/db"));
|
|
26
|
+
const schema_1 = require("./schema");
|
|
27
|
+
const util_1 = require("util");
|
|
27
28
|
class BaseField {
|
|
28
29
|
logValue(val) {
|
|
29
30
|
if (this.sensitive) {
|
|
@@ -37,6 +38,7 @@ exports.BaseField = BaseField;
|
|
|
37
38
|
class UUIDField extends BaseField {
|
|
38
39
|
constructor(options) {
|
|
39
40
|
super();
|
|
41
|
+
this.options = options;
|
|
40
42
|
this.type = { dbType: schema_1.DBType.UUID };
|
|
41
43
|
const polymorphic = options.polymorphic;
|
|
42
44
|
if (polymorphic) {
|
|
@@ -64,6 +66,7 @@ class UUIDField extends BaseField {
|
|
|
64
66
|
values: polymorphic.types,
|
|
65
67
|
hideFromGraphQL: true,
|
|
66
68
|
derivedWhenEmbedded: true,
|
|
69
|
+
nullable: options.nullable,
|
|
67
70
|
}),
|
|
68
71
|
];
|
|
69
72
|
}
|
|
@@ -74,10 +77,35 @@ class UUIDField extends BaseField {
|
|
|
74
77
|
name,
|
|
75
78
|
hideFromGraphQL: true,
|
|
76
79
|
derivedWhenEmbedded: true,
|
|
80
|
+
nullable: options.nullable,
|
|
77
81
|
}),
|
|
78
82
|
];
|
|
79
83
|
}
|
|
80
84
|
}
|
|
85
|
+
if (options.fieldEdge?.enforceSchema &&
|
|
86
|
+
!options.fieldEdge.getLoaderInfoFromSchema) {
|
|
87
|
+
throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
isBuilder(val) {
|
|
91
|
+
return val.placeholderID !== undefined;
|
|
92
|
+
}
|
|
93
|
+
async valid(val) {
|
|
94
|
+
if (!this.options.fieldEdge?.enforceSchema) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema;
|
|
98
|
+
const loaderInfo = getLoaderInfo(this.options.fieldEdge.schema);
|
|
99
|
+
if (!loaderInfo) {
|
|
100
|
+
throw new Error(`couldn't get loaderInfo for ${this.options.fieldEdge.schema}`);
|
|
101
|
+
}
|
|
102
|
+
if (this.isBuilder(val)) {
|
|
103
|
+
// if builder, the nodeType of the builder and the nodeType of the loaderInfo should match
|
|
104
|
+
return val.nodeType === loaderInfo.nodeType;
|
|
105
|
+
}
|
|
106
|
+
// TODO we need context here to make sure that we hit local cache
|
|
107
|
+
const row = await loaderInfo.loaderFactory.createLoader().load(val);
|
|
108
|
+
return row !== null;
|
|
81
109
|
}
|
|
82
110
|
}
|
|
83
111
|
exports.UUIDField = UUIDField;
|
|
@@ -87,17 +115,67 @@ function UUIDType(options) {
|
|
|
87
115
|
}
|
|
88
116
|
exports.UUIDType = UUIDType;
|
|
89
117
|
class IntegerField extends BaseField {
|
|
90
|
-
constructor() {
|
|
91
|
-
super(
|
|
118
|
+
constructor(options) {
|
|
119
|
+
super();
|
|
92
120
|
this.type = { dbType: schema_1.DBType.Int };
|
|
121
|
+
this.validators = [];
|
|
122
|
+
this.options = { name: "field" };
|
|
123
|
+
// for legacy callers
|
|
124
|
+
this.handleOptions(options || this.options);
|
|
125
|
+
}
|
|
126
|
+
getOptions() {
|
|
127
|
+
return this.options;
|
|
128
|
+
}
|
|
129
|
+
handleOptions(options) {
|
|
130
|
+
const params = {
|
|
131
|
+
min: this.min,
|
|
132
|
+
max: this.max,
|
|
133
|
+
};
|
|
134
|
+
for (const k in params) {
|
|
135
|
+
const v = options[k];
|
|
136
|
+
if (v !== undefined) {
|
|
137
|
+
params[k].apply(this, [v]);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
this.options = options;
|
|
141
|
+
}
|
|
142
|
+
min(l) {
|
|
143
|
+
return this.validate((val) => val >= l);
|
|
144
|
+
}
|
|
145
|
+
max(l) {
|
|
146
|
+
return this.validate((val) => val <= l);
|
|
147
|
+
}
|
|
148
|
+
valid(val) {
|
|
149
|
+
for (const validator of this.validators) {
|
|
150
|
+
if (!validator(val)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
validate(validator) {
|
|
157
|
+
this.validators.push(validator);
|
|
158
|
+
return this;
|
|
93
159
|
}
|
|
94
160
|
}
|
|
95
161
|
exports.IntegerField = IntegerField;
|
|
96
162
|
function IntegerType(options) {
|
|
97
|
-
let result = new IntegerField();
|
|
163
|
+
let result = new IntegerField(options);
|
|
98
164
|
return Object.assign(result, options);
|
|
99
165
|
}
|
|
100
166
|
exports.IntegerType = IntegerType;
|
|
167
|
+
class BigIntegerField extends BaseField {
|
|
168
|
+
constructor() {
|
|
169
|
+
super(...arguments);
|
|
170
|
+
this.type = { dbType: schema_1.DBType.BigInt };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.BigIntegerField = BigIntegerField;
|
|
174
|
+
function BigIntegerType(options) {
|
|
175
|
+
let result = new BigIntegerField();
|
|
176
|
+
return Object.assign(result, options);
|
|
177
|
+
}
|
|
178
|
+
exports.BigIntegerType = BigIntegerType;
|
|
101
179
|
class FloatField extends BaseField {
|
|
102
180
|
constructor() {
|
|
103
181
|
super(...arguments);
|
|
@@ -128,11 +206,12 @@ class StringField extends BaseField {
|
|
|
128
206
|
this.type = { dbType: schema_1.DBType.String };
|
|
129
207
|
this.validators = [];
|
|
130
208
|
this.formatters = [];
|
|
209
|
+
this.options = { name: "field" };
|
|
131
210
|
// for legacy callers
|
|
132
211
|
this.handleOptions(options || { name: "field" });
|
|
133
212
|
}
|
|
134
213
|
getOptions() {
|
|
135
|
-
return this.
|
|
214
|
+
return this.options;
|
|
136
215
|
}
|
|
137
216
|
handleOptions(options) {
|
|
138
217
|
const noParams = {
|
|
@@ -160,6 +239,7 @@ class StringField extends BaseField {
|
|
|
160
239
|
noParams[k].apply(this);
|
|
161
240
|
}
|
|
162
241
|
}
|
|
242
|
+
this.options = options;
|
|
163
243
|
}
|
|
164
244
|
minLen(l) {
|
|
165
245
|
return this.validate((val) => {
|
|
@@ -310,12 +390,12 @@ class TimeField extends BaseField {
|
|
|
310
390
|
if (this.withTimezone) {
|
|
311
391
|
// for some reason this API is backwards
|
|
312
392
|
let div = (val.getTimezoneOffset() / 60) * -1;
|
|
313
|
-
offset = exports.leftPad(div);
|
|
393
|
+
offset = (0, exports.leftPad)(div);
|
|
314
394
|
}
|
|
315
|
-
let hh = exports.leftPad(val.getHours());
|
|
316
|
-
let mm = exports.leftPad(val.getMinutes());
|
|
317
|
-
let ss = exports.leftPad(val.getSeconds());
|
|
318
|
-
let ms = exports.leftPad(val.getMilliseconds());
|
|
395
|
+
let hh = (0, exports.leftPad)(val.getHours());
|
|
396
|
+
let mm = (0, exports.leftPad)(val.getMinutes());
|
|
397
|
+
let ss = (0, exports.leftPad)(val.getSeconds());
|
|
398
|
+
let ms = (0, exports.leftPad)(val.getMilliseconds());
|
|
319
399
|
if (ms !== "00" && offset) {
|
|
320
400
|
return `${hh}:${mm}:${ss}.${ms}${offset}`;
|
|
321
401
|
}
|
|
@@ -348,11 +428,11 @@ class DateField extends BaseField {
|
|
|
348
428
|
if (!(val instanceof Date)) {
|
|
349
429
|
return val;
|
|
350
430
|
}
|
|
351
|
-
let yy = exports.leftPad(val.getFullYear());
|
|
431
|
+
let yy = (0, exports.leftPad)(val.getFullYear());
|
|
352
432
|
// lol this API
|
|
353
433
|
// for some reason this is 0-index
|
|
354
|
-
let mm = exports.leftPad(val.getMonth() + 1);
|
|
355
|
-
let dd = exports.leftPad(val.getDate());
|
|
434
|
+
let mm = (0, exports.leftPad)(val.getMonth() + 1);
|
|
435
|
+
let dd = (0, exports.leftPad)(val.getDate());
|
|
356
436
|
let ret = `${yy}-${mm}-${dd}`;
|
|
357
437
|
return ret;
|
|
358
438
|
}
|
|
@@ -370,20 +450,33 @@ class EnumField extends BaseField {
|
|
|
370
450
|
// if createEnumType boolean, we create postgres enum otherwise we use a string for it
|
|
371
451
|
dbType: options.createEnumType ? schema_1.DBType.Enum : schema_1.DBType.StringEnum,
|
|
372
452
|
values: options.values,
|
|
453
|
+
enumMap: options.map,
|
|
373
454
|
type: options.tsType || options.name,
|
|
374
455
|
graphQLType: options.graphQLType || options.name,
|
|
375
456
|
};
|
|
376
457
|
if (!options.foreignKey) {
|
|
377
|
-
if (!options.values) {
|
|
378
|
-
throw new Error("values required if not look up table enum. Look-up table enum indicated by foreignKey field");
|
|
458
|
+
if (!options.values && !options.map) {
|
|
459
|
+
throw new Error("values or map required if not look up table enum. Look-up table enum indicated by foreignKey field");
|
|
379
460
|
}
|
|
380
|
-
if (
|
|
381
|
-
|
|
461
|
+
if (options.values) {
|
|
462
|
+
if (!options.values.length) {
|
|
463
|
+
throw new Error("need at least one value in enum type");
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (options.map) {
|
|
467
|
+
let count = 0;
|
|
468
|
+
for (const k in options.map) {
|
|
469
|
+
count++;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
if (!count) {
|
|
473
|
+
throw new Error("need at least one entry in enum map");
|
|
474
|
+
}
|
|
382
475
|
}
|
|
383
476
|
}
|
|
384
477
|
else {
|
|
385
|
-
if (options.values) {
|
|
386
|
-
throw new Error("cannot specify values and foreign key for lookup table enum type");
|
|
478
|
+
if (options.values || options.map) {
|
|
479
|
+
throw new Error("cannot specify values or map and foreign key for lookup table enum type");
|
|
387
480
|
}
|
|
388
481
|
if (options.createEnumType) {
|
|
389
482
|
throw new Error("cannot specify createEnumType without specifying values");
|
|
@@ -396,30 +489,55 @@ class EnumField extends BaseField {
|
|
|
396
489
|
}
|
|
397
490
|
}
|
|
398
491
|
this.values = options.values;
|
|
492
|
+
this.map = options.map;
|
|
399
493
|
}
|
|
494
|
+
// TODO need to update this for map
|
|
400
495
|
convertForGQL(value) {
|
|
401
|
-
return snake_case_1.snakeCase(value).toUpperCase();
|
|
496
|
+
return (0, snake_case_1.snakeCase)(value).toUpperCase();
|
|
402
497
|
}
|
|
403
498
|
valid(val) {
|
|
404
499
|
// lookup table enum and indicated via presence of foreignKey
|
|
405
|
-
if (!this.values) {
|
|
500
|
+
if (!this.values && !this.map) {
|
|
406
501
|
return true;
|
|
407
502
|
}
|
|
408
|
-
|
|
409
|
-
|
|
503
|
+
if (this.values) {
|
|
504
|
+
let str = String(val);
|
|
505
|
+
return this.values.some((value) => value === str || this.convertForGQL(value) === str);
|
|
506
|
+
}
|
|
507
|
+
for (const k in this.map) {
|
|
508
|
+
const v = this.map[k];
|
|
509
|
+
if (v === val || this.convertForGQL(k) === val) {
|
|
510
|
+
// TODO decide on behavior for GQL since GQL only supports one type
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return false;
|
|
410
515
|
}
|
|
411
516
|
format(val) {
|
|
412
517
|
// TODO need to format correctly for graphql purposes...
|
|
413
518
|
// how to best get the values in the db...
|
|
414
|
-
if (!this.values) {
|
|
519
|
+
if (!this.values && !this.map) {
|
|
415
520
|
return val;
|
|
416
521
|
}
|
|
417
522
|
let str = String(val);
|
|
418
|
-
|
|
419
|
-
let
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
523
|
+
if (this.values) {
|
|
524
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
525
|
+
let value = this.values[i];
|
|
526
|
+
// store the format that maps to the given value in the db instead of saving the upper case value
|
|
527
|
+
if (str === value || str === this.convertForGQL(value)) {
|
|
528
|
+
return value;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (this.map) {
|
|
533
|
+
for (const k in this.map) {
|
|
534
|
+
const v = this.map[k];
|
|
535
|
+
if (str === v) {
|
|
536
|
+
return v;
|
|
537
|
+
}
|
|
538
|
+
if (str === this.convertForGQL(k)) {
|
|
539
|
+
return v;
|
|
540
|
+
}
|
|
423
541
|
}
|
|
424
542
|
}
|
|
425
543
|
// whelp, just return what's passed
|
|
@@ -436,6 +554,7 @@ class ListField extends BaseField {
|
|
|
436
554
|
constructor(field, options) {
|
|
437
555
|
super();
|
|
438
556
|
this.field = field;
|
|
557
|
+
this.validators = [];
|
|
439
558
|
if (field.type.dbType === schema_1.DBType.List) {
|
|
440
559
|
throw new Error(`nested lists not currently supported`);
|
|
441
560
|
}
|
|
@@ -445,36 +564,92 @@ class ListField extends BaseField {
|
|
|
445
564
|
};
|
|
446
565
|
Object.assign(this, options);
|
|
447
566
|
}
|
|
448
|
-
|
|
567
|
+
validate(validator) {
|
|
568
|
+
this.validators.push(validator);
|
|
569
|
+
return this;
|
|
570
|
+
}
|
|
571
|
+
async valid(val) {
|
|
449
572
|
if (!Array.isArray(val)) {
|
|
450
573
|
return false;
|
|
451
574
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
455
|
-
for (const v of val) {
|
|
456
|
-
if (!this.field.valid(v)) {
|
|
575
|
+
for (const validator of this.validators) {
|
|
576
|
+
if (!validator(val)) {
|
|
457
577
|
return false;
|
|
458
578
|
}
|
|
459
579
|
}
|
|
460
|
-
|
|
580
|
+
const valid = this.field.valid;
|
|
581
|
+
if (!valid) {
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
const res = valid.apply(this.field, [val[0]]);
|
|
585
|
+
if (util_1.types.isPromise(res)) {
|
|
586
|
+
const ret = await Promise.all(val.map(async (v) => await valid.apply(this.field, [v])));
|
|
587
|
+
return ret.every((v) => v);
|
|
588
|
+
}
|
|
589
|
+
const ret = val.map((v) => valid.apply(this.field, [v]));
|
|
590
|
+
const result = ret.every((v) => v);
|
|
591
|
+
return result;
|
|
592
|
+
}
|
|
593
|
+
postgresVal(val, jsonType) {
|
|
594
|
+
if (!jsonType) {
|
|
595
|
+
return val;
|
|
596
|
+
}
|
|
597
|
+
return JSON.stringify(val);
|
|
461
598
|
}
|
|
462
599
|
format(val) {
|
|
463
600
|
if (!Array.isArray(val)) {
|
|
464
601
|
throw new Error(`need an array to format`);
|
|
465
602
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
603
|
+
const elemDBType = this.type.listElemType.dbType;
|
|
604
|
+
const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
|
|
605
|
+
const postgres = db_1.default.getDialect() === db_1.Dialect.Postgres;
|
|
606
|
+
if (!postgres && !this.field.format) {
|
|
607
|
+
return JSON.stringify(val);
|
|
608
|
+
}
|
|
609
|
+
let ret = [];
|
|
610
|
+
let postgresRet = "{";
|
|
611
|
+
for (let i = 0; i < val.length; i++) {
|
|
612
|
+
let formatted = val[i];
|
|
613
|
+
if (this.field.format) {
|
|
614
|
+
formatted = this.field.format(val[i]);
|
|
615
|
+
}
|
|
616
|
+
// postgres supports arrays natively so we
|
|
617
|
+
// structure it in the expected format
|
|
618
|
+
if (postgres) {
|
|
619
|
+
postgresRet += this.postgresVal(formatted, jsonType);
|
|
620
|
+
if (i !== val.length - 1) {
|
|
621
|
+
postgresRet += ",";
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
ret[i] = formatted;
|
|
469
626
|
}
|
|
470
627
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
|
|
474
|
-
return `{${val.join(",")}}`;
|
|
628
|
+
if (postgres) {
|
|
629
|
+
return postgresRet + "}";
|
|
475
630
|
}
|
|
476
|
-
|
|
477
|
-
|
|
631
|
+
return JSON.stringify(ret);
|
|
632
|
+
}
|
|
633
|
+
minLen(l) {
|
|
634
|
+
return this.validate((val) => val.length >= l);
|
|
635
|
+
}
|
|
636
|
+
maxLen(l) {
|
|
637
|
+
return this.validate((val) => val.length <= l);
|
|
638
|
+
}
|
|
639
|
+
length(l) {
|
|
640
|
+
return this.validate((val) => val.length === l);
|
|
641
|
+
}
|
|
642
|
+
// like python's range() function
|
|
643
|
+
// start is where to start and stop is the number to stop (not inclusive in the range)
|
|
644
|
+
range(start, stop) {
|
|
645
|
+
return this.validate((val) => {
|
|
646
|
+
for (const v of val) {
|
|
647
|
+
if (v < start || v >= stop) {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return true;
|
|
652
|
+
});
|
|
478
653
|
}
|
|
479
654
|
}
|
|
480
655
|
exports.ListField = ListField;
|
|
@@ -486,10 +661,18 @@ function IntListType(options) {
|
|
|
486
661
|
return new ListField(IntegerType(options), options);
|
|
487
662
|
}
|
|
488
663
|
exports.IntListType = IntListType;
|
|
664
|
+
function IntegerListType(options) {
|
|
665
|
+
return new ListField(IntegerType(options), options);
|
|
666
|
+
}
|
|
667
|
+
exports.IntegerListType = IntegerListType;
|
|
489
668
|
function FloatListType(options) {
|
|
490
669
|
return new ListField(FloatType(options), options);
|
|
491
670
|
}
|
|
492
671
|
exports.FloatListType = FloatListType;
|
|
672
|
+
function BigIntegerListType(options) {
|
|
673
|
+
return new ListField(BigIntegerType(options), options);
|
|
674
|
+
}
|
|
675
|
+
exports.BigIntegerListType = BigIntegerListType;
|
|
493
676
|
function BooleanListType(options) {
|
|
494
677
|
return new ListField(BooleanType(options), options);
|
|
495
678
|
}
|
|
@@ -528,3 +711,7 @@ function EnumListType(options) {
|
|
|
528
711
|
return new ListField(EnumType(options), options);
|
|
529
712
|
}
|
|
530
713
|
exports.EnumListType = EnumListType;
|
|
714
|
+
function UUIDListType(options) {
|
|
715
|
+
return new ListField(UUIDType(options), options);
|
|
716
|
+
}
|
|
717
|
+
exports.UUIDListType = UUIDListType;
|
package/schema/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { Schema };
|
|
|
3
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";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
|
+
export * from "./json_field";
|
package/schema/index.js
CHANGED
|
@@ -25,3 +25,4 @@ Object.defineProperty(exports, "Node", { enumerable: true, get: function () { re
|
|
|
25
25
|
Object.defineProperty(exports, "BaseEntSchema", { enumerable: true, get: function () { return base_schema_1.BaseEntSchema; } });
|
|
26
26
|
Object.defineProperty(exports, "BaseEntSchemaWithTZ", { enumerable: true, get: function () { return base_schema_1.BaseEntSchemaWithTZ; } });
|
|
27
27
|
__exportStar(require("./field"), exports);
|
|
28
|
+
__exportStar(require("./json_field"), exports);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FieldOptions, Type, Field, ImportType } from "./schema";
|
|
2
|
+
import { BaseField, ListField } from "./field";
|
|
3
|
+
export interface JSONOptions extends FieldOptions {
|
|
4
|
+
validator?: (val: any) => boolean;
|
|
5
|
+
importType?: ImportType;
|
|
6
|
+
}
|
|
7
|
+
export declare class JSONField extends BaseField implements Field {
|
|
8
|
+
private options;
|
|
9
|
+
type: Type;
|
|
10
|
+
constructor(jsonb: boolean, options: JSONOptions);
|
|
11
|
+
format(val: any): string;
|
|
12
|
+
valid(val: any): boolean;
|
|
13
|
+
}
|
|
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;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JSONListType = exports.JSONBListType = exports.JSONBType = exports.JSONType = exports.JSONField = void 0;
|
|
4
|
+
const schema_1 = require("./schema");
|
|
5
|
+
const field_1 = require("./field");
|
|
6
|
+
class JSONField extends field_1.BaseField {
|
|
7
|
+
constructor(jsonb, options) {
|
|
8
|
+
super();
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.type = {
|
|
11
|
+
dbType: schema_1.DBType.JSON,
|
|
12
|
+
};
|
|
13
|
+
if (jsonb) {
|
|
14
|
+
this.type.dbType = schema_1.DBType.JSONB;
|
|
15
|
+
}
|
|
16
|
+
if (options.importType) {
|
|
17
|
+
this.type.importType = options.importType;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
format(val) {
|
|
21
|
+
return JSON.stringify(val);
|
|
22
|
+
}
|
|
23
|
+
valid(val) {
|
|
24
|
+
if (this.options.validator) {
|
|
25
|
+
return this.options.validator(val);
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.JSONField = JSONField;
|
|
31
|
+
function JSONType(options) {
|
|
32
|
+
let result = new JSONField(false, options);
|
|
33
|
+
return Object.assign(result, options);
|
|
34
|
+
}
|
|
35
|
+
exports.JSONType = JSONType;
|
|
36
|
+
function JSONBType(options) {
|
|
37
|
+
let result = new JSONField(true, options);
|
|
38
|
+
return Object.assign(result, options);
|
|
39
|
+
}
|
|
40
|
+
exports.JSONBType = JSONBType;
|
|
41
|
+
function JSONBListType(options) {
|
|
42
|
+
return new field_1.ListField(JSONBType(options), options);
|
|
43
|
+
}
|
|
44
|
+
exports.JSONBListType = JSONBListType;
|
|
45
|
+
function JSONListType(options) {
|
|
46
|
+
return new field_1.ListField(JSONType(options), options);
|
|
47
|
+
}
|
|
48
|
+
exports.JSONListType = JSONListType;
|
package/schema/schema.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Data, Ent, LoaderInfo } from "../core/base";
|
|
2
|
+
import { Builder } from "../action/action";
|
|
1
3
|
export default interface Schema {
|
|
2
4
|
fields: Field[];
|
|
3
5
|
tableName?: string;
|
|
@@ -22,6 +24,7 @@ export interface AssocEdge {
|
|
|
22
24
|
tableName?: string;
|
|
23
25
|
edgeActions?: EdgeAction[];
|
|
24
26
|
hideFromGraphQL?: boolean;
|
|
27
|
+
edgeConstName?: string;
|
|
25
28
|
}
|
|
26
29
|
export interface EdgeAction {
|
|
27
30
|
operation: ActionOperation;
|
|
@@ -32,6 +35,7 @@ export interface EdgeAction {
|
|
|
32
35
|
}
|
|
33
36
|
export interface InverseAssocEdge {
|
|
34
37
|
name: string;
|
|
38
|
+
edgeConstName?: string;
|
|
35
39
|
}
|
|
36
40
|
export interface EdgeGroupAction {
|
|
37
41
|
operation: ActionOperation.EdgeGroup;
|
|
@@ -52,18 +56,22 @@ export interface AssocEdgeGroup {
|
|
|
52
56
|
}
|
|
53
57
|
export declare type Edge = AssocEdge;
|
|
54
58
|
export interface Pattern {
|
|
59
|
+
name: string;
|
|
55
60
|
fields: Field[];
|
|
61
|
+
edges?: Edge[];
|
|
56
62
|
}
|
|
57
63
|
export declare enum DBType {
|
|
58
64
|
UUID = "UUID",
|
|
59
65
|
Int64ID = "Int64ID",
|
|
60
66
|
Boolean = "Boolean",
|
|
61
67
|
Int = "Int",
|
|
68
|
+
BigInt = "BigInt",
|
|
62
69
|
Float = "Float",
|
|
63
70
|
String = "String",
|
|
64
71
|
Timestamp = "Timestamp",
|
|
65
72
|
Timestamptz = "Timestamptz",
|
|
66
73
|
JSON = "JSON",
|
|
74
|
+
JSONB = "JSONB",
|
|
67
75
|
Enum = "Enum",
|
|
68
76
|
StringEnum = "StringEnum",
|
|
69
77
|
Date = "Date",
|
|
@@ -71,22 +79,42 @@ export declare enum DBType {
|
|
|
71
79
|
Timetz = "Timetz",
|
|
72
80
|
List = "List"
|
|
73
81
|
}
|
|
82
|
+
export interface ImportType {
|
|
83
|
+
path: string;
|
|
84
|
+
type: string;
|
|
85
|
+
}
|
|
86
|
+
declare type EnumMap = {
|
|
87
|
+
[key: string]: string;
|
|
88
|
+
};
|
|
74
89
|
export interface Type {
|
|
75
90
|
dbType: DBType;
|
|
76
91
|
listElemType?: Type;
|
|
77
92
|
type?: string;
|
|
78
93
|
graphQLType?: string;
|
|
79
94
|
values?: string[];
|
|
95
|
+
enumMap?: EnumMap;
|
|
96
|
+
importType?: ImportType;
|
|
80
97
|
}
|
|
81
98
|
export interface ForeignKey {
|
|
82
99
|
schema: string;
|
|
83
100
|
column: string;
|
|
84
101
|
name?: string;
|
|
85
102
|
disableIndex?: boolean;
|
|
103
|
+
disableBuilderType?: boolean;
|
|
104
|
+
}
|
|
105
|
+
declare type getLoaderInfoFn = (type: string) => LoaderInfo;
|
|
106
|
+
export interface InverseFieldEdge {
|
|
107
|
+
name: string;
|
|
108
|
+
edgeConstName?: string;
|
|
109
|
+
tableName?: string;
|
|
110
|
+
hideFromGraphQL?: boolean;
|
|
86
111
|
}
|
|
87
112
|
export interface FieldEdge {
|
|
88
113
|
schema: string;
|
|
89
|
-
inverseEdge
|
|
114
|
+
inverseEdge?: string | InverseFieldEdge;
|
|
115
|
+
enforceSchema?: boolean;
|
|
116
|
+
getLoaderInfoFromSchema?: getLoaderInfoFn;
|
|
117
|
+
disableBuilderType?: boolean;
|
|
90
118
|
}
|
|
91
119
|
export interface FieldOptions {
|
|
92
120
|
name: string;
|
|
@@ -103,8 +131,9 @@ export interface FieldOptions {
|
|
|
103
131
|
fieldEdge?: FieldEdge;
|
|
104
132
|
primaryKey?: boolean;
|
|
105
133
|
disableUserEditable?: boolean;
|
|
106
|
-
defaultValueOnCreate?(): any;
|
|
107
|
-
|
|
134
|
+
defaultValueOnCreate?(builder: Builder<Ent>, input: Data): any;
|
|
135
|
+
defaultToViewerOnCreate?: boolean;
|
|
136
|
+
defaultValueOnEdit?(builder: Builder<Ent>, input: Data): any;
|
|
108
137
|
derivedWhenEmbedded?: boolean;
|
|
109
138
|
polymorphic?: boolean | PolymorphicOptions;
|
|
110
139
|
derivedFields?: Field[];
|
|
@@ -112,10 +141,11 @@ export interface FieldOptions {
|
|
|
112
141
|
export interface PolymorphicOptions {
|
|
113
142
|
types?: string[];
|
|
114
143
|
hideFromInverseGraphQL?: boolean;
|
|
144
|
+
disableBuilderType?: boolean;
|
|
115
145
|
}
|
|
116
146
|
export interface Field extends FieldOptions {
|
|
117
147
|
type: Type;
|
|
118
|
-
valid?(val: any): boolean;
|
|
148
|
+
valid?(val: any): Promise<boolean> | boolean;
|
|
119
149
|
format?(val: any): any;
|
|
120
150
|
logValue(val: any): any;
|
|
121
151
|
}
|
|
@@ -141,6 +171,7 @@ export interface ActionField {
|
|
|
141
171
|
nullable?: boolean | NullableListOptions;
|
|
142
172
|
list?: boolean;
|
|
143
173
|
actionName?: string;
|
|
174
|
+
excludedFields?: string[];
|
|
144
175
|
}
|
|
145
176
|
export interface Action {
|
|
146
177
|
operation: ActionOperation;
|
|
@@ -150,6 +181,10 @@ export interface Action {
|
|
|
150
181
|
graphQLName?: string;
|
|
151
182
|
hideFromGraphQL?: boolean;
|
|
152
183
|
actionOnlyFields?: ActionField[];
|
|
184
|
+
excludedFields?: string[];
|
|
185
|
+
optionalFields?: string[];
|
|
186
|
+
requiredFields?: string[];
|
|
187
|
+
noFields?: boolean;
|
|
153
188
|
}
|
|
154
189
|
export declare const NoFields = "__NO_FIELDS__";
|
|
155
190
|
export declare function requiredField(field: string): string;
|
package/schema/schema.js
CHANGED
|
@@ -10,12 +10,14 @@ var DBType;
|
|
|
10
10
|
DBType["Int64ID"] = "Int64ID";
|
|
11
11
|
DBType["Boolean"] = "Boolean";
|
|
12
12
|
DBType["Int"] = "Int";
|
|
13
|
+
DBType["BigInt"] = "BigInt";
|
|
13
14
|
DBType["Float"] = "Float";
|
|
14
15
|
DBType["String"] = "String";
|
|
15
16
|
//
|
|
16
17
|
DBType["Timestamp"] = "Timestamp";
|
|
17
18
|
DBType["Timestamptz"] = "Timestamptz";
|
|
18
19
|
DBType["JSON"] = "JSON";
|
|
20
|
+
DBType["JSONB"] = "JSONB";
|
|
19
21
|
DBType["Enum"] = "Enum";
|
|
20
22
|
DBType["StringEnum"] = "StringEnum";
|
|
21
23
|
DBType["Date"] = "Date";
|