@eddeee888/gcg-typescript-resolver-files 0.18.0 → 0.18.1

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 (78) hide show
  1. package/package.json +6 -2
  2. package/CHANGELOG.md +0 -816
  3. package/DEVELOPMENT.md +0 -49
  4. package/dist/tsconfig.lib.tsbuildinfo +0 -1
  5. package/eslint.config.mjs +0 -22
  6. package/project.json +0 -8
  7. package/src/addVirtualTypesFileToTsMorphProject/addVirtualTypesFileToTsMorphProject.ts +0 -109
  8. package/src/addVirtualTypesFileToTsMorphProject/index.ts +0 -1
  9. package/src/defineConfig.spec.ts +0 -76
  10. package/src/defineConfig.ts +0 -37
  11. package/src/generateResolverFiles/addExternalResolverImport.ts +0 -185
  12. package/src/generateResolverFiles/addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented.spec.ts +0 -1174
  13. package/src/generateResolverFiles/addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented.ts +0 -144
  14. package/src/generateResolverFiles/addResolverMainFiles.ts +0 -343
  15. package/src/generateResolverFiles/ensureEnumTypeResolversAreGenerated.ts +0 -51
  16. package/src/generateResolverFiles/generateResolverFiles.ts +0 -148
  17. package/src/generateResolverFiles/getImportStatementWithExpectedNamedImport.spec.ts +0 -127
  18. package/src/generateResolverFiles/getImportStatementWithExpectedNamedImport.ts +0 -25
  19. package/src/generateResolverFiles/getVariableStatementWithExpectedIdentifier.spec.ts +0 -147
  20. package/src/generateResolverFiles/getVariableStatementWithExpectedIdentifier.ts +0 -34
  21. package/src/generateResolverFiles/handleGraphQLEnumType.ts +0 -100
  22. package/src/generateResolverFiles/handleGraphQLInterfaceType.ts +0 -70
  23. package/src/generateResolverFiles/handleGraphQLObjectType.ts +0 -171
  24. package/src/generateResolverFiles/handleGraphQLRootObjectTypeField.ts +0 -105
  25. package/src/generateResolverFiles/handleGraphQLScalarType.ts +0 -81
  26. package/src/generateResolverFiles/handleGraphQLUnionType.ts +0 -68
  27. package/src/generateResolverFiles/index.ts +0 -2
  28. package/src/generateResolverFiles/postProcessFiles.ts +0 -287
  29. package/src/generateResolverFiles/types.ts +0 -203
  30. package/src/generateResolverFiles/visitNamedType.ts +0 -66
  31. package/src/generateTypeDefsFiles/generateTypeDefsContent.ts +0 -15
  32. package/src/generateTypeDefsFiles/generateTypeDefsFiles.ts +0 -100
  33. package/src/generateTypeDefsFiles/index.ts +0 -1
  34. package/src/getGraphQLObjectTypeResolversToGenerate/getGraphQLObjectTypeResolversToGenerate.ts +0 -361
  35. package/src/getGraphQLObjectTypeResolversToGenerate/getNodePropertyMap.spec.ts +0 -115
  36. package/src/getGraphQLObjectTypeResolversToGenerate/getNodePropertyMap.ts +0 -88
  37. package/src/getGraphQLObjectTypeResolversToGenerate/index.ts +0 -1
  38. package/src/index.ts +0 -3
  39. package/src/normalizeAddConfigPath/index.ts +0 -1
  40. package/src/normalizeAddConfigPath/normalizeAddConfigPath.ts +0 -29
  41. package/src/parseGraphQLSchema/index.ts +0 -2
  42. package/src/parseGraphQLSchema/normalizeResolverName.ts +0 -28
  43. package/src/parseGraphQLSchema/parseGraphQLSchema.ts +0 -531
  44. package/src/parseGraphQLSchema/parseLocationForOutputDir.ts +0 -76
  45. package/src/parseSources/index.ts +0 -1
  46. package/src/parseSources/parseSources.ts +0 -83
  47. package/src/parseTypeMappers/collectTypeMappersFromSourceFile.spec.ts +0 -789
  48. package/src/parseTypeMappers/collectTypeMappersFromSourceFile.ts +0 -197
  49. package/src/parseTypeMappers/index.ts +0 -1
  50. package/src/parseTypeMappers/parseTypeMappers.ts +0 -75
  51. package/src/preset.ts +0 -317
  52. package/src/utils/cwd.ts +0 -8
  53. package/src/utils/fmt.ts +0 -16
  54. package/src/utils/index.ts +0 -12
  55. package/src/utils/isMatchResolverNamePattern.ts +0 -27
  56. package/src/utils/isNativeNamedType.ts +0 -21
  57. package/src/utils/isRootObjectType.ts +0 -8
  58. package/src/utils/isWhitelistedModule.spec.ts +0 -71
  59. package/src/utils/isWhitelistedModule.ts +0 -21
  60. package/src/utils/logger.ts +0 -14
  61. package/src/utils/normalizeImportExtension.spec.ts +0 -42
  62. package/src/utils/normalizeImportExtension.ts +0 -16
  63. package/src/utils/normalizeRelativePath.ts +0 -6
  64. package/src/utils/parseLocationForWhitelistedModule.spec.ts +0 -130
  65. package/src/utils/parseLocationForWhitelistedModule.ts +0 -38
  66. package/src/utils/printImportLine.spec.ts +0 -150
  67. package/src/utils/printImportLine.ts +0 -78
  68. package/src/utils/relativeModulePath.ts +0 -7
  69. package/src/validateAndMergeParsedConfigs/index.ts +0 -1
  70. package/src/validateAndMergeParsedConfigs/validateAndMergeParsedConfigs.spec.ts +0 -211
  71. package/src/validateAndMergeParsedConfigs/validateAndMergeParsedConfigs.ts +0 -92
  72. package/src/validatePresetConfig/index.ts +0 -1
  73. package/src/validatePresetConfig/validatePresetConfig.spec.ts +0 -706
  74. package/src/validatePresetConfig/validatePresetConfig.ts +0 -571
  75. package/tsconfig.json +0 -14
  76. package/tsconfig.lib.json +0 -18
  77. package/tsconfig.spec.json +0 -20
  78. package/vite.config.ts +0 -24
@@ -1,361 +0,0 @@
1
- import {
2
- type InterfaceDeclaration,
3
- type TypeAliasDeclaration,
4
- type ClassDeclaration,
5
- type ExportSpecifier,
6
- type SourceFile,
7
- type Project,
8
- type Identifier,
9
- SyntaxKind,
10
- Node,
11
- } from 'ts-morph';
12
- import type {
13
- TypeMapperDetails,
14
- TypeMappersMap,
15
- } from '../parseTypeMappers/index.js';
16
- import {
17
- type NodePropertyMap,
18
- getNodePropertyMap,
19
- } from './getNodePropertyMap.js';
20
- import type { ParsedGraphQLSchemaMeta } from '../parseGraphQLSchema/index.js';
21
- import type { GeneratedTypesFileMeta } from '../generateResolverFiles/index.js';
22
-
23
- export type GraphQLObjectTypeResolversToGenerate = Record<
24
- string,
25
- Record<string, { resolverName: string; resolverDeclaration: string }>
26
- >;
27
-
28
- export const getGraphQLObjectTypeResolversToGenerate = ({
29
- mode,
30
- tsMorphProject,
31
- typesSourceFile,
32
- typeMappersMap,
33
- userDefinedSchemaObjectTypeMap,
34
- generatedTypesFileMeta,
35
- }: {
36
- mode: 'smart' | 'fast';
37
- tsMorphProject: Project;
38
- typesSourceFile: SourceFile;
39
- typeMappersMap: TypeMappersMap;
40
- userDefinedSchemaObjectTypeMap: ParsedGraphQLSchemaMeta['userDefinedSchemaTypeMap']['object'];
41
- generatedTypesFileMeta: GeneratedTypesFileMeta;
42
- }): GraphQLObjectTypeResolversToGenerate => {
43
- const typeMappersEntries = Object.entries(typeMappersMap);
44
- if (typeMappersEntries.length === 0) {
45
- return {};
46
- }
47
-
48
- /**
49
- * `generatedTypesFileMeta.generatedResolverTypes.userDefined` is `schemaType` -> `generatedResolverTypes`
50
- * We will be parsing `types.generated.ts` file for the `generatedResolverTypes`
51
- * So, we need to invert `generatedTypesFileMeta.generatedResolverTypes.userDefined` to get `generatedResolverTypes` -> `schemaType`
52
- * e.g.
53
- *
54
- * generatedTypesFileMeta.generatedResolverTypes.userDefined = {
55
- * User: {
56
- * name: 'UserResolvers'
57
- * }
58
- * }
59
- *
60
- * after transformation:
61
- *
62
- * generatedSchemaTypeNameMap = {
63
- * UserResolvers: 'User'
64
- * }
65
- */
66
- const generatedSchemaTypeNameMap = Object.entries(
67
- generatedTypesFileMeta.generatedResolverTypes.userDefined
68
- ).reduce<Record<string, string>>(
69
- (res, [schemaType, generatedSchemaTypeName]) => {
70
- res[generatedSchemaTypeName.name] = schemaType;
71
- return res;
72
- },
73
- {}
74
- );
75
-
76
- if (mode === 'fast') {
77
- // 1. Get property map of all schema types
78
- const resolverTypesMap: Record<
79
- string, // Schema type
80
- { node: Node; properties: NodePropertyMap }
81
- > = {};
82
-
83
- const syntaxList = typesSourceFile.getChildAtIndex(0); // Assumption: There is a root node in this file that contain all exports
84
- if (!syntaxList) {
85
- throw new Error(
86
- `Root node of generated types file doesn't exist. This likely means the file is empty. This shouldn't happen.`
87
- );
88
- }
89
- // Assumption: All resolvers exports are 1 level below root node i.e. we can use syntaxList.getChildren()
90
- for (const node of syntaxList.getChildren()) {
91
- if (
92
- node.isKind(SyntaxKind.TypeAliasDeclaration) ||
93
- node.isKind(SyntaxKind.InterfaceDeclaration)
94
- ) {
95
- const identifierName = node.getNameNode().getText(); // e.g. UserResolvers, BookResolvers
96
- const schemaType = generatedSchemaTypeNameMap[identifierName]; // schemaType examples: User, Book
97
-
98
- if (schemaType && typeMappersMap[schemaType]) {
99
- resolverTypesMap[schemaType] = {
100
- node,
101
- properties: getNodePropertyMap({ node }),
102
- };
103
- }
104
- }
105
- }
106
-
107
- // 3. Find resolvers to generate and add reason
108
- const result: GraphQLObjectTypeResolversToGenerate = {};
109
- typeMappersEntries.forEach(([_, { schemaType, mapper }]) => {
110
- const resolverType = resolverTypesMap[schemaType];
111
- if (!resolverType) {
112
- return;
113
- }
114
-
115
- const mapperOriginalDeclarationNode =
116
- mustGetMapperOriginalDeclarationNode({
117
- tsMorphProject,
118
- mapper,
119
- });
120
- const mapperPropsMap = getNodePropertyMap({
121
- node: mapperOriginalDeclarationNode,
122
- });
123
-
124
- Object.values(resolverType.properties).forEach((resolverTypeProp) => {
125
- result[schemaType] = result[schemaType] || {};
126
- const resolverTypePropName = resolverTypeProp.name;
127
-
128
- const mapperPropIdentifier = `${mapper.name}.${resolverTypePropName}`;
129
- const schemaTypePropIdentifier = `${schemaType}.${resolverTypePropName}`;
130
-
131
- // 1. Generated resolvers types may have one or more of these meta resolvers
132
- // A mapper would most likely never have these resolvers, so we skip them
133
- // Otherwise, these resolvers will always be generated
134
- const metaResolvers: Record<string, boolean> = {
135
- __isTypeOf: true,
136
- __resolveReference: true,
137
- };
138
- if (metaResolvers[resolverTypePropName]) {
139
- return;
140
- }
141
-
142
- const mapperProp = mapperPropsMap[resolverTypePropName];
143
- // 2. If mapper does not have a field in resolver type, add missing resolver
144
- if (!mapperProp) {
145
- result[schemaType][resolverTypePropName] = {
146
- resolverName: resolverTypePropName,
147
- resolverDeclaration: `async (_parent, _arg, _ctx) => { /* ${schemaTypePropIdentifier} resolver is required because ${schemaTypePropIdentifier} exists but ${mapperPropIdentifier} does not */ }`,
148
- };
149
- return;
150
- }
151
-
152
- // 3. If mapper and resolver props have the same name, compare their types
153
- const sourceType = mapperProp.type;
154
-
155
- // A resolver type may look like this:
156
- // `book?: Resolver<Maybe<ResolversTypes['Book']>, ParentType, ContextType>;`
157
- const targetType = resolverTypeProp.type // type is `Resolver<Maybe<ResolversTypes['Book']>, ParentType, ContextType> | undefined` because book resolver is optional
158
- .getNonNullableType() // removing nullable, it becomes `Resolver<Maybe<ResolversTypes['Book']>, ParentType, ContextType>`
159
- .getAliasTypeArguments()[0]; // first type argument is `Maybe<ResolversTypes['Book']>`
160
-
161
- if (sourceType.isAssignableTo(targetType)) {
162
- return;
163
- }
164
-
165
- result[schemaType][resolverTypePropName] = {
166
- resolverName: resolverTypePropName,
167
- resolverDeclaration: `({ ${resolverTypePropName} }, _arg, _ctx) => {
168
- /* ${schemaTypePropIdentifier} resolver is required because ${schemaTypePropIdentifier} and ${mapperPropIdentifier} are not compatible */
169
- return ${resolverTypePropName}
170
- }`,
171
- };
172
- });
173
- });
174
-
175
- return result;
176
- }
177
-
178
- // 1. Get property map of all schema types
179
- const schemaResolversTypePropertyMap: Record<string, NodePropertyMap> = {};
180
-
181
- const populateSchemaTypeResolversPropertyMap = (
182
- node: TypeAliasDeclaration | InterfaceDeclaration
183
- ): void => {
184
- const identifier = node.getNameNode();
185
- const identifierName = identifier.getText();
186
-
187
- const schemaType = generatedSchemaTypeNameMap[identifierName];
188
-
189
- if (schemaType && userDefinedSchemaObjectTypeMap[schemaType]) {
190
- schemaResolversTypePropertyMap[schemaType] = getNodePropertyMap({ node });
191
- }
192
- };
193
- typesSourceFile
194
- .getDescendantsOfKind(SyntaxKind.TypeAliasDeclaration)
195
- .forEach(populateSchemaTypeResolversPropertyMap);
196
-
197
- typesSourceFile
198
- .getDescendantsOfKind(SyntaxKind.InterfaceDeclaration)
199
- .forEach(populateSchemaTypeResolversPropertyMap);
200
-
201
- // 3. Find resolvers to generate and add reason
202
- const result: GraphQLObjectTypeResolversToGenerate = {};
203
- typeMappersEntries.forEach(([_, { schemaType, mapper }]) => {
204
- const matchedSchemaTypePropertyMap =
205
- schemaResolversTypePropertyMap[schemaType];
206
- if (!matchedSchemaTypePropertyMap) {
207
- return;
208
- }
209
-
210
- const originalDeclarationNode = mustGetMapperOriginalDeclarationNode({
211
- tsMorphProject,
212
- mapper,
213
- });
214
- const typeMapperPropertyMap = getNodePropertyMap({
215
- node: originalDeclarationNode,
216
- });
217
-
218
- Object.values(matchedSchemaTypePropertyMap).forEach(
219
- (schemaTypeProperty) => {
220
- const typeMapperProperty =
221
- typeMapperPropertyMap[schemaTypeProperty.name];
222
-
223
- const typeMapperPropertyIdentifier = `${mapper.name}.${schemaTypeProperty.name}`;
224
- const schemaTypePropertyIdentifier = `${schemaType}.${schemaTypeProperty.name}`;
225
-
226
- // Generated resolvers types may have one or more of these meta resolvers
227
- // A mapper would most likely never have these resolvers, so we skip them
228
- // Otherwise, these resolvers will always be generated
229
- const metaResolvers: Record<string, boolean> = {
230
- __isTypeOf: true,
231
- __resolveReference: true,
232
- };
233
-
234
- if (metaResolvers[schemaTypeProperty.name]) {
235
- return;
236
- }
237
-
238
- result[schemaType] = result[schemaType] || {};
239
-
240
- // If mapper does not have a field in schema type, add missing resolver
241
- if (!typeMapperProperty) {
242
- result[schemaType][schemaTypeProperty.name] = {
243
- resolverName: schemaTypeProperty.name,
244
- resolverDeclaration: `async (_parent, _arg, _ctx) => { /* ${schemaTypePropertyIdentifier} resolver is required because ${schemaTypePropertyIdentifier} exists but ${typeMapperPropertyIdentifier} does not */ }`,
245
- };
246
- return;
247
- }
248
-
249
- /**
250
- * FIXME: TypeScript's `isTypeAssignableTo` should be used to check if the mapper type vs resolver return type is compatible.
251
- * The current challenge is to:
252
- * - Switch from using the schema type to resolver return type e.g. `User` -> `UserResolver`
253
- * - Take the ReturnType of the resolver function type e.g. `Resolver<ResolversTypes['UserRole'], ParentType, ContextType>`
254
- *
255
- * For now, the workaround now is to generate all resolvers with matching names,
256
- * then use TS diagnostics to see if there's error when trying to merge the two keys.
257
- *
258
- * Note: this happens only when mappers are used
259
- */
260
- result[schemaType][schemaTypeProperty.name] = {
261
- resolverName: schemaTypeProperty.name,
262
- resolverDeclaration: `({ ${schemaTypeProperty.name} }, _arg, _ctx) => {
263
- /* ${schemaTypePropertyIdentifier} resolver is required because ${schemaTypePropertyIdentifier} and ${typeMapperPropertyIdentifier} are not compatible */
264
- return ${schemaTypeProperty.name}
265
- }`,
266
- };
267
-
268
- return;
269
- }
270
- );
271
- });
272
-
273
- return result;
274
- };
275
-
276
- const mustGetMapperOriginalDeclarationNode = ({
277
- tsMorphProject,
278
- mapper,
279
- }: {
280
- tsMorphProject: Project;
281
- mapper: TypeMapperDetails['mapper'];
282
- }): Node => {
283
- const typeMapperFile = tsMorphProject.getSourceFile(mapper.filename);
284
- if (!typeMapperFile) {
285
- throw new Error(
286
- `Unable to find ${typeMapperFile} file after parsing. This shouldn't happen.`
287
- );
288
- }
289
-
290
- /**
291
- * Finding `firstDescendantThatIsMapper` here is a bit of the duplicated traversing logic in `collectTypeMappersFromSourceFile`.
292
- * However, in `collectTypeMappersFromSourceFile`, we find the mappers details.
293
- * And here, we actually do look for the mapper nodes and run analysis on it.
294
- *
295
- * Previously, we were parsing the node property map in `collectTypeMappersFromSourceFile`
296
- * but for some reason `isAssignableTo` has issue comparing types, so we have to move the static analysis here for now.
297
- */
298
- const firstDescendantThatIsMapper = (():
299
- | GetOriginalDeclarationNodeParams
300
- | undefined => {
301
- for (const descendant of typeMapperFile.getDescendants()) {
302
- const typedNode = descendant.isKind(mapper.kind);
303
- if (typedNode) {
304
- let identifierNode = descendant.getNameNode();
305
- if (descendant.isKind(SyntaxKind.ExportSpecifier)) {
306
- const aliasNode = descendant.getAliasNode();
307
- if (aliasNode) {
308
- identifierNode = aliasNode;
309
- }
310
- }
311
-
312
- if (identifierNode?.getText() === mapper.name) {
313
- return {
314
- declarationNode: descendant,
315
- identifierNode,
316
- };
317
- }
318
- }
319
- }
320
- return;
321
- })();
322
-
323
- if (!firstDescendantThatIsMapper) {
324
- throw new Error(
325
- `Unable to find ${mapper.name} node after parsing. This shouldn't happen.`
326
- );
327
- }
328
-
329
- return getOriginalDeclarationNode(firstDescendantThatIsMapper);
330
- };
331
-
332
- interface GetOriginalDeclarationNodeParams {
333
- declarationNode:
334
- | InterfaceDeclaration
335
- | TypeAliasDeclaration
336
- | ExportSpecifier
337
- | ClassDeclaration;
338
- identifierNode: Identifier;
339
- }
340
- const getOriginalDeclarationNode = ({
341
- declarationNode,
342
- identifierNode,
343
- }: GetOriginalDeclarationNodeParams): Node => {
344
- if (
345
- declarationNode.isKind(SyntaxKind.ExportSpecifier) ||
346
- declarationNode.isKind(SyntaxKind.ClassDeclaration)
347
- ) {
348
- return identifierNode.getDefinitionNodes()[0];
349
- }
350
-
351
- // InterfaceDeclaration
352
- if (declarationNode.isKind(SyntaxKind.InterfaceDeclaration)) {
353
- return declarationNode;
354
- }
355
-
356
- // TypeAliasDeclaration
357
- const typeNode = declarationNode.getTypeNodeOrThrow();
358
- return Node.isTypeReference(typeNode)
359
- ? identifierNode.getDefinitionNodes()[0] // If type alias is a reference, go to definition using `getDefinitionNodes`
360
- : declarationNode;
361
- };
@@ -1,115 +0,0 @@
1
- import { Project, Node } from 'ts-morph';
2
- import { getNodePropertyMap } from './getNodePropertyMap.js';
3
-
4
- describe('getNodePropertyMap', () => {
5
- it('correctly resolves property map of a typical types.generated.ts', () => {
6
- const project = new Project();
7
- const sourceFile = project.createSourceFile(
8
- '/path/to/types.generated.ts',
9
- `
10
- export type Maybe<T> = T | null;
11
- export type Scalars = {
12
- ID: { input: string; output: string; }
13
- String: { input: string; output: string; }
14
- Boolean: { input: boolean; output: boolean; }
15
- Int: { input: number; output: number; }
16
- Float: { input: number; output: number; }
17
- DateTime: { input: Date; output: Date | string | number; }
18
- };
19
- export type User = {
20
- __typename: 'User';
21
- accountGitHub?: Maybe<Scalars['String']['output']>;
22
- accountGoogle?: Maybe<Scalars['String']['output']>;
23
- createdAt: Scalars['DateTime']['output'];
24
- fullName: Scalars['String']['output'];
25
- id: Scalars['ID']['output'];
26
- role: UserRole;
27
- };
28
- export type UserRole = 'ADMIN' | 'USER';`
29
- );
30
-
31
- const userDeclarationNode = sourceFile.getFirstDescendant(
32
- (node) => Node.isTypeAliasDeclaration(node) && node.getName() === 'User'
33
- );
34
-
35
- const nodePropertyMap = getNodePropertyMap({ node: userDeclarationNode });
36
-
37
- expect(nodePropertyMap.__typename.name).toBe('__typename');
38
-
39
- expect(nodePropertyMap.accountGitHub.name).toBe('accountGitHub');
40
-
41
- expect(nodePropertyMap.accountGoogle.name).toBe('accountGoogle');
42
-
43
- expect(nodePropertyMap.createdAt.name).toBe('createdAt');
44
-
45
- expect(nodePropertyMap.fullName.name).toBe('fullName');
46
-
47
- expect(nodePropertyMap.id.name).toBe('id');
48
-
49
- expect(nodePropertyMap.role.name).toBe('role');
50
- });
51
-
52
- it('correctly resolves property map a class', () => {
53
- const project = new Project();
54
- const sourceFile = project.createSourceFile(
55
- '/path/to/types.ts',
56
- `
57
- export type UserRole = 'ADMIN' | 'USER';
58
- export class User {
59
- #_id: string;
60
- private word: string;
61
- protected word2: string;
62
-
63
- name: string;
64
- role: UserRole;
65
-
66
- get id(): string {
67
- return this.#_id;
68
- }
69
- }`
70
- );
71
-
72
- const userDeclarationNode = sourceFile.getFirstDescendant(
73
- (node) => Node.isClassDeclaration(node) && node.getName() === 'User'
74
- );
75
-
76
- const nodePropertyMap = getNodePropertyMap({ node: userDeclarationNode });
77
-
78
- expect(nodePropertyMap._id).toBe(undefined);
79
- expect(nodePropertyMap.id).toBe(undefined);
80
- expect(nodePropertyMap.word).toBe(undefined);
81
- expect(nodePropertyMap.word2).toBe(undefined);
82
-
83
- expect(nodePropertyMap.name.name).toBe('name');
84
-
85
- expect(nodePropertyMap.role.name).toBe('role');
86
- });
87
-
88
- it('correctly resolves property map a type alias mapper', () => {
89
- const project = new Project();
90
- const sourceFile = project.createSourceFile(
91
- '/path/to/mappers.ts',
92
- `
93
- type UserRole = 'Admin' | 'User';
94
- export type UserMapper = {
95
- id: number;
96
- name: string;
97
- role: UserRole;
98
- }`
99
- );
100
-
101
- const node = sourceFile.getFirstDescendant(
102
- (descendant) =>
103
- Node.isTypeAliasDeclaration(descendant) &&
104
- descendant.getName() === 'UserMapper'
105
- );
106
-
107
- const nodePropertyMap = getNodePropertyMap({ node });
108
-
109
- expect(nodePropertyMap.id.name).toBe('id');
110
-
111
- expect(nodePropertyMap.name.name).toBe('name');
112
-
113
- expect(nodePropertyMap.role.name).toBe('role');
114
- });
115
- });
@@ -1,88 +0,0 @@
1
- import {
2
- type ClassDeclaration,
3
- type Node,
4
- type Type,
5
- SyntaxKind,
6
- } from 'ts-morph';
7
-
8
- type NodePropertyMapValue = {
9
- name: string;
10
- type: Type;
11
- };
12
- export type NodePropertyMap = Record<string, NodePropertyMapValue>;
13
-
14
- /**
15
- * Function to get properties of a Node in a map
16
- * If unable to find, returns empty object
17
- */
18
- export const getNodePropertyMap = ({
19
- node,
20
- }: {
21
- node: Node | undefined;
22
- }): NodePropertyMap => {
23
- if (!node) {
24
- return {};
25
- }
26
-
27
- const properties = ((): NodePropertyMapValue[] => {
28
- if (node.isKind(SyntaxKind.ClassDeclaration)) {
29
- const result: NodePropertyMapValue[] = [];
30
- collectClassNodeProperties(node, result);
31
- return result;
32
- }
33
-
34
- return node
35
- .getType()
36
- .getProperties()
37
- .map((prop) => {
38
- return {
39
- name: prop.getName(),
40
- type: prop.getTypeAtLocation(node),
41
- };
42
- });
43
- })();
44
-
45
- const nodePropertyMap = properties.reduce<NodePropertyMap>(
46
- (res, { name, type }) => {
47
- res[name] = {
48
- name,
49
- type,
50
- };
51
- return res;
52
- },
53
- {}
54
- );
55
-
56
- return nodePropertyMap;
57
- };
58
-
59
- const collectClassNodeProperties = (
60
- classNode: ClassDeclaration,
61
- result: NodePropertyMapValue[]
62
- ): void => {
63
- const baseClass = classNode.getBaseClass();
64
- if (baseClass) {
65
- collectClassNodeProperties(baseClass, result);
66
- }
67
-
68
- classNode.getInstanceProperties().forEach((prop) => {
69
- if (
70
- prop.hasModifier(SyntaxKind.PrivateKeyword) ||
71
- prop.hasModifier(SyntaxKind.ProtectedKeyword)
72
- ) {
73
- return;
74
- }
75
- if (prop.getName().startsWith('#')) {
76
- // ecma script private field is skipped
77
- return;
78
- }
79
- if (classNode.getGetAccessor(prop.getName())) {
80
- // getter is skipped
81
- return;
82
- }
83
- result.push({
84
- name: prop.getName(),
85
- type: prop.getType(),
86
- });
87
- });
88
- };
@@ -1 +0,0 @@
1
- export * from './getGraphQLObjectTypeResolversToGenerate.js';
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export { defineConfig as defineServerConfig } from '@eddeee888/gcg-server-config';
2
- export { preset } from './preset.js';
3
- export { defineConfig } from './defineConfig.js';
@@ -1 +0,0 @@
1
- export * from './normalizeAddConfigPath.js';
@@ -1,29 +0,0 @@
1
- import * as path from 'path';
2
- import type { AddPluginConfig } from '@graphql-codegen/add';
3
-
4
- /**
5
- * normalizeAddConfigPath
6
- *
7
- * Function to turn the add config keys into normalized path a.k.a. path from baseOutputDir
8
- * This helps us detects targeted file being given in different formats e.g. './types.generated.ts' vs 'types.generated.ts'
9
- */
10
- export const normalizeAddConfigPath = ({
11
- add,
12
- baseOutputDir,
13
- }: {
14
- add?: Record<string, AddPluginConfig>;
15
- baseOutputDir: string;
16
- }): Record<string, AddPluginConfig> | undefined => {
17
- if (!add) {
18
- return undefined;
19
- }
20
-
21
- const normalizedPathAdd = Object.entries(add).reduce<
22
- Record<string, AddPluginConfig>
23
- >((res, [originalFilePath, config]) => {
24
- res[path.posix.join(baseOutputDir, originalFilePath)] = config;
25
- return res;
26
- }, {});
27
-
28
- return normalizedPathAdd;
29
- };
@@ -1,2 +0,0 @@
1
- export * from './parseGraphQLSchema.js';
2
- export type { NormalizedResolverName } from './normalizeResolverName.js';
@@ -1,28 +0,0 @@
1
- import type { RootObjectType } from '../utils/index.js';
2
-
3
- export interface NormalizedResolverName {
4
- base: string;
5
- withModule: string;
6
- }
7
-
8
- /**
9
- * Function to get format resolver name based on its definition in the schema
10
- * - Root object type resolver e.g Query.me, Mutation.updateUser
11
- * - Object type e.g. User, Profile
12
- *
13
- * Returns an object with 2 key/value pairs:
14
- * - base: resolver name without module. This is used by to match up with config.externalResolvers.
15
- * - withModule: resolver name with module. This is used to identify the resolver INTERNAL unique path used in main resolver files.
16
- */
17
- export const normalizeResolverName = (
18
- moduleName: string,
19
- name: string,
20
- rootObject: RootObjectType | null
21
- ): NormalizedResolverName => {
22
- const baseResolverName = !rootObject ? name : `${rootObject}.${name}`;
23
-
24
- return {
25
- base: baseResolverName,
26
- withModule: `${moduleName}.${baseResolverName}`,
27
- };
28
- };