nextjs-hasura-auth 0.1.0

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.
@@ -0,0 +1,548 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Generator = Generator;
18
+ const debug_1 = __importDefault(require("./debug"));
19
+ // @ts-ignore // Assuming debug.js is moved to lib/debug.ts or similar and returns a function
20
+ const debug = (0, debug_1.default)('apollo:generator');
21
+ const core_1 = require("@apollo/client/core"); // Use core for gql
22
+ /**
23
+ * Creates a GraphQL query generator based on the provided schema.
24
+ *
25
+ * @param schema - The GraphQL schema in schema.json format.
26
+ * @returns A function to generate queries.
27
+ */
28
+ function Generator(schema) {
29
+ // Check schema structure
30
+ if (!schema || !schema.first_level_queries) {
31
+ throw new Error('❌ Invalid schema format. Schema must contain first_level_queries field');
32
+ }
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
+ return function generate(opts) {
40
+ let varCounter = opts.varCounter || 1;
41
+ if (!opts || !opts.operation || !opts.table) {
42
+ throw new Error('❌ operation and table must be specified in options');
43
+ }
44
+ const { operation, table } = opts;
45
+ const where = opts.where || null;
46
+ const returning = opts.returning || null;
47
+ const aggregate = opts.aggregate || null;
48
+ const fragments = opts.fragments || [];
49
+ const validOperations = ['query', 'subscription', 'insert', 'update', 'delete'];
50
+ if (!validOperations.includes(operation)) {
51
+ throw new Error(`❌ Invalid operation type: ${operation}. Allowed types: ${validOperations.join(', ')}`);
52
+ }
53
+ let tableName = table;
54
+ let schemaSection = 'first_level_queries';
55
+ if (aggregate && operation === 'query') {
56
+ tableName = `${table}_aggregate`;
57
+ }
58
+ if (operation === 'query') {
59
+ schemaSection = 'first_level_queries';
60
+ }
61
+ else if (operation === 'subscription') {
62
+ schemaSection = 'subscriptions';
63
+ }
64
+ else if (['insert', 'update', 'delete'].includes(operation)) {
65
+ schemaSection = 'mutations';
66
+ if (operation === 'insert') {
67
+ tableName = `insert_${table}`;
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.`);
80
+ }
81
+ // Special handling for update/delete by pk
82
+ let isByPkOperation = false;
83
+ if (['update', 'delete'].includes(operation) && opts.pk_columns) {
84
+ isByPkOperation = true;
85
+ tableName = `${operation}_${table}_by_pk`; // e.g., update_users_by_pk
86
+ }
87
+ else if (operation === 'query' && opts.pk_columns) {
88
+ isByPkOperation = true;
89
+ tableName = `${table}_by_pk`; // e.g., users_by_pk
90
+ }
91
+ else if (operation === 'insert' && opts.object && !opts.objects) {
92
+ // Try to find insert_table_one mutation
93
+ const oneMutationName = `insert_${table}_one`;
94
+ if (schema.mutations && schema.mutations[oneMutationName]) {
95
+ tableName = oneMutationName;
96
+ isByPkOperation = true; // Treat insert_one like a by_pk operation for simplicity
97
+ }
98
+ else {
99
+ tableName = `insert_${table}`; // Fallback to regular insert
100
+ }
101
+ }
102
+ else if (operation === 'insert') {
103
+ tableName = `insert_${table}`;
104
+ }
105
+ else if (operation === 'update') {
106
+ tableName = `update_${table}`;
107
+ }
108
+ else if (operation === 'delete') {
109
+ tableName = `delete_${table}`;
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`;
118
+ }
119
+ const possibleQueries = Object.keys(schema[schemaSection]);
120
+ let queryName = possibleQueries.find(q => q === tableName);
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];
131
+ if (!queryInfo) {
132
+ throw new Error(`❌ Query info for "${queryName}" not found in schema section "${schemaSection}"`);
133
+ }
134
+ const queryArgs = [];
135
+ const variables = {};
136
+ const varParts = [];
137
+ // Helper function with improved required logic
138
+ const getGqlType = (argName, argSchema, value, defaultType = 'String', forceRequired = false) => {
139
+ let typeName = (argSchema === null || argSchema === void 0 ? void 0 : argSchema.type) || defaultType;
140
+ let isList = (argSchema === null || argSchema === void 0 ? void 0 : argSchema.isList) || false; // Rely more on schema or explicit checks
141
+ let isRequired = forceRequired || (argSchema === null || argSchema === void 0 ? void 0 : argSchema.isRequired) || false;
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;
188
+ }
189
+ if (argName === '_set') {
190
+ finalType = `${baseTable}_set_input`;
191
+ finalIsList = false;
192
+ finalIsRequired = true;
193
+ }
194
+ if (argName === 'where') {
195
+ finalType = `${baseTable}_bool_exp`;
196
+ finalIsList = false;
197
+ finalIsRequired = false;
198
+ }
199
+ // If it's a direct PK arg (like `id` in `users_by_pk(id: uuid!)`)
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;
213
+ };
214
+ // Argument processing function (now relies on getGqlType for correctness)
215
+ const processArg = (argName, value, argSchema, isDirectPk = false) => {
216
+ if (value === undefined || value === null)
217
+ return;
218
+ const varName = `v${varCounter++}`;
219
+ queryArgs.push(`${argName}: $${varName}`);
220
+ variables[varName] = value;
221
+ const gqlType = getGqlType(argName, argSchema, value, 'String', isDirectPk);
222
+ varParts.push(`$${varName}: ${gqlType}`);
223
+ };
224
+ // --- Argument Processing with deterministic order ---
225
+ const argProcessingOrder = [
226
+ // Common args first
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];
248
+ let value = undefined;
249
+ let isDirectPk = false;
250
+ // Map opts to schema args
251
+ if (argName === 'pk_columns' && opts.pk_columns) {
252
+ // Process this ONLY if the operation expects pk_columns (update_by_pk)
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
+ }
260
+ }
261
+ else if (argName === '_set' && opts._set) {
262
+ value = opts._set;
263
+ }
264
+ else if (argName === 'objects' && (opts.objects || opts.object)) {
265
+ value = opts.objects || [opts.object];
266
+ }
267
+ else if (argName === 'object' && opts.object && !opts.objects) {
268
+ value = opts.object;
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;
276
+ }
277
+ else {
278
+ // This direct PK arg is not in schema, maybe it expects pk_columns object?
279
+ // Let's skip processing it directly if pk_columns object is also in the processing order
280
+ if (argProcessingOrder.includes('pk_columns'))
281
+ continue;
282
+ else
283
+ value = opts.pk_columns[argName]; // Process if pk_columns object isn't expected
284
+ }
285
+ }
286
+ else if (opts[argName] !== undefined) {
287
+ value = opts[argName];
288
+ }
289
+ if (value !== undefined) {
290
+ processArg(argName, value, argSchema, isDirectPk);
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
+ }
304
+ }
305
+ }
306
+ // --- End Argument Processing ---
307
+ const returningFields = [];
308
+ function processReturningField(field, currentVarCounterRef) {
309
+ if (typeof field === 'string') {
310
+ return field.trim();
311
+ }
312
+ if (typeof field === 'object' && field !== null) {
313
+ const fieldName = Object.keys(field)[0];
314
+ const subFieldsOrParams = field[fieldName];
315
+ if (typeof subFieldsOrParams === 'boolean' && subFieldsOrParams) {
316
+ return fieldName;
317
+ }
318
+ if (typeof subFieldsOrParams === 'boolean' && !subFieldsOrParams) {
319
+ return ''; // Explicitly skip false fields
320
+ }
321
+ if (Array.isArray(subFieldsOrParams)) {
322
+ const subFieldsStr = subFieldsOrParams
323
+ .map(sf => processReturningField(sf, currentVarCounterRef))
324
+ .filter(Boolean) // Remove empty strings from skipped fields
325
+ .join('\n ');
326
+ return subFieldsStr ? `${fieldName} {\n ${subFieldsStr}\n }` : '';
327
+ }
328
+ if (typeof subFieldsOrParams === 'string') {
329
+ return `${fieldName} {\n ${subFieldsOrParams}\n }`;
330
+ }
331
+ // Handling nested query object with potential parameters
332
+ if (typeof subFieldsOrParams === 'object' && subFieldsOrParams !== null) {
333
+ const { where: nestedWhere, limit: nestedLimit, offset: nestedOffset, order_by: nestedOrderBy, alias, returning: nestedReturningDef } = subFieldsOrParams, otherParams = __rest(subFieldsOrParams, ["where", "limit", "offset", "order_by", "alias", "returning"]);
334
+ const relationName = fieldName;
335
+ const fieldAliasOrName = alias || relationName;
336
+ const relationArgTypeNameBase = alias ? alias : relationName;
337
+ const nestedArgs = [];
338
+ // Nested argument processing
339
+ const processNestedArg = (argName, value, typeSuffix, defaultType = 'String', forceList = false) => {
340
+ if (value === undefined || value === null)
341
+ return;
342
+ const varName = `v${currentVarCounterRef.count++}`;
343
+ nestedArgs.push(`${argName}: $${varName}`);
344
+ variables[varName] = value;
345
+ // Construct type, e.g., users_bool_exp, posts_order_by
346
+ let gqlType = typeSuffix ? `${relationArgTypeNameBase}${typeSuffix}` : defaultType;
347
+ let isRequired = false; // Assume nested args aren't required unless schema says so
348
+ let isList = forceList || (argName === 'order_by'); // Force list for order_by
349
+ // Basic check if type name implies list/required (might need schema lookup)
350
+ if (gqlType.startsWith('['))
351
+ isList = true;
352
+ if (gqlType.endsWith('!')) {
353
+ isRequired = true;
354
+ gqlType = gqlType.slice(0, -1);
355
+ }
356
+ // Strip list markers if present, handle wrapping below
357
+ if (gqlType.startsWith('[') && gqlType.endsWith(']')) {
358
+ gqlType = gqlType.slice(1, -1);
359
+ }
360
+ let finalType = gqlType;
361
+ if (isList) {
362
+ // Assume inner type is required for order_by list
363
+ const innerRequired = argName === 'order_by' ? '!' : '';
364
+ finalType = `[${gqlType}${innerRequired}]`;
365
+ // Is the list itself required? (Usually not for nested args)
366
+ isRequired = false;
367
+ }
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
+ }
379
+ const nestedArgsStr = nestedArgs.length > 0 ? `(${nestedArgs.join(', ')})` : '';
380
+ let finalNestedReturning = ['id']; // Default returning 'id'
381
+ if (nestedReturningDef) {
382
+ if (Array.isArray(nestedReturningDef)) {
383
+ finalNestedReturning = nestedReturningDef;
384
+ }
385
+ else if (typeof nestedReturningDef === 'string') {
386
+ finalNestedReturning = nestedReturningDef.split(/\s+/).filter(Boolean);
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 }));
393
+ }
394
+ }
395
+ const nestedFieldsStr = finalNestedReturning
396
+ .map(f => processReturningField(f, currentVarCounterRef))
397
+ .filter(Boolean) // Remove empty strings from skipped fields
398
+ .join('\n ');
399
+ // Use alias in the field definition if present
400
+ const fieldDefinition = alias ? `${relationName}: ${fieldAliasOrName}` : fieldAliasOrName;
401
+ return nestedFieldsStr ? `${fieldDefinition}${nestedArgsStr} {\n ${nestedFieldsStr}\n }` : '';
402
+ }
403
+ return ''; // Skip invalid field types
404
+ }
405
+ return ''; // Skip invalid field types
406
+ }
407
+ const varCounterRef = { count: varCounter }; // Use ref for mutable counter in recursion
408
+ // ---- START MODIFICATION ----
409
+ let defaultFieldsGenerated = false;
410
+ // Function to generate default fields based on operation type and schema
411
+ const generateDefaultFields = () => {
412
+ var _a;
413
+ if (defaultFieldsGenerated)
414
+ return; // Generate only once
415
+ if (aggregate) {
416
+ // Aggregate logic already adds `aggregate { ... }` and potentially `nodes { ... }`
417
+ // No separate default fields needed here unless `returning` for nodes is omitted
418
+ // The existing aggregate logic handles the structure.
419
+ }
420
+ else if (queryInfo.returning_fields && !isByPkOperation && operation !== 'delete') {
421
+ // Default fields for query, subscription, insert (non-PK)
422
+ returningFields.push('id');
423
+ ['name', 'email', 'created_at', 'updated_at'].forEach(f => {
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
+ });
436
+ }
437
+ // If no PK fields were added, push id as fallback
438
+ if (returningFields.length === 0 && ((_a = queryInfo.returning_fields) === null || _a === void 0 ? void 0 : _a.id)) {
439
+ returningFields.push('id');
440
+ }
441
+ }
442
+ else { // Default for other mutations _by_pk (update) and query_by_pk
443
+ if (queryInfo.returning_fields) {
444
+ returningFields.push('id'); // Default fallback
445
+ }
446
+ }
447
+ defaultFieldsGenerated = true;
448
+ };
449
+ // Process returning option
450
+ if (returning) {
451
+ if (Array.isArray(returning)) { // Explicit array provided - overrides defaults
452
+ returning
453
+ .map(field => processReturningField(field, varCounterRef))
454
+ .filter(Boolean)
455
+ .forEach(processedField => returningFields.push(processedField));
456
+ defaultFieldsGenerated = true; // Mark defaults as handled/overridden
457
+ }
458
+ else if (typeof returning === 'string') { // Explicit string provided - overrides defaults
459
+ returning.split(/\s+/).filter(Boolean)
460
+ .map(field => processReturningField(field, varCounterRef)) // Process simple strings
461
+ .filter(Boolean)
462
+ .forEach(processedField => returningFields.push(processedField));
463
+ defaultFieldsGenerated = true; // Mark defaults as handled/overridden
464
+ }
465
+ else if (typeof returning === 'object' && returning !== null) { // NEW: Object provided - ADD to defaults
466
+ // 1. Generate default fields first
467
+ generateDefaultFields();
468
+ // 2. Process the object as additional relations/fields
469
+ Object.entries(returning).forEach(([key, value]) => {
470
+ // Construct the object format processReturningField expects: { relationName: subOptions }
471
+ const fieldObject = { [key]: value };
472
+ const processedField = processReturningField(fieldObject, varCounterRef);
473
+ if (processedField) {
474
+ // Avoid adding duplicates if default already added it (less likely for relations)
475
+ if (!returningFields.includes(processedField)) {
476
+ returningFields.push(processedField);
477
+ }
478
+ }
479
+ });
480
+ }
481
+ else {
482
+ // Invalid returning type? Fallback to defaults.
483
+ generateDefaultFields();
484
+ }
485
+ }
486
+ else { // returning is null or undefined - Use defaults
487
+ generateDefaultFields();
488
+ }
489
+ // ---- END MODIFICATION ----
490
+ varCounter = varCounterRef.count; // Update main counter
491
+ // Adjust structure for bulk mutations (insert, update, delete) vs single (_one, _by_pk)
492
+ let finalReturningFields = [...returningFields];
493
+ if (['insert', 'update', 'delete'].includes(operation) && !isByPkOperation) {
494
+ // Bulk operations usually return affected_rows and a nested 'returning' array
495
+ const fieldsForReturning = finalReturningFields.filter(f => !f.startsWith('affected_rows')); // Keep existing fields
496
+ finalReturningFields = ['affected_rows']; // Start with affected_rows
497
+ if (fieldsForReturning.length > 0) {
498
+ const returningFieldsStr = fieldsForReturning.join('\n ');
499
+ finalReturningFields.push(`returning {\n ${returningFieldsStr}\n }`);
500
+ }
501
+ }
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
+ let gqlOperationType;
506
+ if (operation === 'query') {
507
+ gqlOperationType = 'query';
508
+ }
509
+ else if (operation === 'subscription') {
510
+ gqlOperationType = 'subscription';
511
+ }
512
+ else { // insert, update, delete
513
+ gqlOperationType = 'mutation';
514
+ }
515
+ // Construct operation name (e.g., QueryUsers, MutationInsertUsersOne)
516
+ const opNamePrefix = gqlOperationType.charAt(0).toUpperCase() + gqlOperationType.slice(1);
517
+ // Ensure tablePascal handles potential empty parts from split
518
+ const tablePascal = queryName.split('_').map(part => part ? part.charAt(0).toUpperCase() + part.slice(1) : '').join('');
519
+ const operationName = `${opNamePrefix}${tablePascal}`;
520
+ const argsStr = queryArgs.length > 0 ? `(${queryArgs.join(', ')})` : '';
521
+ const returningStr = finalReturningFields.length > 0 ? finalReturningFields.join('\n ') : (queryInfo.returning_fields ? 'id' : ''); // Fallback to id if possible
522
+ const fragmentsStr = fragments.length > 0 ? `\n${fragments.join('\n')}` : '';
523
+ const queryStr = `
524
+ ${gqlOperationType} ${operationName}${varParts.length > 0 ? `(${varParts.join(', ')})` : ''} {
525
+ ${queryName}${argsStr}${returningStr ? ` {
526
+ ${returningStr}
527
+ }` : ''}
528
+ }${fragmentsStr}
529
+ `;
530
+ try {
531
+ const gqlQuery = (0, core_1.gql)(queryStr);
532
+ return {
533
+ queryString: queryStr,
534
+ query: gqlQuery,
535
+ variables,
536
+ varCounter
537
+ };
538
+ }
539
+ catch (error) {
540
+ console.error("❌ Error parsing GraphQL query:", error.message);
541
+ console.error("Generated Query String:", queryStr);
542
+ console.error("Variables:", JSON.stringify(variables, null, 2));
543
+ throw new Error(`Failed to parse generated GraphQL query: ${error.message}`);
544
+ }
545
+ };
546
+ }
547
+ // Export the factory function
548
+ exports.default = Generator;
@@ -0,0 +1,3 @@
1
+ export * from './utils';
2
+ export * from './apollo';
3
+ export * from './generator';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // Export all utilities from the lib directory
18
+ __exportStar(require("./utils"), exports);
19
+ __exportStar(require("./apollo"), exports);
20
+ __exportStar(require("./generator"), exports);
@@ -0,0 +1,67 @@
1
+ import { type JWTPayload } from 'jose';
2
+ /**
3
+ * Get JWT secret from environment variables (for signing/verifying JWS)
4
+ * This remains synchronous as it doesn't involve async crypto operations here.
5
+ * @returns {Uint8Array} Secret key for JWT signing
6
+ */
7
+ export declare const getJwtSecret: () => Uint8Array;
8
+ /**
9
+ * Get NextAuth secret from environment variables and hash it using Web Crypto API (SHA-256).
10
+ * IMPORTANT: This MUST match the NEXTAUTH_SECRET used by next-auth.
11
+ * @returns {Promise<Uint8Array>} Secret key for JWE operations (always 32 bytes/256 bits)
12
+ */
13
+ export declare const getNextAuthSecret: () => Promise<Uint8Array>;
14
+ /**
15
+ * Extracts the algorithm type from JWT secret configuration (for JWS)
16
+ * This remains synchronous.
17
+ * @returns {string} The algorithm type (default: 'HS256')
18
+ */
19
+ export declare const getJwtAlgorithm: () => string;
20
+ /**
21
+ * Creates a JWT token (JWS) with Hasura claims
22
+ *
23
+ * @param {string} userId - User ID
24
+ * @param {Record<string, any>} [additionalClaims={}] - Additional claims for the token
25
+ * @param {{ expiresIn?: string }} [options={}] - Options for token generation
26
+ * @returns {Promise<string>} JWT token (JWS format)
27
+ */
28
+ export declare const generateJWT: (userId: string, additionalClaims?: Record<string, any>, options?: {
29
+ expiresIn?: string;
30
+ }) => Promise<string>;
31
+ /**
32
+ * Verifies a JWT token (JWS)
33
+ * @param {string} token - JWT token (JWS format) to verify
34
+ * @returns {Promise<JWTPayload>} Token payload
35
+ */
36
+ export declare const verifyJWT: (token: string) => Promise<JWTPayload>;
37
+ /**
38
+ * Decrypts a NextAuth session token (JWE)
39
+ * @param {string} sessionToken - The encrypted session token (JWE) from the cookie
40
+ * @returns {Promise<JWTPayload>} The decrypted payload
41
+ */
42
+ export declare const decryptNextAuthToken: (sessionToken: string) => Promise<JWTPayload>;
43
+ /**
44
+ * Extract user ID from a verified/decrypted JWT payload
45
+ * @param {JWTPayload} payload - The token payload
46
+ * @returns {string | null} User ID or null if not found
47
+ */
48
+ export declare const getUserIdFromPayload: (payload: JWTPayload) => string | null;
49
+ /**
50
+ * Get Hasura claims from a verified/decrypted JWT payload
51
+ * @param {JWTPayload} payload - The token payload
52
+ * @returns {Record<string, any> | null} Hasura claims or null if not found
53
+ */
54
+ export declare const getHasuraClaimsFromPayload: (payload: JWTPayload) => Record<string, any> | null;
55
+ declare const _default: {
56
+ getJwtSecret: () => Uint8Array;
57
+ getNextAuthSecret: () => Promise<Uint8Array>;
58
+ getJwtAlgorithm: () => string;
59
+ generateJWT: (userId: string, additionalClaims?: Record<string, any>, options?: {
60
+ expiresIn?: string;
61
+ }) => Promise<string>;
62
+ verifyJWT: (token: string) => Promise<JWTPayload>;
63
+ decryptNextAuthToken: (sessionToken: string) => Promise<JWTPayload>;
64
+ getUserIdFromPayload: (payload: JWTPayload) => string | null;
65
+ getHasuraClaimsFromPayload: (payload: JWTPayload) => Record<string, any> | null;
66
+ };
67
+ export default _default;