tina4-nodejs 3.13.137 → 3.13.138
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 +19466 -18048
- 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 +19458 -18043
- 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 +15 -3
- package/packages/core/src/auth.ts +21 -8
- package/packages/core/src/authGate.ts +8 -0
- 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 +16 -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 +8 -0
- package/packages/core/src/job.ts +8 -0
- package/packages/core/src/logger.ts +8 -0
- package/packages/core/src/mcp.test.ts +8 -0
- package/packages/core/src/mcp.ts +8 -0
- package/packages/core/src/messenger.ts +143 -86
- package/packages/core/src/metrics.ts +13 -0
- package/packages/core/src/middleware.ts +1178 -1096
- 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 +8 -0
- package/packages/core/src/queue.ts +8 -0
- package/packages/core/src/queueBackends/kafkaBackend.ts +8 -0
- package/packages/core/src/queueBackends/liteBackend.ts +8 -0
- package/packages/core/src/queueBackends/mongoBackend.ts +21 -8
- 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 +73 -24
- 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 +8 -0
- 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 +8 -0
- package/packages/core/src/static.ts +8 -0
- package/packages/core/src/test.ts +8 -0
- package/packages/core/src/testClient.ts +8 -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 +8 -0
- 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 +151 -17
- package/packages/frond/src/engine.ts +177 -17
- package/packages/frond/src/index.ts +8 -0
- package/packages/orm/dist/index.js +8125 -6708
- 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/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 +0 -21
- package/types/core/src/htmlElement.d.ts +0 -15
- 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/queueBackends/mongoBackend.d.ts +2 -0
- 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/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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
(function(){"use strict";(()=>{try{const t=window.location.pathname||"";return t.startsWith("/__dev")||t.startsWith("/__feedback")}catch{return!1}})()?console.info("tina4-feedback-widget: skipping on developer path"):window.__tina4FeedbackLoaded?console.warn("tina4-feedback-widget already loaded; skipping"):(window.__tina4FeedbackLoaded=!0,b());function b(){const c=(getComputedStyle(document.documentElement).getPropertyValue("--primary")||"").trim()||"#3b82f6";h(c);const l=m();document.body.appendChild(l);let e=null,u;const r=[];l.addEventListener("click",()=>{if(e){e.remove(),e=null,l.style.display="";return}e=g(),document.body.appendChild(e),l.style.display="none",setTimeout(()=>e?.querySelector("textarea")?.focus(),0)});function g(){const o=document.createElement("div");o.className="tina4-fb-modal",o.innerHTML=`
|
|
2
10
|
<div class="tina4-fb-head">
|
|
3
11
|
<span class="tina4-fb-title">Tell us what's not working</span>
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Last-resort finder for `@tina4/core/<subpath>` under Node's ESM resolver.
|
|
3
11
|
*
|
package/packages/core/src/ai.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Tina4 AI — Install AI coding assistant context files.
|
|
3
11
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/** Zero-dependency app-facing AI client (ADR-0053 + ADR-0060). */
|
|
2
10
|
import http, { type IncomingMessage } from "node:http";
|
|
3
11
|
import https from "node:https";
|
package/packages/core/src/api.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Tina4 API Client — HTTP client using Node.js built-in modules only.
|
|
3
11
|
*
|
|
@@ -667,7 +675,7 @@ export class Api {
|
|
|
667
675
|
url += (url.includes("?") ? "&" : "?") + qs;
|
|
668
676
|
}
|
|
669
677
|
|
|
670
|
-
const { headers, data } = this.buildRequest("GET", "application/json", undefined);
|
|
678
|
+
const { headers, data } = this.buildRequest("GET", "application/json", undefined, undefined, url);
|
|
671
679
|
|
|
672
680
|
// An injected transport can't stream (it returns a buffered result), so
|
|
673
681
|
// write its body out; only the real network path streams chunk-by-chunk.
|
|
@@ -760,7 +768,7 @@ export class Api {
|
|
|
760
768
|
const url = this.buildUrl(path);
|
|
761
769
|
const method = (opts.method ?? "GET").toUpperCase();
|
|
762
770
|
const contentType = opts.contentType ?? "application/json";
|
|
763
|
-
const { headers, data } = this.buildRequest(method, contentType, opts.body, opts.headers);
|
|
771
|
+
const { headers, data } = this.buildRequest(method, contentType, opts.body, opts.headers, url);
|
|
764
772
|
const totalSec = this.streamSeconds(opts.timeout, "TINA4_API_TIMEOUT", this.timeout);
|
|
765
773
|
const connectSec = this.streamSeconds(opts.connectTimeout, "TINA4_API_CONNECT_TIMEOUT", 10);
|
|
766
774
|
const opened = await this.openStreamRequest(method, url, headers, data, connectSec);
|
|
@@ -904,6 +912,7 @@ export class Api {
|
|
|
904
912
|
contentType: string,
|
|
905
913
|
body: unknown,
|
|
906
914
|
extraHeaders?: Record<string, string>,
|
|
915
|
+
targetUrl?: string,
|
|
907
916
|
): { headers: Record<string, string>; data: Buffer | undefined } {
|
|
908
917
|
const headers: Record<string, string> = { "User-Agent": `Tina4/${TINA4_VERSION}`, ...this.headers };
|
|
909
918
|
if (this.authHeader) {
|
|
@@ -943,6 +952,9 @@ export class Api {
|
|
|
943
952
|
Object.assign(headers, extraHeaders);
|
|
944
953
|
}
|
|
945
954
|
|
|
955
|
+
if (targetUrl !== undefined && !sameOrigin(targetUrl, this.baseUrl)) {
|
|
956
|
+
for (const name of STRIP_ON_CROSS_ORIGIN) deleteHeaderCaseInsensitive(headers, name);
|
|
957
|
+
}
|
|
946
958
|
return { headers, data };
|
|
947
959
|
}
|
|
948
960
|
|
|
@@ -985,7 +997,7 @@ export class Api {
|
|
|
985
997
|
contentType: string = "application/json",
|
|
986
998
|
extraHeaders?: Record<string, string>,
|
|
987
999
|
): Promise<ApiResult> {
|
|
988
|
-
const { headers, data } = this.buildRequest(method, contentType, body, extraHeaders);
|
|
1000
|
+
const { headers, data } = this.buildRequest(method, contentType, body, extraHeaders, url);
|
|
989
1001
|
|
|
990
1002
|
// A user-injected transport fully replaces the network call.
|
|
991
1003
|
if (this.transportFn) {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Tina4 Auth — Zero-dependency JWT, password hashing, and auth middleware.
|
|
3
11
|
*
|
|
@@ -12,7 +20,7 @@
|
|
|
12
20
|
* checkPassword("secret123", hash); // true
|
|
13
21
|
*/
|
|
14
22
|
import { createHmac, createSign, createVerify, pbkdf2Sync, randomBytes, timingSafeEqual } from "node:crypto";
|
|
15
|
-
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
|
23
|
+
import { appendFileSync, existsSync, readFileSync, openSync, closeSync, fstatSync, fchmodSync, constants } from "node:fs";
|
|
16
24
|
import { join } from "node:path";
|
|
17
25
|
import type { Middleware, Tina4Request, Tina4Response } from "./types.js";
|
|
18
26
|
import { isTruthy } from "./dotenv.js";
|
|
@@ -107,14 +115,19 @@ export function ensureDevSecret(cwd?: string): string | null {
|
|
|
107
115
|
const baseDir = cwd ?? process.cwd();
|
|
108
116
|
const envLocalPath = join(baseDir, ".env.local");
|
|
109
117
|
try {
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
if (
|
|
118
|
+
// Read and append through one descriptor so replacing a pathname cannot
|
|
119
|
+
// redirect either operation to an unrelated file.
|
|
120
|
+
const fd = openSync(envLocalPath, constants.O_RDWR | constants.O_APPEND | constants.O_CREAT | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0), 0o600);
|
|
121
|
+
try {
|
|
122
|
+
const info = fstatSync(fd);
|
|
123
|
+
if (!info.isFile() || info.nlink !== 1) throw new Error("Refusing a non-regular or multiply-linked configuration file");
|
|
124
|
+
fchmodSync(fd, 0o600);
|
|
125
|
+
const existing = readFileSync(fd, "utf-8");
|
|
126
|
+
const prefix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
127
|
+
appendFileSync(fd, `${prefix}TINA4_SECRET=${newSecret}\n`);
|
|
128
|
+
} finally {
|
|
129
|
+
closeSync(fd);
|
|
116
130
|
}
|
|
117
|
-
appendFileSync(envLocalPath, `${prefix}TINA4_SECRET=${newSecret}\n`);
|
|
118
131
|
void _logInfo("Auth: generated a development secret, saved to .env.local (gitignored)");
|
|
119
132
|
} catch {
|
|
120
133
|
// Keep the in-memory secret for this run; warn but never crash boot.
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Secure-by-default route auth gate — shared by the live server dispatch and the
|
|
3
11
|
* in-process TestClient so the test surface enforces the IDENTICAL gate as
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Background tasks — periodic callbacks that run alongside the HTTP server.
|
|
3
11
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Multi-backend response cache for GET requests.
|
|
3
11
|
*
|
|
@@ -56,6 +64,7 @@ import * as fs from "node:fs";
|
|
|
56
64
|
import * as path from "node:path";
|
|
57
65
|
import * as crypto from "node:crypto";
|
|
58
66
|
import * as net from "node:net";
|
|
67
|
+
import { optionalPackageMissing } from "./optionalPackage.js";
|
|
59
68
|
|
|
60
69
|
// ── Credential parsing (WHATWG URL or TINA4_CACHE_USERNAME / _PASSWORD) ──
|
|
61
70
|
|
|
@@ -181,6 +190,12 @@ interface CacheBackend {
|
|
|
181
190
|
/** One-time async connect/probe. Resolves once the backend has decided
|
|
182
191
|
* availability; createBackend() awaits this before falling back to file. */
|
|
183
192
|
ready?(): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* When unavailable because the app has not installed the backend's driver
|
|
195
|
+
* (an optional peer, ADR-0067): the actionable install message, appended to
|
|
196
|
+
* the fallback warning. null for every other cause.
|
|
197
|
+
*/
|
|
198
|
+
missingDriver?(): string | null;
|
|
184
199
|
}
|
|
185
200
|
|
|
186
201
|
// ── Memory backend ────────────────────────────────────────────────
|
|
@@ -1141,6 +1156,7 @@ class MongoBackend implements CacheBackend {
|
|
|
1141
1156
|
private misses = 0;
|
|
1142
1157
|
private maxEntries: number;
|
|
1143
1158
|
private available = false;
|
|
1159
|
+
private missingDriverMessage: string | null = null;
|
|
1144
1160
|
private readyPromise: Promise<void>;
|
|
1145
1161
|
// The mongodb driver types aren't depended on at compile time (optional dep).
|
|
1146
1162
|
private client: any = null;
|
|
@@ -1178,8 +1194,15 @@ class MongoBackend implements CacheBackend {
|
|
|
1178
1194
|
try {
|
|
1179
1195
|
// Dynamic import so @tina4/core has no hard dependency on `mongodb` and an
|
|
1180
1196
|
// absent driver degrades to file-fallback (never an import-time crash).
|
|
1181
|
-
|
|
1182
|
-
|
|
1197
|
+
let importError: any = null;
|
|
1198
|
+
const mod: any = await import("mongodb").catch((error) => { importError = error; return null; });
|
|
1199
|
+
if (!mod || !mod.MongoClient) {
|
|
1200
|
+
this.available = false;
|
|
1201
|
+
if (importError?.code === "ERR_MODULE_NOT_FOUND") {
|
|
1202
|
+
this.missingDriverMessage = optionalPackageMissing("the mongodb cache backend", ["mongodb"]).message;
|
|
1203
|
+
}
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1183
1206
|
const client = new mod.MongoClient(this.url, { serverSelectionTimeoutMS: 4000 });
|
|
1184
1207
|
await client.connect();
|
|
1185
1208
|
await client.db(this.dbName).command({ ping: 1 });
|
|
@@ -1200,6 +1223,10 @@ class MongoBackend implements CacheBackend {
|
|
|
1200
1223
|
return this.readyPromise;
|
|
1201
1224
|
}
|
|
1202
1225
|
|
|
1226
|
+
missingDriver(): string | null {
|
|
1227
|
+
return this.missingDriverMessage;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1203
1230
|
async isAvailable(): Promise<boolean> {
|
|
1204
1231
|
await this.readyPromise;
|
|
1205
1232
|
return this.available;
|
|
@@ -1291,6 +1318,7 @@ class DatabaseBackend implements CacheBackend {
|
|
|
1291
1318
|
private misses = 0;
|
|
1292
1319
|
private maxEntries: number;
|
|
1293
1320
|
private available = false;
|
|
1321
|
+
private missingDriverMessage: string | null = null;
|
|
1294
1322
|
private readyPromise: Promise<void>;
|
|
1295
1323
|
// @tina4/orm Database instance (optional dep, loaded dynamically).
|
|
1296
1324
|
private db: any = null;
|
|
@@ -1324,8 +1352,13 @@ class DatabaseBackend implements CacheBackend {
|
|
|
1324
1352
|
try { db.commit(); } catch { /* sqlite autocommits DDL */ }
|
|
1325
1353
|
this.db = db;
|
|
1326
1354
|
this.available = true;
|
|
1327
|
-
} catch {
|
|
1355
|
+
} catch (error) {
|
|
1328
1356
|
this.available = false;
|
|
1357
|
+
// The ORM adapters already phrase a missing driver as the install
|
|
1358
|
+
// command; carry THAT through, and nothing else (a connect error can
|
|
1359
|
+
// name the host and user).
|
|
1360
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1361
|
+
if (/npm install \S/.test(message)) this.missingDriverMessage = message;
|
|
1329
1362
|
} finally {
|
|
1330
1363
|
if (prevAuto === undefined) delete process.env.TINA4_AUTO_CACHING; else process.env.TINA4_AUTO_CACHING = prevAuto;
|
|
1331
1364
|
if (prevDb === undefined) delete process.env.TINA4_DB_CACHE; else process.env.TINA4_DB_CACHE = prevDb;
|
|
@@ -1336,6 +1369,10 @@ class DatabaseBackend implements CacheBackend {
|
|
|
1336
1369
|
return this.readyPromise;
|
|
1337
1370
|
}
|
|
1338
1371
|
|
|
1372
|
+
missingDriver(): string | null {
|
|
1373
|
+
return this.missingDriverMessage;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1339
1376
|
async isAvailable(): Promise<boolean> {
|
|
1340
1377
|
await this.readyPromise;
|
|
1341
1378
|
return this.available;
|
|
@@ -1531,9 +1568,11 @@ export async function createBackend(config?: {
|
|
|
1531
1568
|
// degrading to a no-op cache. Mirrors the Python master.
|
|
1532
1569
|
if (typeof backend.isAvailable === "function" && !(await backend.isAvailable())) {
|
|
1533
1570
|
// eslint-disable-next-line no-console
|
|
1571
|
+
const installHint = backend.missingDriver?.() ?? null;
|
|
1534
1572
|
console.warn(
|
|
1535
1573
|
`[tina4] Cache backend '${backendName}' is unavailable ` +
|
|
1536
|
-
`(driver missing or service unreachable) — falling back to 'file'
|
|
1574
|
+
`(driver missing or service unreachable) — falling back to 'file'.` +
|
|
1575
|
+
(installHint ? ` ${installHint}` : ""),
|
|
1537
1576
|
);
|
|
1538
1577
|
return new FileBackend(cacheDir(), maxEntries);
|
|
1539
1578
|
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Tina4 Constants — HTTP status codes and content types.
|
|
3
11
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
/**
|
|
2
10
|
* Lightweight dependency injection container.
|
|
3
11
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
// Tina4 Node.js
|
|
2
10
|
//
|
|
3
11
|
// Text folding + chunking for the Context subsystem.
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2026 Code Infinity
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
This Source Code Form is subject to the terms of the Mozilla Public
|
|
5
|
+
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
6
|
+
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
// Tina4 Node.js
|
|
2
10
|
//
|
|
3
11
|
// Context — a native, zero-dependency code/doc grounding index.
|