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
|
@@ -105,7 +105,6 @@ export declare class Messenger {
|
|
|
105
105
|
private fromAddress;
|
|
106
106
|
private fromName;
|
|
107
107
|
private encryption;
|
|
108
|
-
private useTls;
|
|
109
108
|
/** Whether an SMTP host was actually configured (see the constructor). */
|
|
110
109
|
private smtpConfigured;
|
|
111
110
|
/** The local mailbox, present only when this messenger captures. */
|
|
@@ -116,6 +115,13 @@ export declare class Messenger {
|
|
|
116
115
|
private imapPass;
|
|
117
116
|
private imapEncryption;
|
|
118
117
|
constructor(options?: MessengerOptions);
|
|
118
|
+
/**
|
|
119
|
+
* How the SMTP connection is secured (ADR-0071 section 1). Port 465 is the
|
|
120
|
+
* implicit-TLS submission port whatever the setting; `ssl` is implicit TLS on
|
|
121
|
+
* any port; `tls` / `starttls` upgrade with a required STARTTLS; `none` is
|
|
122
|
+
* plaintext on purpose.
|
|
123
|
+
*/
|
|
124
|
+
private smtpTransport;
|
|
119
125
|
/**
|
|
120
126
|
* Read-only IMAP encryption mode for inspection / tests.
|
|
121
127
|
* Returns one of "tls", "starttls", "none", "ssl".
|
|
@@ -142,6 +148,11 @@ export declare class Messenger {
|
|
|
142
148
|
private prepareRecipients;
|
|
143
149
|
private connectSmtpSocket;
|
|
144
150
|
private requireSmtpResponse;
|
|
151
|
+
/**
|
|
152
|
+
* Connect, read the greeting, EHLO, and - for the STARTTLS transport - upgrade.
|
|
153
|
+
* STARTTLS is REQUIRED: when the server does not offer it the session fails
|
|
154
|
+
* here, before AUTH or MAIL FROM is ever sent.
|
|
155
|
+
*/
|
|
145
156
|
private openSmtpSession;
|
|
146
157
|
private authenticateSmtp;
|
|
147
158
|
private sendSmtpEnvelope;
|
|
@@ -3,4 +3,6 @@ export declare class MetricsEngineError extends Error {
|
|
|
3
3
|
}
|
|
4
4
|
export declare function enginePath(): string | null;
|
|
5
5
|
export declare function fullAnalysis(root?: string): Record<string, any>;
|
|
6
|
+
/** The root the last full scan covered ("" before any scan). */
|
|
7
|
+
export declare function metricsScanRoot(): string;
|
|
6
8
|
export declare function fileDetail(filePath: string): Record<string, any>;
|
|
@@ -164,6 +164,8 @@ export interface CorsConfig {
|
|
|
164
164
|
}
|
|
165
165
|
/** Reset the CORS warn-once ledger. Test seam. */
|
|
166
166
|
export declare function resetCorsWarnings(): void;
|
|
167
|
+
/** The reasons warned about so far in this process (bounded by construction). */
|
|
168
|
+
export declare function corsWarningReasons(): string[];
|
|
167
169
|
/**
|
|
168
170
|
* The resolved CORS policy — ONE implementation of the rules.
|
|
169
171
|
*
|
|
@@ -210,9 +212,35 @@ export declare class CorsPolicy {
|
|
|
210
212
|
/**
|
|
211
213
|
* The CORS headers for a request origin. `isPreflight` adds Max-Age, which
|
|
212
214
|
* the Fetch Standard only defines for a preflight response.
|
|
215
|
+
*
|
|
216
|
+
* `sameOrigin` (see isSameOriginRequest) marks a request whose Origin is the
|
|
217
|
+
* request's OWN origin. Browsers send Origin on every same-origin POST/PUT/
|
|
218
|
+
* PATCH/DELETE, and such a request needs no CORS headers at all, so it is not
|
|
219
|
+
* a CORS event: it is never warned about (tina4-python#139). It is handled by
|
|
220
|
+
* the configured policy exactly like any other request - the flag silences a
|
|
221
|
+
* warning and never grants anything, so a spoofed Host gains nothing.
|
|
222
|
+
*
|
|
223
|
+
* A warning never advises '*': it names the one origin the operator could add.
|
|
213
224
|
*/
|
|
214
|
-
headersFor(requestOrigin: string, isPreflight: boolean): Record<string, string>;
|
|
225
|
+
headersFor(requestOrigin: string, isPreflight: boolean, sameOrigin?: boolean): Record<string, string>;
|
|
215
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Is the request SAME-origin: does its Origin equal the request's own origin?
|
|
229
|
+
*
|
|
230
|
+
* The own origin is the request's scheme (first hop of X-Forwarded-Proto, else
|
|
231
|
+
* the native TLS socket) and host (first hop of X-Forwarded-Host, else Host).
|
|
232
|
+
* Both sides go through the WHATWG URL parser, so scheme and host compare
|
|
233
|
+
* case-insensitively and http:80 / https:443 equal the port-less form. An
|
|
234
|
+
* unparseable Origin (including the opaque "null") is never same-origin.
|
|
235
|
+
*
|
|
236
|
+
* Proxy headers are honoured without a trusted-proxy check on purpose: the
|
|
237
|
+
* answer only decides whether a CORS WARNING is logged, never what the policy
|
|
238
|
+
* grants, so a forged header gains the sender nothing.
|
|
239
|
+
*/
|
|
240
|
+
export declare function isSameOriginRequest(req: {
|
|
241
|
+
headers: Record<string, string | string[] | undefined>;
|
|
242
|
+
socket?: unknown;
|
|
243
|
+
}): boolean;
|
|
216
244
|
/**
|
|
217
245
|
* Built-in CORS middleware (function form).
|
|
218
246
|
*
|
|
@@ -302,6 +330,22 @@ export declare class RequestLogger {
|
|
|
302
330
|
* Router.use(SecurityHeadersMiddleware);
|
|
303
331
|
*/
|
|
304
332
|
export declare class SecurityHeadersMiddleware {
|
|
333
|
+
/**
|
|
334
|
+
* Run BEFORE route matching (ADR-0012), so EVERY response gets the headers,
|
|
335
|
+
* not only a matched route's. Static files, the SPA index.html at "/",
|
|
336
|
+
* template pages, 404s and 405s are all answered by the not-found fallback
|
|
337
|
+
* chain, which only the pre-match pass reaches. As a post-match middleware
|
|
338
|
+
* this left an SPA's front door with no CSP and frameable (tina4-python#137).
|
|
339
|
+
* The headers read no route metadata, so nothing is lost by running early.
|
|
340
|
+
*/
|
|
341
|
+
static preMatch: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* The canonical security header set (SECHDR-DEC-01) with its environment
|
|
344
|
+
* overrides, WITHOUT Strict-Transport-Security, which depends on the
|
|
345
|
+
* request's scheme. Also what a transport rejection carries (ADR-0068
|
|
346
|
+
* section 4), written before the scheme is known.
|
|
347
|
+
*/
|
|
348
|
+
static canonicalHeaders(): Record<string, string>;
|
|
305
349
|
static beforeSecurity(req: Tina4Request, res: Tina4Response): [Tina4Request, Tina4Response];
|
|
306
350
|
/** Warn-once ledger for the default-CSP heads-up (per process). */
|
|
307
351
|
private static cspDefaultWarned;
|
package/types/core/src/mqtt.d.ts
CHANGED
|
@@ -1,36 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zero-dependency MQTT 3.1.1 client — the protocol every broker and every IoT
|
|
3
|
-
* device already speaks.
|
|
4
|
-
*
|
|
5
|
-
* Built on Node's `node:net` and `node:tls` stdlib modules only: no npm package,
|
|
6
|
-
* so an app that talks to Mosquitto / EMQX / HiveMQ / AWS IoT adds nothing to its
|
|
7
|
-
* dependency tree. Shaped like the Queue on purpose — publish / subscribe /
|
|
8
|
-
* consume:
|
|
9
|
-
*
|
|
10
|
-
* import { Mqtt } from "@tina4stack/tina4-node";
|
|
11
|
-
*
|
|
12
|
-
* const mqtt = new Mqtt({ url: "mqtt://broker:1883" }); // TINA4_MQTT_URL
|
|
13
|
-
* await mqtt.connect();
|
|
14
|
-
* await mqtt.publish("fleet/meter-42/telemetry", '{"kwh":12.5}', 1);
|
|
15
|
-
*
|
|
16
|
-
* for await (const message of mqtt.consume("fleet/+/telemetry", 1)) {
|
|
17
|
-
* if (message.isDuplicate()) continue; // QoS 1 is at-least-once
|
|
18
|
-
* store(message.topic, message.payload);
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* Environment: TINA4_MQTT_URL (default mqtt://127.0.0.1:1883),
|
|
22
|
-
* TINA4_MQTT_CLIENT_ID, TINA4_MQTT_KEEPALIVE (seconds, default 60),
|
|
23
|
-
* TINA4_MQTT_CA_FILE, TINA4_MQTT_TLS_VERIFY.
|
|
24
|
-
*
|
|
25
|
-
* Node has no synchronous blocking socket read, so connect()/publish()/
|
|
26
|
-
* subscribe()/receive() are async and consume() is an async generator — the same
|
|
27
|
-
* idiom as the Queue. No background task runs by default; opt in to the
|
|
28
|
-
* cooperative keepalive with startKeepalive(), which registers a background()
|
|
29
|
-
* task exactly like the queue consumers do.
|
|
30
|
-
*
|
|
31
|
-
* Single reader: like every MQTT client the socket has ONE network reader. Call
|
|
32
|
-
* receive()/consume() from one place.
|
|
33
|
-
*/
|
|
34
1
|
import { MqttMessage } from "./mqttMessage.js";
|
|
35
2
|
/** Any MQTT protocol / connection failure. */
|
|
36
3
|
export declare class MqttError extends Error {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional peer packages: the database drivers and service clients an
|
|
3
|
+
* APPLICATION installs, never the framework (ADR-0067).
|
|
4
|
+
*
|
|
5
|
+
* tina4-nodejs installs as exactly one package. `pg`, `mongodb`, `redis` and
|
|
6
|
+
* the `@aws-sdk` S3 client are optional peerDependencies, which npm does not
|
|
7
|
+
* install, so for most apps "missing" is the normal state. Every feature that
|
|
8
|
+
* reaches for one must therefore fail at the point of use with the exact
|
|
9
|
+
* command that fixes it - never a bare MODULE_NOT_FOUND, never a silent no-op.
|
|
10
|
+
*/
|
|
11
|
+
/** The actionable "install it" error, one wording for every optional peer. */
|
|
12
|
+
export declare function optionalPackageMissing(feature: string, packageNames: string[]): Error;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve an optional peer from the FRAMEWORK's location and return its module
|
|
15
|
+
* URL, or throw the actionable error. Synchronous, so a constructor can refuse
|
|
16
|
+
* immediately (parity with the Python master, which raises ImportError in the
|
|
17
|
+
* constructor) instead of leaving a rejected promise for later.
|
|
18
|
+
*
|
|
19
|
+
* Resolving from here rather than from process.cwd() is what finds the peer an
|
|
20
|
+
* app installed, wherever the server was started from.
|
|
21
|
+
*
|
|
22
|
+
* @param installTogether packages the feature needs as a set (S3 needs the
|
|
23
|
+
* client AND the presigner), all named in the one install command.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveOptionalPackage(packageName: string, feature: string, installTogether?: string[]): string;
|
package/types/core/src/plan.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project plan management — persistent, human-readable task state.
|
|
3
|
-
*
|
|
4
|
-
* Ported from tina4_python/dev_admin/plan.py (master reference).
|
|
5
|
-
* A plan is a markdown file under plan/ at the project root with sections
|
|
6
|
-
* for title, goal, steps (checkboxes), and notes. Exactly one plan is
|
|
7
|
-
* "current" at a time, recorded in plan/.current.
|
|
8
|
-
*
|
|
9
|
-
* Byte-for-byte compatible with Python's plan/*.md storage.
|
|
10
|
-
*/
|
|
11
1
|
export interface PlanStep {
|
|
12
2
|
text: string;
|
|
13
3
|
done: boolean;
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project index — lightweight, persistent "where is what" map.
|
|
3
|
-
*
|
|
4
|
-
* Ported from tina4_python/dev_admin/project_index.py (master reference).
|
|
5
|
-
*
|
|
6
|
-
* Storage: .tina4/project_index.json at the project root.
|
|
7
|
-
* Freshness: lazy-refreshes on read via mtime compare — no watchers.
|
|
8
|
-
* Extractors: per-language symbol extraction (TS/JS, Twig/HTML, SQL, Markdown,
|
|
9
|
-
* Python) using regex. No LLM involvement — pure static analysis.
|
|
10
|
-
*/
|
|
11
1
|
export interface FileRoute {
|
|
12
2
|
method: string;
|
|
13
3
|
path: string;
|
package/types/core/src/push.d.ts
CHANGED
|
@@ -11,6 +11,11 @@ export interface PushOptions {
|
|
|
11
11
|
privateKey?: string;
|
|
12
12
|
ttl?: number;
|
|
13
13
|
urgency?: "very-low" | "low" | "normal" | "high";
|
|
14
|
+
/**
|
|
15
|
+
* SSRF guard (ADR-0084): an explicit allow-list of hosts / host:port / CIDRs
|
|
16
|
+
* that bypass the private-endpoint refusal even with the opt-out off.
|
|
17
|
+
*/
|
|
18
|
+
allowHosts?: string[];
|
|
14
19
|
}
|
|
15
20
|
export interface PushResult {
|
|
16
21
|
ok: boolean;
|
|
@@ -59,7 +59,7 @@ export interface ConsumeOptions {
|
|
|
59
59
|
export interface QueueBackendInterface {
|
|
60
60
|
push(queue: string, payload: unknown, delay?: number, priority?: number): string;
|
|
61
61
|
pop(queue: string): QueueJob | null;
|
|
62
|
-
size(queue: string): number;
|
|
62
|
+
size(queue: string, status?: string): number;
|
|
63
63
|
clear(queue: string): void;
|
|
64
64
|
/**
|
|
65
65
|
* Release whatever connection the backend holds, and be safe to call twice.
|
|
@@ -74,6 +74,7 @@ export interface QueueBackendInterface {
|
|
|
74
74
|
close(): void;
|
|
75
75
|
complete?(queue: string, id: string): void;
|
|
76
76
|
fail?(queue: string, id: string, error: string, maxRetries: number, retryBackoff: number): void;
|
|
77
|
+
reject?(queue: string, id: string, reason: string, maxRetries: number): void;
|
|
77
78
|
/**
|
|
78
79
|
* Explicit manual re-queue: returns true if the id was found and revived,
|
|
79
80
|
* false otherwise (parity with Python's backend.retry_job()). A backend may
|
|
@@ -289,6 +290,11 @@ export declare class Queue {
|
|
|
289
290
|
* after retryBackoff seconds) or dead-letter (attempts >= maxRetries).
|
|
290
291
|
*/
|
|
291
292
|
_failJob(queue: string, job: QueueJob, error: string, maxRetries: number): void;
|
|
293
|
+
/**
|
|
294
|
+
* Dead-letter a job immediately — no retry (ADR-0023 reject()). Distinct from
|
|
295
|
+
* _failJob, which retries until maxRetries is spent.
|
|
296
|
+
*/
|
|
297
|
+
_rejectJob(queue: string, job: QueueJob, reason: string, maxRetries: number): void;
|
|
292
298
|
/**
|
|
293
299
|
* Re-queue a job back to the main queue directory with incremented attempts.
|
|
294
300
|
*/
|
|
@@ -130,5 +130,14 @@ export declare class LiteBackend {
|
|
|
130
130
|
* dead-letter file -- two spellings of the same intent that previously
|
|
131
131
|
* diverged.
|
|
132
132
|
*/
|
|
133
|
+
/**
|
|
134
|
+
* Reject a job permanently — dead-letter it NOW, no retry (ADR-0023).
|
|
135
|
+
*
|
|
136
|
+
* Unlike failJob(), which requeues until maxRetries is spent, rejectJob()
|
|
137
|
+
* moves a known-poison job straight to the dead-letter store. attempts is
|
|
138
|
+
* floored at maxRetries so deadLetters() (attempts >= maxRetries) returns it
|
|
139
|
+
* and size("dead") agrees.
|
|
140
|
+
*/
|
|
141
|
+
rejectJob(queue: string, job: QueueJob, reason: string, maxRetries: number): void;
|
|
133
142
|
retryJob(queue: string, job: QueueJob, delaySeconds?: number): void;
|
|
134
143
|
}
|
|
@@ -42,6 +42,8 @@ export declare class MongoBackend implements QueueBackend {
|
|
|
42
42
|
private collection;
|
|
43
43
|
private visibilityTimeout;
|
|
44
44
|
private maxRetries;
|
|
45
|
+
/** Module URL of the app-installed `mongodb` driver, resolved once. */
|
|
46
|
+
private driverUrl;
|
|
45
47
|
constructor(config?: MongoConfig);
|
|
46
48
|
/**
|
|
47
49
|
* Resolved connection config — exposed for testing/introspection.
|
|
@@ -74,7 +76,14 @@ export declare class MongoBackend implements QueueBackend {
|
|
|
74
76
|
popById(queue: string, id: string): QueueJob | null;
|
|
75
77
|
push(queue: string, payload: unknown, delay?: number, priority?: number): string;
|
|
76
78
|
pop(queue: string): QueueJob | null;
|
|
77
|
-
size(queue: string): number;
|
|
79
|
+
size(queue: string, status?: string): number;
|
|
80
|
+
/**
|
|
81
|
+
* Dead-letter a job immediately — no retry (ADR-0023 reject()). Distinct from
|
|
82
|
+
* fail(): fail() requeues until maxRetries is spent. attempts is floored at
|
|
83
|
+
* maxRetries so deadLetters()/size("dead") (which filter/scope to the
|
|
84
|
+
* dead-letter store) see it.
|
|
85
|
+
*/
|
|
86
|
+
reject(queue: string, id: string, reason: string, maxRetries: number): void;
|
|
78
87
|
clear(queue: string): void;
|
|
79
88
|
/**
|
|
80
89
|
* Acknowledge a completed job — drop its reservation so the reclaim never
|
|
@@ -11,6 +11,18 @@ import type { Tina4Request, UploadedFile } from "./types.js";
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function makeCaseInsensitiveHeaders(raw: IncomingHttpHeaders): IncomingHttpHeaders;
|
|
13
13
|
export declare function createRequest(req: IncomingMessage): Tina4Request;
|
|
14
|
+
export declare const DEFAULT_MAX_UPLOAD_SIZE = 10485760;
|
|
15
|
+
/**
|
|
16
|
+
* Read a numeric limit from the environment. A value that is not a usable
|
|
17
|
+
* number falls back to the default with a warning naming the variable (the
|
|
18
|
+
* same rule as PHP's Server::resolveLimit) - a typo must never be what
|
|
19
|
+
* disables a DoS guard.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveLimit(name: string, fallback: number, zeroAllowed?: boolean): number;
|
|
22
|
+
/** TINA4_MAX_UPLOAD_SIZE, read when it is needed so a value from .env counts. */
|
|
23
|
+
export declare function maxUploadSize(): number;
|
|
24
|
+
/** The one 413 wording (ADR-0068 section 4). */
|
|
25
|
+
export declare function bodyTooLargeMessage(bytes: number | bigint | string, limit: number): string;
|
|
14
26
|
export declare class PayloadTooLargeError extends Error {
|
|
15
27
|
statusCode: number;
|
|
16
28
|
constructor(actual: number, limit: number);
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { ServerResponse } from "node:http";
|
|
2
2
|
import type { Tina4Response } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The caller's name as a JSON string literal with non-ASCII escaped, byte-
|
|
5
|
+
* identical to Python's json.dumps (ADR-0068), so a name that is itself broken
|
|
6
|
+
* cannot break the error message or the log line carrying it.
|
|
7
|
+
*/
|
|
8
|
+
export declare function quoteHeaderName(name: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Refuse a response header whose name is not an HTTP token or whose value
|
|
11
|
+
* carries CR, LF or NUL, with the exact ADR-0068 wording. node:http refuses
|
|
12
|
+
* these too, but names a broken header raw (a CR/LF in the name reaches the
|
|
13
|
+
* log line) - this is the ADR's form, checked first.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertSafeHeader(name: string, value: unknown): void;
|
|
3
16
|
/**
|
|
4
17
|
* Set the default templates directory for render().
|
|
5
18
|
* Called by server.ts during startup.
|
|
@@ -88,6 +88,25 @@ export declare function _checkLegacyEnvVars(): void;
|
|
|
88
88
|
* of killing an innocent process.
|
|
89
89
|
*/
|
|
90
90
|
export declare function killPort(port: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Variables that mark a CI run, in ADR-0070's order (ci_env_vars). A run is CI
|
|
93
|
+
* when any of them holds a value that, trimmed and lower-cased, is non-empty
|
|
94
|
+
* and not in CI_NOT_SET_VALUES.
|
|
95
|
+
*/
|
|
96
|
+
export declare const CI_ENVIRONMENT_VARIABLES: string[];
|
|
97
|
+
/** Values that say "not under CI" (ADR-0070 ci_not_set_values), compared trimmed and lower-cased. */
|
|
98
|
+
export declare const CI_NOT_SET_VALUES: string[];
|
|
99
|
+
/**
|
|
100
|
+
* Whether the server may open a browser (ADR-0070): only for a developer at a
|
|
101
|
+
* desk. Every rule is a veto; nothing forces a browser open past one.
|
|
102
|
+
*
|
|
103
|
+
* 1. development only - the caller's resolved debug mode, and never with
|
|
104
|
+
* TINA4_PRODUCTION truthy or in a cluster worker (the primary decides);
|
|
105
|
+
* 2. never when TINA4_NO_BROWSER is truthy (true/1/yes/on);
|
|
106
|
+
* 3. never with --no-browser / a programmatic noBrowser (it can only veto);
|
|
107
|
+
* 4. never under CI.
|
|
108
|
+
*/
|
|
109
|
+
export declare function shouldOpenBrowser(isDevelopment: boolean, noBrowser?: boolean): boolean;
|
|
91
110
|
/**
|
|
92
111
|
* Resolve port and host with priority: explicit config > ENV var > default.
|
|
93
112
|
* Exported for testability.
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tina4 session handlers — turn a failed `execFileSync` child into a readable cause.
|
|
3
|
-
*
|
|
4
|
-
* The session-handler interface is synchronous but every backend client is async,
|
|
5
|
-
* so each command runs in a short-lived `node -e` child. When that child fails,
|
|
6
|
-
* `execFileSync` throws an error whose `.message` begins "Command failed:" and
|
|
7
|
-
* then embeds THE ENTIRE GENERATED SCRIPT — kilobytes of source with the real
|
|
8
|
-
* reason nowhere in it. Every handler used to throw exactly that, so an
|
|
9
|
-
* operator debugging a Redis outage got a wall of JavaScript instead of
|
|
10
|
-
* "connect ECONNREFUSED 127.0.0.1:6379".
|
|
11
|
-
*
|
|
12
|
-
* The children already write the real reason to stderr; `execFileSync` captures
|
|
13
|
-
* it on `err.stderr`. This module is the ONE place that prefers it, so the three
|
|
14
|
-
* call sites (respClient, mongoClient, redisHandler's npm path) cannot drift.
|
|
15
|
-
*/
|
|
16
1
|
/**
|
|
17
2
|
* Extract the most useful one-line cause from a thrown `execFileSync` error.
|
|
18
3
|
*
|
|
@@ -86,9 +86,33 @@ export declare class DatabaseSessionHandler implements SessionHandler {
|
|
|
86
86
|
/** Run a statement that returns nothing. */
|
|
87
87
|
private exec;
|
|
88
88
|
/**
|
|
89
|
-
* Ensure the session table exists (called once on first use)
|
|
89
|
+
* Ensure the session table exists (called once on first use) - safely when
|
|
90
|
+
* several processes race to create it.
|
|
91
|
+
*
|
|
92
|
+
* Every per-engine statement above is check-then-act, so two processes can
|
|
93
|
+
* both find the table absent and both CREATE; the loser errors, and every
|
|
94
|
+
* engine spells that differently (a pg_type unique violation on PostgreSQL,
|
|
95
|
+
* Msg 2714 on SQL Server, an RDB$RELATIONS unique violation on Firebird). So
|
|
96
|
+
* a failure is judged by RE-CHECKING whether the table now exists, never by
|
|
97
|
+
* parsing the message - the rescue the Firebird note above has always
|
|
98
|
+
* assumed, and which was not here. MEASURED on the lab before it: six real
|
|
99
|
+
* processes racing lost one to five of them on PostgreSQL, SQLite and
|
|
100
|
+
* Firebird.
|
|
101
|
+
*
|
|
102
|
+
* The re-check is RETRIED because the loser can fail BEFORE the winner has
|
|
103
|
+
* committed. On MySQL, CREATE TABLE IF NOT EXISTS takes a shared metadata
|
|
104
|
+
* lock, checks, then upgrades it to exclusive; two upgrades deadlock, and when
|
|
105
|
+
* MySQL cannot back the victim off silently it answers 1213 "Deadlock found"
|
|
106
|
+
* while the winner's table is still invisible (tina4-php CI run 35972320442).
|
|
107
|
+
* Bounded, so a genuine failure (no CREATE grant) still throws. Same attempts
|
|
108
|
+
* and delays in all four frameworks.
|
|
90
109
|
*/
|
|
91
110
|
private ensureTable;
|
|
111
|
+
/**
|
|
112
|
+
* Whether tina4_session exists, asked the one way every engine answers alike:
|
|
113
|
+
* a query against it that returns no rows succeeds only if it is there.
|
|
114
|
+
*/
|
|
115
|
+
private tableExists;
|
|
92
116
|
read(sessionId: string): SessionData | null;
|
|
93
117
|
write(sessionId: string, data: SessionData, ttl: number): void;
|
|
94
118
|
destroy(sessionId: string): void;
|
package/types/core/src/sso.d.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stored SSO identity, only while it is live (ADR-0079 s5). `stored` is the
|
|
3
|
+
* reserved _tina4_sso session value. The identity needs an issuer and a
|
|
4
|
+
* subject, and a numeric expires_at that is 0 (the provider gave no lifetime)
|
|
5
|
+
* or still in the future.
|
|
6
|
+
*
|
|
7
|
+
* Its own dependency-free module, so the auth gate can use it without
|
|
8
|
+
* importing the OIDC client (and everything the client imports).
|
|
9
|
+
*/
|
|
10
|
+
export declare function liveSessionIdentity(stored: unknown): Record<string, any> | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const ALLOW_PRIVATE_ENV = "TINA4_ALLOW_PRIVATE_REQUESTS";
|
|
2
|
+
/** Raised when the SSRF guard refuses an outbound request. */
|
|
3
|
+
export declare class SsrfError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
/** True when TINA4_ALLOW_PRIVATE_REQUESTS opts out of the guard. */
|
|
7
|
+
export declare function allowPrivateRequests(): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Classify one IP string: true = private/internal, refuse it. An IPv4-mapped
|
|
10
|
+
* IPv6 address is classified by its embedded IPv4. An unparseable value is
|
|
11
|
+
* treated as blocked - the guard refuses what it cannot classify.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isBlockedAddress(ip: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Refuse `url` when it targets a private/internal address. Throws SsrfError for a
|
|
16
|
+
* non-http(s) scheme, an unresolvable host, or any resolved address in the
|
|
17
|
+
* blocked space. `allowHosts` is a list of hosts / host:port / CIDRs to permit.
|
|
18
|
+
*/
|
|
19
|
+
export declare function guardUrl(url: string, allowHosts?: string[]): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse, Server } from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* Answer through a ServerResponse with the rejection shape and close. Every
|
|
4
|
+
* header already on the response is dropped: the shape is exact. Node closes
|
|
5
|
+
* the connection once the answer is flushed (Connection: close), so the rest
|
|
6
|
+
* of a refused upload is never read.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sendTransportRejection(res: ServerResponse, status: number, message: string, end?: {
|
|
9
|
+
(cb?: () => void): ServerResponse<IncomingMessage>;
|
|
10
|
+
(chunk: any, cb?: () => void): ServerResponse<IncomingMessage>;
|
|
11
|
+
(chunk: any, encoding: BufferEncoding, cb?: () => void): ServerResponse<IncomingMessage>;
|
|
12
|
+
}): void;
|
|
13
|
+
/**
|
|
14
|
+
* ADR-0068 section 2 for Node. node:http refuses an unsafe header where it is
|
|
15
|
+
* set (setHeader / appendHeader / writeHead). A header set straight on the raw
|
|
16
|
+
* response - past Tina4's own call-site check - used to surface as a route
|
|
17
|
+
* error page. Here the refusal is recorded instead, and whatever the handler
|
|
18
|
+
* sends next becomes the fixture's 500 {"error":"Invalid response header"},
|
|
19
|
+
* logged by header name. Tina4's own Response keeps refusing at the call site
|
|
20
|
+
* (its check runs before this layer is reached).
|
|
21
|
+
*/
|
|
22
|
+
export declare function guardUnsafeHeaders(res: ServerResponse): void;
|
|
23
|
+
/**
|
|
24
|
+
* Create the HTTP server Tina4 listens with - the main port, its loopback
|
|
25
|
+
* siblings, the AI port and every cluster worker - so every one of them keeps
|
|
26
|
+
* the same limits and answers.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createTina4HttpServer(handler: (req: IncomingMessage, res: ServerResponse) => unknown): Server;
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Which upstream hops are allowed to speak for a client (ADR-0019).
|
|
3
|
-
*
|
|
4
|
-
* X-Forwarded-For is written by whoever sends it. Reading it unconditionally
|
|
5
|
-
* lets any client choose its own rate-limit bucket, and - worse - choose
|
|
6
|
-
* SOMEONE ELSE'S, which is a starvation primitive against a third party. So
|
|
7
|
-
* the forwarding headers are believed only when the raw socket peer is a proxy
|
|
8
|
-
* the operator has explicitly declared.
|
|
9
|
-
*
|
|
10
|
-
* Configured by TINA4_TRUSTED_PROXIES: comma-separated exact addresses and/or
|
|
11
|
-
* CIDR ranges, IPv4 and IPv6, e.g. "10.0.0.0/8, 192.168.1.5, ::1, fd00::/8".
|
|
12
|
-
* Empty or unset means trust NOTHING, which is the secure default.
|
|
13
|
-
*
|
|
14
|
-
* Zero-dependency: node: has no CIDR matcher, so the packing and prefix
|
|
15
|
-
* comparison are done here over plain byte arrays.
|
|
16
|
-
*/
|
|
17
1
|
/** [packed network address, prefix bits] */
|
|
18
2
|
type Network = [Uint8Array, number];
|
|
19
3
|
/**
|
|
@@ -198,6 +198,11 @@ export interface Tina4Config {
|
|
|
198
198
|
* and staticDir are resolved relative to this path instead of process.cwd(). */
|
|
199
199
|
basePath?: string;
|
|
200
200
|
routesDir?: string;
|
|
201
|
+
/**
|
|
202
|
+
* Never open a browser on start (ADR-0070 rule 3, the programmatic
|
|
203
|
+
* --no-browser). It can only veto: false does not force one open.
|
|
204
|
+
*/
|
|
205
|
+
noBrowser?: boolean;
|
|
201
206
|
modelsDir?: string;
|
|
202
207
|
templatesDir?: string;
|
|
203
208
|
staticDir?: string;
|
|
@@ -47,6 +47,7 @@ export declare class NATSBackplane implements WebSocketBackplane {
|
|
|
47
47
|
private url;
|
|
48
48
|
private subs;
|
|
49
49
|
private ready;
|
|
50
|
+
private natsModuleUrl;
|
|
50
51
|
constructor(url?: string);
|
|
51
52
|
publish(channel: string, message: string): Promise<void>;
|
|
52
53
|
subscribe(channel: string, callback: (message: string) => void): Promise<void>;
|
package/types/core/src/wsdl.d.ts
CHANGED
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tina4 WSDL/SOAP — SOAP 1.1 / WSDL 1.1 service base class.
|
|
3
|
-
*
|
|
4
|
-
* Auto-generates WSDL definitions and handles SOAP XML requests.
|
|
5
|
-
* Zero external dependencies — uses simple string parsing for XML.
|
|
6
|
-
*
|
|
7
|
-
* Matches the PHP reference implementation (Tina4\WSDL).
|
|
8
|
-
*
|
|
9
|
-
* import { WSDLService, WSDLOperation } from "@tina4/core";
|
|
10
|
-
*
|
|
11
|
-
* class Calculator extends WSDLService {
|
|
12
|
-
* serviceName = "Calculator";
|
|
13
|
-
* serviceUrl = "/api/calculator";
|
|
14
|
-
*
|
|
15
|
-
* @WSDLOperation({ output: { Result: "int" } })
|
|
16
|
-
* async Add(a: number, b: number): Promise<Record<string, unknown>> {
|
|
17
|
-
* return { Result: a + b };
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
*/
|
|
21
1
|
export interface WSDLOperationMeta {
|
|
22
2
|
name: string;
|
|
23
3
|
description?: string;
|
|
@@ -34,8 +14,14 @@ interface WSDLOperationConfig {
|
|
|
34
14
|
*
|
|
35
15
|
* @WSDLOperation({ description: "Add two numbers", input: { a: "int", b: "int" }, output: { Result: "int" } })
|
|
36
16
|
* async Add(a: number, b: number): Promise<Record<string, unknown>> { ... }
|
|
17
|
+
*
|
|
18
|
+
* Works under both decorator flavours: TC39 standard decorators (what tsx and
|
|
19
|
+
* esbuild compile by default: `(method, context)`) and TypeScript's
|
|
20
|
+
* experimentalDecorators (`(prototype, name, descriptor)`).
|
|
37
21
|
*/
|
|
38
|
-
export declare function WSDLOperation(config?: WSDLOperationConfig): (
|
|
22
|
+
export declare function WSDLOperation(config?: WSDLOperationConfig): (target: unknown, context: string | symbol | {
|
|
23
|
+
name: string | symbol;
|
|
24
|
+
}, descriptor?: PropertyDescriptor) => PropertyDescriptor | undefined;
|
|
39
25
|
export declare abstract class WSDLService {
|
|
40
26
|
abstract serviceName: string;
|
|
41
27
|
abstract serviceUrl: string;
|
|
@@ -72,7 +58,7 @@ export declare abstract class WSDLService {
|
|
|
72
58
|
/**
|
|
73
59
|
* Handle incoming SOAP request (parse XML, dispatch to method, return SOAP response).
|
|
74
60
|
*/
|
|
75
|
-
handle(soapXml?: string): Promise<string>;
|
|
61
|
+
handle(soapXml?: string | Uint8Array): Promise<string>;
|
|
76
62
|
/**
|
|
77
63
|
* Register this service's routes on a router.
|
|
78
64
|
* GET /service-url?wsdl -> WSDL XML
|
|
@@ -241,7 +241,13 @@ export declare class Frond {
|
|
|
241
241
|
*/
|
|
242
242
|
private applyFastFilter;
|
|
243
243
|
private applyRenderedFilter;
|
|
244
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Sandbox gate for a WHOLE expression (F6/ADR-0077): refuse a dunder walk or
|
|
246
|
+
* a root variable outside the allow-list. Applied to output, if conditions,
|
|
247
|
+
* set right-hand sides and for iterables so none can smuggle a blocked
|
|
248
|
+
* variable past the per-output gate.
|
|
249
|
+
*/
|
|
250
|
+
private sandboxExprOk;
|
|
245
251
|
private resolveConcatenation;
|
|
246
252
|
private applyRenderedFilters;
|
|
247
253
|
private evalVarInner;
|
|
@@ -98,6 +98,12 @@ export declare class FirebirdAdapter implements DatabaseAdapter {
|
|
|
98
98
|
/** Connect to Firebird. Must be called before using the adapter. */
|
|
99
99
|
/** ADR-0044 required adapter capability. */
|
|
100
100
|
getDatabaseType(): string;
|
|
101
|
+
/**
|
|
102
|
+
* Quote a name the ORM emits the way Firebird stores it: UPPER CASE (see
|
|
103
|
+
* fbQuote). An already-quoted name passes through - the escape hatch for a
|
|
104
|
+
* genuinely case-sensitive table. Python master: FirebirdAdapter.quote_identifier.
|
|
105
|
+
*/
|
|
106
|
+
quoteIdentifier(name: string): string;
|
|
101
107
|
/** ADR-0044: readable/writable native boolean. */
|
|
102
108
|
autocommit: boolean;
|
|
103
109
|
/**
|
|
@@ -186,6 +192,12 @@ export declare class FirebirdAdapter implements DatabaseAdapter {
|
|
|
186
192
|
lastId?: number | bigint;
|
|
187
193
|
}>;
|
|
188
194
|
executeAsync(sql: string, params?: unknown[]): Promise<unknown>;
|
|
195
|
+
/**
|
|
196
|
+
* Run a row-producing statement ONCE and return its rows, for
|
|
197
|
+
* Database.execute(). node-firebird's execute() returns no rows, so a SELECT
|
|
198
|
+
* or an `INSERT ... RETURNING` through execute() used to lose them.
|
|
199
|
+
*/
|
|
200
|
+
executeRowsAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
189
201
|
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
|
|
190
202
|
queryAsync<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
191
203
|
/**
|
|
@@ -45,8 +45,19 @@ export declare class MssqlAdapter implements DatabaseAdapter {
|
|
|
45
45
|
* `startAt` lets a caller that has already consumed N placeholders (an UPDATE
|
|
46
46
|
* whose SET values are @p0..@p{N-1}) continue the numbering into a raw WHERE
|
|
47
47
|
* fragment instead of restarting at @p0.
|
|
48
|
+
*
|
|
49
|
+
* Only REAL placeholders are rewritten: a `?` inside a string literal, a
|
|
50
|
+
* quoted identifier or a comment is left alone (tina4-python#138).
|
|
48
51
|
*/
|
|
49
52
|
private convertPlaceholders;
|
|
53
|
+
/**
|
|
54
|
+
* The SQL the driver receives. With NO parameters it is sent EXACTLY as
|
|
55
|
+
* written (the cross-framework contract): there is nothing to bind.
|
|
56
|
+
*
|
|
57
|
+
* tina4: with parameters every `?` outside a literal, quoted identifier or
|
|
58
|
+
* comment is a placeholder.
|
|
59
|
+
*/
|
|
60
|
+
private bindable;
|
|
50
61
|
execute(sql: string, params?: unknown[]): unknown;
|
|
51
62
|
executeMany(sql: string, paramsList: unknown[][]): {
|
|
52
63
|
totalAffected: number;
|
|
@@ -23,6 +23,8 @@ export declare class MysqlAdapter implements DatabaseAdapter {
|
|
|
23
23
|
/** Connect to MySQL. Must be called before using the adapter. */
|
|
24
24
|
/** ADR-0044 required adapter capability. */
|
|
25
25
|
getDatabaseType(): string;
|
|
26
|
+
/** MySQL identifiers are backtick-quoted; a double-quoted token is a string. */
|
|
27
|
+
quoteIdentifier(name: string): string;
|
|
26
28
|
/** ADR-0044: readable/writable native boolean. */
|
|
27
29
|
autocommit: boolean;
|
|
28
30
|
/**
|