cl-orm 1.0.0 → 2.1.0
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/README.md +12 -6
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -1
- package/lib/queries/_utils.d.ts +1 -1
- package/lib/queries/_utils.js +6 -5
- package/lib/queries/delete.js +1 -1
- package/lib/queries/insert.js +2 -2
- package/lib/queries/select.js +5 -5
- package/lib/queries/update.js +2 -7
- package/lib/queries/where/operators.d.ts +3 -0
- package/lib/queries/where/operators.js +16 -9
- package/lib/queries/where/where.js +10 -0
- package/lib/types.d.ts +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
[npm-image]: https://img.shields.io/npm/v/cl-orm.svg
|
|
2
|
+
[npm-url]: https://npmjs.org/package/cl-orm
|
|
3
|
+
[downloads-image]: https://img.shields.io/npm/dt/cl-orm.svg
|
|
4
|
+
[downloads-url]: https://npmjs.org/package/cl-orm
|
|
5
|
+
|
|
1
6
|
# CL ORM
|
|
2
7
|
|
|
3
8
|
<img align="right" width="64" height="64" alt="Logo" src="website/static/img/favicon.svg">
|
|
4
9
|
|
|
5
|
-
A lightweight **ORM** for **Cloudflare Workers** (**D1** and **Durable Objects**), designed to be intuitive
|
|
10
|
+
⛅️ A lightweight **ORM** for **Cloudflare Workers** (**D1** and **Durable Objects**), designed to be intuitive and productive, focused on essential functionality.
|
|
6
11
|
|
|
7
|
-
-
|
|
12
|
+
[![NPM Version][npm-image]][npm-url]
|
|
13
|
+
[![NPM Downloads][downloads-image]][downloads-url]
|
|
8
14
|
|
|
9
15
|
---
|
|
10
16
|
|
|
@@ -14,10 +20,10 @@ A lightweight **ORM** for **Cloudflare Workers** (**D1** and **Durable Objects**
|
|
|
14
20
|
|
|
15
21
|
## Why
|
|
16
22
|
|
|
17
|
-
- Supports both **Cloudflare D1** and **Durable Objects
|
|
23
|
+
- Supports both **Cloudflare D1** and **Durable Objects SQL Storage**.
|
|
18
24
|
- Unified **Connection** interface across different database drivers.
|
|
19
|
-
-
|
|
20
|
-
- Automatic **Prepared Statements
|
|
25
|
+
- User-friendly **ORM** for **INSERT**, **SELECT**, **UPDATE**, **DELETE** and **WHERE** clauses.
|
|
26
|
+
- Automatic **Prepared Statements**.
|
|
21
27
|
|
|
22
28
|
---
|
|
23
29
|
|
|
@@ -82,7 +88,7 @@ import { OP } from 'cl-orm';
|
|
|
82
88
|
|
|
83
89
|
export const getUser = async (db: Connection, id: number) => {
|
|
84
90
|
const user = await db.select({
|
|
85
|
-
|
|
91
|
+
from: 'users',
|
|
86
92
|
where: OP.eq('id', id),
|
|
87
93
|
limit: 1,
|
|
88
94
|
});
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { useD1 } from './drivers/d1.js';
|
|
2
2
|
export { useDO } from './drivers/do.js';
|
|
3
3
|
export { OP } from './queries/where/operators.js';
|
|
4
|
-
export
|
|
4
|
+
export { backtick as bt } from './queries/_utils.js';
|
|
5
|
+
export type { QueryResult, Connection, Meta, Condition, Param, WhereClause, WhereItem, WhereShorthand, } from './types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OP = exports.useDO = exports.useD1 = void 0;
|
|
3
|
+
exports.bt = exports.OP = exports.useDO = exports.useD1 = void 0;
|
|
4
4
|
var d1_js_1 = require("./drivers/d1.js");
|
|
5
5
|
Object.defineProperty(exports, "useD1", { enumerable: true, get: function () { return d1_js_1.useD1; } });
|
|
6
6
|
var do_js_1 = require("./drivers/do.js");
|
|
7
7
|
Object.defineProperty(exports, "useDO", { enumerable: true, get: function () { return do_js_1.useDO; } });
|
|
8
8
|
var operators_js_1 = require("./queries/where/operators.js");
|
|
9
9
|
Object.defineProperty(exports, "OP", { enumerable: true, get: function () { return operators_js_1.OP; } });
|
|
10
|
+
var _utils_js_1 = require("./queries/_utils.js");
|
|
11
|
+
Object.defineProperty(exports, "bt", { enumerable: true, get: function () { return _utils_js_1.backtick; } });
|
package/lib/queries/_utils.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const backtick: (name: string) => string;
|
package/lib/queries/_utils.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
if (name.includes('
|
|
3
|
+
exports.backtick = void 0;
|
|
4
|
+
const backtick = (name) => {
|
|
5
|
+
if (name.includes('`'))
|
|
6
|
+
return name;
|
|
7
|
+
if (name.includes('.'))
|
|
6
8
|
return name
|
|
7
9
|
.split('.')
|
|
8
10
|
.map((part) => `\`${part}\``)
|
|
9
11
|
.join('.');
|
|
10
|
-
}
|
|
11
12
|
return `\`${name}\``;
|
|
12
13
|
};
|
|
13
|
-
exports.
|
|
14
|
+
exports.backtick = backtick;
|
package/lib/queries/delete.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.buildDelete = void 0;
|
|
|
4
4
|
const _utils_js_1 = require("./_utils.js");
|
|
5
5
|
const where_js_1 = require("./where/where.js");
|
|
6
6
|
const buildDelete = (options) => {
|
|
7
|
-
const parts = ['DELETE FROM', (0, _utils_js_1.
|
|
7
|
+
const parts = ['DELETE FROM', (0, _utils_js_1.backtick)(options.from)];
|
|
8
8
|
const params = [];
|
|
9
9
|
if (options.where) {
|
|
10
10
|
const where = (0, where_js_1.buildWhere)(options.where);
|
package/lib/queries/insert.js
CHANGED
|
@@ -7,12 +7,12 @@ const buildInsert = (options) => {
|
|
|
7
7
|
? options.values
|
|
8
8
|
: [options.values];
|
|
9
9
|
const columns = Object.keys(rows[0]);
|
|
10
|
-
const columnsSql = columns.map(_utils_js_1.
|
|
10
|
+
const columnsSql = columns.map(_utils_js_1.backtick).join(', ');
|
|
11
11
|
const placeholders = `(${columns.map(() => '?').join(', ')})`;
|
|
12
12
|
const valuesSql = rows.map(() => placeholders).join(', ');
|
|
13
13
|
const params = rows.flatMap((row) => columns.map((col) => row[col]));
|
|
14
14
|
return {
|
|
15
|
-
sql: `INSERT INTO ${(0, _utils_js_1.
|
|
15
|
+
sql: `INSERT INTO ${(0, _utils_js_1.backtick)(options.into)} (${columnsSql}) VALUES ${valuesSql}`,
|
|
16
16
|
params,
|
|
17
17
|
};
|
|
18
18
|
};
|
package/lib/queries/select.js
CHANGED
|
@@ -8,13 +8,13 @@ const buildColumns = (columns) => {
|
|
|
8
8
|
return '*';
|
|
9
9
|
if (typeof columns === 'string')
|
|
10
10
|
return columns;
|
|
11
|
-
return columns.map(_utils_js_1.
|
|
11
|
+
return columns.map(_utils_js_1.backtick).join(', ');
|
|
12
12
|
};
|
|
13
13
|
const buildJoin = (join) => {
|
|
14
14
|
const type = join.outer
|
|
15
15
|
? `${join.type.toUpperCase()} OUTER`
|
|
16
16
|
: join.type.toUpperCase();
|
|
17
|
-
return `${type} JOIN ${(0, _utils_js_1.
|
|
17
|
+
return `${type} JOIN ${(0, _utils_js_1.backtick)(join.table)} ON ${(0, _utils_js_1.backtick)(join.on.a)} = ${(0, _utils_js_1.backtick)(join.on.b)}`;
|
|
18
18
|
};
|
|
19
19
|
const buildSelect = (options) => {
|
|
20
20
|
const parts = ['SELECT'];
|
|
@@ -22,7 +22,7 @@ const buildSelect = (options) => {
|
|
|
22
22
|
if (options.distinct)
|
|
23
23
|
parts.push('DISTINCT');
|
|
24
24
|
parts.push(buildColumns(options.columns));
|
|
25
|
-
parts.push('FROM', (0, _utils_js_1.
|
|
25
|
+
parts.push('FROM', (0, _utils_js_1.backtick)(options.from));
|
|
26
26
|
if (options.join) {
|
|
27
27
|
const joins = Array.isArray(options.join) ? options.join : [options.join];
|
|
28
28
|
for (const join of joins) {
|
|
@@ -35,10 +35,10 @@ const buildSelect = (options) => {
|
|
|
35
35
|
params.push(...where.params);
|
|
36
36
|
}
|
|
37
37
|
if (options.groupBy)
|
|
38
|
-
parts.push('GROUP BY', (0, _utils_js_1.
|
|
38
|
+
parts.push('GROUP BY', (0, _utils_js_1.backtick)(options.groupBy));
|
|
39
39
|
if (options.orderBy) {
|
|
40
40
|
const [column, direction = 'ASC'] = options.orderBy;
|
|
41
|
-
parts.push('ORDER BY', (0, _utils_js_1.
|
|
41
|
+
parts.push('ORDER BY', (0, _utils_js_1.backtick)(column), direction);
|
|
42
42
|
}
|
|
43
43
|
if (options.limit !== undefined) {
|
|
44
44
|
parts.push('LIMIT ?');
|
package/lib/queries/update.js
CHANGED
|
@@ -5,14 +5,9 @@ const _utils_js_1 = require("./_utils.js");
|
|
|
5
5
|
const where_js_1 = require("./where/where.js");
|
|
6
6
|
const buildUpdate = (options) => {
|
|
7
7
|
const columns = Object.keys(options.set);
|
|
8
|
-
const setSql = columns.map((col) => `${(0, _utils_js_1.
|
|
8
|
+
const setSql = columns.map((col) => `${(0, _utils_js_1.backtick)(col)} = ?`).join(', ');
|
|
9
9
|
const params = columns.map((col) => options.set[col]);
|
|
10
|
-
const parts = [
|
|
11
|
-
'UPDATE',
|
|
12
|
-
(0, _utils_js_1.quoteIdentifier)(options.table),
|
|
13
|
-
'SET',
|
|
14
|
-
setSql,
|
|
15
|
-
];
|
|
10
|
+
const parts = ['UPDATE', (0, _utils_js_1.backtick)(options.table), 'SET', setSql];
|
|
16
11
|
if (options.where) {
|
|
17
12
|
const where = (0, where_js_1.buildWhere)(options.where);
|
|
18
13
|
parts.push('WHERE', where.sql);
|
|
@@ -20,4 +20,7 @@ export declare const OP: {
|
|
|
20
20
|
};
|
|
21
21
|
between: (column: string, params: [Param, Param]) => Condition;
|
|
22
22
|
notBetween: (column: string, params: [Param, Param]) => Condition;
|
|
23
|
+
AND: (...conditions: Condition[]) => Condition;
|
|
24
|
+
OR: (...conditions: Condition[]) => Condition;
|
|
25
|
+
XOR: (...conditions: Condition[]) => Condition;
|
|
23
26
|
};
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OP = void 0;
|
|
4
4
|
const _utils_js_1 = require("../_utils.js");
|
|
5
|
+
const logical = (connector, conditions) => ({
|
|
6
|
+
condition: `(${conditions.map((c) => c.condition).join(` ${connector} `)})`,
|
|
7
|
+
params: conditions.flatMap((c) => c.params),
|
|
8
|
+
});
|
|
5
9
|
const comparison = (column, operator, param) => ({
|
|
6
|
-
condition: `${(0, _utils_js_1.
|
|
10
|
+
condition: `${(0, _utils_js_1.backtick)(column)} ${operator} ?`,
|
|
7
11
|
params: [param],
|
|
8
12
|
});
|
|
9
13
|
exports.OP = {
|
|
@@ -16,45 +20,48 @@ exports.OP = {
|
|
|
16
20
|
like: (column, param) => comparison(column, 'LIKE', param),
|
|
17
21
|
notLike: (column, param) => comparison(column, 'NOT LIKE', param),
|
|
18
22
|
isNull: (column) => ({
|
|
19
|
-
condition: `${(0, _utils_js_1.
|
|
23
|
+
condition: `${(0, _utils_js_1.backtick)(column)} IS NULL`,
|
|
20
24
|
params: [],
|
|
21
25
|
}),
|
|
22
26
|
isNotNull: (column) => ({
|
|
23
|
-
condition: `${(0, _utils_js_1.
|
|
27
|
+
condition: `${(0, _utils_js_1.backtick)(column)} IS NOT NULL`,
|
|
24
28
|
params: [],
|
|
25
29
|
}),
|
|
26
30
|
in: ((column, valuesOrSubquery, subqueryParams) => {
|
|
27
31
|
if (typeof valuesOrSubquery === 'string') {
|
|
28
32
|
return {
|
|
29
|
-
condition: `${(0, _utils_js_1.
|
|
33
|
+
condition: `${(0, _utils_js_1.backtick)(column)} IN (${valuesOrSubquery})`,
|
|
30
34
|
params: subqueryParams ?? [],
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
const placeholders = valuesOrSubquery.map(() => '?').join(', ');
|
|
34
38
|
return {
|
|
35
|
-
condition: `${(0, _utils_js_1.
|
|
39
|
+
condition: `${(0, _utils_js_1.backtick)(column)} IN (${placeholders})`,
|
|
36
40
|
params: valuesOrSubquery,
|
|
37
41
|
};
|
|
38
42
|
}),
|
|
39
43
|
notIn: ((column, valuesOrSubquery, subqueryParams) => {
|
|
40
44
|
if (typeof valuesOrSubquery === 'string') {
|
|
41
45
|
return {
|
|
42
|
-
condition: `${(0, _utils_js_1.
|
|
46
|
+
condition: `${(0, _utils_js_1.backtick)(column)} NOT IN (${valuesOrSubquery})`,
|
|
43
47
|
params: subqueryParams ?? [],
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
const placeholders = valuesOrSubquery.map(() => '?').join(', ');
|
|
47
51
|
return {
|
|
48
|
-
condition: `${(0, _utils_js_1.
|
|
52
|
+
condition: `${(0, _utils_js_1.backtick)(column)} NOT IN (${placeholders})`,
|
|
49
53
|
params: valuesOrSubquery,
|
|
50
54
|
};
|
|
51
55
|
}),
|
|
52
56
|
between: (column, params) => ({
|
|
53
|
-
condition: `${(0, _utils_js_1.
|
|
57
|
+
condition: `${(0, _utils_js_1.backtick)(column)} BETWEEN ? AND ?`,
|
|
54
58
|
params,
|
|
55
59
|
}),
|
|
56
60
|
notBetween: (column, params) => ({
|
|
57
|
-
condition: `${(0, _utils_js_1.
|
|
61
|
+
condition: `${(0, _utils_js_1.backtick)(column)} NOT BETWEEN ? AND ?`,
|
|
58
62
|
params,
|
|
59
63
|
}),
|
|
64
|
+
AND: (...conditions) => logical('AND', conditions),
|
|
65
|
+
OR: (...conditions) => logical('OR', conditions),
|
|
66
|
+
XOR: (...conditions) => logical('XOR', conditions),
|
|
60
67
|
};
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildWhere = void 0;
|
|
4
|
+
const _utils_js_1 = require("../_utils.js");
|
|
4
5
|
const isConnector = (value) => typeof value === 'string' && ['AND', 'OR', 'XOR', 'NOT'].includes(value);
|
|
5
6
|
const isCondition = (value) => typeof value === 'object' && !Array.isArray(value) && 'condition' in value;
|
|
7
|
+
const isShorthand = (value) => typeof value === 'object' && !Array.isArray(value) && !('condition' in value);
|
|
8
|
+
const fromShorthand = (shorthand) => {
|
|
9
|
+
const entries = Object.entries(shorthand);
|
|
10
|
+
const sql = entries.map(([key]) => `${(0, _utils_js_1.backtick)(key)} = ?`).join(' AND ');
|
|
11
|
+
const params = entries.map(([, value]) => value);
|
|
12
|
+
return { sql, params };
|
|
13
|
+
};
|
|
6
14
|
const processItems = (items) => {
|
|
7
15
|
const parts = [];
|
|
8
16
|
const params = [];
|
|
@@ -27,6 +35,8 @@ const processItems = (items) => {
|
|
|
27
35
|
const buildWhere = (where) => {
|
|
28
36
|
if (typeof where === 'string')
|
|
29
37
|
return { sql: where, params: [] };
|
|
38
|
+
if (isShorthand(where))
|
|
39
|
+
return fromShorthand(where);
|
|
30
40
|
if (isCondition(where))
|
|
31
41
|
return { sql: where.condition, params: [...where.params] };
|
|
32
42
|
return processItems(where);
|
package/lib/types.d.ts
CHANGED
|
@@ -5,10 +5,11 @@ export type Condition = {
|
|
|
5
5
|
};
|
|
6
6
|
export type Connector = 'AND' | 'OR' | 'XOR' | 'NOT';
|
|
7
7
|
export type WhereItem = Condition | Connector | WhereItem[];
|
|
8
|
-
export type
|
|
8
|
+
export type WhereShorthand = Record<string, Param>;
|
|
9
|
+
export type WhereClause = string | Condition | WhereItem[] | WhereShorthand;
|
|
9
10
|
type Values = Record<string, unknown>;
|
|
10
11
|
export type InsertOptions = {
|
|
11
|
-
|
|
12
|
+
into: string;
|
|
12
13
|
values: Values | Values[];
|
|
13
14
|
};
|
|
14
15
|
export type JoinOptions = {
|
|
@@ -23,7 +24,7 @@ export type JoinOptions = {
|
|
|
23
24
|
export type SelectOptions = {
|
|
24
25
|
distinct?: boolean;
|
|
25
26
|
columns?: string | string[];
|
|
26
|
-
|
|
27
|
+
from: string;
|
|
27
28
|
join?: JoinOptions | JoinOptions[];
|
|
28
29
|
where?: WhereClause;
|
|
29
30
|
limit?: number;
|
|
@@ -39,7 +40,7 @@ export type UpdateOptions = {
|
|
|
39
40
|
params?: unknown[];
|
|
40
41
|
};
|
|
41
42
|
export type DeleteOptions = {
|
|
42
|
-
|
|
43
|
+
from: string;
|
|
43
44
|
where?: WhereClause;
|
|
44
45
|
limit?: number;
|
|
45
46
|
params?: unknown[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cl-orm",
|
|
3
3
|
"main": "./lib/index.js",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"description": "A lightweight ORM for Cloudflare Workers (D1 and Durable Objects), designed to be intuitive, productive and focused on essential functionality",
|
|
6
6
|
"homepage": "https://wellwelwel.github.io/cl-orm/docs/",
|
|
7
7
|
"license": "MIT",
|