@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,127 +0,0 @@
1
- import { Project } from 'ts-morph';
2
- import { getImportStatementWithExpectedNamedImport } from './getImportStatementWithExpectedNamedImport.js';
3
-
4
- describe('getImportStatementWithExpectedNamedImport', () => {
5
- it('returns import statement if found for objectType files', () => {
6
- const project = new Project();
7
- const sourceFile = project.createSourceFile(
8
- '/pathto/User.ts',
9
- `
10
- import { UserResolvers } from '../types.generated.ts';
11
- export const User: UserResolvers = {
12
- id: ({ id }) => id,
13
- }
14
- `
15
- );
16
-
17
- const result = getImportStatementWithExpectedNamedImport(sourceFile, {
18
- __filetype: 'objectType',
19
- content: '',
20
- filesystem: {
21
- type: 'virtual',
22
- contentUpdated: false,
23
- },
24
- mainImportIdentifier: 'User',
25
- meta: {
26
- moduleName: 'user',
27
- relativePathFromBaseToModule: ['user'],
28
- resolverTypeImportDeclaration: '',
29
- variableStatement: '',
30
- resolverType: {
31
- baseImport: 'UserResolvers',
32
- final: 'UserResolvers',
33
- otherVariants: [],
34
- },
35
- normalizedResolverName: {
36
- base: 'User',
37
- withModule: 'user.User',
38
- },
39
- },
40
- });
41
-
42
- expect(result.importDeclaration?.getText()).toBe(
43
- `import { UserResolvers } from '../types.generated.ts';`
44
- );
45
- });
46
-
47
- it('returns import statement if found for rootObjectTypeFieldResolver files', () => {
48
- const project = new Project();
49
- const sourceFile = project.createSourceFile(
50
- '/pathto/Query/me.ts',
51
- `
52
- import { QueryResolvers } from '../types.generated.ts';
53
- export const me: QueryResolvers['me'] = () => {};
54
- `
55
- );
56
-
57
- const result = getImportStatementWithExpectedNamedImport(sourceFile, {
58
- __filetype: 'rootObjectTypeFieldResolver',
59
- content: '',
60
- filesystem: {
61
- type: 'virtual',
62
- contentUpdated: false,
63
- },
64
- mainImportIdentifier: 'user',
65
- meta: {
66
- belongsToRootObject: 'Query',
67
- moduleName: 'user',
68
- normalizedResolverName: {
69
- base: 'Query.user',
70
- withModule: 'user.Query.user',
71
- },
72
- relativePathFromBaseToModule: ['user'],
73
- resolverType: {
74
- baseImport: 'QueryResolvers',
75
- resolver: "QueryResolvers['me']",
76
- final: "NonNullable<QueryResolvers['me']>",
77
- },
78
- resolverTypeImportDeclaration: '',
79
- variableStatement: '',
80
- },
81
- });
82
-
83
- expect(result.importDeclaration?.getText()).toBe(
84
- `import { QueryResolvers } from '../types.generated.ts';`
85
- );
86
- });
87
-
88
- it('returns import statement if found for interfaceResolver files', () => {
89
- const project = new Project();
90
- const sourceFile = project.createSourceFile(
91
- '/pathto/User.ts',
92
- `
93
- import { NodeResolvers } from '../types.generated.ts';
94
- export const Node: NodeResolvers = {
95
- }
96
- `
97
- );
98
-
99
- const result = getImportStatementWithExpectedNamedImport(sourceFile, {
100
- __filetype: 'interfaceResolver',
101
- content: '',
102
- filesystem: {
103
- type: 'virtual',
104
- contentUpdated: false,
105
- },
106
- mainImportIdentifier: 'user',
107
- meta: {
108
- moduleName: 'user',
109
- normalizedResolverName: {
110
- base: 'Query.user',
111
- withModule: 'user.Query.user',
112
- },
113
- relativePathFromBaseToModule: ['user'],
114
- resolverType: {
115
- baseImport: 'NodeResolvers',
116
- final: 'NodeResolvers',
117
- },
118
- resolverTypeImportDeclaration: '',
119
- variableStatement: '',
120
- },
121
- });
122
-
123
- expect(result.importDeclaration?.getText()).toBe(
124
- `import { NodeResolvers } from '../types.generated.ts';`
125
- );
126
- });
127
- });
@@ -1,25 +0,0 @@
1
- import type { ImportDeclaration, SourceFile } from 'ts-morph';
2
- import type { ResolverFile } from './types.js';
3
-
4
- export const getImportStatementWithExpectedNamedImport = (
5
- sourceFile: SourceFile,
6
- resolverFile: ResolverFile
7
- ): {
8
- importDeclaration: ImportDeclaration | undefined;
9
- } => {
10
- const importDeclaration = sourceFile.getImportDeclaration((declaration) => {
11
- let foundNamedImport = false;
12
- declaration.getNamedImports().forEach((namedImport) => {
13
- if (
14
- namedImport.getName() === resolverFile.meta.resolverType?.baseImport
15
- ) {
16
- foundNamedImport = true;
17
- }
18
- });
19
- return foundNamedImport;
20
- });
21
-
22
- return {
23
- importDeclaration,
24
- };
25
- };
@@ -1,147 +0,0 @@
1
- import { Project } from 'ts-morph';
2
- import { getVariableStatementWithExpectedIdentifier } from './getVariableStatementWithExpectedIdentifier.js';
3
-
4
- describe('getVariableStatementWithExpectedIdentifier()', () => {
5
- it('gets VariableStatement node and isExported=true if found', () => {
6
- const project = new Project();
7
- const sourceFile = project.createSourceFile(
8
- '/pathto/User.ts',
9
- `
10
- import {} from '../types.generated.ts';
11
-
12
- const DontLookAtThisNode = {};
13
-
14
- export const User: UserResolvers = {
15
- id: ({ id }) => id,
16
- }
17
-
18
- const DontLookAtThisNodeEither = {};
19
- `
20
- );
21
- const result = getVariableStatementWithExpectedIdentifier(sourceFile, {
22
- __filetype: 'objectType',
23
- content: '',
24
- filesystem: {
25
- type: 'virtual',
26
- contentUpdated: false,
27
- },
28
- mainImportIdentifier: 'User',
29
- meta: {
30
- moduleName: 'user',
31
- relativePathFromBaseToModule: ['user'],
32
- variableStatement: '',
33
- resolverTypeImportDeclaration: '',
34
- resolverType: {
35
- baseImport: 'UserResolvers',
36
- final: 'UserResolvers',
37
- otherVariants: [],
38
- },
39
- normalizedResolverName: {
40
- base: 'User',
41
- withModule: 'user.User',
42
- },
43
- },
44
- });
45
-
46
- expect(result.isExported).toBe(true);
47
- expect(result.variableStatement?.getText()).toMatchInlineSnapshot(`
48
- "export const User: UserResolvers = {
49
- id: ({ id }) => id,
50
- }"
51
- `);
52
- });
53
-
54
- it('returns variableStatement=undefined and isExported=false if NOT found', () => {
55
- const project = new Project();
56
- const sourceFile = project.createSourceFile(
57
- '/pathto/User.ts',
58
- `
59
- import {} from '../types.generated.ts';
60
-
61
- const DontLookAtThisNode = {};
62
-
63
- export const Userssss: UserResolvers = {
64
- id: ({ id }) => id,
65
- }
66
-
67
- const DontLookAtThisNodeEither = {};
68
- `
69
- );
70
- const result = getVariableStatementWithExpectedIdentifier(sourceFile, {
71
- __filetype: 'objectType',
72
- content: '',
73
- filesystem: {
74
- type: 'virtual',
75
- contentUpdated: false,
76
- },
77
- mainImportIdentifier: 'User',
78
- meta: {
79
- moduleName: 'user',
80
- relativePathFromBaseToModule: ['user'],
81
- variableStatement: '',
82
- resolverTypeImportDeclaration: '',
83
- resolverType: {
84
- baseImport: 'UserResolvers',
85
- final: 'UserResolvers',
86
- otherVariants: [],
87
- },
88
- normalizedResolverName: {
89
- base: 'User',
90
- withModule: 'user.User',
91
- },
92
- },
93
- });
94
-
95
- expect(result.isExported).toBe(false);
96
- expect(result.variableStatement).toBeUndefined();
97
- });
98
-
99
- it('returns variableStatement=undefined and isExported=true if found but not exported', () => {
100
- const project = new Project();
101
- const sourceFile = project.createSourceFile(
102
- '/pathto/User.ts',
103
- `
104
- import {} from '../types.generated.ts';
105
-
106
- const DontLookAtThisNode = {};
107
-
108
- const User: UserResolvers = {
109
- id: ({ id }) => id,
110
- }
111
-
112
- const DontLookAtThisNodeEither = {};
113
- `
114
- );
115
- const result = getVariableStatementWithExpectedIdentifier(sourceFile, {
116
- __filetype: 'objectType',
117
- content: '',
118
- filesystem: {
119
- type: 'virtual',
120
- contentUpdated: false,
121
- },
122
- mainImportIdentifier: 'User',
123
- meta: {
124
- moduleName: 'user',
125
- relativePathFromBaseToModule: ['user'],
126
- variableStatement: '',
127
- resolverTypeImportDeclaration: '',
128
- resolverType: {
129
- baseImport: 'UserResolvers',
130
- final: 'UserResolvers',
131
- otherVariants: [],
132
- },
133
- normalizedResolverName: {
134
- base: 'User',
135
- withModule: 'user.User',
136
- },
137
- },
138
- });
139
-
140
- expect(result.isExported).toBe(false);
141
- expect(result.variableStatement?.getText()).toMatchInlineSnapshot(`
142
- "const User: UserResolvers = {
143
- id: ({ id }) => id,
144
- }"
145
- `);
146
- });
147
- });
@@ -1,34 +0,0 @@
1
- import type { SourceFile, VariableStatement } from 'ts-morph';
2
- import type { ResolverFile } from './types.js';
3
-
4
- export const getVariableStatementWithExpectedIdentifier = (
5
- sourceFile: SourceFile,
6
- resolverFile: ResolverFile
7
- ): {
8
- variableStatement: VariableStatement | undefined;
9
- isExported: boolean;
10
- } => {
11
- let isExported = false;
12
-
13
- const variableStatementWithExpectedIdentifier =
14
- sourceFile.getVariableStatement((statement) => {
15
- let hasExpectedIdentifier = false;
16
- statement
17
- .getDeclarationList()
18
- .getDeclarations()
19
- .forEach((declarationNode) => {
20
- if (declarationNode.getName() === resolverFile.mainImportIdentifier) {
21
- hasExpectedIdentifier = true;
22
- if (statement.isExported()) {
23
- isExported = true;
24
- }
25
- }
26
- });
27
- return hasExpectedIdentifier;
28
- });
29
-
30
- return {
31
- variableStatement: variableStatementWithExpectedIdentifier,
32
- isExported,
33
- };
34
- };
@@ -1,100 +0,0 @@
1
- import {
2
- isMatchResolverNamePattern,
3
- logger,
4
- printImportLine,
5
- } from '../utils/index.js';
6
- import type { GraphQLTypeHandler } from './types.js';
7
-
8
- export const handleGraphQLEnumType: GraphQLTypeHandler<
9
- null,
10
- { allowedValues: string[] }
11
- > = (
12
- {
13
- fieldFilePath,
14
- relativePathFromBaseToModule,
15
- resolverName,
16
- isFileAlreadyOnFilesystem,
17
- normalizedResolverName,
18
- resolversTypeMeta,
19
- moduleName,
20
- allowedValues,
21
- },
22
- {
23
- result,
24
- config: {
25
- typeMappersMap,
26
- resolverGeneration,
27
- emitLegacyCommonJSImports,
28
- importExtension,
29
- },
30
- }
31
- ) => {
32
- const matchedPatternToGenerate = isMatchResolverNamePattern({
33
- pattern: resolverGeneration.enum,
34
- value: normalizedResolverName.withModule,
35
- });
36
- const mapperDetails = typeMappersMap[normalizedResolverName.base];
37
-
38
- if (
39
- !matchedPatternToGenerate &&
40
- !mapperDetails &&
41
- !isFileAlreadyOnFilesystem
42
- ) {
43
- logger.debug(
44
- `Skipped Enum resolver generation: "${normalizedResolverName.withModule}". Pattern: "${resolverGeneration.enum}".`
45
- );
46
- return;
47
- }
48
-
49
- const forcedGenerationWarning = (() => {
50
- if (!matchedPatternToGenerate && mapperDetails) {
51
- logger.debug(
52
- `Enum resolver generation was NOT skipped because there is a associated mapper: "${normalizedResolverName.withModule}". "Pattern: ${resolverGeneration.enum}". Mapper: ${mapperDetails.mapper.name}`
53
- );
54
- return `/*
55
- * Note: This enum file is generated because "${mapperDetails.mapper.name}" is declared. This is to ensure runtime safety.
56
- * If you want to skip this file generation, remove the mapper or update the pattern in the \`resolverGeneration.object\` config.
57
- */\n`;
58
- }
59
- return '';
60
- })();
61
-
62
- const resolverTypeImportDeclaration = printImportLine({
63
- isTypeImport: true,
64
- module: resolversTypeMeta.module,
65
- moduleType: resolversTypeMeta.moduleType,
66
- namedImports: [resolversTypeMeta.typeNamedImport],
67
- emitLegacyCommonJSImports,
68
- importExtension,
69
- });
70
-
71
- const variableStatement = `${forcedGenerationWarning}export const ${resolverName}: ${
72
- resolversTypeMeta.typeString
73
- } = {
74
- ${allowedValues.map((value) => `${value}: '${value}'`).join(',\n')}
75
- }`;
76
-
77
- result.files[fieldFilePath] = {
78
- __filetype: 'enumResolver',
79
- filesystem: {
80
- type: 'virtual',
81
- contentUpdated: false,
82
- },
83
- content: `
84
- ${resolverTypeImportDeclaration}
85
- ${variableStatement}`,
86
- mainImportIdentifier: resolverName,
87
- meta: {
88
- moduleName,
89
- relativePathFromBaseToModule,
90
- resolverTypeImportDeclaration,
91
- variableStatement,
92
- resolverType: {
93
- baseImport: resolversTypeMeta.typeNamedImport,
94
- final: resolversTypeMeta.typeString,
95
- },
96
- normalizedResolverName,
97
- allowedValues,
98
- },
99
- };
100
- };
@@ -1,70 +0,0 @@
1
- import {
2
- printImportLine,
3
- isMatchResolverNamePattern,
4
- logger,
5
- } from '../utils/index.js';
6
- import type { GraphQLTypeHandler } from './types.js';
7
-
8
- export const handleGraphQLInterfaceType: GraphQLTypeHandler = (
9
- {
10
- fieldFilePath,
11
- isFileAlreadyOnFilesystem,
12
- resolverName,
13
- normalizedResolverName,
14
- resolversTypeMeta,
15
- moduleName,
16
- relativePathFromBaseToModule,
17
- },
18
- {
19
- result,
20
- config: { resolverGeneration, emitLegacyCommonJSImports, importExtension },
21
- }
22
- ) => {
23
- if (
24
- !isMatchResolverNamePattern({
25
- pattern: resolverGeneration.interface,
26
- value: normalizedResolverName.withModule,
27
- }) &&
28
- !isFileAlreadyOnFilesystem
29
- ) {
30
- logger.debug(
31
- `Skipped Interface resolver generation: "${normalizedResolverName.withModule}". Pattern: "${resolverGeneration.interface}".`
32
- );
33
- return;
34
- }
35
-
36
- const resolverTypeString = resolversTypeMeta.typeString;
37
-
38
- const resolverTypeImportDeclaration = printImportLine({
39
- isTypeImport: true,
40
- module: resolversTypeMeta.module,
41
- moduleType: resolversTypeMeta.moduleType,
42
- namedImports: [resolversTypeMeta.typeNamedImport],
43
- emitLegacyCommonJSImports,
44
- importExtension,
45
- });
46
- const variableStatement = `export const ${resolverName}: ${resolverTypeString} = { /* Implement ${resolverName} interface logic here */ };`;
47
-
48
- result.files[fieldFilePath] = {
49
- __filetype: 'interfaceResolver',
50
- filesystem: {
51
- type: 'virtual',
52
- contentUpdated: false,
53
- },
54
- content: `
55
- ${resolverTypeImportDeclaration}
56
- ${variableStatement}`,
57
- mainImportIdentifier: resolverName,
58
- meta: {
59
- moduleName,
60
- relativePathFromBaseToModule,
61
- normalizedResolverName,
62
- resolverTypeImportDeclaration,
63
- variableStatement,
64
- resolverType: {
65
- baseImport: resolversTypeMeta.typeNamedImport,
66
- final: resolverTypeString,
67
- },
68
- },
69
- };
70
- };
@@ -1,171 +0,0 @@
1
- import type { GraphQLTypeHandler } from './types.js';
2
- import {
3
- printImportLine,
4
- isMatchResolverNamePattern,
5
- logger,
6
- } from '../utils/index.js';
7
-
8
- export const handleGraphQLObjectType: GraphQLTypeHandler<
9
- null,
10
- {
11
- fieldsToPick?: string[];
12
- }
13
- > = (
14
- {
15
- fieldFilePath,
16
- resolverName,
17
- isFileAlreadyOnFilesystem,
18
- normalizedResolverName,
19
- resolversTypeMeta,
20
- moduleName,
21
- relativePathFromBaseToModule,
22
- fieldsToPick = [], // If fieldsToPick.length === 0, it means the current object handles all resolvers
23
- generatedTypesFileMeta,
24
- },
25
- {
26
- result,
27
- config: {
28
- resolverGeneration,
29
- typeMappersMap,
30
- graphQLObjectTypeResolversToGenerate,
31
- emitLegacyCommonJSImports,
32
- importExtension,
33
- },
34
- }
35
- ) => {
36
- const matchedPatternToGenerate = isMatchResolverNamePattern({
37
- pattern: resolverGeneration.object,
38
- value: normalizedResolverName.withModule,
39
- });
40
- const mapperDetails = typeMappersMap[normalizedResolverName.base];
41
-
42
- if (
43
- !matchedPatternToGenerate &&
44
- !mapperDetails &&
45
- !isFileAlreadyOnFilesystem
46
- ) {
47
- logger.debug(
48
- `Skipped Object resolver generation: "${normalizedResolverName.withModule}". "Pattern: ${resolverGeneration.object}".`
49
- );
50
- return;
51
- }
52
-
53
- const forcedGenerationWarning = (() => {
54
- if (!matchedPatternToGenerate && mapperDetails) {
55
- logger.debug(
56
- `Object resolver generation was NOT skipped because there is a associated mapper: "${normalizedResolverName.withModule}". "Pattern: ${resolverGeneration.object}". Mapper: ${mapperDetails.mapper.name}`
57
- );
58
- return `/*
59
- * Note: This object type is generated because "${mapperDetails.mapper.name}" is declared. This is to ensure runtime safety.
60
- *
61
- * When a mapper is used, it is possible to hit runtime errors in some scenarios:
62
- * - given a field name, the schema type's field type does not match mapper's field type
63
- * - or a schema type's field does not exist in the mapper's fields
64
- *
65
- * If you want to skip this file generation, remove the mapper or update the pattern in the \`resolverGeneration.object\` config.
66
- */\n`;
67
- }
68
- return '';
69
- })();
70
-
71
- const hasFieldsToPick = fieldsToPick.length > 0;
72
-
73
- // __isTypeOf is required to resolve abstract types, should user chooses this approach.
74
- // TODO: Run static analysis to enforce only one __isTypeOf per Object type, so users cannot accidentally implement/override it across modules
75
- if (
76
- hasFieldsToPick &&
77
- generatedTypesFileMeta.generatedResolverTypes.userDefined[
78
- normalizedResolverName.base
79
- ].hasIsTypeOf
80
- ) {
81
- fieldsToPick.push('__isTypeOf');
82
- }
83
-
84
- if (
85
- hasFieldsToPick &&
86
- generatedTypesFileMeta.generatedResolverTypes.userDefined[
87
- normalizedResolverName.base
88
- ].federation?.hasResolveReference
89
- ) {
90
- fieldsToPick.push('__resolveReference');
91
- }
92
-
93
- // - `typeString` contains the resolver type
94
- // If there's fieldsToPick, we must only pick said fields from the original resolver type
95
- // - `otherTypeStringVariants` contains other types that are the same as `typeString` but formatted differently
96
- // This is used to check if the resolver type is the same when running static analysis
97
- // We want to use string comparison instead of true AST check because it's a lot faster and simpler
98
- const { typeString, otherTypeStringVariants } = ((): {
99
- typeString: string;
100
- otherTypeStringVariants: string[];
101
- } => {
102
- if (hasFieldsToPick) {
103
- return {
104
- typeString: `Pick<${resolversTypeMeta.typeString}, ${fieldsToPick
105
- .map((fieldName) => `'${fieldName}'`)
106
- .join('|')}>`,
107
- otherTypeStringVariants: [
108
- `Pick<${resolversTypeMeta.typeString}, |${fieldsToPick
109
- .map((fieldName) => `'${fieldName}'`)
110
- .join('|')}>`,
111
- ],
112
- };
113
- }
114
-
115
- return {
116
- typeString: resolversTypeMeta.typeString,
117
- otherTypeStringVariants: [],
118
- };
119
- })();
120
-
121
- // Array of all resolvers that may need type checking
122
- // If there's fieldsToPick, we must only generate said fields
123
- const allResolversToGenerate =
124
- graphQLObjectTypeResolversToGenerate[resolverName];
125
- const resolversToGenerate = hasFieldsToPick
126
- ? fieldsToPick.reduce<typeof allResolversToGenerate>((res, fieldToPick) => {
127
- if (allResolversToGenerate && allResolversToGenerate[fieldToPick]) {
128
- res[fieldToPick] = allResolversToGenerate[fieldToPick];
129
- }
130
- return res;
131
- }, {})
132
- : allResolversToGenerate;
133
-
134
- const variableStatement = `${forcedGenerationWarning}export const ${resolverName}: ${typeString} = {
135
- /* Implement ${resolverName} resolver logic here */
136
- };`;
137
-
138
- const resolverTypeImportDeclaration = printImportLine({
139
- isTypeImport: true,
140
- module: resolversTypeMeta.module,
141
- moduleType: resolversTypeMeta.moduleType,
142
- namedImports: [resolversTypeMeta.typeNamedImport],
143
- emitLegacyCommonJSImports,
144
- importExtension,
145
- });
146
-
147
- result.files[fieldFilePath] = {
148
- __filetype: 'objectType',
149
- filesystem: {
150
- type: 'virtual',
151
- contentUpdated: false,
152
- },
153
- content: `
154
- ${resolverTypeImportDeclaration}
155
- ${variableStatement}`,
156
- mainImportIdentifier: resolverName,
157
- meta: {
158
- moduleName,
159
- relativePathFromBaseToModule,
160
- normalizedResolverName,
161
- resolverTypeImportDeclaration,
162
- variableStatement,
163
- resolverType: {
164
- baseImport: resolversTypeMeta.typeNamedImport,
165
- final: typeString,
166
- otherVariants: otherTypeStringVariants,
167
- },
168
- resolversToGenerate,
169
- },
170
- };
171
- };