@forinda/kickjs-prisma 0.3.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Felix Orinda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @forinda/kickjs-prisma
2
+
3
+ Prisma ORM adapter for the [KickJS](https://forinda.github.io/kick-js/) framework. Provides DI integration, lifecycle management, and query building.
4
+
5
+ ## Features
6
+
7
+ - **PrismaAdapter** - Registers a `PrismaClient` in the DI container and handles graceful disconnect on shutdown.
8
+ - **PrismaQueryAdapter** - Translates framework-agnostic `ParsedQuery` objects into Prisma-compatible `findMany` arguments (`where`, `orderBy`, `skip`, `take`).
9
+ - Optional query logging.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pnpm add @forinda/kickjs-prisma @prisma/client
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { PrismaClient } from '@prisma/client'
21
+ import { PrismaAdapter, PRISMA_CLIENT } from '@forinda/kickjs-prisma'
22
+
23
+ // Register the adapter
24
+ bootstrap({
25
+ modules,
26
+ adapters: [
27
+ new PrismaAdapter({ client: new PrismaClient(), logging: true }),
28
+ ],
29
+ })
30
+
31
+ // Inject in services
32
+ @Service()
33
+ class UserService {
34
+ @Inject(PRISMA_CLIENT) private prisma: PrismaClient
35
+ }
36
+ ```
37
+
38
+ ## License
39
+
40
+ MIT
@@ -0,0 +1,85 @@
1
+ import { AppAdapter, Container } from '@forinda/kickjs-core';
2
+ import { QueryBuilderAdapter, ParsedQuery } from '@forinda/kickjs-http';
3
+
4
+ interface PrismaAdapterOptions {
5
+ /** PrismaClient instance - typed as `any` to avoid version coupling */
6
+ client: any;
7
+ /** Enable query logging (default: false) */
8
+ logging?: boolean;
9
+ }
10
+ /** DI token for resolving the PrismaClient from the container */
11
+ declare const PRISMA_CLIENT: unique symbol;
12
+
13
+ /**
14
+ * Prisma adapter — registers a PrismaClient in the DI container and manages
15
+ * its lifecycle (connection setup and teardown).
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { PrismaClient } from '@prisma/client'
20
+ * import { PrismaAdapter } from '@forinda/kickjs-prisma'
21
+ *
22
+ * bootstrap({
23
+ * modules,
24
+ * adapters: [
25
+ * new PrismaAdapter({ client: new PrismaClient(), logging: true }),
26
+ * ],
27
+ * })
28
+ * ```
29
+ *
30
+ * Inject the client in services:
31
+ * ```ts
32
+ * @Service()
33
+ * class UserService {
34
+ * @Inject(PRISMA_CLIENT) private prisma: PrismaClient
35
+ * }
36
+ * ```
37
+ */
38
+ declare class PrismaAdapter implements AppAdapter {
39
+ private options;
40
+ name: string;
41
+ private client;
42
+ constructor(options: PrismaAdapterOptions);
43
+ /** Register the PrismaClient in the DI container */
44
+ beforeStart(_app: any, container: Container): void;
45
+ /** Disconnect the PrismaClient on shutdown */
46
+ shutdown(): Promise<void>;
47
+ }
48
+
49
+ /** Configuration for the Prisma query builder adapter */
50
+ interface PrismaQueryConfig {
51
+ /** Columns to search across when a search string is provided */
52
+ searchColumns?: string[];
53
+ }
54
+ /** Result shape matching Prisma's findMany arguments */
55
+ interface PrismaQueryResult {
56
+ where?: Record<string, any>;
57
+ orderBy?: Record<string, 'asc' | 'desc'>[];
58
+ skip?: number;
59
+ take?: number;
60
+ }
61
+ /**
62
+ * Translates a ParsedQuery into Prisma-compatible `findMany` arguments.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const adapter = new PrismaQueryAdapter()
67
+ * const parsed = parseQuery(req.query)
68
+ * const args = adapter.build(parsed, { searchColumns: ['name', 'email'] })
69
+ * const users = await prisma.user.findMany(args)
70
+ * ```
71
+ */
72
+ declare class PrismaQueryAdapter implements QueryBuilderAdapter<PrismaQueryResult, PrismaQueryConfig> {
73
+ readonly name = "PrismaQueryAdapter";
74
+ build(parsed: ParsedQuery, config?: PrismaQueryConfig): PrismaQueryResult;
75
+ /** Map FilterItem[] to Prisma where conditions */
76
+ private buildFilters;
77
+ /** Build Prisma orderBy from SortItem[] */
78
+ private buildSort;
79
+ /** Build a search condition using OR + contains across multiple columns */
80
+ private buildSearch;
81
+ /** Attempt to coerce a string value to a number or boolean if appropriate */
82
+ private coerce;
83
+ }
84
+
85
+ export { PRISMA_CLIENT, PrismaAdapter, type PrismaAdapterOptions, PrismaQueryAdapter, type PrismaQueryConfig, type PrismaQueryResult };
package/dist/index.js ADDED
@@ -0,0 +1,196 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/prisma.adapter.ts
5
+ import { Logger, Scope } from "@forinda/kickjs-core";
6
+
7
+ // src/types.ts
8
+ var PRISMA_CLIENT = /* @__PURE__ */ Symbol("PrismaClient");
9
+
10
+ // src/prisma.adapter.ts
11
+ var log = Logger.for("PrismaAdapter");
12
+ var PrismaAdapter = class {
13
+ static {
14
+ __name(this, "PrismaAdapter");
15
+ }
16
+ options;
17
+ name = "PrismaAdapter";
18
+ client;
19
+ constructor(options) {
20
+ this.options = options;
21
+ this.client = options.client;
22
+ }
23
+ /** Register the PrismaClient in the DI container */
24
+ beforeStart(_app, container) {
25
+ if (this.options.logging && typeof this.client.$on === "function") {
26
+ this.client.$on("query", (event) => {
27
+ log.debug(`Query: ${event.query}`);
28
+ log.debug(`Params: ${event.params}`);
29
+ log.debug(`Duration: ${event.duration}ms`);
30
+ });
31
+ }
32
+ container.registerFactory(PRISMA_CLIENT, () => this.client, Scope.SINGLETON);
33
+ log.info("PrismaClient registered in DI container");
34
+ }
35
+ /** Disconnect the PrismaClient on shutdown */
36
+ async shutdown() {
37
+ if (typeof this.client.$disconnect === "function") {
38
+ await this.client.$disconnect();
39
+ log.info("PrismaClient disconnected");
40
+ }
41
+ }
42
+ };
43
+
44
+ // src/query-adapter.ts
45
+ var PrismaQueryAdapter = class {
46
+ static {
47
+ __name(this, "PrismaQueryAdapter");
48
+ }
49
+ name = "PrismaQueryAdapter";
50
+ build(parsed, config = {}) {
51
+ const result = {};
52
+ const whereConditions = this.buildFilters(parsed.filters);
53
+ const searchCondition = this.buildSearch(parsed.search, config.searchColumns);
54
+ if (whereConditions.length > 0 || searchCondition) {
55
+ const andClauses = [];
56
+ if (whereConditions.length > 0) {
57
+ andClauses.push(...whereConditions);
58
+ }
59
+ if (searchCondition) {
60
+ andClauses.push(searchCondition);
61
+ }
62
+ result.where = andClauses.length === 1 ? andClauses[0] : {
63
+ AND: andClauses
64
+ };
65
+ }
66
+ const orderBy = this.buildSort(parsed.sort);
67
+ if (orderBy.length > 0) {
68
+ result.orderBy = orderBy;
69
+ }
70
+ result.skip = parsed.pagination.offset;
71
+ result.take = parsed.pagination.limit;
72
+ return result;
73
+ }
74
+ /** Map FilterItem[] to Prisma where conditions */
75
+ buildFilters(filters) {
76
+ return filters.map((filter) => {
77
+ const { field, operator, value } = filter;
78
+ switch (operator) {
79
+ case "eq":
80
+ return {
81
+ [field]: {
82
+ equals: this.coerce(value)
83
+ }
84
+ };
85
+ case "neq":
86
+ return {
87
+ [field]: {
88
+ not: this.coerce(value)
89
+ }
90
+ };
91
+ case "gt":
92
+ return {
93
+ [field]: {
94
+ gt: this.coerce(value)
95
+ }
96
+ };
97
+ case "gte":
98
+ return {
99
+ [field]: {
100
+ gte: this.coerce(value)
101
+ }
102
+ };
103
+ case "lt":
104
+ return {
105
+ [field]: {
106
+ lt: this.coerce(value)
107
+ }
108
+ };
109
+ case "lte":
110
+ return {
111
+ [field]: {
112
+ lte: this.coerce(value)
113
+ }
114
+ };
115
+ case "contains":
116
+ return {
117
+ [field]: {
118
+ contains: value,
119
+ mode: "insensitive"
120
+ }
121
+ };
122
+ case "starts":
123
+ return {
124
+ [field]: {
125
+ startsWith: value,
126
+ mode: "insensitive"
127
+ }
128
+ };
129
+ case "ends":
130
+ return {
131
+ [field]: {
132
+ endsWith: value,
133
+ mode: "insensitive"
134
+ }
135
+ };
136
+ case "in": {
137
+ const values = value.split(",").map((v) => this.coerce(v.trim()));
138
+ return {
139
+ [field]: {
140
+ in: values
141
+ }
142
+ };
143
+ }
144
+ case "between": {
145
+ const [min, max] = value.split(",").map((v) => this.coerce(v.trim()));
146
+ return {
147
+ [field]: {
148
+ gte: min,
149
+ lte: max
150
+ }
151
+ };
152
+ }
153
+ default:
154
+ return {
155
+ [field]: {
156
+ equals: this.coerce(value)
157
+ }
158
+ };
159
+ }
160
+ });
161
+ }
162
+ /** Build Prisma orderBy from SortItem[] */
163
+ buildSort(sort) {
164
+ return sort.map((item) => ({
165
+ [item.field]: item.direction
166
+ }));
167
+ }
168
+ /** Build a search condition using OR + contains across multiple columns */
169
+ buildSearch(search, searchColumns) {
170
+ if (!search || !searchColumns || searchColumns.length === 0) {
171
+ return null;
172
+ }
173
+ return {
174
+ OR: searchColumns.map((column) => ({
175
+ [column]: {
176
+ contains: search,
177
+ mode: "insensitive"
178
+ }
179
+ }))
180
+ };
181
+ }
182
+ /** Attempt to coerce a string value to a number or boolean if appropriate */
183
+ coerce(value) {
184
+ if (value === "true") return true;
185
+ if (value === "false") return false;
186
+ const num = Number(value);
187
+ if (!Number.isNaN(num) && value.trim() !== "") return num;
188
+ return value;
189
+ }
190
+ };
191
+ export {
192
+ PRISMA_CLIENT,
193
+ PrismaAdapter,
194
+ PrismaQueryAdapter
195
+ };
196
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prisma.adapter.ts","../src/types.ts","../src/query-adapter.ts"],"sourcesContent":["import { Logger, type AppAdapter, type Container, Scope } from '@forinda/kickjs-core'\nimport { PRISMA_CLIENT, type PrismaAdapterOptions } from './types'\n\nconst log = Logger.for('PrismaAdapter')\n\n/**\n * Prisma adapter — registers a PrismaClient in the DI container and manages\n * its lifecycle (connection setup and teardown).\n *\n * @example\n * ```ts\n * import { PrismaClient } from '@prisma/client'\n * import { PrismaAdapter } from '@forinda/kickjs-prisma'\n *\n * bootstrap({\n * modules,\n * adapters: [\n * new PrismaAdapter({ client: new PrismaClient(), logging: true }),\n * ],\n * })\n * ```\n *\n * Inject the client in services:\n * ```ts\n * @Service()\n * class UserService {\n * @Inject(PRISMA_CLIENT) private prisma: PrismaClient\n * }\n * ```\n */\nexport class PrismaAdapter implements AppAdapter {\n name = 'PrismaAdapter'\n private client: any\n\n constructor(private options: PrismaAdapterOptions) {\n this.client = options.client\n }\n\n /** Register the PrismaClient in the DI container */\n beforeStart(_app: any, container: Container): void {\n // Set up query logging if requested\n if (this.options.logging && typeof this.client.$on === 'function') {\n this.client.$on('query', (event: any) => {\n log.debug(`Query: ${event.query}`)\n log.debug(`Params: ${event.params}`)\n log.debug(`Duration: ${event.duration}ms`)\n })\n }\n\n // Register the client instance as a singleton factory in the container\n container.registerFactory(PRISMA_CLIENT, () => this.client, Scope.SINGLETON)\n\n log.info('PrismaClient registered in DI container')\n }\n\n /** Disconnect the PrismaClient on shutdown */\n async shutdown(): Promise<void> {\n if (typeof this.client.$disconnect === 'function') {\n await this.client.$disconnect()\n log.info('PrismaClient disconnected')\n }\n }\n}\n","export interface PrismaAdapterOptions {\n /** PrismaClient instance - typed as `any` to avoid version coupling */\n client: any\n /** Enable query logging (default: false) */\n logging?: boolean\n}\n\n/** DI token for resolving the PrismaClient from the container */\nexport const PRISMA_CLIENT = Symbol('PrismaClient')\n","import type { QueryBuilderAdapter, ParsedQuery, FilterItem, SortItem } from '@forinda/kickjs-http'\n\n/** Configuration for the Prisma query builder adapter */\nexport interface PrismaQueryConfig {\n /** Columns to search across when a search string is provided */\n searchColumns?: string[]\n}\n\n/** Result shape matching Prisma's findMany arguments */\nexport interface PrismaQueryResult {\n where?: Record<string, any>\n orderBy?: Record<string, 'asc' | 'desc'>[]\n skip?: number\n take?: number\n}\n\n/**\n * Translates a ParsedQuery into Prisma-compatible `findMany` arguments.\n *\n * @example\n * ```ts\n * const adapter = new PrismaQueryAdapter()\n * const parsed = parseQuery(req.query)\n * const args = adapter.build(parsed, { searchColumns: ['name', 'email'] })\n * const users = await prisma.user.findMany(args)\n * ```\n */\nexport class PrismaQueryAdapter implements QueryBuilderAdapter<\n PrismaQueryResult,\n PrismaQueryConfig\n> {\n readonly name = 'PrismaQueryAdapter'\n\n build(parsed: ParsedQuery, config: PrismaQueryConfig = {}): PrismaQueryResult {\n const result: PrismaQueryResult = {}\n\n // Build where clause from filters and search\n const whereConditions = this.buildFilters(parsed.filters)\n const searchCondition = this.buildSearch(parsed.search, config.searchColumns)\n\n if (whereConditions.length > 0 || searchCondition) {\n const andClauses: any[] = []\n\n if (whereConditions.length > 0) {\n andClauses.push(...whereConditions)\n }\n if (searchCondition) {\n andClauses.push(searchCondition)\n }\n\n result.where = andClauses.length === 1 ? andClauses[0] : { AND: andClauses }\n }\n\n // Build orderBy\n const orderBy = this.buildSort(parsed.sort)\n if (orderBy.length > 0) {\n result.orderBy = orderBy\n }\n\n // Build pagination\n result.skip = parsed.pagination.offset\n result.take = parsed.pagination.limit\n\n return result\n }\n\n /** Map FilterItem[] to Prisma where conditions */\n private buildFilters(filters: FilterItem[]): Record<string, any>[] {\n return filters.map((filter) => {\n const { field, operator, value } = filter\n\n switch (operator) {\n case 'eq':\n return { [field]: { equals: this.coerce(value) } }\n case 'neq':\n return { [field]: { not: this.coerce(value) } }\n case 'gt':\n return { [field]: { gt: this.coerce(value) } }\n case 'gte':\n return { [field]: { gte: this.coerce(value) } }\n case 'lt':\n return { [field]: { lt: this.coerce(value) } }\n case 'lte':\n return { [field]: { lte: this.coerce(value) } }\n case 'contains':\n return { [field]: { contains: value, mode: 'insensitive' } }\n case 'starts':\n return { [field]: { startsWith: value, mode: 'insensitive' } }\n case 'ends':\n return { [field]: { endsWith: value, mode: 'insensitive' } }\n case 'in': {\n const values = value.split(',').map((v) => this.coerce(v.trim()))\n return { [field]: { in: values } }\n }\n case 'between': {\n const [min, max] = value.split(',').map((v) => this.coerce(v.trim()))\n return { [field]: { gte: min, lte: max } }\n }\n default:\n return { [field]: { equals: this.coerce(value) } }\n }\n })\n }\n\n /** Build Prisma orderBy from SortItem[] */\n private buildSort(sort: SortItem[]): Record<string, 'asc' | 'desc'>[] {\n return sort.map((item) => ({ [item.field]: item.direction }))\n }\n\n /** Build a search condition using OR + contains across multiple columns */\n private buildSearch(search: string, searchColumns?: string[]): Record<string, any> | null {\n if (!search || !searchColumns || searchColumns.length === 0) {\n return null\n }\n\n return {\n OR: searchColumns.map((column) => ({\n [column]: { contains: search, mode: 'insensitive' },\n })),\n }\n }\n\n /** Attempt to coerce a string value to a number or boolean if appropriate */\n private coerce(value: string): string | number | boolean {\n if (value === 'true') return true\n if (value === 'false') return false\n const num = Number(value)\n if (!Number.isNaN(num) && value.trim() !== '') return num\n return value\n }\n}\n"],"mappings":"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","names":["Logger","Scope","PRISMA_CLIENT","Symbol","log","Logger","for","PrismaAdapter","name","client","options","beforeStart","_app","container","logging","$on","event","debug","query","params","duration","registerFactory","PRISMA_CLIENT","Scope","SINGLETON","info","shutdown","$disconnect","PrismaQueryAdapter","name","build","parsed","config","result","whereConditions","buildFilters","filters","searchCondition","buildSearch","search","searchColumns","length","andClauses","push","where","AND","orderBy","buildSort","sort","skip","pagination","offset","take","limit","map","filter","field","operator","value","equals","coerce","not","gt","gte","lt","lte","contains","mode","startsWith","endsWith","values","split","v","trim","in","min","max","item","direction","OR","column","num","Number","isNaN"]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@forinda/kickjs-prisma",
3
+ "version": "0.3.2",
4
+ "description": "Prisma ORM adapter with DI integration, transaction support, and query building for KickJS",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "dependencies": {
18
+ "reflect-metadata": "^0.2.2",
19
+ "@forinda/kickjs-http": "0.4.0",
20
+ "@forinda/kickjs-core": "0.4.0"
21
+ },
22
+ "peerDependencies": {
23
+ "@prisma/client": ">=5.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^24.5.2",
27
+ "tsup": "^8.5.0",
28
+ "typescript": "^5.9.2"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "license": "MIT",
34
+ "author": "Felix Orinda",
35
+ "engines": {
36
+ "node": ">=20.0"
37
+ },
38
+ "homepage": "https://forinda.github.io/kick-js/",
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch",
42
+ "typecheck": "tsc --noEmit",
43
+ "clean": "rm -rf dist .turbo",
44
+ "lint": "tsc --noEmit"
45
+ }
46
+ }