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.
Files changed (81) hide show
  1. package/.editorconfig +12 -0
  2. package/.gitattributes +1 -0
  3. package/.prettierignore +3 -0
  4. package/.prettierrc +34 -0
  5. package/.vscode/settings.json +14 -0
  6. package/README.md +105 -0
  7. package/mcr.config.ts +12 -0
  8. package/package.json +30 -0
  9. package/src/drivers/_utils.ts +31 -0
  10. package/src/drivers/d1.ts +70 -0
  11. package/src/drivers/do.ts +81 -0
  12. package/src/index.ts +13 -0
  13. package/src/queries/_utils.ts +10 -0
  14. package/src/queries/delete.ts +26 -0
  15. package/src/queries/insert.ts +22 -0
  16. package/src/queries/select.ts +64 -0
  17. package/src/queries/update.ts +28 -0
  18. package/src/queries/where/operators.ts +96 -0
  19. package/src/queries/where/where.ts +50 -0
  20. package/src/types.ts +76 -0
  21. package/test/__fixtures__/d1/worker.ts +70 -0
  22. package/test/__fixtures__/d1/wrangler.jsonc +13 -0
  23. package/test/__fixtures__/do/worker.ts +106 -0
  24. package/test/__fixtures__/do/wrangler.jsonc +20 -0
  25. package/test/e2e/d1.test.ts +113 -0
  26. package/test/e2e/do.test.ts +116 -0
  27. package/test/unit/buildDelete.test.ts +36 -0
  28. package/test/unit/buildInsert.test.ts +36 -0
  29. package/test/unit/buildSelect.test.ts +137 -0
  30. package/test/unit/buildUpdate.test.ts +34 -0
  31. package/test/unit/buildWhere.test.ts +249 -0
  32. package/test/unit/operators.test.ts +98 -0
  33. package/test/unit/prepare.test.ts +22 -0
  34. package/test/unit/quoteIdentifier.test.ts +12 -0
  35. package/test/unit/returnsRows.test.ts +41 -0
  36. package/test/unit/setMeta.test.ts +31 -0
  37. package/tsconfig.build.json +4 -0
  38. package/tsconfig.json +34 -0
  39. package/website/.prettierignore +4 -0
  40. package/website/.prettierrc +34 -0
  41. package/website/README.md +3 -0
  42. package/website/docs/documentation/connection.mdx +123 -0
  43. package/website/docs/documentation/queries/_category_.json +7 -0
  44. package/website/docs/documentation/queries/delete.mdx +51 -0
  45. package/website/docs/documentation/queries/insert.mdx +63 -0
  46. package/website/docs/documentation/queries/operators/_category_.json +7 -0
  47. package/website/docs/documentation/queries/operators/between.mdx +17 -0
  48. package/website/docs/documentation/queries/operators/eq.mdx +22 -0
  49. package/website/docs/documentation/queries/operators/gt.mdx +22 -0
  50. package/website/docs/documentation/queries/operators/gte.mdx +22 -0
  51. package/website/docs/documentation/queries/operators/in.mdx +28 -0
  52. package/website/docs/documentation/queries/operators/is-not-null.mdx +22 -0
  53. package/website/docs/documentation/queries/operators/is-null.mdx +22 -0
  54. package/website/docs/documentation/queries/operators/like.mdx +27 -0
  55. package/website/docs/documentation/queries/operators/lt.mdx +22 -0
  56. package/website/docs/documentation/queries/operators/lte.mdx +22 -0
  57. package/website/docs/documentation/queries/operators/ne.mdx +22 -0
  58. package/website/docs/documentation/queries/operators/not-between.mdx +17 -0
  59. package/website/docs/documentation/queries/operators/not-like.mdx +27 -0
  60. package/website/docs/documentation/queries/operators/notIn.mdx +28 -0
  61. package/website/docs/documentation/queries/select.mdx +294 -0
  62. package/website/docs/documentation/queries/update.mdx +61 -0
  63. package/website/docs/documentation/queries/where.mdx +176 -0
  64. package/website/docs/index.mdx +228 -0
  65. package/website/docusaurus.config.ts +82 -0
  66. package/website/package-lock.json +21348 -0
  67. package/website/package.json +59 -0
  68. package/website/plugins/locale.ts +16 -0
  69. package/website/sidebars.ts +18 -0
  70. package/website/src/components/FAQ.tsx +35 -0
  71. package/website/src/components/Loading.tsx +4 -0
  72. package/website/src/components/PageTitle.tsx +29 -0
  73. package/website/src/css/_faq.scss +39 -0
  74. package/website/src/css/_loading.scss +43 -0
  75. package/website/src/css/_mixins.scss +19 -0
  76. package/website/src/css/custom.scss +149 -0
  77. package/website/src/pages/index.tsx +17 -0
  78. package/website/static/.nojekyll +0 -0
  79. package/website/static/img/favicon.svg +1 -0
  80. package/website/test/unit/check-extensions.test.ts +48 -0
  81. package/website/tsconfig.json +14 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "printWidth": 80,
3
+ "tabWidth": 2,
4
+ "useTabs": false,
5
+ "semi": true,
6
+ "singleQuote": true,
7
+ "quoteProps": "as-needed",
8
+ "jsxSingleQuote": true,
9
+ "trailingComma": "es5",
10
+ "bracketSpacing": true,
11
+ "bracketSameLine": false,
12
+ "arrowParens": "always",
13
+ "proseWrap": "preserve",
14
+ "endOfLine": "auto",
15
+ "embeddedLanguageFormatting": "auto",
16
+ "singleAttributePerLine": false,
17
+ "plugins": ["@ianvs/prettier-plugin-sort-imports"],
18
+ "importOrder": [
19
+ "<TYPES>^(node:)",
20
+ "<TYPES>",
21
+ "<TYPES>^[.]",
22
+ "<BUILTIN_MODULES>",
23
+ "<THIRD_PARTY_MODULES>",
24
+ "^[.]"
25
+ ],
26
+ "overrides": [
27
+ {
28
+ "files": "*.jsonc",
29
+ "options": {
30
+ "trailingComma": "none"
31
+ }
32
+ }
33
+ ]
34
+ }
@@ -0,0 +1,3 @@
1
+ # Website
2
+
3
+ This [website](https://wellwelwel.github.io/cl-orm/docs) is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator.
@@ -0,0 +1,123 @@
1
+ ---
2
+ sidebar_position: 1
3
+ tags: [Connection, D1, Durable Objects]
4
+ ---
5
+
6
+ import TabItem from '@theme/TabItem';
7
+ import Tabs from '@theme/Tabs';
8
+
9
+ # Connection
10
+
11
+ **CL ORM** provides two driver functions to create a unified **Connection** interface.
12
+
13
+ ## D1
14
+
15
+ ```ts
16
+ import { useD1 } from 'cl-orm';
17
+
18
+ const db = useD1(env.DB);
19
+ ```
20
+
21
+ > `env.DB` is a `D1Database` binding from your Cloudflare Worker.
22
+
23
+ ## Durable Objects
24
+
25
+ ```ts
26
+ import { useDO } from 'cl-orm';
27
+
28
+ const db = useDO(ctx.storage.sql);
29
+ ```
30
+
31
+ > `ctx.storage.sql` is a `SqlStorage` from your Durable Object.
32
+
33
+ ---
34
+
35
+ ## Available Connection Methods
36
+
37
+ - [**insert**](/docs/documentation/queries/insert)
38
+ - [**select**](/docs/documentation/queries/select)
39
+ - [**update**](/docs/documentation/queries/update)
40
+ - [**delete**](/docs/documentation/queries/delete)
41
+ - **query** — execute raw SQL queries directly
42
+
43
+ ---
44
+
45
+ ## Raw Query
46
+
47
+ You can execute raw SQL queries using the `query` method:
48
+
49
+ <Tabs>
50
+ <TabItem value='D1' default>
51
+
52
+ ```ts
53
+ import { useD1 } from 'cl-orm';
54
+
55
+ const db = useD1(env.DB);
56
+
57
+ const { rows, meta } = await db.query<{ id: number; name: string }>(
58
+ 'SELECT * FROM users WHERE id = ?',
59
+ [1]
60
+ );
61
+
62
+ const user = rows[0] || null;
63
+ ```
64
+
65
+ </TabItem>
66
+ <TabItem value='Durable Objects'>
67
+
68
+ ```ts
69
+ import { useDO } from 'cl-orm';
70
+
71
+ const db = useDO(ctx.storage.sql);
72
+
73
+ const { rows, meta } = await db.query<{ id: number; name: string }>(
74
+ 'SELECT * FROM users WHERE id = ?',
75
+ [1]
76
+ );
77
+
78
+ const user = rows[0] || null;
79
+ ```
80
+
81
+ </TabItem>
82
+ </Tabs>
83
+
84
+ ---
85
+
86
+ ## Raw WHERE
87
+
88
+ You can use a raw string as the `where` clause in `select`, `update` and `delete`, passing the params manually:
89
+
90
+ <Tabs>
91
+ <TabItem value='D1' default>
92
+
93
+ ```ts
94
+ import { useD1 } from 'cl-orm';
95
+
96
+ const db = useD1(env.DB);
97
+
98
+ const user = await db.select<{ id: number; name: string }>({
99
+ table: 'users',
100
+ where: 'id = ?',
101
+ params: [1],
102
+ limit: 1,
103
+ });
104
+ ```
105
+
106
+ </TabItem>
107
+ <TabItem value='Durable Objects'>
108
+
109
+ ```ts
110
+ import { useDO } from 'cl-orm';
111
+
112
+ const db = useDO(ctx.storage.sql);
113
+
114
+ const user = await db.select<{ id: number; name: string }>({
115
+ table: 'users',
116
+ where: 'id = ?',
117
+ params: [1],
118
+ limit: 1,
119
+ });
120
+ ```
121
+
122
+ </TabItem>
123
+ </Tabs>
@@ -0,0 +1,7 @@
1
+ {
2
+ "label": "Queries",
3
+ "link": {
4
+ "type": "generated-index"
5
+ },
6
+ "position": 2
7
+ }
@@ -0,0 +1,51 @@
1
+ ---
2
+ sidebar_position: 4
3
+ ---
4
+
5
+ # DELETE
6
+
7
+ > For **WHERE** examples, please see the **WHERE** section.
8
+
9
+ ## Delete all rows
10
+
11
+ ```ts
12
+ // highlight-start
13
+ import { useD1 } from 'cl-orm';
14
+
15
+ const db = useD1(env.DB);
16
+ // highlight-end
17
+
18
+ await db.delete({
19
+ table: 'temp',
20
+ });
21
+ ```
22
+
23
+ > SQL Query
24
+
25
+ ```sql
26
+ DELETE FROM temp
27
+ ```
28
+
29
+ <hr />
30
+
31
+ ## Limit the rows to be deleted
32
+
33
+ ```ts
34
+ // highlight-start
35
+ import { useD1 } from 'cl-orm';
36
+
37
+ const db = useD1(env.DB);
38
+ // highlight-end
39
+
40
+ await db.delete({
41
+ table: 'test',
42
+ limit: 1,
43
+ });
44
+ ```
45
+
46
+ > SQL Query
47
+
48
+ ```sql
49
+ DELETE FROM test LIMIT ?
50
+ -- params: [1]
51
+ ```
@@ -0,0 +1,63 @@
1
+ ---
2
+ sidebar_position: 0
3
+ ---
4
+
5
+ # INSERT
6
+
7
+ ## Single insertion
8
+
9
+ ```ts
10
+ // highlight-start
11
+ import { useD1 } from 'cl-orm';
12
+
13
+ const db = useD1(env.DB);
14
+ // highlight-end
15
+
16
+ await db.insert({
17
+ table: 'test',
18
+ values: {
19
+ column1: 'foo',
20
+ column2: 1,
21
+ },
22
+ });
23
+ ```
24
+
25
+ > SQL Query
26
+
27
+ ```sql
28
+ INSERT INTO test (column1, column2) VALUES (?, ?)
29
+ -- params: ['foo', 1]
30
+ ```
31
+
32
+ <hr />
33
+
34
+ ## Multiple insertions
35
+
36
+ ```ts
37
+ // highlight-start
38
+ import { useD1 } from 'cl-orm';
39
+
40
+ const db = useD1(env.DB);
41
+ // highlight-end
42
+
43
+ await db.insert({
44
+ table: 'test',
45
+ values: [
46
+ {
47
+ column1: 'foo',
48
+ column2: 1,
49
+ },
50
+ {
51
+ column1: 'bar',
52
+ column2: 2,
53
+ },
54
+ ],
55
+ });
56
+ ```
57
+
58
+ > SQL Query
59
+
60
+ ```sql
61
+ INSERT INTO test (column1, column2) VALUES (?, ?), (?, ?)
62
+ -- params: ['foo', 1, 'bar', 2]
63
+ ```
@@ -0,0 +1,7 @@
1
+ {
2
+ "label": "Operators",
3
+ "link": {
4
+ "type": "generated-index"
5
+ },
6
+ "position": 6
7
+ }
@@ -0,0 +1,17 @@
1
+ ---
2
+ sidebar_position: 13
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # between
7
+
8
+ > between(column: string, params: [Param, Param])
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`createdAt` BETWEEN ? AND ?', params: ['2023-01-01', '2024-01-01'] }
15
+ */
16
+ OP.between('createdAt', ['2023-01-01', '2024-01-01']);
17
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 1
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # eq (equal)
7
+
8
+ > eq(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` = ?', params: [16] }
15
+ */
16
+ OP.eq('id', 16);
17
+
18
+ /**
19
+ * { condition: '`name` = ?', params: ['John'] }
20
+ */
21
+ OP.eq('name', 'John');
22
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 5
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # gt (greaterThan)
7
+
8
+ > gt(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` > ?', params: [16] }
15
+ */
16
+ OP.gt('id', 16);
17
+
18
+ /**
19
+ * { condition: '`createdAt` > ?', params: ['2024-01-01'] }
20
+ */
21
+ OP.gt('createdAt', '2024-01-01');
22
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 7
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # gte (greaterThanOrEqual)
7
+
8
+ > gte(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` >= ?', params: [16] }
15
+ */
16
+ OP.gte('id', 16);
17
+
18
+ /**
19
+ * { condition: '`createdAt` >= ?', params: ['2024-01-01'] }
20
+ */
21
+ OP.gte('createdAt', '2024-01-01');
22
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ sidebar_position: 11
3
+ tags: [OP, Operators, Sub Query, Sub Queries]
4
+ ---
5
+
6
+ # in
7
+
8
+ > in(column: string, params: Param[])
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: 'id IN (?, ?, ?)', params: [16, 20, 50] }
15
+ */
16
+ OP.in('id', [16, 20, 50]);
17
+ ```
18
+
19
+ > in(column: string, subquery: string, params: Param[])
20
+
21
+ ```ts
22
+ import { OP, Param } from 'cl-orm';
23
+
24
+ /**
25
+ * { condition: 'userId IN (SELECT id FROM users WHERE status IN (?, ?))', params: [0, 2] }
26
+ */
27
+ OP.in('userId', 'SELECT id FROM users WHERE status IN (?, ?)', [0, 2]);
28
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 10
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # isNotNull
7
+
8
+ > isNotNull(column: string)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`preferences` IS NOT NULL', params: [] }
15
+ */
16
+ OP.isNotNull('preferences');
17
+
18
+ /**
19
+ * { condition: '`updatedAt` IS NOT NULL', params: [] }
20
+ */
21
+ OP.isNotNull('updatedAt');
22
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 9
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # isNull
7
+
8
+ > isNull(column: string)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`preferences` IS NULL', params: [] }
15
+ */
16
+ OP.isNull('preferences');
17
+
18
+ /**
19
+ * { condition: '`updatedAt` IS NULL', params: [] }
20
+ */
21
+ OP.isNull('updatedAt');
22
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ sidebar_position: 3
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # like
7
+
8
+ > like(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`email` LIKE ?', params: ['%gmail.com'] }
15
+ */
16
+ OP.like('email', '%gmail.com');
17
+
18
+ /**
19
+ * { condition: '`email` LIKE ?', params: ['john@%'] }
20
+ */
21
+ OP.like('email', 'john@%');
22
+
23
+ /**
24
+ * { condition: '`email` LIKE ?', params: ['%gmail%'] }
25
+ */
26
+ OP.like('email', '%gmail%');
27
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 6
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # lt (lessThan)
7
+
8
+ > lt(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` < ?', params: [16] }
15
+ */
16
+ OP.lt('id', 16);
17
+
18
+ /**
19
+ * { condition: '`createdAt` < ?', params: ['2024-01-01'] }
20
+ */
21
+ OP.lt('createdAt', '2024-01-01');
22
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 8
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # lte (lessThanOrEqual)
7
+
8
+ > lte(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` <= ?', params: [16] }
15
+ */
16
+ OP.lte('id', 16);
17
+
18
+ /**
19
+ * { condition: '`createdAt` <= ?', params: ['2024-01-01'] }
20
+ */
21
+ OP.lte('createdAt', '2024-01-01');
22
+ ```
@@ -0,0 +1,22 @@
1
+ ---
2
+ sidebar_position: 2
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # ne (notEqual)
7
+
8
+ > ne(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`id` != ?', params: [16] }
15
+ */
16
+ OP.ne('id', 16);
17
+
18
+ /**
19
+ * { condition: '`name` != ?', params: ['John'] }
20
+ */
21
+ OP.ne('name', 'John');
22
+ ```
@@ -0,0 +1,17 @@
1
+ ---
2
+ sidebar_position: 14
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # notBetween
7
+
8
+ > notBetween(column: string, params: [Param, Param])
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`createdAt` NOT BETWEEN ? AND ?', params: ['2023-01-01', '2024-01-01'] }
15
+ */
16
+ OP.notBetween('createdAt', ['2023-01-01', '2024-01-01']);
17
+ ```
@@ -0,0 +1,27 @@
1
+ ---
2
+ sidebar_position: 4
3
+ tags: [OP, Operators]
4
+ ---
5
+
6
+ # notLike
7
+
8
+ > notLike(column: string, param: Param)
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: '`email` NOT LIKE ?', params: ['%gmail.com'] }
15
+ */
16
+ OP.notLike('email', '%gmail.com');
17
+
18
+ /**
19
+ * { condition: '`email` NOT LIKE ?', params: ['john@%'] }
20
+ */
21
+ OP.notLike('email', 'john@%');
22
+
23
+ /**
24
+ * { condition: '`email` NOT LIKE ?', params: ['%gmail%'] }
25
+ */
26
+ OP.notLike('email', '%gmail%');
27
+ ```
@@ -0,0 +1,28 @@
1
+ ---
2
+ sidebar_position: 12
3
+ tags: [OP, Operators, Sub Query, Sub Queries]
4
+ ---
5
+
6
+ # notIn
7
+
8
+ > notIn(column: string, params: Param[])
9
+
10
+ ```ts
11
+ import { OP, Param } from 'cl-orm';
12
+
13
+ /**
14
+ * { condition: 'id NOT IN (?, ?, ?)', params: [16, 20, 50] }
15
+ */
16
+ OP.notIn('id', [16, 20, 50]);
17
+ ```
18
+
19
+ > notIn(column: string, subquery: string, params: Param[])
20
+
21
+ ```ts
22
+ import { OP, Param } from 'cl-orm';
23
+
24
+ /**
25
+ * { condition: 'userId NOT IN (SELECT id FROM users WHERE status IN (?, ?))', params: [0, 2] }
26
+ */
27
+ OP.notIn('userId', 'SELECT id FROM users WHERE status IN (?, ?)', [0, 2]);
28
+ ```