@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.
Files changed (266) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +45 -0
  3. package/api-doc/.turbo/turbo-build.log +1 -0
  4. package/api-doc/.turbo/turbo-test.log +11 -0
  5. package/api-doc/.turbo/turbo-typecheck.log +1 -0
  6. package/api-doc/CHANGELOG.md +22 -0
  7. package/api-doc/README.md +80 -0
  8. package/api-doc/dist/api-doc.plugin.d.ts +53 -0
  9. package/api-doc/dist/api-doc.plugin.js +452 -0
  10. package/api-doc/dist/index.d.ts +5 -0
  11. package/api-doc/dist/index.js +3 -0
  12. package/api-doc/dist/interfaces/renderer.interface.d.ts +7 -0
  13. package/api-doc/dist/interfaces/renderer.interface.js +1 -0
  14. package/api-doc/dist/renderers/scalar.renderer.d.ts +10 -0
  15. package/api-doc/dist/renderers/scalar.renderer.js +76 -0
  16. package/api-doc/dist/renderers/swagger.renderer.d.ts +10 -0
  17. package/api-doc/dist/renderers/swagger.renderer.js +83 -0
  18. package/api-doc/node_modules/.bin/esbuild +22 -0
  19. package/api-doc/node_modules/.bin/jiti +22 -0
  20. package/api-doc/node_modules/.bin/sass +22 -0
  21. package/api-doc/node_modules/.bin/tsx +22 -0
  22. package/api-doc/node_modules/.bin/vite +22 -0
  23. package/api-doc/node_modules/.bin/vitest +22 -0
  24. package/api-doc/node_modules/.bin/yaml +22 -0
  25. package/api-doc/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  26. package/api-doc/package.json +48 -0
  27. package/api-doc/src/api-doc.plugin.ts +554 -0
  28. package/api-doc/src/index.ts +5 -0
  29. package/api-doc/src/interfaces/renderer.interface.ts +5 -0
  30. package/api-doc/src/plugin.test.ts +740 -0
  31. package/api-doc/src/renderers/scalar.renderer.ts +82 -0
  32. package/api-doc/src/renderers/swagger.renderer.ts +89 -0
  33. package/api-doc/tsconfig.json +21 -0
  34. package/api-doc/vitest.config.ts +13 -0
  35. package/cache/.turbo/turbo-build.log +1 -0
  36. package/cache/.turbo/turbo-test.log +16 -0
  37. package/cache/CHANGELOG.md +23 -0
  38. package/cache/README.md +79 -0
  39. package/cache/dist/cache-service.d.ts +8 -0
  40. package/cache/dist/cache-service.js +21 -0
  41. package/cache/dist/cacheable.d.ts +2 -0
  42. package/cache/dist/cacheable.js +10 -0
  43. package/cache/dist/cloudflare/driver.d.ts +23 -0
  44. package/cache/dist/cloudflare/driver.js +102 -0
  45. package/cache/dist/cloudflare/index.d.ts +3 -0
  46. package/cache/dist/cloudflare/index.js +2 -0
  47. package/cache/dist/cloudflare/plugin.d.ts +19 -0
  48. package/cache/dist/cloudflare/plugin.js +58 -0
  49. package/cache/dist/index.d.ts +11 -0
  50. package/cache/dist/index.js +14 -0
  51. package/cache/dist/local/driver.d.ts +2 -0
  52. package/cache/dist/local/driver.js +98 -0
  53. package/cache/dist/local/index.d.ts +2 -0
  54. package/cache/dist/local/index.js +2 -0
  55. package/cache/dist/local/plugin.d.ts +14 -0
  56. package/cache/dist/local/plugin.js +24 -0
  57. package/cache/dist/redis/driver.d.ts +10 -0
  58. package/cache/dist/redis/driver.js +102 -0
  59. package/cache/dist/redis/index.d.ts +4 -0
  60. package/cache/dist/redis/index.js +2 -0
  61. package/cache/dist/redis/plugin.d.ts +25 -0
  62. package/cache/dist/redis/plugin.js +61 -0
  63. package/cache/dist/resolve.d.ts +24 -0
  64. package/cache/dist/resolve.js +114 -0
  65. package/cache/dist/types.d.ts +18 -0
  66. package/cache/dist/types.js +1 -0
  67. package/cache/node_modules/.bin/esbuild +22 -0
  68. package/cache/node_modules/.bin/jiti +22 -0
  69. package/cache/node_modules/.bin/sass +22 -0
  70. package/cache/node_modules/.bin/tsx +22 -0
  71. package/cache/node_modules/.bin/vite +22 -0
  72. package/cache/node_modules/.bin/vitest +22 -0
  73. package/cache/node_modules/.bin/yaml +22 -0
  74. package/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  75. package/cache/package.json +46 -0
  76. package/cache/src/cache-service.test.ts +16 -0
  77. package/cache/src/cache-service.ts +15 -0
  78. package/cache/src/cacheable.test.ts +78 -0
  79. package/cache/src/cacheable.ts +16 -0
  80. package/cache/src/cloudflare/driver.test.ts +188 -0
  81. package/cache/src/cloudflare/driver.ts +118 -0
  82. package/cache/src/cloudflare/index.ts +3 -0
  83. package/cache/src/cloudflare/plugin.ts +71 -0
  84. package/cache/src/index.test.ts +68 -0
  85. package/cache/src/index.ts +20 -0
  86. package/cache/src/local/driver.ts +117 -0
  87. package/cache/src/local/index.ts +2 -0
  88. package/cache/src/local/plugin.ts +34 -0
  89. package/cache/src/redis/driver.test.ts +71 -0
  90. package/cache/src/redis/driver.ts +124 -0
  91. package/cache/src/redis/index.ts +4 -0
  92. package/cache/src/redis/plugin.ts +84 -0
  93. package/cache/src/resolve.test.ts +257 -0
  94. package/cache/src/resolve.ts +140 -0
  95. package/cache/src/types.ts +14 -0
  96. package/cache/tsconfig.json +21 -0
  97. package/cache/vitest.config.ts +13 -0
  98. package/db/.turbo/turbo-build.log +1 -0
  99. package/db/.turbo/turbo-test.log +21 -0
  100. package/db/CHANGELOG.md +26 -0
  101. package/db/README.md +99 -0
  102. package/db/dist/constants.d.ts +1 -0
  103. package/db/dist/constants.js +1 -0
  104. package/db/dist/d1/index.d.ts +3 -0
  105. package/db/dist/d1/index.js +2 -0
  106. package/db/dist/d1/plugin.d.ts +18 -0
  107. package/db/dist/d1/plugin.js +104 -0
  108. package/db/dist/db-service.d.ts +7 -0
  109. package/db/dist/db-service.js +21 -0
  110. package/db/dist/index.d.ts +15 -0
  111. package/db/dist/index.js +20 -0
  112. package/db/dist/mysql/client.d.ts +36 -0
  113. package/db/dist/mysql/client.js +84 -0
  114. package/db/dist/mysql/driver.d.ts +18 -0
  115. package/db/dist/mysql/driver.js +107 -0
  116. package/db/dist/mysql/index.d.ts +11 -0
  117. package/db/dist/mysql/index.js +11 -0
  118. package/db/dist/mysql/plugin.d.ts +51 -0
  119. package/db/dist/mysql/plugin.js +94 -0
  120. package/db/dist/mysql/types.d.ts +38 -0
  121. package/db/dist/mysql/types.js +1 -0
  122. package/db/dist/postgres/index.d.ts +2 -0
  123. package/db/dist/postgres/index.js +3 -0
  124. package/db/dist/repository.d.ts +14 -0
  125. package/db/dist/repository.js +79 -0
  126. package/db/dist/resolve.d.ts +6 -0
  127. package/db/dist/resolve.js +81 -0
  128. package/db/dist/schema-builder/column-builder.d.ts +26 -0
  129. package/db/dist/schema-builder/column-builder.js +53 -0
  130. package/db/dist/schema-builder/compile-d1.d.ts +5 -0
  131. package/db/dist/schema-builder/compile-d1.js +67 -0
  132. package/db/dist/schema-builder/compile-mysql.d.ts +12 -0
  133. package/db/dist/schema-builder/compile-mysql.js +78 -0
  134. package/db/dist/schema-builder/index.d.ts +8 -0
  135. package/db/dist/schema-builder/index.js +22 -0
  136. package/db/dist/schema-builder/table-builder.d.ts +16 -0
  137. package/db/dist/schema-builder/table-builder.js +38 -0
  138. package/db/dist/schema-builder/types.d.ts +26 -0
  139. package/db/dist/schema-builder/types.js +1 -0
  140. package/db/dist/schema-builder/zod-bridge.d.ts +24 -0
  141. package/db/dist/schema-builder/zod-bridge.js +53 -0
  142. package/db/dist/sqlite/index.d.ts +4 -0
  143. package/db/dist/sqlite/index.js +2 -0
  144. package/db/dist/sqlite/plugin.d.ts +17 -0
  145. package/db/dist/sqlite/plugin.js +33 -0
  146. package/db/dist/types.d.ts +42 -0
  147. package/db/dist/types.js +1 -0
  148. package/db/node_modules/.bin/esbuild +22 -0
  149. package/db/node_modules/.bin/jiti +22 -0
  150. package/db/node_modules/.bin/sass +22 -0
  151. package/db/node_modules/.bin/tsx +22 -0
  152. package/db/node_modules/.bin/vite +22 -0
  153. package/db/node_modules/.bin/vitest +22 -0
  154. package/db/node_modules/.bin/yaml +22 -0
  155. package/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  156. package/db/package.json +59 -0
  157. package/db/src/constants.test.ts +8 -0
  158. package/db/src/constants.ts +1 -0
  159. package/db/src/d1/index.ts +13 -0
  160. package/db/src/d1/plugin.ts +135 -0
  161. package/db/src/db-service.ts +14 -0
  162. package/db/src/index.test.ts +63 -0
  163. package/db/src/index.ts +57 -0
  164. package/db/src/mysql/client.ts +112 -0
  165. package/db/src/mysql/driver.test.ts +190 -0
  166. package/db/src/mysql/driver.ts +116 -0
  167. package/db/src/mysql/index.ts +51 -0
  168. package/db/src/mysql/plugin.test.ts +228 -0
  169. package/db/src/mysql/plugin.ts +128 -0
  170. package/db/src/mysql/types.ts +32 -0
  171. package/db/src/postgres/index.ts +15 -0
  172. package/db/src/repository.test.ts +195 -0
  173. package/db/src/repository.ts +95 -0
  174. package/db/src/resolve.ts +105 -0
  175. package/db/src/schema-builder/column-builder.test.ts +55 -0
  176. package/db/src/schema-builder/column-builder.ts +87 -0
  177. package/db/src/schema-builder/compile-d1.test.ts +60 -0
  178. package/db/src/schema-builder/compile-d1.ts +70 -0
  179. package/db/src/schema-builder/compile-mysql.test.ts +64 -0
  180. package/db/src/schema-builder/compile-mysql.ts +102 -0
  181. package/db/src/schema-builder/index.test.ts +36 -0
  182. package/db/src/schema-builder/index.ts +41 -0
  183. package/db/src/schema-builder/table-builder.test.ts +55 -0
  184. package/db/src/schema-builder/table-builder.ts +50 -0
  185. package/db/src/schema-builder/types.test.ts +68 -0
  186. package/db/src/schema-builder/types.ts +30 -0
  187. package/db/src/schema-builder/zod-bridge.ts +89 -0
  188. package/db/src/sqlite/index.ts +14 -0
  189. package/db/src/sqlite/plugin.ts +46 -0
  190. package/db/src/types.ts +45 -0
  191. package/db/tsconfig.json +21 -0
  192. package/db/vitest.config.ts +13 -0
  193. package/mail/.turbo/turbo-build.log +1 -0
  194. package/mail/.turbo/turbo-test.log +12 -0
  195. package/mail/.turbo/turbo-typecheck.log +1 -0
  196. package/mail/CHANGELOG.md +25 -0
  197. package/mail/README.md +214 -0
  198. package/mail/dist/index.d.ts +4 -0
  199. package/mail/dist/index.js +2 -0
  200. package/mail/dist/plugin.d.ts +64 -0
  201. package/mail/dist/plugin.js +232 -0
  202. package/mail/dist/providers/brevo.provider.d.ts +15 -0
  203. package/mail/dist/providers/brevo.provider.js +75 -0
  204. package/mail/dist/providers/custom.provider.d.ts +9 -0
  205. package/mail/dist/providers/custom.provider.js +22 -0
  206. package/mail/dist/providers/resend.provider.d.ts +16 -0
  207. package/mail/dist/providers/resend.provider.js +77 -0
  208. package/mail/dist/providers/smtp.provider.d.ts +21 -0
  209. package/mail/dist/providers/smtp.provider.js +86 -0
  210. package/mail/dist/rate-limiter.d.ts +16 -0
  211. package/mail/dist/rate-limiter.js +49 -0
  212. package/mail/dist/types.d.ts +68 -0
  213. package/mail/dist/types.js +6 -0
  214. package/mail/node_modules/.bin/esbuild +22 -0
  215. package/mail/node_modules/.bin/jiti +22 -0
  216. package/mail/node_modules/.bin/sass +22 -0
  217. package/mail/node_modules/.bin/tsx +22 -0
  218. package/mail/node_modules/.bin/vite +22 -0
  219. package/mail/node_modules/.bin/vitest +22 -0
  220. package/mail/node_modules/.bin/yaml +22 -0
  221. package/mail/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  222. package/mail/package.json +52 -0
  223. package/mail/src/index.ts +4 -0
  224. package/mail/src/plugin.test.ts +219 -0
  225. package/mail/src/plugin.ts +313 -0
  226. package/mail/src/providers/brevo.provider.ts +78 -0
  227. package/mail/src/providers/custom.provider.ts +29 -0
  228. package/mail/src/providers/resend.provider.ts +74 -0
  229. package/mail/src/providers/smtp.provider.ts +85 -0
  230. package/mail/src/rate-limiter.test.ts +81 -0
  231. package/mail/src/rate-limiter.ts +54 -0
  232. package/mail/src/types.ts +81 -0
  233. package/mail/tsconfig.json +21 -0
  234. package/mail/vitest.config.ts +13 -0
  235. package/package.json +36 -0
  236. package/s3/.turbo/turbo-build.log +1 -0
  237. package/s3/.turbo/turbo-test.log +11 -0
  238. package/s3/CHANGELOG.md +20 -0
  239. package/s3/README.md +90 -0
  240. package/s3/dist/index.d.ts +6 -0
  241. package/s3/dist/index.js +4 -0
  242. package/s3/dist/s3-service.d.ts +7 -0
  243. package/s3/dist/s3-service.js +21 -0
  244. package/s3/dist/s3.driver.d.ts +6 -0
  245. package/s3/dist/s3.driver.js +221 -0
  246. package/s3/dist/s3.plugin.d.ts +24 -0
  247. package/s3/dist/s3.plugin.js +58 -0
  248. package/s3/dist/types.d.ts +30 -0
  249. package/s3/dist/types.js +1 -0
  250. package/s3/node_modules/.bin/esbuild +22 -0
  251. package/s3/node_modules/.bin/jiti +22 -0
  252. package/s3/node_modules/.bin/sass +22 -0
  253. package/s3/node_modules/.bin/tsx +22 -0
  254. package/s3/node_modules/.bin/vite +22 -0
  255. package/s3/node_modules/.bin/vitest +22 -0
  256. package/s3/node_modules/.bin/yaml +22 -0
  257. package/s3/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  258. package/s3/package.json +47 -0
  259. package/s3/src/index.test.ts +20 -0
  260. package/s3/src/index.ts +13 -0
  261. package/s3/src/s3-service.ts +14 -0
  262. package/s3/src/s3.driver.ts +259 -0
  263. package/s3/src/s3.plugin.ts +80 -0
  264. package/s3/src/types.ts +37 -0
  265. package/s3/tsconfig.json +21 -0
  266. package/s3/vitest.config.ts +13 -0
@@ -0,0 +1,18 @@
1
+ import type { Pool } from 'mysql2/promise';
2
+ import type { Logger } from '@rx-ted/packages-core';
3
+ import type { DatabaseDriver } from '../types';
4
+ export declare function createMysqlDriver(options: {
5
+ host: string;
6
+ port: number;
7
+ user: string;
8
+ password?: string;
9
+ database: string;
10
+ ssl?: boolean | {
11
+ rejectUnauthorized?: boolean;
12
+ ca?: string;
13
+ cert?: string;
14
+ key?: string;
15
+ };
16
+ logger?: Logger;
17
+ pool?: Pool;
18
+ }): Promise<DatabaseDriver>;
@@ -0,0 +1,107 @@
1
+ import { createMysqlClient, MysqlDatabaseClient } from './client';
2
+ export async function createMysqlDriver(options) {
3
+ const logger = options.logger;
4
+ if (logger)
5
+ logger.debug({ host: options.host, port: options.port, database: options.database }, 'MySQL: connecting');
6
+ const client = options.pool
7
+ ? new MysqlDatabaseClient(options.pool)
8
+ : await createMysqlClient(options);
9
+ if (logger)
10
+ logger.info('MySQL: connected');
11
+ return new MysqlDriver(client, logger);
12
+ }
13
+ class MysqlDriver {
14
+ client;
15
+ logger;
16
+ constructor(client, logger) {
17
+ this.client = client;
18
+ this.logger = logger;
19
+ }
20
+ async query(sql, params) {
21
+ if (this.logger)
22
+ this.logger.debug({ sql: sql.substring(0, 100), params }, 'MySQL: query');
23
+ const conn = await this.client.getConnection();
24
+ const result = await conn.query(sql, params);
25
+ conn.release();
26
+ if (this.logger)
27
+ this.logger.debug({ rows: result.length }, 'MySQL: result');
28
+ return result;
29
+ }
30
+ async execute(sql, params) {
31
+ if (this.logger)
32
+ this.logger.debug({ sql: sql.substring(0, 100), params }, 'MySQL: execute');
33
+ const conn = await this.client.getConnection();
34
+ const stmt = conn.prepare(sql);
35
+ const result = await stmt.execute(params);
36
+ stmt.release();
37
+ conn.release();
38
+ if (this.logger)
39
+ this.logger.debug({ affectedRows: result.affectedRows, insertId: result.insertId }, 'MySQL: executed');
40
+ return {
41
+ affectedRows: result.affectedRows,
42
+ insertId: result.insertId ? Number(result.insertId) : undefined,
43
+ };
44
+ }
45
+ async transaction(fn) {
46
+ const conn = await this.client.getConnection();
47
+ await conn.query('SET autocommit = 0');
48
+ await conn.query('START TRANSACTION');
49
+ const txDriver = new TransactionalMysqlDriver(conn, this.logger);
50
+ try {
51
+ const result = await fn(txDriver);
52
+ await conn.query('COMMIT');
53
+ await conn.query('SET autocommit = 1');
54
+ if (this.logger)
55
+ this.logger.debug('MySQL: transaction committed');
56
+ return result;
57
+ }
58
+ catch (error) {
59
+ await conn.query('ROLLBACK');
60
+ await conn.query('SET autocommit = 1');
61
+ if (this.logger)
62
+ this.logger.error({ error }, 'MySQL: transaction rolled back');
63
+ throw error;
64
+ }
65
+ finally {
66
+ conn.release();
67
+ }
68
+ }
69
+ async close() {
70
+ await this.client.close();
71
+ if (this.logger)
72
+ this.logger.info('MySQL: closed');
73
+ }
74
+ async healthCheck() {
75
+ try {
76
+ const conn = await this.client.getConnection();
77
+ await conn.query('SELECT 1');
78
+ conn.release();
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ }
86
+ class TransactionalMysqlDriver {
87
+ connection;
88
+ constructor(connection, _logger) {
89
+ this.connection = connection;
90
+ }
91
+ async query(sql, params) {
92
+ return this.connection.query(sql, params);
93
+ }
94
+ async execute(sql, params) {
95
+ const stmt = this.connection.prepare(sql);
96
+ const result = await stmt.execute(params);
97
+ stmt.release();
98
+ return result;
99
+ }
100
+ async transaction(_fn) {
101
+ throw new Error('Nested transactions are not supported');
102
+ }
103
+ async close() { }
104
+ async healthCheck() {
105
+ return true;
106
+ }
107
+ }
@@ -0,0 +1,11 @@
1
+ export { MysqlPlugin, DRIZZLE_GLOBAL_KEY, DB_CONTEXT_KEY, DRIZZLE_CONTEXT_KEY, MYSQL_CONTEXT_KEY, POOL_CONTEXT_KEY, } from './plugin';
2
+ export type { MysqlPluginOptions } from './plugin';
3
+ export { DB_GLOBAL_KEY } from '../constants';
4
+ export { createMysqlDriver } from './driver';
5
+ export { createMysqlPool, createMysqlClient, MysqlDatabaseClient } from './client';
6
+ export type { MysqlClientOptions } from './types';
7
+ export type { DatabaseOptions, SslOptions, DriverOptions, DatabaseDriverOptions, } from './types';
8
+ export { mysqlTable, varchar, int, bigint, char, text, longtext, date, datetime, timestamp, boolean, json, mysqlEnum, uniqueIndex, index, primaryKey, foreignKey, } from 'drizzle-orm/mysql-core';
9
+ export type { MySql2Database } from 'drizzle-orm/mysql2';
10
+ export { drizzle } from 'drizzle-orm/mysql2';
11
+ export * as drizzleORM from 'drizzle-orm';
@@ -0,0 +1,11 @@
1
+ // Plugin
2
+ export { MysqlPlugin, DRIZZLE_GLOBAL_KEY, DB_CONTEXT_KEY, DRIZZLE_CONTEXT_KEY, MYSQL_CONTEXT_KEY, POOL_CONTEXT_KEY, } from './plugin';
3
+ // Global key
4
+ export { DB_GLOBAL_KEY } from '../constants';
5
+ // Raw driver
6
+ export { createMysqlDriver } from './driver';
7
+ export { createMysqlPool, createMysqlClient, MysqlDatabaseClient } from './client';
8
+ // ── Drizzle ORM re-exports ──
9
+ export { mysqlTable, varchar, int, bigint, char, text, longtext, date, datetime, timestamp, boolean, json, mysqlEnum, uniqueIndex, index, primaryKey, foreignKey, } from 'drizzle-orm/mysql-core';
10
+ export { drizzle } from 'drizzle-orm/mysql2';
11
+ export * as drizzleORM from 'drizzle-orm';
@@ -0,0 +1,51 @@
1
+ import type { Hono } from 'hono';
2
+ import type mysql from 'mysql2/promise';
3
+ import { type ILogger } from '@rx-ted/packages-core';
4
+ import type { Application, IPlugin } from '@rx-ted/packages-honest';
5
+ import type { DatabaseDriver } from '../types';
6
+ export declare const DB_CONTEXT_KEY = "context:db";
7
+ export declare const POOL_CONTEXT_KEY = "honest:mysql:pool";
8
+ export declare const DRIZZLE_GLOBAL_KEY = "app:db";
9
+ export declare const DRIZZLE_CONTEXT_KEY = "context:db";
10
+ export declare const MYSQL_CONTEXT_KEY = "honest:mysql";
11
+ export interface MysqlPluginOptions {
12
+ connection: {
13
+ host: string;
14
+ port: number;
15
+ user: string;
16
+ password?: string;
17
+ database: string;
18
+ ssl?: boolean | {
19
+ rejectUnauthorized?: boolean;
20
+ ca?: string;
21
+ cert?: string;
22
+ key?: string;
23
+ };
24
+ connectionLimit?: number;
25
+ };
26
+ contextKey?: string;
27
+ schema?: Record<string, unknown>;
28
+ logger?: boolean | ((log: string) => void);
29
+ plugins?: Array<{
30
+ name: string;
31
+ install: (db: any) => void;
32
+ }>;
33
+ }
34
+ export declare class MysqlPlugin implements IPlugin {
35
+ static readonly globalKey = "app:db";
36
+ readonly name = "mysql-plugin";
37
+ readonly version = "1.0.0";
38
+ logger?: ILogger;
39
+ private driver;
40
+ private drizzleInstance;
41
+ private pool;
42
+ private readonly options;
43
+ private readonly contextKey;
44
+ constructor(options: MysqlPluginOptions);
45
+ getClient(): DatabaseDriver;
46
+ getDrizzle(): any;
47
+ getPool(): mysql.Pool;
48
+ beforeModulesRegistered(app: Application, _hono: Hono): Promise<void>;
49
+ afterModulesRegistered(_app: Application, _hono: Hono): Promise<void>;
50
+ close(): Promise<void>;
51
+ }
@@ -0,0 +1,94 @@
1
+ import { drizzle } from 'drizzle-orm/mysql2';
2
+ import { ENV_SYMBOL } from '@rx-ted/packages-core';
3
+ import { ComponentManager, resolvePluginLogger } from '@rx-ted/packages-honest';
4
+ import { createMysqlPool } from './client';
5
+ import { createMysqlDriver } from './driver';
6
+ import { DB_GLOBAL_KEY } from '../constants';
7
+ import { assertRuntimeSupport } from '../resolve';
8
+ export const DB_CONTEXT_KEY = 'context:db';
9
+ export const POOL_CONTEXT_KEY = 'honest:mysql:pool';
10
+ // Backward-compat aliases
11
+ export const DRIZZLE_GLOBAL_KEY = DB_GLOBAL_KEY;
12
+ export const DRIZZLE_CONTEXT_KEY = DB_CONTEXT_KEY;
13
+ export const MYSQL_CONTEXT_KEY = 'honest:mysql';
14
+ export class MysqlPlugin {
15
+ static globalKey = DB_GLOBAL_KEY;
16
+ name = 'mysql-plugin';
17
+ version = '1.0.0';
18
+ logger;
19
+ driver = null;
20
+ drizzleInstance = null;
21
+ pool = null;
22
+ options;
23
+ contextKey;
24
+ constructor(options) {
25
+ this.options = options;
26
+ this.contextKey = options.contextKey ?? MYSQL_CONTEXT_KEY;
27
+ }
28
+ getClient() {
29
+ if (!this.driver)
30
+ throw new Error('MySQL driver not initialized');
31
+ return this.driver;
32
+ }
33
+ getDrizzle() {
34
+ if (!this.drizzleInstance)
35
+ throw new Error('Drizzle not initialized');
36
+ return this.drizzleInstance;
37
+ }
38
+ getPool() {
39
+ if (!this.pool)
40
+ throw new Error('MySQL pool not initialized');
41
+ return this.pool;
42
+ }
43
+ async beforeModulesRegistered(app, _hono) {
44
+ this.logger ??= resolvePluginLogger(this.name);
45
+ const env = ComponentManager.getPlugin(ENV_SYMBOL);
46
+ assertRuntimeSupport(env.platform, 'mysql');
47
+ this.logger.info({
48
+ host: this.options.connection.host,
49
+ database: this.options.connection.database,
50
+ }, 'MySQL: initializing');
51
+ this.pool = createMysqlPool({ ...this.options.connection });
52
+ this.driver = await createMysqlDriver({
53
+ ...this.options.connection,
54
+ pool: this.pool,
55
+ logger: this.logger,
56
+ });
57
+ const { schema } = this.options;
58
+ this.drizzleInstance = drizzle(this.pool, {
59
+ schema,
60
+ mode: 'default',
61
+ logger: this.options.logger === true
62
+ ? true
63
+ : typeof this.options.logger === 'function'
64
+ ? {
65
+ logQuery: (query, params) => this.options.logger(query),
66
+ }
67
+ : this.options.logger,
68
+ });
69
+ ComponentManager.registerPlugin(DB_GLOBAL_KEY, this.drizzleInstance);
70
+ app.getContext().set(POOL_CONTEXT_KEY, this.pool);
71
+ app.getContext().set(this.contextKey, this.driver);
72
+ app.getContext().set(DB_CONTEXT_KEY, this.drizzleInstance);
73
+ }
74
+ async afterModulesRegistered(_app, _hono) {
75
+ if (!this.logger)
76
+ return;
77
+ const healthy = await this.driver?.healthCheck();
78
+ if (healthy) {
79
+ this.logger.info('MySQL: health check passed');
80
+ }
81
+ else {
82
+ this.logger.error('MySQL: health check failed');
83
+ }
84
+ }
85
+ async close() {
86
+ this.logger?.info('MySQL: shutting down');
87
+ await this.driver?.close();
88
+ if (this.pool)
89
+ await this.pool.end();
90
+ this.driver = null;
91
+ this.drizzleInstance = null;
92
+ this.pool = null;
93
+ }
94
+ }
@@ -0,0 +1,38 @@
1
+ import type { Logger } from '@rx-ted/packages-core';
2
+ export interface DatabaseOptions {
3
+ host: string;
4
+ port: number;
5
+ user: string;
6
+ password?: string;
7
+ database: string;
8
+ ssl?: boolean | {
9
+ rejectUnauthorized?: boolean;
10
+ ca?: string;
11
+ cert?: string;
12
+ key?: string;
13
+ };
14
+ }
15
+ export interface SslOptions {
16
+ rejectUnauthorized?: boolean;
17
+ ca?: string;
18
+ cert?: string;
19
+ key?: string;
20
+ }
21
+ export interface DriverOptions {
22
+ logger?: Logger;
23
+ }
24
+ export interface DatabaseDriverOptions extends DatabaseOptions, DriverOptions {
25
+ }
26
+ export interface MysqlClientOptions {
27
+ host: string;
28
+ port: number;
29
+ user: string;
30
+ password?: string;
31
+ database: string;
32
+ ssl?: boolean | {
33
+ rejectUnauthorized?: boolean;
34
+ ca?: string;
35
+ cert?: string;
36
+ key?: string;
37
+ };
38
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { pgTable, text, integer, boolean, timestamp, pgEnum, uniqueIndex, index, primaryKey, foreignKey, } from 'drizzle-orm/pg-core';
2
+ export type { PgDatabase } from 'drizzle-orm/pg-core';
@@ -0,0 +1,3 @@
1
+ // PostgreSQL dialect — placeholder
2
+ // Re-export Drizzle pg-core types for consumers to use in schema definitions
3
+ export { pgTable, text, integer, boolean, timestamp, pgEnum, uniqueIndex, index, primaryKey, foreignKey, } from 'drizzle-orm/pg-core';
@@ -0,0 +1,14 @@
1
+ import { type Table } from 'drizzle-orm';
2
+ import type { QueryOptions, PaginationResult } from './types';
3
+ export declare class BaseRepository<TTable extends Table> {
4
+ protected db: any;
5
+ protected table: TTable;
6
+ constructor(db: any, table: TTable);
7
+ findById(id: string): Promise<any | null>;
8
+ findMany(options?: QueryOptions): Promise<any[]>;
9
+ findWithPagination(options?: QueryOptions): Promise<PaginationResult<any>>;
10
+ create(data: any): Promise<any>;
11
+ update(id: string, data: any): Promise<any | null>;
12
+ delete(id: string): Promise<boolean>;
13
+ count(where?: Record<string, any>): Promise<number>;
14
+ }
@@ -0,0 +1,79 @@
1
+ import { eq, and } from 'drizzle-orm';
2
+ import { sql } from 'drizzle-orm';
3
+ export class BaseRepository {
4
+ db;
5
+ table;
6
+ constructor(db, table) {
7
+ this.db = db;
8
+ this.table = table;
9
+ }
10
+ async findById(id) {
11
+ const [result] = await this.db
12
+ .select()
13
+ .from(this.table)
14
+ .where(eq(this.table.id, id))
15
+ .limit(1);
16
+ return result ?? null;
17
+ }
18
+ async findMany(options) {
19
+ let query = this.db.select().from(this.table);
20
+ if (options?.where) {
21
+ const conditions = Object.entries(options.where).map(([key, value]) => eq(this.table[key], value));
22
+ query = query.where(and(...conditions));
23
+ }
24
+ if (options?.orderBy) {
25
+ for (const [key, dir] of Object.entries(options.orderBy)) {
26
+ query = query.orderBy(dir === 'desc'
27
+ ? sql `${this.table[key]} desc`
28
+ : sql `${this.table[key]} asc`);
29
+ }
30
+ }
31
+ if (options?.pagination) {
32
+ const { page, pageSize } = options.pagination;
33
+ query = query.limit(pageSize).offset((page - 1) * pageSize);
34
+ }
35
+ return query;
36
+ }
37
+ async findWithPagination(options) {
38
+ const page = options?.pagination?.page ?? 1;
39
+ const pageSize = options?.pagination?.pageSize ?? 10;
40
+ const data = await this.findMany(options);
41
+ const total = await this.count(options?.where);
42
+ return {
43
+ data,
44
+ total,
45
+ page,
46
+ pageSize,
47
+ totalPages: Math.ceil(total / pageSize),
48
+ };
49
+ }
50
+ async create(data) {
51
+ const raw = await this.db.insert(this.table).values(data);
52
+ const r = Array.isArray(raw) ? raw[0] : raw;
53
+ return {
54
+ insertId: Number(r.insertId ?? r.lastInsertRowid ?? r.meta?.last_row_id),
55
+ affectedRows: Number(r.affectedRows ?? r.rowsAffected ?? r.meta?.changes ?? 0),
56
+ };
57
+ }
58
+ async update(id, data) {
59
+ const raw = await this.db
60
+ .update(this.table)
61
+ .set(data)
62
+ .where(eq(this.table.id, id));
63
+ const r = Array.isArray(raw) ? raw[0] : raw;
64
+ return r ?? null;
65
+ }
66
+ async delete(id) {
67
+ const result = await this.db.delete(this.table).where(eq(this.table.id, id));
68
+ return result.affectedRows > 0;
69
+ }
70
+ async count(where) {
71
+ let query = this.db.select({ count: sql `count(*)` }).from(this.table);
72
+ if (where) {
73
+ const conditions = Object.entries(where).map(([key, value]) => eq(this.table[key], value));
74
+ query = query.where(and(...conditions));
75
+ }
76
+ const [result] = await query;
77
+ return Number(result?.count ?? 0);
78
+ }
79
+ }
@@ -0,0 +1,6 @@
1
+ import type { IPlugin } from '@rx-ted/packages-honest';
2
+ export type AppRuntime = 'node' | 'bun' | 'deno' | 'cloudflare' | 'vercel-edge';
3
+ export type DbType = 'd1' | 'sqlite' | 'mysql';
4
+ export declare function assertRuntimeSupport(runtime: AppRuntime, dbType: DbType): void;
5
+ export declare function DBPlugin(schema: Record<string, any>): Promise<IPlugin>;
6
+ export declare function DBPlugin(plugin: IPlugin): Promise<IPlugin>;
@@ -0,0 +1,81 @@
1
+ import { ENV_SYMBOL, Env } from '@rx-ted/packages-core';
2
+ import { ComponentManager } from '@rx-ted/packages-honest';
3
+ const RUNTIME_DB_MAP = {
4
+ cloudflare: ['d1'],
5
+ node: ['sqlite', 'mysql'],
6
+ bun: ['sqlite', 'mysql'],
7
+ deno: ['sqlite', 'mysql'],
8
+ 'vercel-edge': [],
9
+ };
10
+ const PLUGIN_DB_TYPE = {
11
+ D1Plugin: 'd1',
12
+ SqlitePlugin: 'sqlite',
13
+ MysqlPlugin: 'mysql',
14
+ };
15
+ function getAppEnv() {
16
+ if (ComponentManager.hasPlugin(ENV_SYMBOL)) {
17
+ return ComponentManager.getPlugin(ENV_SYMBOL);
18
+ }
19
+ return new Env(process.env, {});
20
+ }
21
+ export function assertRuntimeSupport(runtime, dbType) {
22
+ if (!(runtime in RUNTIME_DB_MAP)) {
23
+ throw new Error(`[db] Unsupported runtime "${runtime}". ` +
24
+ `Supported: ${Object.keys(RUNTIME_DB_MAP).join(', ')}. ` +
25
+ `Contact the developer to add support for this runtime.`);
26
+ }
27
+ const allowed = RUNTIME_DB_MAP[runtime];
28
+ if (!allowed.includes(dbType)) {
29
+ throw new Error(`[db] Database "${dbType}" is not supported on runtime "${runtime}". ` +
30
+ `Allowed databases for "${runtime}": ${allowed.join(', ')}. ` +
31
+ `Change the DB env var or switch to a different runtime.`);
32
+ }
33
+ }
34
+ function dbTypeFromPlugin(plugin) {
35
+ const name = plugin.constructor?.name;
36
+ const dbType = name ? PLUGIN_DB_TYPE[name] : undefined;
37
+ if (!dbType) {
38
+ throw new Error(`[db] Unknown plugin "${name}". ` +
39
+ `Supported plugins: ${Object.keys(PLUGIN_DB_TYPE).join(', ')}.`);
40
+ }
41
+ return dbType;
42
+ }
43
+ export async function DBPlugin(arg) {
44
+ const appEnv = getAppEnv();
45
+ // Explicit mode: user passed a pre-created plugin
46
+ if (arg && typeof arg === 'object' && 'name' in arg && 'version' in arg) {
47
+ const dbType = dbTypeFromPlugin(arg);
48
+ assertRuntimeSupport(appEnv.platform, dbType);
49
+ return arg;
50
+ }
51
+ // Auto-detect mode: arg is schema
52
+ const runtime = appEnv.platform;
53
+ const dbRaw = appEnv.get('DB');
54
+ const db = (typeof dbRaw === 'string' ? dbRaw : undefined) ??
55
+ RUNTIME_DB_MAP[runtime]?.[0] ??
56
+ 'sqlite';
57
+ assertRuntimeSupport(runtime, db);
58
+ if (db === 'd1') {
59
+ const { D1Plugin } = await import('./d1/plugin');
60
+ return new D1Plugin({ schema: arg });
61
+ }
62
+ if (db === 'sqlite') {
63
+ const { SqlitePlugin } = await import('./sqlite/plugin');
64
+ return new SqlitePlugin({
65
+ dbPath: appEnv.var('DB_PATH', 'data/app.db'),
66
+ schema: arg,
67
+ });
68
+ }
69
+ const { MysqlPlugin } = await import('./mysql/plugin');
70
+ return new MysqlPlugin({
71
+ connection: {
72
+ host: appEnv.get('DB_HOST', 'string'),
73
+ port: appEnv.get('DB_PORT', 'number'),
74
+ user: appEnv.get('DB_USER', 'string'),
75
+ password: appEnv.get('DB_PASSWORD') ?? '',
76
+ database: appEnv.get('DB_DATABASE', 'string'),
77
+ },
78
+ schema: arg,
79
+ logger: true,
80
+ });
81
+ }
@@ -0,0 +1,26 @@
1
+ import type { ColumnDefinition, ReferenceDef } from './types';
2
+ type ColumnType = 'varchar' | 'char' | 'text' | 'bigint' | 'integer' | 'boolean' | 'timestamp' | 'date' | 'enum' | 'json' | 'decimal';
3
+ interface ColumnOpts {
4
+ length?: number;
5
+ values?: string[];
6
+ precision?: number;
7
+ scale?: number;
8
+ }
9
+ export declare class ColumnBuilder {
10
+ private def;
11
+ private customDbName?;
12
+ __tableName?: string;
13
+ __columnName?: string;
14
+ constructor(type: ColumnType, opts?: ColumnOpts);
15
+ dbName(name: string): this;
16
+ primaryKey(): this;
17
+ autoIncrement(): this;
18
+ notNull(): this;
19
+ unique(): this;
20
+ default(value: unknown): this;
21
+ references(fn: () => ColumnBuilder, opts?: {
22
+ onDelete?: ReferenceDef['onDelete'];
23
+ }): this;
24
+ build(name: string): ColumnDefinition;
25
+ }
26
+ export {};
@@ -0,0 +1,53 @@
1
+ export class ColumnBuilder {
2
+ def;
3
+ customDbName;
4
+ __tableName;
5
+ __columnName;
6
+ constructor(type, opts) {
7
+ this.def = { type };
8
+ if (opts?.length !== undefined)
9
+ this.def.length = opts.length;
10
+ if (opts?.values !== undefined)
11
+ this.def.values = opts.values;
12
+ if (opts?.precision !== undefined)
13
+ this.def.precision = opts.precision;
14
+ if (opts?.scale !== undefined)
15
+ this.def.scale = opts.scale;
16
+ }
17
+ dbName(name) {
18
+ this.customDbName = name;
19
+ return this;
20
+ }
21
+ primaryKey() {
22
+ this.def.primaryKey = true;
23
+ return this;
24
+ }
25
+ autoIncrement() {
26
+ this.def.autoIncrement = true;
27
+ return this;
28
+ }
29
+ notNull() {
30
+ this.def.notNull = true;
31
+ return this;
32
+ }
33
+ unique() {
34
+ this.def.unique = true;
35
+ return this;
36
+ }
37
+ default(value) {
38
+ this.def.default = value;
39
+ return this;
40
+ }
41
+ references(fn, opts) {
42
+ const target = fn();
43
+ const tbl = target.__tableName ?? target.table?.[Symbol.for('drizzle:Name')];
44
+ const col = target.__columnName ?? target.name;
45
+ if (!tbl || !col)
46
+ throw new Error('references() target not fully initialized (missing table/column name)');
47
+ this.def.references = { table: tbl, column: col, onDelete: opts?.onDelete };
48
+ return this;
49
+ }
50
+ build(name) {
51
+ return { name: this.customDbName ?? name, ...this.def };
52
+ }
53
+ }
@@ -0,0 +1,5 @@
1
+ import type { SQLiteTable } from 'drizzle-orm/sqlite-core';
2
+ import type { SchemaDefinition } from './types';
3
+ export declare function compileD1<T extends SchemaDefinition>(schema: T): {
4
+ [K in keyof T]: SQLiteTable;
5
+ };