@smartive/graphql-magic 23.2.0 → 23.4.0-next.4
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/.github/workflows/release.yml +8 -2
- package/CHANGELOG.md +4 -2
- package/dist/bin/gqm.cjs +678 -64
- package/dist/cjs/index.cjs +2767 -2107
- package/dist/esm/migrations/generate-functions.d.ts +2 -0
- package/dist/esm/migrations/generate-functions.js +59 -0
- package/dist/esm/migrations/generate-functions.js.map +1 -0
- package/dist/esm/migrations/generate.d.ts +8 -1
- package/dist/esm/migrations/generate.js +273 -33
- package/dist/esm/migrations/generate.js.map +1 -1
- package/dist/esm/migrations/index.d.ts +2 -0
- package/dist/esm/migrations/index.js +2 -0
- package/dist/esm/migrations/index.js.map +1 -1
- package/dist/esm/migrations/parse-functions.d.ts +8 -0
- package/dist/esm/migrations/parse-functions.js +105 -0
- package/dist/esm/migrations/parse-functions.js.map +1 -0
- package/dist/esm/migrations/update-functions.d.ts +2 -0
- package/dist/esm/migrations/update-functions.js +174 -0
- package/dist/esm/migrations/update-functions.js.map +1 -0
- package/dist/esm/models/model-definitions.d.ts +4 -1
- package/dist/esm/resolvers/filters.js +73 -14
- package/dist/esm/resolvers/filters.js.map +1 -1
- package/dist/esm/resolvers/selects.js +33 -2
- package/dist/esm/resolvers/selects.js.map +1 -1
- package/dist/esm/resolvers/utils.d.ts +1 -0
- package/dist/esm/resolvers/utils.js +22 -0
- package/dist/esm/resolvers/utils.js.map +1 -1
- package/docs/docs/3-fields.md +149 -0
- package/docs/docs/5-migrations.md +9 -1
- package/package.json +5 -1
- package/src/bin/gqm/gqm.ts +40 -5
- package/src/bin/gqm/settings.ts +7 -0
- package/src/bin/gqm/static-eval.ts +48 -1
- package/src/migrations/generate-functions.ts +72 -0
- package/src/migrations/generate.ts +338 -41
- package/src/migrations/index.ts +2 -0
- package/src/migrations/parse-functions.ts +140 -0
- package/src/migrations/update-functions.ts +216 -0
- package/src/models/model-definitions.ts +4 -1
- package/src/resolvers/filters.ts +81 -25
- package/src/resolvers/selects.ts +38 -5
- package/src/resolvers/utils.ts +32 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { camelCase, Dictionary, kebabCase, lowerFirst, snakeCase, startCase, upperFirst } from 'lodash';
|
|
2
2
|
import {
|
|
3
|
+
BindingElement,
|
|
3
4
|
CaseClause,
|
|
4
5
|
ElementAccessExpression,
|
|
5
6
|
Identifier,
|
|
@@ -47,6 +48,7 @@ export const staticEval = (node: Node | undefined, context: Dictionary<unknown>)
|
|
|
47
48
|
|
|
48
49
|
const VISITOR: Visitor<unknown, Dictionary<unknown>> = {
|
|
49
50
|
undefined: () => undefined,
|
|
51
|
+
[SyntaxKind.BindingElement]: (node: BindingElement, context) => context[node.getName()],
|
|
50
52
|
[SyntaxKind.VariableDeclaration]: (node, context) => staticEval(node.getInitializer(), context),
|
|
51
53
|
[SyntaxKind.ArrayLiteralExpression]: (node, context) => {
|
|
52
54
|
const values: unknown[] = [];
|
|
@@ -146,7 +148,52 @@ const VISITOR: Visitor<unknown, Dictionary<unknown>> = {
|
|
|
146
148
|
const parameters: Dictionary<unknown> = {};
|
|
147
149
|
let i = 0;
|
|
148
150
|
for (const parameter of node.getParameters()) {
|
|
149
|
-
|
|
151
|
+
const argument = args[i];
|
|
152
|
+
|
|
153
|
+
if (parameter.isRestParameter()) {
|
|
154
|
+
parameters[parameter.getName()] = args.slice(i);
|
|
155
|
+
} else {
|
|
156
|
+
const nameNode = parameter.getNameNode();
|
|
157
|
+
if (Node.isObjectBindingPattern(nameNode)) {
|
|
158
|
+
const value = (argument ?? {}) as Dictionary<unknown>;
|
|
159
|
+
const usedKeys = new Set<string>();
|
|
160
|
+
|
|
161
|
+
for (const element of nameNode.getElements()) {
|
|
162
|
+
if (element.getDotDotDotToken()) {
|
|
163
|
+
// Handle rest element (...args)
|
|
164
|
+
const restName = element.getName();
|
|
165
|
+
const restValue: Dictionary<unknown> = {};
|
|
166
|
+
for (const key in value) {
|
|
167
|
+
if (!usedKeys.has(key)) {
|
|
168
|
+
restValue[key] = value[key];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
parameters[restName] = restValue;
|
|
172
|
+
} else {
|
|
173
|
+
// Handle property destructuring (prop: alias = defaultValue)
|
|
174
|
+
const propertyNameNode = element.getPropertyNameNode();
|
|
175
|
+
const elementDetails = element.getNameNode();
|
|
176
|
+
|
|
177
|
+
// If "prop: alias", key is "prop". If just "alias", key is "alias".
|
|
178
|
+
const key = propertyNameNode ? propertyNameNode.getText() : elementDetails.getText();
|
|
179
|
+
const variableName = elementDetails.getText();
|
|
180
|
+
|
|
181
|
+
usedKeys.add(key);
|
|
182
|
+
|
|
183
|
+
let propertyValue = value[key];
|
|
184
|
+
|
|
185
|
+
// Handle default values (= defaultValue)
|
|
186
|
+
if (propertyValue === undefined && element.hasInitializer()) {
|
|
187
|
+
propertyValue = staticEval(element.getInitializer(), { ...context, ...parameters });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
parameters[variableName] = propertyValue;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
parameters[parameter.getName()] = argument;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
150
197
|
i++;
|
|
151
198
|
}
|
|
152
199
|
return staticEval(node.getBody(), { ...context, ...parameters });
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Knex } from 'knex';
|
|
2
|
+
|
|
3
|
+
export const generateFunctionsFromDatabase = async (knex: Knex): Promise<string> => {
|
|
4
|
+
const regularFunctions = await knex.raw(`
|
|
5
|
+
SELECT
|
|
6
|
+
pg_get_functiondef(p.oid) as definition
|
|
7
|
+
FROM pg_proc p
|
|
8
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
9
|
+
WHERE n.nspname = 'public'
|
|
10
|
+
AND NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid)
|
|
11
|
+
ORDER BY p.proname, pg_get_function_identity_arguments(p.oid)
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
const aggregateFunctions = await knex.raw(`
|
|
15
|
+
SELECT
|
|
16
|
+
p.proname as name,
|
|
17
|
+
pg_get_function_identity_arguments(p.oid) as arguments,
|
|
18
|
+
a.aggtransfn::regproc::text as trans_func,
|
|
19
|
+
a.aggfinalfn::regproc::text as final_func,
|
|
20
|
+
a.agginitval as init_val,
|
|
21
|
+
pg_catalog.format_type(a.aggtranstype, NULL) as state_type
|
|
22
|
+
FROM pg_proc p
|
|
23
|
+
JOIN pg_aggregate a ON p.oid = a.aggfnoid
|
|
24
|
+
JOIN pg_namespace n ON p.pronamespace = n.oid
|
|
25
|
+
WHERE n.nspname = 'public'
|
|
26
|
+
ORDER BY p.proname, pg_get_function_identity_arguments(p.oid)
|
|
27
|
+
`);
|
|
28
|
+
|
|
29
|
+
const functions: string[] = [];
|
|
30
|
+
|
|
31
|
+
for (const row of regularFunctions.rows || []) {
|
|
32
|
+
if (row.definition) {
|
|
33
|
+
functions.push(row.definition.trim());
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const row of aggregateFunctions.rows || []) {
|
|
38
|
+
const name = row.name || '';
|
|
39
|
+
const argumentsStr = row.arguments || '';
|
|
40
|
+
const transFunc = row.trans_func || '';
|
|
41
|
+
const finalFunc = row.final_func || '';
|
|
42
|
+
const initVal = row.init_val;
|
|
43
|
+
const stateType = row.state_type || '';
|
|
44
|
+
|
|
45
|
+
if (!name || !transFunc || !stateType) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let aggregateDef = `CREATE AGGREGATE ${name}(${argumentsStr}) (\n`;
|
|
50
|
+
aggregateDef += ` SFUNC = ${transFunc},\n`;
|
|
51
|
+
aggregateDef += ` STYPE = ${stateType}`;
|
|
52
|
+
|
|
53
|
+
if (finalFunc) {
|
|
54
|
+
aggregateDef += `,\n FINALFUNC = ${finalFunc}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (initVal !== null && initVal !== undefined) {
|
|
58
|
+
const initValStr = typeof initVal === 'string' ? `'${initVal}'` : String(initVal);
|
|
59
|
+
aggregateDef += `,\n INITCOND = ${initValStr}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
aggregateDef += '\n);';
|
|
63
|
+
|
|
64
|
+
functions.push(aggregateDef);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (functions.length === 0) {
|
|
68
|
+
return '-- PostgreSQL functions\n-- No functions found in database\n';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return functions.join('\n\n') + '\n';
|
|
72
|
+
};
|