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.
@@ -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,3 @@
1
+ export * from "./global-types.js";
2
+ declare const pluginName: "pothosDrizzleGenerator";
3
+ export default pluginName;
@@ -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,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -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
+ }