@snowtop/ent 0.1.0-alpha14 → 0.1.0-alpha141

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 (169) hide show
  1. package/action/action.d.ts +27 -16
  2. package/action/action.js +22 -7
  3. package/action/executor.d.ts +16 -3
  4. package/action/executor.js +88 -21
  5. package/action/experimental_action.d.ts +25 -16
  6. package/action/experimental_action.js +35 -9
  7. package/action/index.d.ts +3 -1
  8. package/action/index.js +7 -1
  9. package/action/operations.d.ts +125 -0
  10. package/action/operations.js +684 -0
  11. package/action/orchestrator.d.ts +34 -11
  12. package/action/orchestrator.js +355 -92
  13. package/action/relative_value.d.ts +47 -0
  14. package/action/relative_value.js +125 -0
  15. package/action/transaction.d.ts +10 -0
  16. package/action/transaction.js +23 -0
  17. package/auth/auth.d.ts +1 -1
  18. package/core/base.d.ts +51 -21
  19. package/core/base.js +7 -1
  20. package/core/clause.d.ts +85 -40
  21. package/core/clause.js +375 -64
  22. package/core/config.d.ts +12 -1
  23. package/core/config.js +7 -1
  24. package/core/const.d.ts +3 -0
  25. package/core/const.js +6 -0
  26. package/core/context.d.ts +4 -2
  27. package/core/context.js +20 -2
  28. package/core/convert.d.ts +1 -1
  29. package/core/date.js +1 -5
  30. package/core/db.d.ts +12 -8
  31. package/core/db.js +18 -8
  32. package/core/ent.d.ts +66 -93
  33. package/core/ent.js +517 -577
  34. package/core/global_schema.d.ts +7 -0
  35. package/core/global_schema.js +51 -0
  36. package/core/loaders/assoc_count_loader.d.ts +1 -0
  37. package/core/loaders/assoc_count_loader.js +10 -2
  38. package/core/loaders/assoc_edge_loader.d.ts +1 -1
  39. package/core/loaders/assoc_edge_loader.js +8 -11
  40. package/core/loaders/index.d.ts +1 -1
  41. package/core/loaders/index.js +1 -3
  42. package/core/loaders/index_loader.d.ts +3 -3
  43. package/core/loaders/loader.d.ts +2 -2
  44. package/core/loaders/loader.js +5 -5
  45. package/core/loaders/object_loader.d.ts +30 -9
  46. package/core/loaders/object_loader.js +225 -78
  47. package/core/loaders/query_loader.d.ts +6 -12
  48. package/core/loaders/query_loader.js +52 -11
  49. package/core/loaders/raw_count_loader.js +5 -1
  50. package/core/logger.d.ts +1 -1
  51. package/core/logger.js +1 -0
  52. package/core/privacy.d.ts +7 -6
  53. package/core/privacy.js +21 -25
  54. package/core/query/assoc_query.d.ts +3 -2
  55. package/core/query/assoc_query.js +9 -1
  56. package/core/query/custom_clause_query.d.ts +27 -0
  57. package/core/query/custom_clause_query.js +84 -0
  58. package/core/query/custom_query.d.ts +17 -2
  59. package/core/query/custom_query.js +87 -12
  60. package/core/query/index.d.ts +1 -0
  61. package/core/query/index.js +3 -1
  62. package/core/query/query.d.ts +7 -3
  63. package/core/query/query.js +101 -53
  64. package/core/query/shared_assoc_test.d.ts +2 -1
  65. package/core/query/shared_assoc_test.js +35 -45
  66. package/core/query/shared_test.d.ts +8 -1
  67. package/core/query/shared_test.js +470 -236
  68. package/core/viewer.js +1 -1
  69. package/graphql/graphql.d.ts +52 -19
  70. package/graphql/graphql.js +174 -136
  71. package/graphql/graphql_field_helpers.d.ts +7 -1
  72. package/graphql/graphql_field_helpers.js +21 -1
  73. package/graphql/index.d.ts +2 -2
  74. package/graphql/index.js +3 -5
  75. package/graphql/query/connection_type.d.ts +9 -9
  76. package/graphql/query/shared_assoc_test.js +1 -1
  77. package/graphql/query/shared_edge_connection.js +1 -19
  78. package/graphql/scalars/orderby_direction.d.ts +2 -0
  79. package/graphql/scalars/orderby_direction.js +15 -0
  80. package/imports/dataz/example1/_auth.js +128 -47
  81. package/imports/dataz/example1/_viewer.js +87 -39
  82. package/imports/index.d.ts +6 -1
  83. package/imports/index.js +19 -4
  84. package/index.d.ts +14 -5
  85. package/index.js +26 -10
  86. package/package.json +18 -17
  87. package/parse_schema/parse.d.ts +31 -9
  88. package/parse_schema/parse.js +156 -13
  89. package/schema/base_schema.d.ts +9 -3
  90. package/schema/base_schema.js +12 -0
  91. package/schema/field.d.ts +78 -21
  92. package/schema/field.js +231 -71
  93. package/schema/index.d.ts +2 -2
  94. package/schema/index.js +5 -1
  95. package/schema/json_field.d.ts +16 -4
  96. package/schema/json_field.js +32 -2
  97. package/schema/schema.d.ts +96 -19
  98. package/schema/schema.js +11 -13
  99. package/schema/struct_field.d.ts +15 -3
  100. package/schema/struct_field.js +117 -22
  101. package/schema/union_field.d.ts +1 -1
  102. package/scripts/custom_compiler.js +10 -6
  103. package/scripts/custom_graphql.js +142 -31
  104. package/scripts/migrate_v0.1.js +36 -0
  105. package/scripts/move_types.js +120 -0
  106. package/scripts/read_schema.js +20 -5
  107. package/testutils/action/complex_schemas.d.ts +69 -0
  108. package/testutils/action/complex_schemas.js +405 -0
  109. package/testutils/builder.d.ts +39 -43
  110. package/testutils/builder.js +75 -49
  111. package/testutils/db/fixture.d.ts +10 -0
  112. package/testutils/db/fixture.js +26 -0
  113. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +25 -8
  114. package/testutils/db/{test_db.js → temp_db.js} +224 -47
  115. package/testutils/db/value.d.ts +7 -0
  116. package/testutils/db/value.js +251 -0
  117. package/testutils/db_mock.d.ts +16 -4
  118. package/testutils/db_mock.js +52 -7
  119. package/testutils/db_time_zone.d.ts +4 -0
  120. package/testutils/db_time_zone.js +41 -0
  121. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  122. package/testutils/ent-graphql-tests/index.js +52 -23
  123. package/testutils/fake_comms.js +1 -1
  124. package/testutils/fake_data/const.d.ts +2 -1
  125. package/testutils/fake_data/const.js +3 -0
  126. package/testutils/fake_data/fake_contact.d.ts +7 -3
  127. package/testutils/fake_data/fake_contact.js +13 -7
  128. package/testutils/fake_data/fake_event.d.ts +4 -1
  129. package/testutils/fake_data/fake_event.js +7 -6
  130. package/testutils/fake_data/fake_tag.d.ts +36 -0
  131. package/testutils/fake_data/fake_tag.js +89 -0
  132. package/testutils/fake_data/fake_user.d.ts +8 -5
  133. package/testutils/fake_data/fake_user.js +16 -15
  134. package/testutils/fake_data/index.js +5 -1
  135. package/testutils/fake_data/internal.d.ts +2 -0
  136. package/testutils/fake_data/internal.js +7 -1
  137. package/testutils/fake_data/tag_query.d.ts +13 -0
  138. package/testutils/fake_data/tag_query.js +43 -0
  139. package/testutils/fake_data/test_helpers.d.ts +11 -4
  140. package/testutils/fake_data/test_helpers.js +28 -12
  141. package/testutils/fake_data/user_query.d.ts +11 -4
  142. package/testutils/fake_data/user_query.js +54 -22
  143. package/testutils/fake_log.js +1 -1
  144. package/testutils/parse_sql.d.ts +6 -0
  145. package/testutils/parse_sql.js +16 -2
  146. package/testutils/test_edge_global_schema.d.ts +15 -0
  147. package/testutils/test_edge_global_schema.js +62 -0
  148. package/testutils/write.d.ts +2 -2
  149. package/testutils/write.js +33 -7
  150. package/tsc/ast.d.ts +25 -2
  151. package/tsc/ast.js +141 -17
  152. package/tsc/compilerOptions.js +5 -1
  153. package/tsc/move_generated.d.ts +1 -0
  154. package/tsc/move_generated.js +164 -0
  155. package/tsc/transform.d.ts +22 -0
  156. package/tsc/transform.js +181 -0
  157. package/tsc/transform_action.d.ts +22 -0
  158. package/tsc/transform_action.js +183 -0
  159. package/tsc/transform_ent.d.ts +17 -0
  160. package/tsc/transform_ent.js +60 -0
  161. package/tsc/transform_schema.d.ts +27 -0
  162. package/{scripts → tsc}/transform_schema.js +146 -117
  163. package/graphql/enums.d.ts +0 -3
  164. package/graphql/enums.js +0 -25
  165. package/scripts/move_generated.js +0 -142
  166. package/scripts/transform_code.js +0 -113
  167. package/scripts/transform_schema.d.ts +0 -1
  168. /package/scripts/{move_generated.d.ts → migrate_v0.1.d.ts} +0 -0
  169. /package/scripts/{transform_code.d.ts → move_types.d.ts} +0 -0
package/core/viewer.js CHANGED
@@ -35,7 +35,7 @@ class IDViewer {
35
35
  return this.ent;
36
36
  }
37
37
  instanceKey() {
38
- return `idViewer: ${this.viewerID}`;
38
+ return `idViewer:${this.viewerID}`;
39
39
  }
40
40
  }
41
41
  exports.IDViewer = IDViewer;
@@ -1,30 +1,53 @@
1
- import "reflect-metadata";
2
1
  import { GraphQLScalarType } from "graphql";
3
2
  interface ClassType<T = any> {
4
3
  new (...args: any[]): T;
5
4
  }
5
+ declare type StringToStringMap = {
6
+ [key: string]: string;
7
+ };
6
8
  export interface CustomType {
7
9
  type: string;
8
10
  importPath: string;
9
11
  tsType?: string;
10
12
  tsImportPath?: string;
13
+ enumMap?: StringToStringMap;
14
+ inputType?: boolean;
11
15
  [x: string]: any;
12
16
  }
13
- declare type Type = GraphQLScalarType | ClassType | string | CustomType;
14
- export declare type GraphQLConnection<T> = {
17
+ type Type = GraphQLScalarType | ClassType | string | CustomType;
18
+ export type GraphQLConnection<T> = {
15
19
  node: T;
16
20
  };
17
- export interface gqlFieldOptions {
21
+ interface gqlFieldOptionsBase {
18
22
  name?: string;
19
23
  nullable?: boolean | NullableListOptions;
20
24
  description?: string;
21
25
  type?: Type | Array<Type> | GraphQLConnection<Type>;
22
26
  }
27
+ interface gqlFieldArg extends Omit<gqlFieldOptionsBase, "name"> {
28
+ isContextArg?: boolean;
29
+ name: string;
30
+ }
31
+ export interface gqlFieldOptions extends gqlFieldOptionsBase {
32
+ class: string;
33
+ args?: gqlFieldArg[];
34
+ async?: boolean;
35
+ type: NonNullable<gqlFieldOptionsBase["type"]>;
36
+ }
23
37
  export interface gqlObjectOptions {
24
38
  name?: string;
25
39
  description?: string;
26
40
  }
27
- declare type gqlTopLevelOptions = Exclude<gqlFieldOptions, "nullable">;
41
+ export interface gqlObjectWithInterfaceOptions extends gqlObjectOptions {
42
+ interfaces?: string[];
43
+ }
44
+ export interface gqlObjectWithUnionOptions extends gqlObjectOptions {
45
+ unionTypes: string[];
46
+ }
47
+ type gqlMutationOptions = Omit<gqlFieldOptions, "nullable" | "type"> & {
48
+ type?: gqlFieldOptionsBase["type"];
49
+ };
50
+ type gqlQueryOptions = gqlFieldOptions;
28
51
  export declare enum CustomFieldType {
29
52
  Accessor = "ACCESSOR",
30
53
  Field = "FIELD",
@@ -42,6 +65,9 @@ interface CustomFieldImpl {
42
65
  export interface CustomField extends CustomFieldImpl {
43
66
  args: Field[];
44
67
  results: Field[];
68
+ extraImports?: any[];
69
+ functionContents?: string;
70
+ edgeName?: string;
45
71
  }
46
72
  export interface CustomMutation extends CustomField {
47
73
  }
@@ -51,15 +77,17 @@ export interface ProcessedCustomField extends CustomFieldImpl {
51
77
  args: ProcessedField[];
52
78
  results: ProcessedField[];
53
79
  }
54
- export declare type ProcessCustomFieldMap = {
55
- [key: string]: ProcessedCustomField;
80
+ export type ProcessCustomFieldMap = {
81
+ [key: string]: ProcessedCustomField[];
56
82
  };
57
83
  export interface CustomObject {
58
84
  nodeName: string;
59
85
  className: string;
60
86
  description?: string;
87
+ interfaces?: string[];
88
+ unionTypes?: string[];
61
89
  }
62
- declare type NullableListOptions = "contents" | "contentsAndList";
90
+ type NullableListOptions = "contents" | "contentsAndList";
63
91
  interface FieldImpl {
64
92
  type: string;
65
93
  tsType?: string;
@@ -84,8 +112,9 @@ declare enum NullableResult {
84
112
  }
85
113
  export declare const knownAllowedNames: Map<string, string>;
86
114
  export declare const knownDisAllowedNames: Map<string, boolean>;
115
+ export declare const knownInterfaces: Map<string, boolean>;
87
116
  export declare const isCustomType: (type: Type) => type is CustomType;
88
- export declare const addCustomType: (type: CustomType) => void;
117
+ export declare const addCustomType: (type: CustomType, gqlCapture: typeof GQLCapture) => void;
89
118
  export declare class GQLCapture {
90
119
  private static enabled;
91
120
  static enable(enabled: boolean): void;
@@ -96,6 +125,8 @@ export declare class GQLCapture {
96
125
  private static customArgs;
97
126
  private static customInputObjects;
98
127
  private static customObjects;
128
+ private static customInterfaces;
129
+ private static customUnions;
99
130
  private static customTypes;
100
131
  static clear(): void;
101
132
  static getCustomFields(): Map<string, CustomField[]>;
@@ -104,33 +135,35 @@ export declare class GQLCapture {
104
135
  static getCustomArgs(): Map<string, CustomObject>;
105
136
  static getCustomInputObjects(): Map<string, CustomObject>;
106
137
  static getCustomObjects(): Map<string, CustomObject>;
138
+ static getCustomInterfaces(): Map<string, CustomObject>;
139
+ static getCustomUnions(): Map<string, CustomObject>;
107
140
  static getCustomTypes(): Map<string, CustomType>;
108
141
  private static getNullableArg;
109
142
  static getProcessedCustomFields(): ProcessCustomFieldMap;
110
143
  static getProcessedCustomMutations(): ProcessedCustomField[];
111
144
  static getProcessedCustomQueries(): ProcessedCustomField[];
112
145
  private static getProcessedCustomFieldsImpl;
113
- private static getResultFromMetadata;
114
- static gqlField(options?: gqlFieldOptions): any;
146
+ private static getField;
147
+ static gqlField(options: gqlFieldOptions): any;
115
148
  private static getCustomField;
116
- private static argMap;
117
- private static argImpl;
118
- static gqlArg(name: string, options?: gqlFieldOptions): any;
119
- static gqlContextType(): any;
149
+ static gqlContextType(): gqlFieldArg;
120
150
  static gqlArgType(options?: gqlObjectOptions): any;
121
151
  static gqlInputObjectType(options?: gqlObjectOptions): any;
122
- static gqlObjectType(options?: gqlObjectOptions): any;
152
+ static gqlObjectType(options?: gqlObjectWithInterfaceOptions): any;
153
+ static gqlUnionType(options: gqlObjectWithUnionOptions): any;
154
+ static gqlInterfaceType(options?: gqlObjectOptions): any;
123
155
  private static customGQLObject;
124
- static gqlQuery(options?: gqlTopLevelOptions): any;
125
- static gqlMutation(options?: gqlTopLevelOptions): any;
156
+ static gqlQuery(options: gqlQueryOptions): any;
157
+ static gqlMutation(options: gqlMutationOptions): any;
126
158
  static gqlConnection(type: Type): any;
127
159
  static resolve(objects: string[]): void;
128
160
  }
129
161
  export declare const gqlField: typeof GQLCapture.gqlField;
130
- export declare const gqlArg: typeof GQLCapture.gqlArg;
131
162
  export declare const gqlArgType: typeof GQLCapture.gqlArgType;
132
163
  export declare const gqlInputObjectType: typeof GQLCapture.gqlInputObjectType;
133
164
  export declare const gqlObjectType: typeof GQLCapture.gqlObjectType;
165
+ export declare const gqlInterfaceType: typeof GQLCapture.gqlInterfaceType;
166
+ export declare const gqlUnionType: typeof GQLCapture.gqlUnionType;
134
167
  export declare const gqlQuery: typeof GQLCapture.gqlQuery;
135
168
  export declare const gqlMutation: typeof GQLCapture.gqlMutation;
136
169
  export declare const gqlContextType: typeof GQLCapture.gqlContextType;
@@ -1,12 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlArg = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.isCustomType = exports.knownDisAllowedNames = exports.knownAllowedNames = exports.CustomFieldType = void 0;
4
- require("reflect-metadata");
5
- // export interface gqlTopLevelOptions
6
- // name?: string;
7
- // type?: Type | Array<Type>;
8
- // description?: string;
9
- // }
3
+ exports.gqlFileUpload = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlUnionType = exports.gqlInterfaceType = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlField = exports.GQLCapture = exports.addCustomType = exports.isCustomType = exports.knownInterfaces = exports.knownDisAllowedNames = exports.knownAllowedNames = exports.CustomFieldType = void 0;
10
4
  var CustomFieldType;
11
5
  (function (CustomFieldType) {
12
6
  CustomFieldType["Accessor"] = "ACCESSOR";
@@ -29,6 +23,8 @@ exports.knownAllowedNames = new Map([
29
23
  ["Int", "number"],
30
24
  ["Float", "number"],
31
25
  ["ID", "ID"],
26
+ ["JSON", "any"],
27
+ ["Node", "Ent"],
32
28
  ]);
33
29
  exports.knownDisAllowedNames = new Map([
34
30
  ["Function", true],
@@ -36,6 +32,11 @@ exports.knownDisAllowedNames = new Map([
36
32
  ["Array", true],
37
33
  ["Promise", true],
38
34
  ]);
35
+ exports.knownInterfaces = new Map([
36
+ ["Node", true],
37
+ ["Edge", true],
38
+ ["Connection", true],
39
+ ]);
39
40
  const isArray = (type) => {
40
41
  if (typeof type === "function") {
41
42
  return false;
@@ -61,13 +62,15 @@ exports.isCustomType = isCustomType;
61
62
  const isGraphQLScalarType = (type) => {
62
63
  return type.serialize !== undefined;
63
64
  };
64
- const addCustomType = (type) => {
65
+ const addCustomType = (type, gqlCapture) => {
65
66
  // TODO these should return ReadOnly objects...
66
- const customType = GQLCapture.getCustomTypes().get(type.type);
67
- if (customType && customType !== type) {
68
- throw new Error(`cannot add multiple custom types of name ${type.type}`);
67
+ const customTypes = gqlCapture.getCustomTypes();
68
+ const customType = customTypes.get(type.type);
69
+ if (customType && customType === type) {
70
+ return;
69
71
  }
70
- if (customType) {
72
+ if (type.enumMap) {
73
+ customTypes.set(type.type, type);
71
74
  return;
72
75
  }
73
76
  try {
@@ -85,9 +88,21 @@ const addCustomType = (type) => {
85
88
  }
86
89
  }
87
90
  catch (e) {
91
+ if (type.secondaryImportPath) {
92
+ (0, exports.addCustomType)({
93
+ ...type,
94
+ importPath: type.secondaryImportPath,
95
+ }, gqlCapture);
96
+ }
97
+ return;
98
+ }
99
+ if (customType) {
100
+ if (JSON.stringify(customType) !== JSON.stringify(type)) {
101
+ throw new Error(`cannot add multiple custom types of name ${type.type}`);
102
+ }
88
103
  return;
89
104
  }
90
- GQLCapture.getCustomTypes().set(type.type, type);
105
+ customTypes.set(type.type, type);
91
106
  };
92
107
  exports.addCustomType = addCustomType;
93
108
  const getType = (typ, result) => {
@@ -111,7 +126,8 @@ const getType = (typ, result) => {
111
126
  }
112
127
  if ((0, exports.isCustomType)(typ)) {
113
128
  result.type = typ.type;
114
- (0, exports.addCustomType)(typ);
129
+ // TODO???
130
+ (0, exports.addCustomType)(typ, GQLCapture);
115
131
  return;
116
132
  }
117
133
  // GraphQLScalarType or ClassType
@@ -133,8 +149,9 @@ class GQLCapture {
133
149
  this.customArgs.clear();
134
150
  this.customInputObjects.clear();
135
151
  this.customObjects.clear();
152
+ this.customInterfaces.clear();
153
+ this.customUnions.clear();
136
154
  this.customTypes.clear();
137
- this.argMap.clear();
138
155
  }
139
156
  static getCustomFields() {
140
157
  return this.customFields;
@@ -154,6 +171,12 @@ class GQLCapture {
154
171
  static getCustomObjects() {
155
172
  return this.customObjects;
156
173
  }
174
+ static getCustomInterfaces() {
175
+ return this.customInterfaces;
176
+ }
177
+ static getCustomUnions() {
178
+ return this.customUnions;
179
+ }
157
180
  static getCustomTypes() {
158
181
  return this.customTypes;
159
182
  }
@@ -198,33 +221,34 @@ class GQLCapture {
198
221
  return res;
199
222
  });
200
223
  }
201
- static getResultFromMetadata(metadata, options) {
202
- let type = metadata.name;
203
- if ((type === "Number" || type === "Object") && !options?.type) {
204
- throw new Error(`type is required when accessor/function/property returns a ${type}`);
205
- }
224
+ static getField(field) {
206
225
  let list;
207
226
  let scalarType = false;
208
227
  let connection;
209
- if (options?.type) {
228
+ let type = "";
229
+ if (field?.type) {
210
230
  let r = { type: "" };
211
- getType(options.type, r);
231
+ getType(field.type, r);
212
232
  list = r.list;
213
233
  scalarType = r.scalarType || false;
214
234
  connection = r.connection;
215
235
  type = r.type;
216
236
  }
237
+ if (!type) {
238
+ throw new Error(`type is required for accessor/function/property`);
239
+ }
217
240
  if (exports.knownDisAllowedNames.has(type)) {
218
241
  throw new Error(`${type} isn't a valid type for accessor/function/property`);
219
242
  }
220
243
  let result = {
221
- name: metadata.paramName || "",
222
- type,
244
+ name: field?.name || "",
245
+ type: type,
223
246
  tsType: exports.knownAllowedNames.get(type) || this.customTypes.get(type)?.tsType,
224
- nullable: options?.nullable,
247
+ nullable: field?.nullable,
225
248
  list: list,
226
249
  connection: connection,
227
- isContextArg: metadata.isContextArg,
250
+ // @ts-ignore
251
+ isContextArg: field?.isContextArg,
228
252
  };
229
253
  // unknown type. we need to flag that this field needs to eventually be resolved
230
254
  if (!exports.knownAllowedNames.has(type)) {
@@ -236,11 +260,16 @@ class GQLCapture {
236
260
  return result;
237
261
  }
238
262
  static gqlField(options) {
239
- return function (target, propertyKey, descriptor) {
240
- if (!GQLCapture.isEnabled()) {
263
+ return function (_target, ctx) {
264
+ if (!GQLCapture.isEnabled() ||
265
+ (ctx.kind !== "method" &&
266
+ ctx.kind !== "field" &&
267
+ ctx.kind !== "getter") ||
268
+ ctx.static ||
269
+ ctx.private) {
241
270
  return;
242
271
  }
243
- let customField = GQLCapture.getCustomField(target, propertyKey, descriptor, options);
272
+ let customField = GQLCapture.getCustomField(ctx, options);
244
273
  if (!customField) {
245
274
  return;
246
275
  }
@@ -271,152 +300,109 @@ class GQLCapture {
271
300
  GQLCapture.customFields.set(customField.nodeName, list);
272
301
  };
273
302
  }
274
- static getCustomField(target, propertyKey, descriptor, options) {
303
+ static getCustomField(ctx, options, allowNoReturnType) {
275
304
  let fieldType;
276
- let nodeName = target.constructor.name;
277
305
  let args = [];
278
306
  let results = [];
279
- let typeMetadata = Reflect.getMetadata("design:type", target, propertyKey);
280
- let returnTypeMetadata = Reflect.getMetadata("design:returntype", target, propertyKey);
281
- if (returnTypeMetadata) {
282
- // function...
283
- if (returnTypeMetadata.name === "Promise") {
284
- fieldType = CustomFieldType.AsyncFunction;
285
- }
286
- else {
307
+ switch (ctx.kind) {
308
+ case "method":
287
309
  fieldType = CustomFieldType.Function;
288
- }
289
- results.push(GQLCapture.getResultFromMetadata(returnTypeMetadata, options));
290
- }
291
- else if (typeMetadata) {
292
- if (descriptor && descriptor.get) {
293
- fieldType = CustomFieldType.Accessor;
294
- }
295
- else if (descriptor && descriptor.value) {
296
- // could be implicit async
297
- fieldType = CustomFieldType.Function;
298
- }
299
- else {
310
+ if (options.async) {
311
+ fieldType = CustomFieldType.AsyncFunction;
312
+ }
313
+ break;
314
+ case "field":
300
315
  fieldType = CustomFieldType.Field;
301
- }
302
- if (!(options?.allowFunctionType &&
303
- fieldType === CustomFieldType.Function &&
304
- typeMetadata.name === "Function")) {
305
- results.push(GQLCapture.getResultFromMetadata(typeMetadata, options));
306
- }
316
+ break;
317
+ case "getter":
318
+ fieldType = CustomFieldType.Accessor;
319
+ break;
307
320
  }
308
- let params = Reflect.getMetadata("design:paramtypes", target, propertyKey);
309
- if (params && params.length > 0) {
310
- let parsedArgs = GQLCapture.argMap.get(nodeName)?.get(propertyKey) || [];
311
- if (params.length !== parsedArgs.length) {
312
- throw new Error(`args were not captured correctly, ${params.length}, ${parsedArgs.length}`);
313
- }
314
- parsedArgs.forEach((arg) => {
315
- let param = params[arg.index];
316
- let paramName = arg.name;
317
- let field = GQLCapture.getResultFromMetadata({
318
- name: param.name,
319
- paramName,
320
- isContextArg: arg.isContextArg,
321
- }, arg.options);
322
- // TODO this may not be the right order...
323
- args.push(field);
321
+ if (!allowNoReturnType && !options.type) {
322
+ throw new Error(`type is required for ${fieldType}`);
323
+ }
324
+ if (options.type) {
325
+ // override name property passed down so we return '' as name
326
+ results.push(GQLCapture.getField({ ...options, name: "" }));
327
+ }
328
+ if (options.args?.length) {
329
+ options.args.forEach((arg) => {
330
+ args.push(GQLCapture.getField(arg));
324
331
  });
325
- // TODO this is deterministically (so far) coming in reverse order so reverse (for now)
326
- args = args.reverse();
327
332
  }
328
333
  return {
329
- nodeName: nodeName,
330
- gqlName: options?.name || propertyKey,
331
- functionName: propertyKey,
334
+ nodeName: options.class,
335
+ gqlName: options?.name || ctx.name.toString(),
336
+ functionName: ctx.name.toString(),
332
337
  args: args,
333
338
  results: results,
334
339
  fieldType: fieldType,
335
340
  description: options?.description,
336
341
  };
337
342
  }
338
- static argImpl(name, isContextArg, options) {
339
- return function (target, propertyKey, index) {
340
- if (!GQLCapture.isEnabled()) {
341
- return;
342
- }
343
- let nodeName = target.constructor.name;
344
- let m = GQLCapture.argMap.get(nodeName);
345
- if (!m) {
346
- m = new Map();
347
- GQLCapture.argMap.set(nodeName, m);
348
- }
349
- let propertyMap = m.get(propertyKey);
350
- if (!propertyMap) {
351
- propertyMap = [];
352
- m.set(propertyKey, propertyMap);
353
- }
354
- propertyMap.push({
355
- name: name,
356
- index: index,
357
- options: options,
358
- isContextArg,
359
- });
360
- // console.log("arg", name, target, propertyKey, index);
361
- };
362
- }
363
- // TODO custom args because for example name doesn't make sense here.
364
- static gqlArg(name, options) {
365
- return GQLCapture.argImpl(name, undefined, options);
366
- }
367
343
  static gqlContextType() {
368
- // hardcoded?
369
- return GQLCapture.argImpl("context", true, { type: "Context" });
344
+ return {
345
+ name: "context",
346
+ isContextArg: true,
347
+ type: "Context",
348
+ };
370
349
  }
371
350
  static gqlArgType(options) {
372
- return function (target, _propertyKey, _descriptor) {
373
- return GQLCapture.customGQLObject(target, GQLCapture.customArgs, options);
351
+ return function (target, ctx) {
352
+ return GQLCapture.customGQLObject(ctx, GQLCapture.customArgs, options);
374
353
  };
375
354
  }
376
355
  static gqlInputObjectType(options) {
377
- return function (target, _propertyKey, _descriptor) {
378
- return GQLCapture.customGQLObject(target, GQLCapture.customInputObjects, options);
356
+ return function (target, ctx) {
357
+ return GQLCapture.customGQLObject(ctx, GQLCapture.customInputObjects, options);
379
358
  };
380
359
  }
381
360
  static gqlObjectType(options) {
382
- return function (target, _propertyKey, _descriptor) {
383
- return GQLCapture.customGQLObject(target, GQLCapture.customObjects, options);
361
+ return function (target, ctx) {
362
+ return GQLCapture.customGQLObject(ctx, GQLCapture.customObjects, options);
363
+ };
364
+ }
365
+ static gqlUnionType(options) {
366
+ return function (target, ctx) {
367
+ return GQLCapture.customGQLObject(ctx, GQLCapture.customUnions, options);
368
+ };
369
+ }
370
+ static gqlInterfaceType(options) {
371
+ return function (target, ctx) {
372
+ return GQLCapture.customGQLObject(ctx, GQLCapture.customInterfaces, options);
384
373
  };
385
374
  }
386
- static customGQLObject(target, map, options) {
387
- if (!GQLCapture.isEnabled()) {
375
+ static customGQLObject(ctx, map, options) {
376
+ if (!GQLCapture.isEnabled() || ctx.kind !== "class" || !ctx.name) {
388
377
  return;
389
378
  }
390
- let className = target.name;
379
+ let className = ctx.name.toString();
391
380
  let nodeName = options?.name || className;
392
381
  map.set(className, {
393
382
  className,
394
383
  nodeName,
395
384
  description: options?.description,
385
+ // @ts-ignore
386
+ interfaces: options?.interfaces,
387
+ // @ts-ignore
388
+ unionTypes: options?.unionTypes,
396
389
  });
397
390
  }
398
- // TODO query and mutation
399
391
  // we want to specify args if any, name, response if any
400
392
  static gqlQuery(options) {
401
- return function (target, propertyKey, descriptor) {
393
+ return function (target, ctx) {
402
394
  if (!GQLCapture.isEnabled()) {
403
395
  return;
404
396
  }
405
- GQLCapture.customQueries.push(GQLCapture.getCustomField(target, propertyKey, descriptor, options));
397
+ GQLCapture.customQueries.push(GQLCapture.getCustomField(ctx, options));
406
398
  };
407
399
  }
408
- // we want to specify inputs (required), name, response
409
- // input is via gqlArg
410
- // should it be gqlInputArg?
411
400
  static gqlMutation(options) {
412
- return function (target, propertyKey, descriptor) {
401
+ return function (target, ctx) {
413
402
  if (!GQLCapture.isEnabled()) {
414
403
  return;
415
404
  }
416
- GQLCapture.customMutations.push(GQLCapture.getCustomField(target, propertyKey, descriptor, {
417
- ...options,
418
- allowFunctionType: true,
419
- }));
405
+ GQLCapture.customMutations.push(GQLCapture.getCustomField(ctx, options, true));
420
406
  };
421
407
  }
422
408
  static gqlConnection(type) {
@@ -426,13 +412,62 @@ class GQLCapture {
426
412
  }
427
413
  static resolve(objects) {
428
414
  let baseObjects = new Map();
429
- objects.map((object) => baseObjects.set(object, true));
430
- this.customObjects.forEach((_val, key) => baseObjects.set(key, true));
415
+ objects.forEach((object) => baseObjects.set(object, true));
416
+ this.customObjects.forEach((obj, key) => {
417
+ baseObjects.set(key, true);
418
+ obj.interfaces?.forEach((interfaceName) => {
419
+ const inter = this.customInterfaces.get(interfaceName);
420
+ if (inter) {
421
+ const fields = this.customFields.get(inter.nodeName);
422
+ if (fields) {
423
+ // check for duplicate fields
424
+ // if field is already defined no need to add it
425
+ let objFields = this.customFields.get(obj.nodeName);
426
+ if (!objFields) {
427
+ objFields = [];
428
+ }
429
+ let map = new Map();
430
+ for (const f of objFields) {
431
+ map.set(f.gqlName, f);
432
+ }
433
+ for (const field of fields) {
434
+ const newField = {
435
+ ...field,
436
+ nodeName: obj.nodeName,
437
+ };
438
+ if (map.has(field.gqlName)) {
439
+ const existing = map.get(field.gqlName);
440
+ if (JSON.stringify(existing) !== JSON.stringify(newField)) {
441
+ throw new Error(`object ${obj.nodeName} has duplicate field ${field.gqlName} with different definition`);
442
+ }
443
+ continue;
444
+ }
445
+ objFields.push(newField);
446
+ }
447
+ this.customFields.set(obj.nodeName, objFields);
448
+ }
449
+ }
450
+ else if (!exports.knownInterfaces.has(interfaceName)) {
451
+ throw new Error(`object ${key} references unknown interface ${interfaceName}`);
452
+ }
453
+ });
454
+ });
431
455
  let baseArgs = new Map();
432
456
  this.customArgs.forEach((_val, key) => baseArgs.set(key, true));
433
457
  this.customInputObjects.forEach((_val, key) => baseArgs.set(key, true));
434
458
  baseArgs.set("Context", true);
435
459
  this.customTypes.forEach((_val, key) => baseArgs.set(key, true));
460
+ this.customUnions.forEach((val, key) => {
461
+ if (this.customFields.has(key)) {
462
+ throw new Error(`union ${key} has custom fields which is not allowed`);
463
+ }
464
+ val.unionTypes?.forEach((typ) => {
465
+ if (!baseObjects.has(typ)) {
466
+ throw new Error(`union ${key} references ${typ} which isn't a graphql object`);
467
+ }
468
+ });
469
+ });
470
+ // TODO this should be aware of knownCustomTypes
436
471
  const resolveFields = (fields) => {
437
472
  fields.forEach((field) => {
438
473
  // we have a check earlier that *should* make this path impossible
@@ -453,7 +488,9 @@ class GQLCapture {
453
488
  // but i don't think it applies
454
489
  field.results.forEach((result) => {
455
490
  if (result.needsResolving) {
456
- if (baseObjects.has(result.type)) {
491
+ if (baseObjects.has(result.type) ||
492
+ this.customUnions.has(result.type) ||
493
+ this.customInterfaces.has(result.type)) {
457
494
  result.needsResolving = false;
458
495
  }
459
496
  else {
@@ -468,7 +505,6 @@ class GQLCapture {
468
505
  resolveFields(GQLCapture.customMutations);
469
506
  }
470
507
  }
471
- exports.GQLCapture = GQLCapture;
472
508
  GQLCapture.enabled = false;
473
509
  // map from class name to fields
474
510
  GQLCapture.customFields = new Map();
@@ -477,16 +513,18 @@ GQLCapture.customMutations = [];
477
513
  GQLCapture.customArgs = new Map();
478
514
  GQLCapture.customInputObjects = new Map();
479
515
  GQLCapture.customObjects = new Map();
516
+ GQLCapture.customInterfaces = new Map();
517
+ GQLCapture.customUnions = new Map();
480
518
  GQLCapture.customTypes = new Map();
481
- // User -> add -> [{name, options}, {}, {}]
482
- GQLCapture.argMap = new Map();
519
+ exports.GQLCapture = GQLCapture;
483
520
  // why is this a static class lol?
484
521
  // TODO make all these just plain functions
485
522
  exports.gqlField = GQLCapture.gqlField;
486
- exports.gqlArg = GQLCapture.gqlArg;
487
523
  exports.gqlArgType = GQLCapture.gqlArgType;
488
524
  exports.gqlInputObjectType = GQLCapture.gqlInputObjectType;
489
525
  exports.gqlObjectType = GQLCapture.gqlObjectType;
526
+ exports.gqlInterfaceType = GQLCapture.gqlInterfaceType;
527
+ exports.gqlUnionType = GQLCapture.gqlUnionType;
490
528
  exports.gqlQuery = GQLCapture.gqlQuery;
491
529
  exports.gqlMutation = GQLCapture.gqlMutation;
492
530
  exports.gqlContextType = GQLCapture.gqlContextType;