@zintrust/workers 0.1.43 → 0.1.54
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/dist/WorkerFactory.js +27 -2
- package/dist/http/middleware/FeaturesValidator.js +5 -4
- package/package.json +2 -2
- package/src/WorkerFactory.ts +36 -2
- package/src/http/middleware/FeaturesValidator.ts +8 -19
- package/src/ui/components/WorkerExpandPanel.js +0 -8
- package/dist/WorkerShutdownDurableObject.d.ts +0 -12
- package/dist/WorkerShutdownDurableObject.js +0 -41
- package/dist/build-manifest.json +0 -548
- package/dist/ui/workers/index.html +0 -202
- package/dist/ui/workers/main.js +0 -1952
- package/dist/ui/workers/styles.css +0 -1350
- package/dist/ui/workers/zintrust.svg +0 -30
package/dist/WorkerFactory.js
CHANGED
|
@@ -39,12 +39,20 @@ const buildCandidatesForSpecifier = (specifier, root) => {
|
|
|
39
39
|
return [
|
|
40
40
|
path.join(root, 'dist', 'src', 'index.js'),
|
|
41
41
|
path.join(root, 'dist', 'index.js'),
|
|
42
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'dist', 'src', 'index.js'),
|
|
43
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'dist', 'index.js'),
|
|
44
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'src', 'index.js'),
|
|
45
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'index.js'),
|
|
42
46
|
path.join(root, 'src', 'index.ts'),
|
|
43
47
|
];
|
|
44
48
|
}
|
|
45
49
|
if (specifier === '@zintrust/workers') {
|
|
46
50
|
return [
|
|
47
51
|
path.join(root, 'dist', 'packages', 'workers', 'src', 'index.js'),
|
|
52
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'dist', 'src', 'index.js'),
|
|
53
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'dist', 'index.js'),
|
|
54
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'src', 'index.js'),
|
|
55
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'index.js'),
|
|
48
56
|
path.join(root, 'packages', 'workers', 'src', 'index.ts'),
|
|
49
57
|
];
|
|
50
58
|
}
|
|
@@ -78,8 +86,10 @@ const resolvePackageSpecifierUrl = (specifier) => {
|
|
|
78
86
|
try {
|
|
79
87
|
const require = NodeSingletons.module.createRequire(import.meta.url);
|
|
80
88
|
const resolved = require.resolve(specifier);
|
|
81
|
-
if (specifier === '@zintrust/workers' &&
|
|
82
|
-
resolved.includes(`${path.sep}node_modules${path.sep}@zintrust${path.sep}workers${path.sep}`))
|
|
89
|
+
if ((specifier === '@zintrust/workers' &&
|
|
90
|
+
resolved.includes(`${path.sep}node_modules${path.sep}@zintrust${path.sep}workers${path.sep}`)) ||
|
|
91
|
+
(specifier === '@zintrust/core' &&
|
|
92
|
+
resolved.includes(`${path.sep}node_modules${path.sep}@zintrust${path.sep}core${path.sep}`))) {
|
|
83
93
|
const local = resolveLocalPackageFallback(specifier);
|
|
84
94
|
if (local)
|
|
85
95
|
return local;
|
|
@@ -134,6 +144,14 @@ const shouldFallbackToFileImport = (error) => {
|
|
|
134
144
|
message.includes('base scheme is not hierarchical') ||
|
|
135
145
|
message.includes('Failed to resolve module specifier'));
|
|
136
146
|
};
|
|
147
|
+
const isOptionalD1ProxyModuleMissing = (error) => {
|
|
148
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
149
|
+
const code = error?.code ?? '';
|
|
150
|
+
if (code !== 'ERR_MODULE_NOT_FOUND')
|
|
151
|
+
return false;
|
|
152
|
+
return (message.includes('cloudflare-d1-proxy') ||
|
|
153
|
+
message.includes('/packages/cloudflare-d1-proxy/src/index.js'));
|
|
154
|
+
};
|
|
137
155
|
const importModuleFromCode = async (params) => {
|
|
138
156
|
const { code, normalized, cacheKey } = params;
|
|
139
157
|
const dataUrl = `data:text/javascript;base64,${toBase64(code)}`;
|
|
@@ -154,6 +172,9 @@ const importModuleFromCode = async (params) => {
|
|
|
154
172
|
return (await import(fileUrl));
|
|
155
173
|
}
|
|
156
174
|
catch (fileError) {
|
|
175
|
+
if (isOptionalD1ProxyModuleMissing(fileError)) {
|
|
176
|
+
throw fileError;
|
|
177
|
+
}
|
|
157
178
|
Logger.debug(`Processor URL file fallback failed for ${normalized}`, fileError);
|
|
158
179
|
throw error;
|
|
159
180
|
}
|
|
@@ -552,6 +573,10 @@ const fetchProcessorAttempt = async (params) => {
|
|
|
552
573
|
return await cacheProcessorFromResponse({ response, normalized, config, cacheKey });
|
|
553
574
|
}
|
|
554
575
|
catch (error) {
|
|
576
|
+
if (isOptionalD1ProxyModuleMissing(error)) {
|
|
577
|
+
Logger.warn('Processor URL skipped: optional cloudflare-d1-proxy module is unavailable in this runtime.');
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
555
580
|
if (controller.signal.aborted) {
|
|
556
581
|
Logger.error('Processor URL fetch timeout', error);
|
|
557
582
|
}
|
|
@@ -20,8 +20,8 @@ export const withFeaturesValidation = (handler) => {
|
|
|
20
20
|
if (!features) {
|
|
21
21
|
return handler(req, res); // Skip validation if features is not provided
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
if (
|
|
23
|
+
const isPlainObject = Object.prototype.toString.call(features) === '[object Object]' && !Array.isArray(features);
|
|
24
|
+
if (!isPlainObject) {
|
|
25
25
|
return res.setStatus(400).json({
|
|
26
26
|
error: 'Invalid features configuration',
|
|
27
27
|
message: 'Features must be an object',
|
|
@@ -29,7 +29,8 @@ export const withFeaturesValidation = (handler) => {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
// Validate each feature key and value
|
|
32
|
-
const
|
|
32
|
+
const featuresObj = features;
|
|
33
|
+
const featureKeys = Object.keys(featuresObj);
|
|
33
34
|
for (const key of featureKeys) {
|
|
34
35
|
if (!VALID_FEATURES.has(key)) {
|
|
35
36
|
return res.setStatus(400).json({
|
|
@@ -38,7 +39,7 @@ export const withFeaturesValidation = (handler) => {
|
|
|
38
39
|
code: 'INVALID_FEATURE',
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
|
-
const value =
|
|
42
|
+
const value = featuresObj[key];
|
|
42
43
|
if (typeof value !== 'boolean') {
|
|
43
44
|
return res.setStatus(400).json({
|
|
44
45
|
error: 'Invalid feature value',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/workers",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.54",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"node": ">=20.0.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@zintrust/core": "^0.1.
|
|
38
|
+
"@zintrust/core": "^0.1.54"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
package/src/WorkerFactory.ts
CHANGED
|
@@ -72,6 +72,10 @@ const buildCandidatesForSpecifier = (specifier: string, root: string): string[]
|
|
|
72
72
|
return [
|
|
73
73
|
path.join(root, 'dist', 'src', 'index.js'),
|
|
74
74
|
path.join(root, 'dist', 'index.js'),
|
|
75
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'dist', 'src', 'index.js'),
|
|
76
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'dist', 'index.js'),
|
|
77
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'src', 'index.js'),
|
|
78
|
+
path.join(root, 'node_modules', '@zintrust', 'core', 'index.js'),
|
|
75
79
|
path.join(root, 'src', 'index.ts'),
|
|
76
80
|
];
|
|
77
81
|
}
|
|
@@ -79,6 +83,10 @@ const buildCandidatesForSpecifier = (specifier: string, root: string): string[]
|
|
|
79
83
|
if (specifier === '@zintrust/workers') {
|
|
80
84
|
return [
|
|
81
85
|
path.join(root, 'dist', 'packages', 'workers', 'src', 'index.js'),
|
|
86
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'dist', 'src', 'index.js'),
|
|
87
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'dist', 'index.js'),
|
|
88
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'src', 'index.js'),
|
|
89
|
+
path.join(root, 'node_modules', '@zintrust', 'workers', 'index.js'),
|
|
82
90
|
path.join(root, 'packages', 'workers', 'src', 'index.ts'),
|
|
83
91
|
];
|
|
84
92
|
}
|
|
@@ -114,8 +122,12 @@ const resolvePackageSpecifierUrl = (specifier: string): string | null => {
|
|
|
114
122
|
const require = NodeSingletons.module.createRequire(import.meta.url);
|
|
115
123
|
const resolved = require.resolve(specifier);
|
|
116
124
|
if (
|
|
117
|
-
specifier === '@zintrust/workers' &&
|
|
118
|
-
|
|
125
|
+
(specifier === '@zintrust/workers' &&
|
|
126
|
+
resolved.includes(
|
|
127
|
+
`${path.sep}node_modules${path.sep}@zintrust${path.sep}workers${path.sep}`
|
|
128
|
+
)) ||
|
|
129
|
+
(specifier === '@zintrust/core' &&
|
|
130
|
+
resolved.includes(`${path.sep}node_modules${path.sep}@zintrust${path.sep}core${path.sep}`))
|
|
119
131
|
) {
|
|
120
132
|
const local = resolveLocalPackageFallback(specifier);
|
|
121
133
|
if (local) return local;
|
|
@@ -173,6 +185,18 @@ const shouldFallbackToFileImport = (error: unknown): boolean => {
|
|
|
173
185
|
);
|
|
174
186
|
};
|
|
175
187
|
|
|
188
|
+
const isOptionalD1ProxyModuleMissing = (error: unknown): boolean => {
|
|
189
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
190
|
+
const code = (error as { code?: string } | undefined)?.code ?? '';
|
|
191
|
+
|
|
192
|
+
if (code !== 'ERR_MODULE_NOT_FOUND') return false;
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
message.includes('cloudflare-d1-proxy') ||
|
|
196
|
+
message.includes('/packages/cloudflare-d1-proxy/src/index.js')
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
|
|
176
200
|
const importModuleFromCode = async (params: {
|
|
177
201
|
code: string;
|
|
178
202
|
normalized: string;
|
|
@@ -195,6 +219,9 @@ const importModuleFromCode = async (params: {
|
|
|
195
219
|
const fileUrl = NodeSingletons.url.pathToFileURL(filePath).href;
|
|
196
220
|
return (await import(fileUrl)) as Record<string, unknown>;
|
|
197
221
|
} catch (fileError) {
|
|
222
|
+
if (isOptionalD1ProxyModuleMissing(fileError)) {
|
|
223
|
+
throw fileError;
|
|
224
|
+
}
|
|
198
225
|
Logger.debug(`Processor URL file fallback failed for ${normalized}`, fileError);
|
|
199
226
|
throw error;
|
|
200
227
|
}
|
|
@@ -815,6 +842,13 @@ const fetchProcessorAttempt = async (params: {
|
|
|
815
842
|
|
|
816
843
|
return await cacheProcessorFromResponse({ response, normalized, config, cacheKey });
|
|
817
844
|
} catch (error) {
|
|
845
|
+
if (isOptionalD1ProxyModuleMissing(error)) {
|
|
846
|
+
Logger.warn(
|
|
847
|
+
'Processor URL skipped: optional cloudflare-d1-proxy module is unavailable in this runtime.'
|
|
848
|
+
);
|
|
849
|
+
return undefined;
|
|
850
|
+
}
|
|
851
|
+
|
|
818
852
|
if (controller.signal.aborted) {
|
|
819
853
|
Logger.error('Processor URL fetch timeout', error);
|
|
820
854
|
} else {
|
|
@@ -2,20 +2,6 @@ import { Logger, type IRequest, type IResponse } from '@zintrust/core';
|
|
|
2
2
|
|
|
3
3
|
export type RouteHandler = (req: IRequest, res: IResponse) => Promise<void> | void;
|
|
4
4
|
|
|
5
|
-
interface FeaturesConfig {
|
|
6
|
-
clustering: boolean;
|
|
7
|
-
metrics: boolean;
|
|
8
|
-
autoScaling: boolean;
|
|
9
|
-
circuitBreaker: boolean;
|
|
10
|
-
deadLetterQueue: boolean;
|
|
11
|
-
resourceMonitoring: boolean;
|
|
12
|
-
compliance: boolean;
|
|
13
|
-
observability: boolean;
|
|
14
|
-
plugins: boolean;
|
|
15
|
-
versioning: boolean;
|
|
16
|
-
datacenterOrchestration: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
5
|
const VALID_FEATURES = new Set([
|
|
20
6
|
'clustering',
|
|
21
7
|
'metrics',
|
|
@@ -34,14 +20,16 @@ export const withFeaturesValidation = (handler: RouteHandler): RouteHandler => {
|
|
|
34
20
|
return async (req: IRequest, res: IResponse): Promise<void> => {
|
|
35
21
|
try {
|
|
36
22
|
const data = req.data();
|
|
37
|
-
const features = data['features'] as
|
|
23
|
+
const features = data['features'] as unknown;
|
|
38
24
|
|
|
39
25
|
if (!features) {
|
|
40
26
|
return handler(req, res); // Skip validation if features is not provided
|
|
41
27
|
}
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
const isPlainObject =
|
|
30
|
+
Object.prototype.toString.call(features) === '[object Object]' && !Array.isArray(features);
|
|
31
|
+
|
|
32
|
+
if (!isPlainObject) {
|
|
45
33
|
return res.setStatus(400).json({
|
|
46
34
|
error: 'Invalid features configuration',
|
|
47
35
|
message: 'Features must be an object',
|
|
@@ -50,7 +38,8 @@ export const withFeaturesValidation = (handler: RouteHandler): RouteHandler => {
|
|
|
50
38
|
}
|
|
51
39
|
|
|
52
40
|
// Validate each feature key and value
|
|
53
|
-
const
|
|
41
|
+
const featuresObj = features as Record<string, unknown>;
|
|
42
|
+
const featureKeys = Object.keys(featuresObj);
|
|
54
43
|
for (const key of featureKeys) {
|
|
55
44
|
if (!VALID_FEATURES.has(key)) {
|
|
56
45
|
return res.setStatus(400).json({
|
|
@@ -60,7 +49,7 @@ export const withFeaturesValidation = (handler: RouteHandler): RouteHandler => {
|
|
|
60
49
|
});
|
|
61
50
|
}
|
|
62
51
|
|
|
63
|
-
const value =
|
|
52
|
+
const value = featuresObj[key];
|
|
64
53
|
if (typeof value !== 'boolean') {
|
|
65
54
|
return res.setStatus(400).json({
|
|
66
55
|
error: 'Invalid feature value',
|
|
@@ -202,8 +202,6 @@ const createEditJsonHandler = (worker, render) => {
|
|
|
202
202
|
*/
|
|
203
203
|
const createWorkerExpandPanel = (worker, container) => {
|
|
204
204
|
let element;
|
|
205
|
-
const jsonViewer = null;
|
|
206
|
-
const jsonEditor = null;
|
|
207
205
|
|
|
208
206
|
const render = () => {
|
|
209
207
|
if (element) {
|
|
@@ -229,12 +227,6 @@ const createWorkerExpandPanel = (worker, container) => {
|
|
|
229
227
|
};
|
|
230
228
|
|
|
231
229
|
const destroy = () => {
|
|
232
|
-
if (jsonViewer) {
|
|
233
|
-
jsonViewer.destroy();
|
|
234
|
-
}
|
|
235
|
-
if (jsonEditor) {
|
|
236
|
-
jsonEditor.destroy();
|
|
237
|
-
}
|
|
238
230
|
element.remove();
|
|
239
231
|
};
|
|
240
232
|
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
type DurableObjectState = {
|
|
2
|
-
storage: {
|
|
3
|
-
get: (key: string) => Promise<unknown>;
|
|
4
|
-
put: (key: string, value: unknown) => Promise<void>;
|
|
5
|
-
};
|
|
6
|
-
};
|
|
7
|
-
export declare class ZinTrustWorkerShutdownDurableObject {
|
|
8
|
-
private readonly state;
|
|
9
|
-
constructor(state: DurableObjectState);
|
|
10
|
-
fetch(request: Request): Promise<Response>;
|
|
11
|
-
}
|
|
12
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@zintrust/core';
|
|
2
|
-
const loadState = async (state) => {
|
|
3
|
-
const stored = (await state.storage.get('shutdown'));
|
|
4
|
-
return stored ?? { shuttingDown: false };
|
|
5
|
-
};
|
|
6
|
-
const saveState = async (state, value) => {
|
|
7
|
-
await state.storage.put('shutdown', value);
|
|
8
|
-
};
|
|
9
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
10
|
-
export class ZinTrustWorkerShutdownDurableObject {
|
|
11
|
-
state;
|
|
12
|
-
constructor(state) {
|
|
13
|
-
this.state = state;
|
|
14
|
-
}
|
|
15
|
-
async fetch(request) {
|
|
16
|
-
const url = new URL(request.url);
|
|
17
|
-
const path = url.pathname;
|
|
18
|
-
if (request.method === 'GET' && path === '/status') {
|
|
19
|
-
const current = await loadState(this.state);
|
|
20
|
-
return new Response(JSON.stringify(current), {
|
|
21
|
-
status: 200,
|
|
22
|
-
headers: { 'content-type': 'application/json' },
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
if (request.method === 'POST' && path === '/shutdown') {
|
|
26
|
-
const payload = (await request.json().catch(() => ({})));
|
|
27
|
-
const next = {
|
|
28
|
-
shuttingDown: true,
|
|
29
|
-
startedAt: new Date().toISOString(),
|
|
30
|
-
reason: payload.reason ?? 'manual',
|
|
31
|
-
};
|
|
32
|
-
await saveState(this.state, next);
|
|
33
|
-
Logger.info('Worker shutdown requested via Durable Object', next);
|
|
34
|
-
return new Response(JSON.stringify({ ok: true }), {
|
|
35
|
-
status: 202,
|
|
36
|
-
headers: { 'content-type': 'application/json' },
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return new Response('Not Found', { status: 404 });
|
|
40
|
-
}
|
|
41
|
-
}
|