@constructive-io/graphql-query 3.2.4 → 3.3.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.
Files changed (88) hide show
  1. package/README.md +411 -65
  2. package/ast.d.ts +4 -4
  3. package/ast.js +24 -9
  4. package/client/error.d.ts +95 -0
  5. package/client/error.js +277 -0
  6. package/client/execute.d.ts +57 -0
  7. package/client/execute.js +124 -0
  8. package/client/index.d.ts +8 -0
  9. package/client/index.js +20 -0
  10. package/client/typed-document.d.ts +31 -0
  11. package/client/typed-document.js +44 -0
  12. package/custom-ast.d.ts +22 -8
  13. package/custom-ast.js +16 -1
  14. package/esm/ast.js +22 -7
  15. package/esm/client/error.js +271 -0
  16. package/esm/client/execute.js +120 -0
  17. package/esm/client/index.js +8 -0
  18. package/esm/client/typed-document.js +40 -0
  19. package/esm/custom-ast.js +16 -1
  20. package/esm/generators/field-selector.js +381 -0
  21. package/esm/generators/index.js +13 -0
  22. package/esm/generators/mutations.js +200 -0
  23. package/esm/generators/naming-helpers.js +154 -0
  24. package/esm/generators/select.js +661 -0
  25. package/esm/index.js +30 -0
  26. package/esm/introspect/index.js +9 -0
  27. package/esm/introspect/infer-tables.js +697 -0
  28. package/esm/introspect/schema-query.js +120 -0
  29. package/esm/introspect/transform-schema.js +271 -0
  30. package/esm/introspect/transform.js +38 -0
  31. package/esm/meta-object/convert.js +3 -0
  32. package/esm/meta-object/format.json +11 -41
  33. package/esm/meta-object/validate.js +20 -4
  34. package/esm/query-builder.js +14 -18
  35. package/esm/types/index.js +18 -0
  36. package/esm/types/introspection.js +54 -0
  37. package/esm/types/mutation.js +4 -0
  38. package/esm/types/query.js +4 -0
  39. package/esm/types/schema.js +5 -0
  40. package/esm/types/selection.js +4 -0
  41. package/esm/utils.js +69 -0
  42. package/generators/field-selector.d.ts +30 -0
  43. package/generators/field-selector.js +387 -0
  44. package/generators/index.d.ts +9 -0
  45. package/generators/index.js +42 -0
  46. package/generators/mutations.d.ts +30 -0
  47. package/generators/mutations.js +238 -0
  48. package/generators/naming-helpers.d.ts +48 -0
  49. package/generators/naming-helpers.js +169 -0
  50. package/generators/select.d.ts +39 -0
  51. package/generators/select.js +705 -0
  52. package/index.d.ts +19 -0
  53. package/index.js +34 -1
  54. package/introspect/index.d.ts +9 -0
  55. package/introspect/index.js +25 -0
  56. package/introspect/infer-tables.d.ts +42 -0
  57. package/introspect/infer-tables.js +700 -0
  58. package/introspect/schema-query.d.ts +20 -0
  59. package/introspect/schema-query.js +123 -0
  60. package/introspect/transform-schema.d.ts +86 -0
  61. package/introspect/transform-schema.js +281 -0
  62. package/introspect/transform.d.ts +20 -0
  63. package/introspect/transform.js +43 -0
  64. package/meta-object/convert.d.ts +3 -0
  65. package/meta-object/convert.js +3 -0
  66. package/meta-object/format.json +11 -41
  67. package/meta-object/validate.d.ts +8 -3
  68. package/meta-object/validate.js +20 -4
  69. package/package.json +4 -3
  70. package/query-builder.d.ts +11 -12
  71. package/query-builder.js +25 -29
  72. package/{types.d.ts → types/core.d.ts} +25 -18
  73. package/types/index.d.ts +12 -0
  74. package/types/index.js +34 -0
  75. package/types/introspection.d.ts +121 -0
  76. package/types/introspection.js +62 -0
  77. package/types/mutation.d.ts +45 -0
  78. package/types/mutation.js +5 -0
  79. package/types/query.d.ts +91 -0
  80. package/types/query.js +5 -0
  81. package/types/schema.d.ts +265 -0
  82. package/types/schema.js +6 -0
  83. package/types/selection.d.ts +43 -0
  84. package/types/selection.js +5 -0
  85. package/utils.d.ts +17 -0
  86. package/utils.js +72 -0
  87. /package/esm/{types.js → types/core.js} +0 -0
  88. /package/{types.js → types/core.js} +0 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * GraphQL Schema Introspection Query
3
+ *
4
+ * Full introspection query that captures all queries, mutations, and types
5
+ * from a GraphQL endpoint via the standard __schema query.
6
+ */
7
+ import type { IntrospectionQueryResponse } from '../types/introspection';
8
+ /**
9
+ * Full schema introspection query
10
+ *
11
+ * Captures:
12
+ * - All Query fields with args and return types
13
+ * - All Mutation fields with args and return types
14
+ * - All types (OBJECT, INPUT_OBJECT, ENUM, SCALAR) for resolution
15
+ *
16
+ * Uses a recursive TypeRef fragment to handle deeply nested type wrappers
17
+ * (e.g., [String!]! = NON_NULL(LIST(NON_NULL(SCALAR))))
18
+ */
19
+ export declare const SCHEMA_INTROSPECTION_QUERY = "\nquery IntrospectSchema {\n __schema {\n queryType {\n name\n }\n mutationType {\n name\n }\n subscriptionType {\n name\n }\n types {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n name\n description\n type {\n ...TypeRef\n }\n defaultValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n name\n description\n type {\n ...TypeRef\n }\n defaultValue\n }\n interfaces {\n name\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n name\n }\n }\n directives {\n name\n description\n locations\n args {\n name\n description\n type {\n ...TypeRef\n }\n defaultValue\n }\n }\n }\n}\n\nfragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n}\n";
20
+ export type { IntrospectionQueryResponse };
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ /**
3
+ * GraphQL Schema Introspection Query
4
+ *
5
+ * Full introspection query that captures all queries, mutations, and types
6
+ * from a GraphQL endpoint via the standard __schema query.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SCHEMA_INTROSPECTION_QUERY = void 0;
10
+ /**
11
+ * Full schema introspection query
12
+ *
13
+ * Captures:
14
+ * - All Query fields with args and return types
15
+ * - All Mutation fields with args and return types
16
+ * - All types (OBJECT, INPUT_OBJECT, ENUM, SCALAR) for resolution
17
+ *
18
+ * Uses a recursive TypeRef fragment to handle deeply nested type wrappers
19
+ * (e.g., [String!]! = NON_NULL(LIST(NON_NULL(SCALAR))))
20
+ */
21
+ exports.SCHEMA_INTROSPECTION_QUERY = `
22
+ query IntrospectSchema {
23
+ __schema {
24
+ queryType {
25
+ name
26
+ }
27
+ mutationType {
28
+ name
29
+ }
30
+ subscriptionType {
31
+ name
32
+ }
33
+ types {
34
+ kind
35
+ name
36
+ description
37
+ fields(includeDeprecated: true) {
38
+ name
39
+ description
40
+ args {
41
+ name
42
+ description
43
+ type {
44
+ ...TypeRef
45
+ }
46
+ defaultValue
47
+ }
48
+ type {
49
+ ...TypeRef
50
+ }
51
+ isDeprecated
52
+ deprecationReason
53
+ }
54
+ inputFields {
55
+ name
56
+ description
57
+ type {
58
+ ...TypeRef
59
+ }
60
+ defaultValue
61
+ }
62
+ interfaces {
63
+ name
64
+ }
65
+ enumValues(includeDeprecated: true) {
66
+ name
67
+ description
68
+ isDeprecated
69
+ deprecationReason
70
+ }
71
+ possibleTypes {
72
+ name
73
+ }
74
+ }
75
+ directives {
76
+ name
77
+ description
78
+ locations
79
+ args {
80
+ name
81
+ description
82
+ type {
83
+ ...TypeRef
84
+ }
85
+ defaultValue
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ fragment TypeRef on __Type {
92
+ kind
93
+ name
94
+ ofType {
95
+ kind
96
+ name
97
+ ofType {
98
+ kind
99
+ name
100
+ ofType {
101
+ kind
102
+ name
103
+ ofType {
104
+ kind
105
+ name
106
+ ofType {
107
+ kind
108
+ name
109
+ ofType {
110
+ kind
111
+ name
112
+ ofType {
113
+ kind
114
+ name
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ `;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Transform GraphQL introspection data to clean operation types
3
+ *
4
+ * This module converts raw introspection responses into the CleanOperation
5
+ * format used by code generators.
6
+ */
7
+ import type { IntrospectionQueryResponse, IntrospectionType } from '../types/introspection';
8
+ import { getBaseTypeName, isNonNull, unwrapType } from '../types/introspection';
9
+ import type { CleanOperation, TypeRegistry } from '../types/schema';
10
+ /**
11
+ * Build a type registry from introspection types
12
+ * Maps type names to their full resolved definitions
13
+ *
14
+ * This is a two-pass process to handle circular references:
15
+ * 1. First pass: Create all type entries with basic info
16
+ * 2. Second pass: Resolve fields with references to other types
17
+ */
18
+ export declare function buildTypeRegistry(types: IntrospectionType[]): TypeRegistry;
19
+ export interface TransformSchemaResult {
20
+ queries: CleanOperation[];
21
+ mutations: CleanOperation[];
22
+ typeRegistry: TypeRegistry;
23
+ }
24
+ /**
25
+ * Transform introspection response to clean operations
26
+ */
27
+ export declare function transformSchemaToOperations(response: IntrospectionQueryResponse): TransformSchemaResult;
28
+ /**
29
+ * Filter operations by include/exclude patterns
30
+ * Uses glob-like patterns (supports * wildcard)
31
+ */
32
+ export declare function filterOperations(operations: CleanOperation[], include?: string[], exclude?: string[]): CleanOperation[];
33
+ /**
34
+ * Result type for table operation names lookup
35
+ */
36
+ export interface TableOperationNames {
37
+ queries: Set<string>;
38
+ mutations: Set<string>;
39
+ }
40
+ /**
41
+ * Get the set of table-related operation names from tables
42
+ * Used to identify which operations are already covered by table generators
43
+ *
44
+ * IMPORTANT: This uses EXACT matches only from _meta.query fields.
45
+ * Any operation not explicitly listed in _meta will flow through as a
46
+ * custom operation, ensuring 100% coverage of the schema.
47
+ *
48
+ * Table operations (generated by table generators):
49
+ * - Queries: all (list), one (single by PK)
50
+ * - Mutations: create, update (by PK), delete (by PK)
51
+ *
52
+ * Custom operations (generated by custom operation generators):
53
+ * - Unique constraint lookups: *ByUsername, *ByEmail, etc.
54
+ * - Unique constraint mutations: update*By*, delete*By*
55
+ * - True custom operations: login, register, bootstrapUser, etc.
56
+ */
57
+ export declare function getTableOperationNames(tables: Array<{
58
+ name: string;
59
+ query?: {
60
+ all: string;
61
+ one: string | null;
62
+ create: string;
63
+ update: string | null;
64
+ delete: string | null;
65
+ };
66
+ }>): TableOperationNames;
67
+ /**
68
+ * Check if an operation is a table operation (already handled by table generators)
69
+ *
70
+ * Uses EXACT match only - no pattern matching. This ensures:
71
+ * 1. Only operations explicitly in _meta.query are treated as table operations
72
+ * 2. All other operations (including update*By*, delete*By*) become custom operations
73
+ * 3. 100% schema coverage is guaranteed
74
+ */
75
+ export declare function isTableOperation(operation: CleanOperation, tableOperationNames: TableOperationNames): boolean;
76
+ /**
77
+ * Get only custom operations (not covered by table generators)
78
+ *
79
+ * This returns ALL operations that are not exact matches for table CRUD operations.
80
+ * Includes:
81
+ * - Unique constraint queries (*ByUsername, *ByEmail, etc.)
82
+ * - Unique constraint mutations (update*By*, delete*By*)
83
+ * - True custom operations (login, register, bootstrapUser, etc.)
84
+ */
85
+ export declare function getCustomOperations(operations: CleanOperation[], tableOperationNames: TableOperationNames): CleanOperation[];
86
+ export { getBaseTypeName, isNonNull, unwrapType };
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapType = exports.isNonNull = exports.getBaseTypeName = void 0;
4
+ exports.buildTypeRegistry = buildTypeRegistry;
5
+ exports.transformSchemaToOperations = transformSchemaToOperations;
6
+ exports.filterOperations = filterOperations;
7
+ exports.getTableOperationNames = getTableOperationNames;
8
+ exports.isTableOperation = isTableOperation;
9
+ exports.getCustomOperations = getCustomOperations;
10
+ const introspection_1 = require("../types/introspection");
11
+ Object.defineProperty(exports, "getBaseTypeName", { enumerable: true, get: function () { return introspection_1.getBaseTypeName; } });
12
+ Object.defineProperty(exports, "isNonNull", { enumerable: true, get: function () { return introspection_1.isNonNull; } });
13
+ Object.defineProperty(exports, "unwrapType", { enumerable: true, get: function () { return introspection_1.unwrapType; } });
14
+ // ============================================================================
15
+ // Type Registry Builder
16
+ // ============================================================================
17
+ /**
18
+ * Build a type registry from introspection types
19
+ * Maps type names to their full resolved definitions
20
+ *
21
+ * This is a two-pass process to handle circular references:
22
+ * 1. First pass: Create all type entries with basic info
23
+ * 2. Second pass: Resolve fields with references to other types
24
+ */
25
+ function buildTypeRegistry(types) {
26
+ const registry = new Map();
27
+ // First pass: Create all type entries
28
+ for (const type of types) {
29
+ // Skip built-in types that start with __
30
+ if (type.name.startsWith('__'))
31
+ continue;
32
+ const resolvedType = {
33
+ kind: type.kind,
34
+ name: type.name,
35
+ description: type.description ?? undefined,
36
+ };
37
+ // Resolve enum values for ENUM types (no circular refs possible)
38
+ if (type.kind === 'ENUM' && type.enumValues) {
39
+ resolvedType.enumValues = type.enumValues.map((ev) => ev.name);
40
+ }
41
+ // Resolve possible types for UNION types (no circular refs for names)
42
+ if (type.kind === 'UNION' && type.possibleTypes) {
43
+ resolvedType.possibleTypes = type.possibleTypes.map((pt) => pt.name);
44
+ }
45
+ registry.set(type.name, resolvedType);
46
+ }
47
+ // Second pass: Resolve fields (now that all types exist in registry)
48
+ for (const type of types) {
49
+ if (type.name.startsWith('__'))
50
+ continue;
51
+ const resolvedType = registry.get(type.name);
52
+ if (!resolvedType)
53
+ continue;
54
+ // Resolve fields for OBJECT types
55
+ if (type.kind === 'OBJECT' && type.fields) {
56
+ resolvedType.fields = type.fields.map((field) => transformFieldToCleanObjectFieldShallow(field));
57
+ }
58
+ // Resolve input fields for INPUT_OBJECT types
59
+ if (type.kind === 'INPUT_OBJECT' && type.inputFields) {
60
+ resolvedType.inputFields = type.inputFields.map((field) => transformInputValueToCleanArgumentShallow(field));
61
+ }
62
+ }
63
+ return registry;
64
+ }
65
+ /**
66
+ * Transform field to CleanObjectField without resolving nested types
67
+ * (shallow transformation to avoid circular refs)
68
+ */
69
+ function transformFieldToCleanObjectFieldShallow(field) {
70
+ return {
71
+ name: field.name,
72
+ type: transformTypeRefShallow(field.type),
73
+ description: field.description ?? undefined,
74
+ };
75
+ }
76
+ /**
77
+ * Transform input value to CleanArgument without resolving nested types
78
+ */
79
+ function transformInputValueToCleanArgumentShallow(inputValue) {
80
+ return {
81
+ name: inputValue.name,
82
+ type: transformTypeRefShallow(inputValue.type),
83
+ defaultValue: inputValue.defaultValue ?? undefined,
84
+ description: inputValue.description ?? undefined,
85
+ };
86
+ }
87
+ /**
88
+ * Transform TypeRef without resolving nested types
89
+ * Only handles wrappers (LIST, NON_NULL) and stores the type name
90
+ */
91
+ function transformTypeRefShallow(typeRef) {
92
+ const cleanRef = {
93
+ kind: typeRef.kind,
94
+ name: typeRef.name,
95
+ };
96
+ if (typeRef.ofType) {
97
+ cleanRef.ofType = transformTypeRefShallow(typeRef.ofType);
98
+ }
99
+ return cleanRef;
100
+ }
101
+ /**
102
+ * Transform introspection response to clean operations
103
+ */
104
+ function transformSchemaToOperations(response) {
105
+ const { __schema: schema } = response;
106
+ const { types, queryType, mutationType } = schema;
107
+ // Build type registry first
108
+ const typeRegistry = buildTypeRegistry(types);
109
+ // Find Query and Mutation types
110
+ const queryTypeDef = types.find((t) => t.name === queryType.name);
111
+ const mutationTypeDef = mutationType
112
+ ? types.find((t) => t.name === mutationType.name)
113
+ : null;
114
+ // Transform queries
115
+ const queries = queryTypeDef?.fields
116
+ ? queryTypeDef.fields.map((field) => transformFieldToCleanOperation(field, 'query', types))
117
+ : [];
118
+ // Transform mutations
119
+ const mutations = mutationTypeDef?.fields
120
+ ? mutationTypeDef.fields.map((field) => transformFieldToCleanOperation(field, 'mutation', types))
121
+ : [];
122
+ return { queries, mutations, typeRegistry };
123
+ }
124
+ // ============================================================================
125
+ // Field to Operation Transformation
126
+ // ============================================================================
127
+ /**
128
+ * Transform an introspection field to a CleanOperation
129
+ */
130
+ function transformFieldToCleanOperation(field, kind, types) {
131
+ return {
132
+ name: field.name,
133
+ kind,
134
+ args: field.args.map((arg) => transformInputValueToCleanArgument(arg, types)),
135
+ returnType: transformTypeRefToCleanTypeRef(field.type, types),
136
+ description: field.description ?? undefined,
137
+ isDeprecated: field.isDeprecated,
138
+ deprecationReason: field.deprecationReason ?? undefined,
139
+ };
140
+ }
141
+ /**
142
+ * Transform an input value to CleanArgument
143
+ */
144
+ function transformInputValueToCleanArgument(inputValue, types) {
145
+ return {
146
+ name: inputValue.name,
147
+ type: transformTypeRefToCleanTypeRef(inputValue.type, types),
148
+ defaultValue: inputValue.defaultValue ?? undefined,
149
+ description: inputValue.description ?? undefined,
150
+ };
151
+ }
152
+ // ============================================================================
153
+ // Type Reference Transformation
154
+ // ============================================================================
155
+ /**
156
+ * Transform an introspection TypeRef to CleanTypeRef
157
+ * Recursively handles wrapper types (LIST, NON_NULL)
158
+ *
159
+ * NOTE: We intentionally do NOT resolve nested fields here to avoid
160
+ * infinite recursion from circular type references. Fields are resolved
161
+ * lazily via the TypeRegistry when needed for code generation.
162
+ */
163
+ function transformTypeRefToCleanTypeRef(typeRef, types) {
164
+ const cleanRef = {
165
+ kind: typeRef.kind,
166
+ name: typeRef.name,
167
+ };
168
+ // Recursively transform ofType for wrappers (LIST, NON_NULL)
169
+ if (typeRef.ofType) {
170
+ cleanRef.ofType = transformTypeRefToCleanTypeRef(typeRef.ofType, types);
171
+ }
172
+ // For named types, only resolve enum values (they don't have circular refs)
173
+ // Fields are NOT resolved here - they're resolved via TypeRegistry during codegen
174
+ if (typeRef.name && !typeRef.ofType) {
175
+ const typeDef = types.find((t) => t.name === typeRef.name);
176
+ if (typeDef) {
177
+ // Add enum values for ENUM types (safe, no recursion)
178
+ if (typeDef.kind === 'ENUM' && typeDef.enumValues) {
179
+ cleanRef.enumValues = typeDef.enumValues.map((ev) => ev.name);
180
+ }
181
+ // NOTE: OBJECT and INPUT_OBJECT fields are resolved via TypeRegistry
182
+ // to avoid circular reference issues
183
+ }
184
+ }
185
+ return cleanRef;
186
+ }
187
+ // ============================================================================
188
+ // Operation Filtering
189
+ // ============================================================================
190
+ /**
191
+ * Filter operations by include/exclude patterns
192
+ * Uses glob-like patterns (supports * wildcard)
193
+ */
194
+ function filterOperations(operations, include, exclude) {
195
+ let result = operations;
196
+ if (include && include.length > 0) {
197
+ result = result.filter((op) => matchesPatterns(op.name, include));
198
+ }
199
+ if (exclude && exclude.length > 0) {
200
+ result = result.filter((op) => !matchesPatterns(op.name, exclude));
201
+ }
202
+ return result;
203
+ }
204
+ /**
205
+ * Check if a name matches any of the patterns
206
+ * Supports simple glob patterns with * wildcard
207
+ */
208
+ function matchesPatterns(name, patterns) {
209
+ return patterns.some((pattern) => {
210
+ if (pattern === '*')
211
+ return true;
212
+ if (pattern.includes('*')) {
213
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
214
+ return regex.test(name);
215
+ }
216
+ return name === pattern;
217
+ });
218
+ }
219
+ /**
220
+ * Get the set of table-related operation names from tables
221
+ * Used to identify which operations are already covered by table generators
222
+ *
223
+ * IMPORTANT: This uses EXACT matches only from _meta.query fields.
224
+ * Any operation not explicitly listed in _meta will flow through as a
225
+ * custom operation, ensuring 100% coverage of the schema.
226
+ *
227
+ * Table operations (generated by table generators):
228
+ * - Queries: all (list), one (single by PK)
229
+ * - Mutations: create, update (by PK), delete (by PK)
230
+ *
231
+ * Custom operations (generated by custom operation generators):
232
+ * - Unique constraint lookups: *ByUsername, *ByEmail, etc.
233
+ * - Unique constraint mutations: update*By*, delete*By*
234
+ * - True custom operations: login, register, bootstrapUser, etc.
235
+ */
236
+ function getTableOperationNames(tables) {
237
+ const queries = new Set();
238
+ const mutations = new Set();
239
+ for (const table of tables) {
240
+ if (table.query) {
241
+ // Add exact query names from _meta
242
+ queries.add(table.query.all);
243
+ if (table.query.one) {
244
+ queries.add(table.query.one);
245
+ }
246
+ // Add exact mutation names from _meta
247
+ mutations.add(table.query.create);
248
+ if (table.query.update)
249
+ mutations.add(table.query.update);
250
+ if (table.query.delete)
251
+ mutations.add(table.query.delete);
252
+ }
253
+ }
254
+ return { queries, mutations };
255
+ }
256
+ /**
257
+ * Check if an operation is a table operation (already handled by table generators)
258
+ *
259
+ * Uses EXACT match only - no pattern matching. This ensures:
260
+ * 1. Only operations explicitly in _meta.query are treated as table operations
261
+ * 2. All other operations (including update*By*, delete*By*) become custom operations
262
+ * 3. 100% schema coverage is guaranteed
263
+ */
264
+ function isTableOperation(operation, tableOperationNames) {
265
+ if (operation.kind === 'query') {
266
+ return tableOperationNames.queries.has(operation.name);
267
+ }
268
+ return tableOperationNames.mutations.has(operation.name);
269
+ }
270
+ /**
271
+ * Get only custom operations (not covered by table generators)
272
+ *
273
+ * This returns ALL operations that are not exact matches for table CRUD operations.
274
+ * Includes:
275
+ * - Unique constraint queries (*ByUsername, *ByEmail, etc.)
276
+ * - Unique constraint mutations (update*By*, delete*By*)
277
+ * - True custom operations (login, register, bootstrapUser, etc.)
278
+ */
279
+ function getCustomOperations(operations, tableOperationNames) {
280
+ return operations.filter((op) => !isTableOperation(op, tableOperationNames));
281
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Table utility functions for CleanTable[]
3
+ *
4
+ * Note: The _meta transform functions have been removed.
5
+ * Tables are now inferred from standard GraphQL introspection
6
+ * using inferTablesFromIntrospection() in ./infer-tables.ts
7
+ */
8
+ import type { CleanTable } from '../types/schema';
9
+ /**
10
+ * Get table names from CleanTable array
11
+ */
12
+ export declare function getTableNames(tables: CleanTable[]): string[];
13
+ /**
14
+ * Find a table by name
15
+ */
16
+ export declare function findTable(tables: CleanTable[], name: string): CleanTable | undefined;
17
+ /**
18
+ * Filter tables by name pattern (glob-like)
19
+ */
20
+ export declare function filterTables(tables: CleanTable[], include?: string[], exclude?: string[]): CleanTable[];
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTableNames = getTableNames;
4
+ exports.findTable = findTable;
5
+ exports.filterTables = filterTables;
6
+ /**
7
+ * Get table names from CleanTable array
8
+ */
9
+ function getTableNames(tables) {
10
+ return tables.map((t) => t.name);
11
+ }
12
+ /**
13
+ * Find a table by name
14
+ */
15
+ function findTable(tables, name) {
16
+ return tables.find((t) => t.name === name);
17
+ }
18
+ /**
19
+ * Filter tables by name pattern (glob-like)
20
+ */
21
+ function filterTables(tables, include, exclude) {
22
+ let result = tables;
23
+ if (include && include.length > 0) {
24
+ result = result.filter((t) => matchesPatterns(t.name, include));
25
+ }
26
+ if (exclude && exclude.length > 0) {
27
+ result = result.filter((t) => !matchesPatterns(t.name, exclude));
28
+ }
29
+ return result;
30
+ }
31
+ /**
32
+ * Check if a name matches any of the patterns
33
+ * Supports simple glob patterns with * wildcard
34
+ */
35
+ function matchesPatterns(name, patterns) {
36
+ return patterns.some((pattern) => {
37
+ if (pattern.includes('*')) {
38
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
39
+ return regex.test(name);
40
+ }
41
+ return name === pattern;
42
+ });
43
+ }
@@ -58,5 +58,8 @@ interface ConvertedTable {
58
58
  interface ConvertedMetaObject {
59
59
  tables: ConvertedTable[];
60
60
  }
61
+ /**
62
+ * Convert from raw _meta schema response to internal MetaObject format
63
+ */
61
64
  export declare function convertFromMetaSchema(metaSchema: MetaSchemaInput): ConvertedMetaObject;
62
65
  export {};
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertFromMetaSchema = convertFromMetaSchema;
4
+ /**
5
+ * Convert from raw _meta schema response to internal MetaObject format
6
+ */
4
7
  function convertFromMetaSchema(metaSchema) {
5
8
  const { _meta: { tables }, } = metaSchema;
6
9
  const result = {