@snowtop/ent 0.1.0-alpha13 → 0.1.0-alpha131

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 (173) hide show
  1. package/action/action.d.ts +33 -29
  2. package/action/action.js +22 -7
  3. package/action/executor.d.ts +3 -3
  4. package/action/executor.js +8 -3
  5. package/action/experimental_action.d.ts +32 -22
  6. package/action/experimental_action.js +35 -9
  7. package/action/index.d.ts +2 -0
  8. package/action/index.js +7 -1
  9. package/action/orchestrator.d.ts +32 -15
  10. package/action/orchestrator.js +249 -53
  11. package/action/privacy.d.ts +2 -2
  12. package/action/relative_value.d.ts +47 -0
  13. package/action/relative_value.js +125 -0
  14. package/action/transaction.d.ts +10 -0
  15. package/action/transaction.js +23 -0
  16. package/auth/auth.d.ts +1 -1
  17. package/core/base.d.ts +61 -37
  18. package/core/base.js +7 -1
  19. package/core/clause.d.ts +85 -40
  20. package/core/clause.js +375 -64
  21. package/core/config.d.ts +12 -1
  22. package/core/config.js +7 -1
  23. package/core/const.d.ts +3 -0
  24. package/core/const.js +6 -0
  25. package/core/context.d.ts +6 -4
  26. package/core/context.js +20 -2
  27. package/core/convert.d.ts +1 -1
  28. package/core/date.js +1 -5
  29. package/core/db.d.ts +11 -8
  30. package/core/db.js +20 -8
  31. package/core/ent.d.ts +86 -30
  32. package/core/ent.js +626 -197
  33. package/core/global_schema.d.ts +7 -0
  34. package/core/global_schema.js +51 -0
  35. package/core/loaders/assoc_count_loader.d.ts +3 -2
  36. package/core/loaders/assoc_count_loader.js +10 -2
  37. package/core/loaders/assoc_edge_loader.d.ts +2 -2
  38. package/core/loaders/assoc_edge_loader.js +8 -11
  39. package/core/loaders/index.d.ts +1 -1
  40. package/core/loaders/index.js +1 -3
  41. package/core/loaders/index_loader.d.ts +3 -3
  42. package/core/loaders/loader.d.ts +2 -2
  43. package/core/loaders/loader.js +5 -5
  44. package/core/loaders/object_loader.d.ts +32 -11
  45. package/core/loaders/object_loader.js +225 -78
  46. package/core/loaders/query_loader.d.ts +7 -13
  47. package/core/loaders/query_loader.js +52 -11
  48. package/core/loaders/raw_count_loader.d.ts +2 -2
  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 +25 -24
  53. package/core/privacy.js +21 -25
  54. package/core/query/assoc_query.d.ts +7 -6
  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 +20 -5
  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 +8 -4
  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.d.ts +3 -3
  69. package/core/viewer.js +1 -1
  70. package/graphql/graphql.d.ts +51 -19
  71. package/graphql/graphql.js +160 -136
  72. package/graphql/graphql_field_helpers.d.ts +7 -1
  73. package/graphql/graphql_field_helpers.js +21 -1
  74. package/graphql/index.d.ts +2 -2
  75. package/graphql/index.js +3 -5
  76. package/graphql/query/connection_type.d.ts +9 -9
  77. package/graphql/query/edge_connection.d.ts +9 -9
  78. package/graphql/query/page_info.d.ts +1 -1
  79. package/graphql/query/shared_assoc_test.js +1 -1
  80. package/graphql/query/shared_edge_connection.js +1 -19
  81. package/graphql/scalars/orderby_direction.d.ts +2 -0
  82. package/graphql/scalars/orderby_direction.js +15 -0
  83. package/imports/dataz/example1/_auth.js +128 -47
  84. package/imports/dataz/example1/_viewer.js +87 -39
  85. package/imports/index.d.ts +6 -1
  86. package/imports/index.js +19 -4
  87. package/index.d.ts +13 -5
  88. package/index.js +21 -7
  89. package/package.json +17 -17
  90. package/parse_schema/parse.d.ts +31 -9
  91. package/parse_schema/parse.js +155 -13
  92. package/schema/base_schema.d.ts +7 -3
  93. package/schema/base_schema.js +10 -0
  94. package/schema/field.d.ts +78 -21
  95. package/schema/field.js +231 -71
  96. package/schema/index.d.ts +2 -2
  97. package/schema/index.js +5 -1
  98. package/schema/json_field.d.ts +16 -4
  99. package/schema/json_field.js +32 -2
  100. package/schema/schema.d.ts +89 -19
  101. package/schema/schema.js +11 -13
  102. package/schema/struct_field.d.ts +15 -3
  103. package/schema/struct_field.js +117 -22
  104. package/schema/union_field.d.ts +1 -1
  105. package/scripts/custom_compiler.js +10 -6
  106. package/scripts/custom_graphql.js +128 -31
  107. package/scripts/migrate_v0.1.js +36 -0
  108. package/scripts/move_types.js +120 -0
  109. package/scripts/read_schema.js +20 -5
  110. package/testutils/action/complex_schemas.d.ts +69 -0
  111. package/testutils/action/complex_schemas.js +398 -0
  112. package/testutils/builder.d.ts +41 -47
  113. package/testutils/builder.js +76 -49
  114. package/testutils/db/fixture.d.ts +10 -0
  115. package/testutils/db/fixture.js +26 -0
  116. package/testutils/db/{test_db.d.ts → temp_db.d.ts} +24 -8
  117. package/testutils/db/{test_db.js → temp_db.js} +182 -45
  118. package/testutils/db/value.d.ts +7 -0
  119. package/testutils/db/value.js +251 -0
  120. package/testutils/db_mock.d.ts +16 -4
  121. package/testutils/db_mock.js +52 -7
  122. package/testutils/db_time_zone.d.ts +4 -0
  123. package/testutils/db_time_zone.js +41 -0
  124. package/testutils/ent-graphql-tests/index.d.ts +7 -1
  125. package/testutils/ent-graphql-tests/index.js +52 -23
  126. package/testutils/fake_comms.js +1 -1
  127. package/testutils/fake_data/const.d.ts +2 -1
  128. package/testutils/fake_data/const.js +3 -0
  129. package/testutils/fake_data/fake_contact.d.ts +7 -3
  130. package/testutils/fake_data/fake_contact.js +13 -7
  131. package/testutils/fake_data/fake_event.d.ts +4 -1
  132. package/testutils/fake_data/fake_event.js +7 -6
  133. package/testutils/fake_data/fake_tag.d.ts +36 -0
  134. package/testutils/fake_data/fake_tag.js +89 -0
  135. package/testutils/fake_data/fake_user.d.ts +8 -5
  136. package/testutils/fake_data/fake_user.js +16 -15
  137. package/testutils/fake_data/index.js +5 -1
  138. package/testutils/fake_data/internal.d.ts +2 -0
  139. package/testutils/fake_data/internal.js +7 -1
  140. package/testutils/fake_data/tag_query.d.ts +13 -0
  141. package/testutils/fake_data/tag_query.js +43 -0
  142. package/testutils/fake_data/test_helpers.d.ts +11 -4
  143. package/testutils/fake_data/test_helpers.js +28 -12
  144. package/testutils/fake_data/user_query.d.ts +13 -6
  145. package/testutils/fake_data/user_query.js +54 -22
  146. package/testutils/fake_log.d.ts +3 -3
  147. package/testutils/fake_log.js +1 -1
  148. package/testutils/parse_sql.d.ts +6 -0
  149. package/testutils/parse_sql.js +16 -2
  150. package/testutils/test_edge_global_schema.d.ts +15 -0
  151. package/testutils/test_edge_global_schema.js +62 -0
  152. package/testutils/write.d.ts +2 -2
  153. package/testutils/write.js +33 -7
  154. package/tsc/ast.d.ts +25 -2
  155. package/tsc/ast.js +141 -17
  156. package/tsc/compilerOptions.js +5 -1
  157. package/tsc/move_generated.d.ts +1 -0
  158. package/tsc/move_generated.js +164 -0
  159. package/tsc/transform.d.ts +22 -0
  160. package/tsc/transform.js +181 -0
  161. package/tsc/transform_action.d.ts +22 -0
  162. package/tsc/transform_action.js +183 -0
  163. package/tsc/transform_ent.d.ts +17 -0
  164. package/tsc/transform_ent.js +60 -0
  165. package/tsc/transform_schema.d.ts +27 -0
  166. package/{scripts → tsc}/transform_schema.js +146 -117
  167. package/graphql/enums.d.ts +0 -3
  168. package/graphql/enums.js +0 -25
  169. package/scripts/move_generated.js +0 -142
  170. package/scripts/transform_code.js +0 -113
  171. package/scripts/transform_schema.d.ts +0 -1
  172. /package/scripts/{move_generated.d.ts → migrate_v0.1.d.ts} +0 -0
  173. /package/scripts/{transform_code.d.ts → move_types.d.ts} +0 -0
package/core/viewer.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ID, Ent, Viewer, Context } from "./base";
2
2
  export declare class LoggedOutViewer implements Viewer {
3
- context?: Context | undefined;
4
- constructor(context?: Context | undefined);
3
+ context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined;
4
+ constructor(context?: Context<Viewer<Ent<any> | null, ID | null>> | undefined);
5
5
  viewerID: null;
6
6
  viewer(): Promise<null>;
7
7
  instanceKey(): string;
@@ -18,6 +18,6 @@ export declare class IDViewer implements Viewer {
18
18
  constructor(viewerID: ID, opts?: Partial<IDViewerOptions>);
19
19
  constructor(opts: IDViewerOptions);
20
20
  setContext(ctx: Context): this;
21
- viewer(): Promise<Ent | null>;
21
+ viewer(): Promise<Ent<Viewer<Ent<any> | null, ID | null>> | null>;
22
22
  instanceKey(): string;
23
23
  }
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,52 @@
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 gqlFieldOptionsBase {
28
+ isContextArg?: boolean;
29
+ }
30
+ export interface gqlFieldOptions extends gqlFieldOptionsBase {
31
+ nodeName: string;
32
+ args?: gqlFieldArg[];
33
+ async?: boolean;
34
+ type: NonNullable<gqlFieldOptionsBase["type"]>;
35
+ }
23
36
  export interface gqlObjectOptions {
24
37
  name?: string;
25
38
  description?: string;
26
39
  }
27
- declare type gqlTopLevelOptions = Exclude<gqlFieldOptions, "nullable">;
40
+ export interface gqlObjectWithInterfaceOptions extends gqlObjectOptions {
41
+ interfaces?: string[];
42
+ }
43
+ export interface gqlObjectWithUnionOptions extends gqlObjectOptions {
44
+ unionTypes: string[];
45
+ }
46
+ type gqlMutationOptions = Omit<gqlFieldOptions, "nullable" | "type"> & {
47
+ type?: gqlFieldOptionsBase["type"];
48
+ };
49
+ type gqlQueryOptions = gqlFieldOptions;
28
50
  export declare enum CustomFieldType {
29
51
  Accessor = "ACCESSOR",
30
52
  Field = "FIELD",
@@ -42,6 +64,9 @@ interface CustomFieldImpl {
42
64
  export interface CustomField extends CustomFieldImpl {
43
65
  args: Field[];
44
66
  results: Field[];
67
+ extraImports?: any[];
68
+ functionContents?: string;
69
+ edgeName?: string;
45
70
  }
46
71
  export interface CustomMutation extends CustomField {
47
72
  }
@@ -51,15 +76,17 @@ export interface ProcessedCustomField extends CustomFieldImpl {
51
76
  args: ProcessedField[];
52
77
  results: ProcessedField[];
53
78
  }
54
- export declare type ProcessCustomFieldMap = {
55
- [key: string]: ProcessedCustomField;
79
+ export type ProcessCustomFieldMap = {
80
+ [key: string]: ProcessedCustomField[];
56
81
  };
57
82
  export interface CustomObject {
58
83
  nodeName: string;
59
84
  className: string;
60
85
  description?: string;
86
+ interfaces?: string[];
87
+ unionTypes?: string[];
61
88
  }
62
- declare type NullableListOptions = "contents" | "contentsAndList";
89
+ type NullableListOptions = "contents" | "contentsAndList";
63
90
  interface FieldImpl {
64
91
  type: string;
65
92
  tsType?: string;
@@ -84,8 +111,9 @@ declare enum NullableResult {
84
111
  }
85
112
  export declare const knownAllowedNames: Map<string, string>;
86
113
  export declare const knownDisAllowedNames: Map<string, boolean>;
114
+ export declare const knownInterfaces: Map<string, boolean>;
87
115
  export declare const isCustomType: (type: Type) => type is CustomType;
88
- export declare const addCustomType: (type: CustomType) => void;
116
+ export declare const addCustomType: (type: CustomType, gqlCapture: typeof GQLCapture) => void;
89
117
  export declare class GQLCapture {
90
118
  private static enabled;
91
119
  static enable(enabled: boolean): void;
@@ -96,6 +124,8 @@ export declare class GQLCapture {
96
124
  private static customArgs;
97
125
  private static customInputObjects;
98
126
  private static customObjects;
127
+ private static customInterfaces;
128
+ private static customUnions;
99
129
  private static customTypes;
100
130
  static clear(): void;
101
131
  static getCustomFields(): Map<string, CustomField[]>;
@@ -104,33 +134,35 @@ export declare class GQLCapture {
104
134
  static getCustomArgs(): Map<string, CustomObject>;
105
135
  static getCustomInputObjects(): Map<string, CustomObject>;
106
136
  static getCustomObjects(): Map<string, CustomObject>;
137
+ static getCustomInterfaces(): Map<string, CustomObject>;
138
+ static getCustomUnions(): Map<string, CustomObject>;
107
139
  static getCustomTypes(): Map<string, CustomType>;
108
140
  private static getNullableArg;
109
141
  static getProcessedCustomFields(): ProcessCustomFieldMap;
110
142
  static getProcessedCustomMutations(): ProcessedCustomField[];
111
143
  static getProcessedCustomQueries(): ProcessedCustomField[];
112
144
  private static getProcessedCustomFieldsImpl;
113
- private static getResultFromMetadata;
114
- static gqlField(options?: gqlFieldOptions): any;
145
+ private static getField;
146
+ static gqlField(options: gqlFieldOptions): any;
115
147
  private static getCustomField;
116
- private static argMap;
117
- private static argImpl;
118
- static gqlArg(name: string, options?: gqlFieldOptions): any;
119
- static gqlContextType(): any;
148
+ static gqlContextType(): gqlFieldArg;
120
149
  static gqlArgType(options?: gqlObjectOptions): any;
121
150
  static gqlInputObjectType(options?: gqlObjectOptions): any;
122
- static gqlObjectType(options?: gqlObjectOptions): any;
151
+ static gqlObjectType(options?: gqlObjectWithInterfaceOptions): any;
152
+ static gqlUnionType(options: gqlObjectWithUnionOptions): any;
153
+ static gqlInterfaceType(options?: gqlObjectOptions): any;
123
154
  private static customGQLObject;
124
- static gqlQuery(options?: gqlTopLevelOptions): any;
125
- static gqlMutation(options?: gqlTopLevelOptions): any;
155
+ static gqlQuery(options: gqlQueryOptions): any;
156
+ static gqlMutation(options: gqlMutationOptions): any;
126
157
  static gqlConnection(type: Type): any;
127
158
  static resolve(objects: string[]): void;
128
159
  }
129
160
  export declare const gqlField: typeof GQLCapture.gqlField;
130
- export declare const gqlArg: typeof GQLCapture.gqlArg;
131
161
  export declare const gqlArgType: typeof GQLCapture.gqlArgType;
132
162
  export declare const gqlInputObjectType: typeof GQLCapture.gqlInputObjectType;
133
163
  export declare const gqlObjectType: typeof GQLCapture.gqlObjectType;
164
+ export declare const gqlInterfaceType: typeof GQLCapture.gqlInterfaceType;
165
+ export declare const gqlUnionType: typeof GQLCapture.gqlUnionType;
134
166
  export declare const gqlQuery: typeof GQLCapture.gqlQuery;
135
167
  export declare const gqlMutation: typeof GQLCapture.gqlMutation;
136
168
  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.nodeName,
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,48 @@ 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
+ let objFields = this.customFields.get(obj.nodeName);
424
+ if (!objFields) {
425
+ objFields = [];
426
+ }
427
+ for (const field of fields) {
428
+ objFields.push({
429
+ ...field,
430
+ nodeName: obj.nodeName,
431
+ });
432
+ }
433
+ this.customFields.set(obj.nodeName, objFields);
434
+ }
435
+ }
436
+ else if (!exports.knownInterfaces.has(interfaceName)) {
437
+ throw new Error(`object ${key} references unknown interface ${interfaceName}`);
438
+ }
439
+ });
440
+ });
431
441
  let baseArgs = new Map();
432
442
  this.customArgs.forEach((_val, key) => baseArgs.set(key, true));
433
443
  this.customInputObjects.forEach((_val, key) => baseArgs.set(key, true));
434
444
  baseArgs.set("Context", true);
435
445
  this.customTypes.forEach((_val, key) => baseArgs.set(key, true));
446
+ this.customUnions.forEach((val, key) => {
447
+ if (this.customFields.has(key)) {
448
+ throw new Error(`union ${key} has custom fields which is not allowed`);
449
+ }
450
+ val.unionTypes?.forEach((typ) => {
451
+ if (!baseObjects.has(typ)) {
452
+ throw new Error(`union ${key} references ${typ} which isn't a graphql object`);
453
+ }
454
+ });
455
+ });
456
+ // TODO this should be aware of knownCustomTypes
436
457
  const resolveFields = (fields) => {
437
458
  fields.forEach((field) => {
438
459
  // we have a check earlier that *should* make this path impossible
@@ -453,7 +474,9 @@ class GQLCapture {
453
474
  // but i don't think it applies
454
475
  field.results.forEach((result) => {
455
476
  if (result.needsResolving) {
456
- if (baseObjects.has(result.type)) {
477
+ if (baseObjects.has(result.type) ||
478
+ this.customUnions.has(result.type) ||
479
+ this.customInterfaces.has(result.type)) {
457
480
  result.needsResolving = false;
458
481
  }
459
482
  else {
@@ -468,7 +491,6 @@ class GQLCapture {
468
491
  resolveFields(GQLCapture.customMutations);
469
492
  }
470
493
  }
471
- exports.GQLCapture = GQLCapture;
472
494
  GQLCapture.enabled = false;
473
495
  // map from class name to fields
474
496
  GQLCapture.customFields = new Map();
@@ -477,16 +499,18 @@ GQLCapture.customMutations = [];
477
499
  GQLCapture.customArgs = new Map();
478
500
  GQLCapture.customInputObjects = new Map();
479
501
  GQLCapture.customObjects = new Map();
502
+ GQLCapture.customInterfaces = new Map();
503
+ GQLCapture.customUnions = new Map();
480
504
  GQLCapture.customTypes = new Map();
481
- // User -> add -> [{name, options}, {}, {}]
482
- GQLCapture.argMap = new Map();
505
+ exports.GQLCapture = GQLCapture;
483
506
  // why is this a static class lol?
484
507
  // TODO make all these just plain functions
485
508
  exports.gqlField = GQLCapture.gqlField;
486
- exports.gqlArg = GQLCapture.gqlArg;
487
509
  exports.gqlArgType = GQLCapture.gqlArgType;
488
510
  exports.gqlInputObjectType = GQLCapture.gqlInputObjectType;
489
511
  exports.gqlObjectType = GQLCapture.gqlObjectType;
512
+ exports.gqlInterfaceType = GQLCapture.gqlInterfaceType;
513
+ exports.gqlUnionType = GQLCapture.gqlUnionType;
490
514
  exports.gqlQuery = GQLCapture.gqlQuery;
491
515
  exports.gqlMutation = GQLCapture.gqlMutation;
492
516
  exports.gqlContextType = GQLCapture.gqlContextType;