@zintrust/core 0.9.5 → 1.2.0
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/package.json +8 -22
- package/src/cli/commands/EnvKeyGenerateCommand.js +1 -1
- package/src/index.js +3 -3
- package/src/proxy/CloudflareProxyShared.d.ts +4 -17
- package/src/proxy/CloudflareProxyShared.d.ts.map +1 -1
- package/src/proxy/CloudflareProxyShared.js +2 -38
- package/src/proxy/WorkerSigning.d.ts +33 -0
- package/src/proxy/WorkerSigning.d.ts.map +1 -0
- package/src/proxy/WorkerSigning.js +77 -0
- package/src/proxy.d.ts +1 -2
- package/src/proxy.d.ts.map +1 -1
- package/src/proxy.js +1 -2
- package/src/runtime/WorkerAdapterImports.d.ts +2 -2
- package/src/runtime/WorkerAdapterImports.js +1 -1
- package/src/templates/project/basic/routes/storage.ts.tpl +25 -0
- package/src/tools/http/Http.d.ts.map +1 -1
- package/src/tools/http/Http.js +97 -25
- package/src/zintrust.plugins.d.ts +3 -6
- package/src/zintrust.plugins.d.ts.map +1 -1
- package/src/zintrust.plugins.js +3 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Production-grade TypeScript backend framework for JavaScript",
|
|
5
5
|
"homepage": "https://zintrust.com",
|
|
6
6
|
"repository": {
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"axios": "^1.15.0",
|
|
74
74
|
"@eslint/plugin-kit": "^0.7.1",
|
|
75
75
|
"follow-redirects": "^1.16.0",
|
|
76
|
-
"@tootallnate/once": "
|
|
76
|
+
"@tootallnate/once": "3.0.1",
|
|
77
77
|
"node-forge": "^1.4.0",
|
|
78
|
-
"fast-xml-parser": "
|
|
78
|
+
"fast-xml-parser": "5.7.1",
|
|
79
79
|
"brace-expansion": "^5.0.5",
|
|
80
80
|
"picomatch": "^4.0.4",
|
|
81
81
|
"cross-spawn": "^7.0.5",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"rollup": "^4.59.0",
|
|
85
85
|
"vite": "^8.0.5",
|
|
86
86
|
"flatted": "^3.4.2",
|
|
87
|
-
"uuid": "
|
|
87
|
+
"uuid": "14.0.0",
|
|
88
88
|
"@actions/github": {
|
|
89
89
|
"undici": "^6.24.0"
|
|
90
90
|
},
|
|
@@ -94,24 +94,10 @@
|
|
|
94
94
|
"miniflare": {
|
|
95
95
|
"undici": "^7.24.4"
|
|
96
96
|
},
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"
|
|
101
|
-
"fast-xml-parser": "^5.7.1"
|
|
102
|
-
},
|
|
103
|
-
"@google-cloud/storage": {
|
|
104
|
-
"uuid": "^14.0.0"
|
|
105
|
-
},
|
|
106
|
-
"@google-cloud/storage@7.19.0": {
|
|
107
|
-
"uuid": "^14.0.0"
|
|
108
|
-
},
|
|
109
|
-
"gaxios": {
|
|
110
|
-
"uuid": "^14.0.0"
|
|
111
|
-
},
|
|
112
|
-
"teeny-request": {
|
|
113
|
-
"uuid": "^14.0.0"
|
|
114
|
-
}
|
|
97
|
+
"http-proxy-agent": "7.0.2",
|
|
98
|
+
"retry-request": "8.0.2",
|
|
99
|
+
"gaxios": "7.1.4",
|
|
100
|
+
"teeny-request": "10.1.2"
|
|
115
101
|
},
|
|
116
102
|
"bin": {
|
|
117
103
|
"zintrust": "bin/zintrust.js",
|
|
@@ -78,7 +78,7 @@ export const EnvKeyGenerateCommand = Object.freeze({
|
|
|
78
78
|
}
|
|
79
79
|
envContent = upsertEnvValue(envContent, envKey, key);
|
|
80
80
|
await fs.writeFile(envPath, envContent);
|
|
81
|
-
Logger.info(`${envKey} set successfully
|
|
81
|
+
Logger.info(`${envKey} set successfully.`);
|
|
82
82
|
}
|
|
83
83
|
catch (error) {
|
|
84
84
|
Logger.error(`Failed to update ${envKey} in .env`, error);
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core
|
|
2
|
+
* @zintrust/core v1.2.0
|
|
3
3
|
*
|
|
4
4
|
* ZinTrust Framework - Production-Grade TypeScript Backend
|
|
5
5
|
* Built for performance, type safety, and exceptional developer experience
|
|
6
6
|
*
|
|
7
7
|
* Build Information:
|
|
8
|
-
* Built: 2026-04-
|
|
8
|
+
* Built: 2026-04-24T08:45:23.492Z
|
|
9
9
|
* Node: >=20.0.0
|
|
10
10
|
* License: MIT
|
|
11
11
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Available at runtime for debugging and health checks
|
|
22
22
|
*/
|
|
23
23
|
export const ZINTRUST_VERSION = '0.1.41';
|
|
24
|
-
export const ZINTRUST_BUILD_DATE = '2026-04-
|
|
24
|
+
export const ZINTRUST_BUILD_DATE = '2026-04-24T08:45:23.460Z'; // Replaced during build
|
|
25
25
|
export { Application } from './boot/Application.js';
|
|
26
26
|
export { AwsSigV4 } from './common/index.js';
|
|
27
27
|
export { SignedRequest } from './security/SignedRequest.js';
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export type ProxyNonceNamespace = {
|
|
5
|
-
get: (key: string) => Promise<string | null>;
|
|
6
|
-
put: (key: string, value: string, options?: ProxyNoncePutOptions) => Promise<void>;
|
|
7
|
-
};
|
|
8
|
-
type SignedRequestOptions = Readonly<{
|
|
9
|
-
secretEnvVar: string;
|
|
10
|
-
missingSecretStatus: number;
|
|
11
|
-
missingSecretMessage: string;
|
|
12
|
-
defaultSigningWindowMs: number;
|
|
13
|
-
}>;
|
|
14
|
-
type ReadAndVerifyJsonOptions = SignedRequestOptions & Readonly<{
|
|
1
|
+
import type { WorkerSigningOptions } from './WorkerSigning';
|
|
2
|
+
export type { ProxyNonceNamespace, ProxyNoncePutOptions, WorkerSigningOptions, } from './WorkerSigning';
|
|
3
|
+
type ReadAndVerifyJsonOptions = WorkerSigningOptions & Readonly<{
|
|
15
4
|
defaultMaxBodyBytes: number;
|
|
16
5
|
}>;
|
|
17
6
|
type ProxyRequestEnv = object;
|
|
@@ -34,8 +23,7 @@ export declare const parseOptionalJson: (text: string) => {
|
|
|
34
23
|
ok: false;
|
|
35
24
|
response: Response;
|
|
36
25
|
};
|
|
37
|
-
export declare const
|
|
38
|
-
export declare const verifySignedRequest: (request: Request, env: ProxyRequestEnv, bodyBytes: Uint8Array, options: SignedRequestOptions) => Promise<Response | {
|
|
26
|
+
export declare const verifySignedRequest: (request: Request, env: ProxyRequestEnv, bodyBytes: Uint8Array, options: WorkerSigningOptions) => Promise<Response | {
|
|
39
27
|
ok: true;
|
|
40
28
|
}>;
|
|
41
29
|
export declare const readAndVerifyJson: (request: Request, env: ProxyRequestEnv, options: ReadAndVerifyJsonOptions) => Promise<{
|
|
@@ -46,5 +34,4 @@ export declare const readAndVerifyJson: (request: Request, env: ProxyRequestEnv,
|
|
|
46
34
|
ok: false;
|
|
47
35
|
response: Response;
|
|
48
36
|
}>;
|
|
49
|
-
export {};
|
|
50
37
|
//# sourceMappingURL=CloudflareProxyShared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudflareProxyShared.d.ts","sourceRoot":"","sources":["../../../src/proxy/CloudflareProxyShared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CloudflareProxyShared.d.ts","sourceRoot":"","sources":["../../../src/proxy/CloudflareProxyShared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,KAAK,wBAAwB,GAAG,oBAAoB,GAClD,QAAQ,CAAC;IACP,mBAAmB,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEL,KAAK,eAAe,GAAG,MAAM,CAAC;AAE9B,eAAO,MAAM,IAAI,GAAI,QAAQ,MAAM,EAAE,MAAM,OAAO,KAAG,QAQpD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,QAG/E,CAAC;AAMF,eAAO,MAAM,SAAS,GAAI,KAAK,eAAe,EAAE,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAKhF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,IAI9D,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAS,OAAO,EAChB,UAAU,MAAM,KACf,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAY3F,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,KACX;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAezF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,KAAK,eAAe,EACpB,WAAW,UAAU,EACrB,SAAS,oBAAoB,KAC5B,OAAO,CAAC,QAAQ,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAQjC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,SAAS,OAAO,EAChB,KAAK,eAAe,EACpB,SAAS,wBAAwB,KAChC,OAAO,CACN;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,GAC5E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAapC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isString } from '../helper/index.js';
|
|
2
2
|
import { ErrorHandler } from './ErrorHandler.js';
|
|
3
3
|
import { RequestValidator } from './RequestValidator.js';
|
|
4
|
-
import {
|
|
4
|
+
import { WorkerSigning } from './WorkerSigning.js';
|
|
5
5
|
export const json = (status, body) => {
|
|
6
6
|
return new Response(JSON.stringify(body), {
|
|
7
7
|
status,
|
|
@@ -59,44 +59,8 @@ export const parseOptionalJson = (text) => {
|
|
|
59
59
|
}
|
|
60
60
|
return { ok: true, payload: parsed.value };
|
|
61
61
|
};
|
|
62
|
-
const loadSigningSecret = (env, secretEnvVar) => {
|
|
63
|
-
const directValue = getEnvValue(env, secretEnvVar);
|
|
64
|
-
const direct = isString(directValue) ? directValue.trim() : '';
|
|
65
|
-
if (direct !== '')
|
|
66
|
-
return direct;
|
|
67
|
-
const fallbackValue = getEnvValue(env, 'APP_KEY');
|
|
68
|
-
const fallback = isString(fallbackValue) ? fallbackValue.trim() : '';
|
|
69
|
-
if (fallback !== '')
|
|
70
|
-
return fallback;
|
|
71
|
-
return null;
|
|
72
|
-
};
|
|
73
|
-
export const verifyNonceKv = async (kv, keyId, nonce, ttlMs) => {
|
|
74
|
-
const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));
|
|
75
|
-
const storageKey = `nonce:${keyId}:${nonce}`;
|
|
76
|
-
const existing = await kv.get(storageKey);
|
|
77
|
-
if (existing !== null)
|
|
78
|
-
return false;
|
|
79
|
-
await kv.put(storageKey, '1', { expirationTtl: ttlSeconds });
|
|
80
|
-
return true;
|
|
81
|
-
};
|
|
82
62
|
export const verifySignedRequest = async (request, env, bodyBytes, options) => {
|
|
83
|
-
const
|
|
84
|
-
if (secret === null) {
|
|
85
|
-
return toErrorResponse(options.missingSecretStatus, 'CONFIG_ERROR', options.missingSecretMessage);
|
|
86
|
-
}
|
|
87
|
-
const windowMs = getEnvInt(env, 'ZT_PROXY_SIGNING_WINDOW_MS', options.defaultSigningWindowMs);
|
|
88
|
-
const nonceStore = getEnvValue(env, 'ZT_NONCES');
|
|
89
|
-
const verifyResult = await SigningService.verifyWithKeyProvider({
|
|
90
|
-
method: request.method,
|
|
91
|
-
url: request.url,
|
|
92
|
-
body: bodyBytes,
|
|
93
|
-
headers: request.headers,
|
|
94
|
-
windowMs,
|
|
95
|
-
getSecretForKeyId: (_keyId) => secret,
|
|
96
|
-
verifyNonce: nonceStore === undefined || nonceStore === null
|
|
97
|
-
? undefined
|
|
98
|
-
: async (keyId, nonce, ttlMs) => verifyNonceKv(nonceStore, keyId, nonce, ttlMs),
|
|
99
|
-
});
|
|
63
|
+
const verifyResult = await WorkerSigning.verifySignedRequest(request, env, bodyBytes, options);
|
|
100
64
|
if (!verifyResult.ok) {
|
|
101
65
|
return toErrorResponse(verifyResult.status, verifyResult.code, verifyResult.message);
|
|
102
66
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ProxyNoncePutOptions = {
|
|
2
|
+
expirationTtl?: number;
|
|
3
|
+
};
|
|
4
|
+
export type ProxyNonceNamespace = {
|
|
5
|
+
get: (key: string) => Promise<string | null>;
|
|
6
|
+
put: (key: string, value: string, options?: ProxyNoncePutOptions) => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
export type WorkerSigningOptions = Readonly<{
|
|
9
|
+
secretEnvVar: string;
|
|
10
|
+
missingSecretStatus: number;
|
|
11
|
+
missingSecretMessage: string;
|
|
12
|
+
defaultSigningWindowMs: number;
|
|
13
|
+
}>;
|
|
14
|
+
type WorkerRequestEnv = object;
|
|
15
|
+
type WorkerSigningResult = {
|
|
16
|
+
ok: true;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
status: number;
|
|
20
|
+
code: string;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const WorkerSigning: Readonly<{
|
|
24
|
+
verifyNonceKv: (kv: ProxyNonceNamespace, keyId: string, nonce: string, ttlMs: number) => Promise<boolean>;
|
|
25
|
+
verifySignedRequest: (request: Request, env: WorkerRequestEnv, bodyBytes: Uint8Array, options: WorkerSigningOptions) => Promise<WorkerSigningResult | {
|
|
26
|
+
ok: false;
|
|
27
|
+
status: number;
|
|
28
|
+
code: "CONFIG_ERROR";
|
|
29
|
+
message: string;
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=WorkerSigning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkerSigning.d.ts","sourceRoot":"","sources":["../../../src/proxy/WorkerSigning.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC,CAAC;AAEH,KAAK,gBAAgB,GAAG,MAAM,CAAC;AAE/B,KAAK,mBAAmB,GACpB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAkGjE,eAAO,MAAM,aAAa;wBAlDpB,mBAAmB,SAChB,MAAM,SACN,MAAM,SACN,MAAM,KACZ,OAAO,CAAC,OAAO,CAAC;mCAUR,OAAO,OACX,gBAAgB,aACV,UAAU,WACZ,oBAAoB,KAC5B,OAAO,CACR,mBAAmB,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAC3F;EAiCC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { isString } from '../helper/index.js';
|
|
2
|
+
import { SignedRequest } from '../security/SignedRequest.js';
|
|
3
|
+
const getEnvValue = (env, name) => {
|
|
4
|
+
return env[name];
|
|
5
|
+
};
|
|
6
|
+
const getEnvInt = (env, name, fallback) => {
|
|
7
|
+
const raw = getEnvValue(env, name);
|
|
8
|
+
if (!isString(raw))
|
|
9
|
+
return fallback;
|
|
10
|
+
const parsed = Number.parseInt(raw, 10);
|
|
11
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
12
|
+
};
|
|
13
|
+
const loadSigningSecret = (env, secretEnvVar) => {
|
|
14
|
+
const directValue = getEnvValue(env, secretEnvVar);
|
|
15
|
+
const direct = isString(directValue) ? directValue.trim() : '';
|
|
16
|
+
if (direct !== '')
|
|
17
|
+
return direct;
|
|
18
|
+
const fallbackValue = getEnvValue(env, 'APP_KEY');
|
|
19
|
+
const fallback = isString(fallbackValue) ? fallbackValue.trim() : '';
|
|
20
|
+
if (fallback !== '')
|
|
21
|
+
return fallback;
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
const mapVerifyResult = (result) => {
|
|
25
|
+
if (result.ok)
|
|
26
|
+
return { ok: true };
|
|
27
|
+
if (result.code === 'MISSING_HEADER' || result.code === 'INVALID_TIMESTAMP') {
|
|
28
|
+
return { ok: false, status: 401, code: result.code, message: result.message };
|
|
29
|
+
}
|
|
30
|
+
if (result.code === 'EXPIRED') {
|
|
31
|
+
return { ok: false, status: 401, code: result.code, message: result.message };
|
|
32
|
+
}
|
|
33
|
+
if (result.code === 'UNKNOWN_KEY') {
|
|
34
|
+
return { ok: false, status: 403, code: result.code, message: result.message };
|
|
35
|
+
}
|
|
36
|
+
if (result.code === 'REPLAYED') {
|
|
37
|
+
return { ok: false, status: 409, code: result.code, message: result.message };
|
|
38
|
+
}
|
|
39
|
+
return { ok: false, status: 403, code: result.code, message: result.message };
|
|
40
|
+
};
|
|
41
|
+
const verifyNonceKv = async (kv, keyId, nonce, ttlMs) => {
|
|
42
|
+
const ttlSeconds = Math.max(1, Math.ceil(ttlMs / 1000));
|
|
43
|
+
const storageKey = `nonce:${keyId}:${nonce}`;
|
|
44
|
+
const existing = await kv.get(storageKey);
|
|
45
|
+
if (existing !== null)
|
|
46
|
+
return false;
|
|
47
|
+
await kv.put(storageKey, '1', { expirationTtl: ttlSeconds });
|
|
48
|
+
return true;
|
|
49
|
+
};
|
|
50
|
+
const verifySignedRequest = async (request, env, bodyBytes, options) => {
|
|
51
|
+
const secret = loadSigningSecret(env, options.secretEnvVar);
|
|
52
|
+
if (secret === null) {
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
status: options.missingSecretStatus,
|
|
56
|
+
code: 'CONFIG_ERROR',
|
|
57
|
+
message: options.missingSecretMessage,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const windowMs = getEnvInt(env, 'ZT_PROXY_SIGNING_WINDOW_MS', options.defaultSigningWindowMs);
|
|
61
|
+
const nonceStore = getEnvValue(env, 'ZT_NONCES');
|
|
62
|
+
return mapVerifyResult(await SignedRequest.verify({
|
|
63
|
+
method: request.method,
|
|
64
|
+
url: request.url,
|
|
65
|
+
body: bodyBytes,
|
|
66
|
+
headers: request.headers,
|
|
67
|
+
windowMs,
|
|
68
|
+
getSecretForKeyId: (_keyId) => secret,
|
|
69
|
+
verifyNonce: nonceStore === undefined || nonceStore === null
|
|
70
|
+
? undefined
|
|
71
|
+
: async (keyId, nonce, ttlMs) => verifyNonceKv(nonceStore, keyId, nonce, ttlMs),
|
|
72
|
+
}));
|
|
73
|
+
};
|
|
74
|
+
export const WorkerSigning = Object.freeze({
|
|
75
|
+
verifyNonceKv,
|
|
76
|
+
verifySignedRequest,
|
|
77
|
+
});
|
package/src/proxy.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
export { RemoteSignedJson } from './common/RemoteSignedJson';
|
|
2
1
|
export { ZintrustD1Proxy } from './proxy/d1/ZintrustD1Proxy';
|
|
3
2
|
export { ErrorHandler } from './proxy/ErrorHandler';
|
|
4
3
|
export { ZintrustKvProxy } from './proxy/kv/ZintrustKvProxy';
|
|
5
4
|
export { RequestValidator } from './proxy/RequestValidator';
|
|
6
|
-
export {
|
|
5
|
+
export { WorkerSigning } from './proxy/WorkerSigning';
|
|
7
6
|
//# sourceMappingURL=proxy.d.ts.map
|
package/src/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|
package/src/proxy.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export { RemoteSignedJson } from './common/RemoteSignedJson.js';
|
|
2
1
|
export { ZintrustD1Proxy } from './proxy/d1/ZintrustD1Proxy.js';
|
|
3
2
|
export { ErrorHandler } from './proxy/ErrorHandler.js';
|
|
4
3
|
export { ZintrustKvProxy } from './proxy/kv/ZintrustKvProxy.js';
|
|
5
4
|
export { RequestValidator } from './proxy/RequestValidator.js';
|
|
6
|
-
export {
|
|
5
|
+
export { WorkerSigning } from './proxy/WorkerSigning.js';
|
|
@@ -22,7 +22,7 @@ const tryImportOptional = async () => {
|
|
|
22
22
|
await tryImportProjectRuntime();
|
|
23
23
|
await import('./WorkerProjectPlugins.js');
|
|
24
24
|
};
|
|
25
|
-
const ready = tryImportOptional();
|
|
25
|
+
const ready = await tryImportOptional();
|
|
26
26
|
export const WorkerAdapterImports = Object.freeze({
|
|
27
27
|
loaded: true,
|
|
28
28
|
ready,
|
|
@@ -8,6 +8,31 @@ import {
|
|
|
8
8
|
} from '@zintrust/core';
|
|
9
9
|
|
|
10
10
|
export function registerStorageRoutes(router: IRouter): void {
|
|
11
|
+
// Public file serving: /storage/<path>
|
|
12
|
+
Router.get(router, '/storage/:path*', async (req, res) => {
|
|
13
|
+
const raw = req.getParam('path') ?? '';
|
|
14
|
+
const key = typeof raw === 'string' ? decodeURIComponent(raw).replaceAll('\\\u005C', '/') : '';
|
|
15
|
+
|
|
16
|
+
if (key.trim() === '') {
|
|
17
|
+
res.setStatus(400).json({ message: 'Missing path' });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Respect private folder convention: do not expose keys under `private/`
|
|
22
|
+
if (key.startsWith('private/') || key === 'private') {
|
|
23
|
+
res.setStatus(404).json({ message: 'Not Found' });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const contents = await Storage.get('local', key);
|
|
29
|
+
res.setHeader(HTTP_HEADERS.CONTENT_TYPE, 'application/octet-stream');
|
|
30
|
+
res.setStatus(200).send(contents);
|
|
31
|
+
} catch {
|
|
32
|
+
res.setStatus(404).json({ message: 'Not Found' });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
11
36
|
Router.get(router, '/storage/download', async (req, res) => {
|
|
12
37
|
const tokenRaw = req.getQueryParam('token');
|
|
13
38
|
const token = typeof tokenRaw === 'string' ? tokenRaw : '';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../../../src/tools/http/Http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAElF,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,MAAM,eAAe,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,MAAM,GACN,WAAW,GACX,eAAe,GACf,IAAI,GACJ,QAAQ,GACR,eAAe,CAAC;AAEpB,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,KAAK,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CAChG,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IACtD,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACnE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;IAChE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC;IACtC,MAAM,IAAI,YAAY,CAAC;IACvB,MAAM,IAAI,YAAY,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,YAAY,CAAC;IACpD,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1F;AAED;;GAEG;AACH,KAAK,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../../../src/tools/http/Http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAElF,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,MAAM,eAAe,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,MAAM,GACN,WAAW,GACX,eAAe,GACf,IAAI,GACJ,QAAQ,GACR,eAAe,CAAC;AAEpB,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,KAAK,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CAChG,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IACtD,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACnE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;IAChE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC;IACtC,MAAM,IAAI,YAAY,CAAC;IACvB,MAAM,IAAI,YAAY,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,YAAY,CAAC;IACpD,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAC/B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1F;AAED;;GAEG;AACH,KAAK,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AA8dtD;;GAEG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;aACM,MAAM,GAAG,YAAY;IAI9B;;OAEG;cACO,MAAM,SAAS,eAAe,GAAG,IAAI,GAAG,YAAY;IAQ9D;;OAEG;aACM,MAAM,SAAS,eAAe,GAAG,IAAI,GAAG,YAAY;IAQ7D;;OAEG;eACQ,MAAM,SAAS,eAAe,GAAG,IAAI,GAAG,YAAY;IAQ/D;;OAEG;gBACS,MAAM,SAAS,eAAe,GAAG,IAAI,GAAG,YAAY;EAOhE,CAAC;AAEH,eAAe,UAAU,CAAC"}
|
package/src/tools/http/Http.js
CHANGED
|
@@ -80,6 +80,56 @@ const normalizeBodyInit = (body) => {
|
|
|
80
80
|
}
|
|
81
81
|
return body;
|
|
82
82
|
};
|
|
83
|
+
const hasAuthorizationHeader = (headers) => {
|
|
84
|
+
return Object.keys(headers).some((name) => name.toLowerCase() === 'authorization');
|
|
85
|
+
};
|
|
86
|
+
const decodeCredentialComponent = (value) => {
|
|
87
|
+
try {
|
|
88
|
+
return decodeURIComponent(value);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const encodeBase64Utf8 = (value) => {
|
|
95
|
+
if (typeof Buffer !== 'undefined') {
|
|
96
|
+
return Buffer.from(value, 'utf8').toString('base64');
|
|
97
|
+
}
|
|
98
|
+
if (typeof globalThis.btoa === 'function') {
|
|
99
|
+
const bytes = new TextEncoder().encode(value);
|
|
100
|
+
let binary = '';
|
|
101
|
+
for (const byte of bytes) {
|
|
102
|
+
binary += String.fromCodePoint(byte);
|
|
103
|
+
}
|
|
104
|
+
return globalThis.btoa(binary);
|
|
105
|
+
}
|
|
106
|
+
throw ErrorFactory.createTryCatchError('HTTP basic auth encoding is unavailable');
|
|
107
|
+
};
|
|
108
|
+
const normalizeCredentialUrl = (url, headers) => {
|
|
109
|
+
let parsed;
|
|
110
|
+
try {
|
|
111
|
+
parsed = new URL(url);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return { url, headers };
|
|
115
|
+
}
|
|
116
|
+
const username = parsed.username;
|
|
117
|
+
const password = parsed.password;
|
|
118
|
+
if (username === '' && password === '') {
|
|
119
|
+
return { url, headers };
|
|
120
|
+
}
|
|
121
|
+
const nextHeaders = { ...headers };
|
|
122
|
+
if (!hasAuthorizationHeader(nextHeaders)) {
|
|
123
|
+
const credentials = encodeBase64Utf8(`${decodeCredentialComponent(username)}:${decodeCredentialComponent(password)}`);
|
|
124
|
+
nextHeaders['Authorization'] = `Basic ${credentials}`;
|
|
125
|
+
}
|
|
126
|
+
parsed.username = '';
|
|
127
|
+
parsed.password = '';
|
|
128
|
+
return {
|
|
129
|
+
url: parsed.toString(),
|
|
130
|
+
headers: nextHeaders,
|
|
131
|
+
};
|
|
132
|
+
};
|
|
83
133
|
const serializeFormBody = (body) => {
|
|
84
134
|
if (body === null || body === undefined)
|
|
85
135
|
return body;
|
|
@@ -153,8 +203,8 @@ const captureTraceResponseBody = async (response) => {
|
|
|
153
203
|
* Perform the actual request for a given state. Separated to keep the builder small
|
|
154
204
|
*/
|
|
155
205
|
async function performRequest(state) {
|
|
156
|
-
const { response, bodyText, durationMs } = await performRequestRaw(state);
|
|
157
|
-
Logger.debug(`HTTP ${
|
|
206
|
+
const { response, bodyText, durationMs, effectiveState } = await performRequestRaw(state);
|
|
207
|
+
Logger.debug(`HTTP ${effectiveState.method} ${effectiveState.url}`, {
|
|
158
208
|
status: response.status,
|
|
159
209
|
duration: `${durationMs}ms`,
|
|
160
210
|
size: bodyText.length,
|
|
@@ -162,31 +212,45 @@ async function performRequest(state) {
|
|
|
162
212
|
return createHttpResponse(response, bodyText);
|
|
163
213
|
}
|
|
164
214
|
async function performRequestRaw(state) {
|
|
165
|
-
const { response, durationMs, requestBody } = await performFetch(state);
|
|
215
|
+
const { response, durationMs, requestBody, effectiveState } = await performFetch(state);
|
|
166
216
|
const bodyText = await response.text();
|
|
167
|
-
emitHttpClientTrace({
|
|
168
|
-
|
|
217
|
+
emitHttpClientTrace({
|
|
218
|
+
state: effectiveState,
|
|
219
|
+
requestBody,
|
|
220
|
+
response,
|
|
221
|
+
responseBody: bodyText,
|
|
222
|
+
durationMs,
|
|
223
|
+
});
|
|
224
|
+
return { response, bodyText, durationMs, requestBody, effectiveState };
|
|
169
225
|
}
|
|
170
226
|
async function performFetch(state) {
|
|
171
227
|
const timeout = state.timeout ?? Env.getInt('HTTP_TIMEOUT', 30000);
|
|
172
228
|
const controller = new AbortController();
|
|
229
|
+
const normalizedTarget = normalizeCredentialUrl(state.url, state.headers);
|
|
230
|
+
const effectiveState = normalizedTarget.url === state.url && normalizedTarget.headers === state.headers
|
|
231
|
+
? state
|
|
232
|
+
: {
|
|
233
|
+
...state,
|
|
234
|
+
url: normalizedTarget.url,
|
|
235
|
+
headers: normalizedTarget.headers,
|
|
236
|
+
};
|
|
173
237
|
let timeoutId;
|
|
174
238
|
if (timeout > 0) {
|
|
175
239
|
timeoutId = globalThis.setTimeout(() => controller.abort(), timeout);
|
|
176
240
|
}
|
|
177
241
|
const buildInit = () => {
|
|
178
242
|
if (OpenTelemetry.isEnabled()) {
|
|
179
|
-
OpenTelemetry.injectTraceHeaders(
|
|
243
|
+
OpenTelemetry.injectTraceHeaders(effectiveState.headers);
|
|
180
244
|
}
|
|
181
|
-
const requestBody = serializeRequestBody(
|
|
245
|
+
const requestBody = serializeRequestBody(effectiveState);
|
|
182
246
|
const init = {
|
|
183
|
-
method:
|
|
184
|
-
headers:
|
|
247
|
+
method: effectiveState.method,
|
|
248
|
+
headers: effectiveState.headers,
|
|
185
249
|
signal: controller.signal,
|
|
186
250
|
};
|
|
187
251
|
if (requestBody !== undefined &&
|
|
188
252
|
requestBody !== null &&
|
|
189
|
-
['POST', 'PUT', 'PATCH', 'DELETE'].includes(
|
|
253
|
+
['POST', 'PUT', 'PATCH', 'DELETE'].includes(effectiveState.method)) {
|
|
190
254
|
init.body = requestBody;
|
|
191
255
|
}
|
|
192
256
|
return { init, requestBody };
|
|
@@ -194,28 +258,28 @@ async function performFetch(state) {
|
|
|
194
258
|
const startTime = Date.now();
|
|
195
259
|
try {
|
|
196
260
|
const { init, requestBody } = buildInit();
|
|
197
|
-
const response = await globalThis.fetch(
|
|
261
|
+
const response = await globalThis.fetch(effectiveState.url, init);
|
|
198
262
|
const duration = Date.now() - startTime;
|
|
199
|
-
return { response, durationMs: duration, requestBody };
|
|
263
|
+
return { response, durationMs: duration, requestBody, effectiveState };
|
|
200
264
|
}
|
|
201
265
|
catch (error) {
|
|
202
266
|
const duration = Date.now() - startTime;
|
|
203
267
|
emitHttpClientTrace({
|
|
204
|
-
state,
|
|
205
|
-
requestBody: serializeRequestBody(
|
|
268
|
+
state: effectiveState,
|
|
269
|
+
requestBody: serializeRequestBody(effectiveState),
|
|
206
270
|
durationMs: duration,
|
|
207
271
|
error: error instanceof Error ? error.message : String(error),
|
|
208
272
|
});
|
|
209
273
|
if (error instanceof Error && error.name === 'AbortError') {
|
|
210
274
|
throw ErrorFactory.createConnectionError(`HTTP request timeout after ${timeout}ms`, {
|
|
211
|
-
url:
|
|
212
|
-
method:
|
|
275
|
+
url: effectiveState.url,
|
|
276
|
+
method: effectiveState.method,
|
|
213
277
|
timeout,
|
|
214
278
|
});
|
|
215
279
|
}
|
|
216
280
|
throw ErrorFactory.createTryCatchError(`HTTP request failed: ${error.message}`, {
|
|
217
|
-
url:
|
|
218
|
-
method:
|
|
281
|
+
url: effectiveState.url,
|
|
282
|
+
method: effectiveState.method,
|
|
219
283
|
error: error instanceof Error ? error.message : String(error),
|
|
220
284
|
});
|
|
221
285
|
}
|
|
@@ -225,6 +289,18 @@ async function performFetch(state) {
|
|
|
225
289
|
}
|
|
226
290
|
}
|
|
227
291
|
}
|
|
292
|
+
async function performFetchWithTrace(state) {
|
|
293
|
+
const result = await performFetch(state);
|
|
294
|
+
const responseBody = await captureTraceResponseBody(result.response);
|
|
295
|
+
emitHttpClientTrace({
|
|
296
|
+
state: result.effectiveState,
|
|
297
|
+
requestBody: result.requestBody,
|
|
298
|
+
response: result.response,
|
|
299
|
+
responseBody,
|
|
300
|
+
durationMs: result.durationMs,
|
|
301
|
+
});
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
228
304
|
/**
|
|
229
305
|
* Create request builder with fluent API
|
|
230
306
|
*/
|
|
@@ -251,7 +327,7 @@ function createRequestBuilder(method, url, initialBody) {
|
|
|
251
327
|
return self;
|
|
252
328
|
},
|
|
253
329
|
withBasicAuth(username, password) {
|
|
254
|
-
const credentials =
|
|
330
|
+
const credentials = encodeBase64Utf8(`${username}:${password}`);
|
|
255
331
|
state.headers['Authorization'] = `Basic ${credentials}`;
|
|
256
332
|
return self;
|
|
257
333
|
},
|
|
@@ -281,15 +357,11 @@ function createRequestBuilder(method, url, initialBody) {
|
|
|
281
357
|
return performRequest(state);
|
|
282
358
|
},
|
|
283
359
|
async sendRaw() {
|
|
284
|
-
const { response
|
|
285
|
-
const responseBody = await captureTraceResponseBody(response);
|
|
286
|
-
emitHttpClientTrace({ state, requestBody, response, responseBody, durationMs });
|
|
360
|
+
const { response } = await performFetchWithTrace(state);
|
|
287
361
|
return response;
|
|
288
362
|
},
|
|
289
363
|
async sendStream() {
|
|
290
|
-
const { response
|
|
291
|
-
const responseBody = await captureTraceResponseBody(response);
|
|
292
|
-
emitHttpClientTrace({ state, requestBody, response, responseBody, durationMs });
|
|
364
|
+
const { response } = await performFetchWithTrace(state);
|
|
293
365
|
return { response, stream: response.body };
|
|
294
366
|
},
|
|
295
367
|
};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
|
|
6
|
-
* optional adapters/drivers into core registries.
|
|
7
|
-
*
|
|
2
|
+
* Auto-generated fallback module.
|
|
3
|
+
* This file is created by scripts/ensure-worker-plugins.mjs when missing.
|
|
4
|
+
* It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
|
|
8
5
|
*/
|
|
9
6
|
export type {};
|
|
10
7
|
export declare const __zintrustGeneratedPluginStub = "zintrust.plugins.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,CAAC;AAgBf,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;;AACnE,wBAAkB"}
|
package/src/zintrust.plugins.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
|
|
6
|
-
* optional adapters/drivers into core registries.
|
|
7
|
-
*
|
|
2
|
+
* Auto-generated fallback module.
|
|
3
|
+
* This file is created by scripts/ensure-worker-plugins.mjs when missing.
|
|
4
|
+
* It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
|
|
8
5
|
*/
|
|
9
6
|
import * as TraceRuntime from './runtime/plugins/trace-runtime.js';
|
|
10
7
|
globalThis.__zintrust_system_trace_plugin_requested__ = true;
|