Skip to content

Commit

Permalink
Added config option to limit depth of relations (temporary (hopefully…
Browse files Browse the repository at this point in the history
…) solution to issue #11)
  • Loading branch information
Sukairo-02 committed May 28, 2024
1 parent 4055a35 commit 2986f94
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ runPg.ts
Tests/.temp
Tests/Migrations
.DS_Store
drizzle.test-heavy.ts
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "drizzle-graphql",
"type": "module",
"author": "Drizzle Team",
"version": "0.7.3",
"version": "0.8.0",
"description": "Automatically generate GraphQL schema or customizable schema config fields from Drizzle ORM schema",
"scripts": {
"build": "pnpm tsx scripts/build.ts",
Expand Down Expand Up @@ -44,7 +44,7 @@
"cpy": "^11.0.1",
"dockerode": "^4.0.2",
"dprint": "^0.45.1",
"drizzle-kit": "^0.21.2",
"drizzle-kit": "^0.21.4",
"drizzle-orm": "0.30.10",
"get-port": "^7.0.0",
"glob": "^10.3.10",
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,22 @@ export const buildSchema = <TDbClient extends AnyDrizzleDB<any>>(
);
}

if (typeof config?.relationsDepthLimit === 'number') {
if (config.relationsDepthLimit < 0) {
throw new Error('config.relationsDepthLimit is supposed to be nonnegative integer or undefined!');
}
if (config.relationsDepthLimit !== ~~config.relationsDepthLimit) {
throw new Error('config.relationsDepthLimit is supposed to be nonnegative integer or undefined!');
}
}

let generatorOutput;
if (is(db, MySqlDatabase)) {
generatorOutput = generateMySQL(db, schema);
generatorOutput = generateMySQL(db, schema, config?.relationsDepthLimit);
} else if (is(db, PgDatabase)) {
generatorOutput = generatePG(db, schema);
generatorOutput = generatePG(db, schema, config?.relationsDepthLimit);
} else if (is(db, BaseSQLiteDatabase)) {
generatorOutput = generateSQLite(db, schema);
generatorOutput = generateSQLite(db, schema, config?.relationsDepthLimit);
} else throw new Error('Unknown database instance type');

const { queries, mutations, inputs, types } = generatorOutput;
Expand Down
26 changes: 19 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,25 @@ export type GeneratedData<
entities: GeneratedEntities<TDatabase>;
};

/**
* Determines whether generated mutations will be passed to returned schema.
*
* Set value to `false` to omit mutations from returned schema.
*
* Flag is treated as if set to `true` by default.
*/
export type BuildSchemaConfig = {
/**
* Determines whether generated mutations will be passed to returned schema.
*
* Set value to `false` to omit mutations from returned schema.
*
* Flag is treated as if set to `true` by default.
*/
mutations?: boolean;
/**
* Limits depth of generated relation fields on queries.
*
* Expects non-negative integer or undefined.
*
* Set value to `undefined` to not limit relation depth.
*
* Set value to `0` to omit relations altogether.
*
* Value is treated as if set to `undefined` by default.
*/
relationsDepthLimit?: number;
};
12 changes: 11 additions & 1 deletion src/util/builders/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ const generateSelectFields = <TWithOrder extends boolean>(
relationMap: Record<string, Record<string, TableNamedRelations>>,
typeName: string,
withOrder: TWithOrder,
relationsDepthLimit: number | undefined,
currentDepth: number = 0,
usedTables: Set<string> = new Set(),
): SelectData<TWithOrder> => {
const relations = relationMap[tableName];
Expand All @@ -340,7 +342,10 @@ const generateSelectFields = <TWithOrder extends boolean>(

const tableFields = generateTableSelectTypeFieldsCached(table, tableName);

if (usedTables.has(tableName) || !relationEntries.length) {
if (
usedTables.has(tableName) || (typeof relationsDepthLimit === 'number' && currentDepth >= relationsDepthLimit)
|| !relationEntries.length
) {
return {
order,
filters,
Expand All @@ -351,6 +356,7 @@ const generateSelectFields = <TWithOrder extends boolean>(

const rawRelationFields: [string, ConvertedRelationColumnWithArgs][] = [];
const updatedUsedTables = new Set(usedTables).add(tableName);
const newDepth = currentDepth + 1;

for (const [relationName, { targetTableName, relation }] of relationEntries) {
const relTypeName = `${typeName}${pascalize(relationName)}Relation`;
Expand All @@ -362,6 +368,8 @@ const generateSelectFields = <TWithOrder extends boolean>(
relationMap,
relTypeName,
!isOne,
relationsDepthLimit,
newDepth,
updatedUsedTables,
);

Expand Down Expand Up @@ -410,6 +418,7 @@ export const generateTableTypes = <
tables: Record<string, Table>,
relationMap: Record<string, Record<string, TableNamedRelations>>,
withReturning: WithReturning,
relationsDepthLimit: number | undefined,
): GeneratedTableTypes<WithReturning> => {
const stylizedName = pascalize(tableName);
const { tableFields, relationFields, filters, order } = generateSelectFields(
Expand All @@ -418,6 +427,7 @@ export const generateTableTypes = <
relationMap,
stylizedName,
true,
relationsDepthLimit,
);

const table = tables[tableName]!;
Expand Down
3 changes: 2 additions & 1 deletion src/util/builders/mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export const generateSchemaData = <
>(
db: TDrizzleInstance,
schema: TSchema,
relationsDepthLimit: number | undefined,
): GeneratedEntities<TDrizzleInstance, TSchema> => {
const rawSchema = schema;
const schemaEntries = Object.entries(rawSchema);
Expand Down Expand Up @@ -383,7 +384,7 @@ export const generateSchemaData = <
const gqlSchemaTypes = Object.fromEntries(
Object.entries(tables).map(([tableName, table]) => [
tableName,
generateTableTypes(tableName, tables, namedRelations, false),
generateTableTypes(tableName, tables, namedRelations, false, relationsDepthLimit),
]),
);

Expand Down
3 changes: 2 additions & 1 deletion src/util/builders/pg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ export const generateSchemaData = <
>(
db: TDrizzleInstance,
schema: TSchema,
relationsDepthLimit: number | undefined,
): GeneratedEntities<TDrizzleInstance, TSchema> => {
const rawSchema = schema;
const schemaEntries = Object.entries(rawSchema);
Expand Down Expand Up @@ -397,7 +398,7 @@ export const generateSchemaData = <
const gqlSchemaTypes = Object.fromEntries(
Object.entries(tables).map(([tableName, table]) => [
tableName,
generateTableTypes(tableName, tables, namedRelations, true),
generateTableTypes(tableName, tables, namedRelations, true, relationsDepthLimit),
]),
);

Expand Down
3 changes: 2 additions & 1 deletion src/util/builders/sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export const generateSchemaData = <
>(
db: TDrizzleInstance,
schema: TSchema,
relationsDepthLimit: number | undefined,
): GeneratedEntities<TDrizzleInstance, TSchema> => {
const rawSchema = schema;
const schemaEntries = Object.entries(rawSchema);
Expand Down Expand Up @@ -406,7 +407,7 @@ export const generateSchemaData = <
const gqlSchemaTypes = Object.fromEntries(
Object.entries(tables).map(([tableName, table]) => [
tableName,
generateTableTypes(tableName, tables, namedRelations, true),
generateTableTypes(tableName, tables, namedRelations, true, relationsDepthLimit),
]),
);

Expand Down

0 comments on commit 2986f94

Please sign in to comment.