@smartive/graphql-magic 23.4.0-next.9 → 23.5.0-next.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.
- package/CHANGELOG.md +17 -3
- package/dist/bin/gqm.cjs +66 -0
- package/package.json +3 -3
- package/src/bin/gqm/static-eval.ts +102 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
## [23.
|
|
1
|
+
## [23.5.0-next.1](https://github.com/smartive/graphql-magic/compare/v23.4.1...v23.5.0-next.1) (2026-02-09)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* functions.sql and expression fiedls ([65d7079](https://github.com/smartive/graphql-magic/commit/65d7079b54da3a11300cb714a7ca70032e591204))
|
|
6
|
+
* Use functions.ts instead of functions.sql ([58e0653](https://github.com/smartive/graphql-magic/commit/58e065347b2f3f1c80691911b5191af38586c1e2))
|
|
2
7
|
|
|
3
8
|
### Bug Fixes
|
|
4
9
|
|
|
5
|
-
*
|
|
6
|
-
*
|
|
10
|
+
* Functions code order ([cf7f7a4](https://github.com/smartive/graphql-magic/commit/cf7f7a4421e8297af866c3ecc04b5e672862e6ab))
|
|
11
|
+
* Generated expression handling ([e325eb2](https://github.com/smartive/graphql-magic/commit/e325eb232b7bbbbe7d65f9fae5221f4a764a8600))
|
|
12
|
+
* improve handling of missing revision fields in migration updates ([4296662](https://github.com/smartive/graphql-magic/commit/429666247224ef782280fd6144cb749468b934cd))
|
|
13
|
+
* Index ([42d109f](https://github.com/smartive/graphql-magic/commit/42d109fc6dbbf8fc7937f076403a69885779d8f6))
|
|
14
|
+
* Linting ([2e997e4](https://github.com/smartive/graphql-magic/commit/2e997e464371a9d8cf05ceb67a6cd29a9452f615))
|
|
15
|
+
* Omit more stuff ([df2ae04](https://github.com/smartive/graphql-magic/commit/df2ae044557166e876b7646d6ebe67a78df2722e))
|
|
16
|
+
* Permissions ([c198115](https://github.com/smartive/graphql-magic/commit/c19811552ac3de05d4c1069116620067ec0a5540))
|
|
17
|
+
* Temporarily disable tags ([52962c1](https://github.com/smartive/graphql-magic/commit/52962c1a792c1ae010ae542c23d50dd4f8486dde))
|
|
18
|
+
* Trigger release ([2cd67b9](https://github.com/smartive/graphql-magic/commit/2cd67b91d33d101793c04eb87ad9c226bc0fdd0f))
|
|
19
|
+
* Trigger release ([d5ac376](https://github.com/smartive/graphql-magic/commit/d5ac376533460921a638c71f4c9a69c83a057897))
|
|
20
|
+
* Update functions ([3717f8a](https://github.com/smartive/graphql-magic/commit/3717f8aba9d908fbde8d2f49e7c21f87fe6a8d12))
|
package/dist/bin/gqm.cjs
CHANGED
|
@@ -2821,6 +2821,72 @@ var VISITOR = {
|
|
|
2821
2821
|
}),
|
|
2822
2822
|
[import_ts_morph2.SyntaxKind.SpreadElement]: (node, context) => staticEval(node.getExpression(), context),
|
|
2823
2823
|
[import_ts_morph2.SyntaxKind.SpreadAssignment]: (node, context) => staticEval(node.getExpression(), context),
|
|
2824
|
+
[import_ts_morph2.SyntaxKind.ImportSpecifier]: (node, context) => {
|
|
2825
|
+
const nameNode = node.getNameNode();
|
|
2826
|
+
const name2 = nameNode.getText();
|
|
2827
|
+
if (name2 in KNOWN_IDENTIFIERS) {
|
|
2828
|
+
return KNOWN_IDENTIFIERS[name2];
|
|
2829
|
+
}
|
|
2830
|
+
if (nameNode instanceof import_ts_morph2.StringLiteral) {
|
|
2831
|
+
throw new Error(`Cannot handle computed import specifier: ${name2}. Only static imports are supported.`);
|
|
2832
|
+
}
|
|
2833
|
+
const definitions = nameNode.getDefinitionNodes();
|
|
2834
|
+
let externalDefinition = definitions.find((d) => d.compilerNode !== node.compilerNode);
|
|
2835
|
+
if (!externalDefinition) {
|
|
2836
|
+
const importDeclaration = node.getImportDeclaration();
|
|
2837
|
+
let sourceFile = importDeclaration.getModuleSpecifierSourceFile();
|
|
2838
|
+
if (!sourceFile) {
|
|
2839
|
+
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
|
|
2840
|
+
const project = node.getProject();
|
|
2841
|
+
if (moduleSpecifier.startsWith("@/")) {
|
|
2842
|
+
const suffix = moduleSpecifier.substring(2);
|
|
2843
|
+
sourceFile = project.getSourceFiles().find((sf) => {
|
|
2844
|
+
const filePath = sf.getFilePath();
|
|
2845
|
+
return filePath.endsWith(`/${suffix}.ts`) || filePath.endsWith(`/${suffix}.tsx`) || filePath.endsWith(`/${suffix}/index.ts`) || filePath.endsWith(`/${suffix}/index.tsx`);
|
|
2846
|
+
});
|
|
2847
|
+
if (!sourceFile) {
|
|
2848
|
+
const candidates = [
|
|
2849
|
+
`src/${suffix}.ts`,
|
|
2850
|
+
`src/${suffix}.tsx`,
|
|
2851
|
+
`src/${suffix}/index.ts`,
|
|
2852
|
+
`src/${suffix}/index.tsx`
|
|
2853
|
+
];
|
|
2854
|
+
for (const candidate of candidates) {
|
|
2855
|
+
try {
|
|
2856
|
+
const added = project.addSourceFileAtPathIfExists(candidate);
|
|
2857
|
+
if (added) {
|
|
2858
|
+
sourceFile = added;
|
|
2859
|
+
break;
|
|
2860
|
+
}
|
|
2861
|
+
} catch {
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
if (sourceFile) {
|
|
2868
|
+
const localName = node.getName();
|
|
2869
|
+
const propertyName = node.compilerNode.propertyName?.getText();
|
|
2870
|
+
const exportedName = propertyName ?? localName;
|
|
2871
|
+
const exportedDeclarations = sourceFile.getExportedDeclarations();
|
|
2872
|
+
const declarations = exportedDeclarations.get(exportedName);
|
|
2873
|
+
const declaration = declarations?.[0];
|
|
2874
|
+
if (declaration) {
|
|
2875
|
+
externalDefinition = declaration;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
if (externalDefinition && externalDefinition.getKind() === import_ts_morph2.SyntaxKind.ImportSpecifier) {
|
|
2880
|
+
return staticEval(externalDefinition, context);
|
|
2881
|
+
}
|
|
2882
|
+
if (!externalDefinition) {
|
|
2883
|
+
const importDeclaration = node.getImportDeclaration();
|
|
2884
|
+
throw new Error(
|
|
2885
|
+
`No definition node found for import specifier '${name2}' imported from '${importDeclaration.getModuleSpecifierValue()}'.`
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
return staticEval(externalDefinition, context);
|
|
2889
|
+
},
|
|
2824
2890
|
[import_ts_morph2.SyntaxKind.Identifier]: (node, context) => {
|
|
2825
2891
|
const identifierName = node.getText();
|
|
2826
2892
|
if (identifierName in KNOWN_IDENTIFIERS) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartive/graphql-magic",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.5.0-next.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"knex": "^3.0.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@smartive/eslint-config": "7.0.
|
|
71
|
+
"@smartive/eslint-config": "7.0.1",
|
|
72
72
|
"@smartive/prettier-config": "3.1.2",
|
|
73
73
|
"@types/jest": "30.0.0",
|
|
74
74
|
"@types/lodash": "4.17.23",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"conventional-changelog-conventionalcommits": "9.1.0",
|
|
78
78
|
"create-ts-index": "1.14.0",
|
|
79
79
|
"del-cli": "7.0.0",
|
|
80
|
-
"esbuild": "0.27.
|
|
80
|
+
"esbuild": "0.27.3",
|
|
81
81
|
"eslint": "9.39.2",
|
|
82
82
|
"jest": "30.2.0",
|
|
83
83
|
"mock-knex": "0.4.13",
|
|
@@ -4,10 +4,12 @@ import {
|
|
|
4
4
|
CaseClause,
|
|
5
5
|
ElementAccessExpression,
|
|
6
6
|
Identifier,
|
|
7
|
+
ImportSpecifier,
|
|
7
8
|
Node,
|
|
8
9
|
ObjectLiteralExpression,
|
|
9
10
|
PrefixUnaryExpression,
|
|
10
11
|
ShorthandPropertyAssignment,
|
|
12
|
+
StringLiteral,
|
|
11
13
|
SyntaxKind,
|
|
12
14
|
TemplateExpression,
|
|
13
15
|
TemplateTail,
|
|
@@ -77,6 +79,106 @@ const VISITOR: Visitor<unknown, Dictionary<unknown>> = {
|
|
|
77
79
|
}),
|
|
78
80
|
[SyntaxKind.SpreadElement]: (node, context) => staticEval(node.getExpression(), context),
|
|
79
81
|
[SyntaxKind.SpreadAssignment]: (node, context) => staticEval(node.getExpression(), context),
|
|
82
|
+
[SyntaxKind.ImportSpecifier]: (node: ImportSpecifier, context) => {
|
|
83
|
+
const nameNode = node.getNameNode();
|
|
84
|
+
const name = nameNode.getText();
|
|
85
|
+
|
|
86
|
+
if (name in KNOWN_IDENTIFIERS) {
|
|
87
|
+
return KNOWN_IDENTIFIERS[name];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (nameNode instanceof StringLiteral) {
|
|
91
|
+
throw new Error(`Cannot handle computed import specifier: ${name}. Only static imports are supported.`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const definitions = nameNode.getDefinitionNodes();
|
|
95
|
+
// Filter out the node itself to prevent infinite recursion
|
|
96
|
+
// We compare compilerNode references to handle distinct ts-morph wrapper instances
|
|
97
|
+
let externalDefinition = definitions.find((d) => d.compilerNode !== node.compilerNode);
|
|
98
|
+
|
|
99
|
+
// Fallback: If definition navigation fails (e.g. path aliases), try resolving module manually
|
|
100
|
+
if (!externalDefinition) {
|
|
101
|
+
const importDeclaration = node.getImportDeclaration();
|
|
102
|
+
let sourceFile = importDeclaration.getModuleSpecifierSourceFile();
|
|
103
|
+
|
|
104
|
+
// If ts-morph failed to find the file (common with aliases without project config), try manual lookup
|
|
105
|
+
if (!sourceFile) {
|
|
106
|
+
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
|
|
107
|
+
const project = node.getProject();
|
|
108
|
+
|
|
109
|
+
if (moduleSpecifier.startsWith('@/')) {
|
|
110
|
+
const suffix = moduleSpecifier.substring(2);
|
|
111
|
+
|
|
112
|
+
// 1. Check if the file is already loaded in the project
|
|
113
|
+
sourceFile = project.getSourceFiles().find((sf) => {
|
|
114
|
+
const filePath = sf.getFilePath();
|
|
115
|
+
// Check for direct match or index file
|
|
116
|
+
return (
|
|
117
|
+
filePath.endsWith(`/${suffix}.ts`) ||
|
|
118
|
+
filePath.endsWith(`/${suffix}.tsx`) ||
|
|
119
|
+
filePath.endsWith(`/${suffix}/index.ts`) ||
|
|
120
|
+
filePath.endsWith(`/${suffix}/index.tsx`)
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// 2. If not loaded, try to find and add it from disk (heuristic: @/ -> src/)
|
|
125
|
+
if (!sourceFile) {
|
|
126
|
+
const candidates = [
|
|
127
|
+
`src/${suffix}.ts`,
|
|
128
|
+
`src/${suffix}.tsx`,
|
|
129
|
+
`src/${suffix}/index.ts`,
|
|
130
|
+
`src/${suffix}/index.tsx`,
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
for (const candidate of candidates) {
|
|
134
|
+
try {
|
|
135
|
+
// addSourceFileAtPathIfExists resolves relative to CWD
|
|
136
|
+
const added = project.addSourceFileAtPathIfExists(candidate);
|
|
137
|
+
if (added) {
|
|
138
|
+
sourceFile = added;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
} catch {
|
|
142
|
+
// Ignore load errors
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (sourceFile) {
|
|
150
|
+
// Use property path if aliased (import { RealName as Alias }), otherwise name
|
|
151
|
+
// The import specifier is { propertyName as name }
|
|
152
|
+
// If propertyName is undefined, then propertyName is name
|
|
153
|
+
// We want the original propertyName to look up exports
|
|
154
|
+
const localName = node.getName();
|
|
155
|
+
const propertyName = node.compilerNode.propertyName?.getText();
|
|
156
|
+
const exportedName = propertyName ?? localName;
|
|
157
|
+
|
|
158
|
+
const exportedDeclarations = sourceFile.getExportedDeclarations();
|
|
159
|
+
const declarations = exportedDeclarations.get(exportedName);
|
|
160
|
+
const declaration = declarations?.[0];
|
|
161
|
+
|
|
162
|
+
if (declaration) {
|
|
163
|
+
externalDefinition = declaration;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Handle re-exports: if the definition is another ImportSpecifier (in a different file), recurse
|
|
169
|
+
if (externalDefinition && externalDefinition.getKind() === SyntaxKind.ImportSpecifier) {
|
|
170
|
+
return staticEval(externalDefinition, context);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!externalDefinition) {
|
|
174
|
+
const importDeclaration = node.getImportDeclaration();
|
|
175
|
+
throw new Error(
|
|
176
|
+
`No definition node found for import specifier '${name}' imported from '${importDeclaration.getModuleSpecifierValue()}'.`,
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return staticEval(externalDefinition, context);
|
|
181
|
+
},
|
|
80
182
|
[SyntaxKind.Identifier]: (node: Identifier, context) => {
|
|
81
183
|
const identifierName = node.getText();
|
|
82
184
|
if (identifierName in KNOWN_IDENTIFIERS) {
|