@constructive-io/graphql-query 3.6.7 → 3.8.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.
package/custom-ast.d.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  import type { FieldNode } from 'graphql';
2
- import type { CleanField } from './types/schema';
2
+ import type { Field } from './types/schema';
3
3
  import type { MetaField } from './types';
4
4
  /**
5
5
  * Get custom AST for MetaField type - handles PostgreSQL types that need subfield selections
6
6
  */
7
7
  export declare function getCustomAst(fieldDefn?: MetaField): FieldNode | null;
8
8
  /**
9
- * Generate custom AST for CleanField type - handles GraphQL types that need subfield selections
9
+ * Generate custom AST for Field type - handles GraphQL types that need subfield selections
10
10
  */
11
- export declare function getCustomAstForCleanField(field: CleanField): FieldNode;
11
+ export declare function getCustomAstForCleanField(field: Field): FieldNode;
12
12
  /**
13
- * Check if a CleanField requires subfield selection based on its GraphQL type
13
+ * Check if a Field requires subfield selection based on its GraphQL type
14
14
  */
15
- export declare function requiresSubfieldSelection(field: CleanField): boolean;
15
+ export declare function requiresSubfieldSelection(field: Field): boolean;
16
16
  /**
17
17
  * Generate AST for GeometryPoint type
18
18
  */
package/custom-ast.js CHANGED
@@ -62,7 +62,7 @@ function getCustomAst(fieldDefn) {
62
62
  });
63
63
  }
64
64
  /**
65
- * Generate custom AST for CleanField type - handles GraphQL types that need subfield selections
65
+ * Generate custom AST for Field type - handles GraphQL types that need subfield selections
66
66
  */
67
67
  function getCustomAstForCleanField(field) {
68
68
  const { name, type } = field;
@@ -90,7 +90,7 @@ function getCustomAstForCleanField(field) {
90
90
  });
91
91
  }
92
92
  /**
93
- * Check if a CleanField requires subfield selection based on its GraphQL type
93
+ * Check if a Field requires subfield selection based on its GraphQL type
94
94
  */
95
95
  function requiresSubfieldSelection(field) {
96
96
  const { gqlType } = field.type;
package/esm/custom-ast.js CHANGED
@@ -19,7 +19,7 @@ export function getCustomAst(fieldDefn) {
19
19
  });
20
20
  }
21
21
  /**
22
- * Generate custom AST for CleanField type - handles GraphQL types that need subfield selections
22
+ * Generate custom AST for Field type - handles GraphQL types that need subfield selections
23
23
  */
24
24
  export function getCustomAstForCleanField(field) {
25
25
  const { name, type } = field;
@@ -47,7 +47,7 @@ export function getCustomAstForCleanField(field) {
47
47
  });
48
48
  }
49
49
  /**
50
- * Check if a CleanField requires subfield selection based on its GraphQL type
50
+ * Check if a Field requires subfield selection based on its GraphQL type
51
51
  */
52
52
  export function requiresSubfieldSelection(field) {
53
53
  const { gqlType } = field.type;
@@ -12,7 +12,7 @@ import { normalizeInflectionValue, toCamelCasePlural, toCamelCaseSingular, toCre
12
12
  // Re-export naming helpers for backwards compatibility
13
13
  export { toCamelCasePlural, toOrderByTypeName } from './naming-helpers';
14
14
  /**
15
- * Convert CleanTable to MetaObject format for QueryBuilder
15
+ * Convert Table to MetaObject format for QueryBuilder
16
16
  */
17
17
  export function cleanTableToMetaObject(tables) {
18
18
  return {
@@ -64,7 +64,7 @@ export function cleanTableToMetaObject(tables) {
64
64
  };
65
65
  }
66
66
  /**
67
- * Generate basic IntrospectionSchema from CleanTable array
67
+ * Generate basic IntrospectionSchema from Table array
68
68
  * This creates a minimal schema for AST generation
69
69
  */
70
70
  export function generateIntrospectionSchema(tables) {
@@ -178,7 +178,7 @@ export function generateIntrospectionSchema(tables) {
178
178
  return schema;
179
179
  }
180
180
  /**
181
- * Convert CleanTable fields to QueryBuilder properties
181
+ * Convert Table fields to QueryBuilder properties
182
182
  */
183
183
  function convertFieldsToProperties(fields) {
184
184
  const properties = {};
@@ -249,7 +249,7 @@ function convertFieldSelectionToSelectionOptions(table, allTables, options) {
249
249
  return convertToSelectionOptions(table, allTables, options);
250
250
  }
251
251
  /**
252
- * Generate SELECT query AST directly from CleanTable
252
+ * Generate SELECT query AST directly from Table
253
253
  */
254
254
  function generateSelectQueryAST(table, allTables, selection, options, relationFieldMap) {
255
255
  const pluralName = toCamelCasePlural(table.name, table);
@@ -571,7 +571,7 @@ function findRelatedTable(relationField, table, allTables) {
571
571
  return allTables.find((tbl) => tbl.name === referencedTableName) || null;
572
572
  }
573
573
  /**
574
- * Generate FindOne query AST directly from CleanTable
574
+ * Generate FindOne query AST directly from Table
575
575
  */
576
576
  function generateFindOneQueryAST(table) {
577
577
  const singularName = toCamelCaseSingular(table.name, table);
@@ -623,7 +623,7 @@ function generateFindOneQueryAST(table) {
623
623
  return print(ast);
624
624
  }
625
625
  /**
626
- * Generate Count query AST directly from CleanTable
626
+ * Generate Count query AST directly from Table
627
627
  */
628
628
  function generateCountQueryAST(table) {
629
629
  const pluralName = toCamelCasePlural(table.name, table);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Introspection barrel export
3
3
  *
4
- * Re-exports introspection utilities for converting GraphQL schemas to CleanTable format.
4
+ * Re-exports introspection utilities for converting GraphQL schemas to Table format.
5
5
  */
6
6
  export * from './infer-tables';
7
7
  export * from './transform';
@@ -73,11 +73,11 @@ function isInternalType(name) {
73
73
  return name.startsWith('__');
74
74
  }
75
75
  /**
76
- * Infer CleanTable[] from GraphQL introspection by recognizing PostGraphile patterns
76
+ * Infer Table[] from GraphQL introspection by recognizing PostGraphile patterns
77
77
  *
78
78
  * @param introspection - Standard GraphQL introspection response
79
79
  * @param options - Optional configuration
80
- * @returns Array of CleanTable objects compatible with existing generators
80
+ * @returns Array of Table objects compatible with existing generators
81
81
  */
82
82
  export function inferTablesFromIntrospection(introspection, options = {}) {
83
83
  const { __schema: schema } = introspection;
@@ -90,7 +90,7 @@ export function inferTablesFromIntrospection(introspection, options = {}) {
90
90
  const mutationFields = mutationType
91
91
  ? getTypeFields(typeMap.get(mutationType.name))
92
92
  : [];
93
- // Step 1: Build CleanTable for each inferred entity
93
+ // Step 1: Build Table for each inferred entity
94
94
  const tables = [];
95
95
  for (const entityName of entityNames) {
96
96
  const entityType = typeMap.get(entityName);
@@ -169,7 +169,7 @@ function resolveEntityNameFromConnectionType(connectionType, typeMap) {
169
169
  return nodeTypeName;
170
170
  }
171
171
  /**
172
- * Build a complete CleanTable from an entity type
172
+ * Build a complete Table from an entity type
173
173
  */
174
174
  function buildCleanTable(entityName, entityType, typeMap, queryFields, mutationFields, entityToConnection, connectionToEntity, commentsEnabled) {
175
175
  // Extract scalar fields from entity type
@@ -300,7 +300,7 @@ function isEntityType(typeName, entityToConnection) {
300
300
  return entityToConnection.has(typeName);
301
301
  }
302
302
  /**
303
- * Convert IntrospectionTypeRef to CleanFieldType
303
+ * Convert IntrospectionTypeRef to FieldType
304
304
  */
305
305
  function convertToCleanFieldType(typeRef) {
306
306
  const baseType = unwrapType(typeRef);
@@ -31,6 +31,7 @@ query IntrospectSchema {
31
31
  kind
32
32
  name
33
33
  description
34
+ isOneOf
34
35
  fields(includeDeprecated: true) {
35
36
  name
36
37
  description
@@ -46,12 +46,16 @@ export function buildTypeRegistry(types) {
46
46
  // Resolve input fields for INPUT_OBJECT types
47
47
  if (type.kind === 'INPUT_OBJECT' && type.inputFields) {
48
48
  resolvedType.inputFields = type.inputFields.map((field) => transformInputValueToCleanArgumentShallow(field));
49
+ // Detect @oneOf directive (GraphQL 16+ discriminated union inputs)
50
+ if (type.isOneOf) {
51
+ resolvedType.isOneOf = true;
52
+ }
49
53
  }
50
54
  }
51
55
  return registry;
52
56
  }
53
57
  /**
54
- * Transform field to CleanObjectField without resolving nested types
58
+ * Transform field to ObjectField without resolving nested types
55
59
  * (shallow transformation to avoid circular refs)
56
60
  */
57
61
  function transformFieldToCleanObjectFieldShallow(field) {
@@ -62,7 +66,7 @@ function transformFieldToCleanObjectFieldShallow(field) {
62
66
  };
63
67
  }
64
68
  /**
65
- * Transform input value to CleanArgument without resolving nested types
69
+ * Transform input value to Argument without resolving nested types
66
70
  */
67
71
  function transformInputValueToCleanArgumentShallow(inputValue) {
68
72
  return {
@@ -113,7 +117,7 @@ export function transformSchemaToOperations(response) {
113
117
  // Field to Operation Transformation
114
118
  // ============================================================================
115
119
  /**
116
- * Transform an introspection field to a CleanOperation
120
+ * Transform an introspection field to a Operation
117
121
  */
118
122
  function transformFieldToCleanOperation(field, kind, types) {
119
123
  return {
@@ -127,7 +131,7 @@ function transformFieldToCleanOperation(field, kind, types) {
127
131
  };
128
132
  }
129
133
  /**
130
- * Transform an input value to CleanArgument
134
+ * Transform an input value to Argument
131
135
  */
132
136
  function transformInputValueToCleanArgument(inputValue, types) {
133
137
  return {
@@ -141,7 +145,7 @@ function transformInputValueToCleanArgument(inputValue, types) {
141
145
  // Type Reference Transformation
142
146
  // ============================================================================
143
147
  /**
144
- * Transform an introspection TypeRef to CleanTypeRef
148
+ * Transform an introspection TypeRef to TypeRef
145
149
  * Recursively handles wrapper types (LIST, NON_NULL)
146
150
  *
147
151
  * NOTE: We intentionally do NOT resolve nested fields here to avoid
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Get table names from CleanTable array
2
+ * Get table names from Table array
3
3
  */
4
4
  export function getTableNames(tables) {
5
5
  return tables.map((t) => t.name);
@@ -6,7 +6,7 @@
6
6
  */
7
7
  // Original QueryBuilder runtime types
8
8
  export * from './core';
9
- // Codegen-style schema types (CleanTable, CleanField, etc.)
9
+ // Codegen-style schema types (Table, Field, etc.)
10
10
  export * from './schema';
11
11
  // Introspection types
12
12
  export * from './introspection';
@@ -3,20 +3,20 @@
3
3
  * Converts user-friendly selection options to internal SelectionOptions format
4
4
  */
5
5
  import type { QuerySelectionOptions } from '../types';
6
- import type { CleanTable } from '../types/schema';
6
+ import type { Table } from '../types/schema';
7
7
  import type { FieldSelection } from '../types/selection';
8
8
  /**
9
9
  * Convert simplified field selection to QueryBuilder SelectionOptions
10
10
  */
11
- export declare function convertToSelectionOptions(table: CleanTable, allTables: CleanTable[], selection?: FieldSelection): QuerySelectionOptions | null;
11
+ export declare function convertToSelectionOptions(table: Table, allTables: Table[], selection?: FieldSelection): QuerySelectionOptions | null;
12
12
  /**
13
13
  * Check if a field is relational using table metadata
14
14
  */
15
- export declare function isRelationalField(fieldName: string, table: CleanTable): boolean;
15
+ export declare function isRelationalField(fieldName: string, table: Table): boolean;
16
16
  /**
17
17
  * Get all available relation fields from a table
18
18
  */
19
- export declare function getAvailableRelations(table: CleanTable): Array<{
19
+ export declare function getAvailableRelations(table: Table): Array<{
20
20
  fieldName: string;
21
21
  type: 'belongsTo' | 'hasOne' | 'hasMany' | 'manyToMany';
22
22
  referencedTable?: string;
@@ -24,7 +24,7 @@ export declare function getAvailableRelations(table: CleanTable): Array<{
24
24
  /**
25
25
  * Validate field selection against table schema
26
26
  */
27
- export declare function validateFieldSelection(selection: FieldSelection, table: CleanTable): {
27
+ export declare function validateFieldSelection(selection: FieldSelection, table: Table): {
28
28
  isValid: boolean;
29
29
  errors: string[];
30
30
  };
@@ -1,11 +1,11 @@
1
1
  import { TypedDocumentString } from '../client/typed-document';
2
2
  import type { MutationOptions } from '../types/mutation';
3
- import type { CleanTable } from '../types/schema';
3
+ import type { Table } from '../types/schema';
4
4
  /**
5
5
  * Build PostGraphile-style CREATE mutation
6
6
  * PostGraphile expects: mutation { createTableName(input: { tableName: TableNameInput! }) { tableName { ... } } }
7
7
  */
8
- export declare function buildPostGraphileCreate(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
8
+ export declare function buildPostGraphileCreate(table: Table, _allTables: Table[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
9
9
  input: {
10
10
  [key: string]: Record<string, unknown>;
11
11
  };
@@ -14,7 +14,7 @@ export declare function buildPostGraphileCreate(table: CleanTable, _allTables: C
14
14
  * Build PostGraphile-style UPDATE mutation
15
15
  * PostGraphile expects: mutation { updateTableName(input: { id: UUID!, patch: TableNamePatch! }) { tableName { ... } } }
16
16
  */
17
- export declare function buildPostGraphileUpdate(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
17
+ export declare function buildPostGraphileUpdate(table: Table, _allTables: Table[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
18
18
  input: {
19
19
  id: string | number;
20
20
  } & Record<string, unknown>;
@@ -23,7 +23,7 @@ export declare function buildPostGraphileUpdate(table: CleanTable, _allTables: C
23
23
  * Build PostGraphile-style DELETE mutation
24
24
  * PostGraphile expects: mutation { deleteTableName(input: { id: UUID! }) { clientMutationId } }
25
25
  */
26
- export declare function buildPostGraphileDelete(table: CleanTable, _allTables: CleanTable[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
26
+ export declare function buildPostGraphileDelete(table: Table, _allTables: Table[], _options?: MutationOptions): TypedDocumentString<Record<string, unknown>, {
27
27
  input: {
28
28
  id: string | number;
29
29
  };
@@ -1,4 +1,4 @@
1
- import type { CleanTable } from '../types/schema';
1
+ import type { Table } from '../types/schema';
2
2
  /**
3
3
  * Safely normalise a server-provided inflection value.
4
4
  * Returns `null` for null, undefined, or whitespace-only strings.
@@ -12,26 +12,26 @@ export declare function normalizeInflectionValue(value: string | null | undefine
12
12
  *
13
13
  * Example: "ActionGoal" -> "actionGoals", "User" -> "users", "Person" -> "people"
14
14
  */
15
- export declare function toCamelCasePlural(tableName: string, table?: CleanTable | null): string;
15
+ export declare function toCamelCasePlural(tableName: string, table?: Table | null): string;
16
16
  /**
17
17
  * Convert PascalCase table name to camelCase singular field name.
18
18
  * Prefers server-provided names when available.
19
19
  */
20
- export declare function toCamelCaseSingular(tableName: string, table?: CleanTable | null): string;
21
- export declare function toCreateMutationName(tableName: string, table?: CleanTable | null): string;
22
- export declare function toUpdateMutationName(tableName: string, table?: CleanTable | null): string;
23
- export declare function toDeleteMutationName(tableName: string, table?: CleanTable | null): string;
24
- export declare function toCreateInputTypeName(tableName: string, table?: CleanTable | null): string;
20
+ export declare function toCamelCaseSingular(tableName: string, table?: Table | null): string;
21
+ export declare function toCreateMutationName(tableName: string, table?: Table | null): string;
22
+ export declare function toUpdateMutationName(tableName: string, table?: Table | null): string;
23
+ export declare function toDeleteMutationName(tableName: string, table?: Table | null): string;
24
+ export declare function toCreateInputTypeName(tableName: string, table?: Table | null): string;
25
25
  export declare function toUpdateInputTypeName(tableName: string): string;
26
26
  export declare function toDeleteInputTypeName(tableName: string): string;
27
- export declare function toFilterTypeName(tableName: string, table?: CleanTable | null): string;
27
+ export declare function toFilterTypeName(tableName: string, table?: Table | null): string;
28
28
  /**
29
29
  * Resolve PostGraphile patch field name.
30
30
  * In v5 this is typically entity-specific: e.g. "userPatch", "contactPatch".
31
31
  * Prefers the value discovered from the schema (`table.query.patchFieldName`
32
32
  * or `table.inflection.patchField`), falls back to `${singularName}Patch`.
33
33
  */
34
- export declare function toPatchFieldName(tableName: string, table?: CleanTable | null): string;
34
+ export declare function toPatchFieldName(tableName: string, table?: Table | null): string;
35
35
  /**
36
36
  * Convert camelCase field name to SCREAMING_SNAKE_CASE for PostGraphile
37
37
  * orderBy enums.
@@ -45,4 +45,4 @@ export declare function toOrderByEnumValue(fieldName: string, direction: 'asc' |
45
45
  * Generate the PostGraphile OrderBy enum type name for a table.
46
46
  * Prefers server-provided `table.inflection.orderByType` when available.
47
47
  */
48
- export declare function toOrderByTypeName(tableName: string, table?: CleanTable | null): string;
48
+ export declare function toOrderByTypeName(tableName: string, table?: Table | null): string;
@@ -2,34 +2,34 @@ import { TypedDocumentString } from '../client/typed-document';
2
2
  import { QueryBuilder } from '../query-builder';
3
3
  import type { MetaObject, QueryIntrospectionSchema } from '../types';
4
4
  import type { QueryOptions } from '../types/query';
5
- import type { CleanTable } from '../types/schema';
5
+ import type { Table } from '../types/schema';
6
6
  export { toCamelCasePlural, toOrderByTypeName } from './naming-helpers';
7
7
  /**
8
- * Convert CleanTable to MetaObject format for QueryBuilder
8
+ * Convert Table to MetaObject format for QueryBuilder
9
9
  */
10
- export declare function cleanTableToMetaObject(tables: CleanTable[]): MetaObject;
10
+ export declare function cleanTableToMetaObject(tables: Table[]): MetaObject;
11
11
  /**
12
- * Generate basic IntrospectionSchema from CleanTable array
12
+ * Generate basic IntrospectionSchema from Table array
13
13
  * This creates a minimal schema for AST generation
14
14
  */
15
- export declare function generateIntrospectionSchema(tables: CleanTable[]): QueryIntrospectionSchema;
15
+ export declare function generateIntrospectionSchema(tables: Table[]): QueryIntrospectionSchema;
16
16
  /**
17
17
  * Create AST-based query builder for a table
18
18
  */
19
- export declare function createASTQueryBuilder(tables: CleanTable[]): QueryBuilder;
19
+ export declare function createASTQueryBuilder(tables: Table[]): QueryBuilder;
20
20
  /**
21
21
  * Build a SELECT query for a table with optional filtering, sorting, and pagination
22
22
  * Uses direct AST generation without intermediate conversions
23
23
  */
24
- export declare function buildSelect(table: CleanTable, allTables: readonly CleanTable[], options?: QueryOptions): TypedDocumentString<Record<string, unknown>, QueryOptions>;
24
+ export declare function buildSelect(table: Table, allTables: readonly Table[], options?: QueryOptions): TypedDocumentString<Record<string, unknown>, QueryOptions>;
25
25
  /**
26
26
  * Build a single row query by primary key or unique field
27
27
  */
28
- export declare function buildFindOne(table: CleanTable, _pkField?: string): TypedDocumentString<Record<string, unknown>, Record<string, unknown>>;
28
+ export declare function buildFindOne(table: Table, _pkField?: string): TypedDocumentString<Record<string, unknown>, Record<string, unknown>>;
29
29
  /**
30
30
  * Build a count query for a table
31
31
  */
32
- export declare function buildCount(table: CleanTable): TypedDocumentString<{
32
+ export declare function buildCount(table: Table): TypedDocumentString<{
33
33
  [key: string]: {
34
34
  totalCount: number;
35
35
  };
@@ -56,7 +56,7 @@ var naming_helpers_2 = require("./naming-helpers");
56
56
  Object.defineProperty(exports, "toCamelCasePlural", { enumerable: true, get: function () { return naming_helpers_2.toCamelCasePlural; } });
57
57
  Object.defineProperty(exports, "toOrderByTypeName", { enumerable: true, get: function () { return naming_helpers_2.toOrderByTypeName; } });
58
58
  /**
59
- * Convert CleanTable to MetaObject format for QueryBuilder
59
+ * Convert Table to MetaObject format for QueryBuilder
60
60
  */
61
61
  function cleanTableToMetaObject(tables) {
62
62
  return {
@@ -108,7 +108,7 @@ function cleanTableToMetaObject(tables) {
108
108
  };
109
109
  }
110
110
  /**
111
- * Generate basic IntrospectionSchema from CleanTable array
111
+ * Generate basic IntrospectionSchema from Table array
112
112
  * This creates a minimal schema for AST generation
113
113
  */
114
114
  function generateIntrospectionSchema(tables) {
@@ -222,7 +222,7 @@ function generateIntrospectionSchema(tables) {
222
222
  return schema;
223
223
  }
224
224
  /**
225
- * Convert CleanTable fields to QueryBuilder properties
225
+ * Convert Table fields to QueryBuilder properties
226
226
  */
227
227
  function convertFieldsToProperties(fields) {
228
228
  const properties = {};
@@ -293,7 +293,7 @@ function convertFieldSelectionToSelectionOptions(table, allTables, options) {
293
293
  return (0, field_selector_1.convertToSelectionOptions)(table, allTables, options);
294
294
  }
295
295
  /**
296
- * Generate SELECT query AST directly from CleanTable
296
+ * Generate SELECT query AST directly from Table
297
297
  */
298
298
  function generateSelectQueryAST(table, allTables, selection, options, relationFieldMap) {
299
299
  const pluralName = (0, naming_helpers_1.toCamelCasePlural)(table.name, table);
@@ -615,7 +615,7 @@ function findRelatedTable(relationField, table, allTables) {
615
615
  return allTables.find((tbl) => tbl.name === referencedTableName) || null;
616
616
  }
617
617
  /**
618
- * Generate FindOne query AST directly from CleanTable
618
+ * Generate FindOne query AST directly from Table
619
619
  */
620
620
  function generateFindOneQueryAST(table) {
621
621
  const singularName = (0, naming_helpers_1.toCamelCaseSingular)(table.name, table);
@@ -667,7 +667,7 @@ function generateFindOneQueryAST(table) {
667
667
  return (0, graphql_1.print)(ast);
668
668
  }
669
669
  /**
670
- * Generate Count query AST directly from CleanTable
670
+ * Generate Count query AST directly from Table
671
671
  */
672
672
  function generateCountQueryAST(table) {
673
673
  const pluralName = (0, naming_helpers_1.toCamelCasePlural)(table.name, table);
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Introspection barrel export
3
3
  *
4
- * Re-exports introspection utilities for converting GraphQL schemas to CleanTable format.
4
+ * Re-exports introspection utilities for converting GraphQL schemas to Table format.
5
5
  */
6
6
  export * from './infer-tables';
7
7
  export * from './transform';
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Introspection barrel export
4
4
  *
5
- * Re-exports introspection utilities for converting GraphQL schemas to CleanTable format.
5
+ * Re-exports introspection utilities for converting GraphQL schemas to Table format.
6
6
  */
7
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
8
  if (k2 === undefined) k2 = k;
@@ -1,5 +1,5 @@
1
1
  import type { IntrospectionQueryResponse } from '../types/introspection';
2
- import type { CleanTable } from '../types/schema';
2
+ import type { Table } from '../types/schema';
3
3
  /**
4
4
  * PostGraphile naming patterns for type detection
5
5
  */
@@ -32,11 +32,11 @@ export interface InferTablesOptions {
32
32
  comments?: boolean;
33
33
  }
34
34
  /**
35
- * Infer CleanTable[] from GraphQL introspection by recognizing PostGraphile patterns
35
+ * Infer Table[] from GraphQL introspection by recognizing PostGraphile patterns
36
36
  *
37
37
  * @param introspection - Standard GraphQL introspection response
38
38
  * @param options - Optional configuration
39
- * @returns Array of CleanTable objects compatible with existing generators
39
+ * @returns Array of Table objects compatible with existing generators
40
40
  */
41
- export declare function inferTablesFromIntrospection(introspection: IntrospectionQueryResponse, options?: InferTablesOptions): CleanTable[];
41
+ export declare function inferTablesFromIntrospection(introspection: IntrospectionQueryResponse, options?: InferTablesOptions): Table[];
42
42
  export {};
@@ -76,11 +76,11 @@ function isInternalType(name) {
76
76
  return name.startsWith('__');
77
77
  }
78
78
  /**
79
- * Infer CleanTable[] from GraphQL introspection by recognizing PostGraphile patterns
79
+ * Infer Table[] from GraphQL introspection by recognizing PostGraphile patterns
80
80
  *
81
81
  * @param introspection - Standard GraphQL introspection response
82
82
  * @param options - Optional configuration
83
- * @returns Array of CleanTable objects compatible with existing generators
83
+ * @returns Array of Table objects compatible with existing generators
84
84
  */
85
85
  function inferTablesFromIntrospection(introspection, options = {}) {
86
86
  const { __schema: schema } = introspection;
@@ -93,7 +93,7 @@ function inferTablesFromIntrospection(introspection, options = {}) {
93
93
  const mutationFields = mutationType
94
94
  ? getTypeFields(typeMap.get(mutationType.name))
95
95
  : [];
96
- // Step 1: Build CleanTable for each inferred entity
96
+ // Step 1: Build Table for each inferred entity
97
97
  const tables = [];
98
98
  for (const entityName of entityNames) {
99
99
  const entityType = typeMap.get(entityName);
@@ -172,7 +172,7 @@ function resolveEntityNameFromConnectionType(connectionType, typeMap) {
172
172
  return nodeTypeName;
173
173
  }
174
174
  /**
175
- * Build a complete CleanTable from an entity type
175
+ * Build a complete Table from an entity type
176
176
  */
177
177
  function buildCleanTable(entityName, entityType, typeMap, queryFields, mutationFields, entityToConnection, connectionToEntity, commentsEnabled) {
178
178
  // Extract scalar fields from entity type
@@ -303,7 +303,7 @@ function isEntityType(typeName, entityToConnection) {
303
303
  return entityToConnection.has(typeName);
304
304
  }
305
305
  /**
306
- * Convert IntrospectionTypeRef to CleanFieldType
306
+ * Convert IntrospectionTypeRef to FieldType
307
307
  */
308
308
  function convertToCleanFieldType(typeRef) {
309
309
  const baseType = (0, introspection_1.unwrapType)(typeRef);
@@ -16,5 +16,5 @@ import type { IntrospectionQueryResponse } from '../types/introspection';
16
16
  * Uses a recursive TypeRef fragment to handle deeply nested type wrappers
17
17
  * (e.g., [String!]! = NON_NULL(LIST(NON_NULL(SCALAR))))
18
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";
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 isOneOf\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
20
  export type { IntrospectionQueryResponse };
@@ -34,6 +34,7 @@ query IntrospectSchema {
34
34
  kind
35
35
  name
36
36
  description
37
+ isOneOf
37
38
  fields(includeDeprecated: true) {
38
39
  name
39
40
  description
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Transform GraphQL introspection data to clean operation types
3
3
  *
4
- * This module converts raw introspection responses into the CleanOperation
4
+ * This module converts raw introspection responses into the Operation
5
5
  * format used by code generators.
6
6
  */
7
7
  import type { IntrospectionQueryResponse, IntrospectionType } from '../types/introspection';
8
8
  import { getBaseTypeName, isNonNull, unwrapType } from '../types/introspection';
9
- import type { CleanOperation, TypeRegistry } from '../types/schema';
9
+ import type { Operation, TypeRegistry } from '../types/schema';
10
10
  /**
11
11
  * Build a type registry from introspection types
12
12
  * Maps type names to their full resolved definitions
@@ -17,8 +17,8 @@ import type { CleanOperation, TypeRegistry } from '../types/schema';
17
17
  */
18
18
  export declare function buildTypeRegistry(types: IntrospectionType[]): TypeRegistry;
19
19
  export interface TransformSchemaResult {
20
- queries: CleanOperation[];
21
- mutations: CleanOperation[];
20
+ queries: Operation[];
21
+ mutations: Operation[];
22
22
  typeRegistry: TypeRegistry;
23
23
  }
24
24
  /**
@@ -29,7 +29,7 @@ export declare function transformSchemaToOperations(response: IntrospectionQuery
29
29
  * Filter operations by include/exclude patterns
30
30
  * Uses glob-like patterns (supports * wildcard)
31
31
  */
32
- export declare function filterOperations(operations: CleanOperation[], include?: string[], exclude?: string[]): CleanOperation[];
32
+ export declare function filterOperations(operations: Operation[], include?: string[], exclude?: string[]): Operation[];
33
33
  /**
34
34
  * Result type for table operation names lookup
35
35
  */
@@ -72,7 +72,7 @@ export declare function getTableOperationNames(tables: Array<{
72
72
  * 2. All other operations (including update*By*, delete*By*) become custom operations
73
73
  * 3. 100% schema coverage is guaranteed
74
74
  */
75
- export declare function isTableOperation(operation: CleanOperation, tableOperationNames: TableOperationNames): boolean;
75
+ export declare function isTableOperation(operation: Operation, tableOperationNames: TableOperationNames): boolean;
76
76
  /**
77
77
  * Get only custom operations (not covered by table generators)
78
78
  *
@@ -82,5 +82,5 @@ export declare function isTableOperation(operation: CleanOperation, tableOperati
82
82
  * - Unique constraint mutations (update*By*, delete*By*)
83
83
  * - True custom operations (login, register, bootstrapUser, etc.)
84
84
  */
85
- export declare function getCustomOperations(operations: CleanOperation[], tableOperationNames: TableOperationNames): CleanOperation[];
85
+ export declare function getCustomOperations(operations: Operation[], tableOperationNames: TableOperationNames): Operation[];
86
86
  export { getBaseTypeName, isNonNull, unwrapType };
@@ -58,12 +58,16 @@ function buildTypeRegistry(types) {
58
58
  // Resolve input fields for INPUT_OBJECT types
59
59
  if (type.kind === 'INPUT_OBJECT' && type.inputFields) {
60
60
  resolvedType.inputFields = type.inputFields.map((field) => transformInputValueToCleanArgumentShallow(field));
61
+ // Detect @oneOf directive (GraphQL 16+ discriminated union inputs)
62
+ if (type.isOneOf) {
63
+ resolvedType.isOneOf = true;
64
+ }
61
65
  }
62
66
  }
63
67
  return registry;
64
68
  }
65
69
  /**
66
- * Transform field to CleanObjectField without resolving nested types
70
+ * Transform field to ObjectField without resolving nested types
67
71
  * (shallow transformation to avoid circular refs)
68
72
  */
69
73
  function transformFieldToCleanObjectFieldShallow(field) {
@@ -74,7 +78,7 @@ function transformFieldToCleanObjectFieldShallow(field) {
74
78
  };
75
79
  }
76
80
  /**
77
- * Transform input value to CleanArgument without resolving nested types
81
+ * Transform input value to Argument without resolving nested types
78
82
  */
79
83
  function transformInputValueToCleanArgumentShallow(inputValue) {
80
84
  return {
@@ -125,7 +129,7 @@ function transformSchemaToOperations(response) {
125
129
  // Field to Operation Transformation
126
130
  // ============================================================================
127
131
  /**
128
- * Transform an introspection field to a CleanOperation
132
+ * Transform an introspection field to a Operation
129
133
  */
130
134
  function transformFieldToCleanOperation(field, kind, types) {
131
135
  return {
@@ -139,7 +143,7 @@ function transformFieldToCleanOperation(field, kind, types) {
139
143
  };
140
144
  }
141
145
  /**
142
- * Transform an input value to CleanArgument
146
+ * Transform an input value to Argument
143
147
  */
144
148
  function transformInputValueToCleanArgument(inputValue, types) {
145
149
  return {
@@ -153,7 +157,7 @@ function transformInputValueToCleanArgument(inputValue, types) {
153
157
  // Type Reference Transformation
154
158
  // ============================================================================
155
159
  /**
156
- * Transform an introspection TypeRef to CleanTypeRef
160
+ * Transform an introspection TypeRef to TypeRef
157
161
  * Recursively handles wrapper types (LIST, NON_NULL)
158
162
  *
159
163
  * NOTE: We intentionally do NOT resolve nested fields here to avoid
@@ -1,20 +1,20 @@
1
1
  /**
2
- * Table utility functions for CleanTable[]
2
+ * Table utility functions for Table[]
3
3
  *
4
4
  * Note: The _meta transform functions have been removed.
5
5
  * Tables are now inferred from standard GraphQL introspection
6
6
  * using inferTablesFromIntrospection() in ./infer-tables.ts
7
7
  */
8
- import type { CleanTable } from '../types/schema';
8
+ import type { Table } from '../types/schema';
9
9
  /**
10
- * Get table names from CleanTable array
10
+ * Get table names from Table array
11
11
  */
12
- export declare function getTableNames(tables: CleanTable[]): string[];
12
+ export declare function getTableNames(tables: Table[]): string[];
13
13
  /**
14
14
  * Find a table by name
15
15
  */
16
- export declare function findTable(tables: CleanTable[], name: string): CleanTable | undefined;
16
+ export declare function findTable(tables: Table[], name: string): Table | undefined;
17
17
  /**
18
18
  * Filter tables by name pattern (glob-like)
19
19
  */
20
- export declare function filterTables(tables: CleanTable[], include?: string[], exclude?: string[]): CleanTable[];
20
+ export declare function filterTables(tables: Table[], include?: string[], exclude?: string[]): Table[];
@@ -4,7 +4,7 @@ exports.getTableNames = getTableNames;
4
4
  exports.findTable = findTable;
5
5
  exports.filterTables = filterTables;
6
6
  /**
7
- * Get table names from CleanTable array
7
+ * Get table names from Table array
8
8
  */
9
9
  function getTableNames(tables) {
10
10
  return tables.map((t) => t.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-query",
3
- "version": "3.6.7",
3
+ "version": "3.8.0",
4
4
  "description": "Constructive GraphQL Query",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "main": "index.js",
@@ -34,7 +34,7 @@
34
34
  "grafast": "1.0.0-rc.9",
35
35
  "graphile-build-pg": "5.0.0-rc.8",
36
36
  "graphile-config": "1.0.0-rc.6",
37
- "graphile-settings": "^4.10.3",
37
+ "graphile-settings": "^4.12.0",
38
38
  "graphql": "16.13.0",
39
39
  "inflection": "^3.0.0",
40
40
  "inflekt": "^0.3.3",
@@ -51,5 +51,5 @@
51
51
  "devDependencies": {
52
52
  "makage": "^0.1.10"
53
53
  },
54
- "gitHead": "3b3735292589a49601f40645ea7880f584a23b77"
54
+ "gitHead": "b8d4ae2b36e37e7f3533f858f19ec000febaa04b"
55
55
  }
package/types/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { DocumentNode, FieldNode, SelectionSetNode, VariableDefinitionNode } from 'graphql';
2
- import type { CleanField } from './schema';
2
+ import type { Field } from './schema';
3
3
  export type ASTNode = DocumentNode | FieldNode | SelectionSetNode | VariableDefinitionNode;
4
4
  export interface NestedProperties {
5
5
  [key: string]: QueryProperty | NestedProperties;
@@ -71,7 +71,7 @@ export interface GraphQLVariables {
71
71
  export interface QueryFieldSelection {
72
72
  name: string;
73
73
  isObject: boolean;
74
- fieldDefn?: MetaField | CleanField;
74
+ fieldDefn?: MetaField | Field;
75
75
  selection?: QueryFieldSelection[];
76
76
  variables?: GraphQLVariables;
77
77
  isBelongTo?: boolean;
package/types/index.js CHANGED
@@ -22,7 +22,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  // Original QueryBuilder runtime types
24
24
  __exportStar(require("./core"), exports);
25
- // Codegen-style schema types (CleanTable, CleanField, etc.)
25
+ // Codegen-style schema types (Table, Field, etc.)
26
26
  __exportStar(require("./schema"), exports);
27
27
  // Introspection types
28
28
  __exportStar(require("./introspection"), exports);
@@ -63,6 +63,8 @@ export interface IntrospectionType {
63
63
  interfaces: Array<{
64
64
  name: string;
65
65
  }> | null;
66
+ /** Whether this INPUT_OBJECT type uses @oneOf (GraphQL 16+ discriminated union input) */
67
+ isOneOf?: boolean;
66
68
  }
67
69
  /**
68
70
  * Root type references in schema
package/types/schema.d.ts CHANGED
@@ -5,12 +5,12 @@
5
5
  /**
6
6
  * Represents a database table with its fields and relations
7
7
  */
8
- export interface CleanTable {
8
+ export interface Table {
9
9
  name: string;
10
10
  /** Description from PostgreSQL COMMENT (smart comments stripped) */
11
11
  description?: string;
12
- fields: CleanField[];
13
- relations: CleanRelations;
12
+ fields: Field[];
13
+ relations: Relations;
14
14
  /** PostGraphile inflection rules for this table */
15
15
  inflection?: TableInflection;
16
16
  /** Query operation names from introspection */
@@ -94,20 +94,20 @@ export interface TableConstraints {
94
94
  }
95
95
  export interface ConstraintInfo {
96
96
  name: string;
97
- fields: CleanField[];
97
+ fields: Field[];
98
98
  }
99
99
  export interface ForeignKeyConstraint extends ConstraintInfo {
100
100
  refTable: string;
101
- refFields: CleanField[];
101
+ refFields: Field[];
102
102
  }
103
103
  /**
104
104
  * Represents a field/column in a table
105
105
  */
106
- export interface CleanField {
106
+ export interface Field {
107
107
  name: string;
108
108
  /** Description from PostgreSQL COMMENT (smart comments stripped) */
109
109
  description?: string;
110
- type: CleanFieldType;
110
+ type: FieldType;
111
111
  /** Whether the column has a NOT NULL constraint (inferred from NON_NULL wrapper on entity type field) */
112
112
  isNotNull?: boolean | null;
113
113
  /** Whether the column has a DEFAULT value (inferred by comparing entity vs CreateInput field nullability) */
@@ -116,7 +116,7 @@ export interface CleanField {
116
116
  /**
117
117
  * Field type information from PostGraphile introspection
118
118
  */
119
- export interface CleanFieldType {
119
+ export interface FieldType {
120
120
  /** GraphQL type name (e.g., "String", "UUID", "Int") */
121
121
  gqlType: string;
122
122
  /** Whether this is an array type */
@@ -135,64 +135,72 @@ export interface CleanFieldType {
135
135
  /**
136
136
  * All relation types for a table
137
137
  */
138
- export interface CleanRelations {
139
- belongsTo: CleanBelongsToRelation[];
140
- hasOne: CleanHasOneRelation[];
141
- hasMany: CleanHasManyRelation[];
142
- manyToMany: CleanManyToManyRelation[];
138
+ export interface Relations {
139
+ belongsTo: BelongsToRelation[];
140
+ hasOne: HasOneRelation[];
141
+ hasMany: HasManyRelation[];
142
+ manyToMany: ManyToManyRelation[];
143
143
  }
144
144
  /**
145
145
  * BelongsTo relation (foreign key on this table)
146
146
  */
147
- export interface CleanBelongsToRelation {
147
+ export interface BelongsToRelation {
148
148
  fieldName: string | null;
149
149
  isUnique: boolean;
150
150
  referencesTable: string;
151
151
  type: string | null;
152
- keys: CleanField[];
152
+ keys: Field[];
153
153
  }
154
154
  /**
155
155
  * HasOne relation (foreign key on other table, unique)
156
156
  */
157
- export interface CleanHasOneRelation {
157
+ export interface HasOneRelation {
158
158
  fieldName: string | null;
159
159
  isUnique: boolean;
160
160
  referencedByTable: string;
161
161
  type: string | null;
162
- keys: CleanField[];
162
+ keys: Field[];
163
163
  }
164
164
  /**
165
165
  * HasMany relation (foreign key on other table, not unique)
166
166
  */
167
- export interface CleanHasManyRelation {
167
+ export interface HasManyRelation {
168
168
  fieldName: string | null;
169
169
  isUnique: boolean;
170
170
  referencedByTable: string;
171
171
  type: string | null;
172
- keys: CleanField[];
172
+ keys: Field[];
173
173
  }
174
174
  /**
175
175
  * ManyToMany relation (through junction table)
176
176
  */
177
- export interface CleanManyToManyRelation {
177
+ export interface ManyToManyRelation {
178
178
  fieldName: string | null;
179
179
  rightTable: string;
180
180
  junctionTable: string;
181
181
  type: string | null;
182
+ /** Junction FK field names pointing to the left table */
183
+ junctionLeftKeyFields?: string[];
184
+ /** Junction FK field names pointing to the right table */
185
+ junctionRightKeyFields?: string[];
186
+ /** Left table key fields (usually just 'id') */
187
+ leftKeyFields?: string[];
188
+ /** Right table key fields (usually just 'id') */
189
+ rightKeyFields?: string[];
182
190
  }
183
191
  /**
184
192
  * Clean representation of a GraphQL operation (query or mutation)
185
193
  * Derived from introspection data
186
194
  */
187
- export interface CleanOperation {
195
+ export interface Operation {
188
196
  /** Operation name (e.g., "login", "currentUser", "cars") */
189
197
  name: string;
190
198
  /** Operation kind */
191
199
  kind: 'query' | 'mutation';
192
200
  /** Arguments/variables for the operation */
193
- args: CleanArgument[];
201
+ args: Argument[];
194
202
  /** Return type */
195
- returnType: CleanTypeRef;
203
+ returnType: TypeRef;
196
204
  /** Description from schema */
197
205
  description?: string;
198
206
  /** Whether this is deprecated */
@@ -203,11 +211,11 @@ export interface CleanOperation {
203
211
  /**
204
212
  * Clean representation of an operation argument
205
213
  */
206
- export interface CleanArgument {
214
+ export interface Argument {
207
215
  /** Argument name */
208
216
  name: string;
209
217
  /** Argument type */
210
- type: CleanTypeRef;
218
+ type: TypeRef;
211
219
  /** Default value (as string) */
212
220
  defaultValue?: string;
213
221
  /** Description from schema */
@@ -216,30 +224,30 @@ export interface CleanArgument {
216
224
  /**
217
225
  * Clean type reference - simplified from introspection TypeRef
218
226
  */
219
- export interface CleanTypeRef {
227
+ export interface TypeRef {
220
228
  /** Type kind */
221
229
  kind: 'SCALAR' | 'OBJECT' | 'INPUT_OBJECT' | 'ENUM' | 'LIST' | 'NON_NULL';
222
230
  /** Type name (null for LIST and NON_NULL wrappers) */
223
231
  name: string | null;
224
232
  /** Inner type for LIST and NON_NULL wrappers */
225
- ofType?: CleanTypeRef;
233
+ ofType?: TypeRef;
226
234
  /** Resolved TypeScript type string */
227
235
  tsType?: string;
228
236
  /** Fields for OBJECT types */
229
- fields?: CleanObjectField[];
237
+ fields?: ObjectField[];
230
238
  /** Input fields for INPUT_OBJECT types */
231
- inputFields?: CleanArgument[];
239
+ inputFields?: Argument[];
232
240
  /** Values for ENUM types */
233
241
  enumValues?: string[];
234
242
  }
235
243
  /**
236
244
  * Field on an object type
237
245
  */
238
- export interface CleanObjectField {
246
+ export interface ObjectField {
239
247
  /** Field name */
240
248
  name: string;
241
249
  /** Field type */
242
- type: CleanTypeRef;
250
+ type: TypeRef;
243
251
  /** Description */
244
252
  description?: string;
245
253
  }
@@ -255,11 +263,13 @@ export interface ResolvedType {
255
263
  name: string;
256
264
  description?: string;
257
265
  /** Fields for OBJECT types */
258
- fields?: CleanObjectField[];
266
+ fields?: ObjectField[];
259
267
  /** Input fields for INPUT_OBJECT types */
260
- inputFields?: CleanArgument[];
268
+ inputFields?: Argument[];
261
269
  /** Values for ENUM types */
262
270
  enumValues?: string[];
263
271
  /** Possible types for UNION types */
264
272
  possibleTypes?: string[];
273
+ /** Whether this INPUT_OBJECT uses @oneOf (GraphQL 16+ discriminated union input) */
274
+ isOneOf?: boolean;
265
275
  }