@snowtop/ent 0.0.2 → 0.0.3-4.alpha
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.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 +41 -0
- package/parse_schema/parse.js +147 -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 +252 -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,13 @@ 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");
|
|
25
|
+
const camel_case_1 = require("camel-case");
|
|
26
26
|
const db_1 = __importStar(require("../core/db"));
|
|
27
|
+
const schema_1 = require("./schema");
|
|
28
|
+
const util_1 = require("util");
|
|
27
29
|
class BaseField {
|
|
28
30
|
logValue(val) {
|
|
29
31
|
if (this.sensitive) {
|
|
@@ -37,6 +39,7 @@ exports.BaseField = BaseField;
|
|
|
37
39
|
class UUIDField extends BaseField {
|
|
38
40
|
constructor(options) {
|
|
39
41
|
super();
|
|
42
|
+
this.options = options;
|
|
40
43
|
this.type = { dbType: schema_1.DBType.UUID };
|
|
41
44
|
const polymorphic = options.polymorphic;
|
|
42
45
|
if (polymorphic) {
|
|
@@ -64,6 +67,7 @@ class UUIDField extends BaseField {
|
|
|
64
67
|
values: polymorphic.types,
|
|
65
68
|
hideFromGraphQL: true,
|
|
66
69
|
derivedWhenEmbedded: true,
|
|
70
|
+
nullable: options.nullable,
|
|
67
71
|
}),
|
|
68
72
|
];
|
|
69
73
|
}
|
|
@@ -74,10 +78,52 @@ class UUIDField extends BaseField {
|
|
|
74
78
|
name,
|
|
75
79
|
hideFromGraphQL: true,
|
|
76
80
|
derivedWhenEmbedded: true,
|
|
81
|
+
nullable: options.nullable,
|
|
77
82
|
}),
|
|
78
83
|
];
|
|
79
84
|
}
|
|
80
85
|
}
|
|
86
|
+
if (options.fieldEdge?.enforceSchema &&
|
|
87
|
+
!options.fieldEdge.getLoaderOptions) {
|
|
88
|
+
throw new Error(`cannot enforceSchema if getLoaderOptions wasn't passed in`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
isBuilder(val) {
|
|
92
|
+
return val.placeholderID !== undefined;
|
|
93
|
+
}
|
|
94
|
+
async valid(val) {
|
|
95
|
+
if (!this.options.fieldEdge?.enforceSchema) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// move loaders to their own file
|
|
99
|
+
// tableName, fields, all loaders in a file
|
|
100
|
+
// loader.ts
|
|
101
|
+
// loadAny.ts loads that...
|
|
102
|
+
// need a mapping to NodeType
|
|
103
|
+
// add NodeType to Builder and use that?
|
|
104
|
+
// instead of loaderOptions
|
|
105
|
+
// TODO #510 consistency.
|
|
106
|
+
// want getLoaderFromSchema and getLoaderFromNodeType
|
|
107
|
+
// or just go from Schema -> NodeType -> getLoaderFromNodeType
|
|
108
|
+
const f = (0, camel_case_1.camelCase)(this.options.fieldEdge.schema);
|
|
109
|
+
const getLoaderOptions = this.options.fieldEdge.getLoaderOptions;
|
|
110
|
+
const loadRowOptions = getLoaderOptions(f);
|
|
111
|
+
// loadRowOptions.fields
|
|
112
|
+
// can check fields and tableName without checking ent to deal with
|
|
113
|
+
// circular dependencies issues?
|
|
114
|
+
// and now this. what do we want to compare tableName and fields? something about builder eq NodeType...
|
|
115
|
+
if (!loadRowOptions) {
|
|
116
|
+
throw new Error(`couldn't get loaderOptions for ${f}`);
|
|
117
|
+
}
|
|
118
|
+
console.debug(val);
|
|
119
|
+
if (this.isBuilder(val)) {
|
|
120
|
+
console.debug("is buiklder");
|
|
121
|
+
// if builder, the ent type of the builder and the ent type returned by the load constructor should match
|
|
122
|
+
return val.ent === loadRowOptions.ent;
|
|
123
|
+
}
|
|
124
|
+
// TODO we need context here to make sure that we hit local cache
|
|
125
|
+
const row = await loadRowOptions.loaderFactory.createLoader().load(val);
|
|
126
|
+
return row !== null;
|
|
81
127
|
}
|
|
82
128
|
}
|
|
83
129
|
exports.UUIDField = UUIDField;
|
|
@@ -87,17 +133,67 @@ function UUIDType(options) {
|
|
|
87
133
|
}
|
|
88
134
|
exports.UUIDType = UUIDType;
|
|
89
135
|
class IntegerField extends BaseField {
|
|
90
|
-
constructor() {
|
|
91
|
-
super(
|
|
136
|
+
constructor(options) {
|
|
137
|
+
super();
|
|
92
138
|
this.type = { dbType: schema_1.DBType.Int };
|
|
139
|
+
this.validators = [];
|
|
140
|
+
this.options = { name: "field" };
|
|
141
|
+
// for legacy callers
|
|
142
|
+
this.handleOptions(options || this.options);
|
|
143
|
+
}
|
|
144
|
+
getOptions() {
|
|
145
|
+
return this.options;
|
|
146
|
+
}
|
|
147
|
+
handleOptions(options) {
|
|
148
|
+
const params = {
|
|
149
|
+
min: this.min,
|
|
150
|
+
max: this.max,
|
|
151
|
+
};
|
|
152
|
+
for (const k in params) {
|
|
153
|
+
const v = options[k];
|
|
154
|
+
if (v !== undefined) {
|
|
155
|
+
params[k].apply(this, [v]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.options = options;
|
|
159
|
+
}
|
|
160
|
+
min(l) {
|
|
161
|
+
return this.validate((val) => val >= l);
|
|
162
|
+
}
|
|
163
|
+
max(l) {
|
|
164
|
+
return this.validate((val) => val <= l);
|
|
165
|
+
}
|
|
166
|
+
valid(val) {
|
|
167
|
+
for (const validator of this.validators) {
|
|
168
|
+
if (!validator(val)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
validate(validator) {
|
|
175
|
+
this.validators.push(validator);
|
|
176
|
+
return this;
|
|
93
177
|
}
|
|
94
178
|
}
|
|
95
179
|
exports.IntegerField = IntegerField;
|
|
96
180
|
function IntegerType(options) {
|
|
97
|
-
let result = new IntegerField();
|
|
181
|
+
let result = new IntegerField(options);
|
|
98
182
|
return Object.assign(result, options);
|
|
99
183
|
}
|
|
100
184
|
exports.IntegerType = IntegerType;
|
|
185
|
+
class BigIntegerField extends BaseField {
|
|
186
|
+
constructor() {
|
|
187
|
+
super(...arguments);
|
|
188
|
+
this.type = { dbType: schema_1.DBType.BigInt };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.BigIntegerField = BigIntegerField;
|
|
192
|
+
function BigIntegerType(options) {
|
|
193
|
+
let result = new BigIntegerField();
|
|
194
|
+
return Object.assign(result, options);
|
|
195
|
+
}
|
|
196
|
+
exports.BigIntegerType = BigIntegerType;
|
|
101
197
|
class FloatField extends BaseField {
|
|
102
198
|
constructor() {
|
|
103
199
|
super(...arguments);
|
|
@@ -128,11 +224,12 @@ class StringField extends BaseField {
|
|
|
128
224
|
this.type = { dbType: schema_1.DBType.String };
|
|
129
225
|
this.validators = [];
|
|
130
226
|
this.formatters = [];
|
|
227
|
+
this.options = { name: "field" };
|
|
131
228
|
// for legacy callers
|
|
132
229
|
this.handleOptions(options || { name: "field" });
|
|
133
230
|
}
|
|
134
231
|
getOptions() {
|
|
135
|
-
return this.
|
|
232
|
+
return this.options;
|
|
136
233
|
}
|
|
137
234
|
handleOptions(options) {
|
|
138
235
|
const noParams = {
|
|
@@ -160,6 +257,7 @@ class StringField extends BaseField {
|
|
|
160
257
|
noParams[k].apply(this);
|
|
161
258
|
}
|
|
162
259
|
}
|
|
260
|
+
this.options = options;
|
|
163
261
|
}
|
|
164
262
|
minLen(l) {
|
|
165
263
|
return this.validate((val) => {
|
|
@@ -310,12 +408,12 @@ class TimeField extends BaseField {
|
|
|
310
408
|
if (this.withTimezone) {
|
|
311
409
|
// for some reason this API is backwards
|
|
312
410
|
let div = (val.getTimezoneOffset() / 60) * -1;
|
|
313
|
-
offset = exports.leftPad(div);
|
|
411
|
+
offset = (0, exports.leftPad)(div);
|
|
314
412
|
}
|
|
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());
|
|
413
|
+
let hh = (0, exports.leftPad)(val.getHours());
|
|
414
|
+
let mm = (0, exports.leftPad)(val.getMinutes());
|
|
415
|
+
let ss = (0, exports.leftPad)(val.getSeconds());
|
|
416
|
+
let ms = (0, exports.leftPad)(val.getMilliseconds());
|
|
319
417
|
if (ms !== "00" && offset) {
|
|
320
418
|
return `${hh}:${mm}:${ss}.${ms}${offset}`;
|
|
321
419
|
}
|
|
@@ -348,11 +446,11 @@ class DateField extends BaseField {
|
|
|
348
446
|
if (!(val instanceof Date)) {
|
|
349
447
|
return val;
|
|
350
448
|
}
|
|
351
|
-
let yy = exports.leftPad(val.getFullYear());
|
|
449
|
+
let yy = (0, exports.leftPad)(val.getFullYear());
|
|
352
450
|
// lol this API
|
|
353
451
|
// for some reason this is 0-index
|
|
354
|
-
let mm = exports.leftPad(val.getMonth() + 1);
|
|
355
|
-
let dd = exports.leftPad(val.getDate());
|
|
452
|
+
let mm = (0, exports.leftPad)(val.getMonth() + 1);
|
|
453
|
+
let dd = (0, exports.leftPad)(val.getDate());
|
|
356
454
|
let ret = `${yy}-${mm}-${dd}`;
|
|
357
455
|
return ret;
|
|
358
456
|
}
|
|
@@ -370,20 +468,33 @@ class EnumField extends BaseField {
|
|
|
370
468
|
// if createEnumType boolean, we create postgres enum otherwise we use a string for it
|
|
371
469
|
dbType: options.createEnumType ? schema_1.DBType.Enum : schema_1.DBType.StringEnum,
|
|
372
470
|
values: options.values,
|
|
471
|
+
enumMap: options.map,
|
|
373
472
|
type: options.tsType || options.name,
|
|
374
473
|
graphQLType: options.graphQLType || options.name,
|
|
375
474
|
};
|
|
376
475
|
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");
|
|
476
|
+
if (!options.values && !options.map) {
|
|
477
|
+
throw new Error("values or map required if not look up table enum. Look-up table enum indicated by foreignKey field");
|
|
379
478
|
}
|
|
380
|
-
if (
|
|
381
|
-
|
|
479
|
+
if (options.values) {
|
|
480
|
+
if (!options.values.length) {
|
|
481
|
+
throw new Error("need at least one value in enum type");
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (options.map) {
|
|
485
|
+
let count = 0;
|
|
486
|
+
for (const k in options.map) {
|
|
487
|
+
count++;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
if (!count) {
|
|
491
|
+
throw new Error("need at least one entry in enum map");
|
|
492
|
+
}
|
|
382
493
|
}
|
|
383
494
|
}
|
|
384
495
|
else {
|
|
385
|
-
if (options.values) {
|
|
386
|
-
throw new Error("cannot specify values and foreign key for lookup table enum type");
|
|
496
|
+
if (options.values || options.map) {
|
|
497
|
+
throw new Error("cannot specify values or map and foreign key for lookup table enum type");
|
|
387
498
|
}
|
|
388
499
|
if (options.createEnumType) {
|
|
389
500
|
throw new Error("cannot specify createEnumType without specifying values");
|
|
@@ -396,30 +507,55 @@ class EnumField extends BaseField {
|
|
|
396
507
|
}
|
|
397
508
|
}
|
|
398
509
|
this.values = options.values;
|
|
510
|
+
this.map = options.map;
|
|
399
511
|
}
|
|
512
|
+
// TODO need to update this for map
|
|
400
513
|
convertForGQL(value) {
|
|
401
|
-
return snake_case_1.snakeCase(value).toUpperCase();
|
|
514
|
+
return (0, snake_case_1.snakeCase)(value).toUpperCase();
|
|
402
515
|
}
|
|
403
516
|
valid(val) {
|
|
404
517
|
// lookup table enum and indicated via presence of foreignKey
|
|
405
|
-
if (!this.values) {
|
|
518
|
+
if (!this.values && !this.map) {
|
|
406
519
|
return true;
|
|
407
520
|
}
|
|
408
|
-
|
|
409
|
-
|
|
521
|
+
if (this.values) {
|
|
522
|
+
let str = String(val);
|
|
523
|
+
return this.values.some((value) => value === str || this.convertForGQL(value) === str);
|
|
524
|
+
}
|
|
525
|
+
for (const k in this.map) {
|
|
526
|
+
const v = this.map[k];
|
|
527
|
+
if (v === val || this.convertForGQL(k) === val) {
|
|
528
|
+
// TODO decide on behavior for GQL since GQL only supports one type
|
|
529
|
+
return true;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return false;
|
|
410
533
|
}
|
|
411
534
|
format(val) {
|
|
412
535
|
// TODO need to format correctly for graphql purposes...
|
|
413
536
|
// how to best get the values in the db...
|
|
414
|
-
if (!this.values) {
|
|
537
|
+
if (!this.values && !this.map) {
|
|
415
538
|
return val;
|
|
416
539
|
}
|
|
417
540
|
let str = String(val);
|
|
418
|
-
|
|
419
|
-
let
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
541
|
+
if (this.values) {
|
|
542
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
543
|
+
let value = this.values[i];
|
|
544
|
+
// store the format that maps to the given value in the db instead of saving the upper case value
|
|
545
|
+
if (str === value || str === this.convertForGQL(value)) {
|
|
546
|
+
return value;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (this.map) {
|
|
551
|
+
for (const k in this.map) {
|
|
552
|
+
const v = this.map[k];
|
|
553
|
+
if (str === v) {
|
|
554
|
+
return v;
|
|
555
|
+
}
|
|
556
|
+
if (str === this.convertForGQL(k)) {
|
|
557
|
+
return v;
|
|
558
|
+
}
|
|
423
559
|
}
|
|
424
560
|
}
|
|
425
561
|
// whelp, just return what's passed
|
|
@@ -436,6 +572,7 @@ class ListField extends BaseField {
|
|
|
436
572
|
constructor(field, options) {
|
|
437
573
|
super();
|
|
438
574
|
this.field = field;
|
|
575
|
+
this.validators = [];
|
|
439
576
|
if (field.type.dbType === schema_1.DBType.List) {
|
|
440
577
|
throw new Error(`nested lists not currently supported`);
|
|
441
578
|
}
|
|
@@ -445,36 +582,92 @@ class ListField extends BaseField {
|
|
|
445
582
|
};
|
|
446
583
|
Object.assign(this, options);
|
|
447
584
|
}
|
|
448
|
-
|
|
585
|
+
validate(validator) {
|
|
586
|
+
this.validators.push(validator);
|
|
587
|
+
return this;
|
|
588
|
+
}
|
|
589
|
+
async valid(val) {
|
|
449
590
|
if (!Array.isArray(val)) {
|
|
450
591
|
return false;
|
|
451
592
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
455
|
-
for (const v of val) {
|
|
456
|
-
if (!this.field.valid(v)) {
|
|
593
|
+
for (const validator of this.validators) {
|
|
594
|
+
if (!validator(val)) {
|
|
457
595
|
return false;
|
|
458
596
|
}
|
|
459
597
|
}
|
|
460
|
-
|
|
598
|
+
const valid = this.field.valid;
|
|
599
|
+
if (!valid) {
|
|
600
|
+
return true;
|
|
601
|
+
}
|
|
602
|
+
const res = valid.apply(this.field, [val[0]]);
|
|
603
|
+
if (util_1.types.isPromise(res)) {
|
|
604
|
+
const ret = await Promise.all(val.map(async (v) => await valid.apply(this.field, [v])));
|
|
605
|
+
return ret.every((v) => v);
|
|
606
|
+
}
|
|
607
|
+
const ret = val.map((v) => valid.apply(this.field, [v]));
|
|
608
|
+
const result = ret.every((v) => v);
|
|
609
|
+
return result;
|
|
610
|
+
}
|
|
611
|
+
postgresVal(val, jsonType) {
|
|
612
|
+
if (!jsonType) {
|
|
613
|
+
return val;
|
|
614
|
+
}
|
|
615
|
+
return JSON.stringify(val);
|
|
461
616
|
}
|
|
462
617
|
format(val) {
|
|
463
618
|
if (!Array.isArray(val)) {
|
|
464
619
|
throw new Error(`need an array to format`);
|
|
465
620
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
621
|
+
const elemDBType = this.type.listElemType.dbType;
|
|
622
|
+
const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
|
|
623
|
+
const postgres = db_1.default.getDialect() === db_1.Dialect.Postgres;
|
|
624
|
+
if (!postgres && !this.field.format) {
|
|
625
|
+
return JSON.stringify(val);
|
|
626
|
+
}
|
|
627
|
+
let ret = [];
|
|
628
|
+
let postgresRet = "{";
|
|
629
|
+
for (let i = 0; i < val.length; i++) {
|
|
630
|
+
let formatted = val[i];
|
|
631
|
+
if (this.field.format) {
|
|
632
|
+
formatted = this.field.format(val[i]);
|
|
633
|
+
}
|
|
634
|
+
// postgres supports arrays natively so we
|
|
635
|
+
// structure it in the expected format
|
|
636
|
+
if (postgres) {
|
|
637
|
+
postgresRet += this.postgresVal(formatted, jsonType);
|
|
638
|
+
if (i !== val.length - 1) {
|
|
639
|
+
postgresRet += ",";
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
ret[i] = formatted;
|
|
469
644
|
}
|
|
470
645
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (db_1.default.getDialect() === db_1.Dialect.Postgres) {
|
|
474
|
-
return `{${val.join(",")}}`;
|
|
646
|
+
if (postgres) {
|
|
647
|
+
return postgresRet + "}";
|
|
475
648
|
}
|
|
476
|
-
|
|
477
|
-
|
|
649
|
+
return JSON.stringify(ret);
|
|
650
|
+
}
|
|
651
|
+
minLen(l) {
|
|
652
|
+
return this.validate((val) => val.length >= l);
|
|
653
|
+
}
|
|
654
|
+
maxLen(l) {
|
|
655
|
+
return this.validate((val) => val.length <= l);
|
|
656
|
+
}
|
|
657
|
+
length(l) {
|
|
658
|
+
return this.validate((val) => val.length === l);
|
|
659
|
+
}
|
|
660
|
+
// like python's range() function
|
|
661
|
+
// start is where to start and stop is the number to stop (not inclusive in the range)
|
|
662
|
+
range(start, stop) {
|
|
663
|
+
return this.validate((val) => {
|
|
664
|
+
for (const v of val) {
|
|
665
|
+
if (v < start || v >= stop) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
return true;
|
|
670
|
+
});
|
|
478
671
|
}
|
|
479
672
|
}
|
|
480
673
|
exports.ListField = ListField;
|
|
@@ -486,10 +679,18 @@ function IntListType(options) {
|
|
|
486
679
|
return new ListField(IntegerType(options), options);
|
|
487
680
|
}
|
|
488
681
|
exports.IntListType = IntListType;
|
|
682
|
+
function IntegerListType(options) {
|
|
683
|
+
return new ListField(IntegerType(options), options);
|
|
684
|
+
}
|
|
685
|
+
exports.IntegerListType = IntegerListType;
|
|
489
686
|
function FloatListType(options) {
|
|
490
687
|
return new ListField(FloatType(options), options);
|
|
491
688
|
}
|
|
492
689
|
exports.FloatListType = FloatListType;
|
|
690
|
+
function BigIntegerListType(options) {
|
|
691
|
+
return new ListField(BigIntegerType(options), options);
|
|
692
|
+
}
|
|
693
|
+
exports.BigIntegerListType = BigIntegerListType;
|
|
493
694
|
function BooleanListType(options) {
|
|
494
695
|
return new ListField(BooleanType(options), options);
|
|
495
696
|
}
|
|
@@ -528,3 +729,7 @@ function EnumListType(options) {
|
|
|
528
729
|
return new ListField(EnumType(options), options);
|
|
529
730
|
}
|
|
530
731
|
exports.EnumListType = EnumListType;
|
|
732
|
+
function UUIDListType(options) {
|
|
733
|
+
return new ListField(UUIDType(options), options);
|
|
734
|
+
}
|
|
735
|
+
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, LoadEntOptions } 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 getLoaderOptionsFn = (type: any) => LoadEntOptions<Ent>;
|
|
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
|
+
getLoaderOptions?: getLoaderOptionsFn;
|
|
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";
|