@snowtop/ent 0.0.40-alpha6 → 0.1.0-alpha10

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 (65) hide show
  1. package/action/action.d.ts +14 -14
  2. package/action/executor.d.ts +1 -1
  3. package/action/experimental_action.d.ts +20 -20
  4. package/action/experimental_action.js +1 -1
  5. package/action/orchestrator.d.ts +10 -10
  6. package/action/orchestrator.js +14 -14
  7. package/core/base.d.ts +6 -6
  8. package/core/ent.d.ts +2 -1
  9. package/core/ent.js +14 -10
  10. package/core/privacy.d.ts +1 -1
  11. package/core/query/assoc_query.js +2 -2
  12. package/core/query/query.d.ts +1 -1
  13. package/graphql/builtins/connection.js +3 -3
  14. package/graphql/builtins/edge.js +2 -2
  15. package/graphql/builtins/node.js +1 -1
  16. package/graphql/graphql.js +2 -2
  17. package/graphql/index.d.ts +1 -0
  18. package/graphql/index.js +3 -1
  19. package/graphql/mutations/union.d.ts +2 -0
  20. package/graphql/mutations/union.js +35 -0
  21. package/graphql/query/connection_type.js +6 -6
  22. package/graphql/query/page_info.js +4 -4
  23. package/graphql/query/shared_assoc_test.js +2 -2
  24. package/graphql/scalars/time.d.ts +1 -1
  25. package/imports/index.d.ts +0 -1
  26. package/imports/index.js +3 -36
  27. package/package.json +2 -2
  28. package/parse_schema/parse.d.ts +15 -3
  29. package/parse_schema/parse.js +42 -7
  30. package/schema/base_schema.d.ts +36 -1
  31. package/schema/base_schema.js +63 -17
  32. package/schema/field.d.ts +25 -25
  33. package/schema/field.js +42 -33
  34. package/schema/index.d.ts +4 -2
  35. package/schema/index.js +5 -1
  36. package/schema/json_field.d.ts +6 -6
  37. package/schema/json_field.js +2 -2
  38. package/schema/schema.d.ts +11 -6
  39. package/schema/schema.js +46 -12
  40. package/schema/struct_field.d.ts +17 -0
  41. package/schema/struct_field.js +102 -0
  42. package/schema/union_field.d.ts +23 -0
  43. package/schema/union_field.js +79 -0
  44. package/scripts/custom_compiler.js +2 -19
  45. package/scripts/read_schema.js +15 -1
  46. package/scripts/transform_code.d.ts +1 -0
  47. package/scripts/transform_code.js +114 -0
  48. package/scripts/transform_schema.d.ts +1 -0
  49. package/scripts/transform_schema.js +357 -0
  50. package/testutils/builder.d.ts +19 -15
  51. package/testutils/builder.js +41 -7
  52. package/testutils/db/test_db.js +9 -9
  53. package/testutils/ent-graphql-tests/index.js +19 -12
  54. package/testutils/fake_data/fake_contact.d.ts +3 -7
  55. package/testutils/fake_data/fake_contact.js +14 -26
  56. package/testutils/fake_data/fake_event.d.ts +3 -7
  57. package/testutils/fake_data/fake_event.js +20 -33
  58. package/testutils/fake_data/fake_user.d.ts +3 -7
  59. package/testutils/fake_data/fake_user.js +22 -36
  60. package/testutils/fake_data/test_helpers.js +1 -1
  61. package/testutils/fake_data/user_query.d.ts +2 -2
  62. package/tsc/ast.d.ts +20 -0
  63. package/tsc/ast.js +131 -0
  64. package/tsc/compilerOptions.d.ts +7 -0
  65. package/tsc/compilerOptions.js +95 -0
package/schema/field.js CHANGED
@@ -40,19 +40,25 @@ class UUIDField extends BaseField {
40
40
  super();
41
41
  this.options = options;
42
42
  this.type = { dbType: schema_1.DBType.UUID };
43
- const polymorphic = options.polymorphic;
43
+ if (options?.fieldEdge?.enforceSchema &&
44
+ !options.fieldEdge.getLoaderInfoFromSchema) {
45
+ throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
46
+ }
47
+ }
48
+ getDerivedFields(fieldName) {
49
+ const polymorphic = this.options?.polymorphic;
44
50
  if (polymorphic) {
45
51
  let name = "";
46
- if (options.name.endsWith("_id")) {
47
- let idx = options.name.indexOf("_id");
48
- name = options.name.substring(0, idx) + "_type";
52
+ if (fieldName.endsWith("_id")) {
53
+ let idx = fieldName.indexOf("_id");
54
+ name = fieldName.substring(0, idx) + "_type";
49
55
  }
50
- else if (options.name.endsWith("ID")) {
51
- let idx = options.name.indexOf("ID");
52
- name = options.name.substring(0, idx) + "Type";
56
+ else if (fieldName.endsWith("ID")) {
57
+ let idx = fieldName.indexOf("ID");
58
+ name = fieldName.substring(0, idx) + "Type";
53
59
  }
54
60
  else {
55
- throw new Error(`unsupported id polymorhpic type ${options.name}`);
61
+ throw new Error(`unsupported id polymorhpic type ${fieldName}`);
56
62
  }
57
63
  // polymorphic field automatically hidden from GraphQL
58
64
  // can be made visible with custom fields if user wants to change this behavior
@@ -60,38 +66,33 @@ class UUIDField extends BaseField {
60
66
  // intentionally not made private as it doesn't seem like it needs to be hidden
61
67
  if (typeof polymorphic === "object" && polymorphic.types) {
62
68
  // an enum with types validated here
63
- this.derivedFields = [
64
- EnumType({
65
- name,
69
+ return {
70
+ [name]: EnumType({
66
71
  values: polymorphic.types,
67
72
  hideFromGraphQL: true,
68
73
  derivedWhenEmbedded: true,
69
- nullable: options.nullable,
74
+ nullable: this.options?.nullable,
70
75
  }),
71
- ];
76
+ };
72
77
  }
73
78
  else {
74
79
  // just a string field...
75
- this.derivedFields = [
76
- StringType({
77
- name,
80
+ return {
81
+ [name]: StringType({
78
82
  hideFromGraphQL: true,
79
83
  derivedWhenEmbedded: true,
80
- nullable: options.nullable,
84
+ nullable: this.options?.nullable,
81
85
  }),
82
- ];
86
+ };
83
87
  }
84
88
  }
85
- if (options.fieldEdge?.enforceSchema &&
86
- !options.fieldEdge.getLoaderInfoFromSchema) {
87
- throw new Error(`cannot enforceSchema if getLoaderInfoFromSchema wasn't passed in`);
88
- }
89
+ return {};
89
90
  }
90
91
  isBuilder(val) {
91
92
  return val.placeholderID !== undefined;
92
93
  }
93
94
  async valid(val) {
94
- if (!this.options.fieldEdge?.enforceSchema) {
95
+ if (!this.options?.fieldEdge?.enforceSchema) {
95
96
  return true;
96
97
  }
97
98
  const getLoaderInfo = this.options.fieldEdge.getLoaderInfoFromSchema;
@@ -119,7 +120,7 @@ class IntegerField extends BaseField {
119
120
  super();
120
121
  this.type = { dbType: schema_1.DBType.Int };
121
122
  this.validators = [];
122
- this.options = { name: "field" };
123
+ this.options = {};
123
124
  // for legacy callers
124
125
  this.handleOptions(options || this.options);
125
126
  }
@@ -206,9 +207,9 @@ class StringField extends BaseField {
206
207
  this.type = { dbType: schema_1.DBType.String };
207
208
  this.validators = [];
208
209
  this.formatters = [];
209
- this.options = { name: "field" };
210
+ this.options = {};
210
211
  // for legacy callers
211
- this.handleOptions(options || { name: "field" });
212
+ this.handleOptions(options || {});
212
213
  }
213
214
  getOptions() {
214
215
  return this.options;
@@ -347,7 +348,7 @@ class TimestampField extends BaseField {
347
348
  }
348
349
  exports.TimestampField = TimestampField;
349
350
  function TimestampType(options) {
350
- let result = new TimestampField(options);
351
+ let result = new TimestampField({ ...options });
351
352
  return Object.assign(result, options);
352
353
  }
353
354
  exports.TimestampType = TimestampType;
@@ -374,7 +375,7 @@ class TimeField extends BaseField {
374
375
  constructor(options) {
375
376
  super();
376
377
  this.type = { dbType: schema_1.DBType.Time };
377
- if (options.withTimezone) {
378
+ if (options?.withTimezone) {
378
379
  this.type = {
379
380
  dbType: schema_1.DBType.Timetz,
380
381
  };
@@ -451,8 +452,8 @@ class EnumField extends BaseField {
451
452
  dbType: options.createEnumType ? schema_1.DBType.Enum : schema_1.DBType.StringEnum,
452
453
  values: options.values,
453
454
  enumMap: options.map,
454
- type: options.tsType || options.name,
455
- graphQLType: options.graphQLType || options.name,
455
+ type: options.tsType,
456
+ graphQLType: options.graphQLType,
456
457
  };
457
458
  if (!options.foreignKey) {
458
459
  if (!options.values && !options.map) {
@@ -596,13 +597,17 @@ class ListField extends BaseField {
596
597
  }
597
598
  return JSON.stringify(val);
598
599
  }
599
- format(val) {
600
+ format(val, nested) {
600
601
  if (!Array.isArray(val)) {
601
602
  throw new Error(`need an array to format`);
602
603
  }
603
604
  const elemDBType = this.type.listElemType.dbType;
604
605
  const jsonType = elemDBType === "JSON" || elemDBType === "JSONB";
605
- const postgres = db_1.default.getDialect() === db_1.Dialect.Postgres;
606
+ // postgres ish doesn't apply when nested
607
+ const postgres = !nested && db_1.default.getDialect() === db_1.Dialect.Postgres;
608
+ if (nested && !this.field.format) {
609
+ return val;
610
+ }
606
611
  if (!postgres && !this.field.format) {
607
612
  return JSON.stringify(val);
608
613
  }
@@ -611,7 +616,7 @@ class ListField extends BaseField {
611
616
  for (let i = 0; i < val.length; i++) {
612
617
  let formatted = val[i];
613
618
  if (this.field.format) {
614
- formatted = this.field.format(val[i]);
619
+ formatted = this.field.format(val[i], nested);
615
620
  }
616
621
  // postgres supports arrays natively so we
617
622
  // structure it in the expected format
@@ -628,6 +633,10 @@ class ListField extends BaseField {
628
633
  if (postgres) {
629
634
  return postgresRet + "}";
630
635
  }
636
+ // don't JSON.stringify if nested
637
+ if (nested) {
638
+ return ret;
639
+ }
631
640
  return JSON.stringify(ret);
632
641
  }
633
642
  minLen(l) {
package/schema/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import Schema from "./schema";
2
2
  export { Schema };
3
- export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
4
- export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, } 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, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
4
+ export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, } from "./base_schema";
5
5
  export * from "./field";
6
6
  export * from "./json_field";
7
+ export * from "./struct_field";
8
+ export * from "./union_field";
package/schema/index.js CHANGED
@@ -10,7 +10,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.SQLStatementOperation = exports.optionalField = exports.requiredField = exports.ConstraintType = exports.NoFields = exports.ActionOperation = exports.getStorageKey = exports.getFieldsWithPrivacy = exports.getFields = exports.DBType = void 0;
13
+ exports.EntSchemaWithTZ = exports.EntSchema = exports.BaseEntSchemaWithTZ = exports.BaseEntSchema = exports.Node = exports.Timestamps = exports.getObjectLoaderProperties = exports.getTransformedReadClause = exports.SQLStatementOperation = exports.optionalField = exports.requiredField = exports.ConstraintType = exports.NoFields = exports.ActionOperation = exports.getStorageKey = exports.getFieldsWithPrivacy = exports.getFields = exports.DBType = void 0;
14
14
  var schema_1 = require("./schema");
15
15
  Object.defineProperty(exports, "DBType", { enumerable: true, get: function () { return schema_1.DBType; } });
16
16
  Object.defineProperty(exports, "getFields", { enumerable: true, get: function () { return schema_1.getFields; } });
@@ -29,5 +29,9 @@ Object.defineProperty(exports, "Timestamps", { enumerable: true, get: function (
29
29
  Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return base_schema_1.Node; } });
30
30
  Object.defineProperty(exports, "BaseEntSchema", { enumerable: true, get: function () { return base_schema_1.BaseEntSchema; } });
31
31
  Object.defineProperty(exports, "BaseEntSchemaWithTZ", { enumerable: true, get: function () { return base_schema_1.BaseEntSchemaWithTZ; } });
32
+ Object.defineProperty(exports, "EntSchema", { enumerable: true, get: function () { return base_schema_1.EntSchema; } });
33
+ Object.defineProperty(exports, "EntSchemaWithTZ", { enumerable: true, get: function () { return base_schema_1.EntSchemaWithTZ; } });
32
34
  __exportStar(require("./field"), exports);
33
35
  __exportStar(require("./json_field"), exports);
36
+ __exportStar(require("./struct_field"), exports);
37
+ __exportStar(require("./union_field"), exports);
@@ -5,13 +5,13 @@ export interface JSONOptions extends FieldOptions {
5
5
  importType?: ImportType;
6
6
  }
7
7
  export declare class JSONField extends BaseField implements Field {
8
- private options;
8
+ private options?;
9
9
  type: Type;
10
- constructor(jsonb: boolean, options: JSONOptions);
10
+ constructor(jsonb: boolean, options?: JSONOptions | undefined);
11
11
  format(val: any): string;
12
12
  valid(val: any): boolean;
13
13
  }
14
- export declare function JSONType(options: 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;
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;
@@ -13,7 +13,7 @@ class JSONField extends field_1.BaseField {
13
13
  if (jsonb) {
14
14
  this.type.dbType = schema_1.DBType.JSONB;
15
15
  }
16
- if (options.importType) {
16
+ if (options?.importType) {
17
17
  this.type.importType = options.importType;
18
18
  }
19
19
  }
@@ -21,7 +21,7 @@ class JSONField extends field_1.BaseField {
21
21
  return JSON.stringify(val);
22
22
  }
23
23
  valid(val) {
24
- if (this.options.validator) {
24
+ if (this.options?.validator) {
25
25
  return this.options.validator(val);
26
26
  }
27
27
  return true;
@@ -1,8 +1,11 @@
1
1
  import { Data, Ent, LoaderInfo, PrivacyPolicy, Viewer } from "../core/base";
2
2
  import { Builder } from "../action/action";
3
3
  import { Clause } from "../core/clause";
4
+ export declare type FieldMap = {
5
+ [key: string]: Field;
6
+ };
4
7
  export default interface Schema {
5
- fields: Field[];
8
+ fields: FieldMap | Field[];
6
9
  tableName?: string;
7
10
  patterns?: Pattern[];
8
11
  edges?: Edge[];
@@ -58,7 +61,7 @@ export interface AssocEdgeGroup {
58
61
  export declare type Edge = AssocEdge;
59
62
  export interface Pattern {
60
63
  name: string;
61
- fields: Field[];
64
+ fields: FieldMap | Field[];
62
65
  edges?: Edge[];
63
66
  transformRead?: () => Clause;
64
67
  transformWrite?: <T extends Ent>(stmt: UpdateOperation<T>) => TransformedUpdateOperation<T> | undefined;
@@ -117,6 +120,8 @@ export interface Type {
117
120
  values?: string[];
118
121
  enumMap?: EnumMap;
119
122
  importType?: ImportType;
123
+ subFields?: FieldMap;
124
+ unionFields?: FieldMap;
120
125
  }
121
126
  export interface ForeignKey {
122
127
  schema: string;
@@ -140,7 +145,6 @@ export interface FieldEdge {
140
145
  disableBuilderType?: boolean;
141
146
  }
142
147
  export interface FieldOptions {
143
- name: string;
144
148
  nullable?: boolean;
145
149
  storageKey?: string;
146
150
  serverDefault?: any;
@@ -160,8 +164,9 @@ export interface FieldOptions {
160
164
  defaultValueOnEdit?(builder: Builder<Ent>, input: Data): any;
161
165
  derivedWhenEmbedded?: boolean;
162
166
  polymorphic?: boolean | PolymorphicOptions;
163
- derivedFields?: Field[];
164
167
  privacyPolicy?: PrivacyPolicy | (() => PrivacyPolicy);
168
+ getDerivedFields?(name: string): FieldMap;
169
+ [x: string]: any;
165
170
  }
166
171
  export interface PolymorphicOptions {
167
172
  types?: string[];
@@ -171,7 +176,7 @@ export interface PolymorphicOptions {
171
176
  export interface Field extends FieldOptions {
172
177
  type: Type;
173
178
  valid?(val: any): Promise<boolean> | boolean;
174
- format?(val: any): any;
179
+ format?(val: any, nested?: boolean): any;
175
180
  logValue(val: any): any;
176
181
  }
177
182
  export interface SchemaConstructor {
@@ -180,7 +185,7 @@ export interface SchemaConstructor {
180
185
  export declare type SchemaInputType = Schema | SchemaConstructor;
181
186
  export declare function getSchema(value: SchemaInputType): Schema;
182
187
  export declare function getFields(value: SchemaInputType): Map<string, Field>;
183
- export declare function getStorageKey(field: Field): string;
188
+ export declare function getStorageKey(field: Field, fieldName: string): string;
184
189
  export declare function getFieldsWithPrivacy(value: SchemaInputType): Map<string, PrivacyPolicy>;
185
190
  export declare function getTransformedReadClause(value: SchemaInputType): Clause | undefined;
186
191
  interface objectLoaderOptions {
package/schema/schema.js CHANGED
@@ -55,12 +55,25 @@ exports.getSchema = getSchema;
55
55
  function getFields(value) {
56
56
  const schema = getSchema(value);
57
57
  function addFields(fields) {
58
- for (const field of fields) {
59
- const derivedFields = field.derivedFields;
60
- if (derivedFields !== undefined) {
61
- addFields(derivedFields);
58
+ if (Array.isArray(fields)) {
59
+ for (const field of fields) {
60
+ const name = field.name;
61
+ if (!name) {
62
+ throw new Error(`name required`);
63
+ }
64
+ if (field.getDerivedFields !== undefined) {
65
+ addFields(field.getDerivedFields(name));
66
+ }
67
+ m.set(name, field);
62
68
  }
63
- m.set(field.name, field);
69
+ return;
70
+ }
71
+ for (const name in fields) {
72
+ const field = fields[name];
73
+ if (field.getDerivedFields !== undefined) {
74
+ addFields(field.getDerivedFields(name));
75
+ }
76
+ m.set(name, field);
64
77
  }
65
78
  }
66
79
  let m = new Map();
@@ -73,18 +86,39 @@ function getFields(value) {
73
86
  return m;
74
87
  }
75
88
  exports.getFields = getFields;
76
- function getStorageKey(field) {
77
- return field.storageKey || (0, snake_case_1.snakeCase)(field.name);
89
+ function getStorageKey(field, fieldName) {
90
+ return field.storageKey || (0, snake_case_1.snakeCase)(fieldName);
78
91
  }
79
92
  exports.getStorageKey = getStorageKey;
80
93
  // returns a mapping of storage key to field privacy
81
94
  function getFieldsWithPrivacy(value) {
82
95
  const schema = getSchema(value);
83
96
  function addFields(fields) {
84
- for (const field of fields) {
85
- const derivedFields = field.derivedFields;
86
- if (derivedFields !== undefined) {
87
- addFields(derivedFields);
97
+ if (Array.isArray(fields)) {
98
+ for (const field of fields) {
99
+ const name = field.name;
100
+ if (!field.name) {
101
+ throw new Error(`name required`);
102
+ }
103
+ if (field.getDerivedFields !== undefined) {
104
+ addFields(field.getDerivedFields(name));
105
+ }
106
+ if (field.privacyPolicy) {
107
+ let privacyPolicy;
108
+ if (typeof field.privacyPolicy === "function") {
109
+ privacyPolicy = field.privacyPolicy();
110
+ }
111
+ else {
112
+ privacyPolicy = field.privacyPolicy;
113
+ }
114
+ m.set(getStorageKey(field, name), privacyPolicy);
115
+ }
116
+ }
117
+ }
118
+ for (const name in fields) {
119
+ const field = fields[name];
120
+ if (field.getDerivedFields !== undefined) {
121
+ addFields(field.getDerivedFields(name));
88
122
  }
89
123
  if (field.privacyPolicy) {
90
124
  let privacyPolicy;
@@ -94,7 +128,7 @@ function getFieldsWithPrivacy(value) {
94
128
  else {
95
129
  privacyPolicy = field.privacyPolicy;
96
130
  }
97
- m.set(getStorageKey(field), privacyPolicy);
131
+ m.set(getStorageKey(field, name), privacyPolicy);
98
132
  }
99
133
  }
100
134
  }
@@ -0,0 +1,17 @@
1
+ import { BaseField, ListField } from "./field";
2
+ import { FieldOptions, Field, Type, FieldMap } from "./schema";
3
+ export interface StructOptions extends FieldOptions {
4
+ tsType: string;
5
+ fields: FieldMap;
6
+ graphQLType?: string;
7
+ jsonNotJSONB?: boolean;
8
+ }
9
+ export declare class StructField extends BaseField implements Field {
10
+ private options;
11
+ type: Type;
12
+ constructor(options: StructOptions);
13
+ format(obj: any, nested?: boolean): string | Object;
14
+ valid(obj: any): Promise<boolean>;
15
+ }
16
+ export declare function StructType(options: StructOptions): StructField & StructOptions;
17
+ export declare function StructListType(options: StructOptions): ListField;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StructListType = exports.StructType = exports.StructField = void 0;
4
+ const field_1 = require("./field");
5
+ const schema_1 = require("./schema");
6
+ const camel_case_1 = require("camel-case");
7
+ class StructField extends field_1.BaseField {
8
+ constructor(options) {
9
+ super();
10
+ this.options = options;
11
+ this.type = {
12
+ dbType: schema_1.DBType.JSONB,
13
+ };
14
+ this.type.subFields = options.fields;
15
+ this.type.type = options.tsType;
16
+ this.type.graphQLType = options.graphQLType || options.tsType;
17
+ if (options.jsonNotJSONB) {
18
+ this.type.dbType = schema_1.DBType.JSON;
19
+ }
20
+ }
21
+ // right now, we store things in the db in lowerCase format
22
+ // this will lead to issues if field changes.
23
+ // TODO: use storageKey and convert back...
24
+ format(obj, nested) {
25
+ if (!(obj instanceof Object)) {
26
+ throw new Error("valid was not called");
27
+ }
28
+ let ret = {};
29
+ for (const k in this.options.fields) {
30
+ // TODO more #510
31
+ let dbKey = (0, camel_case_1.camelCase)(k);
32
+ let val = obj[dbKey];
33
+ // for tests with snake_case
34
+ if (val === undefined && obj[k] !== undefined) {
35
+ val = obj[k];
36
+ dbKey = k;
37
+ }
38
+ if (val === undefined) {
39
+ continue;
40
+ }
41
+ const field = this.options.fields[k];
42
+ if (field.format) {
43
+ // indicate nested so this isn't JSON stringified
44
+ ret[dbKey] = field.format(val, true);
45
+ }
46
+ else {
47
+ ret[dbKey] = val;
48
+ }
49
+ }
50
+ // don't json.stringify if nested
51
+ if (nested) {
52
+ return ret;
53
+ }
54
+ return JSON.stringify(ret);
55
+ }
56
+ async valid(obj) {
57
+ if (!(obj instanceof Object)) {
58
+ return false;
59
+ }
60
+ let promises = [];
61
+ // TODO probably need to support optional fields...
62
+ let valid = true;
63
+ for (const k in this.options.fields) {
64
+ const field = this.options.fields[k];
65
+ // TODO more #510
66
+ let dbKey = (0, camel_case_1.camelCase)(k);
67
+ let val = obj[dbKey];
68
+ // for tests with snake_case
69
+ if (val === undefined && obj[k] !== undefined) {
70
+ val = obj[k];
71
+ dbKey = k;
72
+ }
73
+ if (val === undefined || val === null) {
74
+ // nullable, nothing to do here
75
+ if (field.nullable) {
76
+ continue;
77
+ }
78
+ valid = false;
79
+ break;
80
+ }
81
+ if (!field.valid) {
82
+ continue;
83
+ }
84
+ promises.push(field.valid(val));
85
+ }
86
+ if (!valid) {
87
+ return valid;
88
+ }
89
+ const ret = await Promise.all(promises);
90
+ return ret.every((v) => v);
91
+ }
92
+ }
93
+ exports.StructField = StructField;
94
+ function StructType(options) {
95
+ let result = new StructField(options);
96
+ return Object.assign(result, options);
97
+ }
98
+ exports.StructType = StructType;
99
+ function StructListType(options) {
100
+ return new field_1.ListField(StructType(options), options);
101
+ }
102
+ exports.StructListType = StructListType;
@@ -0,0 +1,23 @@
1
+ import { StructField } from "./struct_field";
2
+ import { FieldOptions, Type } from "./schema";
3
+ import { BaseField, ListField } from "./field";
4
+ export declare type StructMap = {
5
+ [key: string]: StructField;
6
+ };
7
+ export interface UnionOptions extends FieldOptions {
8
+ tsType: string;
9
+ fields: StructMap;
10
+ graphQLType?: string;
11
+ jsonNotJSONB?: boolean;
12
+ }
13
+ export declare class UnionField extends BaseField implements FieldOptions {
14
+ private options;
15
+ type: Type;
16
+ m: Map<Object, string>;
17
+ constructor(options: UnionOptions);
18
+ format(obj: any): string | Object;
19
+ private validField;
20
+ valid(obj: any): Promise<boolean>;
21
+ }
22
+ export declare function UnionType(options: UnionOptions): UnionField & UnionOptions;
23
+ export declare function UnionListType(options: UnionOptions): ListField;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnionListType = exports.UnionType = exports.UnionField = void 0;
4
+ const schema_1 = require("./schema");
5
+ const field_1 = require("./field");
6
+ // used to know which key in the union is valid.
7
+ // maybe there's a better way of doing this eventually
8
+ const KEY = "___valid___key___";
9
+ class UnionField extends field_1.BaseField {
10
+ constructor(options) {
11
+ super();
12
+ this.options = options;
13
+ this.type = {
14
+ dbType: schema_1.DBType.JSONB,
15
+ };
16
+ this.m = new Map();
17
+ this.type.unionFields = options.fields;
18
+ this.type.type = options.tsType;
19
+ this.type.graphQLType = options.graphQLType || options.tsType;
20
+ // TODO should throw if not nested?
21
+ if (options.jsonNotJSONB) {
22
+ this.type.dbType = schema_1.DBType.JSON;
23
+ }
24
+ }
25
+ format(obj) {
26
+ if (!(obj instanceof Object)) {
27
+ throw new Error("valid was not called");
28
+ }
29
+ const k = obj[KEY];
30
+ if (k === undefined) {
31
+ throw new Error(`need to call valid first`);
32
+ }
33
+ // now delete it since we don't need it anymore
34
+ delete obj[KEY];
35
+ const field = this.options.fields[k];
36
+ // always nested for now so pass through
37
+ return field.format(obj, true);
38
+ }
39
+ async validField(k, f, obj) {
40
+ const valid = await f.valid(obj);
41
+ return {
42
+ valid,
43
+ key: k,
44
+ };
45
+ }
46
+ async valid(obj) {
47
+ if (!(obj instanceof Object)) {
48
+ return false;
49
+ }
50
+ let promises = [];
51
+ for (const k in this.options.fields) {
52
+ const field = this.options.fields[k];
53
+ promises.push(this.validField(k, field, obj));
54
+ }
55
+ let lastKey;
56
+ let validCt = 0;
57
+ const ret = await Promise.all(promises);
58
+ for (const v of ret) {
59
+ if (v.valid) {
60
+ validCt++;
61
+ lastKey = v.key;
62
+ }
63
+ }
64
+ if (lastKey !== undefined) {
65
+ obj[KEY] = lastKey;
66
+ }
67
+ return validCt == 1;
68
+ }
69
+ }
70
+ exports.UnionField = UnionField;
71
+ function UnionType(options) {
72
+ let result = new UnionField(options);
73
+ return Object.assign(result, options);
74
+ }
75
+ exports.UnionType = UnionType;
76
+ function UnionListType(options) {
77
+ return new field_1.ListField(UnionType(options), options);
78
+ }
79
+ exports.UnionListType = UnionListType;
@@ -25,9 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const typescript_1 = __importDefault(require("typescript"));
27
27
  const path = __importStar(require("path"));
28
- const fs = __importStar(require("fs"));
29
- const json5_1 = __importDefault(require("json5"));
30
28
  const glob_1 = __importDefault(require("glob"));
29
+ const compilerOptions_1 = require("../tsc/compilerOptions");
31
30
  // TODO this should probably be its own package but for now it's here
32
31
  class Compiler {
33
32
  constructor(sourceFiles, moduleSearchLocations) {
@@ -35,7 +34,7 @@ class Compiler {
35
34
  this.moduleSearchLocations = moduleSearchLocations;
36
35
  this.regexMap = new Map();
37
36
  this.resolvers = [];
38
- this.options = this.readCompilerOptions();
37
+ this.options = (0, compilerOptions_1.readCompilerOptions)(".");
39
38
  if (this.options.paths) {
40
39
  for (let key in this.options.paths) {
41
40
  if (key === "*") {
@@ -105,22 +104,6 @@ class Compiler {
105
104
  }
106
105
  return undefined;
107
106
  }
108
- readCompilerOptions() {
109
- let json = {};
110
- try {
111
- json = json5_1.default.parse(fs.readFileSync("./tsconfig.json", {
112
- encoding: "utf8",
113
- }));
114
- }
115
- catch (e) {
116
- console.error("couldn't read tsconfig.json file");
117
- }
118
- let options = json["compilerOptions"] || {};
119
- if (options.moduleResolution === "node") {
120
- options.moduleResolution = typescript_1.default.ModuleResolutionKind.NodeJs;
121
- }
122
- return options;
123
- }
124
107
  createCompilerHost() {
125
108
  return {
126
109
  getSourceFile: this.getSourceFile,