@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,64 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getTableName } from 'drizzle-orm';
|
|
3
|
+
import { compileMysql } from './compile-mysql';
|
|
4
|
+
import type { SchemaDefinition } from './types';
|
|
5
|
+
|
|
6
|
+
const schema: SchemaDefinition = {
|
|
7
|
+
users: {
|
|
8
|
+
name: 'users',
|
|
9
|
+
columns: {
|
|
10
|
+
id: { type: 'char', name: 'id', length: 36, primaryKey: true },
|
|
11
|
+
email: { type: 'varchar', name: 'email', length: 255, unique: true, notNull: true },
|
|
12
|
+
name: { type: 'varchar', name: 'name', length: 100 },
|
|
13
|
+
role: { type: 'enum', name: 'role', values: ['admin', 'user'], default: 'user' },
|
|
14
|
+
age: { type: 'integer', name: 'age' },
|
|
15
|
+
meta: { type: 'json', name: 'meta' },
|
|
16
|
+
createdAt: { type: 'timestamp', name: 'created_at', notNull: true },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe('compileMysql', () => {
|
|
22
|
+
it('returns compiled table objects', () => {
|
|
23
|
+
const result = compileMysql(schema);
|
|
24
|
+
expect(result.users).toBeDefined();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('compiled table has column accessors', () => {
|
|
28
|
+
const result = compileMysql(schema);
|
|
29
|
+
const u = result.users as any;
|
|
30
|
+
expect(typeof u.id).toBe('object');
|
|
31
|
+
expect(typeof u.email).toBe('object');
|
|
32
|
+
expect(typeof u.role).toBe('object');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('compiled table name matches', () => {
|
|
36
|
+
const result = compileMysql(schema);
|
|
37
|
+
expect(getTableName(result.users)).toBe('users');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('handles schema with two tables and FK reference', () => {
|
|
41
|
+
const schemaWithFk: SchemaDefinition = {
|
|
42
|
+
users: {
|
|
43
|
+
name: 'users',
|
|
44
|
+
columns: { id: { type: 'char', name: 'id', length: 36, primaryKey: true } },
|
|
45
|
+
},
|
|
46
|
+
user_auth: {
|
|
47
|
+
name: 'user_auth',
|
|
48
|
+
columns: {
|
|
49
|
+
id: { type: 'integer', name: 'id', autoIncrement: true, primaryKey: true },
|
|
50
|
+
userId: {
|
|
51
|
+
type: 'char',
|
|
52
|
+
name: 'user_id',
|
|
53
|
+
length: 36,
|
|
54
|
+
notNull: true,
|
|
55
|
+
references: { table: 'users', column: 'id', onDelete: 'cascade' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
const result = compileMysql(schemaWithFk);
|
|
61
|
+
expect(result.users).toBeDefined();
|
|
62
|
+
expect(result.user_auth).toBeDefined();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mysqlTable,
|
|
3
|
+
varchar,
|
|
4
|
+
char,
|
|
5
|
+
text,
|
|
6
|
+
int,
|
|
7
|
+
bigint,
|
|
8
|
+
boolean,
|
|
9
|
+
datetime,
|
|
10
|
+
date,
|
|
11
|
+
mysqlEnum,
|
|
12
|
+
json,
|
|
13
|
+
decimal,
|
|
14
|
+
} from 'drizzle-orm/mysql-core';
|
|
15
|
+
import type { MySqlTableWithColumns } from 'drizzle-orm/mysql-core';
|
|
16
|
+
import type { TableDefinition, ColumnDefinition } from './types';
|
|
17
|
+
|
|
18
|
+
type AnyMySqlTable<N extends string = string> = MySqlTableWithColumns<{
|
|
19
|
+
name: N;
|
|
20
|
+
columns: Record<string, any>;
|
|
21
|
+
dialect: string;
|
|
22
|
+
schema: string | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
export function compileMysql<T extends Record<string, TableDefinition>>(
|
|
26
|
+
schema: T,
|
|
27
|
+
): { [K in keyof T]: T[K] extends TableDefinition<infer N> ? AnyMySqlTable<N & string> : never } {
|
|
28
|
+
const compiled: Record<string, any> = {};
|
|
29
|
+
|
|
30
|
+
const dbNameToKey: Record<string, string> = {};
|
|
31
|
+
for (const key of Object.keys(schema)) {
|
|
32
|
+
dbNameToKey[schema[key].name] = key;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for (const tableName of Object.keys(schema)) {
|
|
36
|
+
const tableDef = schema[tableName];
|
|
37
|
+
const builders: Record<string, any> = {};
|
|
38
|
+
for (const [colName, colDef] of Object.entries(tableDef.columns)) {
|
|
39
|
+
let col = toMysqlColumn(colDef.name, colDef);
|
|
40
|
+
if (colDef.references) {
|
|
41
|
+
const refKey = dbNameToKey[colDef.references.table] ?? colDef.references.table;
|
|
42
|
+
col = col.references(() => compiled[refKey]?.[colDef.references!.column], {
|
|
43
|
+
onDelete: colDef.references!.onDelete,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
builders[colName] = col;
|
|
47
|
+
}
|
|
48
|
+
compiled[tableName] = mysqlTable(tableDef.name, builders);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return compiled as any;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function toMysqlColumn(name: string, def: ColumnDefinition): any {
|
|
55
|
+
let col: any;
|
|
56
|
+
switch (def.type) {
|
|
57
|
+
case 'varchar':
|
|
58
|
+
col = varchar(name, { length: def.length ?? 255 });
|
|
59
|
+
break;
|
|
60
|
+
case 'char':
|
|
61
|
+
col = char(name, { length: def.length ?? 1 });
|
|
62
|
+
break;
|
|
63
|
+
case 'text':
|
|
64
|
+
col = text(name);
|
|
65
|
+
break;
|
|
66
|
+
case 'bigint':
|
|
67
|
+
col = bigint(name, { mode: 'number', unsigned: true });
|
|
68
|
+
break;
|
|
69
|
+
case 'integer':
|
|
70
|
+
col = int(name);
|
|
71
|
+
break;
|
|
72
|
+
case 'boolean':
|
|
73
|
+
col = boolean(name);
|
|
74
|
+
break;
|
|
75
|
+
case 'timestamp':
|
|
76
|
+
col = datetime(name);
|
|
77
|
+
break;
|
|
78
|
+
case 'date':
|
|
79
|
+
col = date(name);
|
|
80
|
+
break;
|
|
81
|
+
case 'enum':
|
|
82
|
+
col =
|
|
83
|
+
def.values && def.values.length > 0
|
|
84
|
+
? mysqlEnum(name, def.values as [string, ...string[]])
|
|
85
|
+
: text(name);
|
|
86
|
+
break;
|
|
87
|
+
case 'json':
|
|
88
|
+
col = json(name);
|
|
89
|
+
break;
|
|
90
|
+
case 'decimal':
|
|
91
|
+
col = decimal(name, { precision: def.precision, scale: def.scale });
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
col = text(name);
|
|
95
|
+
}
|
|
96
|
+
if (def.primaryKey) col = col.primaryKey();
|
|
97
|
+
if (def.autoIncrement) col = col.autoincrement();
|
|
98
|
+
if (def.notNull) col = col.notNull();
|
|
99
|
+
if (def.unique) col = col.unique();
|
|
100
|
+
if (def.default !== undefined) col = col.default(def.default);
|
|
101
|
+
return col;
|
|
102
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { t, table, compileSchema } from './index';
|
|
3
|
+
|
|
4
|
+
describe('compileSchema dispatcher', () => {
|
|
5
|
+
const schema = {
|
|
6
|
+
users: table('users', {
|
|
7
|
+
id: t.char(36).primaryKey(),
|
|
8
|
+
email: t.varchar(255).unique().notNull(),
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
it('compileSchema with mysql dialect', () => {
|
|
13
|
+
const result = compileSchema('mysql', schema);
|
|
14
|
+
expect(result.users).toBeDefined();
|
|
15
|
+
expect(typeof (result.users as any).id).toBe('object');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('compileSchema with d1 dialect', () => {
|
|
19
|
+
const result = compileSchema('d1', schema);
|
|
20
|
+
expect(result.users).toBeDefined();
|
|
21
|
+
expect(typeof (result.users as any).id).toBe('object');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('compileSchema with sqlite dialect', () => {
|
|
25
|
+
const result = compileSchema('sqlite', schema);
|
|
26
|
+
expect(result.users).toBeDefined();
|
|
27
|
+
expect(typeof (result.users as any).id).toBe('object');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('sqlite produces same column types as d1', () => {
|
|
31
|
+
const sqlite = compileSchema('sqlite', schema);
|
|
32
|
+
const d1 = compileSchema('d1', schema);
|
|
33
|
+
expect(sqlite.users.constructor.name).toBe('SQLiteTable');
|
|
34
|
+
expect(d1.users.constructor.name).toBe('SQLiteTable');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { t, table } from './table-builder';
|
|
2
|
+
export type {
|
|
3
|
+
Dialect,
|
|
4
|
+
ColumnDefinition,
|
|
5
|
+
TableDefinition,
|
|
6
|
+
SchemaDefinition,
|
|
7
|
+
ReferenceDef,
|
|
8
|
+
} from './types';
|
|
9
|
+
export { compileMysql } from './compile-mysql';
|
|
10
|
+
export { compileD1 } from './compile-d1';
|
|
11
|
+
export {
|
|
12
|
+
zdb,
|
|
13
|
+
getZodDbMeta,
|
|
14
|
+
isZodObject,
|
|
15
|
+
toTableDefinition,
|
|
16
|
+
toColumnDefinition,
|
|
17
|
+
} from './zod-bridge';
|
|
18
|
+
export type { ZodDbMeta } from './zod-bridge';
|
|
19
|
+
import { isZodObject, toTableDefinition } from './zod-bridge';
|
|
20
|
+
import type { Dialect } from './types';
|
|
21
|
+
import { compileMysql } from './compile-mysql';
|
|
22
|
+
import { compileD1 } from './compile-d1';
|
|
23
|
+
|
|
24
|
+
export function compileSchema<T extends Record<string, any>>(
|
|
25
|
+
dialect: Dialect,
|
|
26
|
+
schema: T,
|
|
27
|
+
): Record<string, any> {
|
|
28
|
+
const definitions: Record<string, any> = {};
|
|
29
|
+
for (const [name, def] of Object.entries(schema)) {
|
|
30
|
+
definitions[name] = isZodObject(def) ? toTableDefinition(name, def) : def;
|
|
31
|
+
}
|
|
32
|
+
switch (dialect) {
|
|
33
|
+
case 'mysql':
|
|
34
|
+
return compileMysql(definitions);
|
|
35
|
+
case 'd1':
|
|
36
|
+
case 'sqlite':
|
|
37
|
+
return compileD1(definitions);
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(`Unknown dialect: ${dialect}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { t, table } from './table-builder';
|
|
3
|
+
|
|
4
|
+
describe('table builder DSL', () => {
|
|
5
|
+
it('t.varchar creates builder with length', () => {
|
|
6
|
+
const def = t.varchar(255).build('email');
|
|
7
|
+
expect(def.type).toBe('varchar');
|
|
8
|
+
expect(def.length).toBe(255);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('t supports all portable types', () => {
|
|
12
|
+
expect(t.char(36).build('a').type).toBe('char');
|
|
13
|
+
expect(t.text().build('a').type).toBe('text');
|
|
14
|
+
expect(t.bigint().build('a').type).toBe('bigint');
|
|
15
|
+
expect(t.integer().build('a').type).toBe('integer');
|
|
16
|
+
expect(t.boolean().build('a').type).toBe('boolean');
|
|
17
|
+
expect(t.timestamp().build('a').type).toBe('timestamp');
|
|
18
|
+
expect(t.date().build('a').type).toBe('date');
|
|
19
|
+
expect(t.enum(['x', 'y']).build('a').type).toBe('enum');
|
|
20
|
+
expect(t.json().build('a').type).toBe('json');
|
|
21
|
+
expect(t.decimal(10, 2).build('a').type).toBe('decimal');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('table() creates TableDefinition with column names', () => {
|
|
25
|
+
const users = table('users', {
|
|
26
|
+
id: t.char(36).primaryKey(),
|
|
27
|
+
email: t.varchar(255).unique().notNull(),
|
|
28
|
+
name: t.varchar(100),
|
|
29
|
+
});
|
|
30
|
+
expect(users.name).toBe('users');
|
|
31
|
+
expect(Object.keys(users.columns)).toEqual(['id', 'email', 'name']);
|
|
32
|
+
expect(users.columns.id.primaryKey).toBe(true);
|
|
33
|
+
expect(users.columns.email.unique).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('table() sets table/column names on builders for references', () => {
|
|
37
|
+
const users = table('users', { id: t.char(36).primaryKey() });
|
|
38
|
+
expect(users.columns.id.name).toBe('id');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('two tables with foreign key reference', () => {
|
|
42
|
+
const users = table('users', {
|
|
43
|
+
id: t.char(36).primaryKey(),
|
|
44
|
+
});
|
|
45
|
+
const posts = table('posts', {
|
|
46
|
+
id: t.char(36).primaryKey(),
|
|
47
|
+
authorId: t.char(36).references(() => users.id),
|
|
48
|
+
});
|
|
49
|
+
expect(posts.columns.authorId.references).toEqual({
|
|
50
|
+
table: 'users',
|
|
51
|
+
column: 'id',
|
|
52
|
+
onDelete: undefined,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ColumnBuilder } from './column-builder';
|
|
2
|
+
import type { TableDefinition, ColumnDefinition } from './types';
|
|
3
|
+
|
|
4
|
+
function c(
|
|
5
|
+
type: ConstructorParameters<typeof ColumnBuilder>[0],
|
|
6
|
+
opts?: ConstructorParameters<typeof ColumnBuilder>[1],
|
|
7
|
+
) {
|
|
8
|
+
return new ColumnBuilder(type, opts);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const t = {
|
|
12
|
+
varchar: (length: number) => c('varchar', { length }),
|
|
13
|
+
char: (length: number) => c('char', { length }),
|
|
14
|
+
text: () => c('text'),
|
|
15
|
+
bigint: () => c('bigint'),
|
|
16
|
+
integer: () => c('integer'),
|
|
17
|
+
boolean: () => c('boolean'),
|
|
18
|
+
timestamp: () => c('timestamp'),
|
|
19
|
+
date: () => c('date'),
|
|
20
|
+
enum: (values: string[]) => c('enum', { values }),
|
|
21
|
+
json: () => c('json'),
|
|
22
|
+
decimal: (p: number, s: number) => c('decimal', { precision: p, scale: s }),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function table<N extends string>(
|
|
26
|
+
name: N,
|
|
27
|
+
columns: Record<string, ColumnBuilder>,
|
|
28
|
+
): TableDefinition<N> {
|
|
29
|
+
const defs: Record<string, ColumnDefinition> = {};
|
|
30
|
+
for (const [colName, builder] of Object.entries(columns)) {
|
|
31
|
+
builder.__tableName = name;
|
|
32
|
+
builder.__columnName = colName;
|
|
33
|
+
defs[colName] = builder.build(colName);
|
|
34
|
+
}
|
|
35
|
+
const tbl: TableDefinition<N> = { name, columns: defs };
|
|
36
|
+
return proxyTable(tbl, columns);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function proxyTable<N extends string>(
|
|
40
|
+
tbl: TableDefinition<N>,
|
|
41
|
+
columns: Record<string, ColumnBuilder>,
|
|
42
|
+
): TableDefinition<N> {
|
|
43
|
+
return new Proxy(tbl, {
|
|
44
|
+
get(target, prop) {
|
|
45
|
+
if (prop in target) return (target as any)[prop];
|
|
46
|
+
if (typeof prop === 'string' && prop in columns) return columns[prop];
|
|
47
|
+
return undefined;
|
|
48
|
+
},
|
|
49
|
+
}) as unknown as TableDefinition<N>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import type { ColumnDefinition, TableDefinition, SchemaDefinition } from './types';
|
|
3
|
+
|
|
4
|
+
describe('schema-builder types', () => {
|
|
5
|
+
it('ColumnDefinition shape with common fields', () => {
|
|
6
|
+
const col: ColumnDefinition = {
|
|
7
|
+
type: 'varchar',
|
|
8
|
+
name: 'email',
|
|
9
|
+
length: 255,
|
|
10
|
+
notNull: true,
|
|
11
|
+
unique: true,
|
|
12
|
+
};
|
|
13
|
+
expect(col.type).toBe('varchar');
|
|
14
|
+
expect(col.notNull).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('ColumnDefinition supports autoIncrement', () => {
|
|
18
|
+
const col: ColumnDefinition = {
|
|
19
|
+
type: 'integer',
|
|
20
|
+
name: 'id',
|
|
21
|
+
autoIncrement: true,
|
|
22
|
+
primaryKey: true,
|
|
23
|
+
};
|
|
24
|
+
expect(col.autoIncrement).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('ColumnDefinition supports enum values and default', () => {
|
|
28
|
+
const col: ColumnDefinition = {
|
|
29
|
+
type: 'enum',
|
|
30
|
+
name: 'role',
|
|
31
|
+
values: ['admin', 'user'],
|
|
32
|
+
default: 'user',
|
|
33
|
+
};
|
|
34
|
+
expect(col.values).toEqual(['admin', 'user']);
|
|
35
|
+
expect(col.default).toBe('user');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('ColumnDefinition supports precision and scale', () => {
|
|
39
|
+
const col: ColumnDefinition = { type: 'decimal', name: 'price', precision: 10, scale: 2 };
|
|
40
|
+
expect(col.precision).toBe(10);
|
|
41
|
+
expect(col.scale).toBe(2);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('ColumnDefinition supports references with onDelete', () => {
|
|
45
|
+
const col: ColumnDefinition = {
|
|
46
|
+
type: 'char',
|
|
47
|
+
name: 'user_id',
|
|
48
|
+
length: 36,
|
|
49
|
+
references: { table: 'users', column: 'id', onDelete: 'cascade' },
|
|
50
|
+
};
|
|
51
|
+
expect(col.references?.table).toBe('users');
|
|
52
|
+
expect(col.references?.onDelete).toBe('cascade');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('TableDefinition shape', () => {
|
|
56
|
+
const t: TableDefinition = {
|
|
57
|
+
name: 'users',
|
|
58
|
+
columns: { id: { type: 'char', name: 'id', length: 36, primaryKey: true } },
|
|
59
|
+
};
|
|
60
|
+
expect(t.name).toBe('users');
|
|
61
|
+
expect(t.columns.id.primaryKey).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('SchemaDefinition is record of tables', () => {
|
|
65
|
+
const s: SchemaDefinition = { users: { name: 'users', columns: {} } };
|
|
66
|
+
expect(s.users.name).toBe('users');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type Dialect = 'mysql' | 'd1' | 'sqlite';
|
|
2
|
+
|
|
3
|
+
export interface ReferenceDef {
|
|
4
|
+
table: string;
|
|
5
|
+
column: string;
|
|
6
|
+
onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ColumnDefinition {
|
|
10
|
+
type: string;
|
|
11
|
+
/** DB column name (distinct from the Record key which is the JS property name) */
|
|
12
|
+
name: string;
|
|
13
|
+
primaryKey?: boolean;
|
|
14
|
+
autoIncrement?: boolean;
|
|
15
|
+
notNull?: boolean;
|
|
16
|
+
unique?: boolean;
|
|
17
|
+
default?: unknown;
|
|
18
|
+
length?: number;
|
|
19
|
+
values?: string[];
|
|
20
|
+
precision?: number;
|
|
21
|
+
scale?: number;
|
|
22
|
+
references?: ReferenceDef;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface TableDefinition<N extends string = string> {
|
|
26
|
+
name: N;
|
|
27
|
+
columns: Record<string, ColumnDefinition>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type SchemaDefinition = Record<string, TableDefinition>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ColumnDefinition, ReferenceDef } from './types';
|
|
3
|
+
|
|
4
|
+
const DB_COL = Symbol('zod:db-col');
|
|
5
|
+
|
|
6
|
+
export interface ZodDbMeta {
|
|
7
|
+
type:
|
|
8
|
+
| 'varchar'
|
|
9
|
+
| 'char'
|
|
10
|
+
| 'text'
|
|
11
|
+
| 'bigint'
|
|
12
|
+
| 'integer'
|
|
13
|
+
| 'boolean'
|
|
14
|
+
| 'timestamp'
|
|
15
|
+
| 'date'
|
|
16
|
+
| 'enum'
|
|
17
|
+
| 'json'
|
|
18
|
+
| 'decimal';
|
|
19
|
+
dbName?: string;
|
|
20
|
+
primaryKey?: boolean;
|
|
21
|
+
autoIncrement?: boolean;
|
|
22
|
+
notNull?: boolean;
|
|
23
|
+
unique?: boolean;
|
|
24
|
+
default?: unknown;
|
|
25
|
+
length?: number;
|
|
26
|
+
values?: string[];
|
|
27
|
+
precision?: number;
|
|
28
|
+
scale?: number;
|
|
29
|
+
references?: ReferenceDef;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function zdb<T extends z.ZodType>(zod: T, meta: ZodDbMeta): T {
|
|
33
|
+
Object.defineProperty(zod, DB_COL, {
|
|
34
|
+
value: meta,
|
|
35
|
+
writable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
});
|
|
38
|
+
return zod;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getZodDbMeta(zod: z.ZodType): ZodDbMeta | undefined {
|
|
42
|
+
return (zod as any)[DB_COL];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isZodObject(schema: unknown): schema is z.ZodObject<any> {
|
|
46
|
+
return typeof schema === 'object' && schema !== null && 'shape' in schema;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function toColumnDefinition(jsName: string, zod: z.ZodType): ColumnDefinition {
|
|
50
|
+
const meta = getZodDbMeta(zod);
|
|
51
|
+
if (!meta) {
|
|
52
|
+
const inner = (zod as any)._def?.innerType;
|
|
53
|
+
if (zod instanceof z.ZodDefault && inner) {
|
|
54
|
+
return toColumnDefinition(jsName, inner);
|
|
55
|
+
}
|
|
56
|
+
if (zod instanceof z.ZodNullable && inner) {
|
|
57
|
+
return toColumnDefinition(jsName, inner);
|
|
58
|
+
}
|
|
59
|
+
if (zod instanceof z.ZodOptional && inner) {
|
|
60
|
+
return toColumnDefinition(jsName, inner);
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`Column "${jsName}" has no db metadata. Use zdb() to attach metadata.`);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
name: meta.dbName ?? jsName,
|
|
66
|
+
type: meta.type,
|
|
67
|
+
primaryKey: meta.primaryKey,
|
|
68
|
+
autoIncrement: meta.autoIncrement,
|
|
69
|
+
notNull: meta.notNull,
|
|
70
|
+
unique: meta.unique,
|
|
71
|
+
default: meta.default,
|
|
72
|
+
length: meta.length,
|
|
73
|
+
values: meta.values,
|
|
74
|
+
precision: meta.precision,
|
|
75
|
+
scale: meta.scale,
|
|
76
|
+
references: meta.references,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function toTableDefinition(
|
|
81
|
+
name: string,
|
|
82
|
+
schema: z.ZodObject<any>,
|
|
83
|
+
): { name: string; columns: Record<string, ColumnDefinition> } {
|
|
84
|
+
const columns: Record<string, ColumnDefinition> = {};
|
|
85
|
+
for (const [key, zod] of Object.entries(schema.shape)) {
|
|
86
|
+
columns[key] = toColumnDefinition(key, zod as z.ZodType);
|
|
87
|
+
}
|
|
88
|
+
return { name, columns };
|
|
89
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
sqliteTable,
|
|
3
|
+
text,
|
|
4
|
+
integer,
|
|
5
|
+
real,
|
|
6
|
+
blob,
|
|
7
|
+
uniqueIndex,
|
|
8
|
+
index,
|
|
9
|
+
primaryKey,
|
|
10
|
+
foreignKey,
|
|
11
|
+
} from 'drizzle-orm/sqlite-core';
|
|
12
|
+
export type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
13
|
+
export { SqlitePlugin } from './plugin';
|
|
14
|
+
export type { SqlitePluginOptions } from './plugin';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import type { IPlugin, Application } from '@rx-ted/packages-honest';
|
|
3
|
+
import { ComponentManager, resolvePluginLogger } from '@rx-ted/packages-honest';
|
|
4
|
+
import { ENV_SYMBOL, type Env, type ILogger } from '@rx-ted/packages-core';
|
|
5
|
+
import { createClient } from '@libsql/client';
|
|
6
|
+
import { drizzle } from 'drizzle-orm/libsql';
|
|
7
|
+
import { DB_GLOBAL_KEY } from '../constants';
|
|
8
|
+
import { assertRuntimeSupport, type AppRuntime } from '../resolve';
|
|
9
|
+
|
|
10
|
+
export interface SqlitePluginOptions {
|
|
11
|
+
dbPath: string;
|
|
12
|
+
schema: Record<string, any>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class SqlitePlugin implements IPlugin {
|
|
16
|
+
readonly name = 'sqlite-plugin';
|
|
17
|
+
readonly version = '0.0.1';
|
|
18
|
+
logger?: ILogger;
|
|
19
|
+
private db: any = null;
|
|
20
|
+
|
|
21
|
+
constructor(private options: SqlitePluginOptions) {}
|
|
22
|
+
|
|
23
|
+
async beforeModulesRegistered(_app: Application, _hono: Hono): Promise<void> {
|
|
24
|
+
this.logger ??= resolvePluginLogger(this.name);
|
|
25
|
+
|
|
26
|
+
const env = ComponentManager.getPlugin<Env>(ENV_SYMBOL);
|
|
27
|
+
assertRuntimeSupport(env.platform as AppRuntime, 'sqlite');
|
|
28
|
+
|
|
29
|
+
this.logger.info(`connecting to SQLite: ${this.options.dbPath}`);
|
|
30
|
+
|
|
31
|
+
const client = createClient({ url: `file:${this.options.dbPath}` });
|
|
32
|
+
const raw = drizzle(client, { schema: this.options.schema });
|
|
33
|
+
this.db = raw;
|
|
34
|
+
|
|
35
|
+
ComponentManager.registerPlugin(DB_GLOBAL_KEY, this.db);
|
|
36
|
+
|
|
37
|
+
this.logger.info(`SQLite connected: ${this.options.dbPath}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async close(): Promise<void> {
|
|
41
|
+
if (this.db?.$client) {
|
|
42
|
+
this.db.$client.close();
|
|
43
|
+
this.logger?.info('SQLite connection closed');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
package/db/src/types.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface PreparedStatement {
|
|
2
|
+
execute(params?: unknown[]): Promise<QueryResult>;
|
|
3
|
+
release(): void;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface DatabaseConnection {
|
|
7
|
+
prepare(sql: string): PreparedStatement;
|
|
8
|
+
query<T>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
9
|
+
execute(sql: string, params?: unknown[]): Promise<QueryResult>;
|
|
10
|
+
release(): void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DatabaseClient {
|
|
14
|
+
prepare(sql: string): PreparedStatement;
|
|
15
|
+
getConnection(): Promise<DatabaseConnection>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface QueryResult {
|
|
20
|
+
affectedRows: number;
|
|
21
|
+
insertId?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DatabaseDriver {
|
|
25
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
26
|
+
execute(sql: string, params?: unknown[]): Promise<QueryResult>;
|
|
27
|
+
transaction<T>(fn: (driver: DatabaseDriver) => Promise<T>): Promise<T>;
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
healthCheck(): Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface QueryOptions {
|
|
33
|
+
where?: Record<string, any>;
|
|
34
|
+
orderBy?: Record<string, 'asc' | 'desc'>;
|
|
35
|
+
pagination?: { page: number; pageSize: number };
|
|
36
|
+
include?: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PaginationResult<T> {
|
|
40
|
+
data: T[];
|
|
41
|
+
total: number;
|
|
42
|
+
page: number;
|
|
43
|
+
pageSize: number;
|
|
44
|
+
totalPages: number;
|
|
45
|
+
}
|
package/db/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": false,
|
|
9
|
+
"experimentalDecorators": true,
|
|
10
|
+
"emitDecoratorMetadata": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"types": ["node"],
|
|
16
|
+
"rootDir": "./src",
|
|
17
|
+
"outDir": "./dist"
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"exclude": ["**/*.test.ts"]
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
import { getWorkspaceAliases } from '../../../vitest.workspace-aliases';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
resolve: {
|
|
6
|
+
alias: getWorkspaceAliases(),
|
|
7
|
+
},
|
|
8
|
+
test: {
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'node',
|
|
11
|
+
exclude: ['node_modules'],
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$ tsc -p tsconfig.json
|