@forinda/kickjs-prisma 1.2.11 → 1.2.12

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/dist/index.js CHANGED
@@ -1,196 +1 @@
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
1
+ var f=Object.defineProperty;var a=(u,t)=>f(u,"name",{value:t,configurable:!0});import{Logger as p,Scope as g}from"@forinda/kickjs-core";var l=Symbol("PrismaClient");var c=p.for("PrismaAdapter"),h=class{static{a(this,"PrismaAdapter")}options;name="PrismaAdapter";client;constructor(t){this.options=t,this.client=t.client}beforeStart(t,r){this.options.logging&&typeof this.client.$on=="function"&&this.client.$on("query",e=>{c.debug(`Query: ${e.query}`),c.debug(`Params: ${e.params}`),c.debug(`Duration: ${e.duration}ms`)}),r.registerFactory(l,()=>this.client,g.SINGLETON),c.info("PrismaClient registered in DI container")}async shutdown(){typeof this.client.$disconnect=="function"&&(await this.client.$disconnect(),c.info("PrismaClient disconnected"))}};var m=class{static{a(this,"PrismaQueryAdapter")}name="PrismaQueryAdapter";build(t,r={}){let e={},o=this.buildFilters(t.filters),i=this.buildSearch(t.search,r.searchColumns);if(o.length>0||i){let n=[];o.length>0&&n.push(...o),i&&n.push(i),e.where=n.length===1?n[0]:{AND:n}}let s=this.buildSort(t.sort);return s.length>0&&(e.orderBy=s),e.skip=t.pagination.offset,e.take=t.pagination.limit,e}buildFilters(t){return t.map(r=>{let{field:e,operator:o,value:i}=r;switch(o){case"eq":return{[e]:{equals:this.coerce(i)}};case"neq":return{[e]:{not:this.coerce(i)}};case"gt":return{[e]:{gt:this.coerce(i)}};case"gte":return{[e]:{gte:this.coerce(i)}};case"lt":return{[e]:{lt:this.coerce(i)}};case"lte":return{[e]:{lte:this.coerce(i)}};case"contains":return{[e]:{contains:i,mode:"insensitive"}};case"starts":return{[e]:{startsWith:i,mode:"insensitive"}};case"ends":return{[e]:{endsWith:i,mode:"insensitive"}};case"in":{let s=i.split(",").map(n=>this.coerce(n.trim()));return{[e]:{in:s}}}case"between":{let[s,n]=i.split(",").map(d=>this.coerce(d.trim()));return{[e]:{gte:s,lte:n}}}default:return{[e]:{equals:this.coerce(i)}}}})}buildSort(t){return t.map(r=>({[r.field]:r.direction}))}buildSearch(t,r){return!t||!r||r.length===0?null:{OR:r.map(e=>({[e]:{contains:t,mode:"insensitive"}}))}}coerce(t){if(t==="true")return!0;if(t==="false")return!1;let r=Number(t);return!Number.isNaN(r)&&t.trim()!==""?r:t}};export{l as PRISMA_CLIENT,h as PrismaAdapter,m as PrismaQueryAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forinda/kickjs-prisma",
3
- "version": "1.2.11",
3
+ "version": "1.2.12",
4
4
  "description": "Prisma ORM adapter with DI integration, transaction support, and query building for KickJS",
5
5
  "keywords": [
6
6
  "kickjs",
@@ -39,8 +39,8 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "reflect-metadata": "^0.2.2",
42
- "@forinda/kickjs-core": "1.2.11",
43
- "@forinda/kickjs-http": "1.2.11"
42
+ "@forinda/kickjs-core": "1.2.12",
43
+ "@forinda/kickjs-http": "1.2.12"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@prisma/client": ">=5.0.0"
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
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"]}