@trackunit/react-graphql-tools 1.14.45 → 1.14.47
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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 1.14.47 (2026-06-30)
|
|
2
|
+
|
|
3
|
+
### 🧱 Updated Dependencies
|
|
4
|
+
|
|
5
|
+
- Updated react-vite-test-setup to 0.0.47
|
|
6
|
+
|
|
7
|
+
## 1.14.46 (2026-06-29)
|
|
8
|
+
|
|
9
|
+
This was a version bump only for react-graphql-tools to align it with other projects, there were no code changes.
|
|
10
|
+
|
|
1
11
|
## 1.14.45 (2026-06-29)
|
|
2
12
|
|
|
3
13
|
### 🧱 Updated Dependencies
|
package/package.json
CHANGED
|
@@ -6,14 +6,15 @@ const tslib_1 = require("tslib");
|
|
|
6
6
|
const fs_1 = require("fs");
|
|
7
7
|
const path_1 = require("path");
|
|
8
8
|
const prettier = tslib_1.__importStar(require("prettier"));
|
|
9
|
+
const ts_morph_1 = require("ts-morph");
|
|
9
10
|
const scrubMockFile_1 = require("./scrubMockFile");
|
|
10
11
|
const utils_1 = require("./utils");
|
|
11
12
|
/**
|
|
12
13
|
* Generates React hooks from your graphql files.
|
|
13
14
|
*/
|
|
14
|
-
const scrubFileContent = async (fileContent, nxRoot, isVerbose) => {
|
|
15
|
+
const scrubFileContent = async (fileContent, nxRoot, isVerbose, providedSourceFile) => {
|
|
15
16
|
const start = new Date().getTime();
|
|
16
|
-
const sourceFile = (0, utils_1.createSourceFile)(fileContent);
|
|
17
|
+
const sourceFile = providedSourceFile ?? (0, utils_1.createSourceFile)(fileContent);
|
|
17
18
|
let resultFileContent = "";
|
|
18
19
|
const scalarsType = sourceFile.getTypeAliasOrThrow("Scalars");
|
|
19
20
|
scalarsType.getEndLineNumber();
|
|
@@ -29,14 +30,14 @@ const scrubFileContent = async (fileContent, nxRoot, isVerbose) => {
|
|
|
29
30
|
}
|
|
30
31
|
sourceFile.getEnums().forEach(enumType => {
|
|
31
32
|
const typeName = enumType.getName();
|
|
32
|
-
if (preservedTypes.
|
|
33
|
+
if (preservedTypes.has(typeName) && !alreadyAdded.includes(typeName) && !(0, utils_1.isFragment)(typeName)) {
|
|
33
34
|
alreadyAdded.push(typeName);
|
|
34
35
|
resultFileContent += "\n" + (0, utils_1.convertEnumToConstObject)(enumType) + "\n";
|
|
35
36
|
}
|
|
36
37
|
});
|
|
37
38
|
sourceFile.getTypeAliases().forEach(typeAlias => {
|
|
38
39
|
const typeName = typeAlias.getName();
|
|
39
|
-
if (preservedTypes.
|
|
40
|
+
if (preservedTypes.has(typeName) && !alreadyAdded.includes(typeName) && !(0, utils_1.isFragment)(typeName)) {
|
|
40
41
|
alreadyAdded.push(typeName);
|
|
41
42
|
resultFileContent += "\n" + typeAlias.getText() + "\n";
|
|
42
43
|
}
|
|
@@ -61,8 +62,20 @@ const scrubFile = async (file, nxRoot, isVerbose) => {
|
|
|
61
62
|
if (fileContent.length === 0) {
|
|
62
63
|
console.warn(`File ${file} is empty`);
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// Parse the (large) generated file into ts-morph once and share it between the main and mock scrub
|
|
66
|
+
// instead of parsing it twice. Use the mock's stricter compiler options (the main scrub doesn't use
|
|
67
|
+
// the TypeChecker, so they don't affect its output).
|
|
68
|
+
const sharedSourceFile = new ts_morph_1.Project({
|
|
69
|
+
compilerOptions: {
|
|
70
|
+
noUnusedLocals: true,
|
|
71
|
+
noUnusedParameters: true,
|
|
72
|
+
strictNullChecks: true,
|
|
73
|
+
},
|
|
74
|
+
}).createSourceFile("tmp.ts", fileContent);
|
|
75
|
+
// The main scrub reads line numbers from the pristine AST, so it must run before the mock scrub
|
|
76
|
+
// mutates the shared source file via insertStatements().
|
|
77
|
+
const scrubbedFileContent = await (0, exports.scrubFileContent)(fileContent, nxRoot, isVerbose, sharedSourceFile);
|
|
78
|
+
const scrubbedMockFileContent = await (0, scrubMockFile_1.scrubMockFileContent)(fileContent, nxRoot, isVerbose, sharedSourceFile);
|
|
66
79
|
let options = null;
|
|
67
80
|
try {
|
|
68
81
|
options = prettier
|
|
@@ -281,16 +281,16 @@ const generateMockFromType = (type, text) => {
|
|
|
281
281
|
/**
|
|
282
282
|
* Generates React hooks from your graphql files.
|
|
283
283
|
*/
|
|
284
|
-
const scrubMockFileContent = async (fileContent, nxRoot, isVerbose) => {
|
|
284
|
+
const scrubMockFileContent = async (fileContent, nxRoot, isVerbose, providedSourceFile) => {
|
|
285
285
|
const start = new Date().getTime();
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
286
|
+
const generatedFile = providedSourceFile ??
|
|
287
|
+
new ts_morph_1.Project({
|
|
288
|
+
compilerOptions: {
|
|
289
|
+
noUnusedLocals: true,
|
|
290
|
+
noUnusedParameters: true,
|
|
291
|
+
strictNullChecks: true,
|
|
292
|
+
},
|
|
293
|
+
}).createSourceFile("tmpMock.ts", fileContent);
|
|
294
294
|
const mockThese = [];
|
|
295
295
|
generatedFile.insertStatements(0, "/* eslint-disable @typescript-eslint/no-explicit-any */");
|
|
296
296
|
generatedFile.insertStatements(1, "/* eslint-disable @typescript-eslint/array-type */");
|
|
@@ -70,26 +70,33 @@ const getFullPathUpOfNode = (node) => {
|
|
|
70
70
|
const getPreservedTypes = (sourceFile, isVerbose) => {
|
|
71
71
|
const typeAliases = sourceFile.getTypeAliases();
|
|
72
72
|
const queryAndMutations = [];
|
|
73
|
-
const preservedTypes =
|
|
73
|
+
const preservedTypes = new Set();
|
|
74
74
|
const variablesListToProcess = [];
|
|
75
75
|
const queryMutationListToProcess = [];
|
|
76
76
|
typeAliases.forEach(typeAlias => {
|
|
77
77
|
const name = typeAlias.getName();
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
let typeLiteralText = null;
|
|
81
|
-
if (typeLiteral) {
|
|
82
|
-
// Find the __typename property
|
|
83
|
-
const typenameProperty = typeLiteral.getProperties().find(prop => prop.getName() === "__typename");
|
|
84
|
-
if (typenameProperty) {
|
|
85
|
-
typeLiteralText = typenameProperty.getType().getText().replaceAll('"', "");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
78
|
+
// Name-based classification needs no type info, so handle it first and skip resolving the
|
|
79
|
+
// `__typename` literal for the (many) *Variables / *Fragment aliases.
|
|
88
80
|
if (isQueryVariables(name) || isMutationVariables(name) || isSubscriptionVariables(name) || (0, exports.isFragment)(name)) {
|
|
89
81
|
variablesListToProcess.push(typeAlias);
|
|
90
82
|
queryAndMutations.push(typeAlias);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Get the type literal node that contains the properties
|
|
86
|
+
const typeLiteral = typeAlias.getTypeNode()?.asKind(ts_morph_1.SyntaxKind.TypeLiteral);
|
|
87
|
+
if (!typeLiteral) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// Find the __typename property
|
|
91
|
+
const typenameProperty = typeLiteral.getProperties().find(prop => prop.getName() === "__typename");
|
|
92
|
+
if (!typenameProperty) {
|
|
93
|
+
return;
|
|
91
94
|
}
|
|
92
|
-
|
|
95
|
+
// Read the literal straight from the AST type node (`__typename?: 'Query'`) instead of asking the
|
|
96
|
+
// TypeChecker via `getType()`, which is dramatically faster on large generated files. The AST text
|
|
97
|
+
// keeps the source quote style (codegen emits single quotes), so strip both quote characters.
|
|
98
|
+
const typeLiteralText = (typenameProperty.getTypeNode()?.getText() ?? typenameProperty.getType().getText()).replace(/['"]/g, "");
|
|
99
|
+
if (isQuery({ typeLiteralText, name }) ||
|
|
93
100
|
isMutation({ typeLiteralText, name }) ||
|
|
94
101
|
isSubscription({ typeLiteralText, name })) {
|
|
95
102
|
queryMutationListToProcess.push(typeAlias);
|
|
@@ -117,29 +124,32 @@ const getPreservedTypes = (sourceFile, isVerbose) => {
|
|
|
117
124
|
};
|
|
118
125
|
exports.getPreservedTypes = getPreservedTypes;
|
|
119
126
|
const preserveTypes = (node, preservedTypes, sourceFile, isVerbose) => {
|
|
120
|
-
const typeReferences = [];
|
|
121
127
|
node.forEachDescendant(descendant => {
|
|
122
|
-
if (descendant.getKind()
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
128
|
+
if (descendant.getKind() !== ts_morph_1.SyntaxKind.TypeReference) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// `getText()` serialises the node's subtree, so compute it once instead of up to nine times.
|
|
132
|
+
const text = descendant.getText();
|
|
133
|
+
if (text.startsWith("Scalars") ||
|
|
134
|
+
text.startsWith("Maybe<") ||
|
|
135
|
+
text.startsWith("InputMaybe<") ||
|
|
136
|
+
text.startsWith("Array<") ||
|
|
137
|
+
text.startsWith("Exact<") ||
|
|
138
|
+
text.includes("__typename")) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (isVerbose) {
|
|
142
|
+
// eslint-disable-next-line no-console
|
|
143
|
+
console.log("ADDING", getFullPathUpOfNode(descendant), ":", text, descendant.getKindName());
|
|
144
|
+
}
|
|
145
|
+
if (!preservedTypes.has(text)) {
|
|
146
|
+
const foundTypeAlias = sourceFile.getTypeAlias(text);
|
|
147
|
+
preservedTypes.add(text);
|
|
148
|
+
if (foundTypeAlias) {
|
|
149
|
+
preserveTypes(foundTypeAlias, preservedTypes, sourceFile, isVerbose);
|
|
139
150
|
}
|
|
140
151
|
}
|
|
141
152
|
});
|
|
142
|
-
return typeReferences;
|
|
143
153
|
};
|
|
144
154
|
/**
|
|
145
155
|
* Convert an enum to a const object and string literal type
|