@constructive-io/graphql-codegen 2.21.0 → 2.22.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 (93) hide show
  1. package/cli/codegen/barrel.d.ts +4 -1
  2. package/cli/codegen/barrel.js +18 -12
  3. package/cli/codegen/client.js +33 -0
  4. package/cli/codegen/custom-mutations.d.ts +4 -0
  5. package/cli/codegen/custom-mutations.js +39 -13
  6. package/cli/codegen/custom-queries.d.ts +4 -0
  7. package/cli/codegen/custom-queries.js +36 -11
  8. package/cli/codegen/gql-ast.js +9 -5
  9. package/cli/codegen/index.js +35 -7
  10. package/cli/codegen/mutations.d.ts +2 -0
  11. package/cli/codegen/mutations.js +87 -23
  12. package/cli/codegen/orm/barrel.js +4 -2
  13. package/cli/codegen/orm/index.js +17 -0
  14. package/cli/codegen/orm/input-types-generator.js +83 -29
  15. package/cli/codegen/orm/model-generator.js +6 -4
  16. package/cli/codegen/queries.js +36 -27
  17. package/cli/codegen/scalars.d.ts +6 -4
  18. package/cli/codegen/scalars.js +17 -9
  19. package/cli/codegen/schema-types-generator.d.ts +26 -0
  20. package/cli/codegen/schema-types-generator.js +365 -0
  21. package/cli/codegen/ts-ast.d.ts +3 -1
  22. package/cli/codegen/ts-ast.js +2 -2
  23. package/cli/codegen/type-resolver.d.ts +52 -6
  24. package/cli/codegen/type-resolver.js +97 -19
  25. package/cli/codegen/types.d.ts +7 -4
  26. package/cli/codegen/types.js +94 -41
  27. package/cli/codegen/utils.d.ts +20 -2
  28. package/cli/codegen/utils.js +32 -7
  29. package/cli/commands/generate-orm.js +5 -5
  30. package/cli/commands/generate.d.ts +4 -1
  31. package/cli/commands/generate.js +27 -8
  32. package/cli/introspect/transform-schema.d.ts +33 -21
  33. package/cli/introspect/transform-schema.js +31 -21
  34. package/esm/cli/codegen/barrel.d.ts +4 -1
  35. package/esm/cli/codegen/barrel.js +18 -12
  36. package/esm/cli/codegen/client.js +33 -0
  37. package/esm/cli/codegen/custom-mutations.d.ts +4 -0
  38. package/esm/cli/codegen/custom-mutations.js +40 -14
  39. package/esm/cli/codegen/custom-queries.d.ts +4 -0
  40. package/esm/cli/codegen/custom-queries.js +37 -12
  41. package/esm/cli/codegen/gql-ast.js +10 -6
  42. package/esm/cli/codegen/index.js +35 -7
  43. package/esm/cli/codegen/mutations.d.ts +2 -0
  44. package/esm/cli/codegen/mutations.js +88 -24
  45. package/esm/cli/codegen/orm/barrel.js +4 -2
  46. package/esm/cli/codegen/orm/index.js +17 -0
  47. package/esm/cli/codegen/orm/input-types-generator.js +83 -29
  48. package/esm/cli/codegen/orm/model-generator.js +7 -5
  49. package/esm/cli/codegen/queries.js +37 -28
  50. package/esm/cli/codegen/scalars.d.ts +6 -4
  51. package/esm/cli/codegen/scalars.js +16 -8
  52. package/esm/cli/codegen/schema-types-generator.d.ts +26 -0
  53. package/esm/cli/codegen/schema-types-generator.js +362 -0
  54. package/esm/cli/codegen/ts-ast.d.ts +3 -1
  55. package/esm/cli/codegen/ts-ast.js +2 -2
  56. package/esm/cli/codegen/type-resolver.d.ts +52 -6
  57. package/esm/cli/codegen/type-resolver.js +97 -20
  58. package/esm/cli/codegen/types.d.ts +7 -4
  59. package/esm/cli/codegen/types.js +95 -41
  60. package/esm/cli/codegen/utils.d.ts +20 -2
  61. package/esm/cli/codegen/utils.js +31 -7
  62. package/esm/cli/commands/generate-orm.js +5 -5
  63. package/esm/cli/commands/generate.d.ts +4 -1
  64. package/esm/cli/commands/generate.js +27 -8
  65. package/esm/cli/introspect/transform-schema.d.ts +33 -21
  66. package/esm/cli/introspect/transform-schema.js +31 -21
  67. package/esm/types/schema.d.ts +2 -0
  68. package/package.json +8 -6
  69. package/types/schema.d.ts +2 -0
  70. package/__tests__/codegen/input-types-generator.test.d.ts +0 -1
  71. package/__tests__/codegen/input-types-generator.test.js +0 -635
  72. package/__tests__/codegen/react-query-optional.test.d.ts +0 -1
  73. package/__tests__/codegen/react-query-optional.test.js +0 -292
  74. package/cli/codegen/filters.d.ts +0 -27
  75. package/cli/codegen/filters.js +0 -357
  76. package/cli/codegen/orm/input-types-generator.test.d.ts +0 -1
  77. package/cli/codegen/orm/input-types-generator.test.js +0 -75
  78. package/cli/codegen/orm/select-types.test.d.ts +0 -11
  79. package/cli/codegen/orm/select-types.test.js +0 -22
  80. package/cli/introspect/transform-schema.test.d.ts +0 -1
  81. package/cli/introspect/transform-schema.test.js +0 -67
  82. package/esm/__tests__/codegen/input-types-generator.test.d.ts +0 -1
  83. package/esm/__tests__/codegen/input-types-generator.test.js +0 -633
  84. package/esm/__tests__/codegen/react-query-optional.test.d.ts +0 -1
  85. package/esm/__tests__/codegen/react-query-optional.test.js +0 -290
  86. package/esm/cli/codegen/filters.d.ts +0 -27
  87. package/esm/cli/codegen/filters.js +0 -351
  88. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +0 -1
  89. package/esm/cli/codegen/orm/input-types-generator.test.js +0 -73
  90. package/esm/cli/codegen/orm/select-types.test.d.ts +0 -11
  91. package/esm/cli/codegen/orm/select-types.test.js +0 -21
  92. package/esm/cli/introspect/transform-schema.test.d.ts +0 -1
  93. package/esm/cli/introspect/transform-schema.test.js +0 -65
@@ -1,290 +0,0 @@
1
- /**
2
- * Tests for React Query optional flag in code generators
3
- *
4
- * Verifies that when reactQueryEnabled is false:
5
- * - Query generators skip React Query imports and hooks
6
- * - Mutation generators return null (since they require React Query)
7
- * - Standalone fetch functions are still generated for queries
8
- */
9
- import { generateListQueryHook, generateSingleQueryHook, generateAllQueryHooks } from '../../cli/codegen/queries';
10
- import { generateCreateMutationHook, generateUpdateMutationHook, generateDeleteMutationHook, generateAllMutationHooks } from '../../cli/codegen/mutations';
11
- import { generateCustomQueryHook, generateAllCustomQueryHooks } from '../../cli/codegen/custom-queries';
12
- import { generateCustomMutationHook, generateAllCustomMutationHooks } from '../../cli/codegen/custom-mutations';
13
- // ============================================================================
14
- // Test Fixtures
15
- // ============================================================================
16
- const fieldTypes = {
17
- uuid: { gqlType: 'UUID', isArray: false },
18
- string: { gqlType: 'String', isArray: false },
19
- int: { gqlType: 'Int', isArray: false },
20
- datetime: { gqlType: 'Datetime', isArray: false },
21
- };
22
- const emptyRelations = {
23
- belongsTo: [],
24
- hasOne: [],
25
- hasMany: [],
26
- manyToMany: [],
27
- };
28
- function createTable(partial) {
29
- return {
30
- name: partial.name,
31
- fields: partial.fields ?? [],
32
- relations: partial.relations ?? emptyRelations,
33
- query: partial.query,
34
- inflection: partial.inflection,
35
- constraints: partial.constraints,
36
- };
37
- }
38
- const userTable = createTable({
39
- name: 'User',
40
- fields: [
41
- { name: 'id', type: fieldTypes.uuid },
42
- { name: 'email', type: fieldTypes.string },
43
- { name: 'name', type: fieldTypes.string },
44
- { name: 'createdAt', type: fieldTypes.datetime },
45
- ],
46
- query: {
47
- all: 'users',
48
- one: 'user',
49
- create: 'createUser',
50
- update: 'updateUser',
51
- delete: 'deleteUser',
52
- },
53
- });
54
- function createTypeRef(kind, name, ofType) {
55
- return { kind, name, ofType };
56
- }
57
- const sampleQueryOperation = {
58
- name: 'currentUser',
59
- kind: 'query',
60
- args: [],
61
- returnType: createTypeRef('OBJECT', 'User'),
62
- description: 'Get the current authenticated user',
63
- };
64
- const sampleMutationOperation = {
65
- name: 'login',
66
- kind: 'mutation',
67
- args: [
68
- { name: 'email', type: createTypeRef('NON_NULL', null, createTypeRef('SCALAR', 'String')) },
69
- { name: 'password', type: createTypeRef('NON_NULL', null, createTypeRef('SCALAR', 'String')) },
70
- ],
71
- returnType: createTypeRef('OBJECT', 'LoginPayload'),
72
- description: 'Authenticate user',
73
- };
74
- const emptyTypeRegistry = new Map();
75
- // ============================================================================
76
- // Tests - Query Generators with reactQueryEnabled: false
77
- // ============================================================================
78
- describe('Query generators with reactQueryEnabled: false', () => {
79
- describe('generateListQueryHook', () => {
80
- it('should not include React Query imports when disabled', () => {
81
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
82
- expect(result.content).not.toContain('@tanstack/react-query');
83
- expect(result.content).not.toContain('useQuery');
84
- expect(result.content).not.toContain('UseQueryOptions');
85
- });
86
- it('should not include useXxxQuery hook when disabled', () => {
87
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
88
- expect(result.content).not.toContain('export function useUsersQuery');
89
- });
90
- it('should not include prefetch function when disabled', () => {
91
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
92
- expect(result.content).not.toContain('export async function prefetchUsersQuery');
93
- });
94
- it('should still include standalone fetch function when disabled', () => {
95
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
96
- expect(result.content).toContain('export async function fetchUsersQuery');
97
- });
98
- it('should still include GraphQL document when disabled', () => {
99
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
100
- expect(result.content).toContain('usersQueryDocument');
101
- });
102
- it('should still include query key factory when disabled', () => {
103
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
104
- expect(result.content).toContain('usersQueryKey');
105
- });
106
- it('should update file header when disabled', () => {
107
- const result = generateListQueryHook(userTable, { reactQueryEnabled: false });
108
- expect(result.content).toContain('List query functions for User');
109
- });
110
- });
111
- describe('generateSingleQueryHook', () => {
112
- it('should not include React Query imports when disabled', () => {
113
- const result = generateSingleQueryHook(userTable, { reactQueryEnabled: false });
114
- expect(result.content).not.toContain('@tanstack/react-query');
115
- expect(result.content).not.toContain('useQuery');
116
- });
117
- it('should not include useXxxQuery hook when disabled', () => {
118
- const result = generateSingleQueryHook(userTable, { reactQueryEnabled: false });
119
- expect(result.content).not.toContain('export function useUserQuery');
120
- });
121
- it('should still include standalone fetch function when disabled', () => {
122
- const result = generateSingleQueryHook(userTable, { reactQueryEnabled: false });
123
- expect(result.content).toContain('export async function fetchUserQuery');
124
- });
125
- });
126
- describe('generateAllQueryHooks', () => {
127
- it('should generate files without React Query when disabled', () => {
128
- const results = generateAllQueryHooks([userTable], { reactQueryEnabled: false });
129
- expect(results.length).toBe(2); // list + single
130
- for (const result of results) {
131
- expect(result.content).not.toContain('@tanstack/react-query');
132
- expect(result.content).not.toContain('useQuery');
133
- }
134
- });
135
- });
136
- });
137
- // ============================================================================
138
- // Tests - Query Generators with reactQueryEnabled: true (default)
139
- // ============================================================================
140
- describe('Query generators with reactQueryEnabled: true (default)', () => {
141
- describe('generateListQueryHook', () => {
142
- it('should include React Query imports by default', () => {
143
- const result = generateListQueryHook(userTable);
144
- expect(result.content).toContain('@tanstack/react-query');
145
- expect(result.content).toContain('useQuery');
146
- });
147
- it('should include useXxxQuery hook by default', () => {
148
- const result = generateListQueryHook(userTable);
149
- expect(result.content).toContain('export function useUsersQuery');
150
- });
151
- it('should include prefetch function by default', () => {
152
- const result = generateListQueryHook(userTable);
153
- expect(result.content).toContain('export async function prefetchUsersQuery');
154
- });
155
- it('should include standalone fetch function by default', () => {
156
- const result = generateListQueryHook(userTable);
157
- expect(result.content).toContain('export async function fetchUsersQuery');
158
- });
159
- });
160
- });
161
- // ============================================================================
162
- // Tests - Mutation Generators with reactQueryEnabled: false
163
- // ============================================================================
164
- describe('Mutation generators with reactQueryEnabled: false', () => {
165
- describe('generateCreateMutationHook', () => {
166
- it('should return null when disabled', () => {
167
- const result = generateCreateMutationHook(userTable, { reactQueryEnabled: false });
168
- expect(result).toBeNull();
169
- });
170
- });
171
- describe('generateUpdateMutationHook', () => {
172
- it('should return null when disabled', () => {
173
- const result = generateUpdateMutationHook(userTable, { reactQueryEnabled: false });
174
- expect(result).toBeNull();
175
- });
176
- });
177
- describe('generateDeleteMutationHook', () => {
178
- it('should return null when disabled', () => {
179
- const result = generateDeleteMutationHook(userTable, { reactQueryEnabled: false });
180
- expect(result).toBeNull();
181
- });
182
- });
183
- describe('generateAllMutationHooks', () => {
184
- it('should return empty array when disabled', () => {
185
- const results = generateAllMutationHooks([userTable], { reactQueryEnabled: false });
186
- expect(results).toEqual([]);
187
- });
188
- });
189
- });
190
- // ============================================================================
191
- // Tests - Mutation Generators with reactQueryEnabled: true (default)
192
- // ============================================================================
193
- describe('Mutation generators with reactQueryEnabled: true (default)', () => {
194
- describe('generateCreateMutationHook', () => {
195
- it('should return mutation file by default', () => {
196
- const result = generateCreateMutationHook(userTable);
197
- expect(result).not.toBeNull();
198
- expect(result.content).toContain('useMutation');
199
- });
200
- });
201
- describe('generateAllMutationHooks', () => {
202
- it('should return mutation files by default', () => {
203
- const results = generateAllMutationHooks([userTable]);
204
- expect(results.length).toBeGreaterThan(0);
205
- });
206
- });
207
- });
208
- // ============================================================================
209
- // Tests - Custom Query Generators with reactQueryEnabled: false
210
- // ============================================================================
211
- describe('Custom query generators with reactQueryEnabled: false', () => {
212
- describe('generateCustomQueryHook', () => {
213
- it('should not include React Query imports when disabled', () => {
214
- const result = generateCustomQueryHook({
215
- operation: sampleQueryOperation,
216
- typeRegistry: emptyTypeRegistry,
217
- reactQueryEnabled: false,
218
- });
219
- expect(result.content).not.toContain('@tanstack/react-query');
220
- expect(result.content).not.toContain('useQuery');
221
- });
222
- it('should not include useXxxQuery hook when disabled', () => {
223
- const result = generateCustomQueryHook({
224
- operation: sampleQueryOperation,
225
- typeRegistry: emptyTypeRegistry,
226
- reactQueryEnabled: false,
227
- });
228
- expect(result.content).not.toContain('export function useCurrentUserQuery');
229
- });
230
- it('should still include standalone fetch function when disabled', () => {
231
- const result = generateCustomQueryHook({
232
- operation: sampleQueryOperation,
233
- typeRegistry: emptyTypeRegistry,
234
- reactQueryEnabled: false,
235
- });
236
- expect(result.content).toContain('export async function fetchCurrentUserQuery');
237
- });
238
- });
239
- describe('generateAllCustomQueryHooks', () => {
240
- it('should generate files without React Query when disabled', () => {
241
- const results = generateAllCustomQueryHooks({
242
- operations: [sampleQueryOperation],
243
- typeRegistry: emptyTypeRegistry,
244
- reactQueryEnabled: false,
245
- });
246
- expect(results.length).toBe(1);
247
- expect(results[0].content).not.toContain('@tanstack/react-query');
248
- });
249
- });
250
- });
251
- // ============================================================================
252
- // Tests - Custom Mutation Generators with reactQueryEnabled: false
253
- // ============================================================================
254
- describe('Custom mutation generators with reactQueryEnabled: false', () => {
255
- describe('generateCustomMutationHook', () => {
256
- it('should return null when disabled', () => {
257
- const result = generateCustomMutationHook({
258
- operation: sampleMutationOperation,
259
- typeRegistry: emptyTypeRegistry,
260
- reactQueryEnabled: false,
261
- });
262
- expect(result).toBeNull();
263
- });
264
- });
265
- describe('generateAllCustomMutationHooks', () => {
266
- it('should return empty array when disabled', () => {
267
- const results = generateAllCustomMutationHooks({
268
- operations: [sampleMutationOperation],
269
- typeRegistry: emptyTypeRegistry,
270
- reactQueryEnabled: false,
271
- });
272
- expect(results).toEqual([]);
273
- });
274
- });
275
- });
276
- // ============================================================================
277
- // Tests - Custom Mutation Generators with reactQueryEnabled: true (default)
278
- // ============================================================================
279
- describe('Custom mutation generators with reactQueryEnabled: true (default)', () => {
280
- describe('generateCustomMutationHook', () => {
281
- it('should return mutation file by default', () => {
282
- const result = generateCustomMutationHook({
283
- operation: sampleMutationOperation,
284
- typeRegistry: emptyTypeRegistry,
285
- });
286
- expect(result).not.toBeNull();
287
- expect(result.content).toContain('useMutation');
288
- });
289
- });
290
- });
@@ -1,27 +0,0 @@
1
- /**
2
- * PostGraphile filter type generators
3
- *
4
- * Generates TypeScript interfaces for PostGraphile filter types:
5
- * - Base scalar filters (StringFilter, IntFilter, etc.)
6
- * - Table-specific filters (CarFilter, UserFilter, etc.)
7
- * - OrderBy enum types
8
- */
9
- import type { CleanTable } from '../../types/schema';
10
- /**
11
- * Generate all base PostGraphile filter types
12
- * These are shared across all tables
13
- */
14
- export declare function generateBaseFilterTypes(): string;
15
- /**
16
- * Generate filter interface for a specific table
17
- */
18
- export declare function generateTableFilter(table: CleanTable): string;
19
- /**
20
- * Generate OrderBy type for a specific table
21
- */
22
- export declare function generateTableOrderBy(table: CleanTable): string;
23
- /**
24
- * Generate inline filter and orderBy types for a query hook file
25
- * These are embedded directly in the hook file for self-containment
26
- */
27
- export declare function generateInlineFilterTypes(table: CleanTable): string;
@@ -1,351 +0,0 @@
1
- import { getFilterTypeName, getOrderByTypeName, getScalarFilterType, getScalarFields, toScreamingSnake, getGeneratedFileHeader, } from './utils';
2
- // ============================================================================
3
- // Base filter type definitions
4
- // ============================================================================
5
- /**
6
- * Generate all base PostGraphile filter types
7
- * These are shared across all tables
8
- */
9
- export function generateBaseFilterTypes() {
10
- return `${getGeneratedFileHeader('PostGraphile base filter types')}
11
-
12
- // ============================================================================
13
- // String filters
14
- // ============================================================================
15
-
16
- export interface StringFilter {
17
- isNull?: boolean;
18
- equalTo?: string;
19
- notEqualTo?: string;
20
- distinctFrom?: string;
21
- notDistinctFrom?: string;
22
- in?: string[];
23
- notIn?: string[];
24
- lessThan?: string;
25
- lessThanOrEqualTo?: string;
26
- greaterThan?: string;
27
- greaterThanOrEqualTo?: string;
28
- includes?: string;
29
- notIncludes?: string;
30
- includesInsensitive?: string;
31
- notIncludesInsensitive?: string;
32
- startsWith?: string;
33
- notStartsWith?: string;
34
- startsWithInsensitive?: string;
35
- notStartsWithInsensitive?: string;
36
- endsWith?: string;
37
- notEndsWith?: string;
38
- endsWithInsensitive?: string;
39
- notEndsWithInsensitive?: string;
40
- like?: string;
41
- notLike?: string;
42
- likeInsensitive?: string;
43
- notLikeInsensitive?: string;
44
- }
45
-
46
- export interface StringListFilter {
47
- isNull?: boolean;
48
- equalTo?: string[];
49
- notEqualTo?: string[];
50
- distinctFrom?: string[];
51
- notDistinctFrom?: string[];
52
- lessThan?: string[];
53
- lessThanOrEqualTo?: string[];
54
- greaterThan?: string[];
55
- greaterThanOrEqualTo?: string[];
56
- contains?: string[];
57
- containedBy?: string[];
58
- overlaps?: string[];
59
- anyEqualTo?: string;
60
- anyNotEqualTo?: string;
61
- anyLessThan?: string;
62
- anyLessThanOrEqualTo?: string;
63
- anyGreaterThan?: string;
64
- anyGreaterThanOrEqualTo?: string;
65
- }
66
-
67
- // ============================================================================
68
- // Numeric filters
69
- // ============================================================================
70
-
71
- export interface IntFilter {
72
- isNull?: boolean;
73
- equalTo?: number;
74
- notEqualTo?: number;
75
- distinctFrom?: number;
76
- notDistinctFrom?: number;
77
- in?: number[];
78
- notIn?: number[];
79
- lessThan?: number;
80
- lessThanOrEqualTo?: number;
81
- greaterThan?: number;
82
- greaterThanOrEqualTo?: number;
83
- }
84
-
85
- export interface IntListFilter {
86
- isNull?: boolean;
87
- equalTo?: number[];
88
- notEqualTo?: number[];
89
- distinctFrom?: number[];
90
- notDistinctFrom?: number[];
91
- lessThan?: number[];
92
- lessThanOrEqualTo?: number[];
93
- greaterThan?: number[];
94
- greaterThanOrEqualTo?: number[];
95
- contains?: number[];
96
- containedBy?: number[];
97
- overlaps?: number[];
98
- anyEqualTo?: number;
99
- anyNotEqualTo?: number;
100
- anyLessThan?: number;
101
- anyLessThanOrEqualTo?: number;
102
- anyGreaterThan?: number;
103
- anyGreaterThanOrEqualTo?: number;
104
- }
105
-
106
- export interface FloatFilter {
107
- isNull?: boolean;
108
- equalTo?: number;
109
- notEqualTo?: number;
110
- distinctFrom?: number;
111
- notDistinctFrom?: number;
112
- in?: number[];
113
- notIn?: number[];
114
- lessThan?: number;
115
- lessThanOrEqualTo?: number;
116
- greaterThan?: number;
117
- greaterThanOrEqualTo?: number;
118
- }
119
-
120
- export interface BigIntFilter {
121
- isNull?: boolean;
122
- equalTo?: string;
123
- notEqualTo?: string;
124
- distinctFrom?: string;
125
- notDistinctFrom?: string;
126
- in?: string[];
127
- notIn?: string[];
128
- lessThan?: string;
129
- lessThanOrEqualTo?: string;
130
- greaterThan?: string;
131
- greaterThanOrEqualTo?: string;
132
- }
133
-
134
- export interface BigFloatFilter {
135
- isNull?: boolean;
136
- equalTo?: string;
137
- notEqualTo?: string;
138
- distinctFrom?: string;
139
- notDistinctFrom?: string;
140
- in?: string[];
141
- notIn?: string[];
142
- lessThan?: string;
143
- lessThanOrEqualTo?: string;
144
- greaterThan?: string;
145
- greaterThanOrEqualTo?: string;
146
- }
147
-
148
- // ============================================================================
149
- // Boolean filter
150
- // ============================================================================
151
-
152
- export interface BooleanFilter {
153
- isNull?: boolean;
154
- equalTo?: boolean;
155
- notEqualTo?: boolean;
156
- distinctFrom?: boolean;
157
- notDistinctFrom?: boolean;
158
- in?: boolean[];
159
- notIn?: boolean[];
160
- }
161
-
162
- // ============================================================================
163
- // UUID filter
164
- // ============================================================================
165
-
166
- export interface UUIDFilter {
167
- isNull?: boolean;
168
- equalTo?: string;
169
- notEqualTo?: string;
170
- distinctFrom?: string;
171
- notDistinctFrom?: string;
172
- in?: string[];
173
- notIn?: string[];
174
- lessThan?: string;
175
- lessThanOrEqualTo?: string;
176
- greaterThan?: string;
177
- greaterThanOrEqualTo?: string;
178
- }
179
-
180
- export interface UUIDListFilter {
181
- isNull?: boolean;
182
- equalTo?: string[];
183
- notEqualTo?: string[];
184
- distinctFrom?: string[];
185
- notDistinctFrom?: string[];
186
- lessThan?: string[];
187
- lessThanOrEqualTo?: string[];
188
- greaterThan?: string[];
189
- greaterThanOrEqualTo?: string[];
190
- contains?: string[];
191
- containedBy?: string[];
192
- overlaps?: string[];
193
- anyEqualTo?: string;
194
- anyNotEqualTo?: string;
195
- anyLessThan?: string;
196
- anyLessThanOrEqualTo?: string;
197
- anyGreaterThan?: string;
198
- anyGreaterThanOrEqualTo?: string;
199
- }
200
-
201
- // ============================================================================
202
- // Date/Time filters
203
- // ============================================================================
204
-
205
- export interface DatetimeFilter {
206
- isNull?: boolean;
207
- equalTo?: string;
208
- notEqualTo?: string;
209
- distinctFrom?: string;
210
- notDistinctFrom?: string;
211
- in?: string[];
212
- notIn?: string[];
213
- lessThan?: string;
214
- lessThanOrEqualTo?: string;
215
- greaterThan?: string;
216
- greaterThanOrEqualTo?: string;
217
- }
218
-
219
- export interface DateFilter {
220
- isNull?: boolean;
221
- equalTo?: string;
222
- notEqualTo?: string;
223
- distinctFrom?: string;
224
- notDistinctFrom?: string;
225
- in?: string[];
226
- notIn?: string[];
227
- lessThan?: string;
228
- lessThanOrEqualTo?: string;
229
- greaterThan?: string;
230
- greaterThanOrEqualTo?: string;
231
- }
232
-
233
- export interface TimeFilter {
234
- isNull?: boolean;
235
- equalTo?: string;
236
- notEqualTo?: string;
237
- distinctFrom?: string;
238
- notDistinctFrom?: string;
239
- in?: string[];
240
- notIn?: string[];
241
- lessThan?: string;
242
- lessThanOrEqualTo?: string;
243
- greaterThan?: string;
244
- greaterThanOrEqualTo?: string;
245
- }
246
-
247
- // ============================================================================
248
- // JSON filter
249
- // ============================================================================
250
-
251
- export interface JSONFilter {
252
- isNull?: boolean;
253
- equalTo?: unknown;
254
- notEqualTo?: unknown;
255
- distinctFrom?: unknown;
256
- notDistinctFrom?: unknown;
257
- in?: unknown[];
258
- notIn?: unknown[];
259
- contains?: unknown;
260
- containedBy?: unknown;
261
- containsKey?: string;
262
- containsAllKeys?: string[];
263
- containsAnyKeys?: string[];
264
- }
265
- `;
266
- }
267
- // ============================================================================
268
- // Table-specific filter generators
269
- // ============================================================================
270
- /**
271
- * Generate filter interface for a specific table
272
- */
273
- export function generateTableFilter(table) {
274
- const filterTypeName = getFilterTypeName(table);
275
- const scalarFields = getScalarFields(table);
276
- const fieldFilters = scalarFields
277
- .map((field) => {
278
- const filterType = getFieldFilterType(field);
279
- if (!filterType)
280
- return null;
281
- return ` ${field.name}?: ${filterType};`;
282
- })
283
- .filter(Boolean)
284
- .join('\n');
285
- return `export interface ${filterTypeName} {
286
- ${fieldFilters}
287
- /** Logical AND */
288
- and?: ${filterTypeName}[];
289
- /** Logical OR */
290
- or?: ${filterTypeName}[];
291
- /** Logical NOT */
292
- not?: ${filterTypeName};
293
- }`;
294
- }
295
- /**
296
- * Get the filter type for a specific field
297
- */
298
- function getFieldFilterType(field) {
299
- const { gqlType, isArray } = field.type;
300
- // Handle array types
301
- if (isArray) {
302
- const cleanType = gqlType.replace(/!/g, '');
303
- switch (cleanType) {
304
- case 'String':
305
- return 'StringListFilter';
306
- case 'Int':
307
- return 'IntListFilter';
308
- case 'UUID':
309
- return 'UUIDListFilter';
310
- default:
311
- return null;
312
- }
313
- }
314
- return getScalarFilterType(gqlType);
315
- }
316
- // ============================================================================
317
- // OrderBy enum generators
318
- // ============================================================================
319
- /**
320
- * Generate OrderBy type for a specific table
321
- */
322
- export function generateTableOrderBy(table) {
323
- const orderByTypeName = getOrderByTypeName(table);
324
- const scalarFields = getScalarFields(table);
325
- const fieldOrderBys = scalarFields.flatMap((field) => {
326
- const screamingName = toScreamingSnake(field.name);
327
- return [`'${screamingName}_ASC'`, `'${screamingName}_DESC'`];
328
- });
329
- // Add standard PostGraphile order options
330
- const standardOrderBys = [
331
- "'NATURAL'",
332
- "'PRIMARY_KEY_ASC'",
333
- "'PRIMARY_KEY_DESC'",
334
- ];
335
- const allOrderBys = [...fieldOrderBys, ...standardOrderBys];
336
- return `export type ${orderByTypeName} = ${allOrderBys.join(' | ')};`;
337
- }
338
- // ============================================================================
339
- // Combined generators for hook files
340
- // ============================================================================
341
- /**
342
- * Generate inline filter and orderBy types for a query hook file
343
- * These are embedded directly in the hook file for self-containment
344
- */
345
- export function generateInlineFilterTypes(table) {
346
- const filterDef = generateTableFilter(table);
347
- const orderByDef = generateTableOrderBy(table);
348
- return `${filterDef}
349
-
350
- ${orderByDef}`;
351
- }
@@ -1 +0,0 @@
1
- export {};