cl-orm 0.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/.editorconfig +12 -0
- package/.gitattributes +1 -0
- package/.prettierignore +3 -0
- package/.prettierrc +34 -0
- package/.vscode/settings.json +14 -0
- package/README.md +105 -0
- package/mcr.config.ts +12 -0
- package/package.json +30 -0
- package/src/drivers/_utils.ts +31 -0
- package/src/drivers/d1.ts +70 -0
- package/src/drivers/do.ts +81 -0
- package/src/index.ts +13 -0
- package/src/queries/_utils.ts +10 -0
- package/src/queries/delete.ts +26 -0
- package/src/queries/insert.ts +22 -0
- package/src/queries/select.ts +64 -0
- package/src/queries/update.ts +28 -0
- package/src/queries/where/operators.ts +96 -0
- package/src/queries/where/where.ts +50 -0
- package/src/types.ts +76 -0
- package/test/__fixtures__/d1/worker.ts +70 -0
- package/test/__fixtures__/d1/wrangler.jsonc +13 -0
- package/test/__fixtures__/do/worker.ts +106 -0
- package/test/__fixtures__/do/wrangler.jsonc +20 -0
- package/test/e2e/d1.test.ts +113 -0
- package/test/e2e/do.test.ts +116 -0
- package/test/unit/buildDelete.test.ts +36 -0
- package/test/unit/buildInsert.test.ts +36 -0
- package/test/unit/buildSelect.test.ts +137 -0
- package/test/unit/buildUpdate.test.ts +34 -0
- package/test/unit/buildWhere.test.ts +249 -0
- package/test/unit/operators.test.ts +98 -0
- package/test/unit/prepare.test.ts +22 -0
- package/test/unit/quoteIdentifier.test.ts +12 -0
- package/test/unit/returnsRows.test.ts +41 -0
- package/test/unit/setMeta.test.ts +31 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +34 -0
- package/website/.prettierignore +4 -0
- package/website/.prettierrc +34 -0
- package/website/README.md +3 -0
- package/website/docs/documentation/connection.mdx +123 -0
- package/website/docs/documentation/queries/_category_.json +7 -0
- package/website/docs/documentation/queries/delete.mdx +51 -0
- package/website/docs/documentation/queries/insert.mdx +63 -0
- package/website/docs/documentation/queries/operators/_category_.json +7 -0
- package/website/docs/documentation/queries/operators/between.mdx +17 -0
- package/website/docs/documentation/queries/operators/eq.mdx +22 -0
- package/website/docs/documentation/queries/operators/gt.mdx +22 -0
- package/website/docs/documentation/queries/operators/gte.mdx +22 -0
- package/website/docs/documentation/queries/operators/in.mdx +28 -0
- package/website/docs/documentation/queries/operators/is-not-null.mdx +22 -0
- package/website/docs/documentation/queries/operators/is-null.mdx +22 -0
- package/website/docs/documentation/queries/operators/like.mdx +27 -0
- package/website/docs/documentation/queries/operators/lt.mdx +22 -0
- package/website/docs/documentation/queries/operators/lte.mdx +22 -0
- package/website/docs/documentation/queries/operators/ne.mdx +22 -0
- package/website/docs/documentation/queries/operators/not-between.mdx +17 -0
- package/website/docs/documentation/queries/operators/not-like.mdx +27 -0
- package/website/docs/documentation/queries/operators/notIn.mdx +28 -0
- package/website/docs/documentation/queries/select.mdx +294 -0
- package/website/docs/documentation/queries/update.mdx +61 -0
- package/website/docs/documentation/queries/where.mdx +176 -0
- package/website/docs/index.mdx +228 -0
- package/website/docusaurus.config.ts +82 -0
- package/website/package-lock.json +21348 -0
- package/website/package.json +59 -0
- package/website/plugins/locale.ts +16 -0
- package/website/sidebars.ts +18 -0
- package/website/src/components/FAQ.tsx +35 -0
- package/website/src/components/Loading.tsx +4 -0
- package/website/src/components/PageTitle.tsx +29 -0
- package/website/src/css/_faq.scss +39 -0
- package/website/src/css/_loading.scss +43 -0
- package/website/src/css/_mixins.scss +19 -0
- package/website/src/css/custom.scss +149 -0
- package/website/src/pages/index.tsx +17 -0
- package/website/static/.nojekyll +0 -0
- package/website/static/img/favicon.svg +1 -0
- package/website/test/unit/check-extensions.test.ts +48 -0
- package/website/tsconfig.json +14 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: /
|
|
3
|
+
position: 1
|
|
4
|
+
title: Getting Started
|
|
5
|
+
description: A lightweight ORM for Cloudflare Workers, designed to be intuitive, productive and focused on essential functionality.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import { FAQ } from '@site/src/components/FAQ';
|
|
9
|
+
import { PageTitle } from '@site/src/components/PageTitle';
|
|
10
|
+
import Logo from '@site/static/img/favicon.svg';
|
|
11
|
+
import TabItem from '@theme/TabItem';
|
|
12
|
+
import Tabs from '@theme/Tabs';
|
|
13
|
+
|
|
14
|
+
<PageTitle title='CL ORM | Getting Started' />
|
|
15
|
+
|
|
16
|
+
[npm-image]: https://img.shields.io/npm/v/cl-orm.svg
|
|
17
|
+
[npm-url]: https://npmjs.org/package/cl-orm
|
|
18
|
+
[downloads-image]: https://img.shields.io/npm/dt/cl-orm.svg
|
|
19
|
+
[downloads-url]: https://npmjs.org/package/cl-orm
|
|
20
|
+
|
|
21
|
+
# CL ORM
|
|
22
|
+
|
|
23
|
+
<div className='title-section'>
|
|
24
|
+
<aside>
|
|
25
|
+
A lightweight **ORM** for **Cloudflare Workers**, designed to be intuitive, productive and focused on essential functionality.
|
|
26
|
+
|
|
27
|
+
[![NPM Version][npm-image]][npm-url]
|
|
28
|
+
[![NPM Downloads][downloads-image]][downloads-url]
|
|
29
|
+
|
|
30
|
+
> This project supports **Cloudflare D1** and **Durable Objects SQL Storage** as database drivers.
|
|
31
|
+
|
|
32
|
+
</aside>
|
|
33
|
+
<aside>
|
|
34
|
+
<Logo className='logo' width={64} height={64} />
|
|
35
|
+
</aside>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
## Why
|
|
39
|
+
|
|
40
|
+
- Supports both **Cloudflare D1** and **Durable Objects** SQL Storage.
|
|
41
|
+
- Unified **Connection** interface across different database drivers.
|
|
42
|
+
- An user-friendly ORM for **INSERT**, **SELECT**, **UPDATE**, **DELETE** and **WHERE** clauses.
|
|
43
|
+
- Automatic **Prepared Statements** (including **LIMIT** and **OFFSET**).
|
|
44
|
+
|
|
45
|
+
<hr />
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm i cl-orm
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
<hr />
|
|
54
|
+
|
|
55
|
+
## Getting Started
|
|
56
|
+
|
|
57
|
+
### Connect
|
|
58
|
+
|
|
59
|
+
<Tabs>
|
|
60
|
+
<TabItem value='D1' default>
|
|
61
|
+
|
|
62
|
+
#### src/index.ts
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { useD1 } from 'cl-orm';
|
|
66
|
+
|
|
67
|
+
export default {
|
|
68
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
69
|
+
const db = useD1(env.DB);
|
|
70
|
+
|
|
71
|
+
await db.query('SELECT 1');
|
|
72
|
+
// ...
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### wrangler.jsonc
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"name": "my-worker",
|
|
82
|
+
"main": "src/index.ts",
|
|
83
|
+
"d1_databases": [
|
|
84
|
+
{
|
|
85
|
+
"binding": "DB",
|
|
86
|
+
"database_name": "my-database",
|
|
87
|
+
"database_id": "<your-database-id>"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
</TabItem>
|
|
94
|
+
<TabItem value='Durable Objects'>
|
|
95
|
+
|
|
96
|
+
#### src/index.ts
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { useDO } from 'cl-orm';
|
|
100
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
101
|
+
|
|
102
|
+
export class MyDurableObject extends DurableObject {
|
|
103
|
+
async fetch(request: Request): Promise<Response> {
|
|
104
|
+
const db = useDO(this.ctx.storage.sql);
|
|
105
|
+
|
|
106
|
+
await db.query('SELECT 1');
|
|
107
|
+
// ...
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### wrangler.jsonc
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"name": "my-worker",
|
|
117
|
+
"main": "src/index.ts",
|
|
118
|
+
"durable_objects": {
|
|
119
|
+
"bindings": [
|
|
120
|
+
{
|
|
121
|
+
"name": "MY_DO",
|
|
122
|
+
"class_name": "MyDurableObject"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
"migrations": [
|
|
127
|
+
{
|
|
128
|
+
"tag": "v1",
|
|
129
|
+
"new_sqlite_classes": ["MyDurableObject"]
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
</TabItem>
|
|
136
|
+
</Tabs>
|
|
137
|
+
|
|
138
|
+
<hr />
|
|
139
|
+
|
|
140
|
+
## Documentation
|
|
141
|
+
|
|
142
|
+
See detailed specifications and usage in [**Documentation**](/docs/category/documentation) section.
|
|
143
|
+
|
|
144
|
+
<hr />
|
|
145
|
+
|
|
146
|
+
## D1 vs Durable Objects
|
|
147
|
+
|
|
148
|
+
**CL ORM** provides a unified **Connection** interface across both drivers. The same API works identically regardless of the underlying database.
|
|
149
|
+
|
|
150
|
+
> The following examples are based on **TypeScript** and **ES Modules**.
|
|
151
|
+
|
|
152
|
+
### Returning a single user
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import type { Connection } from 'cl-orm';
|
|
156
|
+
import { OP } from 'cl-orm';
|
|
157
|
+
|
|
158
|
+
export const getUser = async (db: Connection, id: number) => {
|
|
159
|
+
const user = await db.select({
|
|
160
|
+
table: 'users',
|
|
161
|
+
where: OP.eq('id', id),
|
|
162
|
+
limit: 1,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return user;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Usage: await getUser(db, 15);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
> Due to `limit: 1`, it returns a direct object with the row result or `null`.
|
|
172
|
+
|
|
173
|
+
<FAQ title={<><ins>OP</ins> Explanation</>}>
|
|
174
|
+
|
|
175
|
+
**OP** = Operation
|
|
176
|
+
|
|
177
|
+
`OP.eq`: is **column** equal to **value**<br/>
|
|
178
|
+
|
|
179
|
+
See all available operators [here](/docs/category/operators).
|
|
180
|
+
|
|
181
|
+
</FAQ >
|
|
182
|
+
|
|
183
|
+
<hr />
|
|
184
|
+
|
|
185
|
+
### Returning enabled users based on their specializations
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import type { Connection, Param } from 'cl-orm';
|
|
189
|
+
import { OP } from 'cl-orm';
|
|
190
|
+
|
|
191
|
+
export const getUsersBySpecializations = async (
|
|
192
|
+
db: Connection,
|
|
193
|
+
specializations: Param[]
|
|
194
|
+
) => {
|
|
195
|
+
const users = await db.select({
|
|
196
|
+
table: 'users',
|
|
197
|
+
columns: ['name', 'age'],
|
|
198
|
+
where: [
|
|
199
|
+
OP.eq('status', true),
|
|
200
|
+
'AND',
|
|
201
|
+
OP.in('specialization', specializations),
|
|
202
|
+
],
|
|
203
|
+
orderBy: ['name'],
|
|
204
|
+
limit: 10,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return users;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// Usage: await getUsersBySpecializations(db, ['frontend', 'backend']);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
<FAQ title={<><ins>OP</ins> Explanation</>}>
|
|
214
|
+
|
|
215
|
+
**OP** = Operation
|
|
216
|
+
|
|
217
|
+
`OP.eq`: is **column** equal to **value**<br/>
|
|
218
|
+
`OP.in`: is in **column** [**values**,]
|
|
219
|
+
|
|
220
|
+
See all available operators [here](/docs/category/operators).
|
|
221
|
+
|
|
222
|
+
</FAQ >
|
|
223
|
+
|
|
224
|
+
<hr />
|
|
225
|
+
|
|
226
|
+
## Acknowledgements
|
|
227
|
+
|
|
228
|
+
- The operator names **eq**, **ne**, **gt**, **lt**, **gte** and **lte** are inspired by [**Sequelize**](https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#operators).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type * as Preset from '@docusaurus/preset-classic';
|
|
2
|
+
import type { Config } from '@docusaurus/types';
|
|
3
|
+
import { themes as prismThemes } from 'prism-react-renderer';
|
|
4
|
+
import { getLocaleURL, navbarLocalePlugin } from './plugins/locale.js';
|
|
5
|
+
|
|
6
|
+
const config: Config = {
|
|
7
|
+
title: 'CL ORM',
|
|
8
|
+
url: 'https://wellwelwel.github.io/',
|
|
9
|
+
baseUrl: '/cl-orm/',
|
|
10
|
+
organizationName: 'wellwelwel',
|
|
11
|
+
projectName: 'cl-orm',
|
|
12
|
+
trailingSlash: false,
|
|
13
|
+
favicon: 'img/favicon.svg',
|
|
14
|
+
|
|
15
|
+
onBrokenLinks: 'throw',
|
|
16
|
+
onBrokenAnchors: 'throw',
|
|
17
|
+
markdown: {
|
|
18
|
+
hooks: {
|
|
19
|
+
onBrokenMarkdownLinks: 'throw',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
presets: [
|
|
24
|
+
[
|
|
25
|
+
'classic',
|
|
26
|
+
{
|
|
27
|
+
docs: {
|
|
28
|
+
sidebarPath: './sidebars.ts',
|
|
29
|
+
editUrl: 'https://github.com/wellwelwel/cl-orm/tree/main/website/',
|
|
30
|
+
},
|
|
31
|
+
theme: {
|
|
32
|
+
customCss: './src/css/custom.scss',
|
|
33
|
+
},
|
|
34
|
+
blog: false,
|
|
35
|
+
} satisfies Preset.Options,
|
|
36
|
+
],
|
|
37
|
+
],
|
|
38
|
+
|
|
39
|
+
themeConfig: {
|
|
40
|
+
// image: 'img/cl-orm-social-card.jpg',
|
|
41
|
+
navbar: {
|
|
42
|
+
// logo: {
|
|
43
|
+
// alt: 'CL ORM Logo',
|
|
44
|
+
// src: 'img/favicon.svg',
|
|
45
|
+
// },
|
|
46
|
+
items: [
|
|
47
|
+
{
|
|
48
|
+
to: getLocaleURL(),
|
|
49
|
+
label: 'CL ORM',
|
|
50
|
+
position: 'left',
|
|
51
|
+
className: 'navbar__brand navbar__manual--title text--truncate',
|
|
52
|
+
activeBaseRegex: `^/$`,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
to: '/docs/category/documentation',
|
|
56
|
+
label: 'Docs',
|
|
57
|
+
position: 'left',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
href: 'https://github.com/wellwelwel/cl-orm',
|
|
61
|
+
position: 'right',
|
|
62
|
+
className: 'header-github-link',
|
|
63
|
+
'aria-label': 'GitHub Repository',
|
|
64
|
+
},
|
|
65
|
+
{ type: 'search', position: 'right' },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
prism: {
|
|
69
|
+
theme: prismThemes.dracula,
|
|
70
|
+
darkTheme: prismThemes.dracula,
|
|
71
|
+
additionalLanguages: ['bash', 'sql'],
|
|
72
|
+
},
|
|
73
|
+
} satisfies Preset.ThemeConfig,
|
|
74
|
+
|
|
75
|
+
plugins: [
|
|
76
|
+
'docusaurus-plugin-sass',
|
|
77
|
+
'@easyops-cn/docusaurus-search-local',
|
|
78
|
+
navbarLocalePlugin,
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default config;
|