@apisr/drizzle-model 2.0.2 → 2.0.4

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.
@@ -1,198 +0,0 @@
1
- import { buildSelectProjection } from "./projection.mjs";
2
- import { MutateResult, QueryResult } from "./thenable.mjs";
3
- import { applyExclude, applyFormat, applySelect } from "./transform.mjs";
4
- import { compileWhere } from "./where.mjs";
5
- import { runWithJoins } from "./with.mjs";
6
- import { and } from "drizzle-orm";
7
-
8
- //#region src/model/core/runtime.ts
9
- function compileEffectiveWhere(table, optionsWhere, stateWhere) {
10
- const base = compileWhere(table, optionsWhere);
11
- const extra = compileWhere(table, stateWhere);
12
- if (base && extra) return and(base, extra);
13
- return base ?? extra;
14
- }
15
- function isReturningIdDialect(dialect) {
16
- return dialect === "MySQL" || dialect === "SingleStore" || dialect === "CockroachDB";
17
- }
18
- async function execReturn(q, mState, dialect) {
19
- if (typeof q?.returning === "function") return await (mState.returnSelect ? q.returning(mState.returnSelect) : q.returning());
20
- if (isReturningIdDialect(dialect) && typeof q?.$returningId === "function") return await q.$returningId();
21
- return await q;
22
- }
23
- function normalizeUpsertTarget(table, target) {
24
- if (!target) return target;
25
- if (typeof target === "string") return table[target] ?? target;
26
- if (Array.isArray(target)) return target.map((t) => typeof t === "string" ? table[t] ?? t : t);
27
- return target;
28
- }
29
- function makeModelRuntime(config) {
30
- const baseState = {
31
- db: config.db,
32
- where: void 0
33
- };
34
- const build = (state) => {
35
- const modelObj = {
36
- $model: "model",
37
- $modelName: config.tableName,
38
- $format: config.options.format,
39
- $formatValue: void 0,
40
- where(value) {
41
- return build({
42
- ...state,
43
- where: value
44
- });
45
- },
46
- include(value) {
47
- return value;
48
- },
49
- extend(nextOptions) {
50
- return makeModelRuntime({
51
- ...config,
52
- options: {
53
- ...config.options,
54
- ...nextOptions,
55
- methods: {
56
- ...nextOptions?.methods ?? {},
57
- ...config.options?.methods ?? {}
58
- },
59
- format: nextOptions?.format ?? config.options?.format
60
- }
61
- });
62
- },
63
- db(db) {
64
- return makeModelRuntime({
65
- ...config,
66
- db
67
- });
68
- }
69
- };
70
- const attachMethods = (methods) => {
71
- if (!methods) return;
72
- for (const [key, fn] of Object.entries(methods)) if (typeof fn === "function") modelObj[key] = fn.bind(modelObj);
73
- };
74
- attachMethods(config.options.methods);
75
- modelObj.findMany = () => {
76
- const runner = async (qState) => {
77
- const table = config.schema[config.tableName];
78
- const whereSql = compileEffectiveWhere(table, config.options.where, state.where);
79
- let result;
80
- if (qState.with) result = await runWithJoins({
81
- db: config.db,
82
- schema: config.schema,
83
- relations: config.relations,
84
- tableName: config.tableName,
85
- table,
86
- dialect: config.dialect,
87
- whereSql,
88
- qState,
89
- kind: "many"
90
- });
91
- else {
92
- const { selectMap } = buildSelectProjection(table, qState.select, qState.exclude);
93
- let q = config.db.select(selectMap).from(table);
94
- if (whereSql) q = q.where(whereSql);
95
- result = await q;
96
- }
97
- let out = result;
98
- if (qState.select) out = applySelect(out, qState.select);
99
- if (qState.exclude) out = applyExclude(out, qState.exclude);
100
- if (!qState.raw) out = applyFormat(out, config.options.format);
101
- return out;
102
- };
103
- return new QueryResult({}, runner);
104
- };
105
- modelObj.findFirst = () => {
106
- const runner = async (qState) => {
107
- const table = config.schema[config.tableName];
108
- const whereSql = compileEffectiveWhere(table, config.options.where, state.where);
109
- let result;
110
- if (qState.with) result = await runWithJoins({
111
- db: config.db,
112
- schema: config.schema,
113
- relations: config.relations,
114
- tableName: config.tableName,
115
- table,
116
- dialect: config.dialect,
117
- whereSql,
118
- qState,
119
- kind: "one"
120
- });
121
- else {
122
- const { selectMap } = buildSelectProjection(table, qState.select, qState.exclude);
123
- let q = config.db.select(selectMap).from(table);
124
- if (whereSql) q = q.where(whereSql);
125
- q = q.limit(1);
126
- result = (await q)[0];
127
- }
128
- let out = result;
129
- if (qState.select) out = applySelect(out, qState.select);
130
- if (qState.exclude) out = applyExclude(out, qState.exclude);
131
- if (!qState.raw) out = applyFormat(out, config.options.format);
132
- return out;
133
- };
134
- return new QueryResult({}, runner);
135
- };
136
- modelObj.insert = (value) => {
137
- const runner = async (mState) => {
138
- const table = config.schema[config.tableName];
139
- return await execReturn(config.db.insert(table).values(mState.value), mState, config.dialect);
140
- };
141
- return new MutateResult({
142
- kind: "insert",
143
- value
144
- }, runner);
145
- };
146
- modelObj.update = (value) => {
147
- const runner = async (mState) => {
148
- const table = config.schema[config.tableName];
149
- const whereSql = compileEffectiveWhere(table, config.options.where, state.where);
150
- let q = config.db.update(table).set(mState.value);
151
- if (whereSql) q = q.where(whereSql);
152
- return await execReturn(q, mState, config.dialect);
153
- };
154
- return new MutateResult({
155
- kind: "update",
156
- value
157
- }, runner);
158
- };
159
- modelObj.delete = () => {
160
- const runner = async (mState) => {
161
- const table = config.schema[config.tableName];
162
- const whereSql = compileEffectiveWhere(table, config.options.where, state.where);
163
- let q = config.db.delete(table);
164
- if (whereSql) q = q.where(whereSql);
165
- return await execReturn(q, mState, config.dialect);
166
- };
167
- return new MutateResult({ kind: "delete" }, runner);
168
- };
169
- modelObj.upsert = (value) => {
170
- const runner = async (mState) => {
171
- const table = config.schema[config.tableName];
172
- const insertValues = mState.value.insert;
173
- const updateCfg = mState.value.update;
174
- const target = normalizeUpsertTarget(table, mState.value.target);
175
- let updateSet = updateCfg;
176
- if (typeof updateCfg === "function") updateSet = updateCfg({
177
- excluded: (field) => table[field],
178
- inserted: (field) => table[field]
179
- });
180
- let q = config.db.insert(table).values(insertValues);
181
- if (q.onConflictDoUpdate) q = q.onConflictDoUpdate({
182
- target,
183
- set: updateSet
184
- });
185
- return await execReturn(q, mState, config.dialect);
186
- };
187
- return new MutateResult({
188
- kind: "upsert",
189
- value
190
- }, runner);
191
- };
192
- return modelObj;
193
- };
194
- return build(baseState);
195
- }
196
-
197
- //#endregion
198
- export { makeModelRuntime };
@@ -1,64 +0,0 @@
1
- //#region src/model/core/thenable.ts
2
- var ThenableResult = class {
3
- _execute;
4
- constructor(execute) {
5
- this._execute = execute;
6
- }
7
- then(onfulfilled, onrejected) {
8
- return this._execute().then(onfulfilled, onrejected);
9
- }
10
- };
11
- var QueryResult = class QueryResult extends ThenableResult {
12
- state;
13
- runner;
14
- constructor(state, runner) {
15
- super(() => runner(state));
16
- this.state = state;
17
- this.runner = runner;
18
- }
19
- with(value) {
20
- return new QueryResult({
21
- ...this.state,
22
- with: value
23
- }, this.runner);
24
- }
25
- select(value) {
26
- return new QueryResult({
27
- ...this.state,
28
- select: value
29
- }, this.runner);
30
- }
31
- exclude(value) {
32
- return new QueryResult({
33
- ...this.state,
34
- exclude: value
35
- }, this.runner);
36
- }
37
- raw() {
38
- return new QueryResult({
39
- ...this.state,
40
- raw: true
41
- }, this.runner);
42
- }
43
- debug() {
44
- return this.state;
45
- }
46
- };
47
- var MutateResult = class MutateResult extends ThenableResult {
48
- state;
49
- runner;
50
- constructor(state, runner) {
51
- super(() => runner(state));
52
- this.state = state;
53
- this.runner = runner;
54
- }
55
- return(value) {
56
- return new MutateResult({
57
- ...this.state,
58
- returnSelect: value
59
- }, this.runner);
60
- }
61
- };
62
-
63
- //#endregion
64
- export { MutateResult, QueryResult };
@@ -1,39 +0,0 @@
1
- //#region src/model/core/transform.ts
2
- function applySelect(value, select) {
3
- if (value == null) return value;
4
- if (Array.isArray(value)) return value.map((v) => applySelect(v, select));
5
- if (typeof value !== "object") return value;
6
- const out = {};
7
- for (const [key, sel] of Object.entries(select)) {
8
- if (sel === true) {
9
- out[key] = value[key];
10
- continue;
11
- }
12
- if (sel && typeof sel === "object") out[key] = applySelect(value[key], sel);
13
- }
14
- return out;
15
- }
16
- function applyExclude(value, exclude) {
17
- if (value == null) return value;
18
- if (Array.isArray(value)) return value.map((v) => applyExclude(v, exclude));
19
- if (typeof value !== "object") return value;
20
- const out = { ...value };
21
- for (const [key, ex] of Object.entries(exclude)) {
22
- if (ex === true) {
23
- delete out[key];
24
- continue;
25
- }
26
- if (ex && typeof ex === "object" && key in out) out[key] = applyExclude(out[key], ex);
27
- }
28
- return out;
29
- }
30
- function applyFormat(value, format) {
31
- if (!format) return value;
32
- if (value == null) return value;
33
- if (Array.isArray(value)) return value.map((v) => applyFormat(v, format));
34
- if (typeof value !== "object") return value;
35
- return format(value);
36
- }
37
-
38
- //#endregion
39
- export { applyExclude, applyFormat, applySelect };
@@ -1,130 +0,0 @@
1
- import { and, between, eq, gt, gte, ilike, inArray, isNull, like, lt, lte, ne, notBetween, notInArray, or } from "drizzle-orm";
2
-
3
- //#region src/model/core/where.ts
4
- function isPromiseLike(value) {
5
- return value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
6
- }
7
- function isEscapedValue(value) {
8
- return value && typeof value === "object" && ("equal" in value || value.__kind === "esc-op");
9
- }
10
- function unwrapEscapedValue(column, value) {
11
- if (!isEscapedValue(value)) return { value };
12
- if (value.__kind === "esc-op") return { sql: value.op(column, value.value) };
13
- return { value: value.equal };
14
- }
15
- function compileColumnValue(column, value) {
16
- if (isEscapedValue(value)) {
17
- if (value.__kind === "esc-op") return value.op(column, value.value);
18
- return eq(column, value.equal);
19
- }
20
- if (value && typeof value === "object" && !Array.isArray(value)) {
21
- const parts = [];
22
- const pushIf = (sql) => {
23
- if (sql) parts.push(sql);
24
- };
25
- const v = value;
26
- if ("eq" in v) {
27
- const u = unwrapEscapedValue(column, v.eq);
28
- pushIf(u.sql ?? eq(column, u.value));
29
- }
30
- if ("equal" in v) {
31
- const u = unwrapEscapedValue(column, v.equal);
32
- pushIf(u.sql ?? eq(column, u.value));
33
- }
34
- if ("not" in v) {
35
- const u = unwrapEscapedValue(column, v.not);
36
- pushIf(u.sql ?? ne(column, u.value));
37
- }
38
- if ("in" in v) {
39
- const arr = (v.in ?? []).map((item) => unwrapEscapedValue(column, item));
40
- const sqls = arr.map((x) => x.sql).filter(Boolean);
41
- const values = arr.map((x) => x.value).filter((x) => x !== void 0);
42
- if (sqls.length) pushIf(or(...sqls));
43
- if (values.length) pushIf(inArray(column, values));
44
- }
45
- if ("nin" in v) {
46
- const arr = (v.nin ?? []).map((item) => unwrapEscapedValue(column, item));
47
- const sqls = arr.map((x) => x.sql).filter(Boolean);
48
- const values = arr.map((x) => x.value).filter((x) => x !== void 0);
49
- if (sqls.length) pushIf(or(...sqls));
50
- if (values.length) pushIf(notInArray(column, values));
51
- }
52
- if ("isNull" in v) pushIf(v.isNull ? isNull(column) : void 0);
53
- if ("gt" in v) {
54
- const u = unwrapEscapedValue(column, v.gt);
55
- pushIf(u.sql ?? gt(column, u.value));
56
- }
57
- if ("gte" in v) {
58
- const u = unwrapEscapedValue(column, v.gte);
59
- pushIf(u.sql ?? gte(column, u.value));
60
- }
61
- if ("lt" in v) {
62
- const u = unwrapEscapedValue(column, v.lt);
63
- pushIf(u.sql ?? lt(column, u.value));
64
- }
65
- if ("lte" in v) {
66
- const u = unwrapEscapedValue(column, v.lte);
67
- pushIf(u.sql ?? lte(column, u.value));
68
- }
69
- if ("between" in v) {
70
- const a = unwrapEscapedValue(column, v.between?.[0]);
71
- const b = unwrapEscapedValue(column, v.between?.[1]);
72
- if (a.sql) pushIf(a.sql);
73
- if (b.sql) pushIf(b.sql);
74
- pushIf(between(column, a.value, b.value));
75
- }
76
- if ("notBetween" in v) {
77
- const a = unwrapEscapedValue(column, v.notBetween?.[0]);
78
- const b = unwrapEscapedValue(column, v.notBetween?.[1]);
79
- if (a.sql) pushIf(a.sql);
80
- if (b.sql) pushIf(b.sql);
81
- pushIf(notBetween(column, a.value, b.value));
82
- }
83
- if ("like" in v) {
84
- const u = unwrapEscapedValue(column, v.like);
85
- pushIf(u.sql ?? like(column, u.value));
86
- }
87
- if ("ilike" in v) {
88
- const u = unwrapEscapedValue(column, v.ilike);
89
- pushIf(u.sql ?? ilike(column, u.value));
90
- }
91
- if (Array.isArray(v.or)) {
92
- const sub = v.or.map((item) => compileColumnValue(column, item)).filter(Boolean);
93
- if (sub.length) pushIf(or(...sub));
94
- }
95
- if (Array.isArray(v.and)) {
96
- const sub = v.and.map((item) => compileColumnValue(column, item)).filter(Boolean);
97
- if (sub.length) pushIf(and(...sub));
98
- }
99
- if (!parts.length) return;
100
- return parts.length === 1 ? parts[0] : and(...parts);
101
- }
102
- return eq(column, value);
103
- }
104
- function compileWhereObject(fields, where) {
105
- const parts = [];
106
- for (const [key, value] of Object.entries(where)) {
107
- if (value === void 0) continue;
108
- const col = fields[key];
109
- if (col) {
110
- const sql = compileColumnValue(col, value);
111
- if (sql) parts.push(sql);
112
- continue;
113
- }
114
- if (value && typeof value === "object") throw new Error(`Relation where is not implemented yet for key '${key}'.`);
115
- }
116
- if (!parts.length) return;
117
- return parts.length === 1 ? parts[0] : and(...parts);
118
- }
119
- function compileWhere(fields, where) {
120
- if (!where) return;
121
- if (typeof where === "object" && where && !isPromiseLike(where)) {
122
- if (where.$model === "model") throw new Error("Model-as-where is not implemented yet.");
123
- if (where.getSQL) return where;
124
- return compileWhereObject(fields, where);
125
- }
126
- return where;
127
- }
128
-
129
- //#endregion
130
- export { compileWhere };
@@ -1,19 +0,0 @@
1
- import { executeWithJoins } from "./joins.mjs";
2
-
3
- //#region src/model/core/with.ts
4
- async function runWithJoins(args) {
5
- return await executeWithJoins({
6
- db: args.db,
7
- schema: args.schema,
8
- relations: args.relations,
9
- baseTableName: args.tableName,
10
- baseTable: args.table,
11
- dialect: args.dialect,
12
- whereSql: args.whereSql,
13
- withValue: args.qState.with,
14
- limitOne: args.kind === "one"
15
- });
16
- }
17
-
18
- //#endregion
19
- export { runWithJoins };