prisma-ts-select 0.0.33

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,275 @@
1
+ import { Prisma } from '@prisma/client/extension';
2
+ import { match, P } from 'ts-pattern';
3
+
4
+ const DB = {};
5
+ class DbSelect {
6
+ constructor(db) {
7
+ this.db = db;
8
+ }
9
+ from(database) {
10
+ return new _fJoin(this.db, { database, selects: [] });
11
+ }
12
+ }
13
+ class _fRun {
14
+ constructor(db, values) {
15
+ this.db = db;
16
+ this.values = values;
17
+ this.values.limit = typeof this.values.limit === "number" ? this.values.limit : void 0;
18
+ this.values.offset = typeof this.values.offset === "number" ? this.values.offset : void 0;
19
+ }
20
+ run() {
21
+ return this.db.$queryRawUnsafe(
22
+ this.getSQL()
23
+ );
24
+ }
25
+ getTables() {
26
+ return {};
27
+ }
28
+ getFields() {
29
+ return {};
30
+ }
31
+ getSQL(formatted = false) {
32
+ function processCondition(condition, formatted2) {
33
+ return "(" + Object.keys(condition).map((field) => {
34
+ const value = condition[field];
35
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && "op" in value) {
36
+ switch (value.op) {
37
+ case "IN":
38
+ case "NOT IN":
39
+ const valuesList = value.values.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
40
+ return `${String(field)} ${value.op} (${valuesList})`;
41
+ case "BETWEEN":
42
+ if (value.values.length > 2) throw new Error("Too many items supplied to op BETWEEN");
43
+ const [start, end] = value.values;
44
+ return `${String(field)} BETWEEN ${typeof start === "string" ? `'${start}'` : start} AND ${typeof end === "string" ? `'${end}'` : end}`;
45
+ case "LIKE":
46
+ case "NOT LIKE":
47
+ return `${String(field)} ${value.op} '${value.value}'`;
48
+ case "IS NULL":
49
+ case "IS NOT NULL":
50
+ return `${String(field)} ${value.op}`;
51
+ case ">":
52
+ case ">=":
53
+ case "<":
54
+ case "<=":
55
+ case "!=":
56
+ return `${String(field)} ${value.op} ${typeof value.value === "string" ? `'${value.value}'` : value.value}`;
57
+ default:
58
+ throw new Error(`Unsupported operation: ${value.op}`);
59
+ }
60
+ } else if (Array.isArray(value)) {
61
+ const valuesList = value.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
62
+ return `${String(field)} IN (${valuesList})`;
63
+ } else if (value === null) {
64
+ return `${String(field)} IS NULL`;
65
+ } else {
66
+ return `${String(field)} = ${typeof value === "string" ? `'${value}'` : value}`;
67
+ }
68
+ }).join(" AND " + (" ")) + " )";
69
+ }
70
+ function processCriteria(main, joinType = "AND", formatted2 = false) {
71
+ const results = [];
72
+ for (const criteria of main) {
73
+ if (typeof criteria === "string") {
74
+ results.push(criteria);
75
+ continue;
76
+ }
77
+ for (const criterion in criteria) {
78
+ results.push(match(criterion).returnType().with("$AND", (criterion2) => {
79
+ return "(" + //@ts-expect-error criterion
80
+ processCriteria(criteria[criterion2], "AND", formatted2) + ")";
81
+ }).with("$OR", (criterion2) => {
82
+ return "(" + //@ts-expect-error criterion
83
+ processCriteria(criteria[criterion2], "OR", formatted2) + ")";
84
+ }).with("$NOT", (criterion2) => {
85
+ return "(NOT(" + //@ts-expect-error criterion
86
+ processCriteria(criteria[criterion2], "AND", formatted2) + "))";
87
+ }).with("$NOR", (criterion2) => {
88
+ return "(NOT(" + //@ts-expect-error criterion
89
+ processCriteria(criteria[criterion2], "OR", formatted2) + "))";
90
+ }).with(P.string, () => {
91
+ return processCondition(criteria);
92
+ }).exhaustive());
93
+ }
94
+ }
95
+ return results.join((formatted2 ? "\n" : " ") + joinType + (formatted2 ? "\n" : " "));
96
+ }
97
+ const whereClause = this.values.where !== void 0 ? processCriteria(this.values.where, "AND", formatted) : void 0;
98
+ const havingClause = this.values.having !== void 0 ? processCriteria(this.values.having, "AND", formatted) : void 0;
99
+ return [
100
+ this.values.selects.length === 0 ? "" : "SELECT " + (this.values.selectDistinct === true ? "DISTINCT " : "") + this.values.selects.join(", "),
101
+ `FROM ${this.values.database}`,
102
+ this.values.tables?.map(({
103
+ table,
104
+ local,
105
+ remote
106
+ }) => `JOIN ${table} ON ${local} = ${remote}`).join(formatted ? "\n" : " ") ?? "",
107
+ !whereClause ? "" : `WHERE ${whereClause}`,
108
+ !this.values.groupBy?.length ? "" : `GROUP BY ${this.values.groupBy.join(", ")}`,
109
+ !havingClause ? "" : `HAVING ${havingClause}`,
110
+ !(this.values.orderBy && this.values.orderBy.length > 0) ? "" : "ORDER BY " + this.values.orderBy.join(", "),
111
+ !this.values.limit ? "" : `LIMIT ${this.values.limit}`,
112
+ !this.values.offset ? "" : `OFFSET ${this.values.offset}`
113
+ ].filter(Boolean).join(formatted ? "\n" : " ").trim() + ";";
114
+ }
115
+ }
116
+ class _fOffset extends _fRun {
117
+ offset(offset) {
118
+ return new _fRun(this.db, { ...this.values, offset });
119
+ }
120
+ }
121
+ class _fLimit extends _fRun {
122
+ limit(limit) {
123
+ return new _fOffset(this.db, { ...this.values, limit });
124
+ }
125
+ }
126
+ class _fOrderBy extends _fLimit {
127
+ orderBy(orderBy) {
128
+ return new _fLimit(this.db, { ...this.values, orderBy });
129
+ }
130
+ }
131
+ class _fSelect extends _fOrderBy {
132
+ select(select) {
133
+ return new _fSelect(this.db, {
134
+ ...this.values,
135
+ selects: [...this.values.selects, select]
136
+ });
137
+ }
138
+ }
139
+ class _fSelectDistinct extends _fSelect {
140
+ selectDistinct() {
141
+ return new _fSelect(this.db, { ...this.values, selectDistinct: true });
142
+ }
143
+ selectAll() {
144
+ const selects = function(values) {
145
+ if (values.tables && values.tables.length > 0) {
146
+ return [values.database, ...values.tables.map((t) => t.table)].reduce((acc, table) => {
147
+ return acc.concat(Object.keys(DB[table].fields).map((field) => `${table}.${field} AS \`${table}.${field}\``));
148
+ }, []);
149
+ }
150
+ return Object.keys(DB[values.database].fields);
151
+ }(this.values);
152
+ return new _fOrderBy(this.db, {
153
+ ...this.values,
154
+ selects
155
+ });
156
+ }
157
+ //TODO
158
+ // selectAllOmit() {
159
+ // throw new Error("Not implemented yet")
160
+ // }
161
+ }
162
+ class _fHaving extends _fSelectDistinct {
163
+ // TODO Allowed Fields
164
+ // - specified in groupBy
165
+ having(criteria) {
166
+ return new _fSelectDistinct(this.db, {
167
+ ...this.values,
168
+ having: [criteria]
169
+ });
170
+ }
171
+ }
172
+ class _fGroupBy extends _fHaving {
173
+ //TODO this should only accept columns for tables in play
174
+ groupBy(groupBy) {
175
+ return new _fHaving(this.db, { ...this.values, groupBy });
176
+ }
177
+ }
178
+ class _fWhere extends _fGroupBy {
179
+ whereNotNull(col) {
180
+ return new _fWhere(this.db, {
181
+ ...this.values,
182
+ where: [
183
+ ...this.values.where || [],
184
+ {
185
+ $AND: (
186
+ //@ts-expect-error todo comeback to, col is a string or never
187
+ [{ [col]: { op: "IS NOT NULL" } }]
188
+ )
189
+ }
190
+ ]
191
+ });
192
+ }
193
+ whereIsNull(col) {
194
+ return new _fWhere(this.db, {
195
+ ...this.values,
196
+ where: [
197
+ ...this.values.where || [],
198
+ {
199
+ $AND: (
200
+ //@ts-expect-error todo comeback to, col is a string or never
201
+ [{ [col]: { op: "IS NULL" } }]
202
+ )
203
+ }
204
+ ]
205
+ });
206
+ }
207
+ where(criteria) {
208
+ return new _fGroupBy(this.db, {
209
+ ...this.values,
210
+ where: [...this.values.where || [], criteria]
211
+ });
212
+ }
213
+ whereRaw(where) {
214
+ return new _fGroupBy(this.db, {
215
+ ...this.values,
216
+ where: [...this.values.where || [], where.replace(/^\s*where\s*/i, "").trim()]
217
+ });
218
+ }
219
+ }
220
+ class _fJoin extends _fWhere {
221
+ join(table, field, reference) {
222
+ return new _fJoin(this.db, {
223
+ ...this.values,
224
+ tables: [...this.values.tables || [], { table, local: field, remote: reference }]
225
+ });
226
+ }
227
+ joinUnsafeTypeEnforced(table, field, reference) {
228
+ return new _fJoin(this.db, {
229
+ ...this.values,
230
+ tables: [...this.values.tables || [], {
231
+ table,
232
+ local: `${String(table)}.${String(field)}`,
233
+ remote: reference
234
+ }]
235
+ });
236
+ }
237
+ joinUnsafeIgnoreType(table, field, reference) {
238
+ return new _fJoin(this.db, {
239
+ ...this.values,
240
+ tables: [...this.values.tables || [], {
241
+ table,
242
+ local: `${String(table)}.${String(field)}`,
243
+ remote: reference
244
+ }]
245
+ });
246
+ }
247
+ // innerJoin(table: TTables, col1:string, col2:string){
248
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
249
+ // }
250
+ // leftJoin(table: TTables, col1:string, col2:string){
251
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
252
+ // }
253
+ // rightJoin(table: TTables, col1:string, col2:string){
254
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
255
+ // }
256
+ // fullJoin(table: TTables, col1:string, col2:string){
257
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
258
+ // }
259
+ // crossJoin(table: TTables, col1:string, col2:string){
260
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
261
+ // }
262
+ // outerJoin(table: TTables, col1:string, col2:string){
263
+ // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
264
+ // }
265
+ }
266
+ var extend_default = {
267
+ client: {
268
+ $from(table) {
269
+ const client = Prisma.getExtensionContext(this);
270
+ return new DbSelect(client).from(table);
271
+ }
272
+ }
273
+ };
274
+
275
+ export { extend_default as default };
@@ -0,0 +1,4 @@
1
+ 'use strict';
2
+
3
+ require('./chunk-G66FOFCO.cjs');
4
+
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1 @@
1
+ import './chunk-GBXPF5FT.js';
package/package.json ADDED
@@ -0,0 +1,170 @@
1
+ {
2
+ "name": "prisma-ts-select",
3
+ "version": "0.0.33",
4
+ "type": "module",
5
+ "bin": {
6
+ "prisma-ts-select": "dist/bin.cjs"
7
+ },
8
+ "main": "./dist/generator.cjs",
9
+ "module": "./dist/generator.js",
10
+ "types": "./dist/generator.d.cts",
11
+ "exports": {
12
+ "./extend": {
13
+ "import": {
14
+ "import": "./built/extend.js",
15
+ "require": "./built/extend.js",
16
+ "default": "./built/extend.js",
17
+ "types": "./built/extend.d.ts"
18
+ },
19
+ "require": {
20
+ "import": "./built/extend.cjs",
21
+ "require": "./built/extend.cjs",
22
+ "default": "./built/extend.cjs",
23
+ "types": "./built/extend.d.cts"
24
+ }
25
+ },
26
+ ".": {
27
+ "import": {
28
+ "import": "./dist/generator.mjs",
29
+ "default": "./dist/generator.mjs",
30
+ "types": "./dist/generator.d.mts"
31
+ },
32
+ "require": {
33
+ "import": "./dist/generator.js",
34
+ "require": "./dist/generator.js",
35
+ "default": "./dist/generator.js",
36
+ "types": "./dist/generator.d.ts"
37
+ }
38
+ }
39
+ },
40
+ "scripts": {
41
+ "bp": "pnpm build && pnpm version patch && pnpm pack",
42
+ "build": "pnpm exec rimraf dist && tsup",
43
+ "reset": "rm -rf prisma/migrations/ && prisma migrate dev --name init && prisma generate",
44
+ "start": "tsx src/index.ts",
45
+ "prisma-upgrade": "pnpm i --save-dev prisma@latest && pnpm i @prisma/client@latest",
46
+ "lint:ts": "tsc --noEmit -p tsconfig.json",
47
+ "lint:tsw": "pnpm tsc -w",
48
+ "lint": "tsc --noEmit ; eslint \"scripts/**/*.{j,t}s{,x}\" --cache --max-warnings=0",
49
+ "lint:s": "eslint --config .eslintrc.style.json \"scripts/**/*.{j,t}s{,x}\" --cache --max-warnings=0",
50
+ "lint:fix": "eslint --config .eslintrc.style.json \"scripts/**/*.{j,t}s{,x}\" --cache --max-warnings=0 --fix",
51
+ "p:gen": "pnpm exec prisma generate",
52
+ "p:dbp": "pnpm exec prisma db push",
53
+ "p:migrate": "pnpm exec prisma migrate dev",
54
+ "p:update": "pnpm add -D prisma@latest && pnpm add @prisma/client@latest",
55
+ "test": "echo 'TODO call package/usage'",
56
+ "test:jest": "jest",
57
+ "2postinstall": "node src/scripts/postinstall.js",
58
+ "doc": "pnpm exec markdown-toc -i README.md"
59
+ },
60
+ "dependencies": {
61
+ "@prisma/generator-helper": "5.16.2",
62
+ "@prisma/internals": "5.16.2",
63
+ "ts-pattern": "^5.3.1"
64
+ },
65
+ "license": "MIT",
66
+ "author": {
67
+ "name": "Adrian Elton-Browning",
68
+ "email": "gingacodemonkey@gmail.com"
69
+ },
70
+ "bugs": {
71
+ "url": "https://github.com/adrianbrowning/prisma-ts-select/issues"
72
+ },
73
+ "homepage": "Link to homepage or github readme here",
74
+ "repository": {
75
+ "type": "git",
76
+ "url": "https://github.com/adrianbrowning/prisma-ts-select"
77
+ },
78
+ "devDependencies": {
79
+ "@prisma/client": "5.16.1",
80
+ "@semantic-release/changelog": "^6.0.1",
81
+ "@semantic-release/git": "^10.0.1",
82
+ "@stylistic/eslint-plugin": "^1.5.4",
83
+ "@total-typescript/ts-reset": "^0.5.1",
84
+ "@types/better-sqlite3": "^7.6.8",
85
+ "@types/humanize-duration": "^3.27.2",
86
+ "@types/jest": "27.0.3",
87
+ "@types/klaw-sync": "^6.0.1",
88
+ "@types/lodash": "^4.14.197",
89
+ "@types/node": "20.11.30",
90
+ "@types/object-hash": "^3.0.4",
91
+ "@types/prettier": "2.4.2",
92
+ "@typescript-eslint/eslint-plugin": "^6.19.1",
93
+ "@typescript-eslint/parser": "^6.19.1",
94
+ "eslint": "^8.47.0",
95
+ "eslint-plugin-node": "^11.1.0",
96
+ "eslint-plugin-promise": "^6.1.1",
97
+ "eslint-plugin-simple-import-sort": "^9.0.0",
98
+ "eslint-plugin-unused-imports": "^3.0.0",
99
+ "humanize-duration": "^3.30.0",
100
+ "jest": "27.4.7",
101
+ "klaw-sync": "^6.0.0",
102
+ "knip": "^5.9.4",
103
+ "log-with-statusbar": "^1.2.0",
104
+ "markdown-toc": "^1.2.0",
105
+ "prisma": "5.16.1",
106
+ "prisma-dbml-generator": "^0.10.0",
107
+ "prisma-docs-generator": "^0.8.0",
108
+ "prisma-erd-generator": "^1.11.0",
109
+ "progress-string": "^1.2.2",
110
+ "rimraf": "^6.0.1",
111
+ "semantic-release": "^18.0.1",
112
+ "ts-jest": "27.1.4",
113
+ "tsup": "^8.1.0",
114
+ "tsx": "^4.16.0",
115
+ "typescript": "^5.5.3"
116
+ },
117
+ "keywords": [
118
+ "prisma",
119
+ "generator",
120
+ "SQL",
121
+ "type-safe",
122
+ "typescript"
123
+ ],
124
+ "engines": {
125
+ "node": ">=18.17",
126
+ "pnpm": ">= 8.6.12"
127
+ },
128
+ "target": "node",
129
+ "knip": {
130
+ "entry": [
131
+ "scripts/**/*.{js,ts}"
132
+ ],
133
+ "project": [
134
+ "**/*.{js,ts}"
135
+ ],
136
+ "ignoreBinaries": [
137
+ "date"
138
+ ],
139
+ "ignoreDependencies": [
140
+ "prisma-.+"
141
+ ]
142
+ },
143
+ "release": {
144
+ "branches": [
145
+ "main"
146
+ ],
147
+ "plugins": [
148
+ "@semantic-release/commit-analyzer",
149
+ "@semantic-release/release-notes-generator",
150
+ [
151
+ "@semantic-release/changelog",
152
+ {
153
+ "changelogFile": "CHANGELOG.md"
154
+ }
155
+ ],
156
+ "@semantic-release/npm",
157
+ "@semantic-release/github",
158
+ [
159
+ "@semantic-release/git",
160
+ {
161
+ "assets": [
162
+ "CHANGELOG.md",
163
+ "package.json"
164
+ ],
165
+ "message": "chore(release): set `package.json` to ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
166
+ }
167
+ ]
168
+ ]
169
+ }
170
+ }