Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion graphile/graphile-settings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"graphile-upload-plugin": "workspace:^",
"graphile-utils": "5.0.0-rc.8",
"graphql": "16.13.0",
"inflekt": "^0.3.3",
"inflekt": "^0.5.0",
"lru-cache": "^11.2.7",
"pg": "^8.20.0",
"pg-query-context": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ export function buildBelongsToRelations(
sameAttributes(unique.attributes, localAttributes),
);

const remoteCodec = relation.remoteResource?.codec;

belongsTo.push({
fieldName: relationName,
isUnique,
type: relation.remoteResource?.codec?.name || null,
type: remoteCodec?.name || null,
keys: buildFieldList(localAttributes, codec, attributes, context),
references: { name: relation.remoteResource?.codec?.name || 'unknown' },
references: { name: remoteCodec?.name || 'unknown' },
});
}

Expand All @@ -73,12 +75,14 @@ export function buildReverseRelations(
sameAttributes(unique.attributes, remoteAttributes),
);

const remoteCodec = relation.remoteResource?.codec;

const meta: HasRelation = {
fieldName: relationName,
isUnique,
type: relation.remoteResource?.codec?.name || null,
type: remoteCodec?.name || null,
keys: buildFieldList(relation.localAttributes || [], codec, attributes, context),
referencedBy: { name: relation.remoteResource?.codec?.name || 'unknown' },
referencedBy: { name: remoteCodec?.name || 'unknown' },
};

if (isUnique) {
Expand Down
2 changes: 1 addition & 1 deletion graphql/codegen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"gql-ast": "workspace:^",
"graphile-schema": "workspace:^",
"graphql": "16.13.0",
"inflekt": "^0.3.3",
"inflekt": "^0.5.0",
"inquirerer": "^4.7.0",
"jiti": "^2.6.1",
"komoji": "^0.8.1",
Expand Down
47 changes: 10 additions & 37 deletions graphql/codegen/src/core/codegen/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* Codegen utilities - naming conventions, type mapping, and helpers
*/
import { pluralize } from 'inflekt';
import {
lcFirst,
pluralize,
toCamelCase,
toPascalCase,
toScreamingSnake,
ucFirst,
} from 'inflekt';

import type {
Field,
Expand All @@ -11,42 +18,8 @@ import type {
} from '../../types/schema';
import { scalarToFilterType, scalarToTsType } from './scalars';

// ============================================================================
// String manipulation
// ============================================================================

/** Lowercase first character */
export function lcFirst(str: string): string {
return str.charAt(0).toLowerCase() + str.slice(1);
}

/** Uppercase first character */
export function ucFirst(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}

/** Convert to camelCase */
export function toCamelCase(str: string): string {
return str
.replace(/[-_](.)/g, (_, char) => char.toUpperCase())
.replace(/^(.)/, (_, char) => char.toLowerCase());
}

/** Convert to PascalCase */
export function toPascalCase(str: string): string {
return str
.replace(/[-_](.)/g, (_, char) => char.toUpperCase())
.replace(/^(.)/, (_, char) => char.toUpperCase());
}

/** Convert to SCREAMING_SNAKE_CASE */
export function toScreamingSnake(str: string): string {
return str
.replace(/([A-Z])/g, '_$1')
.replace(/[-\s]/g, '_')
.toUpperCase()
.replace(/^_/, '');
}
// Re-export string manipulation helpers from inflekt (single source of truth)
export { lcFirst, toCamelCase, toPascalCase, toScreamingSnake, ucFirst };

// ============================================================================
// Naming conventions for generated code
Expand Down
2 changes: 1 addition & 1 deletion graphql/query/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"graphile-settings": "workspace:^",
"graphql": "16.13.0",
"inflection": "^3.0.0",
"inflekt": "^0.3.3",
"inflekt": "^0.5.0",
"lru-cache": "^11.2.7",
"postgraphile": "5.0.0-rc.10"
},
Expand Down
15 changes: 11 additions & 4 deletions graphql/query/src/generators/field-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
FieldSelectionPreset,
SimpleFieldSelection,
} from '../types/selection';
import { fuzzyFindByName } from 'inflekt';

const relationalFieldSetCache = new WeakMap<Table, Set<string>>();

Expand Down Expand Up @@ -293,11 +294,17 @@ function getRelatedTableScalarFields(
return {};
}

// Find the related table in allTables
const relatedTable = allTables.find((t) => t.name === referencedTableName);
// Find the related table in allTables using shared fuzzy matching from inflekt.
// Handles PascalCase table names vs snake_case/camelCase/plural codec names.
const relatedTable = fuzzyFindByName(
allTables,
referencedTableName,
(t) => t.name,
);
if (!relatedTable) {
// Related table not found in schema - return empty selection
return {};
// Related table not found in schema — return fallback { __typename: true }
// so the query remains valid (nodes need at least one subfield).
return { __typename: true };
}

// Get ALL scalar fields from the related table (non-relational fields)
Expand Down
6 changes: 4 additions & 2 deletions graphql/query/src/generators/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type { QueryOptions } from '../types/query';
import type { Table } from '../types/schema';
import type { FieldSelection } from '../types/selection';
import { convertToSelectionOptions, isRelationalField } from './field-selector';
import { fuzzyFindByName } from 'inflekt';
import {
normalizeInflectionValue,
toCamelCasePlural,
Expand Down Expand Up @@ -787,8 +788,9 @@ function findRelatedTable(
return null;
}

// Find the related table in allTables
return allTables.find((tbl) => tbl.name === referencedTableName) || null;
// Find the related table using shared fuzzy matching from inflekt.
// Handles PascalCase table names vs snake_case/camelCase/plural codec names.
return fuzzyFindByName(allTables, referencedTableName, (tbl) => tbl.name) ?? null;
}

/**
Expand Down
Loading
Loading