@snowtop/ent 0.1.0-alpha9 → 0.1.0-alpha90

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.
Files changed (116) hide show
  1. package/action/action.d.ts +36 -31
  2. package/action/action.js +2 -6
  3. package/action/executor.d.ts +3 -3
  4. package/action/executor.js +2 -2
  5. package/action/experimental_action.d.ts +29 -22
  6. package/action/experimental_action.js +29 -6
  7. package/action/orchestrator.d.ts +38 -16
  8. package/action/orchestrator.js +219 -61
  9. package/action/privacy.d.ts +2 -2
  10. package/core/base.d.ts +45 -24
  11. package/core/base.js +7 -1
  12. package/core/clause.d.ts +68 -7
  13. package/core/clause.js +291 -62
  14. package/core/config.d.ts +8 -0
  15. package/core/context.d.ts +5 -3
  16. package/core/context.js +20 -2
  17. package/core/convert.d.ts +1 -1
  18. package/core/db.d.ts +2 -2
  19. package/core/db.js +1 -1
  20. package/core/ent.d.ts +79 -24
  21. package/core/ent.js +520 -168
  22. package/core/loaders/assoc_count_loader.d.ts +2 -2
  23. package/core/loaders/assoc_count_loader.js +6 -1
  24. package/core/loaders/assoc_edge_loader.d.ts +2 -2
  25. package/core/loaders/index.d.ts +1 -1
  26. package/core/loaders/index.js +1 -3
  27. package/core/loaders/index_loader.d.ts +2 -2
  28. package/core/loaders/loader.js +5 -5
  29. package/core/loaders/object_loader.d.ts +6 -5
  30. package/core/loaders/object_loader.js +62 -58
  31. package/core/loaders/query_loader.d.ts +6 -12
  32. package/core/loaders/query_loader.js +47 -10
  33. package/core/loaders/raw_count_loader.d.ts +2 -2
  34. package/core/logger.d.ts +1 -1
  35. package/core/logger.js +1 -0
  36. package/core/privacy.d.ts +26 -25
  37. package/core/privacy.js +21 -25
  38. package/core/query/assoc_query.d.ts +6 -6
  39. package/core/query/custom_clause_query.d.ts +24 -0
  40. package/core/query/custom_clause_query.js +72 -0
  41. package/core/query/custom_query.d.ts +20 -5
  42. package/core/query/custom_query.js +77 -10
  43. package/core/query/index.d.ts +1 -0
  44. package/core/query/index.js +3 -1
  45. package/core/query/query.d.ts +1 -1
  46. package/core/query/query.js +8 -1
  47. package/core/query/shared_assoc_test.d.ts +1 -1
  48. package/core/query/shared_assoc_test.js +17 -5
  49. package/core/query/shared_test.d.ts +3 -0
  50. package/core/query/shared_test.js +211 -30
  51. package/core/viewer.d.ts +3 -3
  52. package/core/viewer.js +1 -1
  53. package/graphql/graphql.js +6 -0
  54. package/graphql/query/edge_connection.d.ts +9 -9
  55. package/graphql/query/page_info.d.ts +1 -1
  56. package/index.d.ts +11 -5
  57. package/index.js +15 -6
  58. package/package.json +1 -1
  59. package/parse_schema/parse.d.ts +12 -3
  60. package/parse_schema/parse.js +70 -11
  61. package/schema/base_schema.js +3 -0
  62. package/schema/field.d.ts +44 -8
  63. package/schema/field.js +125 -9
  64. package/schema/index.d.ts +2 -2
  65. package/schema/json_field.d.ts +13 -1
  66. package/schema/json_field.js +28 -1
  67. package/schema/schema.d.ts +65 -11
  68. package/schema/schema.js +18 -4
  69. package/schema/struct_field.d.ts +11 -1
  70. package/schema/struct_field.js +44 -5
  71. package/scripts/custom_graphql.js +8 -3
  72. package/scripts/{transform_schema.d.ts → migrate_v0.1.d.ts} +0 -0
  73. package/scripts/migrate_v0.1.js +36 -0
  74. package/scripts/read_schema.js +15 -4
  75. package/testutils/builder.d.ts +31 -21
  76. package/testutils/builder.js +83 -29
  77. package/testutils/db/fixture.d.ts +10 -0
  78. package/testutils/db/fixture.js +26 -0
  79. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +15 -3
  80. package/testutils/db/{test_db.js → temp_db.js} +70 -16
  81. package/testutils/db/value.d.ts +6 -0
  82. package/testutils/db/value.js +251 -0
  83. package/testutils/db_time_zone.d.ts +4 -0
  84. package/testutils/db_time_zone.js +41 -0
  85. package/testutils/fake_data/fake_contact.d.ts +5 -4
  86. package/testutils/fake_data/fake_contact.js +14 -6
  87. package/testutils/fake_data/fake_event.d.ts +5 -3
  88. package/testutils/fake_data/fake_event.js +8 -5
  89. package/testutils/fake_data/fake_user.d.ts +4 -4
  90. package/testutils/fake_data/fake_user.js +16 -13
  91. package/testutils/fake_data/test_helpers.d.ts +3 -2
  92. package/testutils/fake_data/test_helpers.js +8 -6
  93. package/testutils/fake_data/user_query.d.ts +8 -6
  94. package/testutils/fake_data/user_query.js +28 -21
  95. package/testutils/fake_log.d.ts +3 -3
  96. package/testutils/parse_sql.d.ts +6 -0
  97. package/testutils/parse_sql.js +16 -2
  98. package/testutils/test_edge_global_schema.d.ts +15 -0
  99. package/testutils/test_edge_global_schema.js +58 -0
  100. package/testutils/write.d.ts +2 -2
  101. package/testutils/write.js +29 -7
  102. package/tsc/ast.d.ts +44 -0
  103. package/tsc/ast.js +267 -0
  104. package/tsc/compilerOptions.d.ts +6 -0
  105. package/tsc/compilerOptions.js +40 -1
  106. package/tsc/move_generated.d.ts +1 -0
  107. package/tsc/move_generated.js +160 -0
  108. package/tsc/transform.d.ts +21 -0
  109. package/tsc/transform.js +167 -0
  110. package/tsc/transform_action.d.ts +22 -0
  111. package/tsc/transform_action.js +179 -0
  112. package/tsc/transform_ent.d.ts +17 -0
  113. package/tsc/transform_ent.js +59 -0
  114. package/tsc/transform_schema.d.ts +27 -0
  115. package/tsc/transform_schema.js +379 -0
  116. package/scripts/transform_schema.js +0 -445
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSchema = void 0;
4
- function processFields(src, patternName) {
4
+ async function processFields(src, patternName) {
5
5
  const ret = [];
6
6
  let m = {};
7
7
  if (Array.isArray(src)) {
@@ -36,6 +36,19 @@ function processFields(src, patternName) {
36
36
  else {
37
37
  delete f.polymorphic;
38
38
  }
39
+ if (field.private) {
40
+ // convert boolean into object
41
+ // we keep boolean as an option to keep API simple
42
+ if (typeof field.private === "boolean") {
43
+ f.private = {};
44
+ }
45
+ else {
46
+ f.private = field.private;
47
+ }
48
+ }
49
+ else {
50
+ delete f.private;
51
+ }
39
52
  // convert string to object to make API consumed by go simple
40
53
  if (f.fieldEdge && f.fieldEdge.inverseEdge) {
41
54
  if (typeof f.fieldEdge.inverseEdge === "string") {
@@ -47,26 +60,48 @@ function processFields(src, patternName) {
47
60
  if (patternName) {
48
61
  f.patternName = patternName;
49
62
  }
63
+ if (field.serverDefault !== undefined) {
64
+ f.serverDefault = await transformServerDefault(name, field, field.serverDefault);
65
+ }
50
66
  transformType(field.type);
51
67
  if (field.getDerivedFields) {
52
- f.derivedFields = processFields(field.getDerivedFields(name));
68
+ f.derivedFields = await processFields(field.getDerivedFields(name));
53
69
  }
54
70
  if (field.type.subFields) {
55
- f.type.subFields = processFields(field.type.subFields);
71
+ f.type.subFields = await processFields(field.type.subFields);
56
72
  }
57
73
  if (field.type.unionFields) {
58
- f.type.unionFields = processFields(field.type.unionFields);
74
+ f.type.unionFields = await processFields(field.type.unionFields);
59
75
  }
60
76
  if (field.type.listElemType &&
61
77
  field.type.listElemType.subFields &&
62
78
  // check to avoid ts-ignore below. exists just for tsc
63
79
  f.type.listElemType) {
64
- f.type.listElemType.subFields = processFields(field.type.listElemType.subFields);
80
+ f.type.listElemType.subFields = await processFields(field.type.listElemType.subFields);
65
81
  }
66
82
  ret.push(f);
67
83
  }
68
84
  return ret;
69
85
  }
86
+ async function transformServerDefault(name, f, value) {
87
+ if (f.valid) {
88
+ if (!(await f.valid(value))) {
89
+ throw new Error(`invalid value ${value} passed to field ${name}`);
90
+ }
91
+ }
92
+ if (f.format) {
93
+ value = await f.format(value);
94
+ }
95
+ switch (typeof value) {
96
+ case "boolean":
97
+ case "number":
98
+ case "bigint":
99
+ case "string":
100
+ return `${value}`;
101
+ default:
102
+ throw new Error(`invalid value ${value} passed to field ${name}`);
103
+ }
104
+ }
70
105
  function transformImportType(typ) {
71
106
  if (!typ.importType) {
72
107
  return;
@@ -108,12 +143,12 @@ function processEdgeGroups(processedSchema, edgeGroups) {
108
143
  processedSchema.assocEdgeGroups.push(group2);
109
144
  }
110
145
  }
111
- function processPattern(patterns, pattern, processedSchema) {
146
+ async function processPattern(patterns, pattern, processedSchema) {
112
147
  let ret = {
113
148
  ...pattern,
114
149
  };
115
150
  const name = pattern.name;
116
- const fields = processFields(pattern.fields, pattern.name);
151
+ const fields = await processFields(pattern.fields, pattern.name);
117
152
  processedSchema.fields.push(...fields);
118
153
  if (pattern.edges) {
119
154
  const edges = processEdges(pattern.edges, pattern.name);
@@ -130,6 +165,7 @@ function processPattern(patterns, pattern, processedSchema) {
130
165
  name: pattern.name,
131
166
  assocEdges: edges,
132
167
  fields: fields,
168
+ disableMixin: pattern.disableMixin,
133
169
  };
134
170
  }
135
171
  else {
@@ -171,9 +207,13 @@ function processAction(action) {
171
207
  ret.actionOnlyFields = actionOnlyFields;
172
208
  return ret;
173
209
  }
174
- function parseSchema(potentialSchemas) {
210
+ async function parseSchema(potentialSchemas, globalSchema) {
175
211
  let schemas = {};
176
212
  let patterns = {};
213
+ let parsedGlobalSchema;
214
+ if (globalSchema) {
215
+ parsedGlobalSchema = await parseGlobalSchema(globalSchema);
216
+ }
177
217
  for (const key in potentialSchemas) {
178
218
  const value = potentialSchemas[key];
179
219
  let schema;
@@ -202,9 +242,11 @@ function parseSchema(potentialSchemas) {
202
242
  };
203
243
  // let's put patterns first just so we have id, created_at, updated_at first
204
244
  // ¯\_(ツ)_/¯
245
+ let patternNames = [];
205
246
  if (schema.patterns) {
206
247
  for (const pattern of schema.patterns) {
207
- const ret = processPattern(patterns, pattern, processedSchema);
248
+ const ret = await processPattern(patterns, pattern, processedSchema);
249
+ patternNames.push(pattern.name);
208
250
  if (ret.transformsSelect) {
209
251
  if (processedSchema.transformsSelect) {
210
252
  throw new Error(`can only have one pattern which transforms default querying behavior`);
@@ -219,8 +261,9 @@ function parseSchema(potentialSchemas) {
219
261
  }
220
262
  }
221
263
  }
222
- const fields = processFields(schema.fields);
264
+ const fields = await processFields(schema.fields);
223
265
  processedSchema.fields.push(...fields);
266
+ processedSchema.patternNames = patternNames;
224
267
  if (schema.edges) {
225
268
  const edges = processEdges(schema.edges);
226
269
  processedSchema.assocEdges.push(...edges);
@@ -230,6 +273,22 @@ function parseSchema(potentialSchemas) {
230
273
  }
231
274
  schemas[key] = processedSchema;
232
275
  }
233
- return { schemas, patterns };
276
+ return { schemas, patterns, globalSchema: parsedGlobalSchema };
234
277
  }
235
278
  exports.parseSchema = parseSchema;
279
+ async function parseGlobalSchema(s) {
280
+ const ret = {
281
+ globalEdges: [],
282
+ extraEdgeFields: [],
283
+ initForEdges: !!s.extraEdgeFields ||
284
+ s.transformEdgeRead !== undefined ||
285
+ s.transformEdgeWrite !== undefined,
286
+ };
287
+ if (s.extraEdgeFields) {
288
+ ret.extraEdgeFields = await processFields(s.extraEdgeFields);
289
+ }
290
+ if (s.edges) {
291
+ ret.globalEdges = processEdges(s.edges);
292
+ }
293
+ return ret;
294
+ }
@@ -66,6 +66,7 @@ let nodeFieldsWithTZ = {
66
66
  exports.Node = {
67
67
  name: "node",
68
68
  fields: nodeFields,
69
+ disableMixin: true,
69
70
  };
70
71
  // Ent schema. has Node Pattern by default.
71
72
  // exists just to have less typing and easier for clients to implement
@@ -95,6 +96,7 @@ class EntSchemaWithTZ {
95
96
  // default schema added
96
97
  name: "nodeWithTZ",
97
98
  fields: nodeFieldsWithTZ,
99
+ disableMixin: true,
98
100
  },
99
101
  ];
100
102
  this.fields = cfg.fields;
@@ -131,6 +133,7 @@ class BaseEntSchemaWithTZ {
131
133
  // default schema added
132
134
  name: "nodeWithTZ",
133
135
  fields: nodeFieldsWithTZ,
136
+ disableMixin: true,
134
137
  },
135
138
  ];
136
139
  }
package/schema/field.d.ts CHANGED
@@ -44,7 +44,7 @@ export declare function IntegerType(options?: IntegerOptions): IntegerField;
44
44
  export declare class BigIntegerField extends BaseField implements Field {
45
45
  type: Type;
46
46
  }
47
- export declare function BigIntegerType(options: FieldOptions): BigIntegerField;
47
+ export declare function BigIntegerType(options?: FieldOptions): BigIntegerField;
48
48
  export declare class FloatField extends BaseField implements Field {
49
49
  type: Type;
50
50
  }
@@ -118,31 +118,66 @@ export declare class DateField extends BaseField implements Field {
118
118
  format(val: any): any;
119
119
  }
120
120
  export declare function DateType(options?: FieldOptions): DateField;
121
- declare type EnumMap = {
121
+ declare type StringEnumMap = {
122
122
  [key: string]: string;
123
123
  };
124
+ /**
125
+ * @deprecated use StringEnumOptions
126
+ */
124
127
  export interface EnumOptions extends FieldOptions {
125
128
  values?: string[];
126
- map?: EnumMap;
129
+ map?: StringEnumMap;
127
130
  tsType?: string;
128
131
  graphQLType?: string;
129
132
  createEnumType?: boolean;
130
133
  }
134
+ /**
135
+ * @deprecated Use StringEnumField
136
+ */
131
137
  export declare class EnumField extends BaseField implements Field {
132
138
  type: Type;
133
139
  private values?;
134
140
  private map?;
135
- constructor(options: EnumOptions);
141
+ constructor(options: StringEnumOptions);
136
142
  convertForGQL(value: string): string;
137
143
  valid(val: any): boolean;
138
144
  format(val: any): any;
139
145
  }
140
- export declare function EnumType(options: EnumOptions): EnumField;
146
+ export declare class StringEnumField extends EnumField {
147
+ }
148
+ export interface PolymorphicStringEnumOptions extends EnumOptions {
149
+ parentFieldToValidate: string;
150
+ }
151
+ export interface StringEnumOptions extends EnumOptions {
152
+ }
153
+ export declare function EnumType(options: StringEnumOptions): EnumField;
154
+ declare type IntEnumMap = {
155
+ [key: string]: number;
156
+ };
157
+ export interface IntegerEnumOptions extends FieldOptions {
158
+ map: IntEnumMap;
159
+ deprecated?: IntEnumMap;
160
+ tsType?: string;
161
+ graphQLType?: string;
162
+ }
163
+ export declare class IntegerEnumField extends BaseField implements Field {
164
+ type: Type;
165
+ private map;
166
+ constructor(options: IntegerEnumOptions);
167
+ valid(val: any): boolean;
168
+ format(val: any): any;
169
+ }
170
+ export declare function IntegerEnumType(options: IntegerEnumOptions): IntegerEnumField;
171
+ interface ListOptions extends FieldOptions {
172
+ disableJSONStringify?: boolean;
173
+ }
141
174
  export declare class ListField extends BaseField {
142
175
  private field;
176
+ private options?;
143
177
  type: Type;
144
178
  private validators;
145
- constructor(field: Field, options?: FieldOptions);
179
+ constructor(field: Field, options?: ListOptions | undefined);
180
+ __getElemField(): Field;
146
181
  validate(validator: (val: any[]) => boolean): this;
147
182
  valid(val: any): Promise<boolean>;
148
183
  private postgresVal;
@@ -153,7 +188,7 @@ export declare class ListField extends BaseField {
153
188
  range(start: any, stop: any): this;
154
189
  }
155
190
  export declare function StringListType(options?: StringOptions): ListField;
156
- export declare function IntListType(options: FieldOptions): ListField;
191
+ export declare function IntListType(options?: FieldOptions): ListField;
157
192
  export declare function IntegerListType(options?: FieldOptions): ListField;
158
193
  export declare function FloatListType(options?: FieldOptions): ListField;
159
194
  export declare function BigIntegerListType(options: FieldOptions): ListField;
@@ -163,6 +198,7 @@ export declare function TimestamptzListType(options?: TimestampOptions): ListFie
163
198
  export declare function TimeListType(options?: TimeOptions): ListField;
164
199
  export declare function TimetzListType(options: TimeOptions): ListField;
165
200
  export declare function DateListType(options?: FieldOptions): ListField;
166
- export declare function EnumListType(options: EnumOptions): ListField;
201
+ export declare function EnumListType(options: StringEnumOptions): ListField;
202
+ export declare function IntegerEnumListType(options: IntegerEnumOptions): ListField;
167
203
  export declare function UUIDListType(options?: FieldOptions): ListField;
168
204
  export {};
package/schema/field.js CHANGED
@@ -19,12 +19,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
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;
22
+ exports.UUIDListType = exports.IntegerEnumListType = 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.IntegerEnumType = exports.IntegerEnumField = exports.EnumType = exports.StringEnumField = 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;
23
23
  const luxon_1 = require("luxon");
24
24
  const snake_case_1 = require("snake-case");
25
+ const util_1 = require("util");
26
+ const uuid_1 = require("uuid");
27
+ const base_1 = require("../core/base");
25
28
  const db_1 = __importStar(require("../core/db"));
26
29
  const schema_1 = require("./schema");
27
- const util_1 = require("util");
28
30
  class BaseField {
29
31
  logValue(val) {
30
32
  if (this.sensitive) {
@@ -67,21 +69,22 @@ class UUIDField extends BaseField {
67
69
  if (typeof polymorphic === "object" && polymorphic.types) {
68
70
  // an enum with types validated here
69
71
  return {
70
- [name]: EnumType({
72
+ [name]: PolymorphicStringEnumType({
71
73
  values: polymorphic.types,
72
74
  hideFromGraphQL: true,
73
75
  derivedWhenEmbedded: true,
74
76
  nullable: this.options?.nullable,
77
+ parentFieldToValidate: fieldName,
75
78
  }),
76
79
  };
77
80
  }
78
81
  else {
79
- // just a string field...
80
82
  return {
81
- [name]: StringType({
83
+ [name]: PolymorphicStringType({
82
84
  hideFromGraphQL: true,
83
85
  derivedWhenEmbedded: true,
84
86
  nullable: this.options?.nullable,
87
+ parentFieldToValidate: fieldName,
85
88
  }),
86
89
  };
87
90
  }
@@ -92,6 +95,9 @@ class UUIDField extends BaseField {
92
95
  return val.placeholderID !== undefined;
93
96
  }
94
97
  async valid(val) {
98
+ if (typeof val === "string" && !(0, uuid_1.validate)(val)) {
99
+ return false;
100
+ }
95
101
  if (!this.options?.fieldEdge?.enforceSchema) {
96
102
  return true;
97
103
  }
@@ -307,6 +313,33 @@ class StringField extends BaseField {
307
313
  }
308
314
  }
309
315
  exports.StringField = StringField;
316
+ function validatePolymorphicTypeWithFullData(val, b, field) {
317
+ const input = b.getInput();
318
+ const inputKey = b.orchestrator.__getOptions().fieldInfo[field].inputKey;
319
+ const v = input[inputKey];
320
+ if (val === null) {
321
+ // if this is being set to null, ok if v is also null
322
+ return v === null;
323
+ }
324
+ // if this is not being set, ok if v is not being set
325
+ if (val === undefined && b.operation === base_1.WriteOperation.Insert) {
326
+ return v === undefined;
327
+ }
328
+ return true;
329
+ }
330
+ class PolymorphicStringField extends StringField {
331
+ constructor(opts) {
332
+ super(opts);
333
+ this.opts = opts;
334
+ }
335
+ validateWithFullData(val, b) {
336
+ return validatePolymorphicTypeWithFullData(val, b, this.opts.parentFieldToValidate);
337
+ }
338
+ }
339
+ function PolymorphicStringType(opts) {
340
+ let result = new PolymorphicStringField(opts);
341
+ return Object.assign(result, opts);
342
+ }
310
343
  function StringType(options) {
311
344
  let result = new StringField(options);
312
345
  const options2 = { ...options };
@@ -426,9 +459,10 @@ class DateField extends BaseField {
426
459
  this.type = { dbType: schema_1.DBType.Date };
427
460
  }
428
461
  format(val) {
429
- if (!(val instanceof Date)) {
462
+ if (typeof val === "string") {
430
463
  return val;
431
464
  }
465
+ val = new Date(val);
432
466
  let yy = (0, exports.leftPad)(val.getFullYear());
433
467
  // lol this API
434
468
  // for some reason this is 0-index
@@ -444,6 +478,9 @@ function DateType(options) {
444
478
  return Object.assign(result, options);
445
479
  }
446
480
  exports.DateType = DateType;
481
+ /**
482
+ * @deprecated Use StringEnumField
483
+ */
447
484
  class EnumField extends BaseField {
448
485
  constructor(options) {
449
486
  super();
@@ -546,15 +583,75 @@ class EnumField extends BaseField {
546
583
  }
547
584
  }
548
585
  exports.EnumField = EnumField;
586
+ class StringEnumField extends EnumField {
587
+ }
588
+ exports.StringEnumField = StringEnumField;
589
+ class PolymorphicStringEnumField extends StringEnumField {
590
+ constructor(opts) {
591
+ super(opts);
592
+ this.opts = opts;
593
+ }
594
+ validateWithFullData(val, b) {
595
+ return validatePolymorphicTypeWithFullData(val, b, this.opts.parentFieldToValidate);
596
+ }
597
+ }
598
+ function PolymorphicStringEnumType(options) {
599
+ let result = new PolymorphicStringEnumField(options);
600
+ return Object.assign(result, options);
601
+ }
549
602
  function EnumType(options) {
550
- let result = new EnumField(options);
603
+ let result = new StringEnumField(options);
551
604
  return Object.assign(result, options);
552
605
  }
553
606
  exports.EnumType = EnumType;
607
+ class IntegerEnumField extends BaseField {
608
+ constructor(options) {
609
+ super();
610
+ this.type = {
611
+ dbType: schema_1.DBType.IntEnum,
612
+ intEnumMap: options.map,
613
+ type: options.tsType,
614
+ graphQLType: options.graphQLType,
615
+ deprecatedIntEnumMap: options.deprecated,
616
+ };
617
+ let count = 0;
618
+ for (const k in options.map) {
619
+ count++;
620
+ break;
621
+ }
622
+ if (!count) {
623
+ throw new Error("need at least one entry in enum map");
624
+ }
625
+ if (options.foreignKey) {
626
+ throw new Error(`foreignKey on intEnum not supported`);
627
+ }
628
+ this.map = options.map;
629
+ }
630
+ valid(val) {
631
+ // lookup table enum and indicated via presence of foreignKey
632
+ for (const k in this.map) {
633
+ const v = this.map[k];
634
+ if (v === val || v === parseInt(val)) {
635
+ return true;
636
+ }
637
+ }
638
+ return false;
639
+ }
640
+ format(val) {
641
+ return parseInt(val);
642
+ }
643
+ }
644
+ exports.IntegerEnumField = IntegerEnumField;
645
+ function IntegerEnumType(options) {
646
+ let result = new IntegerEnumField(options);
647
+ return Object.assign(result, options);
648
+ }
649
+ exports.IntegerEnumType = IntegerEnumType;
554
650
  class ListField extends BaseField {
555
651
  constructor(field, options) {
556
652
  super();
557
653
  this.field = field;
654
+ this.options = options;
558
655
  this.validators = [];
559
656
  if (field.type.dbType === schema_1.DBType.List) {
560
657
  throw new Error(`nested lists not currently supported`);
@@ -565,6 +662,9 @@ class ListField extends BaseField {
565
662
  };
566
663
  Object.assign(this, options);
567
664
  }
665
+ __getElemField() {
666
+ return this.field;
667
+ }
568
668
  validate(validator) {
569
669
  this.validators.push(validator);
570
670
  return this;
@@ -592,7 +692,12 @@ class ListField extends BaseField {
592
692
  return result;
593
693
  }
594
694
  postgresVal(val, jsonType) {
595
- if (!jsonType) {
695
+ if (!jsonType && val === "") {
696
+ // support empty strings in list
697
+ val = '"' + val + '"';
698
+ return val;
699
+ }
700
+ if (this.options?.disableJSONStringify) {
596
701
  return val;
597
702
  }
598
703
  return JSON.stringify(val);
@@ -720,7 +825,18 @@ function EnumListType(options) {
720
825
  return new ListField(EnumType(options), options);
721
826
  }
722
827
  exports.EnumListType = EnumListType;
828
+ function IntegerEnumListType(options) {
829
+ // not all of these will make sense in a list...
830
+ // can make it work eventually but involves work we're not currently trying to do
831
+ // developer can try to work around it by calling below on their own.
832
+ // unclear what the behavior is
833
+ return new ListField(IntegerEnumType(options), options);
834
+ }
835
+ exports.IntegerEnumListType = IntegerEnumListType;
723
836
  function UUIDListType(options) {
724
- return new ListField(UUIDType(options), options);
837
+ return new ListField(UUIDType(options), {
838
+ ...options,
839
+ disableJSONStringify: true,
840
+ });
725
841
  }
726
842
  exports.UUIDListType = UUIDListType;
package/schema/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import Schema from "./schema";
2
2
  export { Schema };
3
- export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
4
- export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, } from "./base_schema";
3
+ export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, } from "./schema";
4
+ export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, SchemaConfig, } from "./base_schema";
5
5
  export * from "./field";
6
6
  export * from "./json_field";
7
7
  export * from "./struct_field";
@@ -4,14 +4,26 @@ export interface JSONOptions extends FieldOptions {
4
4
  validator?: (val: any) => boolean;
5
5
  importType?: ImportType;
6
6
  }
7
+ interface allJSONOptions extends JSONOptions {
8
+ jsonAsList?: boolean;
9
+ }
7
10
  export declare class JSONField extends BaseField implements Field {
8
11
  private options?;
9
12
  type: Type;
10
- constructor(jsonb: boolean, options?: JSONOptions | undefined);
13
+ constructor(jsonb: boolean, options?: allJSONOptions | undefined);
11
14
  format(val: any): string;
12
15
  valid(val: any): boolean;
13
16
  }
14
17
  export declare function JSONType(options?: JSONOptions): JSONField;
15
18
  export declare function JSONBType(options?: JSONOptions): JSONField;
19
+ /**
20
+ * @deprecated use JSONBTypeAsList
21
+ */
16
22
  export declare function JSONBListType(options?: JSONOptions): ListField;
23
+ /**
24
+ * @deprecated use JSONTypeAsList
25
+ */
17
26
  export declare function JSONListType(options?: JSONOptions): ListField;
27
+ export declare function JSONBTypeAsList(options?: JSONOptions): JSONField & JSONOptions;
28
+ export declare function JSONTypeAsList(options?: JSONOptions): JSONField & JSONOptions;
29
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JSONListType = exports.JSONBListType = exports.JSONBType = exports.JSONType = exports.JSONField = void 0;
3
+ exports.JSONTypeAsList = exports.JSONBTypeAsList = exports.JSONListType = exports.JSONBListType = exports.JSONBType = exports.JSONType = exports.JSONField = void 0;
4
4
  const schema_1 = require("./schema");
5
5
  const field_1 = require("./field");
6
6
  class JSONField extends field_1.BaseField {
@@ -16,6 +16,11 @@ class JSONField extends field_1.BaseField {
16
16
  if (options?.importType) {
17
17
  this.type.importType = options.importType;
18
18
  }
19
+ if (options?.jsonAsList) {
20
+ this.type.listElemType = {
21
+ dbType: schema_1.DBType.JSONB,
22
+ };
23
+ }
19
24
  }
20
25
  format(val) {
21
26
  return JSON.stringify(val);
@@ -38,11 +43,33 @@ function JSONBType(options) {
38
43
  return Object.assign(result, options);
39
44
  }
40
45
  exports.JSONBType = JSONBType;
46
+ /**
47
+ * @deprecated use JSONBTypeAsList
48
+ */
41
49
  function JSONBListType(options) {
42
50
  return new field_1.ListField(JSONBType(options), options);
43
51
  }
44
52
  exports.JSONBListType = JSONBListType;
53
+ /**
54
+ * @deprecated use JSONTypeAsList
55
+ */
45
56
  function JSONListType(options) {
46
57
  return new field_1.ListField(JSONType(options), options);
47
58
  }
48
59
  exports.JSONListType = JSONListType;
60
+ function JSONBTypeAsList(options) {
61
+ let result = new JSONField(true, {
62
+ ...options,
63
+ jsonAsList: true,
64
+ });
65
+ return Object.assign(result, options);
66
+ }
67
+ exports.JSONBTypeAsList = JSONBTypeAsList;
68
+ function JSONTypeAsList(options) {
69
+ let result = new JSONField(false, {
70
+ ...options,
71
+ jsonAsList: true,
72
+ });
73
+ return Object.assign(result, options);
74
+ }
75
+ exports.JSONTypeAsList = JSONTypeAsList;