@rx-ted/packages-honest-plugins 1.0.1
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/CHANGELOG.md +13 -0
- package/README.md +45 -0
- package/api-doc/.turbo/turbo-build.log +1 -0
- package/api-doc/.turbo/turbo-test.log +11 -0
- package/api-doc/.turbo/turbo-typecheck.log +1 -0
- package/api-doc/CHANGELOG.md +22 -0
- package/api-doc/README.md +80 -0
- package/api-doc/dist/api-doc.plugin.d.ts +53 -0
- package/api-doc/dist/api-doc.plugin.js +452 -0
- package/api-doc/dist/index.d.ts +5 -0
- package/api-doc/dist/index.js +3 -0
- package/api-doc/dist/interfaces/renderer.interface.d.ts +7 -0
- package/api-doc/dist/interfaces/renderer.interface.js +1 -0
- package/api-doc/dist/renderers/scalar.renderer.d.ts +10 -0
- package/api-doc/dist/renderers/scalar.renderer.js +76 -0
- package/api-doc/dist/renderers/swagger.renderer.d.ts +10 -0
- package/api-doc/dist/renderers/swagger.renderer.js +83 -0
- package/api-doc/node_modules/.bin/esbuild +22 -0
- package/api-doc/node_modules/.bin/jiti +22 -0
- package/api-doc/node_modules/.bin/sass +22 -0
- package/api-doc/node_modules/.bin/tsx +22 -0
- package/api-doc/node_modules/.bin/vite +22 -0
- package/api-doc/node_modules/.bin/vitest +22 -0
- package/api-doc/node_modules/.bin/yaml +22 -0
- package/api-doc/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/api-doc/package.json +48 -0
- package/api-doc/src/api-doc.plugin.ts +554 -0
- package/api-doc/src/index.ts +5 -0
- package/api-doc/src/interfaces/renderer.interface.ts +5 -0
- package/api-doc/src/plugin.test.ts +740 -0
- package/api-doc/src/renderers/scalar.renderer.ts +82 -0
- package/api-doc/src/renderers/swagger.renderer.ts +89 -0
- package/api-doc/tsconfig.json +21 -0
- package/api-doc/vitest.config.ts +13 -0
- package/cache/.turbo/turbo-build.log +1 -0
- package/cache/.turbo/turbo-test.log +16 -0
- package/cache/CHANGELOG.md +23 -0
- package/cache/README.md +79 -0
- package/cache/dist/cache-service.d.ts +8 -0
- package/cache/dist/cache-service.js +21 -0
- package/cache/dist/cacheable.d.ts +2 -0
- package/cache/dist/cacheable.js +10 -0
- package/cache/dist/cloudflare/driver.d.ts +23 -0
- package/cache/dist/cloudflare/driver.js +102 -0
- package/cache/dist/cloudflare/index.d.ts +3 -0
- package/cache/dist/cloudflare/index.js +2 -0
- package/cache/dist/cloudflare/plugin.d.ts +19 -0
- package/cache/dist/cloudflare/plugin.js +58 -0
- package/cache/dist/index.d.ts +11 -0
- package/cache/dist/index.js +14 -0
- package/cache/dist/local/driver.d.ts +2 -0
- package/cache/dist/local/driver.js +98 -0
- package/cache/dist/local/index.d.ts +2 -0
- package/cache/dist/local/index.js +2 -0
- package/cache/dist/local/plugin.d.ts +14 -0
- package/cache/dist/local/plugin.js +24 -0
- package/cache/dist/redis/driver.d.ts +10 -0
- package/cache/dist/redis/driver.js +102 -0
- package/cache/dist/redis/index.d.ts +4 -0
- package/cache/dist/redis/index.js +2 -0
- package/cache/dist/redis/plugin.d.ts +25 -0
- package/cache/dist/redis/plugin.js +61 -0
- package/cache/dist/resolve.d.ts +24 -0
- package/cache/dist/resolve.js +114 -0
- package/cache/dist/types.d.ts +18 -0
- package/cache/dist/types.js +1 -0
- package/cache/node_modules/.bin/esbuild +22 -0
- package/cache/node_modules/.bin/jiti +22 -0
- package/cache/node_modules/.bin/sass +22 -0
- package/cache/node_modules/.bin/tsx +22 -0
- package/cache/node_modules/.bin/vite +22 -0
- package/cache/node_modules/.bin/vitest +22 -0
- package/cache/node_modules/.bin/yaml +22 -0
- package/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/cache/package.json +46 -0
- package/cache/src/cache-service.test.ts +16 -0
- package/cache/src/cache-service.ts +15 -0
- package/cache/src/cacheable.test.ts +78 -0
- package/cache/src/cacheable.ts +16 -0
- package/cache/src/cloudflare/driver.test.ts +188 -0
- package/cache/src/cloudflare/driver.ts +118 -0
- package/cache/src/cloudflare/index.ts +3 -0
- package/cache/src/cloudflare/plugin.ts +71 -0
- package/cache/src/index.test.ts +68 -0
- package/cache/src/index.ts +20 -0
- package/cache/src/local/driver.ts +117 -0
- package/cache/src/local/index.ts +2 -0
- package/cache/src/local/plugin.ts +34 -0
- package/cache/src/redis/driver.test.ts +71 -0
- package/cache/src/redis/driver.ts +124 -0
- package/cache/src/redis/index.ts +4 -0
- package/cache/src/redis/plugin.ts +84 -0
- package/cache/src/resolve.test.ts +257 -0
- package/cache/src/resolve.ts +140 -0
- package/cache/src/types.ts +14 -0
- package/cache/tsconfig.json +21 -0
- package/cache/vitest.config.ts +13 -0
- package/db/.turbo/turbo-build.log +1 -0
- package/db/.turbo/turbo-test.log +21 -0
- package/db/CHANGELOG.md +26 -0
- package/db/README.md +99 -0
- package/db/dist/constants.d.ts +1 -0
- package/db/dist/constants.js +1 -0
- package/db/dist/d1/index.d.ts +3 -0
- package/db/dist/d1/index.js +2 -0
- package/db/dist/d1/plugin.d.ts +18 -0
- package/db/dist/d1/plugin.js +104 -0
- package/db/dist/db-service.d.ts +7 -0
- package/db/dist/db-service.js +21 -0
- package/db/dist/index.d.ts +15 -0
- package/db/dist/index.js +20 -0
- package/db/dist/mysql/client.d.ts +36 -0
- package/db/dist/mysql/client.js +84 -0
- package/db/dist/mysql/driver.d.ts +18 -0
- package/db/dist/mysql/driver.js +107 -0
- package/db/dist/mysql/index.d.ts +11 -0
- package/db/dist/mysql/index.js +11 -0
- package/db/dist/mysql/plugin.d.ts +51 -0
- package/db/dist/mysql/plugin.js +94 -0
- package/db/dist/mysql/types.d.ts +38 -0
- package/db/dist/mysql/types.js +1 -0
- package/db/dist/postgres/index.d.ts +2 -0
- package/db/dist/postgres/index.js +3 -0
- package/db/dist/repository.d.ts +14 -0
- package/db/dist/repository.js +79 -0
- package/db/dist/resolve.d.ts +6 -0
- package/db/dist/resolve.js +81 -0
- package/db/dist/schema-builder/column-builder.d.ts +26 -0
- package/db/dist/schema-builder/column-builder.js +53 -0
- package/db/dist/schema-builder/compile-d1.d.ts +5 -0
- package/db/dist/schema-builder/compile-d1.js +67 -0
- package/db/dist/schema-builder/compile-mysql.d.ts +12 -0
- package/db/dist/schema-builder/compile-mysql.js +78 -0
- package/db/dist/schema-builder/index.d.ts +8 -0
- package/db/dist/schema-builder/index.js +22 -0
- package/db/dist/schema-builder/table-builder.d.ts +16 -0
- package/db/dist/schema-builder/table-builder.js +38 -0
- package/db/dist/schema-builder/types.d.ts +26 -0
- package/db/dist/schema-builder/types.js +1 -0
- package/db/dist/schema-builder/zod-bridge.d.ts +24 -0
- package/db/dist/schema-builder/zod-bridge.js +53 -0
- package/db/dist/sqlite/index.d.ts +4 -0
- package/db/dist/sqlite/index.js +2 -0
- package/db/dist/sqlite/plugin.d.ts +17 -0
- package/db/dist/sqlite/plugin.js +33 -0
- package/db/dist/types.d.ts +42 -0
- package/db/dist/types.js +1 -0
- package/db/node_modules/.bin/esbuild +22 -0
- package/db/node_modules/.bin/jiti +22 -0
- package/db/node_modules/.bin/sass +22 -0
- package/db/node_modules/.bin/tsx +22 -0
- package/db/node_modules/.bin/vite +22 -0
- package/db/node_modules/.bin/vitest +22 -0
- package/db/node_modules/.bin/yaml +22 -0
- package/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/db/package.json +59 -0
- package/db/src/constants.test.ts +8 -0
- package/db/src/constants.ts +1 -0
- package/db/src/d1/index.ts +13 -0
- package/db/src/d1/plugin.ts +135 -0
- package/db/src/db-service.ts +14 -0
- package/db/src/index.test.ts +63 -0
- package/db/src/index.ts +57 -0
- package/db/src/mysql/client.ts +112 -0
- package/db/src/mysql/driver.test.ts +190 -0
- package/db/src/mysql/driver.ts +116 -0
- package/db/src/mysql/index.ts +51 -0
- package/db/src/mysql/plugin.test.ts +228 -0
- package/db/src/mysql/plugin.ts +128 -0
- package/db/src/mysql/types.ts +32 -0
- package/db/src/postgres/index.ts +15 -0
- package/db/src/repository.test.ts +195 -0
- package/db/src/repository.ts +95 -0
- package/db/src/resolve.ts +105 -0
- package/db/src/schema-builder/column-builder.test.ts +55 -0
- package/db/src/schema-builder/column-builder.ts +87 -0
- package/db/src/schema-builder/compile-d1.test.ts +60 -0
- package/db/src/schema-builder/compile-d1.ts +70 -0
- package/db/src/schema-builder/compile-mysql.test.ts +64 -0
- package/db/src/schema-builder/compile-mysql.ts +102 -0
- package/db/src/schema-builder/index.test.ts +36 -0
- package/db/src/schema-builder/index.ts +41 -0
- package/db/src/schema-builder/table-builder.test.ts +55 -0
- package/db/src/schema-builder/table-builder.ts +50 -0
- package/db/src/schema-builder/types.test.ts +68 -0
- package/db/src/schema-builder/types.ts +30 -0
- package/db/src/schema-builder/zod-bridge.ts +89 -0
- package/db/src/sqlite/index.ts +14 -0
- package/db/src/sqlite/plugin.ts +46 -0
- package/db/src/types.ts +45 -0
- package/db/tsconfig.json +21 -0
- package/db/vitest.config.ts +13 -0
- package/mail/.turbo/turbo-build.log +1 -0
- package/mail/.turbo/turbo-test.log +12 -0
- package/mail/.turbo/turbo-typecheck.log +1 -0
- package/mail/CHANGELOG.md +25 -0
- package/mail/README.md +214 -0
- package/mail/dist/index.d.ts +4 -0
- package/mail/dist/index.js +2 -0
- package/mail/dist/plugin.d.ts +64 -0
- package/mail/dist/plugin.js +232 -0
- package/mail/dist/providers/brevo.provider.d.ts +15 -0
- package/mail/dist/providers/brevo.provider.js +75 -0
- package/mail/dist/providers/custom.provider.d.ts +9 -0
- package/mail/dist/providers/custom.provider.js +22 -0
- package/mail/dist/providers/resend.provider.d.ts +16 -0
- package/mail/dist/providers/resend.provider.js +77 -0
- package/mail/dist/providers/smtp.provider.d.ts +21 -0
- package/mail/dist/providers/smtp.provider.js +86 -0
- package/mail/dist/rate-limiter.d.ts +16 -0
- package/mail/dist/rate-limiter.js +49 -0
- package/mail/dist/types.d.ts +68 -0
- package/mail/dist/types.js +6 -0
- package/mail/node_modules/.bin/esbuild +22 -0
- package/mail/node_modules/.bin/jiti +22 -0
- package/mail/node_modules/.bin/sass +22 -0
- package/mail/node_modules/.bin/tsx +22 -0
- package/mail/node_modules/.bin/vite +22 -0
- package/mail/node_modules/.bin/vitest +22 -0
- package/mail/node_modules/.bin/yaml +22 -0
- package/mail/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/mail/package.json +52 -0
- package/mail/src/index.ts +4 -0
- package/mail/src/plugin.test.ts +219 -0
- package/mail/src/plugin.ts +313 -0
- package/mail/src/providers/brevo.provider.ts +78 -0
- package/mail/src/providers/custom.provider.ts +29 -0
- package/mail/src/providers/resend.provider.ts +74 -0
- package/mail/src/providers/smtp.provider.ts +85 -0
- package/mail/src/rate-limiter.test.ts +81 -0
- package/mail/src/rate-limiter.ts +54 -0
- package/mail/src/types.ts +81 -0
- package/mail/tsconfig.json +21 -0
- package/mail/vitest.config.ts +13 -0
- package/package.json +36 -0
- package/s3/.turbo/turbo-build.log +1 -0
- package/s3/.turbo/turbo-test.log +11 -0
- package/s3/CHANGELOG.md +20 -0
- package/s3/README.md +90 -0
- package/s3/dist/index.d.ts +6 -0
- package/s3/dist/index.js +4 -0
- package/s3/dist/s3-service.d.ts +7 -0
- package/s3/dist/s3-service.js +21 -0
- package/s3/dist/s3.driver.d.ts +6 -0
- package/s3/dist/s3.driver.js +221 -0
- package/s3/dist/s3.plugin.d.ts +24 -0
- package/s3/dist/s3.plugin.js +58 -0
- package/s3/dist/types.d.ts +30 -0
- package/s3/dist/types.js +1 -0
- package/s3/node_modules/.bin/esbuild +22 -0
- package/s3/node_modules/.bin/jiti +22 -0
- package/s3/node_modules/.bin/sass +22 -0
- package/s3/node_modules/.bin/tsx +22 -0
- package/s3/node_modules/.bin/vite +22 -0
- package/s3/node_modules/.bin/vitest +22 -0
- package/s3/node_modules/.bin/yaml +22 -0
- package/s3/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/s3/package.json +47 -0
- package/s3/src/index.test.ts +20 -0
- package/s3/src/index.ts +13 -0
- package/s3/src/s3-service.ts +14 -0
- package/s3/src/s3.driver.ts +259 -0
- package/s3/src/s3.plugin.ts +80 -0
- package/s3/src/types.ts +37 -0
- package/s3/tsconfig.json +21 -0
- package/s3/vitest.config.ts +13 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { BaseRepository } from './repository';
|
|
3
|
+
import type { Table } from 'drizzle-orm';
|
|
4
|
+
|
|
5
|
+
function createMockDb() {
|
|
6
|
+
const results: any[] = [];
|
|
7
|
+
|
|
8
|
+
const qb: any = {
|
|
9
|
+
from: vi.fn().mockReturnThis(),
|
|
10
|
+
where: vi.fn().mockReturnThis(),
|
|
11
|
+
limit: vi.fn().mockReturnThis(),
|
|
12
|
+
offset: vi.fn().mockReturnThis(),
|
|
13
|
+
orderBy: vi.fn().mockReturnThis(),
|
|
14
|
+
};
|
|
15
|
+
qb.then = (resolve: (v: any) => void) => {
|
|
16
|
+
const val = results.shift() ?? [];
|
|
17
|
+
resolve(val);
|
|
18
|
+
return Promise.resolve(val);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const db = {
|
|
22
|
+
select: vi.fn().mockReturnValue(qb),
|
|
23
|
+
insert: vi.fn().mockReturnValue({
|
|
24
|
+
values: vi.fn().mockResolvedValue([{ insertId: 1 }]),
|
|
25
|
+
}),
|
|
26
|
+
update: vi.fn().mockReturnValue({
|
|
27
|
+
set: vi.fn().mockReturnValue({
|
|
28
|
+
where: vi.fn().mockResolvedValue([{ affectedRows: 1 }]),
|
|
29
|
+
}),
|
|
30
|
+
}),
|
|
31
|
+
delete: vi.fn().mockReturnValue({
|
|
32
|
+
where: vi.fn().mockResolvedValue({ affectedRows: 1 }),
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
db,
|
|
38
|
+
qb,
|
|
39
|
+
addResult: (val: any) => {
|
|
40
|
+
results.push(val);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const mockTable = { _: { name: 'users' } } as unknown as Table;
|
|
46
|
+
|
|
47
|
+
describe('BaseRepository', () => {
|
|
48
|
+
let repo: BaseRepository<typeof mockTable>;
|
|
49
|
+
let db: ReturnType<typeof createMockDb>['db'];
|
|
50
|
+
let qb: ReturnType<typeof createMockDb>['qb'];
|
|
51
|
+
let addResult: ReturnType<typeof createMockDb>['addResult'];
|
|
52
|
+
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
const mocks = createMockDb();
|
|
55
|
+
db = mocks.db;
|
|
56
|
+
qb = mocks.qb;
|
|
57
|
+
addResult = mocks.addResult;
|
|
58
|
+
repo = new BaseRepository(mocks.db, mockTable);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('findById', () => {
|
|
62
|
+
it('returns the row when found', async () => {
|
|
63
|
+
addResult([{ id: '1', name: 'Alice' }]);
|
|
64
|
+
|
|
65
|
+
const result = await repo.findById('1');
|
|
66
|
+
|
|
67
|
+
expect(result).toEqual({ id: '1', name: 'Alice' });
|
|
68
|
+
expect(db.select).toHaveBeenCalled();
|
|
69
|
+
expect(qb.from).toHaveBeenCalledWith(mockTable);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('returns null when not found', async () => {
|
|
73
|
+
addResult([]);
|
|
74
|
+
|
|
75
|
+
const result = await repo.findById('1');
|
|
76
|
+
|
|
77
|
+
expect(result).toBeNull();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('findMany', () => {
|
|
82
|
+
it('returns all rows without options', async () => {
|
|
83
|
+
addResult([{ id: '1' }, { id: '2' }]);
|
|
84
|
+
|
|
85
|
+
const result = await repo.findMany();
|
|
86
|
+
|
|
87
|
+
expect(result).toEqual([{ id: '1' }, { id: '2' }]);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('filters with where clause', async () => {
|
|
91
|
+
addResult([{ id: '1', role: 'admin' }]);
|
|
92
|
+
|
|
93
|
+
const result = await repo.findMany({ where: { role: 'admin' } });
|
|
94
|
+
|
|
95
|
+
expect(result).toHaveLength(1);
|
|
96
|
+
expect(qb.where).toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('applies ordering', async () => {
|
|
100
|
+
addResult([{ id: '2' }, { id: '1' }]);
|
|
101
|
+
|
|
102
|
+
await repo.findMany({ orderBy: { createdAt: 'desc' } });
|
|
103
|
+
|
|
104
|
+
expect(qb.orderBy).toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('applies pagination', async () => {
|
|
108
|
+
addResult([{ id: '1' }]);
|
|
109
|
+
|
|
110
|
+
await repo.findMany({ pagination: { page: 2, pageSize: 10 } });
|
|
111
|
+
|
|
112
|
+
expect(qb.limit).toHaveBeenCalledWith(10);
|
|
113
|
+
expect(qb.offset).toHaveBeenCalledWith(10);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('create', () => {
|
|
118
|
+
it('inserts data and returns result', async () => {
|
|
119
|
+
const result = await repo.create({ name: 'Bob' });
|
|
120
|
+
|
|
121
|
+
expect(result).toEqual({ insertId: 1, affectedRows: 0 });
|
|
122
|
+
expect(db.insert().values).toHaveBeenCalledWith({ name: 'Bob' });
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('update', () => {
|
|
127
|
+
it('updates and returns result', async () => {
|
|
128
|
+
const result = await repo.update('1', { name: 'Bob' });
|
|
129
|
+
|
|
130
|
+
expect(result).toEqual({ affectedRows: 1 });
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('delete', () => {
|
|
135
|
+
it('returns true when rows affected', async () => {
|
|
136
|
+
const result = await repo.delete('1');
|
|
137
|
+
|
|
138
|
+
expect(result).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('returns false when no rows affected', async () => {
|
|
142
|
+
(db.delete().where as any).mockResolvedValue({ affectedRows: 0 });
|
|
143
|
+
|
|
144
|
+
const result = await repo.delete('1');
|
|
145
|
+
|
|
146
|
+
expect(result).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('count', () => {
|
|
151
|
+
it('returns count without where', async () => {
|
|
152
|
+
addResult([{ count: 5 }]);
|
|
153
|
+
|
|
154
|
+
const result = await repo.count();
|
|
155
|
+
|
|
156
|
+
expect(result).toBe(5);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('returns 0 when no rows', async () => {
|
|
160
|
+
addResult([{ count: null }]);
|
|
161
|
+
|
|
162
|
+
const result = await repo.count();
|
|
163
|
+
|
|
164
|
+
expect(result).toBe(0);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('filters with where clause', async () => {
|
|
168
|
+
addResult([{ count: 3 }]);
|
|
169
|
+
|
|
170
|
+
const result = await repo.count({ role: 'admin' });
|
|
171
|
+
|
|
172
|
+
expect(result).toBe(3);
|
|
173
|
+
expect(qb.where).toHaveBeenCalled();
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('findWithPagination', () => {
|
|
178
|
+
it('returns paginated result with defaults', async () => {
|
|
179
|
+
addResult([{ id: '1' }, { id: '2' }]); // findMany
|
|
180
|
+
addResult([{ count: 20 }]); // count
|
|
181
|
+
|
|
182
|
+
const result = await repo.findWithPagination({
|
|
183
|
+
pagination: { page: 1, pageSize: 2 },
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
expect(result).toEqual({
|
|
187
|
+
data: [{ id: '1' }, { id: '2' }],
|
|
188
|
+
total: 20,
|
|
189
|
+
page: 1,
|
|
190
|
+
pageSize: 2,
|
|
191
|
+
totalPages: 10,
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type Table, eq, and } from 'drizzle-orm';
|
|
2
|
+
import { sql } from 'drizzle-orm';
|
|
3
|
+
import type { QueryOptions, PaginationResult } from './types';
|
|
4
|
+
|
|
5
|
+
export class BaseRepository<TTable extends Table> {
|
|
6
|
+
protected db: any;
|
|
7
|
+
protected table: TTable;
|
|
8
|
+
|
|
9
|
+
constructor(db: any, table: TTable) {
|
|
10
|
+
this.db = db;
|
|
11
|
+
this.table = table;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async findById(id: string): Promise<any | null> {
|
|
15
|
+
const [result] = await this.db
|
|
16
|
+
.select()
|
|
17
|
+
.from(this.table)
|
|
18
|
+
.where(eq((this.table as any).id, id))
|
|
19
|
+
.limit(1);
|
|
20
|
+
return result ?? null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async findMany(options?: QueryOptions): Promise<any[]> {
|
|
24
|
+
let query = this.db.select().from(this.table);
|
|
25
|
+
if (options?.where) {
|
|
26
|
+
const conditions = Object.entries(options.where).map(([key, value]) =>
|
|
27
|
+
eq((this.table as any)[key], value),
|
|
28
|
+
);
|
|
29
|
+
query = query.where(and(...conditions));
|
|
30
|
+
}
|
|
31
|
+
if (options?.orderBy) {
|
|
32
|
+
for (const [key, dir] of Object.entries(options.orderBy)) {
|
|
33
|
+
query = query.orderBy(
|
|
34
|
+
dir === 'desc'
|
|
35
|
+
? sql`${(this.table as any)[key]} desc`
|
|
36
|
+
: sql`${(this.table as any)[key]} asc`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (options?.pagination) {
|
|
41
|
+
const { page, pageSize } = options.pagination;
|
|
42
|
+
query = query.limit(pageSize).offset((page - 1) * pageSize);
|
|
43
|
+
}
|
|
44
|
+
return query;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async findWithPagination(options?: QueryOptions): Promise<PaginationResult<any>> {
|
|
48
|
+
const page = options?.pagination?.page ?? 1;
|
|
49
|
+
const pageSize = options?.pagination?.pageSize ?? 10;
|
|
50
|
+
const data = await this.findMany(options);
|
|
51
|
+
const total = await this.count(options?.where);
|
|
52
|
+
return {
|
|
53
|
+
data,
|
|
54
|
+
total,
|
|
55
|
+
page,
|
|
56
|
+
pageSize,
|
|
57
|
+
totalPages: Math.ceil(total / pageSize),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async create(data: any): Promise<any> {
|
|
62
|
+
const raw: any = await this.db.insert(this.table).values(data);
|
|
63
|
+
const r = Array.isArray(raw) ? raw[0] : raw;
|
|
64
|
+
return {
|
|
65
|
+
insertId: Number(r.insertId ?? r.lastInsertRowid ?? r.meta?.last_row_id),
|
|
66
|
+
affectedRows: Number(r.affectedRows ?? r.rowsAffected ?? r.meta?.changes ?? 0),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async update(id: string, data: any): Promise<any | null> {
|
|
71
|
+
const raw: any = await this.db
|
|
72
|
+
.update(this.table)
|
|
73
|
+
.set(data)
|
|
74
|
+
.where(eq((this.table as any).id, id));
|
|
75
|
+
const r = Array.isArray(raw) ? raw[0] : raw;
|
|
76
|
+
return r ?? null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async delete(id: string): Promise<boolean> {
|
|
80
|
+
const result = await this.db.delete(this.table).where(eq((this.table as any).id, id));
|
|
81
|
+
return result.affectedRows > 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async count(where?: Record<string, any>): Promise<number> {
|
|
85
|
+
let query = this.db.select({ count: sql<number>`count(*)` }).from(this.table);
|
|
86
|
+
if (where) {
|
|
87
|
+
const conditions = Object.entries(where).map(([key, value]) =>
|
|
88
|
+
eq((this.table as any)[key], value),
|
|
89
|
+
);
|
|
90
|
+
query = query.where(and(...conditions));
|
|
91
|
+
}
|
|
92
|
+
const [result] = await query;
|
|
93
|
+
return Number(result?.count ?? 0);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ENV_SYMBOL, Env } from '@rx-ted/packages-core';
|
|
2
|
+
import { ComponentManager } from '@rx-ted/packages-honest';
|
|
3
|
+
import type { IPlugin } from '@rx-ted/packages-honest';
|
|
4
|
+
|
|
5
|
+
export type AppRuntime = 'node' | 'bun' | 'deno' | 'cloudflare' | 'vercel-edge';
|
|
6
|
+
export type DbType = 'd1' | 'sqlite' | 'mysql';
|
|
7
|
+
|
|
8
|
+
const RUNTIME_DB_MAP: Record<AppRuntime, DbType[]> = {
|
|
9
|
+
cloudflare: ['d1'],
|
|
10
|
+
node: ['sqlite', 'mysql'],
|
|
11
|
+
bun: ['sqlite', 'mysql'],
|
|
12
|
+
deno: ['sqlite', 'mysql'],
|
|
13
|
+
'vercel-edge': [],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const PLUGIN_DB_TYPE: Record<string, DbType> = {
|
|
17
|
+
D1Plugin: 'd1',
|
|
18
|
+
SqlitePlugin: 'sqlite',
|
|
19
|
+
MysqlPlugin: 'mysql',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function getAppEnv(): Env {
|
|
23
|
+
if (ComponentManager.hasPlugin(ENV_SYMBOL)) {
|
|
24
|
+
return ComponentManager.getPlugin<Env>(ENV_SYMBOL);
|
|
25
|
+
}
|
|
26
|
+
return new Env(process.env, {});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function assertRuntimeSupport(runtime: AppRuntime, dbType: DbType): void {
|
|
30
|
+
if (!(runtime in RUNTIME_DB_MAP)) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`[db] Unsupported runtime "${runtime}". ` +
|
|
33
|
+
`Supported: ${Object.keys(RUNTIME_DB_MAP).join(', ')}. ` +
|
|
34
|
+
`Contact the developer to add support for this runtime.`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const allowed = RUNTIME_DB_MAP[runtime];
|
|
38
|
+
if (!allowed.includes(dbType)) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`[db] Database "${dbType}" is not supported on runtime "${runtime}". ` +
|
|
41
|
+
`Allowed databases for "${runtime}": ${allowed.join(', ')}. ` +
|
|
42
|
+
`Change the DB env var or switch to a different runtime.`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function dbTypeFromPlugin(plugin: IPlugin): DbType {
|
|
48
|
+
const name = plugin.constructor?.name;
|
|
49
|
+
const dbType = name ? PLUGIN_DB_TYPE[name] : undefined;
|
|
50
|
+
if (!dbType) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`[db] Unknown plugin "${name}". ` +
|
|
53
|
+
`Supported plugins: ${Object.keys(PLUGIN_DB_TYPE).join(', ')}.`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return dbType;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function DBPlugin(schema: Record<string, any>): Promise<IPlugin>;
|
|
60
|
+
export async function DBPlugin(plugin: IPlugin): Promise<IPlugin>;
|
|
61
|
+
export async function DBPlugin(arg: any): Promise<IPlugin> {
|
|
62
|
+
const appEnv = getAppEnv();
|
|
63
|
+
|
|
64
|
+
// Explicit mode: user passed a pre-created plugin
|
|
65
|
+
if (arg && typeof arg === 'object' && 'name' in arg && 'version' in arg) {
|
|
66
|
+
const dbType = dbTypeFromPlugin(arg as IPlugin);
|
|
67
|
+
assertRuntimeSupport(appEnv.platform as AppRuntime, dbType);
|
|
68
|
+
return arg as IPlugin;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Auto-detect mode: arg is schema
|
|
72
|
+
const runtime = appEnv.platform as AppRuntime;
|
|
73
|
+
const dbRaw = appEnv.get('DB');
|
|
74
|
+
const db: DbType =
|
|
75
|
+
(typeof dbRaw === 'string' ? (dbRaw as DbType) : undefined) ??
|
|
76
|
+
RUNTIME_DB_MAP[runtime]?.[0] ??
|
|
77
|
+
'sqlite';
|
|
78
|
+
assertRuntimeSupport(runtime, db);
|
|
79
|
+
|
|
80
|
+
if (db === 'd1') {
|
|
81
|
+
const { D1Plugin } = await import('./d1/plugin');
|
|
82
|
+
return new D1Plugin({ schema: arg });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (db === 'sqlite') {
|
|
86
|
+
const { SqlitePlugin } = await import('./sqlite/plugin');
|
|
87
|
+
return new SqlitePlugin({
|
|
88
|
+
dbPath: appEnv.var('DB_PATH', 'data/app.db'),
|
|
89
|
+
schema: arg,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const { MysqlPlugin } = await import('./mysql/plugin');
|
|
94
|
+
return new MysqlPlugin({
|
|
95
|
+
connection: {
|
|
96
|
+
host: appEnv.get('DB_HOST', 'string'),
|
|
97
|
+
port: appEnv.get('DB_PORT', 'number'),
|
|
98
|
+
user: appEnv.get('DB_USER', 'string'),
|
|
99
|
+
password: appEnv.get('DB_PASSWORD') ?? '',
|
|
100
|
+
database: appEnv.get('DB_DATABASE', 'string'),
|
|
101
|
+
},
|
|
102
|
+
schema: arg,
|
|
103
|
+
logger: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ColumnBuilder } from './column-builder';
|
|
3
|
+
|
|
4
|
+
describe('ColumnBuilder', () => {
|
|
5
|
+
it('builds varchar definition', () => {
|
|
6
|
+
const col = new ColumnBuilder('varchar', { length: 255 });
|
|
7
|
+
const def = col.build('email');
|
|
8
|
+
expect(def).toMatchObject({ type: 'varchar', name: 'email', length: 255 });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('supports chainable modifiers', () => {
|
|
12
|
+
const def = new ColumnBuilder('bigint')
|
|
13
|
+
.primaryKey()
|
|
14
|
+
.autoIncrement()
|
|
15
|
+
.notNull()
|
|
16
|
+
.unique()
|
|
17
|
+
.build('id');
|
|
18
|
+
expect(def.primaryKey).toBe(true);
|
|
19
|
+
expect(def.autoIncrement).toBe(true);
|
|
20
|
+
expect(def.notNull).toBe(true);
|
|
21
|
+
expect(def.unique).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('supports default value', () => {
|
|
25
|
+
const def = new ColumnBuilder('varchar', { length: 20 }).default('user').build('role');
|
|
26
|
+
expect(def.default).toBe('user');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('supports enum values', () => {
|
|
30
|
+
const def = new ColumnBuilder('enum', { values: ['admin', 'user'] }).build('role');
|
|
31
|
+
expect(def.values).toEqual(['admin', 'user']);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('supports references', () => {
|
|
35
|
+
const target = new ColumnBuilder('char', { length: 36 });
|
|
36
|
+
target.__tableName = 'users';
|
|
37
|
+
target.__columnName = 'id';
|
|
38
|
+
const def = new ColumnBuilder('char', { length: 36 })
|
|
39
|
+
.references(() => target, { onDelete: 'cascade' })
|
|
40
|
+
.build('user_id');
|
|
41
|
+
expect(def.references).toEqual({ table: 'users', column: 'id', onDelete: 'cascade' });
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('supports all portable types', () => {
|
|
45
|
+
expect(new ColumnBuilder('text').build('a').type).toBe('text');
|
|
46
|
+
expect(new ColumnBuilder('boolean').build('a').type).toBe('boolean');
|
|
47
|
+
expect(new ColumnBuilder('timestamp').build('a').type).toBe('timestamp');
|
|
48
|
+
expect(new ColumnBuilder('date').build('a').type).toBe('date');
|
|
49
|
+
expect(new ColumnBuilder('json').build('a').type).toBe('json');
|
|
50
|
+
expect(new ColumnBuilder('decimal', { precision: 10, scale: 2 }).build('a').type).toBe(
|
|
51
|
+
'decimal',
|
|
52
|
+
);
|
|
53
|
+
expect(new ColumnBuilder('integer').build('a').type).toBe('integer');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ColumnDefinition, ReferenceDef } from './types';
|
|
2
|
+
|
|
3
|
+
type ColumnType =
|
|
4
|
+
| 'varchar'
|
|
5
|
+
| 'char'
|
|
6
|
+
| 'text'
|
|
7
|
+
| 'bigint'
|
|
8
|
+
| 'integer'
|
|
9
|
+
| 'boolean'
|
|
10
|
+
| 'timestamp'
|
|
11
|
+
| 'date'
|
|
12
|
+
| 'enum'
|
|
13
|
+
| 'json'
|
|
14
|
+
| 'decimal';
|
|
15
|
+
|
|
16
|
+
interface ColumnOpts {
|
|
17
|
+
length?: number;
|
|
18
|
+
values?: string[];
|
|
19
|
+
precision?: number;
|
|
20
|
+
scale?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ColumnBuilder {
|
|
24
|
+
private def: {
|
|
25
|
+
type: ColumnType;
|
|
26
|
+
primaryKey?: boolean;
|
|
27
|
+
autoIncrement?: boolean;
|
|
28
|
+
notNull?: boolean;
|
|
29
|
+
unique?: boolean;
|
|
30
|
+
default?: unknown;
|
|
31
|
+
length?: number;
|
|
32
|
+
values?: string[];
|
|
33
|
+
precision?: number;
|
|
34
|
+
scale?: number;
|
|
35
|
+
references?: ReferenceDef;
|
|
36
|
+
};
|
|
37
|
+
private customDbName?: string;
|
|
38
|
+
__tableName?: string;
|
|
39
|
+
__columnName?: string;
|
|
40
|
+
|
|
41
|
+
constructor(type: ColumnType, opts?: ColumnOpts) {
|
|
42
|
+
this.def = { type };
|
|
43
|
+
if (opts?.length !== undefined) this.def.length = opts.length;
|
|
44
|
+
if (opts?.values !== undefined) this.def.values = opts.values;
|
|
45
|
+
if (opts?.precision !== undefined) this.def.precision = opts.precision;
|
|
46
|
+
if (opts?.scale !== undefined) this.def.scale = opts.scale;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
dbName(name: string): this {
|
|
50
|
+
this.customDbName = name;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
primaryKey(): this {
|
|
54
|
+
this.def.primaryKey = true;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
autoIncrement(): this {
|
|
58
|
+
this.def.autoIncrement = true;
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
notNull(): this {
|
|
62
|
+
this.def.notNull = true;
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
unique(): this {
|
|
66
|
+
this.def.unique = true;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
default(value: unknown): this {
|
|
70
|
+
this.def.default = value;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
references(fn: () => ColumnBuilder, opts?: { onDelete?: ReferenceDef['onDelete'] }): this {
|
|
75
|
+
const target = fn();
|
|
76
|
+
const tbl = target.__tableName ?? (target as any).table?.[Symbol.for('drizzle:Name')];
|
|
77
|
+
const col = target.__columnName ?? (target as any).name;
|
|
78
|
+
if (!tbl || !col)
|
|
79
|
+
throw new Error('references() target not fully initialized (missing table/column name)');
|
|
80
|
+
this.def.references = { table: tbl, column: col, onDelete: opts?.onDelete };
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
build(name: string): ColumnDefinition {
|
|
85
|
+
return { name: this.customDbName ?? name, ...this.def } as ColumnDefinition;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { compileD1 } from './compile-d1';
|
|
3
|
+
import type { SchemaDefinition } from './types';
|
|
4
|
+
|
|
5
|
+
const schema: SchemaDefinition = {
|
|
6
|
+
users: {
|
|
7
|
+
name: 'users',
|
|
8
|
+
columns: {
|
|
9
|
+
id: { type: 'char', name: 'id', length: 36, primaryKey: true },
|
|
10
|
+
email: { type: 'varchar', name: 'email', length: 255, unique: true, notNull: true },
|
|
11
|
+
name: { type: 'varchar', name: 'name', length: 100 },
|
|
12
|
+
role: { type: 'enum', name: 'role', values: ['admin', 'user'], default: 'user' },
|
|
13
|
+
age: { type: 'integer', name: 'age' },
|
|
14
|
+
active: { type: 'boolean', name: 'active', default: true },
|
|
15
|
+
createdAt: { type: 'timestamp', name: 'created_at', notNull: true },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe('compileD1', () => {
|
|
21
|
+
it('returns compiled table objects', () => {
|
|
22
|
+
const result = compileD1(schema);
|
|
23
|
+
expect(result.users).toBeDefined();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('compiled table has column accessors', () => {
|
|
27
|
+
const result = compileD1(schema);
|
|
28
|
+
expect(typeof (result.users as any).id).toBe('object');
|
|
29
|
+
expect(typeof (result.users as any).email).toBe('object');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('boolean mapped to integer mode boolean', () => {
|
|
33
|
+
const result = compileD1(schema);
|
|
34
|
+
expect((result.users as any).active).toBeDefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('handles references between tables', () => {
|
|
38
|
+
const s: SchemaDefinition = {
|
|
39
|
+
users: {
|
|
40
|
+
name: 'users',
|
|
41
|
+
columns: { id: { type: 'char', name: 'id', length: 36, primaryKey: true } },
|
|
42
|
+
},
|
|
43
|
+
posts: {
|
|
44
|
+
name: 'posts',
|
|
45
|
+
columns: {
|
|
46
|
+
id: { type: 'integer', name: 'id', primaryKey: true, autoIncrement: true },
|
|
47
|
+
authorId: {
|
|
48
|
+
type: 'char',
|
|
49
|
+
name: 'author_id',
|
|
50
|
+
length: 36,
|
|
51
|
+
notNull: true,
|
|
52
|
+
references: { table: 'users', column: 'id', onDelete: 'cascade' },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
const result = compileD1(s);
|
|
58
|
+
expect(result.posts).toBeDefined();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { sqliteTable, text, integer, real } from 'drizzle-orm/sqlite-core';
|
|
2
|
+
import type { SQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
3
|
+
import type { SchemaDefinition, ColumnDefinition } from './types';
|
|
4
|
+
|
|
5
|
+
export function compileD1<T extends SchemaDefinition>(schema: T): { [K in keyof T]: SQLiteTable } {
|
|
6
|
+
const compiled: Record<string, any> = {};
|
|
7
|
+
|
|
8
|
+
const dbNameToKey: Record<string, string> = {};
|
|
9
|
+
for (const key of Object.keys(schema)) {
|
|
10
|
+
dbNameToKey[schema[key].name] = key;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for (const tableName of Object.keys(schema)) {
|
|
14
|
+
const tableDef = schema[tableName];
|
|
15
|
+
const builders: Record<string, any> = {};
|
|
16
|
+
for (const [colName, colDef] of Object.entries(tableDef.columns)) {
|
|
17
|
+
let col = toD1Column(colDef.name, colDef);
|
|
18
|
+
if (colDef.references) {
|
|
19
|
+
const refKey = dbNameToKey[colDef.references.table] ?? colDef.references.table;
|
|
20
|
+
col = col.references(() => compiled[refKey]?.[colDef.references!.column], {
|
|
21
|
+
onDelete: colDef.references!.onDelete,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
builders[colName] = col;
|
|
25
|
+
}
|
|
26
|
+
compiled[tableName] = sqliteTable(tableDef.name, builders);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return compiled as { [K in keyof T]: SQLiteTable };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function toD1Column(name: string, def: ColumnDefinition): any {
|
|
33
|
+
let col: any;
|
|
34
|
+
switch (def.type) {
|
|
35
|
+
case 'varchar':
|
|
36
|
+
case 'char':
|
|
37
|
+
case 'text':
|
|
38
|
+
case 'enum':
|
|
39
|
+
col = text(name);
|
|
40
|
+
break;
|
|
41
|
+
case 'json':
|
|
42
|
+
col = text(name, { mode: 'json' });
|
|
43
|
+
break;
|
|
44
|
+
case 'bigint':
|
|
45
|
+
case 'integer':
|
|
46
|
+
col = integer(name);
|
|
47
|
+
break;
|
|
48
|
+
case 'boolean':
|
|
49
|
+
col = integer(name, { mode: 'boolean' });
|
|
50
|
+
break;
|
|
51
|
+
case 'timestamp':
|
|
52
|
+
case 'date':
|
|
53
|
+
col = integer(name, { mode: 'timestamp' });
|
|
54
|
+
break;
|
|
55
|
+
case 'decimal':
|
|
56
|
+
col = real(name);
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
col = text(name);
|
|
60
|
+
}
|
|
61
|
+
if (def.autoIncrement) {
|
|
62
|
+
col = col.primaryKey({ autoIncrement: true });
|
|
63
|
+
} else if (def.primaryKey) {
|
|
64
|
+
col = col.primaryKey();
|
|
65
|
+
}
|
|
66
|
+
if (def.notNull) col = col.notNull();
|
|
67
|
+
if (def.unique) col = col.unique();
|
|
68
|
+
if (def.default !== undefined) col = col.default(def.default);
|
|
69
|
+
return col;
|
|
70
|
+
}
|