nextjs-hasura-auth 0.1.0 → 0.1.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/APOLLO.md +106 -80
- package/GENERATOR.md +4 -5
- package/README.md +75 -14
- package/dist/lib/apollo.d.ts +9 -9
- package/dist/lib/{apollo.js → apollo.jsx} +14 -39
- package/dist/lib/auth.d.ts +16 -0
- package/dist/lib/auth.jsx +159 -0
- package/dist/lib/client.d.ts +82 -0
- package/dist/lib/client.jsx +237 -0
- package/dist/lib/generator.d.ts +2 -7
- package/dist/lib/generator.js +394 -392
- package/dist/lib/hasura-schema.d.ts +1 -0
- package/dist/lib/hasura-schema.js +72 -0
- package/dist/lib/hasura.d.ts +16 -0
- package/dist/lib/hasura.js +102 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +4 -0
- package/dist/package.json +22 -5
- package/dist/public/hasura-schema.json +7995 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +18 -4
package/dist/lib/generator.js
CHANGED
@@ -15,28 +15,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
15
|
};
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
17
17
|
exports.Generator = Generator;
|
18
|
+
// @ts-ignore
|
19
|
+
const hasura_schema_json_1 = __importDefault(require("../public/hasura-schema.json")); // Импортируем результат интроспекции
|
18
20
|
const debug_1 = __importDefault(require("./debug"));
|
19
|
-
|
21
|
+
const core_1 = require("@apollo/client/core");
|
20
22
|
const debug = (0, debug_1.default)('apollo:generator');
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
// Получаем объект __schema из импортированного результата
|
24
|
+
// Добавляем базовую проверку
|
25
|
+
if (!hasura_schema_json_1.default.data || !hasura_schema_json_1.default.data.__schema) {
|
26
|
+
throw new Error('❌ Invalid introspection result format. Expected { data: { __schema: { ... } } }');
|
27
|
+
}
|
28
|
+
const schema = hasura_schema_json_1.default.data.__schema;
|
29
|
+
// --- Вспомогательная функция для разбора типа GraphQL ---
|
30
|
+
// Рекурсивно разбирает тип (обрабатывая NON_NULL и LIST) и возвращает базовое имя и флаги
|
31
|
+
function getTypeInfo(type) {
|
32
|
+
let isList = false;
|
33
|
+
let isNonNull = false;
|
34
|
+
let isNonNullItem = false; // Для проверки [Type!]
|
35
|
+
let currentType = type;
|
36
|
+
if (currentType.kind === 'NON_NULL') {
|
37
|
+
isNonNull = true;
|
38
|
+
currentType = currentType.ofType;
|
39
|
+
}
|
40
|
+
if (currentType.kind === 'LIST') {
|
41
|
+
isList = true;
|
42
|
+
currentType = currentType.ofType;
|
43
|
+
if (currentType.kind === 'NON_NULL') {
|
44
|
+
isNonNullItem = true;
|
45
|
+
currentType = currentType.ofType;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
// Второй NON_NULL возможен для [Type!]!
|
49
|
+
if (currentType.kind === 'NON_NULL') {
|
50
|
+
isNonNullItem = true; // Если внешний LIST был NON_NULL, то и внутренний тоже
|
51
|
+
currentType = currentType.ofType;
|
52
|
+
}
|
53
|
+
return {
|
54
|
+
name: currentType.name || null, // Return null if name is missing
|
55
|
+
kind: currentType.kind,
|
56
|
+
isList,
|
57
|
+
isNonNull,
|
58
|
+
isNonNullItem,
|
59
|
+
};
|
60
|
+
}
|
61
|
+
// --- ---
|
28
62
|
function Generator(schema) {
|
29
|
-
|
30
|
-
if (!schema || !schema.
|
31
|
-
throw new Error('❌ Invalid schema format.
|
63
|
+
var _a, _b;
|
64
|
+
if (!schema || !schema.queryType || !schema.types) {
|
65
|
+
throw new Error('❌ Invalid schema format. Expected standard introspection __schema object.');
|
66
|
+
}
|
67
|
+
const queryRootName = schema.queryType.name;
|
68
|
+
const mutationRootName = (_a = schema.mutationType) === null || _a === void 0 ? void 0 : _a.name; // Может отсутствовать
|
69
|
+
const subscriptionRootName = (_b = schema.subscriptionType) === null || _b === void 0 ? void 0 : _b.name; // Может отсутствовать
|
70
|
+
// Находим детальные описания корневых типов
|
71
|
+
const queryRoot = schema.types.find((t) => t.kind === 'OBJECT' && t.name === queryRootName);
|
72
|
+
const mutationRoot = mutationRootName ? schema.types.find((t) => t.kind === 'OBJECT' && t.name === mutationRootName) : null;
|
73
|
+
const subscriptionRoot = subscriptionRootName ? schema.types.find((t) => t.kind === 'OBJECT' && t.name === subscriptionRootName) : null;
|
74
|
+
if (!queryRoot) {
|
75
|
+
throw new Error('❌ Query root type description not found in schema types.');
|
32
76
|
}
|
33
|
-
/**
|
34
|
-
* Generates a GraphQL query based on the provided options.
|
35
|
-
*
|
36
|
-
* @param opts - Options object for query generation.
|
37
|
-
* @returns The GraphQL query, variables, and current variable counter.
|
38
|
-
*/
|
39
77
|
return function generate(opts) {
|
78
|
+
var _a, _b, _c;
|
40
79
|
let varCounter = opts.varCounter || 1;
|
41
80
|
if (!opts || !opts.operation || !opts.table) {
|
42
81
|
throw new Error('❌ operation and table must be specified in options');
|
@@ -50,213 +89,126 @@ function Generator(schema) {
|
|
50
89
|
if (!validOperations.includes(operation)) {
|
51
90
|
throw new Error(`❌ Invalid operation type: ${operation}. Allowed types: ${validOperations.join(', ')}`);
|
52
91
|
}
|
53
|
-
|
54
|
-
let
|
55
|
-
|
56
|
-
tableName = `${table}_aggregate`;
|
57
|
-
}
|
92
|
+
// --- Определение корневого типа и полей для поиска ---
|
93
|
+
let rootType = null; // Тип будет 'OBJECT' из __schema.types
|
94
|
+
let rootFields = []; // Массив полей из корневого типа
|
58
95
|
if (operation === 'query') {
|
59
|
-
|
96
|
+
rootType = queryRoot;
|
97
|
+
rootFields = queryRoot.fields || [];
|
60
98
|
}
|
61
99
|
else if (operation === 'subscription') {
|
62
|
-
|
100
|
+
if (!subscriptionRoot)
|
101
|
+
throw new Error('❌ Subscription operations not supported by the schema.');
|
102
|
+
rootType = subscriptionRoot;
|
103
|
+
rootFields = subscriptionRoot.fields || [];
|
63
104
|
}
|
64
|
-
else
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
else if (operation === 'update') {
|
70
|
-
// Handle _by_pk update separately later
|
71
|
-
// tableName = `update_${table}`; // Keep original table for now
|
72
|
-
}
|
73
|
-
else if (operation === 'delete') {
|
74
|
-
// Handle _by_pk delete separately later
|
75
|
-
// tableName = `delete_${table}`; // Keep original table for now
|
76
|
-
}
|
77
|
-
}
|
78
|
-
if (!schema[schemaSection]) {
|
79
|
-
throw new Error(`❌ Schema section ${schemaSection} not found. Schema might be outdated or incorrect.`);
|
105
|
+
else { // insert, update, delete
|
106
|
+
if (!mutationRoot)
|
107
|
+
throw new Error('❌ Mutation operations not supported by the schema.');
|
108
|
+
rootType = mutationRoot;
|
109
|
+
rootFields = mutationRoot.fields || [];
|
80
110
|
}
|
81
|
-
//
|
111
|
+
// --- ---
|
112
|
+
// --- Логика определения имени операции (queryName) ---
|
113
|
+
let targetFieldName = table; // Имя поля, которое ищем в корневом типе
|
82
114
|
let isByPkOperation = false;
|
83
|
-
|
84
|
-
|
85
|
-
|
115
|
+
let isAggregate = operation === 'query' && !!aggregate;
|
116
|
+
// Определяем префиксы и суффиксы для мутаций и by_pk запросов
|
117
|
+
const mutationPrefix = operation === 'insert' ? 'insert_' : operation === 'update' ? 'update_' : operation === 'delete' ? 'delete_' : '';
|
118
|
+
const pkSuffix = '_by_pk';
|
119
|
+
const aggregateSuffix = '_aggregate';
|
120
|
+
const oneSuffix = '_one';
|
121
|
+
// Формируем ожидаемые имена полей (улучшенная логика)
|
122
|
+
if (isAggregate) {
|
123
|
+
targetFieldName = `${table}${aggregateSuffix}`;
|
86
124
|
}
|
87
|
-
else if (
|
88
|
-
|
89
|
-
|
125
|
+
else if (opts.pk_columns) {
|
126
|
+
if (operation === 'query') {
|
127
|
+
targetFieldName = `${table}${pkSuffix}`;
|
128
|
+
isByPkOperation = true;
|
129
|
+
}
|
130
|
+
else if (['update', 'delete'].includes(operation)) {
|
131
|
+
targetFieldName = `${mutationPrefix}${table}${pkSuffix}`;
|
132
|
+
isByPkOperation = true;
|
133
|
+
}
|
134
|
+
// pk_columns не влияет на insert
|
90
135
|
}
|
91
136
|
else if (operation === 'insert' && opts.object && !opts.objects) {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
isByPkOperation = true; // Treat insert_one like a by_pk operation for simplicity
|
137
|
+
const oneFieldName = `${mutationPrefix}${table}${oneSuffix}`;
|
138
|
+
if (rootFields.find(f => f.name === oneFieldName)) {
|
139
|
+
targetFieldName = oneFieldName;
|
140
|
+
// Не ставим isByPkOperation в true для insert_one, т.к. аргументы другие
|
97
141
|
}
|
98
142
|
else {
|
99
|
-
|
143
|
+
targetFieldName = `${mutationPrefix}${table}`;
|
100
144
|
}
|
101
145
|
}
|
102
146
|
else if (operation === 'insert') {
|
103
|
-
|
147
|
+
targetFieldName = `${mutationPrefix}${table}`;
|
104
148
|
}
|
105
149
|
else if (operation === 'update') {
|
106
|
-
|
150
|
+
targetFieldName = `${mutationPrefix}${table}`; // Bulk update
|
107
151
|
}
|
108
152
|
else if (operation === 'delete') {
|
109
|
-
|
110
|
-
}
|
111
|
-
// If not by_pk, and it's a query/sub, keep the original table name for non-aggregate
|
112
|
-
else if (['query', 'subscription'].includes(operation) && !aggregate) {
|
113
|
-
tableName = table;
|
114
|
-
}
|
115
|
-
// If it's an aggregate query
|
116
|
-
else if (operation === 'query' && aggregate) {
|
117
|
-
tableName = `${table}_aggregate`;
|
153
|
+
targetFieldName = `${mutationPrefix}${table}`; // Bulk delete
|
118
154
|
}
|
119
|
-
|
120
|
-
|
121
|
-
// Fallback logic if specific query (like insert_table_one) wasn't found directly
|
122
|
-
if (!queryName) {
|
123
|
-
// General fallback: find first matching query
|
124
|
-
queryName = possibleQueries.find(q => q.includes(table)) || possibleQueries[0];
|
125
|
-
if (!queryName) {
|
126
|
-
throw new Error(`❌ Query/Mutation/Subscription for table "${table}" not found in schema section "${schemaSection}"`);
|
127
|
-
}
|
128
|
-
console.log(`[generator] ⚠️ Could not find exact query name "${tableName}", using fallback "${queryName}"`);
|
129
|
-
}
|
130
|
-
const queryInfo = schema[schemaSection][queryName];
|
155
|
+
// Для обычных query/subscription без pk_columns и aggregate, имя таблицы (targetFieldName) остается исходным 'table'
|
156
|
+
const queryInfo = rootFields.find(f => f.name === targetFieldName);
|
131
157
|
if (!queryInfo) {
|
132
|
-
|
158
|
+
// Fallback для случая, когда _by_pk/aggregate/etc не найдены, но базовый запрос есть
|
159
|
+
const fallbackQueryInfo = rootFields.find(f => f.name === table);
|
160
|
+
if (fallbackQueryInfo && ['query', 'subscription'].includes(operation) && !isAggregate && !isByPkOperation) {
|
161
|
+
console.warn(`[generator] ⚠️ Exact field "${targetFieldName}" not found, using fallback "${table}" in ${rootType.name}`);
|
162
|
+
targetFieldName = table; // Используем базовое имя
|
163
|
+
// queryInfo = fallbackQueryInfo; // Переприсваиваем для дальнейшего использования
|
164
|
+
throw new Error(`❌ Field "${targetFieldName}" not found in root type "${rootType.name}"`); // Упадем здесь, если все равно не нашли
|
165
|
+
}
|
166
|
+
else {
|
167
|
+
throw new Error(`❌ Field "${targetFieldName}" not found in root type "${rootType.name}"`);
|
168
|
+
}
|
133
169
|
}
|
170
|
+
const queryName = queryInfo.name; // Имя поля GraphQL, которое будем использовать
|
171
|
+
// --- ---
|
134
172
|
const queryArgs = [];
|
135
173
|
const variables = {};
|
136
174
|
const varParts = [];
|
137
|
-
//
|
138
|
-
const
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
// Check type name conventions first (e.g., from introspection)
|
143
|
-
if (typeof typeName === 'string') {
|
144
|
-
let baseTypeName = typeName;
|
145
|
-
if (baseTypeName.endsWith('!')) {
|
146
|
-
isRequired = true;
|
147
|
-
baseTypeName = baseTypeName.slice(0, -1);
|
148
|
-
}
|
149
|
-
if (baseTypeName.startsWith('[') && baseTypeName.endsWith(']')) {
|
150
|
-
isList = true;
|
151
|
-
baseTypeName = baseTypeName.slice(1, -1);
|
152
|
-
// Check for inner required type e.g., [String!]
|
153
|
-
if (baseTypeName.endsWith('!')) {
|
154
|
-
// Mark inner as required if needed? (Handled later for known types)
|
155
|
-
baseTypeName = baseTypeName.slice(0, -1);
|
156
|
-
}
|
157
|
-
}
|
158
|
-
typeName = baseTypeName;
|
159
|
-
}
|
160
|
-
// Determine list/required based on arg name conventions
|
161
|
-
const baseTable = table; // Use original table name for type conventions
|
162
|
-
let finalType = typeName;
|
163
|
-
let finalIsRequired = isRequired;
|
164
|
-
let finalIsList = isList;
|
165
|
-
let innerRequired = false;
|
166
|
-
// Apply conventions/overrides
|
167
|
-
if (argName === 'objects') {
|
168
|
-
finalType = `${baseTable}_insert_input`;
|
169
|
-
finalIsList = true;
|
170
|
-
finalIsRequired = true;
|
171
|
-
innerRequired = true;
|
172
|
-
}
|
173
|
-
if (argName === 'object') {
|
174
|
-
finalType = `${baseTable}_insert_input`;
|
175
|
-
finalIsList = false;
|
176
|
-
finalIsRequired = true;
|
177
|
-
}
|
178
|
-
if (argName === 'order_by') {
|
179
|
-
finalType = `${baseTable}_order_by`;
|
180
|
-
finalIsList = true;
|
181
|
-
finalIsRequired = false;
|
182
|
-
innerRequired = true;
|
183
|
-
} // List itself not required, but inner usually is
|
184
|
-
if (argName === 'pk_columns') {
|
185
|
-
finalType = `${baseTable}_pk_columns_input`;
|
186
|
-
finalIsList = false;
|
187
|
-
finalIsRequired = true;
|
175
|
+
// --- РЕФАКТОРИНГ getGqlType ---
|
176
|
+
const getGqlTypeFromSchema = (argType) => {
|
177
|
+
const info = getTypeInfo(argType);
|
178
|
+
if (!info.name) {
|
179
|
+
throw new Error(`Cannot determine base type name for argType: ${JSON.stringify(argType)}`);
|
188
180
|
}
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
finalIsRequired = true;
|
181
|
+
let typeStr = info.name; // Now we know info.name is a string
|
182
|
+
if (info.isList) {
|
183
|
+
typeStr = `[${info.name}${info.isNonNullItem ? '!' : ''}]`;
|
193
184
|
}
|
194
|
-
if (
|
195
|
-
|
196
|
-
finalIsList = false;
|
197
|
-
finalIsRequired = false;
|
185
|
+
if (info.isNonNull) {
|
186
|
+
typeStr += '!';
|
198
187
|
}
|
199
|
-
|
200
|
-
if (forceRequired) {
|
201
|
-
finalIsRequired = true;
|
202
|
-
finalIsList = false; // Direct PK args are typically not lists
|
203
|
-
}
|
204
|
-
// Construct the final type string
|
205
|
-
let typeString = finalType;
|
206
|
-
if (finalIsList) {
|
207
|
-
typeString = `[${finalType}${innerRequired ? '!' : ''}]`;
|
208
|
-
}
|
209
|
-
if (finalIsRequired) {
|
210
|
-
typeString += '!';
|
211
|
-
}
|
212
|
-
return typeString;
|
188
|
+
return typeStr;
|
213
189
|
};
|
214
|
-
//
|
215
|
-
|
216
|
-
|
190
|
+
// --- ---
|
191
|
+
// --- РЕФАКТОРИНГ Цикла обработки аргументов (Top Level) ---
|
192
|
+
const processedArgs = new Set();
|
193
|
+
const addArgument = (argName, value, argDefinition) => {
|
194
|
+
if (processedArgs.has(argName))
|
217
195
|
return;
|
218
196
|
const varName = `v${varCounter++}`;
|
219
197
|
queryArgs.push(`${argName}: $${varName}`);
|
220
198
|
variables[varName] = value;
|
221
|
-
const gqlType =
|
222
|
-
|
199
|
+
const gqlType = getGqlTypeFromSchema(argDefinition.type);
|
200
|
+
// Check if var already exists before pushing
|
201
|
+
if (!varParts.some(p => p.startsWith(`$${varName}:`))) {
|
202
|
+
varParts.push(`$${varName}: ${gqlType}`);
|
203
|
+
}
|
204
|
+
processedArgs.add(argName);
|
223
205
|
};
|
224
|
-
//
|
225
|
-
|
226
|
-
|
227
|
-
'where',
|
228
|
-
// PK args (direct or pk_columns object)
|
229
|
-
...(isByPkOperation && opts.pk_columns ? Object.keys(opts.pk_columns) : []), // Direct PK args like 'id'
|
230
|
-
'pk_columns', // The pk_columns input object itself
|
231
|
-
// Mutation specific
|
232
|
-
'_set',
|
233
|
-
'objects',
|
234
|
-
'object',
|
235
|
-
// Pagination/Sorting
|
236
|
-
'limit',
|
237
|
-
'offset',
|
238
|
-
'order_by'
|
239
|
-
];
|
240
|
-
const processedArgs = new Set();
|
241
|
-
// Process args in defined order
|
242
|
-
for (const argName of argProcessingOrder) {
|
243
|
-
if (!queryInfo.args || !queryInfo.args[argName])
|
244
|
-
continue; // Skip if arg not in schema
|
245
|
-
if (processedArgs.has(argName))
|
246
|
-
continue;
|
247
|
-
const argSchema = queryInfo.args[argName];
|
206
|
+
// 1. Обработка прямых аргументов поля (из queryInfo.args)
|
207
|
+
(_a = queryInfo.args) === null || _a === void 0 ? void 0 : _a.forEach((argDef) => {
|
208
|
+
const argName = argDef.name;
|
248
209
|
let value = undefined;
|
249
|
-
let isDirectPk = false;
|
250
|
-
// Map opts to schema args
|
251
210
|
if (argName === 'pk_columns' && opts.pk_columns) {
|
252
|
-
|
253
|
-
if (operation === 'update') {
|
254
|
-
value = opts.pk_columns;
|
255
|
-
}
|
256
|
-
else {
|
257
|
-
// For query_by_pk and delete_by_pk, pk_columns is used to find direct args
|
258
|
-
continue; // Skip processing pk_columns itself here
|
259
|
-
}
|
211
|
+
value = opts.pk_columns;
|
260
212
|
}
|
261
213
|
else if (argName === '_set' && opts._set) {
|
262
214
|
value = opts._set;
|
@@ -265,269 +217,319 @@ function Generator(schema) {
|
|
265
217
|
value = opts.objects || [opts.object];
|
266
218
|
}
|
267
219
|
else if (argName === 'object' && opts.object && !opts.objects) {
|
268
|
-
|
269
|
-
|
270
|
-
else if (isByPkOperation && opts.pk_columns && opts.pk_columns[argName] !== undefined) {
|
271
|
-
// Handle direct PK arg like `id` for `_by_pk` operations
|
272
|
-
// Check if the schema actually expects this direct arg
|
273
|
-
if (queryInfo.args[argName]) {
|
274
|
-
value = opts.pk_columns[argName];
|
275
|
-
isDirectPk = true;
|
220
|
+
if (queryName.endsWith('_one')) {
|
221
|
+
value = opts.object;
|
276
222
|
}
|
277
223
|
else {
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
224
|
+
value = [opts.object];
|
225
|
+
if (!queryInfo.args.find((a) => a.name === 'objects')) {
|
226
|
+
debug(`Passing single 'object' to bulk operation "%s" which might expect 'objects' array.`, queryName);
|
227
|
+
const objectsArgDef = queryInfo.args.find((a) => a.name === 'objects');
|
228
|
+
if (objectsArgDef) {
|
229
|
+
addArgument('objects', value, objectsArgDef);
|
230
|
+
}
|
231
|
+
else {
|
232
|
+
console.error(`[generator] Cannot determine correct argument ('object' or 'objects') for "${queryName}".`);
|
233
|
+
}
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
else if (queryInfo.args.find((a) => a.name === 'object')) {
|
237
|
+
return;
|
238
|
+
}
|
239
|
+
else {
|
240
|
+
const objectsArgDef = queryInfo.args.find((a) => a.name === 'objects');
|
241
|
+
if (objectsArgDef) {
|
242
|
+
addArgument('objects', value, objectsArgDef);
|
243
|
+
}
|
244
|
+
return;
|
245
|
+
}
|
284
246
|
}
|
285
247
|
}
|
248
|
+
else if (isByPkOperation && opts.pk_columns && opts.pk_columns[argName] !== undefined) {
|
249
|
+
value = opts.pk_columns[argName];
|
250
|
+
}
|
286
251
|
else if (opts[argName] !== undefined) {
|
287
252
|
value = opts[argName];
|
288
253
|
}
|
289
254
|
if (value !== undefined) {
|
290
|
-
|
291
|
-
processedArgs.add(argName);
|
292
|
-
}
|
293
|
-
}
|
294
|
-
// Process any remaining args not in the defined order (should be rare)
|
295
|
-
if (queryInfo.args) {
|
296
|
-
for (const argName in queryInfo.args) {
|
297
|
-
if (!processedArgs.has(argName)) {
|
298
|
-
const value = opts[argName];
|
299
|
-
if (value !== undefined) {
|
300
|
-
processArg(argName, value, queryInfo.args[argName], false);
|
301
|
-
processedArgs.add(argName);
|
302
|
-
}
|
303
|
-
}
|
255
|
+
addArgument(argName, value, argDef);
|
304
256
|
}
|
305
|
-
}
|
306
|
-
// --- End Argument Processing ---
|
257
|
+
});
|
258
|
+
// --- End Top Level Argument Processing ---
|
259
|
+
// --- Returning Field Processing (REWORKED) ---
|
307
260
|
const returningFields = [];
|
308
|
-
|
309
|
-
|
261
|
+
const varCounterRef = { count: varCounter }; // Use ref for nested calls
|
262
|
+
// Helper to find type details from schema by name
|
263
|
+
const findTypeDetails = (typeName) => {
|
264
|
+
if (!typeName)
|
265
|
+
return null;
|
266
|
+
return schema.types.find((t) => t.name === typeName && (t.kind === 'OBJECT' || t.kind === 'INTERFACE'));
|
267
|
+
};
|
268
|
+
// Recursive function to process fields
|
269
|
+
function processReturningField(field, parentTypeName, currentVarCounterRef) {
|
270
|
+
var _a, _b;
|
271
|
+
if (typeof field === 'string')
|
310
272
|
return field.trim();
|
311
|
-
}
|
312
273
|
if (typeof field === 'object' && field !== null) {
|
313
274
|
const fieldName = Object.keys(field)[0];
|
314
275
|
const subFieldsOrParams = field[fieldName];
|
315
|
-
|
316
|
-
|
276
|
+
// Find the field definition in the parent type
|
277
|
+
const parentTypeDetails = findTypeDetails(parentTypeName);
|
278
|
+
const fieldInfo = (_a = parentTypeDetails === null || parentTypeDetails === void 0 ? void 0 : parentTypeDetails.fields) === null || _a === void 0 ? void 0 : _a.find((f) => f.name === fieldName);
|
279
|
+
if (!fieldInfo) {
|
280
|
+
// Use debug instead of console.warn
|
281
|
+
debug(`Field "%s" not found in type "%s". Skipping.`, fieldName, parentTypeName);
|
282
|
+
return ''; // Skip if field not found in parent
|
317
283
|
}
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
284
|
+
// Determine the return type of this field
|
285
|
+
let fieldReturnTypeName = null;
|
286
|
+
let currentFieldType = fieldInfo.type;
|
287
|
+
while (currentFieldType.ofType)
|
288
|
+
currentFieldType = currentFieldType.ofType; // Unwrap LIST/NON_NULL
|
289
|
+
fieldReturnTypeName = currentFieldType.name;
|
290
|
+
if (typeof subFieldsOrParams === 'boolean' && subFieldsOrParams)
|
291
|
+
return fieldName;
|
292
|
+
if (typeof subFieldsOrParams === 'boolean' && !subFieldsOrParams)
|
293
|
+
return ''; // Skip false
|
294
|
+
if (Array.isArray(subFieldsOrParams) || typeof subFieldsOrParams === 'string') {
|
295
|
+
// Simple nested fields (array of strings/objects or single string)
|
296
|
+
const nestedFields = Array.isArray(subFieldsOrParams) ? subFieldsOrParams : subFieldsOrParams.split(/\s+/).filter(Boolean);
|
297
|
+
const nestedProcessed = nestedFields
|
298
|
+
.map(sf => processReturningField(sf, fieldReturnTypeName, currentVarCounterRef)) // <<< Pass return type as new parent
|
299
|
+
.filter(Boolean)
|
325
300
|
.join('\n ');
|
326
|
-
return
|
327
|
-
}
|
328
|
-
if (typeof subFieldsOrParams === 'string') {
|
329
|
-
return `${fieldName} {\n ${subFieldsOrParams}\n }`;
|
301
|
+
return nestedProcessed ? `${fieldName} {\n ${nestedProcessed}\n }` : fieldName; // Return just fieldName if no nested fields processed
|
330
302
|
}
|
331
|
-
|
332
|
-
|
333
|
-
const
|
334
|
-
|
335
|
-
const
|
336
|
-
|
303
|
+
if (typeof subFieldsOrParams === 'object') { // Nested query with potential args
|
304
|
+
const { returning: nestedReturning, alias } = subFieldsOrParams, nestedArgsInput = __rest(subFieldsOrParams, ["returning", "alias"]);
|
305
|
+
const fieldAliasOrName = alias || fieldName;
|
306
|
+
// Field definition might include alias
|
307
|
+
const fieldDefinition = alias ? `${alias}: ${fieldName}` : fieldName;
|
308
|
+
// --- Process Nested Arguments --- (IMPLEMENTED)
|
337
309
|
const nestedArgs = [];
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
310
|
+
if (fieldInfo.args && Object.keys(nestedArgsInput).length > 0) {
|
311
|
+
Object.entries(nestedArgsInput).forEach(([argName, argValue]) => {
|
312
|
+
const argDef = fieldInfo.args.find((a) => a.name === argName);
|
313
|
+
if (argDef && argValue !== undefined) {
|
314
|
+
const varName = `v${currentVarCounterRef.count++}`;
|
315
|
+
nestedArgs.push(`${argName}: $${varName}`);
|
316
|
+
variables[varName] = argValue;
|
317
|
+
const gqlType = getGqlTypeFromSchema(argDef.type); // Use existing helper
|
318
|
+
// Check if var already exists before pushing
|
319
|
+
if (!varParts.some(p => p.startsWith(`$${varName}:`))) {
|
320
|
+
varParts.push(`$${varName}: ${gqlType}`);
|
321
|
+
}
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
// Use debug instead of console.warn
|
325
|
+
debug(`Argument "%s" not found or value is undefined for field "%s"`, argName, fieldName);
|
326
|
+
}
|
327
|
+
});
|
328
|
+
}
|
329
|
+
const nestedArgsStr = nestedArgs.length > 0 ? `(${nestedArgs.join(', ')})` : '';
|
330
|
+
// --- End Nested Arguments ---
|
331
|
+
// --- Process Nested Returning Fields --- (Improved Default Logic)
|
332
|
+
let finalNestedReturning = [];
|
333
|
+
if (nestedReturning) {
|
334
|
+
if (Array.isArray(nestedReturning)) {
|
335
|
+
finalNestedReturning = nestedReturning;
|
355
336
|
}
|
356
|
-
|
357
|
-
|
358
|
-
gqlType = gqlType.slice(1, -1);
|
337
|
+
else if (typeof nestedReturning === 'string') {
|
338
|
+
finalNestedReturning = nestedReturning.split(/\s+/).filter(Boolean);
|
359
339
|
}
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
finalType = `[${gqlType}${innerRequired}]`;
|
365
|
-
// Is the list itself required? (Usually not for nested args)
|
366
|
-
isRequired = false;
|
340
|
+
else if (typeof nestedReturning === 'object') {
|
341
|
+
finalNestedReturning = Object.entries(nestedReturning)
|
342
|
+
.filter(([_, v]) => v)
|
343
|
+
.map(([k, v]) => (typeof v === 'boolean' ? k : { [k]: v }));
|
367
344
|
}
|
368
|
-
varParts.push(`$${varName}: ${finalType}${isRequired ? '!' : ''}`);
|
369
|
-
};
|
370
|
-
processNestedArg('where', nestedWhere, '_bool_exp');
|
371
|
-
processNestedArg('limit', nestedLimit, '', 'Int');
|
372
|
-
processNestedArg('offset', nestedOffset, '', 'Int');
|
373
|
-
// Pass forceList=true for order_by
|
374
|
-
processNestedArg('order_by', nestedOrderBy, '_order_by', 'String', true);
|
375
|
-
// Process other arbitrary parameters
|
376
|
-
for (const paramName in otherParams) {
|
377
|
-
processNestedArg(paramName, otherParams[paramName], ''); // Assume String default
|
378
345
|
}
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
if (
|
383
|
-
finalNestedReturning
|
346
|
+
// If no nested returning specified, try to add default 'id' or '__typename'
|
347
|
+
if (finalNestedReturning.length === 0) {
|
348
|
+
const nestedTypeDetails = findTypeDetails(fieldReturnTypeName);
|
349
|
+
if ((_b = nestedTypeDetails === null || nestedTypeDetails === void 0 ? void 0 : nestedTypeDetails.fields) === null || _b === void 0 ? void 0 : _b.find((f) => f.name === 'id')) {
|
350
|
+
finalNestedReturning.push('id');
|
384
351
|
}
|
385
|
-
else if (
|
386
|
-
finalNestedReturning
|
387
|
-
}
|
388
|
-
else if (typeof nestedReturningDef === 'object') {
|
389
|
-
// Convert object { field: true, another: {...} } to array ['field', { another: {...} }]
|
390
|
-
finalNestedReturning = Object.entries(nestedReturningDef)
|
391
|
-
.filter(([_, value]) => value) // Filter out false values
|
392
|
-
.map(([key, value]) => (typeof value === 'boolean' ? key : { [key]: value }));
|
352
|
+
else if ((nestedTypeDetails === null || nestedTypeDetails === void 0 ? void 0 : nestedTypeDetails.kind) === 'OBJECT' || (nestedTypeDetails === null || nestedTypeDetails === void 0 ? void 0 : nestedTypeDetails.kind) === 'INTERFACE') {
|
353
|
+
finalNestedReturning.push('__typename');
|
393
354
|
}
|
355
|
+
// If it's a SCALAR/ENUM, no body needed
|
394
356
|
}
|
395
|
-
const
|
396
|
-
.map(f => processReturningField(f, currentVarCounterRef))
|
397
|
-
.filter(Boolean)
|
357
|
+
const nestedReturningStr = finalNestedReturning
|
358
|
+
.map(f => processReturningField(f, fieldReturnTypeName, currentVarCounterRef)) // <<< Pass return type
|
359
|
+
.filter(Boolean)
|
398
360
|
.join('\n ');
|
399
|
-
//
|
400
|
-
|
401
|
-
|
361
|
+
// --- End Nested Returning Fields ---
|
362
|
+
// Only add body if there are fields to return AND the type is OBJECT/INTERFACE
|
363
|
+
const nestedFieldTypeDetails = findTypeDetails(fieldReturnTypeName);
|
364
|
+
const needsNestedBody = ((nestedFieldTypeDetails === null || nestedFieldTypeDetails === void 0 ? void 0 : nestedFieldTypeDetails.kind) === 'OBJECT' || (nestedFieldTypeDetails === null || nestedFieldTypeDetails === void 0 ? void 0 : nestedFieldTypeDetails.kind) === 'INTERFACE') && nestedReturningStr;
|
365
|
+
const nestedBody = needsNestedBody ? ` {\n ${nestedReturningStr}\n }` : '';
|
366
|
+
return `${fieldDefinition}${nestedArgsStr}${nestedBody}`;
|
402
367
|
}
|
403
|
-
return ''; // Skip invalid field types
|
404
368
|
}
|
405
|
-
return ''; //
|
369
|
+
return ''; // Should not happen for valid input
|
406
370
|
}
|
407
|
-
|
408
|
-
|
409
|
-
let
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
371
|
+
// --- Main Returning Logic (REWORKED) ---
|
372
|
+
let topLevelReturnTypeName = null;
|
373
|
+
let currentQueryType = queryInfo.type;
|
374
|
+
while (currentQueryType.ofType)
|
375
|
+
currentQueryType = currentQueryType.ofType;
|
376
|
+
topLevelReturnTypeName = currentQueryType.name;
|
377
|
+
let finalReturningFields = []; // Initialize final list
|
378
|
+
// Helper to generate base default fields
|
379
|
+
const baseGenerateDefaultFields = (parentTypeName) => {
|
380
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
381
|
+
const defaults = [];
|
415
382
|
if (aggregate) {
|
416
|
-
//
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
if (queryInfo.returning_fields[f])
|
425
|
-
returningFields.push(f);
|
426
|
-
});
|
427
|
-
}
|
428
|
-
else if (isByPkOperation && operation === 'delete') {
|
429
|
-
// Default for delete_by_pk: Try to return PK fields, fallback to id
|
430
|
-
if (opts.pk_columns && queryInfo.returning_fields) {
|
431
|
-
Object.keys(opts.pk_columns).forEach(pkField => {
|
432
|
-
if (queryInfo.returning_fields[pkField]) {
|
433
|
-
returningFields.push(pkField);
|
434
|
-
}
|
435
|
-
});
|
383
|
+
// Simplified default for aggregate
|
384
|
+
const aggregateFieldInfo = rootFields.find(f => f.name === queryName);
|
385
|
+
let aggReturnTypeName = null;
|
386
|
+
if (aggregateFieldInfo) {
|
387
|
+
let currentAggType = aggregateFieldInfo.type;
|
388
|
+
while (currentAggType.ofType)
|
389
|
+
currentAggType = currentAggType.ofType;
|
390
|
+
aggReturnTypeName = currentAggType.name;
|
436
391
|
}
|
437
|
-
|
438
|
-
if (
|
439
|
-
|
392
|
+
const aggTypeDetails = findTypeDetails(aggReturnTypeName);
|
393
|
+
if ((_a = aggTypeDetails === null || aggTypeDetails === void 0 ? void 0 : aggTypeDetails.fields) === null || _a === void 0 ? void 0 : _a.find((f) => f.name === 'aggregate')) {
|
394
|
+
const aggregateNestedField = aggTypeDetails.fields.find((f) => f.name === 'aggregate');
|
395
|
+
let aggregateNestedTypeName = null;
|
396
|
+
if (aggregateNestedField) {
|
397
|
+
let currentNestedType = aggregateNestedField.type;
|
398
|
+
while (currentNestedType.ofType)
|
399
|
+
currentNestedType = currentNestedType.ofType;
|
400
|
+
aggregateNestedTypeName = currentNestedType.name;
|
401
|
+
}
|
402
|
+
const aggregateNestedTypeDetails = findTypeDetails(aggregateNestedTypeName);
|
403
|
+
if ((_b = aggregateNestedTypeDetails === null || aggregateNestedTypeDetails === void 0 ? void 0 : aggregateNestedTypeDetails.fields) === null || _b === void 0 ? void 0 : _b.find((f) => f.name === 'count')) {
|
404
|
+
defaults.push('aggregate { count }');
|
405
|
+
}
|
406
|
+
else {
|
407
|
+
defaults.push('aggregate { __typename }');
|
408
|
+
}
|
409
|
+
}
|
410
|
+
else {
|
411
|
+
defaults.push('__typename');
|
440
412
|
}
|
441
413
|
}
|
442
|
-
else {
|
443
|
-
|
444
|
-
|
414
|
+
else {
|
415
|
+
const returnTypeDetails = findTypeDetails(parentTypeName);
|
416
|
+
if ((_c = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _c === void 0 ? void 0 : _c.find((f) => f.name === 'id')) {
|
417
|
+
defaults.push('id');
|
418
|
+
}
|
419
|
+
// Add other simple default fields like name, email if they exist?
|
420
|
+
// Example: Check if 'name' exists and add it
|
421
|
+
if ((_d = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _d === void 0 ? void 0 : _d.find((f) => f.name === 'name')) {
|
422
|
+
defaults.push('name');
|
423
|
+
}
|
424
|
+
if ((_e = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _e === void 0 ? void 0 : _e.find((f) => f.name === 'email')) {
|
425
|
+
defaults.push('email');
|
426
|
+
}
|
427
|
+
if ((_f = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _f === void 0 ? void 0 : _f.find((f) => f.name === 'created_at')) {
|
428
|
+
defaults.push('created_at');
|
429
|
+
}
|
430
|
+
if ((_g = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _g === void 0 ? void 0 : _g.find((f) => f.name === 'updated_at')) {
|
431
|
+
defaults.push('updated_at');
|
432
|
+
}
|
433
|
+
// Fallback __typename if still empty and it's an object/interface
|
434
|
+
if (defaults.length === 0 && ((returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.kind) === 'OBJECT' || (returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.kind) === 'INTERFACE')) {
|
435
|
+
defaults.push('__typename');
|
445
436
|
}
|
446
437
|
}
|
447
|
-
|
438
|
+
return defaults;
|
448
439
|
};
|
449
|
-
// Process returning option
|
450
440
|
if (returning) {
|
451
|
-
if (Array.isArray(returning)) {
|
452
|
-
returning
|
453
|
-
.map(field => processReturningField(field, varCounterRef))
|
454
|
-
.filter(Boolean)
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
.
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
// 2. Process the object as additional relations/fields
|
441
|
+
if (Array.isArray(returning)) {
|
442
|
+
finalReturningFields = returning
|
443
|
+
.map(field => processReturningField(field, topLevelReturnTypeName, varCounterRef))
|
444
|
+
.filter(Boolean);
|
445
|
+
// Defaults are fully overridden by array
|
446
|
+
}
|
447
|
+
else if (typeof returning === 'string') {
|
448
|
+
finalReturningFields = returning.split(/\s+/).filter(Boolean)
|
449
|
+
.map(field => processReturningField(field, topLevelReturnTypeName, varCounterRef))
|
450
|
+
.filter(Boolean);
|
451
|
+
// Defaults are fully overridden by string
|
452
|
+
}
|
453
|
+
else if (typeof returning === 'object' && returning !== null) {
|
454
|
+
// 1. Get default fields
|
455
|
+
let currentDefaults = baseGenerateDefaultFields(topLevelReturnTypeName);
|
456
|
+
const customFields = [];
|
457
|
+
// 2. Process fields from the returning object
|
469
458
|
Object.entries(returning).forEach(([key, value]) => {
|
470
|
-
// Construct the object format processReturningField expects: { relationName: subOptions }
|
471
459
|
const fieldObject = { [key]: value };
|
472
|
-
const processedField = processReturningField(fieldObject, varCounterRef);
|
460
|
+
const processedField = processReturningField(fieldObject, topLevelReturnTypeName, varCounterRef);
|
473
461
|
if (processedField) {
|
474
|
-
//
|
475
|
-
|
476
|
-
|
477
|
-
|
462
|
+
// Determine base name (handle alias: "alias: realName" or just "realName")
|
463
|
+
const baseNameMatch = processedField.match(/^([\w\d_]+)(?:\s*:\s*[\w\d_]+)?/);
|
464
|
+
// If alias exists use the original field name (key), otherwise use the matched name
|
465
|
+
const baseName = ((value === null || value === void 0 ? void 0 : value.alias) && typeof value === 'object') ? key : (baseNameMatch ? baseNameMatch[1] : key);
|
466
|
+
// Remove default if it exists with the same base name
|
467
|
+
currentDefaults = currentDefaults.filter(defaultField => {
|
468
|
+
const defaultBaseNameMatch = defaultField.match(/^([\w\d_]+)/);
|
469
|
+
return !(defaultBaseNameMatch && defaultBaseNameMatch[1] === baseName);
|
470
|
+
});
|
471
|
+
customFields.push(processedField); // Add the processed field
|
478
472
|
}
|
479
473
|
});
|
474
|
+
// 3. Combine remaining defaults and custom fields
|
475
|
+
finalReturningFields = [...currentDefaults, ...customFields];
|
480
476
|
}
|
481
477
|
else {
|
482
|
-
// Invalid
|
483
|
-
|
478
|
+
// Invalid type or null, use defaults
|
479
|
+
finalReturningFields = baseGenerateDefaultFields(topLevelReturnTypeName);
|
484
480
|
}
|
485
481
|
}
|
486
|
-
else {
|
487
|
-
|
482
|
+
else {
|
483
|
+
// No returning provided, use defaults
|
484
|
+
finalReturningFields = baseGenerateDefaultFields(topLevelReturnTypeName);
|
488
485
|
}
|
489
|
-
// ---- END MODIFICATION ----
|
490
486
|
varCounter = varCounterRef.count; // Update main counter
|
491
|
-
//
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
487
|
+
// --- End Returning ---
|
488
|
+
// --- Final Query String Assembly --- (Adjusted section)
|
489
|
+
// const returningStr = finalReturningFields.length > 0 ? finalReturningFields.join('\n ') : ''; // Use the calculated finalReturningFields
|
490
|
+
// Логика для affected_rows
|
491
|
+
let assembledReturningFields = [...finalReturningFields]; // Start with the combined list
|
492
|
+
if (['insert', 'update', 'delete'].includes(operation) && !queryName.endsWith('_by_pk') && !queryName.endsWith('_one')) {
|
493
|
+
let directFieldReturnType = queryInfo.type;
|
494
|
+
while (directFieldReturnType.ofType)
|
495
|
+
directFieldReturnType = directFieldReturnType.ofType;
|
496
|
+
const returnTypeDetails = findTypeDetails(directFieldReturnType.name);
|
497
|
+
if (((_b = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _b === void 0 ? void 0 : _b.find((f) => f.name === 'affected_rows')) && ((_c = returnTypeDetails === null || returnTypeDetails === void 0 ? void 0 : returnTypeDetails.fields) === null || _c === void 0 ? void 0 : _c.find((f) => f.name === 'returning'))) {
|
498
|
+
const fieldsForNestedReturning = assembledReturningFields.filter(f => !f.trim().startsWith('affected_rows'));
|
499
|
+
assembledReturningFields = ['affected_rows']; // Reset and start with affected_rows
|
500
|
+
if (fieldsForNestedReturning.length > 0) {
|
501
|
+
const returningFieldsStr = fieldsForNestedReturning.join('\n ');
|
502
|
+
assembledReturningFields.push(`returning {\n ${returningFieldsStr}\n }`);
|
503
|
+
}
|
504
|
+
}
|
505
|
+
else {
|
506
|
+
debug(`Mutation "%s" does not seem to return standard affected_rows/returning fields.`, queryName);
|
500
507
|
}
|
501
508
|
}
|
502
|
-
// Ensure single operations (_one, _by_pk) don't have affected_rows unless explicitly asked?
|
503
|
-
// The current logic seems to handle this by default returning fields based on queryInfo
|
504
|
-
// Determine the GraphQL operation type based on the input operation
|
505
509
|
let gqlOperationType;
|
506
|
-
if (operation === 'query')
|
510
|
+
if (operation === 'query')
|
507
511
|
gqlOperationType = 'query';
|
508
|
-
|
509
|
-
else if (operation === 'subscription') {
|
512
|
+
else if (operation === 'subscription')
|
510
513
|
gqlOperationType = 'subscription';
|
511
|
-
|
512
|
-
else { // insert, update, delete
|
514
|
+
else
|
513
515
|
gqlOperationType = 'mutation';
|
514
|
-
}
|
515
|
-
// Construct operation name (e.g., QueryUsers, MutationInsertUsersOne)
|
516
516
|
const opNamePrefix = gqlOperationType.charAt(0).toUpperCase() + gqlOperationType.slice(1);
|
517
|
-
|
518
|
-
const
|
519
|
-
const operationName = `${opNamePrefix}${tablePascal}`;
|
517
|
+
const queryNamePascal = queryName.split('_').map((part) => part ? part.charAt(0).toUpperCase() + part.slice(1) : '').join('');
|
518
|
+
const operationName = `${opNamePrefix}${queryNamePascal}`;
|
520
519
|
const argsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
|
521
|
-
const
|
520
|
+
const needsBody = currentQueryType.kind === 'OBJECT' || currentQueryType.kind === 'INTERFACE';
|
521
|
+
const returningStr = assembledReturningFields.length > 0 ? assembledReturningFields.join('\n ') : '';
|
522
|
+
const bodyStr = needsBody && returningStr ? ` {\n ${returningStr}\n }` : '';
|
522
523
|
const fragmentsStr = fragments.length > 0 ? `\n${fragments.join('\n')}` : '';
|
523
524
|
const queryStr = `
|
524
525
|
${gqlOperationType} ${operationName}${varParts.length > 0 ? `(${varParts.join(', ')})` : ''} {
|
525
|
-
${queryName}${argsStr}${
|
526
|
-
${returningStr}
|
527
|
-
}` : ''}
|
526
|
+
${queryName}${argsStr}${bodyStr}
|
528
527
|
}${fragmentsStr}
|
529
528
|
`;
|
529
|
+
// --- End Assembly ---
|
530
530
|
try {
|
531
|
+
// debug("Generated Query:", queryStr);
|
532
|
+
// debug("Generated Variables:", variables);
|
531
533
|
const gqlQuery = (0, core_1.gql)(queryStr);
|
532
534
|
return {
|
533
535
|
queryString: queryStr,
|
@@ -544,5 +546,5 @@ function Generator(schema) {
|
|
544
546
|
}
|
545
547
|
};
|
546
548
|
}
|
547
|
-
//
|
548
|
-
exports.default = Generator;
|
549
|
+
// Экспортируем Generator с уже загруженной схемой
|
550
|
+
exports.default = Generator(schema);
|