@eddeee888/gcg-typescript-resolver-files 0.18.0 → 0.18.2
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.
- package/dist/defineConfig.d.ts +1 -1
- package/dist/defineConfig.js +8 -0
- package/package.json +7 -3
- package/CHANGELOG.md +0 -816
- package/DEVELOPMENT.md +0 -49
- package/dist/tsconfig.lib.tsbuildinfo +0 -1
- package/eslint.config.mjs +0 -22
- package/project.json +0 -8
- package/src/addVirtualTypesFileToTsMorphProject/addVirtualTypesFileToTsMorphProject.ts +0 -109
- package/src/addVirtualTypesFileToTsMorphProject/index.ts +0 -1
- package/src/defineConfig.spec.ts +0 -76
- package/src/defineConfig.ts +0 -37
- package/src/generateResolverFiles/addExternalResolverImport.ts +0 -185
- package/src/generateResolverFiles/addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented.spec.ts +0 -1174
- package/src/generateResolverFiles/addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented.ts +0 -144
- package/src/generateResolverFiles/addResolverMainFiles.ts +0 -343
- package/src/generateResolverFiles/ensureEnumTypeResolversAreGenerated.ts +0 -51
- package/src/generateResolverFiles/generateResolverFiles.ts +0 -148
- package/src/generateResolverFiles/getImportStatementWithExpectedNamedImport.spec.ts +0 -127
- package/src/generateResolverFiles/getImportStatementWithExpectedNamedImport.ts +0 -25
- package/src/generateResolverFiles/getVariableStatementWithExpectedIdentifier.spec.ts +0 -147
- package/src/generateResolverFiles/getVariableStatementWithExpectedIdentifier.ts +0 -34
- package/src/generateResolverFiles/handleGraphQLEnumType.ts +0 -100
- package/src/generateResolverFiles/handleGraphQLInterfaceType.ts +0 -70
- package/src/generateResolverFiles/handleGraphQLObjectType.ts +0 -171
- package/src/generateResolverFiles/handleGraphQLRootObjectTypeField.ts +0 -105
- package/src/generateResolverFiles/handleGraphQLScalarType.ts +0 -81
- package/src/generateResolverFiles/handleGraphQLUnionType.ts +0 -68
- package/src/generateResolverFiles/index.ts +0 -2
- package/src/generateResolverFiles/postProcessFiles.ts +0 -287
- package/src/generateResolverFiles/types.ts +0 -203
- package/src/generateResolverFiles/visitNamedType.ts +0 -66
- package/src/generateTypeDefsFiles/generateTypeDefsContent.ts +0 -15
- package/src/generateTypeDefsFiles/generateTypeDefsFiles.ts +0 -100
- package/src/generateTypeDefsFiles/index.ts +0 -1
- package/src/getGraphQLObjectTypeResolversToGenerate/getGraphQLObjectTypeResolversToGenerate.ts +0 -361
- package/src/getGraphQLObjectTypeResolversToGenerate/getNodePropertyMap.spec.ts +0 -115
- package/src/getGraphQLObjectTypeResolversToGenerate/getNodePropertyMap.ts +0 -88
- package/src/getGraphQLObjectTypeResolversToGenerate/index.ts +0 -1
- package/src/index.ts +0 -3
- package/src/normalizeAddConfigPath/index.ts +0 -1
- package/src/normalizeAddConfigPath/normalizeAddConfigPath.ts +0 -29
- package/src/parseGraphQLSchema/index.ts +0 -2
- package/src/parseGraphQLSchema/normalizeResolverName.ts +0 -28
- package/src/parseGraphQLSchema/parseGraphQLSchema.ts +0 -531
- package/src/parseGraphQLSchema/parseLocationForOutputDir.ts +0 -76
- package/src/parseSources/index.ts +0 -1
- package/src/parseSources/parseSources.ts +0 -83
- package/src/parseTypeMappers/collectTypeMappersFromSourceFile.spec.ts +0 -789
- package/src/parseTypeMappers/collectTypeMappersFromSourceFile.ts +0 -197
- package/src/parseTypeMappers/index.ts +0 -1
- package/src/parseTypeMappers/parseTypeMappers.ts +0 -75
- package/src/preset.ts +0 -317
- package/src/utils/cwd.ts +0 -8
- package/src/utils/fmt.ts +0 -16
- package/src/utils/index.ts +0 -12
- package/src/utils/isMatchResolverNamePattern.ts +0 -27
- package/src/utils/isNativeNamedType.ts +0 -21
- package/src/utils/isRootObjectType.ts +0 -8
- package/src/utils/isWhitelistedModule.spec.ts +0 -71
- package/src/utils/isWhitelistedModule.ts +0 -21
- package/src/utils/logger.ts +0 -14
- package/src/utils/normalizeImportExtension.spec.ts +0 -42
- package/src/utils/normalizeImportExtension.ts +0 -16
- package/src/utils/normalizeRelativePath.ts +0 -6
- package/src/utils/parseLocationForWhitelistedModule.spec.ts +0 -130
- package/src/utils/parseLocationForWhitelistedModule.ts +0 -38
- package/src/utils/printImportLine.spec.ts +0 -150
- package/src/utils/printImportLine.ts +0 -78
- package/src/utils/relativeModulePath.ts +0 -7
- package/src/validateAndMergeParsedConfigs/index.ts +0 -1
- package/src/validateAndMergeParsedConfigs/validateAndMergeParsedConfigs.spec.ts +0 -211
- package/src/validateAndMergeParsedConfigs/validateAndMergeParsedConfigs.ts +0 -92
- package/src/validatePresetConfig/index.ts +0 -1
- package/src/validatePresetConfig/validatePresetConfig.spec.ts +0 -706
- package/src/validatePresetConfig/validatePresetConfig.ts +0 -571
- package/tsconfig.json +0 -14
- package/tsconfig.lib.json +0 -18
- package/tsconfig.spec.json +0 -20
- package/vite.config.ts +0 -24
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
printImportLine,
|
|
3
|
-
isMatchResolverNamePattern,
|
|
4
|
-
logger,
|
|
5
|
-
type RootObjectType,
|
|
6
|
-
} from '../utils/index.js';
|
|
7
|
-
import type { GraphQLTypeHandler } from './types.js';
|
|
8
|
-
|
|
9
|
-
export const handleGraphQLRootObjectTypeField: GraphQLTypeHandler<
|
|
10
|
-
RootObjectType
|
|
11
|
-
> = (
|
|
12
|
-
{
|
|
13
|
-
fieldFilePath,
|
|
14
|
-
isFileAlreadyOnFilesystem,
|
|
15
|
-
resolverName,
|
|
16
|
-
belongsToRootObject,
|
|
17
|
-
normalizedResolverName,
|
|
18
|
-
resolversTypeMeta,
|
|
19
|
-
moduleName,
|
|
20
|
-
relativePathFromBaseToModule,
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
result,
|
|
24
|
-
config: { resolverGeneration, emitLegacyCommonJSImports, importExtension },
|
|
25
|
-
}
|
|
26
|
-
) => {
|
|
27
|
-
if (
|
|
28
|
-
(belongsToRootObject === 'Query' &&
|
|
29
|
-
!isMatchResolverNamePattern({
|
|
30
|
-
pattern: resolverGeneration.query,
|
|
31
|
-
value: normalizedResolverName.withModule,
|
|
32
|
-
}) &&
|
|
33
|
-
!isFileAlreadyOnFilesystem) ||
|
|
34
|
-
(belongsToRootObject === 'Mutation' &&
|
|
35
|
-
!isMatchResolverNamePattern({
|
|
36
|
-
pattern: resolverGeneration.mutation,
|
|
37
|
-
value: normalizedResolverName.withModule,
|
|
38
|
-
}) &&
|
|
39
|
-
!isFileAlreadyOnFilesystem) ||
|
|
40
|
-
(belongsToRootObject === 'Subscription' &&
|
|
41
|
-
!isMatchResolverNamePattern({
|
|
42
|
-
pattern: resolverGeneration.subscription,
|
|
43
|
-
value: normalizedResolverName.withModule,
|
|
44
|
-
}) &&
|
|
45
|
-
!isFileAlreadyOnFilesystem)
|
|
46
|
-
) {
|
|
47
|
-
const resolverGenerationPattern =
|
|
48
|
-
belongsToRootObject === 'Query'
|
|
49
|
-
? resolverGeneration.query
|
|
50
|
-
: belongsToRootObject === 'Mutation'
|
|
51
|
-
? resolverGeneration.mutation
|
|
52
|
-
: belongsToRootObject === 'Subscription'
|
|
53
|
-
? resolverGeneration.subscription
|
|
54
|
-
: 'Unknown';
|
|
55
|
-
logger.debug(
|
|
56
|
-
`Skipped ${belongsToRootObject} resolver generation: "${normalizedResolverName.withModule}". Pattern: "${resolverGenerationPattern}".`
|
|
57
|
-
);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const suggestion = `/* Implement ${normalizedResolverName.base} resolver logic here */`;
|
|
62
|
-
|
|
63
|
-
const resolverTypeString = `NonNullable<${resolversTypeMeta.typeString}>`;
|
|
64
|
-
|
|
65
|
-
let variableStatement = `export const ${resolverName}: ${resolverTypeString} = async (_parent, _arg, _ctx) => { ${suggestion} };`;
|
|
66
|
-
if (belongsToRootObject === 'Subscription') {
|
|
67
|
-
variableStatement = `export const ${resolverName}: ${resolverTypeString} = {
|
|
68
|
-
subscribe: async (_parent, _arg, _ctx) => { ${suggestion} },
|
|
69
|
-
}`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const resolverTypeImportDeclaration = printImportLine({
|
|
73
|
-
isTypeImport: true,
|
|
74
|
-
module: resolversTypeMeta.module,
|
|
75
|
-
moduleType: resolversTypeMeta.moduleType,
|
|
76
|
-
namedImports: [resolversTypeMeta.typeNamedImport],
|
|
77
|
-
emitLegacyCommonJSImports,
|
|
78
|
-
importExtension,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
result.files[fieldFilePath] = {
|
|
82
|
-
__filetype: 'rootObjectTypeFieldResolver',
|
|
83
|
-
filesystem: {
|
|
84
|
-
type: 'virtual',
|
|
85
|
-
contentUpdated: false,
|
|
86
|
-
},
|
|
87
|
-
content: `
|
|
88
|
-
${resolverTypeImportDeclaration}
|
|
89
|
-
${variableStatement}`,
|
|
90
|
-
mainImportIdentifier: resolverName,
|
|
91
|
-
meta: {
|
|
92
|
-
moduleName,
|
|
93
|
-
relativePathFromBaseToModule,
|
|
94
|
-
belongsToRootObject,
|
|
95
|
-
resolverTypeImportDeclaration,
|
|
96
|
-
variableStatement,
|
|
97
|
-
resolverType: {
|
|
98
|
-
baseImport: resolversTypeMeta.typeNamedImport,
|
|
99
|
-
resolver: resolversTypeMeta.typeString,
|
|
100
|
-
final: resolverTypeString,
|
|
101
|
-
},
|
|
102
|
-
normalizedResolverName,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
printImportLine,
|
|
3
|
-
isMatchResolverNamePattern,
|
|
4
|
-
logger,
|
|
5
|
-
} from '../utils/index.js';
|
|
6
|
-
import type { GraphQLTypeHandler } from './types.js';
|
|
7
|
-
|
|
8
|
-
const graphQLScalarType = 'GraphQLScalarType';
|
|
9
|
-
|
|
10
|
-
export const handleGraphQLScalarType: GraphQLTypeHandler = (
|
|
11
|
-
{
|
|
12
|
-
fieldFilePath,
|
|
13
|
-
isFileAlreadyOnFilesystem,
|
|
14
|
-
resolverName,
|
|
15
|
-
normalizedResolverName,
|
|
16
|
-
moduleName,
|
|
17
|
-
relativePathFromBaseToModule,
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
result,
|
|
21
|
-
config: { resolverGeneration, emitLegacyCommonJSImports, importExtension },
|
|
22
|
-
}
|
|
23
|
-
) => {
|
|
24
|
-
if (
|
|
25
|
-
!isMatchResolverNamePattern({
|
|
26
|
-
pattern: resolverGeneration.scalar,
|
|
27
|
-
value: normalizedResolverName.withModule,
|
|
28
|
-
}) &&
|
|
29
|
-
!isFileAlreadyOnFilesystem
|
|
30
|
-
) {
|
|
31
|
-
logger.debug(
|
|
32
|
-
`Skipped Scalar resolver generation: "${normalizedResolverName.withModule}". Pattern: "${resolverGeneration.scalar}".`
|
|
33
|
-
);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const resolverTypeImportDeclaration = printImportLine({
|
|
38
|
-
isTypeImport: false,
|
|
39
|
-
module: 'graphql',
|
|
40
|
-
moduleType: 'module',
|
|
41
|
-
namedImports: [graphQLScalarType],
|
|
42
|
-
emitLegacyCommonJSImports,
|
|
43
|
-
importExtension,
|
|
44
|
-
});
|
|
45
|
-
const variableStatement = `export const ${resolverName} = new ${graphQLScalarType}({
|
|
46
|
-
name: '${resolverName}',
|
|
47
|
-
description: '${resolverName} description',
|
|
48
|
-
serialize: (value) => {
|
|
49
|
-
/* Implement logic to turn the returned value from resolvers to a value that can be sent to clients */
|
|
50
|
-
},
|
|
51
|
-
parseValue: (value) => {
|
|
52
|
-
/* Implement logic to parse input that was sent to the server as variables */
|
|
53
|
-
},
|
|
54
|
-
parseLiteral: (ast) => {
|
|
55
|
-
/* Implement logic to parse input that was sent to the server as literal values (string, number, or boolean) */
|
|
56
|
-
},
|
|
57
|
-
});`;
|
|
58
|
-
|
|
59
|
-
result.files[fieldFilePath] = {
|
|
60
|
-
__filetype: 'scalarResolver',
|
|
61
|
-
filesystem: {
|
|
62
|
-
type: 'virtual',
|
|
63
|
-
contentUpdated: false,
|
|
64
|
-
},
|
|
65
|
-
content: `
|
|
66
|
-
${resolverTypeImportDeclaration}
|
|
67
|
-
${variableStatement}`,
|
|
68
|
-
mainImportIdentifier: resolverName,
|
|
69
|
-
meta: {
|
|
70
|
-
moduleName,
|
|
71
|
-
relativePathFromBaseToModule,
|
|
72
|
-
normalizedResolverName,
|
|
73
|
-
resolverTypeImportDeclaration,
|
|
74
|
-
variableStatement,
|
|
75
|
-
resolverType: {
|
|
76
|
-
baseImport: graphQLScalarType,
|
|
77
|
-
final: graphQLScalarType,
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
};
|
|
@@ -1,68 +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 handleGraphQLUnionType: 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.union,
|
|
26
|
-
value: normalizedResolverName.withModule,
|
|
27
|
-
}) &&
|
|
28
|
-
!isFileAlreadyOnFilesystem
|
|
29
|
-
) {
|
|
30
|
-
logger.debug(
|
|
31
|
-
`Skipped Union resolver generation: "${normalizedResolverName.withModule}". Pattern: "${resolverGeneration.union}".`
|
|
32
|
-
);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const resolverTypeImportDeclaration = printImportLine({
|
|
37
|
-
isTypeImport: true,
|
|
38
|
-
module: resolversTypeMeta.module,
|
|
39
|
-
moduleType: resolversTypeMeta.moduleType,
|
|
40
|
-
namedImports: [resolversTypeMeta.typeNamedImport],
|
|
41
|
-
emitLegacyCommonJSImports,
|
|
42
|
-
importExtension,
|
|
43
|
-
});
|
|
44
|
-
const variableStatement = `export const ${resolverName}: ${resolversTypeMeta.typeString} = { /* Implement ${resolverName} union logic here */ };`;
|
|
45
|
-
|
|
46
|
-
result.files[fieldFilePath] = {
|
|
47
|
-
__filetype: 'unionResolver',
|
|
48
|
-
filesystem: {
|
|
49
|
-
type: 'virtual',
|
|
50
|
-
contentUpdated: false,
|
|
51
|
-
},
|
|
52
|
-
content: `
|
|
53
|
-
${resolverTypeImportDeclaration}
|
|
54
|
-
${variableStatement}`,
|
|
55
|
-
mainImportIdentifier: resolverName,
|
|
56
|
-
meta: {
|
|
57
|
-
moduleName,
|
|
58
|
-
relativePathFromBaseToModule,
|
|
59
|
-
normalizedResolverName,
|
|
60
|
-
resolverType: {
|
|
61
|
-
baseImport: resolversTypeMeta.typeNamedImport,
|
|
62
|
-
final: resolversTypeMeta.typeString,
|
|
63
|
-
},
|
|
64
|
-
resolverTypeImportDeclaration,
|
|
65
|
-
variableStatement,
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
};
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import type { SourceFile } from 'ts-morph';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { cwd } from '../utils/index.js';
|
|
4
|
-
import type { ResolverFile, GenerateResolverFilesContext } from './types.js';
|
|
5
|
-
import { getVariableStatementWithExpectedIdentifier } from './getVariableStatementWithExpectedIdentifier.js';
|
|
6
|
-
import {
|
|
7
|
-
type AddedPropertyAssignmentNodes,
|
|
8
|
-
addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented,
|
|
9
|
-
} from './addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented.js';
|
|
10
|
-
import { ensureEnumTypeResolversAreGenerated } from './ensureEnumTypeResolversAreGenerated.js';
|
|
11
|
-
import { getImportStatementWithExpectedNamedImport } from './getImportStatementWithExpectedNamedImport.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* postProcessFiles does static analysis on existing files OR to-be-generated files
|
|
15
|
-
* e.g.
|
|
16
|
-
* - Make sure correct variables are exported
|
|
17
|
-
* - Make sure object types have field resolvers if mapper type's field cannot be used as schema type's field
|
|
18
|
-
*/
|
|
19
|
-
export const postProcessFiles = ({
|
|
20
|
-
config: {
|
|
21
|
-
tsMorph: { project },
|
|
22
|
-
fixObjectTypeResolvers,
|
|
23
|
-
},
|
|
24
|
-
result,
|
|
25
|
-
}: GenerateResolverFilesContext): void => {
|
|
26
|
-
const sourceFilesToProcess: {
|
|
27
|
-
sourceFile: SourceFile;
|
|
28
|
-
resolverFile: ResolverFile;
|
|
29
|
-
}[] = [];
|
|
30
|
-
|
|
31
|
-
// 1. Load resolver files into ts-morph project so we can run static analysis
|
|
32
|
-
Object.entries(result.files).forEach(([filePath, file]) => {
|
|
33
|
-
if (file.__filetype === 'file') {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const existingSourceFile = project.addSourceFileAtPathIfExists(filePath);
|
|
38
|
-
if (existingSourceFile) {
|
|
39
|
-
file.filesystem = {
|
|
40
|
-
type: 'filesystem',
|
|
41
|
-
contentUpdated: false,
|
|
42
|
-
};
|
|
43
|
-
sourceFilesToProcess.push({
|
|
44
|
-
sourceFile: existingSourceFile,
|
|
45
|
-
resolverFile: file,
|
|
46
|
-
});
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// If cannot find existing source files, load files that need post-processing into sourceFilesToProcess
|
|
51
|
-
if (file.__filetype === 'objectType') {
|
|
52
|
-
const virtualSourceFile = project.createSourceFile(
|
|
53
|
-
filePath,
|
|
54
|
-
file.content
|
|
55
|
-
);
|
|
56
|
-
sourceFilesToProcess.push({
|
|
57
|
-
sourceFile: virtualSourceFile,
|
|
58
|
-
resolverFile: file,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// `addedPropertyAssignmentNodes` is used to store added property assignments in object types
|
|
64
|
-
// these property assigments are to be removed if there's no TypeScript error
|
|
65
|
-
const addedPropertyAssignmentNodes: AddedPropertyAssignmentNodes = {};
|
|
66
|
-
|
|
67
|
-
sourceFilesToProcess.forEach(({ sourceFile, resolverFile }) => {
|
|
68
|
-
const normalizedRelativePath = path.posix.relative(
|
|
69
|
-
cwd(),
|
|
70
|
-
sourceFile.getFilePath()
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const { addedVariableStatement } = ensureExportedResolver(
|
|
74
|
-
sourceFile,
|
|
75
|
-
resolverFile
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
resolverFile.__filetype !== 'scalarResolver' ||
|
|
80
|
-
// For scalarResolver, only add `import { GraphQLScalarType } ...` if variable statement was added.
|
|
81
|
-
// This is because user could have used custom scalar. If so, we don't want to add unnecessary import
|
|
82
|
-
(resolverFile.__filetype === 'scalarResolver' && addedVariableStatement)
|
|
83
|
-
) {
|
|
84
|
-
ensureImportedType(sourceFile, resolverFile);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
(fixObjectTypeResolvers.object === 'smart' ||
|
|
89
|
-
fixObjectTypeResolvers.object === 'fast') &&
|
|
90
|
-
resolverFile.__filetype === 'objectType'
|
|
91
|
-
) {
|
|
92
|
-
addObjectTypeResolversPropertyAssignmentNodesIfNotImplemented({
|
|
93
|
-
addedPropertyAssignmentNodes,
|
|
94
|
-
sourceFile,
|
|
95
|
-
resolverFile,
|
|
96
|
-
mode: fixObjectTypeResolvers.object,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
(fixObjectTypeResolvers.enum === 'smart' ||
|
|
102
|
-
fixObjectTypeResolvers.enum === 'fast') &&
|
|
103
|
-
resolverFile.__filetype === 'enumResolver'
|
|
104
|
-
) {
|
|
105
|
-
ensureEnumTypeResolversAreGenerated(sourceFile, resolverFile);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Overwrite existing files with fixes
|
|
109
|
-
result.files[normalizedRelativePath] = {
|
|
110
|
-
...resolverFile,
|
|
111
|
-
content: sourceFile.getText(),
|
|
112
|
-
};
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// 3. ensure object type's added property assignments are removed if there's no related TypeScript error
|
|
116
|
-
// We do this only once at the project level instead of sourceFile level to speed up the process
|
|
117
|
-
if (fixObjectTypeResolvers.object === 'smart') {
|
|
118
|
-
project.getPreEmitDiagnostics().forEach((d) => {
|
|
119
|
-
const filename = d.getSourceFile()?.getFilePath().toString();
|
|
120
|
-
if (!filename || !addedPropertyAssignmentNodes[filename]) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const lineNumberWithError = d.getLineNumber();
|
|
124
|
-
|
|
125
|
-
// If erroring on a recently added line, do not remove as user needs to implement it
|
|
126
|
-
if (
|
|
127
|
-
lineNumberWithError &&
|
|
128
|
-
addedPropertyAssignmentNodes[filename][lineNumberWithError]
|
|
129
|
-
) {
|
|
130
|
-
addedPropertyAssignmentNodes[filename][
|
|
131
|
-
lineNumberWithError
|
|
132
|
-
].__toBeRemoved = false;
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
Object.values(addedPropertyAssignmentNodes).forEach((addedNodes) => {
|
|
136
|
-
Object.values(addedNodes).forEach(
|
|
137
|
-
({ node, resolverFile, __toBeRemoved }) => {
|
|
138
|
-
if (__toBeRemoved) {
|
|
139
|
-
node.remove();
|
|
140
|
-
} else {
|
|
141
|
-
// If found a property assignment that cannot be removed i.e. incompatible types between mapper vs schema types
|
|
142
|
-
// Then we must mark the content as updated to be added to generate list
|
|
143
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// 4. Apply to result files the updated content done in step 2. and 3. above
|
|
151
|
-
sourceFilesToProcess.forEach(({ sourceFile, resolverFile }) => {
|
|
152
|
-
const normalizedRelativePath = path.posix.relative(
|
|
153
|
-
cwd(),
|
|
154
|
-
sourceFile.getFilePath()
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
// Overwrite existing files with fixes
|
|
158
|
-
result.files[normalizedRelativePath] = {
|
|
159
|
-
...resolverFile,
|
|
160
|
-
content: sourceFile.getText(),
|
|
161
|
-
};
|
|
162
|
-
});
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Ensure correctly named resolvers are exported
|
|
167
|
-
*/
|
|
168
|
-
const ensureExportedResolver = (
|
|
169
|
-
sourceFile: SourceFile,
|
|
170
|
-
resolverFile: ResolverFile
|
|
171
|
-
): { addedVariableStatement: boolean } => {
|
|
172
|
-
const { variableStatement, isExported } =
|
|
173
|
-
getVariableStatementWithExpectedIdentifier(sourceFile, resolverFile);
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* If we found the variable statement replace its type with the expected resolver type string
|
|
177
|
-
*
|
|
178
|
-
* This is because we change the type of the resolver in some cases:
|
|
179
|
-
* 1. When `extend type <Object>` is used, we might change its original type to the picked version
|
|
180
|
-
* e.g. `Book` might become `Pick<Book, 'title' | 'author'>`
|
|
181
|
-
*/
|
|
182
|
-
let ensureCorrectResolverType: (() => void) | undefined = undefined;
|
|
183
|
-
if (variableStatement && resolverFile.meta.resolverType?.final) {
|
|
184
|
-
const variableDeclaration = variableStatement
|
|
185
|
-
.getDeclarationList()
|
|
186
|
-
.getDeclarations()[0];
|
|
187
|
-
const typeNode = variableDeclaration?.getTypeNode();
|
|
188
|
-
|
|
189
|
-
ensureCorrectResolverType = typeNode
|
|
190
|
-
? () => {
|
|
191
|
-
const trimTypeString = (value: string): string =>
|
|
192
|
-
value.replace(/[\n\r\s]/g, '');
|
|
193
|
-
|
|
194
|
-
const trimmedOriginalTypeString = trimTypeString(typeNode.getText());
|
|
195
|
-
typeNode.replaceWithText(resolverFile.meta.resolverType.final);
|
|
196
|
-
|
|
197
|
-
// If the formatted type is the semantically the same but formatted differently from `resolverType.final`
|
|
198
|
-
// e.g.
|
|
199
|
-
// ```
|
|
200
|
-
// Pick<
|
|
201
|
-
// BookResolvers,
|
|
202
|
-
// | 'title'
|
|
203
|
-
// | 'author'
|
|
204
|
-
// >`
|
|
205
|
-
// vs
|
|
206
|
-
// `Pick<Book, 'author' | 'title'>`
|
|
207
|
-
// ```
|
|
208
|
-
const newTypeStringVariants =
|
|
209
|
-
'otherVariants' in resolverFile.meta.resolverType
|
|
210
|
-
? [
|
|
211
|
-
resolverFile.meta.resolverType.final,
|
|
212
|
-
...resolverFile.meta.resolverType.otherVariants,
|
|
213
|
-
]
|
|
214
|
-
: [resolverFile.meta.resolverType.final];
|
|
215
|
-
const trimmedNewTypeStringVariants =
|
|
216
|
-
newTypeStringVariants.map(trimTypeString);
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
!trimmedNewTypeStringVariants.find(
|
|
220
|
-
(newText) => newText === trimmedOriginalTypeString
|
|
221
|
-
)
|
|
222
|
-
) {
|
|
223
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
: () => {
|
|
227
|
-
variableDeclaration.setType(resolverFile.meta.resolverType.final);
|
|
228
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// For non-scalarResolver, ensure correct type is imported
|
|
233
|
-
// For scalarResolver, we don't need to add type to the variable statement for a few reasons:
|
|
234
|
-
// - For cases when we need to create a new GraphQLScalarType, it infer the type from `new GraphQLScalarType`
|
|
235
|
-
// - For cases when there's custom user logic, it's up to the user to import the correct type or call `new GraphQLScalarType` by themselves
|
|
236
|
-
if (
|
|
237
|
-
resolverFile.__filetype !== 'scalarResolver' &&
|
|
238
|
-
ensureCorrectResolverType
|
|
239
|
-
) {
|
|
240
|
-
ensureCorrectResolverType();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (!variableStatement) {
|
|
244
|
-
// Did not find variable statement with expected identifier, add it to the end with a warning
|
|
245
|
-
sourceFile.addStatements(resolverFile.meta.variableStatement);
|
|
246
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
247
|
-
|
|
248
|
-
return { addedVariableStatement: true };
|
|
249
|
-
} else if (variableStatement && !isExported) {
|
|
250
|
-
// If has identifier but not exported
|
|
251
|
-
// Add export keyword to statement
|
|
252
|
-
const isExpectedIdentifierExported = Boolean(
|
|
253
|
-
sourceFile
|
|
254
|
-
.getExportedDeclarations()
|
|
255
|
-
.get(resolverFile.mainImportIdentifier)
|
|
256
|
-
);
|
|
257
|
-
if (!isExpectedIdentifierExported) {
|
|
258
|
-
variableStatement.setIsExported(true);
|
|
259
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
260
|
-
}
|
|
261
|
-
// else, if identifier's been exported do nothing
|
|
262
|
-
return { addedVariableStatement: false };
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return { addedVariableStatement: false };
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Ensure correctly imported resolves type generated by typescript-resolvers plugin
|
|
270
|
-
*/
|
|
271
|
-
const ensureImportedType = (
|
|
272
|
-
sourceFile: SourceFile,
|
|
273
|
-
resolverFile: ResolverFile
|
|
274
|
-
): void => {
|
|
275
|
-
const { importDeclaration } = getImportStatementWithExpectedNamedImport(
|
|
276
|
-
sourceFile,
|
|
277
|
-
resolverFile
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
if (!importDeclaration) {
|
|
281
|
-
sourceFile.insertStatements(
|
|
282
|
-
0,
|
|
283
|
-
resolverFile.meta.resolverTypeImportDeclaration
|
|
284
|
-
);
|
|
285
|
-
resolverFile.filesystem.contentUpdated = true;
|
|
286
|
-
}
|
|
287
|
-
};
|