pothos-drizzle-generator 0.0.1
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/LICENSE +21 -0
- package/README.md +127 -0
- package/dist/cjs/PothosDrizzleGeneratorPlugin.d.ts +7 -0
- package/dist/cjs/PothosDrizzleGeneratorPlugin.js +399 -0
- package/dist/cjs/generator.d.ts +63 -0
- package/dist/cjs/generator.js +231 -0
- package/dist/cjs/global-types.d.ts +80 -0
- package/dist/cjs/global-types.js +2 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +28 -0
- package/dist/cjs/libs/operations.d.ts +11 -0
- package/dist/cjs/libs/operations.js +45 -0
- package/dist/cjs/libs/utils.d.ts +58 -0
- package/dist/cjs/libs/utils.js +149 -0
- package/dist/esm/PothosDrizzleGeneratorPlugin.d.ts +7 -0
- package/dist/esm/PothosDrizzleGeneratorPlugin.js +395 -0
- package/dist/esm/generator.d.ts +63 -0
- package/dist/esm/generator.js +227 -0
- package/dist/esm/global-types.d.ts +80 -0
- package/dist/esm/global-types.js +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/libs/operations.d.ts +11 -0
- package/dist/esm/libs/operations.js +40 -0
- package/dist/esm/libs/utils.d.ts +58 -0
- package/dist/esm/libs/utils.js +108 -0
- package/dist/esm/package.json +3 -0
- package/eslint.config.mjs +43 -0
- package/package.json +40 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SchemaTypes } from "@pothos/core";
|
|
2
|
+
import type { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin";
|
|
3
|
+
import type { DBQueryConfigColumns, GetTableViewFieldSelection, RelationsFilter } from "drizzle-orm";
|
|
4
|
+
import type { Operation, OperationBasic } from "./libs/operations.js";
|
|
5
|
+
import type { PgInsertValue, PgTable } from "drizzle-orm/pg-core";
|
|
6
|
+
declare global {
|
|
7
|
+
export namespace PothosSchemaTypes {
|
|
8
|
+
interface Plugins<Types extends SchemaTypes, T extends object = object> {
|
|
9
|
+
pothosDrizzleGenerator: PothosDrizzleGeneratorPlugin<Types, T>;
|
|
10
|
+
}
|
|
11
|
+
type Relations<Types extends SchemaTypes> = Types["DrizzleRelations"];
|
|
12
|
+
type Tables<Types extends SchemaTypes> = keyof Relations<Types>;
|
|
13
|
+
type Columns<Types extends SchemaTypes, U extends Tables<Types>> = keyof DBQueryConfigColumns<GetTableViewFieldSelection<Relations<Types>[U]["table"]>>;
|
|
14
|
+
interface SchemaBuilderOptions<Types extends SchemaTypes> {
|
|
15
|
+
pothosDrizzleGenerator?: {
|
|
16
|
+
depthLimit?: (params: {
|
|
17
|
+
ctx: Types["Context"];
|
|
18
|
+
modelName: Tables<Types>;
|
|
19
|
+
operation: (typeof OperationBasic)[number];
|
|
20
|
+
}) => number | undefined;
|
|
21
|
+
use?: {
|
|
22
|
+
include: (keyof Relations<Types>)[];
|
|
23
|
+
exclude?: undefined;
|
|
24
|
+
} | {
|
|
25
|
+
exclude: (keyof Relations<Types>)[];
|
|
26
|
+
include?: undefined;
|
|
27
|
+
};
|
|
28
|
+
models?: {
|
|
29
|
+
[U in Tables<Types>]?: {
|
|
30
|
+
fields?: {
|
|
31
|
+
include: Columns<Types, U>[];
|
|
32
|
+
exclude?: undefined;
|
|
33
|
+
} | {
|
|
34
|
+
exclude: Columns<Types, U>[];
|
|
35
|
+
include?: undefined;
|
|
36
|
+
};
|
|
37
|
+
operations?: {
|
|
38
|
+
include?: Operation[];
|
|
39
|
+
exclude?: Operation[];
|
|
40
|
+
};
|
|
41
|
+
executable?: (params: {
|
|
42
|
+
ctx: Types["Context"];
|
|
43
|
+
modelName: U;
|
|
44
|
+
operation: (typeof OperationBasic)[number];
|
|
45
|
+
}) => boolean;
|
|
46
|
+
limit?: (params: {
|
|
47
|
+
ctx: Types["Context"];
|
|
48
|
+
modelName: U;
|
|
49
|
+
operation: (typeof OperationBasic)[number];
|
|
50
|
+
}) => number | undefined;
|
|
51
|
+
orderBy?: (params: {
|
|
52
|
+
ctx: Types["Context"];
|
|
53
|
+
modelName: U;
|
|
54
|
+
operation: (typeof OperationBasic)[number];
|
|
55
|
+
}) => {
|
|
56
|
+
[P in Columns<Types, U>]?: "asc" | "desc";
|
|
57
|
+
} | undefined;
|
|
58
|
+
where?: (params: {
|
|
59
|
+
ctx: Types["Context"];
|
|
60
|
+
modelName: U;
|
|
61
|
+
operation: (typeof OperationBasic)[number];
|
|
62
|
+
}) => RelationsFilter<Relations<Types>[U], Relations<Types>> | undefined;
|
|
63
|
+
inputFields?: {
|
|
64
|
+
include: Columns<Types, U>[];
|
|
65
|
+
exclude?: undefined;
|
|
66
|
+
} | {
|
|
67
|
+
exclude: Columns<Types, U>[];
|
|
68
|
+
include?: undefined;
|
|
69
|
+
};
|
|
70
|
+
inputData?: (params: {
|
|
71
|
+
ctx: Types["Context"];
|
|
72
|
+
modelName: U;
|
|
73
|
+
operation: (typeof OperationBasic)[number];
|
|
74
|
+
}) => PgInsertValue<Relations<Types>[U]["table"] extends PgTable ? Relations<Types>[U]["table"] : never, true> | undefined;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import SchemaBuilder from "@pothos/core";
|
|
2
|
+
import { PothosDrizzleGeneratorPlugin } from "./PothosDrizzleGeneratorPlugin.js";
|
|
3
|
+
export * from "./global-types.js";
|
|
4
|
+
const pluginName = "pothosDrizzleGenerator";
|
|
5
|
+
const allowPluginReRegistration = SchemaBuilder.allowPluginReRegistration;
|
|
6
|
+
SchemaBuilder.allowPluginReRegistration = true;
|
|
7
|
+
SchemaBuilder.registerPlugin(pluginName, PothosDrizzleGeneratorPlugin);
|
|
8
|
+
SchemaBuilder.allowPluginReRegistration = allowPluginReRegistration;
|
|
9
|
+
export default pluginName;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const OperationFind: readonly ["findFirst", "findMany"];
|
|
2
|
+
export declare const OperationQuery: readonly ["findFirst", "findMany", "count"];
|
|
3
|
+
export declare const OperationCreate: readonly ["createOne", "createMany"];
|
|
4
|
+
export declare const OperationUpdate: readonly ["update"];
|
|
5
|
+
export declare const OperationDelete: readonly ["delete"];
|
|
6
|
+
export declare const OperationMutation: readonly ["createOne", "createMany", "update", "delete"];
|
|
7
|
+
export declare const OperationBasic: readonly ["findFirst", "findMany", "count", "createOne", "createMany", "update", "delete"];
|
|
8
|
+
export declare const OperationAll: readonly ["find", "update", "delete", "query", "mutation", "findFirst", "findMany", "count", "createOne", "createMany", "update", "delete"];
|
|
9
|
+
export type Operation = (typeof OperationAll)[number] | "all";
|
|
10
|
+
export declare const expandOperations: (operations: readonly Operation[]) => ("findFirst" | "findMany" | "count" | "createOne" | "createMany" | "update" | "delete")[];
|
|
11
|
+
export declare const isOperation: (operations: readonly string[], operation: (typeof OperationBasic)[number]) => boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const OperationFind = ["findFirst", "findMany"];
|
|
2
|
+
export const OperationQuery = [...OperationFind, "count"];
|
|
3
|
+
export const OperationCreate = ["createOne", "createMany"];
|
|
4
|
+
export const OperationUpdate = ["update"];
|
|
5
|
+
export const OperationDelete = ["delete"];
|
|
6
|
+
export const OperationMutation = [
|
|
7
|
+
...OperationCreate,
|
|
8
|
+
...OperationUpdate,
|
|
9
|
+
...OperationDelete,
|
|
10
|
+
];
|
|
11
|
+
export const OperationBasic = [
|
|
12
|
+
...OperationQuery,
|
|
13
|
+
...OperationMutation,
|
|
14
|
+
];
|
|
15
|
+
export const OperationAll = [
|
|
16
|
+
"find",
|
|
17
|
+
"update",
|
|
18
|
+
"delete",
|
|
19
|
+
"query",
|
|
20
|
+
"mutation",
|
|
21
|
+
...OperationBasic,
|
|
22
|
+
];
|
|
23
|
+
export const expandOperations = (operations) => {
|
|
24
|
+
return operations.flatMap((v) => v === "all"
|
|
25
|
+
? OperationBasic
|
|
26
|
+
: v === "find"
|
|
27
|
+
? OperationFind
|
|
28
|
+
: v === "update"
|
|
29
|
+
? OperationUpdate
|
|
30
|
+
: v === "delete"
|
|
31
|
+
? OperationDelete
|
|
32
|
+
: v === "query"
|
|
33
|
+
? OperationQuery
|
|
34
|
+
: v === "mutation"
|
|
35
|
+
? OperationMutation
|
|
36
|
+
: [v]);
|
|
37
|
+
};
|
|
38
|
+
export const isOperation = (operations, operation) => {
|
|
39
|
+
return operations.includes(operation);
|
|
40
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as p from "drizzle-orm";
|
|
2
|
+
import { GraphQLResolveInfo } from "graphql";
|
|
3
|
+
export declare function getQueryDepth(info: GraphQLResolveInfo): number;
|
|
4
|
+
export declare const getQueryFields: (info: GraphQLResolveInfo) => {
|
|
5
|
+
[k: string]: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare const OperatorMap: {
|
|
8
|
+
eq: p.BinaryOperator;
|
|
9
|
+
ne: p.BinaryOperator;
|
|
10
|
+
gt: p.BinaryOperator;
|
|
11
|
+
gte: p.BinaryOperator;
|
|
12
|
+
lt: p.BinaryOperator;
|
|
13
|
+
lte: p.BinaryOperator;
|
|
14
|
+
like: typeof p.like;
|
|
15
|
+
notLike: typeof p.notLike;
|
|
16
|
+
ilike: typeof p.ilike;
|
|
17
|
+
notIlike: typeof p.notIlike;
|
|
18
|
+
isNull: typeof p.isNull;
|
|
19
|
+
isNotNull: typeof p.isNotNull;
|
|
20
|
+
in: typeof p.inArray;
|
|
21
|
+
notIn: typeof p.notInArray;
|
|
22
|
+
arrayContained: typeof p.arrayContained;
|
|
23
|
+
arrayOverlaps: typeof p.arrayOverlaps;
|
|
24
|
+
arrayContains: typeof p.arrayContains;
|
|
25
|
+
};
|
|
26
|
+
type OperatorType = Record<string, Record<keyof typeof OperatorMap, unknown>>;
|
|
27
|
+
type OperatorTree = Record<"AND" | "OR", OperatorType[]> | Record<"NOT", OperatorType> | OperatorType;
|
|
28
|
+
export declare const createWhereQuery: (table: p.SchemaEntry, tree?: OperatorTree) => p.SQL | undefined;
|
|
29
|
+
export declare const createInputOperator: (builder: PothosSchemaTypes.SchemaBuilder<any>, type: string | [string]) => PothosSchemaTypes.InputObjectRef<any, {
|
|
30
|
+
eq?: any;
|
|
31
|
+
ne?: any;
|
|
32
|
+
gt?: any;
|
|
33
|
+
gte?: any;
|
|
34
|
+
lt?: any;
|
|
35
|
+
lte?: any;
|
|
36
|
+
like?: any;
|
|
37
|
+
notLike?: any;
|
|
38
|
+
ilike?: any;
|
|
39
|
+
notIlike?: any;
|
|
40
|
+
isNull?: any;
|
|
41
|
+
isNotNull?: any;
|
|
42
|
+
in: never;
|
|
43
|
+
notIn: never;
|
|
44
|
+
arrayContained: never;
|
|
45
|
+
arrayOverlaps: never;
|
|
46
|
+
arrayContains: never;
|
|
47
|
+
}>;
|
|
48
|
+
type AggregationQueryType = {
|
|
49
|
+
aggregation?: boolean;
|
|
50
|
+
columns?: object;
|
|
51
|
+
with: Record<string, AggregationQueryType>;
|
|
52
|
+
};
|
|
53
|
+
export declare const convertAggregationQuery: (query: AggregationQueryType) => {
|
|
54
|
+
with: Record<string, AggregationQueryType>;
|
|
55
|
+
aggregation?: boolean;
|
|
56
|
+
columns?: object;
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { collectFields } from "@graphql-tools/utils";
|
|
2
|
+
import * as p from "drizzle-orm";
|
|
3
|
+
function getDepthFromSelection(selection, currentDepth) {
|
|
4
|
+
if (selection.kind === "Field" && selection.selectionSet) {
|
|
5
|
+
// 子フィールドがある場合はさらに深さを加算
|
|
6
|
+
const childDepths = selection.selectionSet.selections.map((sel) => getDepthFromSelection(sel, currentDepth + 1));
|
|
7
|
+
return Math.max(...childDepths);
|
|
8
|
+
}
|
|
9
|
+
return currentDepth;
|
|
10
|
+
}
|
|
11
|
+
export function getQueryDepth(info) {
|
|
12
|
+
return getDepthFromSelection(info.fieldNodes[0], 0);
|
|
13
|
+
}
|
|
14
|
+
export const getQueryFields = (info) => {
|
|
15
|
+
return Object.fromEntries(Array.from(collectFields(info.schema, info.fragments, info.variableValues, {}, info.fieldNodes[0].selectionSet).fields.keys()).map((v) => [v, true]));
|
|
16
|
+
};
|
|
17
|
+
const OperatorMap = {
|
|
18
|
+
eq: p.eq,
|
|
19
|
+
ne: p.ne,
|
|
20
|
+
gt: p.gt,
|
|
21
|
+
gte: p.gte,
|
|
22
|
+
lt: p.lt,
|
|
23
|
+
lte: p.lte,
|
|
24
|
+
like: p.like,
|
|
25
|
+
notLike: p.notLike,
|
|
26
|
+
ilike: p.ilike,
|
|
27
|
+
notIlike: p.notIlike,
|
|
28
|
+
isNull: p.isNull,
|
|
29
|
+
isNotNull: p.isNotNull,
|
|
30
|
+
in: p.inArray,
|
|
31
|
+
notIn: p.notInArray,
|
|
32
|
+
arrayContained: p.arrayContained,
|
|
33
|
+
arrayOverlaps: p.arrayOverlaps,
|
|
34
|
+
arrayContains: p.arrayContains,
|
|
35
|
+
};
|
|
36
|
+
export const createWhereQuery = (table, tree) => {
|
|
37
|
+
if (!tree)
|
|
38
|
+
return p.and();
|
|
39
|
+
const result = Object.entries(tree)
|
|
40
|
+
.map(([key, value]) => {
|
|
41
|
+
switch (key) {
|
|
42
|
+
case "AND":
|
|
43
|
+
return value.length
|
|
44
|
+
? p.and(...value.map((v) => createWhereQuery(table, v)))
|
|
45
|
+
: undefined;
|
|
46
|
+
case "OR":
|
|
47
|
+
return value.length
|
|
48
|
+
? p.or(...value.map((v) => createWhereQuery(table, v)))
|
|
49
|
+
: undefined;
|
|
50
|
+
case "NOT": {
|
|
51
|
+
const v = createWhereQuery(table, value);
|
|
52
|
+
return v ? p.not(v) : undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const result = Object.entries(value).map(([k, v]) => {
|
|
56
|
+
const m = OperatorMap[k];
|
|
57
|
+
return m(p.getColumns(table)[key], v);
|
|
58
|
+
});
|
|
59
|
+
if (result.length === 1) {
|
|
60
|
+
return result[0];
|
|
61
|
+
}
|
|
62
|
+
return p.and(...result);
|
|
63
|
+
})
|
|
64
|
+
.flatMap((v) => (v ? [v] : []));
|
|
65
|
+
if (result.length === 1)
|
|
66
|
+
return result[0];
|
|
67
|
+
return p.and(...result);
|
|
68
|
+
};
|
|
69
|
+
export const createInputOperator = (
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
builder, type) => {
|
|
72
|
+
const typeName = Array.isArray(type) ? `Array${type[0]}` : type;
|
|
73
|
+
const name = `${typeName}InputOperator`;
|
|
74
|
+
const inputType = builder.inputType(name, {
|
|
75
|
+
fields: (t) => ({
|
|
76
|
+
eq: t.field({ type }),
|
|
77
|
+
ne: t.field({ type }),
|
|
78
|
+
gt: t.field({ type }),
|
|
79
|
+
gte: t.field({ type }),
|
|
80
|
+
lt: t.field({ type }),
|
|
81
|
+
lte: t.field({ type }),
|
|
82
|
+
like: t.field({ type }),
|
|
83
|
+
notLike: t.field({ type }),
|
|
84
|
+
ilike: t.field({ type }),
|
|
85
|
+
notIlike: t.field({ type }),
|
|
86
|
+
isNull: t.boolean(),
|
|
87
|
+
isNotNull: t.boolean(),
|
|
88
|
+
in: t.field({ type: [type] }),
|
|
89
|
+
notIn: t.field({ type: [type] }),
|
|
90
|
+
arrayContained: t.field({ type: [type] }),
|
|
91
|
+
arrayOverlaps: t.field({ type: [type] }),
|
|
92
|
+
arrayContains: t.field({ type: [type] }),
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
return inputType;
|
|
96
|
+
};
|
|
97
|
+
export const convertAggregationQuery = (query) => {
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
99
|
+
const { aggregation, columns, ...q } = query;
|
|
100
|
+
const newQuery = aggregation ? { ...q, columns: {} } : query;
|
|
101
|
+
const newWith = query.with
|
|
102
|
+
? Object.fromEntries(Object.entries(query.with).map(([key, value]) => [
|
|
103
|
+
key,
|
|
104
|
+
convertAggregationQuery(value),
|
|
105
|
+
]))
|
|
106
|
+
: query.with;
|
|
107
|
+
return { ...newQuery, with: newWith };
|
|
108
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import eslint from "@eslint/js";
|
|
2
|
+
import eslintConfigPrettier from "eslint-config-prettier";
|
|
3
|
+
import importPlugin from "eslint-plugin-import";
|
|
4
|
+
import tslint from "typescript-eslint";
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
eslint.configs.recommended,
|
|
8
|
+
...tslint.configs.recommended,
|
|
9
|
+
eslintConfigPrettier,
|
|
10
|
+
{
|
|
11
|
+
ignores: ["**/global-types.ts"],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
plugins: {
|
|
15
|
+
import: importPlugin,
|
|
16
|
+
},
|
|
17
|
+
rules: {
|
|
18
|
+
"@typescript-eslint/no-unused-vars": "warn",
|
|
19
|
+
"no-empty-pattern": 0,
|
|
20
|
+
"no-empty": 0,
|
|
21
|
+
|
|
22
|
+
"import/order": [
|
|
23
|
+
"warn",
|
|
24
|
+
{
|
|
25
|
+
groups: [
|
|
26
|
+
"builtin",
|
|
27
|
+
"external",
|
|
28
|
+
"internal",
|
|
29
|
+
["parent", "sibling"],
|
|
30
|
+
"object",
|
|
31
|
+
"type",
|
|
32
|
+
"index",
|
|
33
|
+
],
|
|
34
|
+
pathGroupsExcludedImportTypes: ["builtin"],
|
|
35
|
+
alphabetize: {
|
|
36
|
+
order: "asc",
|
|
37
|
+
caseInsensitive: true,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pothos-drizzle-generator",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "./dist/cjs/index.js",
|
|
5
|
+
"types": "./dist/cjs/index.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"require": "./dist/cjs/index.js",
|
|
9
|
+
"import": "./dist/esm/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc && tsc -p ./tsconfig.esm.json && cpy esm dist",
|
|
14
|
+
"watch": "tsc -b -w",
|
|
15
|
+
"lint": "eslint ./src",
|
|
16
|
+
"lint:fix": "eslint --fix ./src"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@graphql-tools/utils": "10.11.0",
|
|
20
|
+
"@pothos/core": "4.10.0",
|
|
21
|
+
"@pothos/plugin-drizzle": "0.16.0",
|
|
22
|
+
"drizzle-orm": "1.0.0-beta.2-f9236e3",
|
|
23
|
+
"graphql": "16.12.0",
|
|
24
|
+
"graphql-scalars": "1.25.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/graphql": "14.5.0",
|
|
28
|
+
"@eslint/js": "9.39.2",
|
|
29
|
+
"eslint": "9.39.2",
|
|
30
|
+
"eslint-config-prettier": "^10.1.8",
|
|
31
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
32
|
+
"eslint-plugin-import": "^2.32.0",
|
|
33
|
+
"typescript": "5.9.3",
|
|
34
|
+
"typescript-eslint": "^8.49.0",
|
|
35
|
+
"cpy-cli": "^6.0.0"
|
|
36
|
+
},
|
|
37
|
+
"repository": "https://github.com/node-libraries/pothos-drizzle-generator",
|
|
38
|
+
"author": "SoraKumo <info@croud.jp>",
|
|
39
|
+
"license": "MIT"
|
|
40
|
+
}
|