pothos-drizzle-generator 0.0.2 → 0.1.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/README.md +94 -2
- package/dist/cjs/PothosDrizzleGeneratorPlugin.js +1 -2
- package/dist/cjs/generator.d.ts +15 -15
- package/dist/cjs/generator.js +21 -20
- package/dist/cjs/global-types.d.ts +82 -16
- package/dist/cjs/libs/utils.d.ts +1 -1
- package/dist/cjs/libs/utils.js +4 -0
- package/dist/esm/PothosDrizzleGeneratorPlugin.js +1 -2
- package/dist/esm/generator.d.ts +15 -15
- package/dist/esm/generator.js +21 -20
- package/dist/esm/global-types.d.ts +82 -16
- package/dist/esm/libs/utils.d.ts +1 -1
- package/dist/esm/libs/utils.js +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,10 @@ A Pothos plugin that automatically generates GraphQL schemas based on Drizzle sc
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
+
# sample
|
|
8
|
+
|
|
9
|
+
https://github.com/SoraKumo001/pothos-drizzle-generator-sample
|
|
10
|
+
|
|
7
11
|
# usage
|
|
8
12
|
|
|
9
13
|
To use this service, you must have version `drizzle-orm@1.0.0-beta.2` or later.
|
|
@@ -45,6 +49,8 @@ const schema = builder.toSchema();
|
|
|
45
49
|
|
|
46
50
|
# Options
|
|
47
51
|
|
|
52
|
+
Settings defined in `all` are overridden by `models`.
|
|
53
|
+
|
|
48
54
|
```ts
|
|
49
55
|
const builder = new SchemaBuilder<PothosTypes>({
|
|
50
56
|
plugins: [
|
|
@@ -61,12 +67,32 @@ const builder = new SchemaBuilder<PothosTypes>({
|
|
|
61
67
|
depthLimit: ({ ctx, modelName, operation }) => $limit$,
|
|
62
68
|
// Specifying the model to use
|
|
63
69
|
use: { include: [...$modelNames$], exclude: [...$modelNames$] },
|
|
70
|
+
// Applies to all models
|
|
71
|
+
all:{
|
|
72
|
+
// Specifying fields to use in queries
|
|
73
|
+
fields: ({ modelName }) => { include: [...$fields$], exclude: [...$fields$] },
|
|
74
|
+
// Specifying the method of operation for the model
|
|
75
|
+
operations: ({ modelName }) => { include: [...$operation$], exclude: [...$operation$] },
|
|
76
|
+
// Runtime Permission Check
|
|
77
|
+
executable: ({ ctx, modelName, operation }) => $permission$,
|
|
78
|
+
// Specify the maximum value for the query's limit
|
|
79
|
+
limit: ({ ctx, modelName, operation }) => $limit$,
|
|
80
|
+
// Override the query's orderBy
|
|
81
|
+
orderBy: ({ ctx, modelName, operation }) => $orderBy$,
|
|
82
|
+
// Add query conditions
|
|
83
|
+
where: ({ ctx, modelName, operation }) => $where$,
|
|
84
|
+
// Specifying input fields
|
|
85
|
+
inputFields: { include: [$fields$], exclude: [$fields$] },
|
|
86
|
+
// Overwriting input data
|
|
87
|
+
inputData: ({ ctx, modelName, operation }) => $inputData$,
|
|
88
|
+
},
|
|
89
|
+
// Apply to individual models
|
|
64
90
|
models: {
|
|
65
91
|
[$modelName$]: {
|
|
66
92
|
// Specifying fields to use in queries
|
|
67
|
-
fields: { include: [...$fields$], exclude: [...$fields$] },
|
|
93
|
+
fields: ({ modelName }) => { include: [...$fields$], exclude: [...$fields$] },
|
|
68
94
|
// Specifying the method of operation for the model
|
|
69
|
-
operations: { include: [...$operation$], exclude: [...$operation$] },
|
|
95
|
+
operations: ({ modelName }) => { include: [...$operation$], exclude: [...$operation$] },
|
|
70
96
|
// Runtime Permission Check
|
|
71
97
|
executable: ({ ctx, modelName, operation }) => $permission$,
|
|
72
98
|
// Specify the maximum value for the query's limit
|
|
@@ -85,6 +111,72 @@ const builder = new SchemaBuilder<PothosTypes>({
|
|
|
85
111
|
});
|
|
86
112
|
```
|
|
87
113
|
|
|
114
|
+
- example
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const builder = new SchemaBuilder<PothosTypes>({
|
|
118
|
+
plugins: [
|
|
119
|
+
DrizzlePlugin,
|
|
120
|
+
PothosDrizzleGeneratorPlugin, // Set plugin
|
|
121
|
+
],
|
|
122
|
+
drizzle: {
|
|
123
|
+
client: () => db,
|
|
124
|
+
relations,
|
|
125
|
+
getTableConfig,
|
|
126
|
+
},
|
|
127
|
+
pothosDrizzleGenerator: {
|
|
128
|
+
// Tables not used
|
|
129
|
+
use: { exclude: ["postsToCategories"] },
|
|
130
|
+
all: {
|
|
131
|
+
// Maximum query depth
|
|
132
|
+
depthLimit: () => 5,
|
|
133
|
+
executable: ({ operation, ctx }) => {
|
|
134
|
+
// Prohibit write operations if the user is not authenticated
|
|
135
|
+
if (isOperation(OperationMutation, operation) && !ctx.get("user")) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
},
|
|
140
|
+
inputFields: () => {
|
|
141
|
+
// Exclude auto-generated fields
|
|
142
|
+
return { exclude: ["createdAt", "updatedAt"] };
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
models: {
|
|
146
|
+
users: {
|
|
147
|
+
// Prohibit data modification
|
|
148
|
+
// operations: { exclude: ["mutation"] },
|
|
149
|
+
},
|
|
150
|
+
posts: {
|
|
151
|
+
// Fields that cannot be overwritten
|
|
152
|
+
// inputFields: () => ({ exclude: ["createdAt", "updatedAt"] }), // Defined in "all", so commented out
|
|
153
|
+
// Set the current user's ID when writing data
|
|
154
|
+
inputData: ({ ctx }) => {
|
|
155
|
+
const user = ctx.get("user");
|
|
156
|
+
if (!user) throw new Error("No permission");
|
|
157
|
+
return { authorId: user.id };
|
|
158
|
+
},
|
|
159
|
+
where: ({ ctx, operation }) => {
|
|
160
|
+
// When querying, only return published data or the user's own data
|
|
161
|
+
if (isOperation(OperationQuery, operation)) {
|
|
162
|
+
return {
|
|
163
|
+
OR: [
|
|
164
|
+
{ published: true },
|
|
165
|
+
{ authorId: { eq: ctx.get("user")?.id } },
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// When writing, only allow operations on the user's own data
|
|
170
|
+
if (isOperation(OperationMutation, operation)) {
|
|
171
|
+
return { authorId: ctx.get("user")?.id };
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
88
180
|
# Current implementation status
|
|
89
181
|
|
|
90
182
|
## Operations
|
|
@@ -15,9 +15,8 @@ class PothosDrizzleGeneratorPlugin extends core_1.BasePlugin {
|
|
|
15
15
|
beforeBuild() {
|
|
16
16
|
const generator = this.generator;
|
|
17
17
|
const builder = this.builder;
|
|
18
|
-
const depthLimit = generator.getDepthLimit();
|
|
19
18
|
const tables = generator.getTables();
|
|
20
|
-
for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, },] of Object.entries(tables)) {
|
|
19
|
+
for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, depthLimit, },] of Object.entries(tables)) {
|
|
21
20
|
const objectRef = builder.objectRef(modelName);
|
|
22
21
|
objectRef.implement({
|
|
23
22
|
fields: (t) => Object.fromEntries(columns.map((c) => {
|
package/dist/cjs/generator.d.ts
CHANGED
|
@@ -9,31 +9,36 @@ type ModelData = {
|
|
|
9
9
|
inputColumns: PgColumn<any, object>[];
|
|
10
10
|
tableInfo: ReturnType<typeof getTableConfig>;
|
|
11
11
|
relations: RelationsRecord;
|
|
12
|
-
executable?: (params: {
|
|
12
|
+
executable?: ((params: {
|
|
13
13
|
ctx: any;
|
|
14
14
|
modelName: string;
|
|
15
15
|
operation: (typeof OperationBasic)[number];
|
|
16
|
-
}) => boolean | undefined;
|
|
17
|
-
limit?: (params: {
|
|
16
|
+
}) => boolean | undefined) | undefined;
|
|
17
|
+
limit?: ((params: {
|
|
18
18
|
ctx: any;
|
|
19
19
|
modelName: string;
|
|
20
20
|
operation: (typeof OperationBasic)[number];
|
|
21
|
-
}) => number | undefined;
|
|
22
|
-
orderBy?: (params: {
|
|
21
|
+
}) => number | undefined) | undefined;
|
|
22
|
+
orderBy?: ((params: {
|
|
23
|
+
ctx: any;
|
|
24
|
+
modelName: string;
|
|
25
|
+
operation: (typeof OperationBasic)[number];
|
|
26
|
+
}) => object | undefined) | undefined;
|
|
27
|
+
where?: ((params: {
|
|
23
28
|
ctx: any;
|
|
24
29
|
modelName: string;
|
|
25
30
|
operation: (typeof OperationBasic)[number];
|
|
26
|
-
}) => object | undefined;
|
|
27
|
-
|
|
31
|
+
}) => object | undefined) | undefined;
|
|
32
|
+
inputData?: ((params: {
|
|
28
33
|
ctx: any;
|
|
29
34
|
modelName: string;
|
|
30
35
|
operation: (typeof OperationBasic)[number];
|
|
31
|
-
}) => object | undefined;
|
|
32
|
-
|
|
36
|
+
}) => object | undefined) | undefined;
|
|
37
|
+
depthLimit?: ((params: {
|
|
33
38
|
ctx: any;
|
|
34
39
|
modelName: string;
|
|
35
40
|
operation: (typeof OperationBasic)[number];
|
|
36
|
-
}) =>
|
|
41
|
+
}) => number | undefined) | undefined;
|
|
37
42
|
};
|
|
38
43
|
export declare class PothosDrizzleGenerator {
|
|
39
44
|
enums: Record<string, PothosSchemaTypes.EnumRef<any, any>>;
|
|
@@ -46,11 +51,6 @@ export declare class PothosDrizzleGenerator {
|
|
|
46
51
|
getClient(ctx: any): DrizzleClient;
|
|
47
52
|
getRelations(): AnyRelations;
|
|
48
53
|
getTables(): Record<string, ModelData>;
|
|
49
|
-
getDepthLimit(): ((params: {
|
|
50
|
-
ctx: any;
|
|
51
|
-
modelName: string | number | symbol;
|
|
52
|
-
operation: (typeof OperationBasic)[number];
|
|
53
|
-
}) => number | undefined) | undefined;
|
|
54
54
|
getInputType(modelName: string, type: string, options: PothosSchemaTypes.InputObjectTypeOptions<any, any>): PothosSchemaTypes.InputObjectRef<any, any>;
|
|
55
55
|
getInputCreate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
|
|
56
56
|
getInputUpdate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
|
package/dist/cjs/generator.js
CHANGED
|
@@ -23,26 +23,30 @@ class PothosDrizzleGenerator {
|
|
|
23
23
|
const relations = this.getRelations();
|
|
24
24
|
const tables = Object.values(relations)
|
|
25
25
|
.filter((t) => (0, drizzle_orm_1.isTable)(t.table))
|
|
26
|
-
.map(({ name, table, relations }) => {
|
|
26
|
+
.map(({ name: modelName, table, relations }) => {
|
|
27
27
|
const tableInfo = getConfig(table);
|
|
28
|
-
const
|
|
28
|
+
const allOptions = options?.all;
|
|
29
|
+
const modelOptions = options?.models?.[modelName];
|
|
29
30
|
const columns = tableInfo.columns;
|
|
30
31
|
//Operations
|
|
31
|
-
const
|
|
32
|
-
const
|
|
32
|
+
const operationValue = (modelOptions?.operations ?? allOptions?.operations)?.({ modelName });
|
|
33
|
+
const operationIncludes = (0, operations_js_1.expandOperations)(operationValue?.include ?? operations_js_1.OperationBasic);
|
|
34
|
+
const operationExcludes = (0, operations_js_1.expandOperations)(operationValue?.exclude ?? []);
|
|
33
35
|
const operations = operationIncludes.filter((v) => !operationExcludes.includes(v));
|
|
34
36
|
// Columns filter
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
const columnValue = (modelOptions?.fields ?? allOptions?.fields)?.({
|
|
38
|
+
modelName,
|
|
39
|
+
});
|
|
40
|
+
const include = columnValue?.include ?? columns.map((c) => c.name);
|
|
41
|
+
const exclude = columnValue?.exclude ?? [];
|
|
38
42
|
const filterColumns = include.filter((name) => !exclude.includes(name));
|
|
39
43
|
// Input columns filter
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const excludeInput =
|
|
44
|
+
const inputFieldValue = (modelOptions?.inputFields ?? allOptions?.inputFields)?.({ modelName });
|
|
45
|
+
const includeInput = inputFieldValue?.include ?? columns.map((c) => c.name);
|
|
46
|
+
const excludeInput = inputFieldValue?.exclude ?? [];
|
|
43
47
|
const filterInputColumns = includeInput.filter((name) => !excludeInput.includes(name));
|
|
44
48
|
return [
|
|
45
|
-
|
|
49
|
+
modelName,
|
|
46
50
|
{
|
|
47
51
|
table,
|
|
48
52
|
columns: columns.filter((c) => filterColumns.includes(c.name)),
|
|
@@ -50,11 +54,12 @@ class PothosDrizzleGenerator {
|
|
|
50
54
|
inputColumns: columns.filter((c) => filterInputColumns.includes(c.name)),
|
|
51
55
|
tableInfo,
|
|
52
56
|
relations,
|
|
53
|
-
executable: modelOptions?.executable,
|
|
54
|
-
limit: modelOptions?.limit,
|
|
55
|
-
orderBy: modelOptions?.orderBy,
|
|
56
|
-
where: modelOptions?.where,
|
|
57
|
-
inputData: modelOptions?.inputData,
|
|
57
|
+
executable: modelOptions?.executable ?? allOptions?.executable,
|
|
58
|
+
limit: modelOptions?.limit ?? allOptions?.limit,
|
|
59
|
+
orderBy: modelOptions?.orderBy ?? allOptions?.orderBy,
|
|
60
|
+
where: modelOptions?.where ?? allOptions?.where,
|
|
61
|
+
inputData: modelOptions?.inputData ?? allOptions?.inputData,
|
|
62
|
+
depthLimit: modelOptions?.depthLimit ?? allOptions?.depthLimit,
|
|
58
63
|
},
|
|
59
64
|
];
|
|
60
65
|
});
|
|
@@ -85,10 +90,6 @@ class PothosDrizzleGenerator {
|
|
|
85
90
|
this.tables = tables;
|
|
86
91
|
return tables;
|
|
87
92
|
}
|
|
88
|
-
getDepthLimit() {
|
|
89
|
-
const options = this.builder.options.pothosDrizzleGenerator;
|
|
90
|
-
return options?.depthLimit;
|
|
91
|
-
}
|
|
92
93
|
getInputType(modelName, type, options) {
|
|
93
94
|
if (!this.inputType[modelName])
|
|
94
95
|
this.inputType[modelName] = {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SchemaTypes } from "@pothos/core";
|
|
2
|
-
import type { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin";
|
|
3
|
-
import type { DBQueryConfigColumns, GetTableViewFieldSelection, RelationsFilter } from "drizzle-orm";
|
|
1
|
+
import type { SchemaTypes } from "@pothos/core";
|
|
2
|
+
import type { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin.js";
|
|
3
|
+
import type { DBQueryConfigColumns, GetTableViewFieldSelection, RelationsFilter, SchemaEntry } from "drizzle-orm";
|
|
4
4
|
import type { Operation, OperationBasic } from "./libs/operations.js";
|
|
5
5
|
import type { PgInsertValue, PgTable } from "drizzle-orm/pg-core";
|
|
6
6
|
declare global {
|
|
@@ -9,15 +9,12 @@ declare global {
|
|
|
9
9
|
pothosDrizzleGenerator: PothosDrizzleGeneratorPlugin<Types, T>;
|
|
10
10
|
}
|
|
11
11
|
type Relations<Types extends SchemaTypes> = Types["DrizzleRelations"];
|
|
12
|
-
type
|
|
13
|
-
type Columns<Types extends SchemaTypes, U extends
|
|
12
|
+
type TableNames<Types extends SchemaTypes> = keyof Relations<Types>;
|
|
13
|
+
type Columns<Types extends SchemaTypes, U extends TableNames<Types>> = keyof DBQueryConfigColumns<GetTableViewFieldSelection<Relations<Types>[U]["table"]>>;
|
|
14
|
+
type AnyTable<Types extends SchemaTypes> = Relations<Types>[keyof Relations<Types>]["table"];
|
|
15
|
+
type AnyColumns<Types extends SchemaTypes> = AnyTable<Types> extends infer R ? R extends SchemaEntry ? keyof DBQueryConfigColumns<GetTableViewFieldSelection<R>> : never : never;
|
|
14
16
|
interface SchemaBuilderOptions<Types extends SchemaTypes> {
|
|
15
17
|
pothosDrizzleGenerator?: {
|
|
16
|
-
depthLimit?: (params: {
|
|
17
|
-
ctx: Types["Context"];
|
|
18
|
-
modelName: Tables<Types>;
|
|
19
|
-
operation: (typeof OperationBasic)[number];
|
|
20
|
-
}) => number | undefined;
|
|
21
18
|
use?: {
|
|
22
19
|
include: (keyof Relations<Types>)[];
|
|
23
20
|
exclude?: undefined;
|
|
@@ -25,24 +22,91 @@ declare global {
|
|
|
25
22
|
exclude: (keyof Relations<Types>)[];
|
|
26
23
|
include?: undefined;
|
|
27
24
|
};
|
|
25
|
+
all?: {
|
|
26
|
+
depthLimit?: <U extends TableNames<Types>>(params: {
|
|
27
|
+
ctx: Types["Context"];
|
|
28
|
+
modelName: U;
|
|
29
|
+
operation: (typeof OperationBasic)[number];
|
|
30
|
+
}) => number | undefined;
|
|
31
|
+
fields?: <U extends TableNames<Types>>(params: {
|
|
32
|
+
modelName: U;
|
|
33
|
+
}) => {
|
|
34
|
+
include: AnyColumns<Types>[];
|
|
35
|
+
exclude?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
exclude: AnyColumns<Types>[];
|
|
38
|
+
include?: undefined;
|
|
39
|
+
} | undefined;
|
|
40
|
+
operations?: <U extends TableNames<Types>>(params: {
|
|
41
|
+
modelName: U;
|
|
42
|
+
}) => {
|
|
43
|
+
include?: Operation[];
|
|
44
|
+
exclude?: Operation[];
|
|
45
|
+
} | undefined;
|
|
46
|
+
executable?: <U extends TableNames<Types>>(params: {
|
|
47
|
+
ctx: Types["Context"];
|
|
48
|
+
modelName: U;
|
|
49
|
+
operation: (typeof OperationBasic)[number];
|
|
50
|
+
}) => boolean | undefined;
|
|
51
|
+
limit?: <U extends TableNames<Types>>(params: {
|
|
52
|
+
ctx: Types["Context"];
|
|
53
|
+
modelName: U;
|
|
54
|
+
operation: (typeof OperationBasic)[number];
|
|
55
|
+
}) => number | undefined;
|
|
56
|
+
orderBy?: <U extends TableNames<Types>>(params: {
|
|
57
|
+
ctx: Types["Context"];
|
|
58
|
+
modelName: U;
|
|
59
|
+
operation: (typeof OperationBasic)[number];
|
|
60
|
+
}) => {
|
|
61
|
+
[P in AnyColumns<Types>]?: "asc" | "desc";
|
|
62
|
+
} | undefined;
|
|
63
|
+
where?: <U extends TableNames<Types>>(params: {
|
|
64
|
+
ctx: Types["Context"];
|
|
65
|
+
modelName: U;
|
|
66
|
+
operation: (typeof OperationBasic)[number];
|
|
67
|
+
}) => RelationsFilter<Relations<Types>[U], Relations<Types>> | undefined;
|
|
68
|
+
inputFields?: <U extends TableNames<Types>>(params: {
|
|
69
|
+
modelName: U;
|
|
70
|
+
}) => {
|
|
71
|
+
include: AnyColumns<Types>[];
|
|
72
|
+
exclude?: undefined;
|
|
73
|
+
} | {
|
|
74
|
+
exclude: AnyColumns<Types>[];
|
|
75
|
+
include?: undefined;
|
|
76
|
+
} | undefined;
|
|
77
|
+
inputData?: <U extends TableNames<Types>>(params: {
|
|
78
|
+
ctx: Types["Context"];
|
|
79
|
+
modelName: U;
|
|
80
|
+
operation: (typeof OperationBasic)[number];
|
|
81
|
+
}) => PgInsertValue<Relations<Types>[U]["table"] extends PgTable ? Relations<Types>[U]["table"] : never, true> | undefined;
|
|
82
|
+
};
|
|
28
83
|
models?: {
|
|
29
|
-
[U in
|
|
30
|
-
|
|
84
|
+
[U in TableNames<Types>]?: {
|
|
85
|
+
depthLimit?: (params: {
|
|
86
|
+
ctx: Types["Context"];
|
|
87
|
+
modelName: U;
|
|
88
|
+
operation: (typeof OperationBasic)[number];
|
|
89
|
+
}) => number | undefined;
|
|
90
|
+
fields?: (params: {
|
|
91
|
+
modelName: U;
|
|
92
|
+
}) => {
|
|
31
93
|
include: Columns<Types, U>[];
|
|
32
94
|
exclude?: undefined;
|
|
33
95
|
} | {
|
|
34
96
|
exclude: Columns<Types, U>[];
|
|
35
97
|
include?: undefined;
|
|
36
98
|
};
|
|
37
|
-
operations?: {
|
|
99
|
+
operations?: <U extends TableNames<Types>>(params: {
|
|
100
|
+
modelName: U;
|
|
101
|
+
}) => {
|
|
38
102
|
include?: Operation[];
|
|
39
103
|
exclude?: Operation[];
|
|
40
|
-
};
|
|
104
|
+
} | undefined;
|
|
41
105
|
executable?: (params: {
|
|
42
106
|
ctx: Types["Context"];
|
|
43
107
|
modelName: U;
|
|
44
108
|
operation: (typeof OperationBasic)[number];
|
|
45
|
-
}) => boolean;
|
|
109
|
+
}) => boolean | undefined;
|
|
46
110
|
limit?: (params: {
|
|
47
111
|
ctx: Types["Context"];
|
|
48
112
|
modelName: U;
|
|
@@ -60,7 +124,9 @@ declare global {
|
|
|
60
124
|
modelName: U;
|
|
61
125
|
operation: (typeof OperationBasic)[number];
|
|
62
126
|
}) => RelationsFilter<Relations<Types>[U], Relations<Types>> | undefined;
|
|
63
|
-
inputFields?: {
|
|
127
|
+
inputFields?: (params: {
|
|
128
|
+
modelName: U;
|
|
129
|
+
}) => {
|
|
64
130
|
include: Columns<Types, U>[];
|
|
65
131
|
exclude?: undefined;
|
|
66
132
|
} | {
|
package/dist/cjs/libs/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as p from "drizzle-orm";
|
|
2
|
-
import { GraphQLResolveInfo } from "graphql";
|
|
2
|
+
import type { GraphQLResolveInfo } from "graphql";
|
|
3
3
|
export declare function getQueryDepth(info: GraphQLResolveInfo): number;
|
|
4
4
|
export declare const getQueryFields: (info: GraphQLResolveInfo) => {
|
|
5
5
|
[k: string]: boolean;
|
package/dist/cjs/libs/utils.js
CHANGED
|
@@ -46,9 +46,13 @@ function getDepthFromSelection(selection, currentDepth) {
|
|
|
46
46
|
return currentDepth;
|
|
47
47
|
}
|
|
48
48
|
function getQueryDepth(info) {
|
|
49
|
+
if (!info.fieldNodes[0])
|
|
50
|
+
return 0;
|
|
49
51
|
return getDepthFromSelection(info.fieldNodes[0], 0);
|
|
50
52
|
}
|
|
51
53
|
const getQueryFields = (info) => {
|
|
54
|
+
if (!info.fieldNodes[0])
|
|
55
|
+
return {};
|
|
52
56
|
return Object.fromEntries(Array.from((0, utils_1.collectFields)(info.schema, info.fragments, info.variableValues, {}, info.fieldNodes[0].selectionSet).fields.keys()).map((v) => [v, true]));
|
|
53
57
|
};
|
|
54
58
|
exports.getQueryFields = getQueryFields;
|
|
@@ -12,9 +12,8 @@ export class PothosDrizzleGeneratorPlugin extends BasePlugin {
|
|
|
12
12
|
beforeBuild() {
|
|
13
13
|
const generator = this.generator;
|
|
14
14
|
const builder = this.builder;
|
|
15
|
-
const depthLimit = generator.getDepthLimit();
|
|
16
15
|
const tables = generator.getTables();
|
|
17
|
-
for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, },] of Object.entries(tables)) {
|
|
16
|
+
for (const [modelName, { table, tableInfo, relations, columns, operations, executable, limit, where, orderBy, inputData, depthLimit, },] of Object.entries(tables)) {
|
|
18
17
|
const objectRef = builder.objectRef(modelName);
|
|
19
18
|
objectRef.implement({
|
|
20
19
|
fields: (t) => Object.fromEntries(columns.map((c) => {
|
package/dist/esm/generator.d.ts
CHANGED
|
@@ -9,31 +9,36 @@ type ModelData = {
|
|
|
9
9
|
inputColumns: PgColumn<any, object>[];
|
|
10
10
|
tableInfo: ReturnType<typeof getTableConfig>;
|
|
11
11
|
relations: RelationsRecord;
|
|
12
|
-
executable?: (params: {
|
|
12
|
+
executable?: ((params: {
|
|
13
13
|
ctx: any;
|
|
14
14
|
modelName: string;
|
|
15
15
|
operation: (typeof OperationBasic)[number];
|
|
16
|
-
}) => boolean | undefined;
|
|
17
|
-
limit?: (params: {
|
|
16
|
+
}) => boolean | undefined) | undefined;
|
|
17
|
+
limit?: ((params: {
|
|
18
18
|
ctx: any;
|
|
19
19
|
modelName: string;
|
|
20
20
|
operation: (typeof OperationBasic)[number];
|
|
21
|
-
}) => number | undefined;
|
|
22
|
-
orderBy?: (params: {
|
|
21
|
+
}) => number | undefined) | undefined;
|
|
22
|
+
orderBy?: ((params: {
|
|
23
|
+
ctx: any;
|
|
24
|
+
modelName: string;
|
|
25
|
+
operation: (typeof OperationBasic)[number];
|
|
26
|
+
}) => object | undefined) | undefined;
|
|
27
|
+
where?: ((params: {
|
|
23
28
|
ctx: any;
|
|
24
29
|
modelName: string;
|
|
25
30
|
operation: (typeof OperationBasic)[number];
|
|
26
|
-
}) => object | undefined;
|
|
27
|
-
|
|
31
|
+
}) => object | undefined) | undefined;
|
|
32
|
+
inputData?: ((params: {
|
|
28
33
|
ctx: any;
|
|
29
34
|
modelName: string;
|
|
30
35
|
operation: (typeof OperationBasic)[number];
|
|
31
|
-
}) => object | undefined;
|
|
32
|
-
|
|
36
|
+
}) => object | undefined) | undefined;
|
|
37
|
+
depthLimit?: ((params: {
|
|
33
38
|
ctx: any;
|
|
34
39
|
modelName: string;
|
|
35
40
|
operation: (typeof OperationBasic)[number];
|
|
36
|
-
}) =>
|
|
41
|
+
}) => number | undefined) | undefined;
|
|
37
42
|
};
|
|
38
43
|
export declare class PothosDrizzleGenerator {
|
|
39
44
|
enums: Record<string, PothosSchemaTypes.EnumRef<any, any>>;
|
|
@@ -46,11 +51,6 @@ export declare class PothosDrizzleGenerator {
|
|
|
46
51
|
getClient(ctx: any): DrizzleClient;
|
|
47
52
|
getRelations(): AnyRelations;
|
|
48
53
|
getTables(): Record<string, ModelData>;
|
|
49
|
-
getDepthLimit(): ((params: {
|
|
50
|
-
ctx: any;
|
|
51
|
-
modelName: string | number | symbol;
|
|
52
|
-
operation: (typeof OperationBasic)[number];
|
|
53
|
-
}) => number | undefined) | undefined;
|
|
54
54
|
getInputType(modelName: string, type: string, options: PothosSchemaTypes.InputObjectTypeOptions<any, any>): PothosSchemaTypes.InputObjectRef<any, any>;
|
|
55
55
|
getInputCreate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
|
|
56
56
|
getInputUpdate(modelName: string): PothosSchemaTypes.InputObjectRef<any, any>;
|
package/dist/esm/generator.js
CHANGED
|
@@ -20,26 +20,30 @@ export class PothosDrizzleGenerator {
|
|
|
20
20
|
const relations = this.getRelations();
|
|
21
21
|
const tables = Object.values(relations)
|
|
22
22
|
.filter((t) => isTable(t.table))
|
|
23
|
-
.map(({ name, table, relations }) => {
|
|
23
|
+
.map(({ name: modelName, table, relations }) => {
|
|
24
24
|
const tableInfo = getConfig(table);
|
|
25
|
-
const
|
|
25
|
+
const allOptions = options?.all;
|
|
26
|
+
const modelOptions = options?.models?.[modelName];
|
|
26
27
|
const columns = tableInfo.columns;
|
|
27
28
|
//Operations
|
|
28
|
-
const
|
|
29
|
-
const
|
|
29
|
+
const operationValue = (modelOptions?.operations ?? allOptions?.operations)?.({ modelName });
|
|
30
|
+
const operationIncludes = expandOperations(operationValue?.include ?? OperationBasic);
|
|
31
|
+
const operationExcludes = expandOperations(operationValue?.exclude ?? []);
|
|
30
32
|
const operations = operationIncludes.filter((v) => !operationExcludes.includes(v));
|
|
31
33
|
// Columns filter
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const columnValue = (modelOptions?.fields ?? allOptions?.fields)?.({
|
|
35
|
+
modelName,
|
|
36
|
+
});
|
|
37
|
+
const include = columnValue?.include ?? columns.map((c) => c.name);
|
|
38
|
+
const exclude = columnValue?.exclude ?? [];
|
|
35
39
|
const filterColumns = include.filter((name) => !exclude.includes(name));
|
|
36
40
|
// Input columns filter
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const excludeInput =
|
|
41
|
+
const inputFieldValue = (modelOptions?.inputFields ?? allOptions?.inputFields)?.({ modelName });
|
|
42
|
+
const includeInput = inputFieldValue?.include ?? columns.map((c) => c.name);
|
|
43
|
+
const excludeInput = inputFieldValue?.exclude ?? [];
|
|
40
44
|
const filterInputColumns = includeInput.filter((name) => !excludeInput.includes(name));
|
|
41
45
|
return [
|
|
42
|
-
|
|
46
|
+
modelName,
|
|
43
47
|
{
|
|
44
48
|
table,
|
|
45
49
|
columns: columns.filter((c) => filterColumns.includes(c.name)),
|
|
@@ -47,11 +51,12 @@ export class PothosDrizzleGenerator {
|
|
|
47
51
|
inputColumns: columns.filter((c) => filterInputColumns.includes(c.name)),
|
|
48
52
|
tableInfo,
|
|
49
53
|
relations,
|
|
50
|
-
executable: modelOptions?.executable,
|
|
51
|
-
limit: modelOptions?.limit,
|
|
52
|
-
orderBy: modelOptions?.orderBy,
|
|
53
|
-
where: modelOptions?.where,
|
|
54
|
-
inputData: modelOptions?.inputData,
|
|
54
|
+
executable: modelOptions?.executable ?? allOptions?.executable,
|
|
55
|
+
limit: modelOptions?.limit ?? allOptions?.limit,
|
|
56
|
+
orderBy: modelOptions?.orderBy ?? allOptions?.orderBy,
|
|
57
|
+
where: modelOptions?.where ?? allOptions?.where,
|
|
58
|
+
inputData: modelOptions?.inputData ?? allOptions?.inputData,
|
|
59
|
+
depthLimit: modelOptions?.depthLimit ?? allOptions?.depthLimit,
|
|
55
60
|
},
|
|
56
61
|
];
|
|
57
62
|
});
|
|
@@ -82,10 +87,6 @@ export class PothosDrizzleGenerator {
|
|
|
82
87
|
this.tables = tables;
|
|
83
88
|
return tables;
|
|
84
89
|
}
|
|
85
|
-
getDepthLimit() {
|
|
86
|
-
const options = this.builder.options.pothosDrizzleGenerator;
|
|
87
|
-
return options?.depthLimit;
|
|
88
|
-
}
|
|
89
90
|
getInputType(modelName, type, options) {
|
|
90
91
|
if (!this.inputType[modelName])
|
|
91
92
|
this.inputType[modelName] = {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SchemaTypes } from "@pothos/core";
|
|
2
|
-
import type { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin";
|
|
3
|
-
import type { DBQueryConfigColumns, GetTableViewFieldSelection, RelationsFilter } from "drizzle-orm";
|
|
1
|
+
import type { SchemaTypes } from "@pothos/core";
|
|
2
|
+
import type { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin.js";
|
|
3
|
+
import type { DBQueryConfigColumns, GetTableViewFieldSelection, RelationsFilter, SchemaEntry } from "drizzle-orm";
|
|
4
4
|
import type { Operation, OperationBasic } from "./libs/operations.js";
|
|
5
5
|
import type { PgInsertValue, PgTable } from "drizzle-orm/pg-core";
|
|
6
6
|
declare global {
|
|
@@ -9,15 +9,12 @@ declare global {
|
|
|
9
9
|
pothosDrizzleGenerator: PothosDrizzleGeneratorPlugin<Types, T>;
|
|
10
10
|
}
|
|
11
11
|
type Relations<Types extends SchemaTypes> = Types["DrizzleRelations"];
|
|
12
|
-
type
|
|
13
|
-
type Columns<Types extends SchemaTypes, U extends
|
|
12
|
+
type TableNames<Types extends SchemaTypes> = keyof Relations<Types>;
|
|
13
|
+
type Columns<Types extends SchemaTypes, U extends TableNames<Types>> = keyof DBQueryConfigColumns<GetTableViewFieldSelection<Relations<Types>[U]["table"]>>;
|
|
14
|
+
type AnyTable<Types extends SchemaTypes> = Relations<Types>[keyof Relations<Types>]["table"];
|
|
15
|
+
type AnyColumns<Types extends SchemaTypes> = AnyTable<Types> extends infer R ? R extends SchemaEntry ? keyof DBQueryConfigColumns<GetTableViewFieldSelection<R>> : never : never;
|
|
14
16
|
interface SchemaBuilderOptions<Types extends SchemaTypes> {
|
|
15
17
|
pothosDrizzleGenerator?: {
|
|
16
|
-
depthLimit?: (params: {
|
|
17
|
-
ctx: Types["Context"];
|
|
18
|
-
modelName: Tables<Types>;
|
|
19
|
-
operation: (typeof OperationBasic)[number];
|
|
20
|
-
}) => number | undefined;
|
|
21
18
|
use?: {
|
|
22
19
|
include: (keyof Relations<Types>)[];
|
|
23
20
|
exclude?: undefined;
|
|
@@ -25,24 +22,91 @@ declare global {
|
|
|
25
22
|
exclude: (keyof Relations<Types>)[];
|
|
26
23
|
include?: undefined;
|
|
27
24
|
};
|
|
25
|
+
all?: {
|
|
26
|
+
depthLimit?: <U extends TableNames<Types>>(params: {
|
|
27
|
+
ctx: Types["Context"];
|
|
28
|
+
modelName: U;
|
|
29
|
+
operation: (typeof OperationBasic)[number];
|
|
30
|
+
}) => number | undefined;
|
|
31
|
+
fields?: <U extends TableNames<Types>>(params: {
|
|
32
|
+
modelName: U;
|
|
33
|
+
}) => {
|
|
34
|
+
include: AnyColumns<Types>[];
|
|
35
|
+
exclude?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
exclude: AnyColumns<Types>[];
|
|
38
|
+
include?: undefined;
|
|
39
|
+
} | undefined;
|
|
40
|
+
operations?: <U extends TableNames<Types>>(params: {
|
|
41
|
+
modelName: U;
|
|
42
|
+
}) => {
|
|
43
|
+
include?: Operation[];
|
|
44
|
+
exclude?: Operation[];
|
|
45
|
+
} | undefined;
|
|
46
|
+
executable?: <U extends TableNames<Types>>(params: {
|
|
47
|
+
ctx: Types["Context"];
|
|
48
|
+
modelName: U;
|
|
49
|
+
operation: (typeof OperationBasic)[number];
|
|
50
|
+
}) => boolean | undefined;
|
|
51
|
+
limit?: <U extends TableNames<Types>>(params: {
|
|
52
|
+
ctx: Types["Context"];
|
|
53
|
+
modelName: U;
|
|
54
|
+
operation: (typeof OperationBasic)[number];
|
|
55
|
+
}) => number | undefined;
|
|
56
|
+
orderBy?: <U extends TableNames<Types>>(params: {
|
|
57
|
+
ctx: Types["Context"];
|
|
58
|
+
modelName: U;
|
|
59
|
+
operation: (typeof OperationBasic)[number];
|
|
60
|
+
}) => {
|
|
61
|
+
[P in AnyColumns<Types>]?: "asc" | "desc";
|
|
62
|
+
} | undefined;
|
|
63
|
+
where?: <U extends TableNames<Types>>(params: {
|
|
64
|
+
ctx: Types["Context"];
|
|
65
|
+
modelName: U;
|
|
66
|
+
operation: (typeof OperationBasic)[number];
|
|
67
|
+
}) => RelationsFilter<Relations<Types>[U], Relations<Types>> | undefined;
|
|
68
|
+
inputFields?: <U extends TableNames<Types>>(params: {
|
|
69
|
+
modelName: U;
|
|
70
|
+
}) => {
|
|
71
|
+
include: AnyColumns<Types>[];
|
|
72
|
+
exclude?: undefined;
|
|
73
|
+
} | {
|
|
74
|
+
exclude: AnyColumns<Types>[];
|
|
75
|
+
include?: undefined;
|
|
76
|
+
} | undefined;
|
|
77
|
+
inputData?: <U extends TableNames<Types>>(params: {
|
|
78
|
+
ctx: Types["Context"];
|
|
79
|
+
modelName: U;
|
|
80
|
+
operation: (typeof OperationBasic)[number];
|
|
81
|
+
}) => PgInsertValue<Relations<Types>[U]["table"] extends PgTable ? Relations<Types>[U]["table"] : never, true> | undefined;
|
|
82
|
+
};
|
|
28
83
|
models?: {
|
|
29
|
-
[U in
|
|
30
|
-
|
|
84
|
+
[U in TableNames<Types>]?: {
|
|
85
|
+
depthLimit?: (params: {
|
|
86
|
+
ctx: Types["Context"];
|
|
87
|
+
modelName: U;
|
|
88
|
+
operation: (typeof OperationBasic)[number];
|
|
89
|
+
}) => number | undefined;
|
|
90
|
+
fields?: (params: {
|
|
91
|
+
modelName: U;
|
|
92
|
+
}) => {
|
|
31
93
|
include: Columns<Types, U>[];
|
|
32
94
|
exclude?: undefined;
|
|
33
95
|
} | {
|
|
34
96
|
exclude: Columns<Types, U>[];
|
|
35
97
|
include?: undefined;
|
|
36
98
|
};
|
|
37
|
-
operations?: {
|
|
99
|
+
operations?: <U extends TableNames<Types>>(params: {
|
|
100
|
+
modelName: U;
|
|
101
|
+
}) => {
|
|
38
102
|
include?: Operation[];
|
|
39
103
|
exclude?: Operation[];
|
|
40
|
-
};
|
|
104
|
+
} | undefined;
|
|
41
105
|
executable?: (params: {
|
|
42
106
|
ctx: Types["Context"];
|
|
43
107
|
modelName: U;
|
|
44
108
|
operation: (typeof OperationBasic)[number];
|
|
45
|
-
}) => boolean;
|
|
109
|
+
}) => boolean | undefined;
|
|
46
110
|
limit?: (params: {
|
|
47
111
|
ctx: Types["Context"];
|
|
48
112
|
modelName: U;
|
|
@@ -60,7 +124,9 @@ declare global {
|
|
|
60
124
|
modelName: U;
|
|
61
125
|
operation: (typeof OperationBasic)[number];
|
|
62
126
|
}) => RelationsFilter<Relations<Types>[U], Relations<Types>> | undefined;
|
|
63
|
-
inputFields?: {
|
|
127
|
+
inputFields?: (params: {
|
|
128
|
+
modelName: U;
|
|
129
|
+
}) => {
|
|
64
130
|
include: Columns<Types, U>[];
|
|
65
131
|
exclude?: undefined;
|
|
66
132
|
} | {
|
package/dist/esm/libs/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as p from "drizzle-orm";
|
|
2
|
-
import { GraphQLResolveInfo } from "graphql";
|
|
2
|
+
import type { GraphQLResolveInfo } from "graphql";
|
|
3
3
|
export declare function getQueryDepth(info: GraphQLResolveInfo): number;
|
|
4
4
|
export declare const getQueryFields: (info: GraphQLResolveInfo) => {
|
|
5
5
|
[k: string]: boolean;
|
package/dist/esm/libs/utils.js
CHANGED
|
@@ -9,9 +9,13 @@ function getDepthFromSelection(selection, currentDepth) {
|
|
|
9
9
|
return currentDepth;
|
|
10
10
|
}
|
|
11
11
|
export function getQueryDepth(info) {
|
|
12
|
+
if (!info.fieldNodes[0])
|
|
13
|
+
return 0;
|
|
12
14
|
return getDepthFromSelection(info.fieldNodes[0], 0);
|
|
13
15
|
}
|
|
14
16
|
export const getQueryFields = (info) => {
|
|
17
|
+
if (!info.fieldNodes[0])
|
|
18
|
+
return {};
|
|
15
19
|
return Object.fromEntries(Array.from(collectFields(info.schema, info.fragments, info.variableValues, {}, info.fieldNodes[0].selectionSet).fields.keys()).map((v) => [v, true]));
|
|
16
20
|
};
|
|
17
21
|
const OperatorMap = {
|