tina4-nodejs 3.13.92 → 3.13.95

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 (193) hide show
  1. package/CLAUDE.md +170 -28
  2. package/README.md +2 -2
  3. package/package.json +13 -9
  4. package/packages/cli/dist/bin.js +33126 -30055
  5. package/packages/cli/src/commands/metrics.ts +17 -11
  6. package/packages/cli/src/commands/serve.ts +10 -9
  7. package/packages/core/dist/index.js +33062 -29908
  8. package/packages/core/src/ai.ts +7 -1
  9. package/packages/core/src/auth.ts +191 -39
  10. package/packages/core/src/background.ts +19 -19
  11. package/packages/core/src/cache.ts +492 -49
  12. package/packages/core/src/devAdmin.ts +79 -32
  13. package/packages/core/src/devMailbox.ts +20 -44
  14. package/packages/core/src/dispatchPipeline.ts +285 -0
  15. package/packages/core/src/dotenv.ts +185 -40
  16. package/packages/core/src/index.ts +7 -6
  17. package/packages/core/src/logger.ts +257 -36
  18. package/packages/core/src/mcp.ts +1 -1
  19. package/packages/core/src/messenger.ts +81 -13
  20. package/packages/core/src/metrics.ts +199 -961
  21. package/packages/core/src/middleware.ts +390 -123
  22. package/packages/core/src/queue.ts +188 -32
  23. package/packages/core/src/queueBackends/kafkaBackend.ts +109 -13
  24. package/packages/core/src/queueBackends/liteBackend.ts +13 -0
  25. package/packages/core/src/queueBackends/mongoBackend.ts +101 -9
  26. package/packages/core/src/queueBackends/rabbitmqBackend.ts +22 -4
  27. package/packages/core/src/rateLimiter.ts +10 -5
  28. package/packages/core/src/request.ts +6 -9
  29. package/packages/core/src/response.ts +46 -1
  30. package/packages/core/src/router.ts +29 -4
  31. package/packages/core/src/server.ts +751 -414
  32. package/packages/core/src/session.ts +244 -27
  33. package/packages/core/src/sessionHandlers/childError.ts +72 -0
  34. package/packages/core/src/sessionHandlers/databaseHandler.ts +338 -48
  35. package/packages/core/src/sessionHandlers/memcachedHandler.ts +181 -0
  36. package/packages/core/src/sessionHandlers/mongoClient.ts +293 -202
  37. package/packages/core/src/sessionHandlers/mongoHandler.ts +88 -8
  38. package/packages/core/src/sessionHandlers/respClient.ts +16 -143
  39. package/packages/core/src/sessionHandlers/sqlClient.ts +290 -0
  40. package/packages/core/src/sessionHandlers/syncBridge.ts +190 -0
  41. package/packages/core/src/sessionHandlers/syncSocket.ts +236 -0
  42. package/packages/core/src/testClient.ts +18 -5
  43. package/packages/core/src/trustedProxy.ts +249 -0
  44. package/packages/core/src/types.ts +29 -5
  45. package/packages/core/src/websocket.ts +66 -0
  46. package/packages/frond/dist/index.js +74 -31
  47. package/packages/frond/src/engine.ts +99 -33
  48. package/packages/orm/dist/index.js +26554 -23400
  49. package/packages/orm/src/adapters/firebird.ts +183 -56
  50. package/packages/orm/src/adapters/mongodb.ts +25 -4
  51. package/packages/orm/src/adapters/mssql.ts +114 -29
  52. package/packages/orm/src/adapters/mysql.ts +103 -40
  53. package/packages/orm/src/adapters/odbc.ts +44 -21
  54. package/packages/orm/src/adapters/postgres.ts +118 -26
  55. package/packages/orm/src/adapters/sqlDialect.ts +120 -0
  56. package/packages/orm/src/adapters/sqlite.ts +64 -25
  57. package/packages/orm/src/baseModel.ts +135 -40
  58. package/packages/orm/src/cachedDatabase.ts +43 -19
  59. package/packages/orm/src/connectTimeout.ts +265 -0
  60. package/packages/orm/src/database.ts +338 -198
  61. package/packages/orm/src/databaseResult.ts +65 -13
  62. package/packages/orm/src/databaseUrl.ts +484 -0
  63. package/packages/orm/src/docstore.ts +386 -145
  64. package/packages/orm/src/index.ts +13 -3
  65. package/packages/orm/src/migration.ts +18 -3
  66. package/packages/orm/src/queryBuilder.ts +38 -4
  67. package/packages/orm/src/sqlTranslator.ts +310 -4
  68. package/packages/orm/src/types.ts +15 -4
  69. package/types/cli/src/bin.d.ts +92 -0
  70. package/types/cli/src/commands/build.d.ts +2 -0
  71. package/types/cli/src/commands/generate.d.ts +47 -0
  72. package/types/cli/src/commands/init.d.ts +1 -0
  73. package/types/cli/src/commands/metrics.d.ts +6 -0
  74. package/types/cli/src/commands/migrate.d.ts +1 -0
  75. package/types/cli/src/commands/migrateCreate.d.ts +1 -0
  76. package/types/cli/src/commands/migrateRollback.d.ts +1 -0
  77. package/types/cli/src/commands/migrateStatus.d.ts +1 -0
  78. package/types/cli/src/commands/queue.d.ts +20 -0
  79. package/types/cli/src/commands/routes.d.ts +1 -0
  80. package/types/cli/src/commands/seed.d.ts +1 -0
  81. package/types/cli/src/commands/serve.d.ts +6 -0
  82. package/types/cli/src/commands/test.d.ts +1 -0
  83. package/types/core/src/ai.d.ts +64 -0
  84. package/types/core/src/api.d.ts +262 -0
  85. package/types/core/src/auth.d.ts +177 -0
  86. package/types/core/src/authGate.d.ts +20 -0
  87. package/types/core/src/background.d.ts +34 -0
  88. package/types/core/src/cache.d.ts +163 -0
  89. package/types/core/src/constants.d.ts +38 -0
  90. package/types/core/src/container.d.ts +44 -0
  91. package/types/core/src/context/chunker.d.ts +31 -0
  92. package/types/core/src/context/index.d.ts +93 -0
  93. package/types/core/src/devAdmin.d.ts +179 -0
  94. package/types/core/src/devMailbox.d.ts +54 -0
  95. package/types/core/src/dispatchPipeline.d.ts +117 -0
  96. package/types/core/src/docs.d.ts +141 -0
  97. package/types/core/src/docsAutoDiscovery.d.ts +6 -0
  98. package/types/core/src/dotenv.d.ts +87 -0
  99. package/types/core/src/env.d.ts +28 -0
  100. package/types/core/src/errorOverlay.d.ts +36 -0
  101. package/types/core/src/events.d.ts +75 -0
  102. package/types/core/src/fakeData.d.ts +55 -0
  103. package/types/core/src/feedback.d.ts +90 -0
  104. package/types/core/src/graphql.d.ts +207 -0
  105. package/types/core/src/health.d.ts +22 -0
  106. package/types/core/src/htmlElement.d.ts +75 -0
  107. package/types/core/src/i18n.d.ts +37 -0
  108. package/types/core/src/index.d.ts +92 -0
  109. package/types/core/src/job.d.ts +39 -0
  110. package/types/core/src/logger.d.ts +200 -0
  111. package/types/core/src/mcp.d.ts +248 -0
  112. package/types/core/src/messenger.d.ts +191 -0
  113. package/types/core/src/metrics.d.ts +41 -0
  114. package/types/core/src/middleware.d.ts +330 -0
  115. package/types/core/src/mqtt.d.ts +257 -0
  116. package/types/core/src/mqttMessage.d.ts +67 -0
  117. package/types/core/src/plan.d.ts +96 -0
  118. package/types/core/src/projectIndex.d.ts +56 -0
  119. package/types/core/src/queue.d.ts +268 -0
  120. package/types/core/src/queueBackends/kafkaBackend.d.ts +117 -0
  121. package/types/core/src/queueBackends/liteBackend.d.ts +128 -0
  122. package/types/core/src/queueBackends/mongoBackend.d.ts +119 -0
  123. package/types/core/src/queueBackends/rabbitmqBackend.d.ts +55 -0
  124. package/types/core/src/rateLimiter.d.ts +49 -0
  125. package/types/core/src/request.d.ts +25 -0
  126. package/types/core/src/response.d.ts +28 -0
  127. package/types/core/src/routeDiscovery.d.ts +12 -0
  128. package/types/core/src/router.d.ts +366 -0
  129. package/types/core/src/scss.d.ts +19 -0
  130. package/types/core/src/server.d.ts +146 -0
  131. package/types/core/src/service.d.ts +115 -0
  132. package/types/core/src/session.d.ts +341 -0
  133. package/types/core/src/sessionHandlers/childError.d.ts +34 -0
  134. package/types/core/src/sessionHandlers/databaseHandler.d.ts +97 -0
  135. package/types/core/src/sessionHandlers/memcachedHandler.d.ts +60 -0
  136. package/types/core/src/sessionHandlers/mongoClient.d.ts +35 -0
  137. package/types/core/src/sessionHandlers/mongoHandler.d.ts +109 -0
  138. package/types/core/src/sessionHandlers/respClient.d.ts +22 -0
  139. package/types/core/src/sessionHandlers/sqlClient.d.ts +39 -0
  140. package/types/core/src/sessionHandlers/syncBridge.d.ts +91 -0
  141. package/types/core/src/sessionHandlers/syncSocket.d.ts +49 -0
  142. package/types/core/src/sessionHandlers/valkeyHandler.d.ts +65 -0
  143. package/types/core/src/static.d.ts +2 -0
  144. package/types/core/src/test.d.ts +94 -0
  145. package/types/core/src/testClient.d.ts +36 -0
  146. package/types/core/src/testing.d.ts +58 -0
  147. package/types/core/src/trustedProxy.d.ts +44 -0
  148. package/types/core/src/types.d.ts +242 -0
  149. package/types/core/src/validator.d.ts +52 -0
  150. package/types/core/src/websocket.d.ts +402 -0
  151. package/types/core/src/websocketBackplane.d.ts +166 -0
  152. package/types/core/src/websocketConnection.d.ts +54 -0
  153. package/types/core/src/wsdl.d.ts +101 -0
  154. package/types/frond/src/engine.d.ts +263 -0
  155. package/types/frond/src/index.d.ts +2 -0
  156. package/types/orm/src/adapters/firebird.d.ts +183 -0
  157. package/types/orm/src/adapters/mongodb.d.ts +81 -0
  158. package/types/orm/src/adapters/mssql.d.ts +77 -0
  159. package/types/orm/src/adapters/mysql.d.ts +67 -0
  160. package/types/orm/src/adapters/odbc.d.ts +94 -0
  161. package/types/orm/src/adapters/postgres.d.ts +86 -0
  162. package/types/orm/src/adapters/sqlDialect.d.ts +71 -0
  163. package/types/orm/src/adapters/sqlite.d.ts +68 -0
  164. package/types/orm/src/autoCrud.d.ts +73 -0
  165. package/types/orm/src/baseModel.d.ts +427 -0
  166. package/types/orm/src/cachedDatabase.d.ts +190 -0
  167. package/types/orm/src/connectTimeout.d.ts +100 -0
  168. package/types/orm/src/database.d.ts +655 -0
  169. package/types/orm/src/databaseResult.d.ts +109 -0
  170. package/types/orm/src/databaseUrl.d.ts +125 -0
  171. package/types/orm/src/docstore.d.ts +241 -0
  172. package/types/orm/src/fakeData.d.ts +22 -0
  173. package/types/orm/src/index.d.ts +43 -0
  174. package/types/orm/src/migration.d.ts +275 -0
  175. package/types/orm/src/model.d.ts +7 -0
  176. package/types/orm/src/query.d.ts +14 -0
  177. package/types/orm/src/queryBuilder.d.ts +193 -0
  178. package/types/orm/src/realtime/index.d.ts +7 -0
  179. package/types/orm/src/realtime/models/attachment.d.ts +43 -0
  180. package/types/orm/src/realtime/models/channel.d.ts +32 -0
  181. package/types/orm/src/realtime/models/channelMember.d.ts +32 -0
  182. package/types/orm/src/realtime/models/message.d.ts +36 -0
  183. package/types/orm/src/realtime/models/workspace.d.ts +26 -0
  184. package/types/orm/src/realtime/realtime.d.ts +24 -0
  185. package/types/orm/src/realtime/storage.d.ts +61 -0
  186. package/types/orm/src/seeder.d.ts +118 -0
  187. package/types/orm/src/sqlTranslator.d.ts +258 -0
  188. package/types/orm/src/types.d.ts +148 -0
  189. package/types/orm/src/validation.d.ts +6 -0
  190. package/types/swagger/src/generator.d.ts +46 -0
  191. package/types/swagger/src/index.d.ts +2 -0
  192. package/types/swagger/src/ui.d.ts +11 -0
  193. package/packages/core/src/sessionHandlers/redisHandler.ts +0 -206
@@ -0,0 +1,77 @@
1
+ import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js";
2
+ export interface MssqlConfig {
3
+ host?: string;
4
+ port?: number;
5
+ user?: string;
6
+ password?: string;
7
+ database?: string;
8
+ connectionString?: string;
9
+ options?: Record<string, unknown>;
10
+ }
11
+ export declare class MssqlAdapter implements DatabaseAdapter {
12
+ private config;
13
+ /**
14
+ * Postgres, MySQL and MSSQL all REQUIRE a name for a derived table, so
15
+ * the COUNT probe in Database.countProbe wraps as
16
+ * `FROM (sql) AS _count_query`. SQLite and Firebird leave this unset and
17
+ * get no alias - Firebird rejects `AS` in that position.
18
+ */
19
+ readonly countSubqueryAlias = "_count_query";
20
+ private connection;
21
+ private _lastInsertId;
22
+ private _inTransaction;
23
+ constructor(config: MssqlConfig | string);
24
+ /** Connect to MSSQL. Must be called before using the adapter. */
25
+ connect(): Promise<void>;
26
+ private parseUrl;
27
+ private ensureConnected;
28
+ /** Translate SQL for MSSQL dialect. */
29
+ translateSql(sql: string): string;
30
+ private execSqlPromise;
31
+ /**
32
+ * Convert ? placeholders to @p0, @p1, ... for tedious.
33
+ *
34
+ * `startAt` lets a caller that has already consumed N placeholders (an UPDATE
35
+ * whose SET values are @p0..@p{N-1}) continue the numbering into a raw WHERE
36
+ * fragment instead of restarting at @p0.
37
+ */
38
+ private convertPlaceholders;
39
+ execute(sql: string, params?: unknown[]): unknown;
40
+ executeMany(sql: string, paramsList: unknown[][]): {
41
+ totalAffected: number;
42
+ lastId?: number | bigint;
43
+ };
44
+ executeManyAsync(sql: string, paramsList: unknown[][]): Promise<{
45
+ totalAffected: number;
46
+ lastId?: number | bigint;
47
+ }>;
48
+ executeAsync(sql: string, params?: unknown[]): Promise<unknown>;
49
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
50
+ queryAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
51
+ fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
52
+ fetchAsync<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): Promise<T[]>;
53
+ fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
54
+ fetchOneAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
55
+ insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): DatabaseResult;
56
+ insertAsync(table: string, data: Record<string, unknown> | Record<string, unknown>[]): Promise<DatabaseResult>;
57
+ update(table: string, data: Record<string, unknown>, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
58
+ updateAsync(table: string, data: Record<string, unknown>, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
59
+ delete(table: string, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
60
+ deleteAsync(table: string, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
61
+ startTransaction(): void;
62
+ startTransactionAsync(): Promise<void>;
63
+ commit(): void;
64
+ commitAsync(): Promise<void>;
65
+ rollback(): void;
66
+ rollbackAsync(): Promise<void>;
67
+ getTables(): string[];
68
+ tablesAsync(): Promise<string[]>;
69
+ getColumns(table: string): ColumnInfo[];
70
+ columnsAsync(table: string): Promise<ColumnInfo[]>;
71
+ lastInsertId(): number | bigint | null;
72
+ close(): void;
73
+ tableExists(name: string): boolean;
74
+ tableExistsAsync(name: string): Promise<boolean>;
75
+ createTable(name: string, columns: Record<string, FieldDefinition>): void;
76
+ createTableAsync(name: string, columns: Record<string, FieldDefinition>): Promise<void>;
77
+ }
@@ -0,0 +1,67 @@
1
+ import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js";
2
+ export interface MysqlConfig {
3
+ host?: string;
4
+ port?: number;
5
+ user?: string;
6
+ password?: string;
7
+ database?: string;
8
+ connectionString?: string;
9
+ }
10
+ export declare class MysqlAdapter implements DatabaseAdapter {
11
+ private config;
12
+ /**
13
+ * Postgres, MySQL and MSSQL all REQUIRE a name for a derived table, so
14
+ * the COUNT probe in Database.countProbe wraps as
15
+ * `FROM (sql) AS _count_query`. SQLite and Firebird leave this unset and
16
+ * get no alias - Firebird rejects `AS` in that position.
17
+ */
18
+ readonly countSubqueryAlias = "_count_query";
19
+ private connection;
20
+ private _lastInsertId;
21
+ private _inTransaction;
22
+ constructor(config: MysqlConfig | string);
23
+ /** Connect to MySQL. Must be called before using the adapter. */
24
+ connect(): Promise<void>;
25
+ private ensureConnected;
26
+ private queryPromise;
27
+ /** Translate SQL for MySQL dialect. */
28
+ translateSql(sql: string): string;
29
+ execute(sql: string, params?: unknown[]): unknown;
30
+ executeMany(sql: string, paramsList: unknown[][]): {
31
+ totalAffected: number;
32
+ lastId?: number | bigint;
33
+ };
34
+ executeManyAsync(sql: string, paramsList: unknown[][]): Promise<{
35
+ totalAffected: number;
36
+ lastId?: number | bigint;
37
+ }>;
38
+ executeAsync(sql: string, params?: unknown[]): Promise<unknown>;
39
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
40
+ queryAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
41
+ fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
42
+ fetchAsync<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): Promise<T[]>;
43
+ fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
44
+ fetchOneAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
45
+ insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): DatabaseResult;
46
+ insertAsync(table: string, data: Record<string, unknown> | Record<string, unknown>[]): Promise<DatabaseResult>;
47
+ update(table: string, data: Record<string, unknown>, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
48
+ updateAsync(table: string, data: Record<string, unknown>, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
49
+ delete(table: string, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
50
+ deleteAsync(table: string, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
51
+ startTransaction(): void;
52
+ startTransactionAsync(): Promise<void>;
53
+ commit(): void;
54
+ commitAsync(): Promise<void>;
55
+ rollback(): void;
56
+ rollbackAsync(): Promise<void>;
57
+ getTables(): string[];
58
+ tablesAsync(): Promise<string[]>;
59
+ getColumns(table: string): ColumnInfo[];
60
+ columnsAsync(table: string): Promise<ColumnInfo[]>;
61
+ lastInsertId(): number | bigint | null;
62
+ close(): void;
63
+ tableExists(name: string): boolean;
64
+ tableExistsAsync(name: string): Promise<boolean>;
65
+ createTable(name: string, columns: Record<string, FieldDefinition>): void;
66
+ createTableAsync(name: string, columns: Record<string, FieldDefinition>): Promise<void>;
67
+ }
@@ -0,0 +1,94 @@
1
+ import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js";
2
+ export interface OdbcConfig {
3
+ /** Full ODBC connection string, e.g. "DSN=MyDSN" or "DRIVER={SQL Server};SERVER=host;DATABASE=db" */
4
+ connectionString: string;
5
+ }
6
+ export declare class OdbcAdapter implements DatabaseAdapter {
7
+ private config;
8
+ private connection;
9
+ private _lastInsertId;
10
+ private _inTransaction;
11
+ /**
12
+ * Accepts either an OdbcConfig object or a raw connection string.
13
+ * When created via Database.create("odbc:///DSN=MyDSN"), the "odbc:///"
14
+ * prefix is stripped by parseDatabaseUrl and the remainder is passed here.
15
+ */
16
+ constructor(config: OdbcConfig | string);
17
+ /** Extract the raw ODBC connection string from config. */
18
+ private getConnectionString;
19
+ /**
20
+ * The address for a diagnostic message. ODBC hides it inside an opaque
21
+ * driver keyword string, so this reads the standard keywords and falls back to
22
+ * the data-source name - it is never used to connect, only to say which target
23
+ * hung.
24
+ */
25
+ private describeTarget;
26
+ /** Connect to the ODBC data source. Must be called before using the adapter. */
27
+ connect(): Promise<void>;
28
+ private ensureConnected;
29
+ execute(sql: string, params?: unknown[]): unknown;
30
+ executeMany(sql: string, paramsList: unknown[][]): {
31
+ totalAffected: number;
32
+ lastId?: number | bigint;
33
+ };
34
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
35
+ fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
36
+ fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
37
+ insert(table: string, data: Record<string, unknown>): DatabaseResult;
38
+ update(table: string, data: Record<string, unknown>, filter: Record<string, unknown>): DatabaseResult;
39
+ delete(table: string, filter: Record<string, unknown> | string | Record<string, unknown>[]): DatabaseResult;
40
+ startTransaction(): void;
41
+ commit(): void;
42
+ rollback(): void;
43
+ getTables(): string[];
44
+ getColumns(table: string): ColumnInfo[];
45
+ tableExists(name: string): boolean;
46
+ createTable(name: string, columns: Record<string, FieldDefinition>): void;
47
+ getTableColumns(name: string): Array<{
48
+ name: string;
49
+ type: string;
50
+ }>;
51
+ addColumn(table: string, colName: string, def: FieldDefinition): void;
52
+ /** Execute a write statement (INSERT, UPDATE, DELETE, DDL). */
53
+ executeAsync(sql: string, params?: unknown[]): Promise<unknown>;
54
+ /** Execute a statement with multiple parameter sets inside a single transaction. */
55
+ executeManyAsync(sql: string, paramsList: unknown[][]): Promise<{
56
+ totalAffected: number;
57
+ lastId?: number | bigint;
58
+ }>;
59
+ /** Run a SELECT and return all matching rows. */
60
+ queryAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
61
+ /** Run a SELECT with optional LIMIT/OFFSET pagination. */
62
+ fetchAsync<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): Promise<T[]>;
63
+ /** Run a SELECT and return the first row or null. */
64
+ fetchOneAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
65
+ /** Insert a single row into a table. */
66
+ insertAsync(table: string, data: Record<string, unknown>): Promise<DatabaseResult>;
67
+ /** Update rows in a table matching filter. */
68
+ updateAsync(table: string, data: Record<string, unknown>, filter: Record<string, unknown>): Promise<DatabaseResult>;
69
+ /** Delete rows from a table. */
70
+ deleteAsync(table: string, filter: Record<string, unknown> | string | Record<string, unknown>[]): Promise<DatabaseResult>;
71
+ /** Begin a transaction. */
72
+ startTransactionAsync(): Promise<void>;
73
+ /** Commit the current transaction. */
74
+ commitAsync(): Promise<void>;
75
+ /** Rollback the current transaction. */
76
+ rollbackAsync(): Promise<void>;
77
+ /** List all user tables using ODBC catalog functions. */
78
+ tablesAsync(): Promise<string[]>;
79
+ /** Get column metadata for a table using ODBC catalog functions. */
80
+ columnsAsync(table: string): Promise<ColumnInfo[]>;
81
+ /** Check whether a table exists. */
82
+ tableExistsAsync(name: string): Promise<boolean>;
83
+ /** Create a table from a FieldDefinition map. Uses generic SQL — works with most ODBC sources. */
84
+ createTableAsync(name: string, columns: Record<string, FieldDefinition>): Promise<void>;
85
+ /** Get raw column name+type list for a table. */
86
+ getTableColumnsAsync(name: string): Promise<Array<{
87
+ name: string;
88
+ type: string;
89
+ }>>;
90
+ /** Add a column to an existing table. */
91
+ addColumnAsync(table: string, colName: string, def: FieldDefinition): Promise<void>;
92
+ lastInsertId(): number | bigint | null;
93
+ close(): void;
94
+ }
@@ -0,0 +1,86 @@
1
+ import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js";
2
+ export interface PostgresConfig {
3
+ host?: string;
4
+ port?: number;
5
+ user?: string;
6
+ password?: string;
7
+ database?: string;
8
+ connectionString?: string;
9
+ }
10
+ export declare class PostgresAdapter implements DatabaseAdapter {
11
+ private config;
12
+ /**
13
+ * Postgres, MySQL and MSSQL all REQUIRE a name for a derived table, so
14
+ * the COUNT probe in Database.countProbe wraps as
15
+ * `FROM (sql) AS _count_query`. SQLite and Firebird leave this unset and
16
+ * get no alias - Firebird rejects `AS` in that position.
17
+ */
18
+ readonly countSubqueryAlias = "_count_query";
19
+ private client;
20
+ private _lastInsertId;
21
+ private _inTransaction;
22
+ constructor(config: PostgresConfig | string);
23
+ /** Connect to PostgreSQL. Must be called before using the adapter. */
24
+ connect(): Promise<void>;
25
+ private ensureConnected;
26
+ /** Convert ? placeholders to $1, $2, ... for pg. */
27
+ /** Ensure bytea columns are Buffer (already the case with pg). No-op guard. */
28
+ private decodeBlobs;
29
+ private convertPlaceholders;
30
+ /**
31
+ * Normalise an `id` column value (typed `unknown` because pg row values are
32
+ * `unknown`) into the shape `_lastInsertId` / `DatabaseResult.lastId`
33
+ * expect. At runtime PG returns numeric PKs as number/bigint (the int8/numeric
34
+ * type parsers above coerce them to Number); a numeric string is coerced to a
35
+ * number so the SERIAL path always returns the integer id.
36
+ *
37
+ * A non-numeric string id — the UUID PK case (`id uuid PRIMARY KEY DEFAULT
38
+ * gen_random_uuid()`) returned via RETURNING — is preserved as-is so the
39
+ * insert surfaces the actual id instead of null (#256). null/undefined/empty
40
+ * still become null.
41
+ */
42
+ private normalizeId;
43
+ execute(sql: string, params?: unknown[]): unknown;
44
+ executeMany(sql: string, paramsList: unknown[][]): {
45
+ totalAffected: number;
46
+ lastId?: number | bigint;
47
+ };
48
+ /** Async executeMany for real usage. */
49
+ executeManyAsync(sql: string, paramsList: unknown[][]): Promise<{
50
+ totalAffected: number;
51
+ lastId?: number | bigint;
52
+ }>;
53
+ /** Async execute for real usage. */
54
+ executeAsync(sql: string, params?: unknown[]): Promise<unknown>;
55
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
56
+ /** Async query for real usage. */
57
+ queryAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
58
+ fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
59
+ fetchAsync<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): Promise<T[]>;
60
+ fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
61
+ fetchOneAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
62
+ insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): DatabaseResult;
63
+ insertAsync(table: string, data: Record<string, unknown> | Record<string, unknown>[]): Promise<DatabaseResult>;
64
+ update(table: string, data: Record<string, unknown>, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
65
+ updateAsync(table: string, data: Record<string, unknown>, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
66
+ delete(table: string, filter: Record<string, unknown>, params?: unknown[]): DatabaseResult;
67
+ deleteAsync(table: string, filter: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseResult>;
68
+ startTransaction(): void;
69
+ startTransactionAsync(): Promise<void>;
70
+ commit(): void;
71
+ commitAsync(): Promise<void>;
72
+ rollback(): void;
73
+ rollbackAsync(): Promise<void>;
74
+ getTables(): string[];
75
+ tablesAsync(): Promise<string[]>;
76
+ getColumns(table: string): ColumnInfo[];
77
+ columnsAsync(table: string): Promise<ColumnInfo[]>;
78
+ lastInsertId(): number | bigint | string | null;
79
+ close(): void;
80
+ tableExists(name: string): boolean;
81
+ tableExistsAsync(name: string): Promise<boolean>;
82
+ createTable(name: string, columns: Record<string, FieldDefinition>): void;
83
+ createTableAsync(name: string, columns: Record<string, FieldDefinition>): Promise<void>;
84
+ /** Translate SQL for PostgreSQL dialect. */
85
+ translateSql(sql: string): string;
86
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * One CRUD SQL builder for every engine, instead of one per adapter.
3
+ *
4
+ * Feature 3's last open item, the 4.3x LOC finding: `insert`/`update`/`delete`
5
+ * built their SQL independently in all seven adapters. Building
6
+ * `INSERT INTO x (a, b) VALUES (?, ?)` is not engine-specific work - Ruby has
7
+ * always done it once - and the seven copies differed in exactly two ways:
8
+ *
9
+ * IDENTIFIER QUOTING "col" | `col` | [col] | Firebird's fbQuote
10
+ * PARAMETER MARKER ? | $1 | @p1
11
+ *
12
+ * Both are captured in a `Dialect` below, so the builders are shared and each
13
+ * adapter declares only what genuinely differs about its engine.
14
+ *
15
+ * These functions build STRINGS and nothing else. Execution and result
16
+ * extraction stay in the adapters on purpose: those really are per-driver
17
+ * (`client.query` vs `lastInsertRowid` vs a Firebird transaction handle), and
18
+ * folding them in here would trade a real duplication for a fake abstraction.
19
+ *
20
+ * MongoDB has no entry: it does not build SQL at all.
21
+ */
22
+ /** How one engine spells identifiers and parameter markers. */
23
+ export interface Dialect {
24
+ /** Quote a table or column name for this engine. */
25
+ quote(name: string): string;
26
+ /**
27
+ * The parameter marker for the 1-based position `index`. Engines with
28
+ * positional markers ($1, @p1) use the index; the rest ignore it.
29
+ */
30
+ marker(index: number): string;
31
+ }
32
+ /** SQLite, and ODBC which follows the SQL standard spelling. */
33
+ export declare const ANSI_DIALECT: Dialect;
34
+ /** PostgreSQL: standard quoting, positional $N markers. */
35
+ export declare const POSTGRES_DIALECT: Dialect;
36
+ /** MySQL: backtick quoting. */
37
+ export declare const MYSQL_DIALECT: Dialect;
38
+ /** MSSQL: bracket quoting, named @pN markers. */
39
+ export declare const MSSQL_DIALECT: Dialect;
40
+ /**
41
+ * Firebird quotes only when it has to: an unquoted identifier is folded to
42
+ * UPPER CASE, so quoting a lower-case name would make it unfindable. The
43
+ * adapter owns that rule and passes its own quoter in.
44
+ */
45
+ export declare function firebirdDialect(fbQuote: (name: string) => string): Dialect;
46
+ /**
47
+ * `INSERT INTO <table> (<cols>) VALUES (<markers>)`.
48
+ *
49
+ * @param suffix Appended verbatim - PostgreSQL passes " RETURNING *" and MSSQL
50
+ * its SCOPE_IDENTITY() probe, the genuinely engine-specific parts.
51
+ * @param startAt Position of the FIRST marker. PostgreSQL numbers its `$N` from
52
+ * 1; MSSQL names its `@pN` from 0 and BINDS by that same name, so
53
+ * shifting it would produce SQL whose parameters do not exist.
54
+ * Engines using `?` ignore this.
55
+ */
56
+ export declare function buildInsert(dialect: Dialect, table: string, keys: string[], suffix?: string, startAt?: number): string;
57
+ /**
58
+ * The `SET a = ?, b = ?` fragment of an UPDATE.
59
+ *
60
+ * @param startAt 1-based position of the FIRST marker. An UPDATE's WHERE
61
+ * clause continues the numbering after the SET values, so a
62
+ * positional engine ($N, @pN) must not restart at 1.
63
+ */
64
+ export declare function buildSetClause(dialect: Dialect, keys: string[], startAt?: number): string;
65
+ /**
66
+ * The `a = ? AND b = ?` fragment for an object filter.
67
+ *
68
+ * @param startAt 1-based position of the first marker, for the same reason as
69
+ * buildSetClause.
70
+ */
71
+ export declare function buildWhereClause(dialect: Dialect, keys: string[], startAt?: number): string;
@@ -0,0 +1,68 @@
1
+ import type { DatabaseAdapter, DatabaseResult, ColumnInfo, FieldDefinition } from "../types.js";
2
+ export declare class SQLiteAdapter implements DatabaseAdapter {
3
+ private db;
4
+ private _lastInsertId;
5
+ /**
6
+ * TINA4_DATABASE_CONNECT_TIMEOUT DOES NOT APPLY HERE, deliberately.
7
+ *
8
+ * There is no connect() to bound: `node:sqlite` opens the file in this
9
+ * SYNCHRONOUS constructor, and a synchronous call cannot be interrupted by a
10
+ * timer on the same thread - the event loop only gets to run the timer after
11
+ * `new DatabaseSync()` has already returned. There is also no host and no port
12
+ * to name in a timeout error. The one case that could still block is a local
13
+ * file on a wedged network mount, which is a kernel-level stall no JS bound
14
+ * can reach. Stated here so the exclusion reads as a decision rather than an
15
+ * adapter somebody forgot.
16
+ */
17
+ constructor(dbPath: string);
18
+ execute(sql: string, params?: unknown[]): unknown;
19
+ executeMany(sql: string, paramsList: unknown[][]): {
20
+ totalAffected: number;
21
+ lastId?: number | bigint;
22
+ };
23
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
24
+ fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
25
+ fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
26
+ insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): DatabaseResult;
27
+ update(table: string, data: Record<string, unknown>, filter: Record<string, unknown> | string, params?: unknown[]): DatabaseResult;
28
+ delete(table: string, filter: Record<string, unknown> | string | Record<string, unknown>[], params?: unknown[]): DatabaseResult;
29
+ private _inTransaction;
30
+ startTransaction(): void;
31
+ commit(): void;
32
+ rollback(): void;
33
+ getTables(): string[];
34
+ getColumns(table: string): ColumnInfo[];
35
+ lastInsertId(): number | bigint | null;
36
+ close(): void;
37
+ /**
38
+ * Atomically increment and return the next value of a tina4_sequences row.
39
+ *
40
+ * DB-contract B (no duplicate primary keys under concurrency): the old
41
+ * read-increment-read path in Database.sequenceNext() yields at every `await`
42
+ * between the read and the write, so two concurrent async callers can read the
43
+ * same `current_value` and return the same id. This method runs the WHOLE
44
+ * operation — ensure-table, seed-if-absent, and the increment-and-return — as
45
+ * ONE synchronous burst on the single shared `node:sqlite` connection. Because
46
+ * `node:sqlite` is synchronous and JavaScript is single-threaded, no other
47
+ * async task can interleave between the statements (there is no `await`
48
+ * inside), so the increment is atomic and every caller gets a distinct id.
49
+ * This is the Node analog of the Python master holding SQLiteAdapter._write_lock
50
+ * across the whole op.
51
+ *
52
+ * On SQLite >= 3.35 a single `UPDATE ... SET current_value = current_value + 1
53
+ * ... RETURNING current_value` is itself atomic and returns the new value in
54
+ * one statement (read via prepare().all() — stmt.run() does not surface
55
+ * RETURNING rows). Older SQLite does `UPDATE ... + 1` then `SELECT`, still
56
+ * race-safe because both run in the same synchronous burst.
57
+ *
58
+ * @throws if the sequence row vanishes mid-increment (never silently returns 1).
59
+ */
60
+ sequenceNextSqlite(seqName: string, seedValue: number): number;
61
+ tableExists(name: string): boolean;
62
+ createTable(name: string, columns: Record<string, FieldDefinition>): void;
63
+ getTableColumns(name: string): Array<{
64
+ name: string;
65
+ type: string;
66
+ }>;
67
+ addColumn(table: string, colName: string, def: FieldDefinition): void;
68
+ }
@@ -0,0 +1,73 @@
1
+ import type { RouteDefinition } from "../../core/src/index.js";
2
+ import type { DiscoveredModel } from "./model.js";
3
+ /**
4
+ * Auto-CRUD — discovers ORM models and auto-generates REST endpoints.
5
+ *
6
+ * Generated endpoints per model:
7
+ * GET /api/{table} — list with pagination, filtering, sorting
8
+ * GET /api/{table}/{id} — get single record
9
+ * POST /api/{table} — create record
10
+ * PUT /api/{table}/{id} — update record
11
+ * DELETE /api/{table}/{id} — delete record
12
+ */
13
+ /**
14
+ * Options accepted by the AutoCrud registration API.
15
+ *
16
+ * `public` is the cross-backend escape hatch (parity with python's `public=True`
17
+ * and php's `bool $public`). Write routes (POST/PUT/DELETE) are secure-by-default
18
+ * — the router gates them unless a def sets `secure: false`. Set `public: true`
19
+ * to open the generated write routes explicitly. Reads (GET) are always public.
20
+ */
21
+ export interface AutoCrudOptions {
22
+ /** When true, the generated write routes (POST/PUT/DELETE) are OPEN (secure:false). Default false → secure. */
23
+ public?: boolean;
24
+ }
25
+ export declare class AutoCrud {
26
+ private static registered;
27
+ /** tableName -> public-writes flag (default secure); mirrors php's `$this->public`. */
28
+ private static publicWrites;
29
+ /**
30
+ * Register a model for auto-CRUD.
31
+ *
32
+ * @param options.public If true, the generated write routes are OPEN (no auth).
33
+ * Default (false) keeps them secure-by-default, matching the framework's write gate.
34
+ */
35
+ static register(model: DiscoveredModel, prefix?: string, options?: AutoCrudOptions): void;
36
+ /**
37
+ * Discover models from the provided array and register them.
38
+ * (In Node.js, models are discovered by the server and passed in.)
39
+ */
40
+ static discover(discoveredModels: DiscoveredModel[], prefix?: string, options?: AutoCrudOptions): string[];
41
+ /**
42
+ * Return all registered models.
43
+ */
44
+ static models(): Map<string, DiscoveredModel>;
45
+ /**
46
+ * Clear all registered models (useful for testing).
47
+ */
48
+ static clear(): void;
49
+ /**
50
+ * Generate route definitions for all registered models, honouring each
51
+ * model's per-table `public` flag (set at register/discover time).
52
+ */
53
+ static generateRoutes(): RouteDefinition[];
54
+ }
55
+ /**
56
+ * Filter discovered models down to those that explicitly opted into auto-CRUD via
57
+ * `static autoCrud = true` (the documented opt-in gate; default false). The server
58
+ * passes only these to generateCrudRoutes, so a model without the flag gets no CRUD
59
+ * endpoints. Exported so the opt-in gate is locked in by a test rather than
60
+ * re-implemented at each call site.
61
+ */
62
+ export declare function crudEligibleModels(models: DiscoveredModel[]): DiscoveredModel[];
63
+ /**
64
+ * Generate CRUD route definitions for the given models.
65
+ * (Standalone function for backward compatibility.)
66
+ *
67
+ * @param options.public When true, the generated write routes (POST/PUT/DELETE)
68
+ * opt OUT of the router's secure-by-default write gate (`secure: false`) — the
69
+ * cross-backend escape hatch (parity with python `public=True` / php `$public`).
70
+ * Default (false) leaves `secure` unset so the router gates writes (secure:true).
71
+ * GET routes are unaffected (reads are already public).
72
+ */
73
+ export declare function generateCrudRoutes(models: DiscoveredModel[], options?: AutoCrudOptions): RouteDefinition[];