tina4-nodejs 3.13.91 → 3.13.94
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 +16 -3
- package/README.md +1 -1
- package/package.json +12 -9
- package/packages/cli/dist/bin.js +1312 -987
- package/packages/core/dist/index.js +1312 -987
- package/packages/core/src/auth.ts +141 -21
- package/packages/core/src/devMailbox.ts +20 -44
- package/packages/core/src/index.ts +2 -2
- package/packages/core/src/messenger.ts +72 -0
- package/packages/core/src/queueBackends/kafkaBackend.ts +108 -12
- package/packages/core/src/sessionHandlers/childError.ts +72 -0
- package/packages/core/src/sessionHandlers/mongoClient.ts +9 -3
- package/packages/core/src/sessionHandlers/redisHandler.ts +18 -5
- package/packages/core/src/sessionHandlers/respClient.ts +5 -1
- package/packages/frond/dist/index.js +74 -31
- package/packages/frond/src/engine.ts +99 -33
- package/packages/orm/dist/index.js +3102 -2777
- package/packages/orm/src/adapters/sqlite.ts +4 -1
- package/packages/orm/src/database.ts +108 -8
- package/types/cli/src/bin.d.ts +92 -0
- package/types/cli/src/commands/build.d.ts +2 -0
- package/types/cli/src/commands/generate.d.ts +47 -0
- package/types/cli/src/commands/init.d.ts +1 -0
- package/types/cli/src/commands/metrics.d.ts +6 -0
- package/types/cli/src/commands/migrate.d.ts +1 -0
- package/types/cli/src/commands/migrateCreate.d.ts +1 -0
- package/types/cli/src/commands/migrateRollback.d.ts +1 -0
- package/types/cli/src/commands/migrateStatus.d.ts +1 -0
- package/types/cli/src/commands/queue.d.ts +20 -0
- package/types/cli/src/commands/routes.d.ts +1 -0
- package/types/cli/src/commands/seed.d.ts +1 -0
- package/types/cli/src/commands/serve.d.ts +6 -0
- package/types/cli/src/commands/test.d.ts +1 -0
- package/types/core/src/ai.d.ts +64 -0
- package/types/core/src/api.d.ts +262 -0
- package/types/core/src/auth.d.ts +154 -0
- package/types/core/src/authGate.d.ts +20 -0
- package/types/core/src/background.d.ts +34 -0
- package/types/core/src/cache.d.ts +160 -0
- package/types/core/src/constants.d.ts +38 -0
- package/types/core/src/container.d.ts +44 -0
- package/types/core/src/context/chunker.d.ts +31 -0
- package/types/core/src/context/index.d.ts +93 -0
- package/types/core/src/devAdmin.d.ts +179 -0
- package/types/core/src/devMailbox.d.ts +54 -0
- package/types/core/src/docs.d.ts +141 -0
- package/types/core/src/docsAutoDiscovery.d.ts +6 -0
- package/types/core/src/dotenv.d.ts +65 -0
- package/types/core/src/env.d.ts +28 -0
- package/types/core/src/errorOverlay.d.ts +36 -0
- package/types/core/src/events.d.ts +75 -0
- package/types/core/src/fakeData.d.ts +55 -0
- package/types/core/src/feedback.d.ts +90 -0
- package/types/core/src/graphql.d.ts +207 -0
- package/types/core/src/health.d.ts +22 -0
- package/types/core/src/htmlElement.d.ts +75 -0
- package/types/core/src/i18n.d.ts +37 -0
- package/types/core/src/index.d.ts +93 -0
- package/types/core/src/job.d.ts +39 -0
- package/types/core/src/logger.d.ts +123 -0
- package/types/core/src/mcp.d.ts +248 -0
- package/types/core/src/messenger.d.ts +191 -0
- package/types/core/src/metrics.d.ts +77 -0
- package/types/core/src/middleware.d.ts +207 -0
- package/types/core/src/mqtt.d.ts +257 -0
- package/types/core/src/mqttMessage.d.ts +67 -0
- package/types/core/src/plan.d.ts +96 -0
- package/types/core/src/projectIndex.d.ts +56 -0
- package/types/core/src/queue.d.ts +219 -0
- package/types/core/src/queueBackends/kafkaBackend.d.ts +117 -0
- package/types/core/src/queueBackends/liteBackend.d.ts +119 -0
- package/types/core/src/queueBackends/mongoBackend.d.ts +97 -0
- package/types/core/src/queueBackends/rabbitmqBackend.d.ts +55 -0
- package/types/core/src/rateLimiter.d.ts +49 -0
- package/types/core/src/request.d.ts +25 -0
- package/types/core/src/response.d.ts +28 -0
- package/types/core/src/routeDiscovery.d.ts +12 -0
- package/types/core/src/router.d.ts +355 -0
- package/types/core/src/scss.d.ts +19 -0
- package/types/core/src/server.d.ts +131 -0
- package/types/core/src/service.d.ts +115 -0
- package/types/core/src/session.d.ts +256 -0
- package/types/core/src/sessionHandlers/childError.d.ts +34 -0
- package/types/core/src/sessionHandlers/databaseHandler.d.ts +42 -0
- package/types/core/src/sessionHandlers/mongoClient.d.ts +24 -0
- package/types/core/src/sessionHandlers/mongoHandler.d.ts +61 -0
- package/types/core/src/sessionHandlers/redisHandler.d.ts +60 -0
- package/types/core/src/sessionHandlers/respClient.d.ts +22 -0
- package/types/core/src/sessionHandlers/valkeyHandler.d.ts +65 -0
- package/types/core/src/static.d.ts +2 -0
- package/types/core/src/test.d.ts +94 -0
- package/types/core/src/testClient.d.ts +36 -0
- package/types/core/src/testing.d.ts +58 -0
- package/types/core/src/types.d.ts +219 -0
- package/types/core/src/validator.d.ts +52 -0
- package/types/core/src/websocket.d.ts +376 -0
- package/types/core/src/websocketBackplane.d.ts +166 -0
- package/types/core/src/websocketConnection.d.ts +54 -0
- package/types/core/src/wsdl.d.ts +101 -0
- package/types/frond/src/engine.d.ts +263 -0
- package/types/frond/src/index.d.ts +2 -0
- package/types/orm/src/adapters/firebird.d.ts +138 -0
- package/types/orm/src/adapters/mongodb.d.ts +81 -0
- package/types/orm/src/adapters/mssql.d.ts +70 -0
- package/types/orm/src/adapters/mysql.d.ts +66 -0
- package/types/orm/src/adapters/odbc.d.ts +97 -0
- package/types/orm/src/adapters/postgres.d.ts +85 -0
- package/types/orm/src/adapters/sqlite.d.ts +56 -0
- package/types/orm/src/autoCrud.d.ts +73 -0
- package/types/orm/src/baseModel.d.ts +391 -0
- package/types/orm/src/cachedDatabase.d.ts +177 -0
- package/types/orm/src/database.d.ts +609 -0
- package/types/orm/src/databaseResult.d.ts +85 -0
- package/types/orm/src/docstore.d.ts +182 -0
- package/types/orm/src/fakeData.d.ts +22 -0
- package/types/orm/src/index.d.ts +40 -0
- package/types/orm/src/migration.d.ts +275 -0
- package/types/orm/src/model.d.ts +7 -0
- package/types/orm/src/query.d.ts +14 -0
- package/types/orm/src/queryBuilder.d.ts +173 -0
- package/types/orm/src/realtime/index.d.ts +7 -0
- package/types/orm/src/realtime/models/attachment.d.ts +43 -0
- package/types/orm/src/realtime/models/channel.d.ts +32 -0
- package/types/orm/src/realtime/models/channelMember.d.ts +32 -0
- package/types/orm/src/realtime/models/message.d.ts +36 -0
- package/types/orm/src/realtime/models/workspace.d.ts +26 -0
- package/types/orm/src/realtime/realtime.d.ts +24 -0
- package/types/orm/src/realtime/storage.d.ts +61 -0
- package/types/orm/src/seeder.d.ts +118 -0
- package/types/orm/src/sqlTranslator.d.ts +134 -0
- package/types/orm/src/types.d.ts +138 -0
- package/types/orm/src/validation.d.ts +6 -0
- package/types/swagger/src/generator.d.ts +46 -0
- package/types/swagger/src/index.d.ts +2 -0
- package/types/swagger/src/ui.d.ts +11 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
export interface ApiResult {
|
|
2
|
+
http_code: number | null;
|
|
3
|
+
body: unknown;
|
|
4
|
+
headers: Record<string, string>;
|
|
5
|
+
error: string | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Result of {@link Api.download}. There is no `body` field — the response
|
|
9
|
+
* body went to disk. `path` is the destination on success and `null` on any
|
|
10
|
+
* error (missing dest, HTTP error status, transport failure); the file is not
|
|
11
|
+
* written on error. Keeps `http_code` (snake_case) for parity with
|
|
12
|
+
* {@link ApiResult} and the Python/PHP/Ruby `download` return.
|
|
13
|
+
*/
|
|
14
|
+
export interface DownloadResult {
|
|
15
|
+
http_code: number | null;
|
|
16
|
+
headers: Record<string, string>;
|
|
17
|
+
error: string | null;
|
|
18
|
+
path: string | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* An injectable transport seam (constructor option `transport`). When supplied
|
|
22
|
+
* it fully REPLACES the node:http/https network call. Called as
|
|
23
|
+
* `(method, url, headers, body, timeout)` and must return the same result
|
|
24
|
+
* shape every verb returns (`{ http_code, body, headers, error }`); may be sync
|
|
25
|
+
* or async.
|
|
26
|
+
*
|
|
27
|
+
* NOTE: Tina4's own test suite must NEVER inject a fake/canned transport — the
|
|
28
|
+
* no-mock rule stands, so framework tests always exercise the real network path
|
|
29
|
+
* against a real local server. This seam exists purely so *application*
|
|
30
|
+
* developers can unit-test code that calls an `Api` instance without a live
|
|
31
|
+
* server.
|
|
32
|
+
*/
|
|
33
|
+
export type ApiTransport = (method: string, url: string, headers: Record<string, string>, body: Buffer | null, timeout: number) => ApiResult | Promise<ApiResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Options for {@link Api.upload}. Supply the file EITHER as `filePath` (a file
|
|
36
|
+
* on disk) OR as `fileBytes` + `filename` (an in-memory payload) — a caller
|
|
37
|
+
* never needs a temp file.
|
|
38
|
+
*/
|
|
39
|
+
export interface UploadOptions {
|
|
40
|
+
/** A file on disk. `filename` defaults to its basename. */
|
|
41
|
+
filePath?: string;
|
|
42
|
+
/** The form field the file is sent under (default `"file"`). */
|
|
43
|
+
fieldName?: string;
|
|
44
|
+
/** Additional text parts of the multipart body. */
|
|
45
|
+
extraFields?: Record<string, string>;
|
|
46
|
+
/** Extra per-call headers merged onto the request. */
|
|
47
|
+
headers?: Record<string, string>;
|
|
48
|
+
/** An in-memory payload (Buffer or string). Requires `filename` for a name. */
|
|
49
|
+
fileBytes?: Buffer | string;
|
|
50
|
+
/** Filename used in the Content-Disposition part header. */
|
|
51
|
+
filename?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Constructor options for {@link Api}. Used as the second argument to
|
|
55
|
+
* `new Api(url, { ... })` — cross-framework parity with Python
|
|
56
|
+
* `Api(bearer_token=, ...)` kwargs added in 3.13.x.
|
|
57
|
+
*/
|
|
58
|
+
export interface ApiOptions {
|
|
59
|
+
authHeader?: string;
|
|
60
|
+
timeout?: number;
|
|
61
|
+
ignoreSsl?: boolean;
|
|
62
|
+
/** Positive form of ignoreSsl — `verifySsl: false` disables verification. */
|
|
63
|
+
verifySsl?: boolean;
|
|
64
|
+
bearerToken?: string;
|
|
65
|
+
username?: string;
|
|
66
|
+
password?: string;
|
|
67
|
+
headers?: Record<string, string>;
|
|
68
|
+
/**
|
|
69
|
+
* Maximum automatic retries on a transient failure (default 0 = off, so
|
|
70
|
+
* existing callers are unaffected). When > 0, a transport error or a
|
|
71
|
+
* retryable status (429/5xx) is retried up to this many times with
|
|
72
|
+
* exponential backoff. NOTE: a retried non-idempotent request (POST/…)
|
|
73
|
+
* may be re-sent — retries are opt-in for that reason.
|
|
74
|
+
*/
|
|
75
|
+
maxRetries?: number;
|
|
76
|
+
/** Base backoff in seconds, doubling each attempt (default 0.5). */
|
|
77
|
+
retryBackoff?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Injectable transport seam (default undefined = the real network path).
|
|
80
|
+
* When supplied it REPLACES the node:http/https call. See {@link ApiTransport}.
|
|
81
|
+
* Tina4's own suite never injects it (no-mock rule) — it exists so
|
|
82
|
+
* application developers can unit-test their own code.
|
|
83
|
+
*/
|
|
84
|
+
transport?: ApiTransport;
|
|
85
|
+
/**
|
|
86
|
+
* Opt-in per-client, in-memory cookie jar (default false = off, zero
|
|
87
|
+
* behaviour change). When true, `Set-Cookie` response headers are parsed and
|
|
88
|
+
* the accumulated `Cookie` header is sent on subsequent requests. Not
|
|
89
|
+
* persisted; scoped to this instance.
|
|
90
|
+
*/
|
|
91
|
+
cookies?: boolean;
|
|
92
|
+
}
|
|
93
|
+
export declare class Api {
|
|
94
|
+
private baseUrl;
|
|
95
|
+
private headers;
|
|
96
|
+
private timeout;
|
|
97
|
+
private authHeader;
|
|
98
|
+
private ignoreSsl;
|
|
99
|
+
private maxRetries;
|
|
100
|
+
private retryBackoff;
|
|
101
|
+
private transportFn?;
|
|
102
|
+
private cookiesEnabled;
|
|
103
|
+
private cookies;
|
|
104
|
+
/**
|
|
105
|
+
* Construct an Api client.
|
|
106
|
+
*
|
|
107
|
+
* Two construction styles supported:
|
|
108
|
+
*
|
|
109
|
+
* // Legacy positional form
|
|
110
|
+
* new Api("https://api.example.com", "Bearer token", 30);
|
|
111
|
+
*
|
|
112
|
+
* // 3.13.1: ergonomic options bag (recommended) — cross-framework
|
|
113
|
+
* // parity with Python tina4_python.api.Api kwargs.
|
|
114
|
+
* new Api("https://api.example.com", { bearerToken: "sk-abc" });
|
|
115
|
+
* new Api("https://api.example.com", { username: "u", password: "p" });
|
|
116
|
+
* new Api("https://api.example.com", { headers: { "X-Tenant": "acme" } });
|
|
117
|
+
* new Api("https://self-signed.local", { verifySsl: false });
|
|
118
|
+
*
|
|
119
|
+
* Bearer wins over basic-auth when both passed. `verifySsl: false` is
|
|
120
|
+
* the positive form of `ignoreSsl: true`; `ignoreSsl` wins when both
|
|
121
|
+
* supplied for backward compatibility.
|
|
122
|
+
*
|
|
123
|
+
* `maxRetries` (default 0 = off) enables automatic retry with
|
|
124
|
+
* exponential backoff (`retryBackoff` seconds base, doubling each
|
|
125
|
+
* attempt) on a transport error or a retryable status (429/5xx). A
|
|
126
|
+
* retried non-idempotent request (POST/…) may be re-sent — retries are
|
|
127
|
+
* opt-in for that reason.
|
|
128
|
+
*
|
|
129
|
+
* new Api("https://api.example.com", { maxRetries: 3, retryBackoff: 0.5 });
|
|
130
|
+
*
|
|
131
|
+
* `transport` (default undefined = the real network path) is an injectable
|
|
132
|
+
* seam so USERS can unit-test their own code; `cookies` (default false)
|
|
133
|
+
* turns on a per-client, in-memory cookie jar.
|
|
134
|
+
*/
|
|
135
|
+
constructor(baseUrl?: string, authHeaderOrOptions?: string | ApiOptions, timeout?: number);
|
|
136
|
+
/**
|
|
137
|
+
* Add custom headers to all subsequent requests.
|
|
138
|
+
*/
|
|
139
|
+
addHeaders(headers: Record<string, string>): void;
|
|
140
|
+
/**
|
|
141
|
+
* Set Bearer token authentication.
|
|
142
|
+
*/
|
|
143
|
+
setBearerToken(token: string): void;
|
|
144
|
+
/**
|
|
145
|
+
* Set Basic authentication.
|
|
146
|
+
*/
|
|
147
|
+
setBasicAuth(username: string, password: string): void;
|
|
148
|
+
/**
|
|
149
|
+
* Disable SSL certificate verification (dev/self-signed certs only).
|
|
150
|
+
*/
|
|
151
|
+
setIgnoreSsl(ignore: boolean): void;
|
|
152
|
+
/**
|
|
153
|
+
* HTTP GET request.
|
|
154
|
+
*/
|
|
155
|
+
get(path: string, params?: Record<string, string>): Promise<ApiResult>;
|
|
156
|
+
/**
|
|
157
|
+
* HTTP POST request.
|
|
158
|
+
*/
|
|
159
|
+
post(path: string, body?: unknown, contentType?: string): Promise<ApiResult>;
|
|
160
|
+
/**
|
|
161
|
+
* HTTP PUT request.
|
|
162
|
+
*/
|
|
163
|
+
put(path: string, body?: unknown, contentType?: string): Promise<ApiResult>;
|
|
164
|
+
/**
|
|
165
|
+
* HTTP PATCH request.
|
|
166
|
+
*/
|
|
167
|
+
patch(path: string, body?: unknown, contentType?: string): Promise<ApiResult>;
|
|
168
|
+
/**
|
|
169
|
+
* HTTP DELETE request.
|
|
170
|
+
*/
|
|
171
|
+
delete(path: string, body?: unknown): Promise<ApiResult>;
|
|
172
|
+
/**
|
|
173
|
+
* Generic request method — public entry point for any HTTP method.
|
|
174
|
+
*/
|
|
175
|
+
sendRequest(method: string, path: string, body?: unknown, contentType?: string): Promise<ApiResult>;
|
|
176
|
+
/**
|
|
177
|
+
* POST a `multipart/form-data` body — a file plus optional text fields.
|
|
178
|
+
*
|
|
179
|
+
* Two ways to supply the file, so a caller never needs a temp file:
|
|
180
|
+
*
|
|
181
|
+
* - `filePath` — a file on disk. `filename` defaults to its basename.
|
|
182
|
+
* - `fileBytes` + `filename` — an in-memory payload (Buffer or string).
|
|
183
|
+
*
|
|
184
|
+
* `fieldName` (default `"file"`) is the form field the file is sent under.
|
|
185
|
+
* `extraFields` become additional text parts. `headers` are extra per-call
|
|
186
|
+
* headers merged onto the request. The part's Content-Type is guessed from
|
|
187
|
+
* the filename (falling back to `application/octet-stream`).
|
|
188
|
+
*
|
|
189
|
+
* Returns the standard {@link ApiResult}. A missing file or no source given
|
|
190
|
+
* returns a clean error result (`http_code` null, `error` set) — it does NOT
|
|
191
|
+
* throw. Retry/backoff (if configured) applies, exactly like the verbs.
|
|
192
|
+
*
|
|
193
|
+
* await api.upload("/avatars", { filePath: "/tmp/me.png" });
|
|
194
|
+
* await api.upload("/avatars", { fileBytes: raw, filename: "me.png",
|
|
195
|
+
* extraFields: { user_id: "42" } });
|
|
196
|
+
*/
|
|
197
|
+
upload(path: string, opts?: UploadOptions): Promise<ApiResult>;
|
|
198
|
+
/**
|
|
199
|
+
* Stream a GET response body to `destPath` in chunks.
|
|
200
|
+
*
|
|
201
|
+
* The body is written to disk `DOWNLOAD_CHUNK_SIZE` bytes at a time instead
|
|
202
|
+
* of being buffered whole in memory — safe for large payloads. Redirect
|
|
203
|
+
* following, the cross-origin auth strip, the cookie jar, and the SSL flag
|
|
204
|
+
* all apply, exactly like the other verbs.
|
|
205
|
+
*
|
|
206
|
+
* Returns {@link DownloadResult} — there is no `body` field (it went to
|
|
207
|
+
* disk). `path` is `destPath` on success and `null` on any error (missing
|
|
208
|
+
* dest, HTTP error status, or a transport failure); the destination file is
|
|
209
|
+
* not written on error.
|
|
210
|
+
*/
|
|
211
|
+
download(path: string, destPath: string, params?: Record<string, string>): Promise<DownloadResult>;
|
|
212
|
+
private buildUrl;
|
|
213
|
+
/**
|
|
214
|
+
* Build the request headers (auth + cookie jar + extras) and serialize the
|
|
215
|
+
* body to a Buffer. Shared by every verb, upload, and download so the wire
|
|
216
|
+
* shape is identical and the transport seam sees exactly what the network
|
|
217
|
+
* path would.
|
|
218
|
+
*/
|
|
219
|
+
private buildRequest;
|
|
220
|
+
/**
|
|
221
|
+
* Execute the request with opt-in retry/backoff.
|
|
222
|
+
*
|
|
223
|
+
* With `maxRetries` > 0, a transport failure (`http_code` null) or a
|
|
224
|
+
* retryable status (429/5xx) is retried up to `maxRetries` times with
|
|
225
|
+
* exponential backoff; any other outcome (2xx, 3xx, other 4xx) returns
|
|
226
|
+
* at once. A retried non-idempotent request may be re-sent — retries
|
|
227
|
+
* are opt-in for that reason.
|
|
228
|
+
*/
|
|
229
|
+
private execute;
|
|
230
|
+
/** A single HTTP attempt — returns the standardized result. */
|
|
231
|
+
private attempt;
|
|
232
|
+
/**
|
|
233
|
+
* Invoke a user-injected transport and normalize its result. The transport
|
|
234
|
+
* is called with `(method, url, headers, body, timeout)` and its returned
|
|
235
|
+
* `Set-Cookie` headers (if any) feed the cookie jar.
|
|
236
|
+
*/
|
|
237
|
+
private callTransport;
|
|
238
|
+
/**
|
|
239
|
+
* Perform the network request, following up to `redirectsLeft` redirects.
|
|
240
|
+
*
|
|
241
|
+
* node:http/https `request` does NOT auto-follow redirects. On a 3xx with a
|
|
242
|
+
* Location, this drains the intermediate response and re-issues to the new
|
|
243
|
+
* URL: 301/302/303 on a non-GET/HEAD become GET (body dropped, urllib
|
|
244
|
+
* behaviour); 307/308 preserve method + body. When the redirect target is a
|
|
245
|
+
* DIFFERENT origin, the Authorization and Cookie headers are stripped so a
|
|
246
|
+
* bearer token / session cookie never leaks to a host you didn't
|
|
247
|
+
* authenticate to.
|
|
248
|
+
*/
|
|
249
|
+
private performRequest;
|
|
250
|
+
/** Buffer a response body, parse JSON if possible, and store cookies. */
|
|
251
|
+
private readResponse;
|
|
252
|
+
/** The accumulated `Cookie` request header, or null when the jar is empty. */
|
|
253
|
+
private cookieHeader;
|
|
254
|
+
/**
|
|
255
|
+
* Parse `Set-Cookie` response headers into the jar (when enabled). Only the
|
|
256
|
+
* leading `name=value` pair of each is kept (Path/HttpOnly/Expires ignored);
|
|
257
|
+
* a later value for the same name overwrites an earlier one.
|
|
258
|
+
*/
|
|
259
|
+
private storeCookies;
|
|
260
|
+
/** Store cookies from a plain header record (the transport seam path). */
|
|
261
|
+
private storeCookiesFromRecord;
|
|
262
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { Middleware } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ensure a usable TINA4_SECRET exists. Run ONCE at server boot, after env load
|
|
4
|
+
* and before auth is used. Mirrors Python's `ensure_dev_secret()`.
|
|
5
|
+
*
|
|
6
|
+
* Order:
|
|
7
|
+
* 1. TINA4_SECRET already set → no-op (return null).
|
|
8
|
+
* 2. NOT dev, OR CI, OR production → emit the actionable warning, return null.
|
|
9
|
+
* NEVER generates or persists a secret in CI / production / non-dev.
|
|
10
|
+
* 3. Otherwise (dev, not CI, not prod, blank secret) → generate a 32-byte hex
|
|
11
|
+
* secret, set it in process.env for THIS run immediately, then try to append
|
|
12
|
+
* it to <cwd>/.env.local (create if missing; never touch .env). On a write
|
|
13
|
+
* failure keep the in-memory secret and warn — boot must never crash.
|
|
14
|
+
*
|
|
15
|
+
* @param cwd - Directory to write .env.local into. Tests pass a temp dir; production passes nothing.
|
|
16
|
+
* @returns The newly-generated secret, or null when nothing was generated.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureDevSecret(cwd?: string): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Seconds of clock skew tolerated on the "nbf" (not-before) claim.
|
|
21
|
+
*
|
|
22
|
+
* Without this, a token minted on one host and validated on another a second
|
|
23
|
+
* behind is rejected for no real reason; RFC 7519 explicitly allows "a small
|
|
24
|
+
* leeway". Same value as the Python master's `_JWT_LEEWAY_SECONDS`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const JWT_LEEWAY_SECONDS = 60;
|
|
27
|
+
/**
|
|
28
|
+
* Pick the JWT algorithm: explicit argument, else TINA4_JWT_ALGORITHM, else HS256.
|
|
29
|
+
*
|
|
30
|
+
* Throws (naming the supported set and the env var) when asked for an algorithm
|
|
31
|
+
* we cannot sign — a silent downgrade to HS256 is the whole bug in python#106.
|
|
32
|
+
*
|
|
33
|
+
* @param algorithm - Explicit algorithm; wins over the environment when given.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveAlgorithm(algorithm?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Create a signed JWT token.
|
|
38
|
+
*
|
|
39
|
+
* Secret is always read from `process.env.TINA4_SECRET`.
|
|
40
|
+
* Algorithm is read from `process.env.TINA4_JWT_ALGORITHM` (default "HS256");
|
|
41
|
+
* HS256 / HS384 / HS512 / RS256 are supported and anything else throws.
|
|
42
|
+
*
|
|
43
|
+
* The header's `alg` is always the algorithm that actually signed the token.
|
|
44
|
+
*
|
|
45
|
+
* No `nbf` (not-before) claim is stamped — parity with Python and PHP. Pass your
|
|
46
|
+
* own `nbf` in the payload to post-date a token; `validToken` enforces it.
|
|
47
|
+
*
|
|
48
|
+
* @param payload - Claims to encode (e.g. `{ userId: 1, role: "admin" }`)
|
|
49
|
+
* @param secretOrExpiresIn - Signing secret string, OR expiresIn number in MINUTES (back-compat with old 2-arg form)
|
|
50
|
+
* @param expiresIn - Lifetime in MINUTES (default 60). `0` ⇒ no `exp` claim (non-expiring). Only used when secret is a string.
|
|
51
|
+
* @param algorithm - Overrides TINA4_JWT_ALGORITHM for this call.
|
|
52
|
+
* @returns Signed JWT string: header.payload.signature
|
|
53
|
+
* @throws When the resolved algorithm is not one Tina4 can sign.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getToken(payload: Record<string, unknown>, secretOrExpiresIn?: string | number, expiresIn?: number, algorithm?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Validate a JWT token. Returns the decoded payload on success, `null` if
|
|
58
|
+
* invalid/expired/malformed.
|
|
59
|
+
*
|
|
60
|
+
* 3.13.0 — return type changed from `boolean` to `Record<string, unknown> | null`.
|
|
61
|
+
* Matches the convention used by `jsonwebtoken` and the Python / PHP / Ruby
|
|
62
|
+
* Auth.validToken signatures shipped at the same time. Legacy
|
|
63
|
+
* `if (validToken(t))` patterns keep working because a non-null object is
|
|
64
|
+
* truthy and null is falsy.
|
|
65
|
+
*
|
|
66
|
+
* Secret is read from `process.env.TINA4_SECRET` when not passed explicitly.
|
|
67
|
+
* Algorithm is read from `process.env.TINA4_JWT_ALGORITHM` (default "HS256").
|
|
68
|
+
*
|
|
69
|
+
* Checks, in order: the header's `alg` must BE the expected algorithm (blocks alg
|
|
70
|
+
* substitution, including `alg: "none"`, before any signature work), then the
|
|
71
|
+
* signature, then `exp`, then `nbf` (with `JWT_LEEWAY_SECONDS` of clock skew).
|
|
72
|
+
*/
|
|
73
|
+
export declare function validToken(token: string, secret?: string, algorithm?: string): Record<string, unknown> | null;
|
|
74
|
+
/**
|
|
75
|
+
* Get the JWT payload WITHOUT verifying signature or expiration.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getPayload(token: string): Record<string, unknown> | null;
|
|
78
|
+
/**
|
|
79
|
+
* Hash a password using PBKDF2-SHA256.
|
|
80
|
+
*
|
|
81
|
+
* @param password - Plaintext password
|
|
82
|
+
* @param salt - Hex-encoded salt (auto-generated if omitted)
|
|
83
|
+
* @param iterations - PBKDF2 iterations (default 260000)
|
|
84
|
+
* @returns Format: `pbkdf2_sha256$iterations$salt$hash` (all hex-encoded)
|
|
85
|
+
*/
|
|
86
|
+
export declare function hashPassword(password: string, salt?: string, iterations?: number): string;
|
|
87
|
+
/**
|
|
88
|
+
* Check a password against a PBKDF2 hash string.
|
|
89
|
+
* Supports both $ and : delimiters for backward compatibility.
|
|
90
|
+
*/
|
|
91
|
+
export declare function checkPassword(password: string, hash: string): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Auth middleware that extracts and verifies a Bearer JWT from the
|
|
94
|
+
* Authorization header. On success, attaches the decoded payload to
|
|
95
|
+
* `(request as any).auth`. On failure, sends a 401 JSON response.
|
|
96
|
+
*
|
|
97
|
+
* @param secret - Signing secret / PEM public key (default: TINA4_SECRET env var).
|
|
98
|
+
* @param algorithm - JWT algorithm. Omit it to honour TINA4_JWT_ALGORITHM (then
|
|
99
|
+
* HS256). It used to default to the literal "HS256", which SHADOWED the env
|
|
100
|
+
* var: an app on TINA4_JWT_ALGORITHM=HS512 minted HS512 tokens and this
|
|
101
|
+
* middleware verified them as HS256, rejecting every valid token.
|
|
102
|
+
*/
|
|
103
|
+
export declare function authMiddleware(secret?: string, algorithm?: string): Middleware;
|
|
104
|
+
/**
|
|
105
|
+
* Refresh a JWT token — validate the existing token then re-sign
|
|
106
|
+
* with a fresh expiry.
|
|
107
|
+
*
|
|
108
|
+
* Secret is always read from `process.env.TINA4_SECRET`.
|
|
109
|
+
*
|
|
110
|
+
* @param token - Existing JWT to refresh
|
|
111
|
+
* @param expiresIn - New lifetime in MINUTES (default 60)
|
|
112
|
+
* @returns New signed JWT string, or null if the input token is invalid/expired
|
|
113
|
+
*/
|
|
114
|
+
export declare function refreshToken(token: string, expiresIn?: number): string | null;
|
|
115
|
+
/**
|
|
116
|
+
* Extract a Bearer token from request headers and validate it.
|
|
117
|
+
*
|
|
118
|
+
* @param headers - Object with header keys (e.g. `{ authorization: "Bearer ..." }`)
|
|
119
|
+
* @param secret - HMAC secret or PEM public key
|
|
120
|
+
* @param algorithm - "HS256" or "RS256" (default "HS256")
|
|
121
|
+
* @returns Decoded payload, or null if missing/invalid
|
|
122
|
+
*/
|
|
123
|
+
export declare function authenticateRequest(headers: Record<string, string | string[] | undefined>, secret?: string, algorithm?: string): Record<string, unknown> | null;
|
|
124
|
+
/**
|
|
125
|
+
* Compare an API key against an expected value.
|
|
126
|
+
* If `expected` is omitted, falls back to the `TINA4_API_KEY` env var.
|
|
127
|
+
*
|
|
128
|
+
* Uses constant-time comparison to prevent timing attacks.
|
|
129
|
+
*
|
|
130
|
+
* @param provided - The API key provided by the caller
|
|
131
|
+
* @param expected - The correct API key (defaults to `process.env.TINA4_API_KEY`)
|
|
132
|
+
* @returns true if the keys match
|
|
133
|
+
*/
|
|
134
|
+
export declare function validateApiKey(provided: string, expected?: string): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Auth class that wraps the standalone auth functions so both patterns work:
|
|
137
|
+
*
|
|
138
|
+
* import { Auth } from "tina4-nodejs";
|
|
139
|
+
* const token = Auth.getToken(payload, secret);
|
|
140
|
+
*
|
|
141
|
+
* import { getToken } from "tina4-nodejs";
|
|
142
|
+
* const token = getToken(payload, secret);
|
|
143
|
+
*/
|
|
144
|
+
export declare class Auth {
|
|
145
|
+
static getToken: typeof getToken;
|
|
146
|
+
static validToken: typeof validToken;
|
|
147
|
+
static getPayload: typeof getPayload;
|
|
148
|
+
static hashPassword: typeof hashPassword;
|
|
149
|
+
static checkPassword: typeof checkPassword;
|
|
150
|
+
static authMiddleware: typeof authMiddleware;
|
|
151
|
+
static refreshToken: typeof refreshToken;
|
|
152
|
+
static authenticateRequest: typeof authenticateRequest;
|
|
153
|
+
static validateApiKey: typeof validateApiKey;
|
|
154
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Tina4Request, Tina4Response } from "./types.js";
|
|
2
|
+
/** Just the auth-relevant fields of a matched route. */
|
|
3
|
+
export interface AuthGateRoute {
|
|
4
|
+
secure?: boolean;
|
|
5
|
+
noAuth?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Enforce auth for a matched route.
|
|
9
|
+
*
|
|
10
|
+
* Returns `true` when the request is REJECTED — a 401 has already been written
|
|
11
|
+
* to `res.raw` and the caller must stop (not run the handler). Returns `false`
|
|
12
|
+
* when the route is public OR a valid token was presented (in which case
|
|
13
|
+
* `req.user` is populated and, for a body formToken, a `FreshToken` header is
|
|
14
|
+
* set). Auth is enforced only for a route that is `secure` and not `noAuth`,
|
|
15
|
+
* and never for `/__dev` dev-admin routes.
|
|
16
|
+
*
|
|
17
|
+
* Token sources, in priority order: `Authorization: Bearer` header, a
|
|
18
|
+
* `formToken` in the parsed body, then a session token.
|
|
19
|
+
*/
|
|
20
|
+
export declare function enforceRouteAuth(req: Tina4Request, res: Tina4Response, match: AuthGateRoute, isDevAdmin: boolean): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background tasks — periodic callbacks that run alongside the HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Python's `tina4_python.core.server.background(fn, interval=1.0)`.
|
|
5
|
+
* Use this instead of `setInterval` directly, so timers integrate with the
|
|
6
|
+
* server lifecycle and clear cleanly on graceful shutdown (SIGTERM/SIGINT)
|
|
7
|
+
* or when `stopAllBackgroundTasks()` is called.
|
|
8
|
+
*
|
|
9
|
+
* import { background } from "@tina4/core";
|
|
10
|
+
*
|
|
11
|
+
* background(() => processQueue(), 2); // every 2 seconds
|
|
12
|
+
* background(async () => await healthCheck(), 30); // async also fine
|
|
13
|
+
*
|
|
14
|
+
* Errors thrown from a callback are caught and logged so a single failing
|
|
15
|
+
* task cannot bring down the rest of the timer wheel.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Register a callback to run periodically alongside the HTTP server.
|
|
19
|
+
*
|
|
20
|
+
* @param callback Function to call (sync or async, no arguments).
|
|
21
|
+
* @param intervalSeconds Seconds between invocations (default: 1).
|
|
22
|
+
* @returns A handle whose `stop()` clears just this one task.
|
|
23
|
+
*/
|
|
24
|
+
export declare function background(callback: () => unknown | Promise<unknown>, intervalSeconds?: number): {
|
|
25
|
+
stop: () => void;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Clear every registered background task. Called automatically on SIGTERM/SIGINT;
|
|
29
|
+
* also called from the server's `close()` so a manual server shutdown stops
|
|
30
|
+
* the timer wheel along with HTTP listeners.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stopAllBackgroundTasks(): void;
|
|
33
|
+
/** Number of currently-registered background tasks (test helper). */
|
|
34
|
+
export declare function backgroundTaskCount(): number;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-backend response cache for GET requests.
|
|
3
|
+
*
|
|
4
|
+
* Backends are selected via the TINA4_CACHE_BACKEND env var:
|
|
5
|
+
* memory — in-process LRU cache (default, zero deps)
|
|
6
|
+
* file — JSON files in data/cache/
|
|
7
|
+
* redis — Redis (raw RESP over TCP, or the `redis` package when present)
|
|
8
|
+
* valkey — Valkey (Redis wire protocol — reuses the Redis backend)
|
|
9
|
+
* memcached — Memcached (zero-dep text protocol over TCP; SHA-256-hashed keys)
|
|
10
|
+
* mongodb — MongoDB TTL collection (optional `mongodb` driver, loaded dynamically)
|
|
11
|
+
* database — a `tina4_cache` table in any Tina4-supported DB (via @tina4/orm)
|
|
12
|
+
*
|
|
13
|
+
* Usage (the KV/module API is ASYNC on Node — Node is async-everywhere):
|
|
14
|
+
* import { responseCache, cacheGet, cacheSet, cacheDelete, cacheClear, cacheStats } from "./cache.js";
|
|
15
|
+
*
|
|
16
|
+
* // As middleware — caches GET responses for ttl seconds
|
|
17
|
+
* middleware.use(responseCache({ ttl: 60 }));
|
|
18
|
+
*
|
|
19
|
+
* // Direct usage (await — same semantics as the other 3 languages, async transport)
|
|
20
|
+
* await cacheSet("key", {"data": "value"}, 120);
|
|
21
|
+
* const value = await cacheGet("key");
|
|
22
|
+
* await cacheDelete("key");
|
|
23
|
+
* await cacheClear();
|
|
24
|
+
* const stats = await cacheStats();
|
|
25
|
+
*
|
|
26
|
+
* Availability + file-fallback (mirrors the Python master):
|
|
27
|
+
* Each network/driver backend reports availability (redis/valkey connect+AUTH+PING,
|
|
28
|
+
* memcached VERSION, mongo connect+ping, database connect). When the configured
|
|
29
|
+
* backend's service is unreachable (or its driver is missing / credentials are
|
|
30
|
+
* wrong), createBackend() logs a warning and falls back to the `file` backend —
|
|
31
|
+
* a real, persistent cache, never a silent no-op. The probe is asynchronous, so
|
|
32
|
+
* createBackend() returns a Promise.
|
|
33
|
+
*
|
|
34
|
+
* Asynchronous, NATIVE network I/O (NO child process):
|
|
35
|
+
* The CacheBackend interface is async (get/set/delete/clear/stats return
|
|
36
|
+
* Promises). The network backends use native async Node I/O — redis/valkey speak
|
|
37
|
+
* RESP over a node:net socket (with AUTH + SELECT db), memcached speaks its text
|
|
38
|
+
* protocol over node:net, and mongodb uses the optional `mongodb` driver. No
|
|
39
|
+
* execFileSync, no child processes — connections are pooled per backend instance
|
|
40
|
+
* so each cache op is a single async round-trip (~sub-ms locally), not a ~30-80ms
|
|
41
|
+
* process spawn. Local backends (memory/file/database-sqlite) resolve immediately.
|
|
42
|
+
*
|
|
43
|
+
* Environment (LOCKED — matches Python exactly):
|
|
44
|
+
* TINA4_CACHE_BACKEND — memory | file | redis | valkey | memcached | mongodb | database (default: memory)
|
|
45
|
+
* TINA4_CACHE_URL — connection URL (redis/valkey/memcached/mongo), or a SQL URL for `database`
|
|
46
|
+
* (database falls back to TINA4_DATABASE_URL)
|
|
47
|
+
* TINA4_CACHE_TTL — default TTL in seconds (default: 60)
|
|
48
|
+
* TINA4_CACHE_MAX_ENTRIES — max entries (default: 1000)
|
|
49
|
+
* TINA4_CACHE_DIR — file backend directory (default: data/cache)
|
|
50
|
+
* TINA4_CACHE_USERNAME — credentials when not embedded in the URL
|
|
51
|
+
* TINA4_CACHE_PASSWORD — credentials when not embedded in the URL
|
|
52
|
+
*/
|
|
53
|
+
import type { Middleware } from "./types.js";
|
|
54
|
+
export interface ResponseCacheConfig {
|
|
55
|
+
/** Default TTL in seconds. 0 = disabled. Default: 60 */
|
|
56
|
+
ttl?: number;
|
|
57
|
+
/** Maximum cache entries. Default: 1000 */
|
|
58
|
+
maxEntries?: number;
|
|
59
|
+
/** Only cache these status codes. Default: [200] */
|
|
60
|
+
statusCodes?: number[];
|
|
61
|
+
/** Cache backend: memory | redis | file. Default: from env or memory */
|
|
62
|
+
backend?: string;
|
|
63
|
+
/** Redis URL. Default: from env or redis://localhost:6379 */
|
|
64
|
+
cacheUrl?: string;
|
|
65
|
+
/** File cache directory. Default: from env or data/cache */
|
|
66
|
+
cacheDir?: string;
|
|
67
|
+
}
|
|
68
|
+
interface CacheBackend {
|
|
69
|
+
get(key: string): Promise<unknown | undefined>;
|
|
70
|
+
set(key: string, value: unknown, ttl: number): Promise<void>;
|
|
71
|
+
delete(key: string): Promise<boolean>;
|
|
72
|
+
clear(): Promise<void>;
|
|
73
|
+
stats(): Promise<{
|
|
74
|
+
hits: number;
|
|
75
|
+
misses: number;
|
|
76
|
+
size: number;
|
|
77
|
+
backend: string;
|
|
78
|
+
}>;
|
|
79
|
+
name(): string;
|
|
80
|
+
/**
|
|
81
|
+
* Whether this backend is actually usable (driver present + service
|
|
82
|
+
* reachable). Local backends (memory/file) are always available; network /
|
|
83
|
+
* driver backends override this so the factory can fall back to the file
|
|
84
|
+
* backend. Mirrors the Python master's `is_available()`. Probed asynchronously
|
|
85
|
+
* (connect/AUTH/PING/VERSION/ping) so no child process is spawned.
|
|
86
|
+
*/
|
|
87
|
+
isAvailable?(): Promise<boolean>;
|
|
88
|
+
/** One-time async connect/probe. Resolves once the backend has decided
|
|
89
|
+
* availability; createBackend() awaits this before falling back to file. */
|
|
90
|
+
ready?(): Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
/** Public shape of a unified cache backend (for cross-package reuse). */
|
|
93
|
+
export type { CacheBackend };
|
|
94
|
+
/**
|
|
95
|
+
* Build a unified cache backend from explicit params or env vars.
|
|
96
|
+
*
|
|
97
|
+
* Backends: memory (default) | file | redis | valkey | memcached | mongodb |
|
|
98
|
+
* database. Unreachable network/driver backends fall back to the file backend.
|
|
99
|
+
* ASYNC because availability is probed asynchronously (connect/AUTH/PING/ping)
|
|
100
|
+
* — no child process. Exported so @tina4/orm can route its persistent DB query
|
|
101
|
+
* cache through the SAME backends (shared cross-instance) without duplicating
|
|
102
|
+
* the implementation. Callers `await createBackend(...)`.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createBackend(config?: {
|
|
105
|
+
backend?: string;
|
|
106
|
+
cacheUrl?: string;
|
|
107
|
+
cacheDir?: string;
|
|
108
|
+
maxEntries?: number;
|
|
109
|
+
}): Promise<CacheBackend>;
|
|
110
|
+
/**
|
|
111
|
+
* Response cache middleware for GET requests.
|
|
112
|
+
* Caches the full response body, content-type, and status code through the
|
|
113
|
+
* unified async backend. Cache key is method + url (including query string).
|
|
114
|
+
*
|
|
115
|
+
* The middleware is ASYNC: the before-path awaits `backend.get` (serve hit) and
|
|
116
|
+
* the after-path awaits `backend.set` (store on the captured `res.raw.end`).
|
|
117
|
+
* The framework's middleware chain (`runRouteMiddlewares` / `MiddlewareChain`)
|
|
118
|
+
* already awaits middleware, so async is transparent. Honors ttl/statusCodes/
|
|
119
|
+
* maxEntries. With the default `memory` backend behaviour is unchanged; a
|
|
120
|
+
* redis/etc. backend distributes cross-instance.
|
|
121
|
+
*/
|
|
122
|
+
export declare function responseCache(config?: ResponseCacheConfig): Middleware;
|
|
123
|
+
/**
|
|
124
|
+
* Clear all cached responses (the responseCache middleware backend).
|
|
125
|
+
* ASYNC on Node — callers `await clearCache()` — because the backend may be a
|
|
126
|
+
* network backend (redis/etc.). Resets the backend's namespace; mirrors the
|
|
127
|
+
* Python ResponseCache.clear_cache() which clears its backend.
|
|
128
|
+
*/
|
|
129
|
+
export declare function clearCache(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Get KV cache stats — reports the same backend that cacheGet/cacheSet/cacheDelete use,
|
|
132
|
+
* so a value stored via cacheSet() is reflected here. Mirrors cache_stats() in the
|
|
133
|
+
* Python / PHP / Ruby frameworks. (Identical to cacheBackendStats(), kept for parity naming.)
|
|
134
|
+
* ASYNC on Node — callers `await cacheStats()`.
|
|
135
|
+
*/
|
|
136
|
+
export declare function cacheStats(): Promise<{
|
|
137
|
+
hits: number;
|
|
138
|
+
misses: number;
|
|
139
|
+
size: number;
|
|
140
|
+
backend: string;
|
|
141
|
+
}>;
|
|
142
|
+
/** Get a value from the cache by key. Returns undefined on miss. */
|
|
143
|
+
export declare function cacheGet(key: string): Promise<unknown | undefined>;
|
|
144
|
+
/** Store a value in the cache with optional TTL (seconds). */
|
|
145
|
+
export declare function cacheSet(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
146
|
+
/** Delete a key from the cache. Returns true if it existed. */
|
|
147
|
+
export declare function cacheDelete(key: string): Promise<boolean>;
|
|
148
|
+
/** Clear all entries from the cache. */
|
|
149
|
+
export declare function cacheClear(): Promise<void>;
|
|
150
|
+
/** Remove expired entries from the cache. Returns count removed. */
|
|
151
|
+
export declare function sweep(): Promise<number>;
|
|
152
|
+
/** Return cache statistics from the active backend. */
|
|
153
|
+
export declare function cacheBackendStats(): Promise<{
|
|
154
|
+
hits: number;
|
|
155
|
+
misses: number;
|
|
156
|
+
size: number;
|
|
157
|
+
backend: string;
|
|
158
|
+
}>;
|
|
159
|
+
/** Reset the default backend (for testing). Closes any pooled connection. */
|
|
160
|
+
export declare function _resetBackend(): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tina4 Constants — HTTP status codes and content types.
|
|
3
|
+
*
|
|
4
|
+
* Standard constants for use in route handlers across all Tina4 frameworks.
|
|
5
|
+
*
|
|
6
|
+
* import { HTTP_OK, HTTP_CREATED, APPLICATION_JSON } from "@tina4/core";
|
|
7
|
+
*
|
|
8
|
+
* get("/api/users", async (request, response) => {
|
|
9
|
+
* return response(users, HTTP_OK);
|
|
10
|
+
* });
|
|
11
|
+
*/
|
|
12
|
+
export declare const HTTP_OK = 200;
|
|
13
|
+
export declare const HTTP_CREATED = 201;
|
|
14
|
+
export declare const HTTP_ACCEPTED = 202;
|
|
15
|
+
export declare const HTTP_NO_CONTENT = 204;
|
|
16
|
+
export declare const HTTP_MOVED = 301;
|
|
17
|
+
export declare const HTTP_REDIRECT = 302;
|
|
18
|
+
export declare const HTTP_NOT_MODIFIED = 304;
|
|
19
|
+
export declare const HTTP_BAD_REQUEST = 400;
|
|
20
|
+
export declare const HTTP_UNAUTHORIZED = 401;
|
|
21
|
+
export declare const HTTP_FORBIDDEN = 403;
|
|
22
|
+
export declare const HTTP_NOT_FOUND = 404;
|
|
23
|
+
export declare const HTTP_METHOD_NOT_ALLOWED = 405;
|
|
24
|
+
export declare const HTTP_CONFLICT = 409;
|
|
25
|
+
export declare const HTTP_GONE = 410;
|
|
26
|
+
export declare const HTTP_UNPROCESSABLE = 422;
|
|
27
|
+
export declare const HTTP_TOO_MANY = 429;
|
|
28
|
+
export declare const HTTP_SERVER_ERROR = 500;
|
|
29
|
+
export declare const HTTP_BAD_GATEWAY = 502;
|
|
30
|
+
export declare const HTTP_UNAVAILABLE = 503;
|
|
31
|
+
export declare const APPLICATION_JSON = "application/json";
|
|
32
|
+
export declare const APPLICATION_XML = "application/xml";
|
|
33
|
+
export declare const APPLICATION_FORM = "application/x-www-form-urlencoded";
|
|
34
|
+
export declare const APPLICATION_OCTET = "application/octet-stream";
|
|
35
|
+
export declare const TEXT_HTML = "text/html; charset=utf-8";
|
|
36
|
+
export declare const TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
37
|
+
export declare const TEXT_CSV = "text/csv";
|
|
38
|
+
export declare const TEXT_XML = "text/xml";
|