tina4-nodejs 3.13.137 → 3.13.139
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/CLAUDE.md +33 -3
- package/COMMERCIAL-LICENSE.md +8 -0
- package/LICENSE +373 -0
- package/NOTICE +11 -0
- package/README.md +24 -2
- package/package.json +44 -6
- package/packages/cli/dist/bin.js +19979 -18102
- package/packages/cli/src/bin.ts +8 -0
- package/packages/cli/src/commands/build.ts +8 -0
- package/packages/cli/src/commands/generate.ts +8 -0
- package/packages/cli/src/commands/init.ts +8 -0
- package/packages/cli/src/commands/lint.ts +8 -0
- package/packages/cli/src/commands/migrate.ts +8 -0
- package/packages/cli/src/commands/migrateCreate.ts +8 -0
- package/packages/cli/src/commands/migrateRollback.ts +8 -0
- package/packages/cli/src/commands/migrateStatus.ts +8 -0
- package/packages/cli/src/commands/queue.ts +8 -0
- package/packages/cli/src/commands/routes.ts +8 -0
- package/packages/cli/src/commands/seed.ts +8 -0
- package/packages/cli/src/commands/serve.ts +11 -0
- package/packages/cli/src/commands/test.ts +8 -0
- package/packages/core/dist/index.js +19976 -18097
- package/packages/core/gallery/auth/src/routes/api/gallery/auth/login/post.ts +8 -0
- package/packages/core/gallery/auth/src/routes/api/gallery/auth/verify/get.ts +8 -0
- package/packages/core/gallery/auth/src/routes/gallery/auth/get.ts +8 -0
- package/packages/core/gallery/database/src/routes/api/gallery/db/notes/get.ts +8 -0
- package/packages/core/gallery/database/src/routes/api/gallery/db/notes/post.ts +8 -0
- package/packages/core/gallery/database/src/routes/api/gallery/db/tables/get.ts +8 -0
- package/packages/core/gallery/error-overlay/src/routes/api/gallery/crash/get.ts +8 -0
- package/packages/core/gallery/orm/src/routes/api/gallery/products/get.ts +8 -0
- package/packages/core/gallery/orm/src/routes/api/gallery/products/post.ts +8 -0
- package/packages/core/gallery/queue/src/lib/queueDb.ts +8 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/consume/post.ts +8 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/fail/post.ts +8 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/produce/post.ts +8 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/retry/post.ts +8 -0
- package/packages/core/gallery/queue/src/routes/api/gallery/queue/status/get.ts +8 -0
- package/packages/core/gallery/queue/src/routes/gallery/queue/get.ts +8 -0
- package/packages/core/gallery/rest-api/src/routes/api/gallery/hello/get.ts +8 -0
- package/packages/core/gallery/rest-api/src/routes/api/gallery/hello/post.ts +8 -0
- package/packages/core/gallery/templates/src/routes/gallery/page/get.ts +8 -0
- package/packages/core/gallery/templates/src/templates/gallery_page.twig +8 -0
- package/packages/core/public/THIRD-PARTY-NOTICES.md +55 -0
- package/packages/core/public/bundled-component-provenance.json +48 -0
- package/packages/core/public/js/tina4js.min.js +13 -3
- package/packages/core/public/licenses/swagger-ui-3.10.0-original-notice.txt +11 -0
- package/packages/core/public/licenses/swagger-ui-5.17.14-NOTICE.txt +2 -0
- package/packages/core/public/licenses/swagger-ui-Apache-2.0.txt +202 -0
- package/packages/core/public/licenses/tina4-css-MIT.txt +21 -0
- package/packages/core/public/licenses/tina4-dev-admin-components.json +240 -0
- package/packages/core/public/licenses/tina4-dev-admin-third-party.txt +919 -0
- package/packages/core/public/licenses/tina4-js-MIT.txt +20 -0
- package/packages/core/src/__feedback/widget.js +8 -0
- package/packages/core/src/_missing.ts +8 -0
- package/packages/core/src/ai.ts +8 -0
- package/packages/core/src/aiClient.ts +8 -0
- package/packages/core/src/api.ts +48 -7
- package/packages/core/src/auth.ts +94 -14
- package/packages/core/src/authGate.ts +35 -20
- package/packages/core/src/background.ts +8 -0
- package/packages/core/src/cache.ts +43 -4
- package/packages/core/src/constants.ts +8 -0
- package/packages/core/src/container.ts +8 -0
- package/packages/core/src/context/chunker.ts +8 -0
- package/packages/core/src/context/index.ts +8 -0
- package/packages/core/src/devAdmin.ts +185 -59
- package/packages/core/src/devMailbox.ts +8 -0
- package/packages/core/src/dispatchPipeline.ts +8 -0
- package/packages/core/src/docs.ts +8 -0
- package/packages/core/src/docsAutoDiscovery.ts +8 -0
- package/packages/core/src/docsParser.ts +8 -0
- package/packages/core/src/docsScanner.ts +44 -0
- package/packages/core/src/docsSignatures.ts +8 -0
- package/packages/core/src/dotenv.ts +8 -0
- package/packages/core/src/env.ts +8 -0
- package/packages/core/src/errorOverlay.ts +8 -0
- package/packages/core/src/events.ts +8 -0
- package/packages/core/src/fakeData.ts +8 -0
- package/packages/core/src/feedback.ts +8 -0
- package/packages/core/src/graphql.ts +108 -5
- package/packages/core/src/health.ts +8 -0
- package/packages/core/src/htmlElement.ts +8 -0
- package/packages/core/src/i18n.ts +8 -0
- package/packages/core/src/index.ts +9 -0
- package/packages/core/src/job.ts +16 -1
- package/packages/core/src/logger.ts +8 -0
- package/packages/core/src/mcp.test.ts +8 -0
- package/packages/core/src/mcp.ts +11 -1
- package/packages/core/src/messenger.ts +143 -86
- package/packages/core/src/metrics.ts +13 -0
- package/packages/core/src/middleware.ts +1181 -1097
- package/packages/core/src/mqtt.ts +8 -0
- package/packages/core/src/mqttMessage.ts +8 -0
- package/packages/core/src/optionalPackage.ts +48 -0
- package/packages/core/src/plan.ts +8 -0
- package/packages/core/src/portTakeover.ts +8 -0
- package/packages/core/src/projectIndex.ts +8 -0
- package/packages/core/src/projectIndexExtractors.ts +8 -0
- package/packages/core/src/projectIndexStorage.ts +8 -0
- package/packages/core/src/push.ts +24 -0
- package/packages/core/src/queue.ts +23 -2
- package/packages/core/src/queueBackends/kafkaBackend.ts +8 -0
- package/packages/core/src/queueBackends/liteBackend.ts +23 -0
- package/packages/core/src/queueBackends/mongoBackend.ts +61 -14
- package/packages/core/src/queueBackends/rabbitmqBackend.ts +8 -0
- package/packages/core/src/rateLimiter.ts +8 -0
- package/packages/core/src/request.ts +59 -10
- package/packages/core/src/response.ts +79 -5
- package/packages/core/src/routeDiscovery.ts +8 -0
- package/packages/core/src/router.ts +8 -0
- package/packages/core/src/server.ts +79 -25
- package/packages/core/src/service.ts +8 -0
- package/packages/core/src/session.ts +8 -0
- package/packages/core/src/sessionHandlers/childError.ts +8 -0
- package/packages/core/src/sessionHandlers/databaseHandler.ts +68 -3
- package/packages/core/src/sessionHandlers/memcachedHandler.ts +8 -0
- package/packages/core/src/sessionHandlers/mongoClient.ts +8 -0
- package/packages/core/src/sessionHandlers/mongoHandler.ts +8 -0
- package/packages/core/src/sessionHandlers/respClient.ts +8 -0
- package/packages/core/src/sessionHandlers/sqlClient.ts +8 -0
- package/packages/core/src/sessionHandlers/syncBridge.ts +8 -0
- package/packages/core/src/sessionHandlers/syncSocket.ts +8 -0
- package/packages/core/src/sessionHandlers/valkeyHandler.ts +8 -0
- package/packages/core/src/sso.ts +20 -4
- package/packages/core/src/ssoIdentity.ts +19 -0
- package/packages/core/src/ssrf.ts +221 -0
- package/packages/core/src/static.ts +8 -0
- package/packages/core/src/test.ts +8 -0
- package/packages/core/src/testClient.ts +11 -0
- package/packages/core/src/testing.ts +8 -0
- package/packages/core/src/transport.ts +369 -0
- package/packages/core/src/trustedProxy.ts +8 -0
- package/packages/core/src/types.ts +13 -0
- package/packages/core/src/validator.ts +8 -0
- package/packages/core/src/version.ts +8 -0
- package/packages/core/src/websocket.ts +12 -2
- package/packages/core/src/websocketBackplane.ts +49 -32
- package/packages/core/src/websocketConnection.ts +8 -0
- package/packages/core/src/wsdl.ts +197 -115
- package/packages/core/templates/errors/302.twig +8 -0
- package/packages/core/templates/errors/401.twig +8 -0
- package/packages/core/templates/errors/403.twig +8 -0
- package/packages/core/templates/errors/404.twig +8 -0
- package/packages/core/templates/errors/500.twig +8 -0
- package/packages/core/templates/errors/502.twig +8 -0
- package/packages/core/templates/errors/503.twig +8 -0
- package/packages/core/templates/errors/base.twig +8 -0
- package/packages/frond/dist/index.js +157 -17
- package/packages/frond/src/engine.ts +186 -17
- package/packages/frond/src/index.ts +8 -0
- package/packages/orm/dist/index.js +8641 -6765
- package/packages/orm/src/adapters/firebird.ts +50 -3
- package/packages/orm/src/adapters/mongodb.ts +8 -0
- package/packages/orm/src/adapters/mssql.ts +29 -7
- package/packages/orm/src/adapters/mysql.ts +17 -1
- package/packages/orm/src/adapters/odbc.ts +11 -0
- package/packages/orm/src/adapters/pg-types.d.ts +8 -0
- package/packages/orm/src/adapters/postgres.ts +34 -8
- package/packages/orm/src/adapters/sqlDialect.ts +57 -0
- package/packages/orm/src/adapters/sqlite.ts +26 -0
- package/packages/orm/src/autoCrud.ts +78 -36
- package/packages/orm/src/baseModel.ts +61 -29
- package/packages/orm/src/cachedDatabase.ts +67 -1
- package/packages/orm/src/connectTimeout.ts +8 -0
- package/packages/orm/src/database.ts +649 -401
- package/packages/orm/src/databaseResult.ts +8 -0
- package/packages/orm/src/databaseUrl.ts +8 -0
- package/packages/orm/src/docstore.ts +23 -1
- package/packages/orm/src/fakeData.ts +8 -0
- package/packages/orm/src/graph/adapters/arango.ts +8 -0
- package/packages/orm/src/graph/adapters/bolt.ts +8 -0
- package/packages/orm/src/graph/adapters/ultipa.ts +8 -0
- package/packages/orm/src/graph/connectTimeout.ts +8 -0
- package/packages/orm/src/graph/errors.ts +8 -0
- package/packages/orm/src/graph/graphAdapter.ts +8 -0
- package/packages/orm/src/graph/graphDatabase.ts +8 -0
- package/packages/orm/src/graph/graphUrl.ts +10 -1
- package/packages/orm/src/graph/shapes.ts +8 -0
- package/packages/orm/src/index.ts +147 -139
- package/packages/orm/src/migration.ts +8 -0
- package/packages/orm/src/model.ts +8 -0
- package/packages/orm/src/modelCollection.ts +8 -0
- package/packages/orm/src/point.ts +8 -0
- package/packages/orm/src/query.ts +149 -33
- package/packages/orm/src/queryBuilder.ts +8 -0
- package/packages/orm/src/realtime/index.ts +8 -0
- package/packages/orm/src/realtime/models/attachment.ts +8 -0
- package/packages/orm/src/realtime/models/channel.ts +8 -0
- package/packages/orm/src/realtime/models/channelMember.ts +8 -0
- package/packages/orm/src/realtime/models/message.ts +8 -0
- package/packages/orm/src/realtime/models/workspace.ts +8 -0
- package/packages/orm/src/realtime/realtime.ts +8 -0
- package/packages/orm/src/realtime/storage.ts +43 -12
- package/packages/orm/src/seeder.ts +8 -0
- package/packages/orm/src/seederTable.ts +8 -0
- package/packages/orm/src/seederTypes.ts +8 -0
- package/packages/orm/src/sqlTranslator.ts +185 -8
- package/packages/orm/src/types.ts +15 -0
- package/packages/orm/src/validation.ts +8 -0
- package/packages/swagger/src/generator.ts +8 -0
- package/packages/swagger/src/index.ts +8 -0
- package/packages/swagger/src/ui.ts +8 -0
- package/types/core/src/api.d.ts +6 -0
- package/types/core/src/auth.d.ts +30 -0
- package/types/core/src/background.d.ts +0 -16
- package/types/core/src/cache.d.ts +6 -0
- package/types/core/src/devAdmin.d.ts +18 -12
- package/types/core/src/docs.d.ts +0 -17
- package/types/core/src/errorOverlay.d.ts +0 -24
- package/types/core/src/events.d.ts +0 -12
- package/types/core/src/feedback.d.ts +0 -23
- package/types/core/src/graphql.d.ts +25 -21
- package/types/core/src/htmlElement.d.ts +0 -15
- package/types/core/src/index.d.ts +1 -0
- package/types/core/src/job.d.ts +1 -0
- package/types/core/src/messenger.d.ts +12 -1
- package/types/core/src/metrics.d.ts +2 -0
- package/types/core/src/middleware.d.ts +45 -1
- package/types/core/src/mqtt.d.ts +0 -33
- package/types/core/src/optionalPackage.d.ts +25 -0
- package/types/core/src/plan.d.ts +0 -10
- package/types/core/src/projectIndex.d.ts +0 -10
- package/types/core/src/push.d.ts +5 -0
- package/types/core/src/queue.d.ts +7 -1
- package/types/core/src/queueBackends/liteBackend.d.ts +9 -0
- package/types/core/src/queueBackends/mongoBackend.d.ts +10 -1
- package/types/core/src/request.d.ts +12 -0
- package/types/core/src/response.d.ts +13 -0
- package/types/core/src/server.d.ts +19 -0
- package/types/core/src/sessionHandlers/childError.d.ts +0 -15
- package/types/core/src/sessionHandlers/databaseHandler.d.ts +25 -1
- package/types/core/src/sso.d.ts +1 -0
- package/types/core/src/ssoIdentity.d.ts +10 -0
- package/types/core/src/ssrf.d.ts +19 -0
- package/types/core/src/transport.d.ts +28 -0
- package/types/core/src/trustedProxy.d.ts +0 -16
- package/types/core/src/types.d.ts +5 -0
- package/types/core/src/websocketBackplane.d.ts +1 -0
- package/types/core/src/wsdl.d.ts +8 -22
- package/types/frond/src/engine.d.ts +7 -1
- package/types/orm/src/adapters/firebird.d.ts +12 -0
- package/types/orm/src/adapters/mssql.d.ts +11 -0
- package/types/orm/src/adapters/mysql.d.ts +2 -0
- package/types/orm/src/adapters/postgres.d.ts +11 -0
- package/types/orm/src/adapters/sqlDialect.d.ts +25 -0
- package/types/orm/src/adapters/sqlite.d.ts +7 -0
- package/types/orm/src/baseModel.d.ts +5 -0
- package/types/orm/src/cachedDatabase.d.ts +27 -0
- package/types/orm/src/database.d.ts +46 -7
- package/types/orm/src/graph/graphUrl.d.ts +0 -8
- package/types/orm/src/index.d.ts +1 -1
- package/types/orm/src/query.d.ts +48 -2
- package/types/orm/src/realtime/storage.d.ts +2 -1
- package/types/orm/src/sqlTranslator.d.ts +70 -18
- package/types/orm/src/types.d.ts +6 -0
|
@@ -38,6 +38,17 @@ export declare class PostgresAdapter implements DatabaseAdapter {
|
|
|
38
38
|
/** Ensure bytea columns are Buffer (already the case with pg). No-op guard. */
|
|
39
39
|
private decodeBlobs;
|
|
40
40
|
private convertPlaceholders;
|
|
41
|
+
/**
|
|
42
|
+
* The SQL the driver receives. With NO parameters it is sent EXACTLY as
|
|
43
|
+
* written (the cross-framework contract): there is nothing to bind, and the
|
|
44
|
+
* rewrite would turn PostgreSQL's jsonb operators `?`, `?|` and `?&` into
|
|
45
|
+
* unbound markers.
|
|
46
|
+
*
|
|
47
|
+
* tina4: with parameters every `?` outside a literal, quoted identifier or
|
|
48
|
+
* comment is a placeholder - use jsonb_exists(), jsonb_exists_any() or
|
|
49
|
+
* jsonb_exists_all() instead of the `?`, `?|` or `?&` operators.
|
|
50
|
+
*/
|
|
51
|
+
private bindable;
|
|
41
52
|
/**
|
|
42
53
|
* Normalise an `id` column value (typed `unknown` because pg row values are
|
|
43
54
|
* `unknown`) into the shape `_lastInsertId` / `DatabaseResult.lastId`
|
|
@@ -29,6 +29,21 @@ export interface Dialect {
|
|
|
29
29
|
*/
|
|
30
30
|
marker(index: number): string;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Quote a table/column name the ORM emits, in one engine's identifier quotes.
|
|
34
|
+
*
|
|
35
|
+
* Port of the Python master's `quote_identifier` (adapter.py; Firebird's
|
|
36
|
+
* override upper-cases): idempotent (an already-quoted name is returned
|
|
37
|
+
* unchanged), dot-aware (`schema.table` quotes each part), and a non-identifier
|
|
38
|
+
* (`*`, `COUNT(*)`, an expression) is passed through untouched. An embedded
|
|
39
|
+
* closing quote is doubled.
|
|
40
|
+
*
|
|
41
|
+
* `upperCase` is Firebird's rule: an unquoted identifier is stored UPPER CASE,
|
|
42
|
+
* so a lower-case name must be quoted upper-case to match it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function quoteIdentifierWith(name: string, open: string, close: string, upperCase?: boolean): string;
|
|
45
|
+
/** The ANSI default: `"name"` (SQLite, PostgreSQL, MSSQL, ODBC). */
|
|
46
|
+
export declare function quoteIdentifierAnsi(name: string): string;
|
|
32
47
|
/** SQLite, and ODBC which follows the SQL standard spelling. */
|
|
33
48
|
export declare const ANSI_DIALECT: Dialect;
|
|
34
49
|
/** PostgreSQL: standard quoting, positional $N markers. */
|
|
@@ -43,6 +58,16 @@ export declare const MSSQL_DIALECT: Dialect;
|
|
|
43
58
|
* adapter owns that rule and passes its own quoter in.
|
|
44
59
|
*/
|
|
45
60
|
export declare function firebirdDialect(fbQuote: (name: string) => string): Dialect;
|
|
61
|
+
/**
|
|
62
|
+
* Refuse a data or filter-map key that is not a plain identifier.
|
|
63
|
+
*
|
|
64
|
+
* tina4: ADR-0069 (G3) - the write helpers emit these keys as column names, and
|
|
65
|
+
* the dialect quoters do not escape, so a key must be a plain identifier
|
|
66
|
+
* (letters, digits, underscore, dollar; not starting with a digit) before any
|
|
67
|
+
* SQL is built. Valid names are emitted exactly as before. Table names are
|
|
68
|
+
* developer code and are not checked here.
|
|
69
|
+
*/
|
|
70
|
+
export declare function assertColumnNames(keys: Iterable<string>): void;
|
|
46
71
|
/**
|
|
47
72
|
* `INSERT INTO <table> (<cols>) VALUES (<markers>)`.
|
|
48
73
|
*
|
|
@@ -36,6 +36,13 @@ export declare class SQLiteAdapter implements DatabaseAdapter {
|
|
|
36
36
|
execute(sql: string, params?: unknown[]): unknown;
|
|
37
37
|
executeMany(sql: string, paramsList: unknown[][]): DatabaseResult;
|
|
38
38
|
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
|
|
39
|
+
/**
|
|
40
|
+
* Run a row-producing statement ONCE and return its rows, for
|
|
41
|
+
* Database.execute(). execute()'s run() discards rows, so a SELECT or an
|
|
42
|
+
* `INSERT ... RETURNING` through execute() used to lose them. A write still
|
|
43
|
+
* records its last insert id, exactly as execute() does.
|
|
44
|
+
*/
|
|
45
|
+
executeRows<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
|
|
39
46
|
fetch<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, skip?: number): T[];
|
|
40
47
|
fetchOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): T | null;
|
|
41
48
|
insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): DatabaseResult;
|
|
@@ -112,6 +112,11 @@ export declare class BaseModel {
|
|
|
112
112
|
* SQLite URLs are initialised synchronously. Other engines require initDatabase()
|
|
113
113
|
* to be called before first use.
|
|
114
114
|
*/
|
|
115
|
+
/**
|
|
116
|
+
* Quote a table/column name in the dialect of the adapter this model runs on
|
|
117
|
+
* (MySQL backticks, Firebird upper-cased, `"name"` elsewhere).
|
|
118
|
+
*/
|
|
119
|
+
protected static quoteName(name: string): string;
|
|
115
120
|
protected static getDb(): DatabaseAdapter;
|
|
116
121
|
/**
|
|
117
122
|
* Get the primary key field name (JS property name).
|
|
@@ -144,10 +144,31 @@ export declare class CachedDatabaseAdapter implements DatabaseAdapter {
|
|
|
144
144
|
private backendSetRows;
|
|
145
145
|
private backendGetOne;
|
|
146
146
|
private backendSetOne;
|
|
147
|
+
/**
|
|
148
|
+
* A write that arrives through a READ method (fetch/fetchOne/query of an
|
|
149
|
+
* `INSERT ... RETURNING`) is still a write: its result must never be cached
|
|
150
|
+
* (a repeat would answer from the cache and never insert) and it flushes the
|
|
151
|
+
* cache like every other write (tina4-python#133 contract).
|
|
152
|
+
*/
|
|
153
|
+
private isWriteRead;
|
|
154
|
+
/** Run a write that came through a read method, then flush (never store). */
|
|
155
|
+
private runWrite;
|
|
156
|
+
private runWriteAsync;
|
|
147
157
|
/** ADR-0044 required capability — delegates to the wrapped adapter. */
|
|
148
158
|
connect(): void | Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* The derived-table alias the COUNT probe needs, forwarded from the wrapped
|
|
161
|
+
* adapter. SQL Server and MySQL REQUIRE `FROM (<sql>) AS _count_query`; the
|
|
162
|
+
* probe reads this property off whatever adapter it is handed, and
|
|
163
|
+
* Database.create() hands it THIS wrapper. Without the forward the probe ran
|
|
164
|
+
* unaliased, the engine rejected it, the error was swallowed, and
|
|
165
|
+
* `result.count` silently became the page length on those two engines.
|
|
166
|
+
*/
|
|
167
|
+
get countSubqueryAlias(): string | undefined;
|
|
149
168
|
/** ADR-0044 required capability — delegates to the wrapped adapter. */
|
|
150
169
|
getDatabaseType(): string;
|
|
170
|
+
/** Identifier quoting is the wrapped engine's, never the wrapper's. */
|
|
171
|
+
quoteIdentifier(name: string): string;
|
|
151
172
|
/**
|
|
152
173
|
* ADR-0044 required capability — a native boolean, readable and writable.
|
|
153
174
|
* A getter/setter pair (not a plain field) so it genuinely delegates to the
|
|
@@ -158,6 +179,12 @@ export declare class CachedDatabaseAdapter implements DatabaseAdapter {
|
|
|
158
179
|
get supportsAtomicBatch(): boolean;
|
|
159
180
|
set supportsAtomicBatch(value: boolean);
|
|
160
181
|
execute(sql: string, params?: unknown[]): unknown;
|
|
182
|
+
/**
|
|
183
|
+
* Forward an adapter's row-returning execute (SQLite, Firebird), for
|
|
184
|
+
* Database.execute(). Resolves `undefined` when the wrapped adapter has none
|
|
185
|
+
* - WITHOUT running anything - so the caller falls back to execute().
|
|
186
|
+
*/
|
|
187
|
+
executeRowsAsync(sql: string, params?: unknown[]): Promise<unknown[] | undefined>;
|
|
161
188
|
executeMany(sql: string, paramsList: unknown[][]): import("./types.js").DatabaseResult | {
|
|
162
189
|
totalAffected: number;
|
|
163
190
|
lastId?: number | bigint;
|
|
@@ -28,8 +28,27 @@ export declare function stripTrailingSemicolons(sql: string): string;
|
|
|
28
28
|
* the single chokepoint every public read/write flows through.
|
|
29
29
|
*/
|
|
30
30
|
export declare function adapterFetch<T = Record<string, unknown>>(adapter: DatabaseAdapter, sql: string, params?: unknown[], limit?: number, skip?: number, noCache?: boolean): Promise<T[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Quote a table/column name the ORM emits, in the bound adapter's dialect
|
|
33
|
+
* (MySQL backticks, Firebird upper-cased, `"name"` elsewhere). Python master:
|
|
34
|
+
* `Database.quote_identifier`. Only for framework-emitted identifiers - a
|
|
35
|
+
* user's raw SQL is never rewritten.
|
|
36
|
+
*/
|
|
37
|
+
export declare function quoteIdentifier(adapter: DatabaseAdapter | null | undefined, name: string): string;
|
|
31
38
|
export declare function adapterQuery<T = Record<string, unknown>>(adapter: DatabaseAdapter, sql: string, params?: unknown[]): Promise<T[]>;
|
|
32
39
|
export declare function adapterFetchOne<T = Record<string, unknown>>(adapter: DatabaseAdapter, sql: string, params?: unknown[]): Promise<T | null>;
|
|
40
|
+
/**
|
|
41
|
+
* Run a row-producing statement through an adapter's own row-returning execute
|
|
42
|
+
* (SQLite's executeRows, Firebird's executeRowsAsync, or the cache wrapper
|
|
43
|
+
* forwarding either). `undefined` means the adapter has none and NOTHING ran.
|
|
44
|
+
*/
|
|
45
|
+
export declare function adapterExecuteRows(adapter: DatabaseAdapter, sql: string, params?: unknown[]): Promise<unknown[] | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* The rows inside a driver's execute() result: pg and tedious carry `.rows`,
|
|
48
|
+
* mysql2 and odbc return the row array itself, and a MySQL CALL returns
|
|
49
|
+
* `[[rows], OkPacket]`. `undefined` when the result carries no row list.
|
|
50
|
+
*/
|
|
51
|
+
export declare function rowsFromExecuteResult(result: unknown): unknown[] | undefined;
|
|
33
52
|
export declare function adapterExecute(adapter: DatabaseAdapter, sql: string, params?: unknown[]): Promise<unknown>;
|
|
34
53
|
/**
|
|
35
54
|
* ADR-0044: the adapter-level batch primitive, called exactly once by
|
|
@@ -277,6 +296,11 @@ export declare class Database {
|
|
|
277
296
|
* the same Database don't clobber each other. startTransaction() sets the
|
|
278
297
|
* pin via .enterWith(); commit()/rollback() clear it.
|
|
279
298
|
*/
|
|
299
|
+
private leases;
|
|
300
|
+
private discardedSlots;
|
|
301
|
+
private repairs;
|
|
302
|
+
private leaseOwner;
|
|
303
|
+
private operationStore;
|
|
280
304
|
private txStore;
|
|
281
305
|
/**
|
|
282
306
|
* Create a Database wrapping an existing adapter.
|
|
@@ -317,8 +341,13 @@ export declare class Database {
|
|
|
317
341
|
* that adapter is returned for every call so the whole transaction is
|
|
318
342
|
* atomic on one connection. Otherwise pooled mode round-robins.
|
|
319
343
|
*/
|
|
344
|
+
private availableAdapter;
|
|
345
|
+
private reserveAdapter;
|
|
346
|
+
private releaseAdapter;
|
|
347
|
+
private repairDiscardedConnections;
|
|
348
|
+
private withConnectionOperation;
|
|
320
349
|
private getNextAdapter;
|
|
321
|
-
/**
|
|
350
|
+
/** Non-owning peek excluding leased connections. Use checkout/checkin for concurrent raw driver work. */
|
|
322
351
|
getAdapter(): DatabaseAdapter;
|
|
323
352
|
/** Get the pool size (0 = single connection mode). */
|
|
324
353
|
poolSize(): number;
|
|
@@ -331,12 +360,8 @@ export declare class Database {
|
|
|
331
360
|
* The caller is responsible for returning it via checkin().
|
|
332
361
|
*/
|
|
333
362
|
checkout(): DatabaseAdapter;
|
|
334
|
-
/**
|
|
335
|
-
|
|
336
|
-
* For round-robin pools this is a no-op (connections stay in the pool array),
|
|
337
|
-
* but the method exists for API parity and future pooling strategies.
|
|
338
|
-
*/
|
|
339
|
-
checkin(_adapter: DatabaseAdapter): void;
|
|
363
|
+
/** Only the borrowing async context can release an explicit lease. */
|
|
364
|
+
checkin(adapter: DatabaseAdapter): void;
|
|
340
365
|
/**
|
|
341
366
|
* Close all pooled connections and clear the pool.
|
|
342
367
|
* Equivalent to close() but named for explicit pool teardown.
|
|
@@ -405,6 +430,12 @@ export declare class Database {
|
|
|
405
430
|
fetchAll<T = Record<string, unknown>>(sql: string, params?: unknown[], limit?: number, offset?: number, opts?: {
|
|
406
431
|
noCache?: boolean;
|
|
407
432
|
}): Promise<T[]>;
|
|
433
|
+
/**
|
|
434
|
+
* Close a write that ran through fetch()/fetchOne() the way execute() closes
|
|
435
|
+
* its own: auto-commit outside an explicit transaction, and leave it to the
|
|
436
|
+
* caller's commit()/rollback() inside one.
|
|
437
|
+
*/
|
|
438
|
+
private commitFetchWrite;
|
|
408
439
|
/**
|
|
409
440
|
* Execute a write statement.
|
|
410
441
|
*
|
|
@@ -459,6 +490,14 @@ export declare class Database {
|
|
|
459
490
|
* throws rather than silently changing nothing (audit feature 4, P1).
|
|
460
491
|
*/
|
|
461
492
|
update(table: string, data: Record<string, unknown>, filter?: Record<string, unknown> | string, params?: unknown[]): Promise<DatabaseWriteResult>;
|
|
493
|
+
/**
|
|
494
|
+
* ADR-0069 (G3): a data or filter-map key must be a plain identifier - it is
|
|
495
|
+
* emitted as a column name. Checked here, before any adapter work, so every
|
|
496
|
+
* engine raises the same error; the SQL builders (sqlDialect) check again for
|
|
497
|
+
* callers that use an adapter directly. MongoDB builds no SQL and its keys are
|
|
498
|
+
* document paths, so it is left alone.
|
|
499
|
+
*/
|
|
500
|
+
private assertWriteKeys;
|
|
462
501
|
/** Delete rows. A filterless delete throws; use truncate() to empty a table. */
|
|
463
502
|
delete(table: string, filter?: Record<string, unknown> | string | Record<string, unknown>[], params?: unknown[]): Promise<DatabaseWriteResult>;
|
|
464
503
|
/** Remove every row. The explicit spelling of a whole-table delete. */
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Graph connection URL parser — the DatabaseUrl sibling for graph engines.
|
|
3
|
-
*
|
|
4
|
-
* Parse a graph connection URL into its parts, the same way DatabaseUrl does for
|
|
5
|
-
* SQL. `engine` is the CANONICAL name the factory selects an adapter by; a scheme
|
|
6
|
-
* alias (bolt/neo4j/memgraph all speak Bolt/Cypher and share ONE adapter) resolves
|
|
7
|
-
* to its engine here. See tina4-documentation/plan/v3/features/139-graph-databases.md.
|
|
8
|
-
*/
|
|
9
1
|
/** The canonical graph engine names. */
|
|
10
2
|
export type GraphEngine = "ultipa" | "bolt" | "arango";
|
|
11
3
|
/** A parsed graph URL: engine, host, port, graph, credentials, params. */
|
package/types/orm/src/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { syncModels, ensureMigrationTable, getNextBatch, isMigrationApplied, rec
|
|
|
15
15
|
export type { MigrationResult, MigrationStatus } from "./migration.js";
|
|
16
16
|
export { AutoCrud, generateCrudRoutes, crudEligibleModels } from "./autoCrud.js";
|
|
17
17
|
export type { AutoCrudOptions } from "./autoCrud.js";
|
|
18
|
-
export { buildQuery, parseQueryString } from "./query.js";
|
|
18
|
+
export { buildQuery, parseQueryString, UnknownFieldError, InvalidQueryParameterError } from "./query.js";
|
|
19
19
|
export { validate } from "./validation.js";
|
|
20
20
|
export type { ValidationError } from "./validation.js";
|
|
21
21
|
export { BaseModel, snakeToCamel, camelToSnake } from "./baseModel.js";
|
package/types/orm/src/query.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QueryOptions } from "./types.js";
|
|
1
|
+
import type { FieldDefinition, QueryOptions } from "./types.js";
|
|
2
2
|
export interface ParsedQuery {
|
|
3
3
|
where: string;
|
|
4
4
|
orderBy: string;
|
|
@@ -6,12 +6,58 @@ export interface ParsedQuery {
|
|
|
6
6
|
offset: number;
|
|
7
7
|
params: unknown[];
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a caller-supplied key to the model's DB column, or null when the key
|
|
11
|
+
* is not a declared field.
|
|
12
|
+
*
|
|
13
|
+
* tina4: ADR-0069 - identifiers that reach SQL come from the model, never the
|
|
14
|
+
* request. The key may be a declared field (property) name or that field's
|
|
15
|
+
* column name; either way the column returned is the model's own, so nothing
|
|
16
|
+
* but a declared column can be emitted. `columnOf` is the caller's existing
|
|
17
|
+
* property->column mapping (BaseModel.getDbColumn / AutoCrud's getDbCol), so
|
|
18
|
+
* the mapping rule lives in one place. Own keys only, so an inherited Object
|
|
19
|
+
* property can never resolve. Used by AutoCrud (filter + sort) and by
|
|
20
|
+
* BaseModel.find(object).
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveFieldColumn(fields: Record<string, FieldDefinition>, columnOf: (field: string) => string, key: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* The declared FIELD (property) name a key names - by the field name itself or
|
|
25
|
+
* by its column - or null. The write-side twin of resolveFieldColumn(): AutoCrud
|
|
26
|
+
* writes need the field, to validate the body and then map it to its column.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveField(fields: Record<string, FieldDefinition>, columnOf: (field: string) => string, key: string): string | null;
|
|
29
|
+
/** A filter or sort key that does not resolve to a declared model field. */
|
|
30
|
+
export declare class UnknownFieldError extends Error {
|
|
31
|
+
readonly kind: "filter" | "sort";
|
|
32
|
+
readonly field: string;
|
|
33
|
+
constructor(kind: "filter" | "sort", field: string);
|
|
34
|
+
}
|
|
35
|
+
/** A query parameter whose SHAPE is wrong (a list or map where one value belongs). */
|
|
36
|
+
export declare class InvalidQueryParameterError extends Error {
|
|
37
|
+
constructor(message: string);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build the list SQL from parsed query options.
|
|
41
|
+
*
|
|
42
|
+
* `quote` renders every table/column name the builder emits - pass the bound
|
|
43
|
+
* adapter's dialect (`(name) => quoteIdentifier(adapter, name)`); the default is
|
|
44
|
+
* the ANSI `"name"`.
|
|
45
|
+
*
|
|
46
|
+
* Every filter key and sort field is passed through `resolveColumn` (see
|
|
47
|
+
* resolveFieldColumn) and only the column it returns is emitted; a key it does
|
|
48
|
+
* not resolve throws UnknownFieldError before any SQL exists. With no
|
|
49
|
+
* resolver, no filter or sort key resolves (ADR-0069).
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildQuery(tableName: string, options: QueryOptions, extraConditions?: string[], quote?: (name: string) => string, resolveColumn?: (key: string) => string | null): {
|
|
10
52
|
sql: string;
|
|
11
53
|
countSql: string;
|
|
12
54
|
params: unknown[];
|
|
13
55
|
limit: number;
|
|
14
56
|
offset: number;
|
|
15
57
|
page: number;
|
|
58
|
+
/** The same SELECT without LIMIT/OFFSET, for adapterFetch to page in the engine's own syntax. */
|
|
59
|
+
pageSql: string;
|
|
60
|
+
/** The filter parameters alone (params minus the trailing limit/offset). */
|
|
61
|
+
filterParams: unknown[];
|
|
16
62
|
};
|
|
17
63
|
export declare function parseQueryString(query: Record<string, string>): QueryOptions;
|
|
@@ -33,7 +33,8 @@ export declare class LocalStorage implements StorageBackend {
|
|
|
33
33
|
exists(key: string): boolean;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* S3-compatible store (AWS S3, MinIO, ...). Opt-in;
|
|
36
|
+
* S3-compatible store (AWS S3, MinIO, ...). Opt-in; the app installs the SDK:
|
|
37
|
+
* `npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner`.
|
|
37
38
|
* Presigned GET URLs let clients fetch large blobs straight from object
|
|
38
39
|
* storage instead of streaming through the app.
|
|
39
40
|
*/
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tina4 SQL Translation — Cross-engine SQL translator.
|
|
3
|
-
*
|
|
4
|
-
* Translates SQL dialect differences between engines so that application
|
|
5
|
-
* code can use a single SQL style and have it adapted at runtime.
|
|
6
|
-
*
|
|
7
|
-
* import { SQLTranslator } from "@tina4/orm";
|
|
8
|
-
*
|
|
9
|
-
* // Firebird: LIMIT/OFFSET → ROWS X TO Y
|
|
10
|
-
* SQLTranslator.limitToRows("SELECT * FROM users LIMIT 10 OFFSET 5");
|
|
11
|
-
* // → "SELECT * FROM users ROWS 6 TO 15"
|
|
12
|
-
*
|
|
13
|
-
* // MSSQL: LIMIT → TOP N
|
|
14
|
-
* SQLTranslator.limitToTop("SELECT * FROM users LIMIT 10");
|
|
15
|
-
* // → "SELECT TOP 10 * FROM users"
|
|
16
|
-
*
|
|
17
|
-
* Also includes a query cache with TTL support.
|
|
18
|
-
*/
|
|
19
1
|
export declare class SQLTranslator {
|
|
20
2
|
private static readonly SPATIAL_ENGINES;
|
|
21
3
|
private static readonly SPATIAL_IDENTIFIER;
|
|
@@ -101,6 +83,29 @@ export declare class SQLTranslator {
|
|
|
101
83
|
* ? → :1, :2, :3 (Oracle, Firebird)
|
|
102
84
|
*/
|
|
103
85
|
static placeholderStyle(sql: string, style: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Offsets of the REAL `?` placeholders in a statement: every `?` that is not
|
|
88
|
+
* inside a string literal ('...', Postgres E'...', dollar-quoted $$...$$ /
|
|
89
|
+
* $tag$...$tag$), a quoted identifier ("..." or `...`), or a comment (-- to
|
|
90
|
+
* end of line, /* ... *\/). A plain text replace turned the `?` in
|
|
91
|
+
* `SELECT 'why?' AS v, ? AS n` into a placeholder and shifted every binding
|
|
92
|
+
* after it (tina4-python#138).
|
|
93
|
+
*
|
|
94
|
+
* @param sql Raw SQL, exactly as the caller wrote it.
|
|
95
|
+
* @param options.backslashEscapes Treat `\` as an escape inside '...' and
|
|
96
|
+
* "..." as well (MySQL's default string syntax). E'...' always does.
|
|
97
|
+
*/
|
|
98
|
+
static placeholderPositions(sql: string, options?: {
|
|
99
|
+
backslashEscapes?: boolean;
|
|
100
|
+
}): number[];
|
|
101
|
+
/**
|
|
102
|
+
* Replace each REAL `?` placeholder (see placeholderPositions) with
|
|
103
|
+
* `marker(index)`, index counting from 0. Literals, quoted identifiers and
|
|
104
|
+
* comments are copied through untouched.
|
|
105
|
+
*/
|
|
106
|
+
static replacePlaceholders(sql: string, marker: (index: number) => string, options?: {
|
|
107
|
+
backslashEscapes?: boolean;
|
|
108
|
+
}): string;
|
|
104
109
|
/**
|
|
105
110
|
* Detect and strip RETURNING clause from INSERT/UPDATE statements.
|
|
106
111
|
* Returns the cleaned SQL and the list of RETURNING columns.
|
|
@@ -204,6 +209,53 @@ export declare class SQLTranslator {
|
|
|
204
209
|
* @param sql Raw SQL; literals and comments are scrubbed before matching.
|
|
205
210
|
*/
|
|
206
211
|
static hasTrailingLimit(sql: string): boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Strip a trailing TOP-LEVEL `ORDER BY` so the statement can be wrapped in
|
|
214
|
+
* `SELECT COUNT(*) FROM (<sql>) AS _count_query` for the row-count probe.
|
|
215
|
+
*
|
|
216
|
+
* SQL Server rejects an ORDER BY inside a derived table unless it carries
|
|
217
|
+
* TOP/OFFSET/FETCH (error 1033), so the probe failed - and the total fell
|
|
218
|
+
* back to the page length - for any read ending in ORDER BY. ORDER BY cannot
|
|
219
|
+
* change a COUNT, so dropping it for the probe ONLY is safe; the paginated
|
|
220
|
+
* query keeps it. An ORDER BY nested in a subquery, or one already legalised
|
|
221
|
+
* by a following OFFSET/FETCH/FOR, is left intact. Positions are found on the
|
|
222
|
+
* scrubbed text, so an `ORDER BY` inside a literal or comment is ignored.
|
|
223
|
+
* Parity with Python `_strip_trailing_order_by` / PHP `stripTrailingOrderBy`.
|
|
224
|
+
*
|
|
225
|
+
* @param sql The read statement the probe is about to wrap.
|
|
226
|
+
*/
|
|
227
|
+
static stripTrailingOrderBy(sql: string): string;
|
|
228
|
+
/**
|
|
229
|
+
* True when the statement CHANGES data, even though it may return rows.
|
|
230
|
+
*
|
|
231
|
+
* fetch()/fetchOne() are the natural way to run a write that RETURNS rows
|
|
232
|
+
* (`INSERT ... RETURNING id`, SQL Server's `OUTPUT inserted.id`), so they
|
|
233
|
+
* cannot treat every statement as a read (tina4-python#133). A write is one
|
|
234
|
+
* whose first word is a DML verb, or a `WITH` whose body holds one (a
|
|
235
|
+
* data-modifying CTE ends in SELECT). The shared cross-framework contract:
|
|
236
|
+
* a write through fetch/fetchOne runs exactly once, with no COUNT probe and
|
|
237
|
+
* no LIMIT/OFFSET/ROWS/TOP pagination, is never cached, and commits like
|
|
238
|
+
* execute(). Python's `_is_write_statement` answers identically.
|
|
239
|
+
*
|
|
240
|
+
* Literals and comments are scrubbed first, so `WHERE note = 'DELETE'` stays
|
|
241
|
+
* a read. Erring towards "write" is the safe direction: a read misread as a
|
|
242
|
+
* write only loses its pagination and cache for that one call.
|
|
243
|
+
*
|
|
244
|
+
* @param sql Raw SQL, exactly as the caller wrote it.
|
|
245
|
+
*/
|
|
246
|
+
static isWriteStatement(sql: string): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Which kind of rows a statement produces, for execute() (cross-framework
|
|
249
|
+
* contract): "read" (SELECT, WITH ... SELECT, VALUES, SHOW, EXPLAIN,
|
|
250
|
+
* DESCRIBE), "returning" (a write with RETURNING, or SQL Server's OUTPUT
|
|
251
|
+
* inserted./deleted.), "procedure" (CALL / EXEC / EXECUTE, which may return a
|
|
252
|
+
* result set), or null for a statement that produces none. A data-modifying
|
|
253
|
+
* CTE (WITH ... INSERT ... SELECT) produces rows too, so it is "read" here and
|
|
254
|
+
* a write for isWriteStatement(). Literals and comments are scrubbed first.
|
|
255
|
+
*
|
|
256
|
+
* @param sql Raw SQL, exactly as the caller wrote it.
|
|
257
|
+
*/
|
|
258
|
+
static rowsKind(sql: string): "read" | "returning" | "procedure" | null;
|
|
207
259
|
/**
|
|
208
260
|
* Append `LIMIT`/`OFFSET` to a statement unless it already carries its own.
|
|
209
261
|
*
|
package/types/orm/src/types.d.ts
CHANGED
|
@@ -99,6 +99,12 @@ export interface DatabaseAdapter {
|
|
|
99
99
|
connect(): void | Promise<void>;
|
|
100
100
|
/** Return the canonical, credential-free engine name ("sqlite", "postgres", ...). */
|
|
101
101
|
getDatabaseType(): string;
|
|
102
|
+
/**
|
|
103
|
+
* Quote a table/column name the ORM emits, in this engine's dialect
|
|
104
|
+
* (Python master: `quote_identifier`). Optional: an adapter without it gets
|
|
105
|
+
* the ANSI `"name"` default through `quoteIdentifier(adapter, name)`.
|
|
106
|
+
*/
|
|
107
|
+
quoteIdentifier?(name: string): string;
|
|
102
108
|
/** Execute a statement (INSERT, UPDATE, DELETE, DDL). */
|
|
103
109
|
execute(sql: string, params?: unknown[]): unknown;
|
|
104
110
|
/**
|