@jango-blockchained/hoox-shared 1.0.8

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.
Files changed (115) hide show
  1. package/README.md +27 -0
  2. package/dist/analytics.d.ts +22 -0
  3. package/dist/analytics.d.ts.map +1 -0
  4. package/dist/analytics.js +34 -0
  5. package/dist/api-client.d.ts +34 -0
  6. package/dist/api-client.d.ts.map +1 -0
  7. package/dist/api-client.js +124 -0
  8. package/dist/colors.d.ts +34 -0
  9. package/dist/colors.d.ts.map +1 -0
  10. package/dist/colors.js +42 -0
  11. package/dist/config.d.ts +24 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +91 -0
  14. package/dist/d1/index.d.ts +5 -0
  15. package/dist/d1/index.d.ts.map +1 -0
  16. package/dist/d1/index.js +316 -0
  17. package/dist/d1/repository.d.ts +77 -0
  18. package/dist/d1/repository.d.ts.map +1 -0
  19. package/dist/d1/schemas.d.ts +85 -0
  20. package/dist/d1/schemas.d.ts.map +1 -0
  21. package/dist/errors.d.ts +39 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +106 -0
  24. package/dist/exchange-client.d.ts +84 -0
  25. package/dist/exchange-client.d.ts.map +1 -0
  26. package/dist/exchange-client.js +104 -0
  27. package/dist/format-time.d.ts +24 -0
  28. package/dist/format-time.d.ts.map +1 -0
  29. package/dist/format-time.js +57 -0
  30. package/dist/formatters.d.ts +32 -0
  31. package/dist/formatters.d.ts.map +1 -0
  32. package/dist/formatters.js +155 -0
  33. package/dist/health.d.ts +19 -0
  34. package/dist/health.d.ts.map +1 -0
  35. package/dist/health.js +117 -0
  36. package/dist/index.d.ts +45 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +2581 -0
  39. package/dist/kvKeys.d.ts +72 -0
  40. package/dist/kvKeys.d.ts.map +1 -0
  41. package/dist/kvKeys.js +107 -0
  42. package/dist/kvUtils.d.ts +26 -0
  43. package/dist/kvUtils.d.ts.map +1 -0
  44. package/dist/kvUtils.js +127 -0
  45. package/dist/legal.d.ts +11 -0
  46. package/dist/legal.d.ts.map +1 -0
  47. package/dist/legal.js +40 -0
  48. package/dist/middleware/auth.d.ts +59 -0
  49. package/dist/middleware/auth.d.ts.map +1 -0
  50. package/dist/middleware/cors.d.ts +28 -0
  51. package/dist/middleware/cors.d.ts.map +1 -0
  52. package/dist/middleware/index.d.ts +10 -0
  53. package/dist/middleware/index.d.ts.map +1 -0
  54. package/dist/middleware/index.js +375 -0
  55. package/dist/middleware/logger.d.ts +16 -0
  56. package/dist/middleware/logger.d.ts.map +1 -0
  57. package/dist/middleware/rate-limit.d.ts +24 -0
  58. package/dist/middleware/rate-limit.d.ts.map +1 -0
  59. package/dist/middleware/security-headers.d.ts +39 -0
  60. package/dist/middleware/security-headers.d.ts.map +1 -0
  61. package/dist/middleware/validate.d.ts +21 -0
  62. package/dist/middleware/validate.d.ts.map +1 -0
  63. package/dist/router.d.ts +11 -0
  64. package/dist/router.d.ts.map +1 -0
  65. package/dist/router.js +123 -0
  66. package/dist/schemas/index.d.ts +4 -0
  67. package/dist/schemas/index.d.ts.map +1 -0
  68. package/dist/schemas/index.js +656 -0
  69. package/dist/schemas/registry.d.ts +8 -0
  70. package/dist/schemas/registry.d.ts.map +1 -0
  71. package/dist/schemas/types.d.ts +79 -0
  72. package/dist/schemas/types.d.ts.map +1 -0
  73. package/dist/schemas/validators.d.ts +35 -0
  74. package/dist/schemas/validators.d.ts.map +1 -0
  75. package/dist/service-bindings.d.ts +32 -0
  76. package/dist/service-bindings.d.ts.map +1 -0
  77. package/dist/service-bindings.js +31 -0
  78. package/dist/session.d.ts +46 -0
  79. package/dist/session.d.ts.map +1 -0
  80. package/dist/session.js +79 -0
  81. package/dist/sse.d.ts +26 -0
  82. package/dist/sse.d.ts.map +1 -0
  83. package/dist/sse.js +91 -0
  84. package/dist/stores/config-store.d.ts +87 -0
  85. package/dist/stores/config-store.d.ts.map +1 -0
  86. package/dist/stores/config-store.js +132 -0
  87. package/dist/stores/service-store.d.ts +206 -0
  88. package/dist/stores/service-store.d.ts.map +1 -0
  89. package/dist/stores/service-store.js +359 -0
  90. package/dist/stores/ui-store.d.ts +63 -0
  91. package/dist/stores/ui-store.d.ts.map +1 -0
  92. package/dist/stores/ui-store.js +62 -0
  93. package/dist/types/errors.d.ts +16 -0
  94. package/dist/types/errors.d.ts.map +1 -0
  95. package/dist/types/errors.js +1 -0
  96. package/dist/types/router.d.ts +22 -0
  97. package/dist/types/router.d.ts.map +1 -0
  98. package/dist/types/router.js +1 -0
  99. package/dist/types.d.ts +317 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +70 -0
  102. package/dist/wizard/engine.d.ts +42 -0
  103. package/dist/wizard/engine.d.ts.map +1 -0
  104. package/dist/wizard/index.d.ts +7 -0
  105. package/dist/wizard/index.d.ts.map +1 -0
  106. package/dist/wizard/index.js +519 -0
  107. package/dist/wizard/persistence.d.ts +14 -0
  108. package/dist/wizard/persistence.d.ts.map +1 -0
  109. package/dist/wizard/presets.d.ts +34 -0
  110. package/dist/wizard/presets.d.ts.map +1 -0
  111. package/dist/wizard/provisioner.d.ts +11 -0
  112. package/dist/wizard/provisioner.d.ts.map +1 -0
  113. package/dist/wizard/types.d.ts +72 -0
  114. package/dist/wizard/types.d.ts.map +1 -0
  115. package/package.json +83 -0
@@ -0,0 +1,656 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+
18
+ // src/schemas/registry.ts
19
+ function deriveCalledBy(manifests) {
20
+ const calledBy = {};
21
+ for (const [workerName, manifest] of Object.entries(manifests)) {
22
+ if (!calledBy[workerName])
23
+ calledBy[workerName] = new Set;
24
+ for (const svc of manifest.services) {
25
+ if (!calledBy[svc.service])
26
+ calledBy[svc.service] = new Set;
27
+ calledBy[svc.service].add(workerName);
28
+ }
29
+ }
30
+ const result = {};
31
+ for (const [worker, callers] of Object.entries(calledBy)) {
32
+ result[worker] = [...callers].sort();
33
+ }
34
+ return result;
35
+ }
36
+ var manifests = {
37
+ hoox: {
38
+ name: "hoox",
39
+ path: "workers/hoox",
40
+ vars: {
41
+ WEBHOOK_API_KEY_BINDING: {
42
+ type: "secret",
43
+ description: "External webhook auth key"
44
+ },
45
+ INTERNAL_KEY_BINDING: {
46
+ type: "secret",
47
+ description: "Inter-worker auth key"
48
+ },
49
+ HA_TOKEN_BINDING: { type: "secret", description: "Home Assistant token" }
50
+ },
51
+ services: [
52
+ {
53
+ binding: "TRADE_SERVICE",
54
+ service: "trade-worker",
55
+ description: "Trading functionality"
56
+ },
57
+ {
58
+ binding: "TELEGRAM_SERVICE",
59
+ service: "telegram-worker",
60
+ description: "Notifications"
61
+ }
62
+ ],
63
+ infrastructure: {
64
+ kv: [
65
+ { binding: "SESSIONS_KV", description: "Webhook session storage" },
66
+ {
67
+ binding: "CONFIG_KV",
68
+ description: "Configuration + rate limiter state"
69
+ }
70
+ ],
71
+ vectorize: [{ binding: "VECTORIZE_INDEX", index: "my-rag-index" }],
72
+ ai: true,
73
+ queues: { producer: ["trade-execution"] },
74
+ durableObjects: [
75
+ { name: "IDEMPOTENCY_STORE", className: "IdempotencyStore" }
76
+ ]
77
+ },
78
+ middleware: [
79
+ "requireAuth",
80
+ "requireInternalAuth",
81
+ "cors",
82
+ "rateLimit",
83
+ "logger",
84
+ "validate"
85
+ ]
86
+ },
87
+ "trade-worker": {
88
+ name: "trade-worker",
89
+ path: "workers/trade-worker",
90
+ vars: {
91
+ INTERNAL_KEY_BINDING: {
92
+ type: "secret",
93
+ description: "Inter-worker auth key"
94
+ },
95
+ TELEGRAM_INTERNAL_KEY_BINDING: {
96
+ type: "secret",
97
+ description: "Telegram outbound auth"
98
+ },
99
+ BINANCE_KEY_BINDING: { type: "secret", description: "Binance API key" },
100
+ BINANCE_SECRET_BINDING: {
101
+ type: "secret",
102
+ description: "Binance API secret"
103
+ },
104
+ MEXC_KEY_BINDING: { type: "secret", description: "MEXC API key" },
105
+ MEXC_SECRET_BINDING: { type: "secret", description: "MEXC API secret" },
106
+ BYBIT_KEY_BINDING: { type: "secret", description: "Bybit API key" },
107
+ BYBIT_SECRET_BINDING: { type: "secret", description: "Bybit API secret" }
108
+ },
109
+ services: [
110
+ {
111
+ binding: "D1_SERVICE",
112
+ service: "d1-worker",
113
+ description: "Database operations"
114
+ },
115
+ {
116
+ binding: "TELEGRAM_SERVICE",
117
+ service: "telegram-worker",
118
+ description: "Notifications"
119
+ }
120
+ ],
121
+ infrastructure: {
122
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }],
123
+ d1: [
124
+ {
125
+ binding: "DB",
126
+ database: "trade-data-db",
127
+ description: "Trade operations"
128
+ }
129
+ ],
130
+ r2: [
131
+ {
132
+ binding: "REPORTS_BUCKET",
133
+ bucket: "trade-reports",
134
+ description: "Trade reports"
135
+ },
136
+ {
137
+ binding: "SYSTEM_LOGS_BUCKET",
138
+ bucket: "hoox-system-logs",
139
+ description: "Verbose exchange logs"
140
+ }
141
+ ],
142
+ queues: { consumer: ["trade-execution"] }
143
+ },
144
+ middleware: ["requireInternalAuth"]
145
+ },
146
+ "telegram-worker": {
147
+ name: "telegram-worker",
148
+ path: "workers/telegram-worker",
149
+ vars: {
150
+ INTERNAL_KEY_BINDING: {
151
+ type: "secret",
152
+ description: "Inter-worker auth key"
153
+ },
154
+ TG_BOT_TOKEN_BINDING: {
155
+ type: "secret",
156
+ description: "Telegram bot token"
157
+ },
158
+ TG_CHAT_ID_BINDING: { type: "secret", description: "Default chat ID" },
159
+ TELEGRAM_SECRET_TOKEN: {
160
+ type: "secret",
161
+ description: "Webhook verification token"
162
+ }
163
+ },
164
+ services: [],
165
+ infrastructure: {
166
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }],
167
+ r2: [
168
+ {
169
+ binding: "UPLOADS_BUCKET",
170
+ bucket: "user-uploads",
171
+ description: "User uploaded files"
172
+ }
173
+ ],
174
+ vectorize: [{ binding: "VECTORIZE_INDEX", index: "my-rag-index" }],
175
+ ai: true
176
+ },
177
+ middleware: ["requireInternalAuth"]
178
+ },
179
+ "d1-worker": {
180
+ name: "d1-worker",
181
+ path: "workers/d1-worker",
182
+ vars: {
183
+ INTERNAL_KEY_BINDING: {
184
+ type: "secret",
185
+ description: "Inter-worker auth key"
186
+ }
187
+ },
188
+ services: [],
189
+ infrastructure: {
190
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }],
191
+ d1: [
192
+ {
193
+ binding: "DB",
194
+ database: "trade-data-db",
195
+ description: "Main database"
196
+ }
197
+ ]
198
+ },
199
+ middleware: ["requireInternalAuth"]
200
+ },
201
+ "web3-wallet-worker": {
202
+ name: "web3-wallet-worker",
203
+ path: "workers/web3-wallet-worker",
204
+ vars: {
205
+ WALLET_PK_SECRET: { type: "secret", description: "Wallet private key" },
206
+ WALLET_MNEMONIC_SECRET: {
207
+ type: "secret",
208
+ description: "Wallet mnemonic phrase"
209
+ }
210
+ },
211
+ services: [
212
+ {
213
+ binding: "TELEGRAM_SERVICE",
214
+ service: "telegram-worker",
215
+ description: "Notifications"
216
+ }
217
+ ],
218
+ infrastructure: {},
219
+ middleware: ["requireInternalAuth"]
220
+ },
221
+ "agent-worker": {
222
+ name: "agent-worker",
223
+ path: "workers/agent-worker",
224
+ vars: {
225
+ AGENT_INTERNAL_KEY: { type: "secret", description: "Agent worker auth" },
226
+ INTERNAL_KEY_BINDING: {
227
+ type: "secret",
228
+ description: "Inter-worker auth key"
229
+ }
230
+ },
231
+ services: [
232
+ {
233
+ binding: "TRADE_SERVICE",
234
+ service: "trade-worker",
235
+ description: "Trading functionality"
236
+ },
237
+ {
238
+ binding: "TELEGRAM_SERVICE",
239
+ service: "telegram-worker",
240
+ description: "Notifications"
241
+ }
242
+ ],
243
+ infrastructure: {
244
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }],
245
+ d1: [
246
+ {
247
+ binding: "DB",
248
+ database: "trade-data-db",
249
+ description: "Portfolio queries"
250
+ }
251
+ ],
252
+ ai: true
253
+ },
254
+ middleware: ["requireInternalAuth"],
255
+ cron: ["*/5 * * * *"]
256
+ },
257
+ "email-worker": {
258
+ name: "email-worker",
259
+ path: "workers/email-worker",
260
+ vars: {
261
+ INTERNAL_KEY_BINDING: {
262
+ type: "secret",
263
+ description: "Inter-worker auth key"
264
+ },
265
+ EMAIL_HOST_BINDING: { type: "secret", description: "Email IMAP host" },
266
+ EMAIL_USER_BINDING: { type: "secret", description: "Email username" },
267
+ EMAIL_PASS_BINDING: { type: "secret", description: "Email password" },
268
+ TRADE_WORKER_NAME: {
269
+ type: "plaintext",
270
+ description: "Trade worker service name",
271
+ default: "trade-worker"
272
+ },
273
+ USE_IMAP: {
274
+ type: "plaintext",
275
+ description: "Use IMAP for email",
276
+ default: "false"
277
+ },
278
+ MAILGUN_API_KEY: { type: "secret", description: "Mailgun API key" },
279
+ EMAIL_SCAN_SUBJECT: { type: "secret", description: "Email scan subject" }
280
+ },
281
+ services: [
282
+ {
283
+ binding: "TRADE_SERVICE",
284
+ service: "trade-worker",
285
+ description: "Trading functionality"
286
+ }
287
+ ],
288
+ infrastructure: {
289
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }]
290
+ },
291
+ middleware: ["requireInternalAuth"],
292
+ cron: ["*/5 * * * *"]
293
+ },
294
+ "analytics-worker": {
295
+ name: "analytics-worker",
296
+ path: "workers/analytics-worker",
297
+ vars: {
298
+ CLOUDFLARE_API_TOKEN: {
299
+ type: "secret",
300
+ description: "CF API token for Analytics SQL"
301
+ },
302
+ CLOUDFLARE_ACCOUNT_ID: {
303
+ type: "plaintext",
304
+ description: "CF Account ID"
305
+ }
306
+ },
307
+ services: [],
308
+ infrastructure: {
309
+ analyticsEngine: true
310
+ },
311
+ middleware: []
312
+ },
313
+ "report-worker": {
314
+ name: "report-worker",
315
+ path: "workers/report-worker",
316
+ vars: {
317
+ CF_API_TOKEN_BINDING: {
318
+ type: "secret",
319
+ description: "CF API token for Browser Rendering"
320
+ },
321
+ ACCOUNT_ID: { type: "plaintext", description: "CF Account ID" }
322
+ },
323
+ services: [
324
+ {
325
+ binding: "D1_SERVICE",
326
+ service: "d1-worker",
327
+ description: "Database queries"
328
+ },
329
+ {
330
+ binding: "TELEGRAM_SERVICE",
331
+ service: "telegram-worker",
332
+ description: "Notifications"
333
+ }
334
+ ],
335
+ infrastructure: {
336
+ r2: [
337
+ {
338
+ binding: "REPORTS_BUCKET",
339
+ bucket: "trade-reports",
340
+ description: "PDF reports"
341
+ }
342
+ ]
343
+ },
344
+ middleware: ["requireInternalAuth"],
345
+ cron: ["0 8 * * *", "0 18 * * *"]
346
+ },
347
+ dashboard: {
348
+ name: "dashboard",
349
+ path: "workers/dashboard",
350
+ vars: {
351
+ DASHBOARD_USER: {
352
+ type: "secret",
353
+ description: "Dashboard admin username"
354
+ },
355
+ DASHBOARD_PASS: {
356
+ type: "secret",
357
+ description: "Dashboard admin password"
358
+ },
359
+ SESSION_SECRET: { type: "secret", description: "Session encryption key" }
360
+ },
361
+ services: [
362
+ {
363
+ binding: "D1_SERVICE",
364
+ service: "d1-worker",
365
+ description: "Database queries"
366
+ },
367
+ {
368
+ binding: "AGENT_SERVICE",
369
+ service: "agent-worker",
370
+ description: "AI risk data"
371
+ }
372
+ ],
373
+ infrastructure: {
374
+ kv: [{ binding: "CONFIG_KV", description: "Configuration" }],
375
+ ai: true
376
+ },
377
+ middleware: []
378
+ }
379
+ };
380
+ var CALLED_BY = deriveCalledBy(manifests);
381
+ var WORKER_MANIFESTS = manifests;
382
+ var WORKER_NAMES = Object.keys(manifests).sort();
383
+ // src/schemas/validators.ts
384
+ import { parse } from "jsonc-parser";
385
+ function validateWranglerJsonc(workerName, manifest, jsoncContent) {
386
+ const errors = [];
387
+ let parsed;
388
+ try {
389
+ parsed = parse(jsoncContent);
390
+ } catch {
391
+ errors.push({
392
+ worker: workerName,
393
+ severity: "error",
394
+ message: "Failed to parse wrangler.jsonc",
395
+ file: "wrangler.jsonc"
396
+ });
397
+ return errors;
398
+ }
399
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
400
+ errors.push({
401
+ worker: workerName,
402
+ severity: "error",
403
+ message: "Failed to parse wrangler.jsonc \u2014 result is not a valid object",
404
+ file: "wrangler.jsonc"
405
+ });
406
+ return errors;
407
+ }
408
+ const declaredVars = parsed?.vars ?? {};
409
+ for (const [name, def] of Object.entries(manifest.vars)) {
410
+ if (!(name in declaredVars)) {
411
+ errors.push({
412
+ worker: workerName,
413
+ severity: "error",
414
+ message: `Missing var: ${name} (${def.description})`,
415
+ file: "wrangler.jsonc"
416
+ });
417
+ }
418
+ }
419
+ for (const [name, def] of Object.entries(manifest.vars)) {
420
+ if (def.type === "secret" && !name.endsWith("_BINDING") && !name.endsWith("_SECRET") && !name.startsWith("CLOUDFLARE_") && name !== "TELEGRAM_SECRET_TOKEN" && name !== "MAILGUN_API_KEY" && name !== "EMAIL_SCAN_SUBJECT" && name !== "DASHBOARD_USER" && name !== "DASHBOARD_PASS" && name !== "SESSION_SECRET" && name !== "AGENT_INTERNAL_KEY") {
421
+ errors.push({
422
+ worker: workerName,
423
+ severity: "warning",
424
+ message: `Secret var "${name}" does not end with _BINDING or _SECRET suffix`,
425
+ file: "wrangler.jsonc"
426
+ });
427
+ }
428
+ }
429
+ const declaredServices = parsed?.services ?? [];
430
+ for (const expected of manifest.services) {
431
+ const match = declaredServices.find((s) => s.binding === expected.binding && s.service === expected.service);
432
+ if (!match) {
433
+ const declared = declaredServices.find((s) => s.binding === expected.binding);
434
+ if (declared) {
435
+ errors.push({
436
+ worker: workerName,
437
+ severity: "error",
438
+ message: `Service "${expected.binding}" points to "${declared.service}" but manifest expects "${expected.service}"`,
439
+ file: "wrangler.jsonc"
440
+ });
441
+ } else {
442
+ errors.push({
443
+ worker: workerName,
444
+ severity: "error",
445
+ message: `Missing service binding: ${expected.binding} -> ${expected.service}`,
446
+ file: "wrangler.jsonc"
447
+ });
448
+ }
449
+ }
450
+ }
451
+ for (const declared of declaredServices) {
452
+ const expected = manifest.services.find((s) => s.binding === declared.binding);
453
+ if (!expected) {
454
+ errors.push({
455
+ worker: workerName,
456
+ severity: "warning",
457
+ message: `Unexpected service binding: ${declared.binding}`,
458
+ file: "wrangler.jsonc"
459
+ });
460
+ }
461
+ }
462
+ return errors;
463
+ }
464
+ function validateRootSecrets(workerName, manifest, rootJsoncContent) {
465
+ const errors = [];
466
+ let parsed;
467
+ try {
468
+ parsed = parse(rootJsoncContent);
469
+ } catch {
470
+ errors.push({
471
+ worker: workerName,
472
+ severity: "error",
473
+ message: "Failed to parse root wrangler.jsonc"
474
+ });
475
+ return errors;
476
+ }
477
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
478
+ errors.push({
479
+ worker: workerName,
480
+ severity: "error",
481
+ message: "Failed to parse root wrangler.jsonc \u2014 result is not a valid object"
482
+ });
483
+ return errors;
484
+ }
485
+ const rootSecrets = parsed?.workers?.[workerName]?.secrets ?? [];
486
+ const expectedSecrets = Object.entries(manifest.vars).filter(([_, def]) => def.type === "secret").map(([name]) => name);
487
+ for (const expected of expectedSecrets) {
488
+ if (!rootSecrets.includes(expected)) {
489
+ errors.push({
490
+ worker: workerName,
491
+ severity: "error",
492
+ message: `Secret "${expected}" missing from root wrangler.jsonc workers.${workerName}.secrets`,
493
+ file: "wrangler.jsonc (root)"
494
+ });
495
+ }
496
+ }
497
+ return errors;
498
+ }
499
+ function validateDevVars(workerName, manifest, devVarsContent) {
500
+ const errors = [];
501
+ const vars = new Map;
502
+ for (const line of devVarsContent.split(`
503
+ `)) {
504
+ const trimmed = line.trim();
505
+ if (trimmed === "" || trimmed.startsWith("#"))
506
+ continue;
507
+ const eqIdx = trimmed.indexOf("=");
508
+ if (eqIdx < 1)
509
+ continue;
510
+ vars.set(trimmed.substring(0, eqIdx).trim(), trimmed.substring(eqIdx + 1).trim());
511
+ }
512
+ for (const [name, def] of Object.entries(manifest.vars)) {
513
+ if (def.type !== "secret")
514
+ continue;
515
+ if (!vars.has(name)) {
516
+ errors.push({
517
+ worker: workerName,
518
+ severity: "error",
519
+ message: `Missing "${name}" in .dev.vars`,
520
+ file: ".dev.vars"
521
+ });
522
+ }
523
+ }
524
+ return errors;
525
+ }
526
+ function generateWranglerJsonc(manifest) {
527
+ const parts = [];
528
+ parts.push(`{`);
529
+ parts.push(` "name": "${manifest.name}",`);
530
+ parts.push(` "main": "src/index.ts",`);
531
+ const varKeys = Object.keys(manifest.vars);
532
+ if (varKeys.length > 0) {
533
+ parts.push(` "vars": {`);
534
+ for (const [i, name] of varKeys.entries()) {
535
+ const def = manifest.vars[name];
536
+ const comma = i < varKeys.length - 1 ? "," : "";
537
+ const val = def.type === "secret" ? "__SECRET__" : JSON.stringify(def.default ?? "");
538
+ parts.push(` "${name}": ${val}${comma}`);
539
+ }
540
+ parts.push(` },`);
541
+ }
542
+ if (manifest.services.length > 0) {
543
+ parts.push(` "services": [`);
544
+ for (const [i, svc] of manifest.services.entries()) {
545
+ const comma = i < manifest.services.length - 1 ? "," : "";
546
+ parts.push(` { "binding": "${svc.binding}", "service": "${svc.service}" }${comma}`);
547
+ }
548
+ parts.push(` ],`);
549
+ }
550
+ const infra = manifest.infrastructure;
551
+ if (infra.kv && infra.kv.length > 0) {
552
+ parts.push(` "kv_namespaces": [`);
553
+ for (const [i, binding] of infra.kv.entries()) {
554
+ const comma = i < infra.kv.length - 1 ? "," : "";
555
+ parts.push(` { "binding": "${binding.binding}", "id": "" }${comma}`);
556
+ }
557
+ parts.push(` ],`);
558
+ }
559
+ if (infra.d1 && infra.d1.length > 0) {
560
+ parts.push(` "d1_databases": [`);
561
+ for (const [i, binding] of infra.d1.entries()) {
562
+ const comma = i < infra.d1.length - 1 ? "," : "";
563
+ parts.push(` { "binding": "${binding.binding}", "database_name": "${binding.database}", "database_id": "" }${comma}`);
564
+ }
565
+ parts.push(` ],`);
566
+ }
567
+ if (infra.r2 && infra.r2.length > 0) {
568
+ parts.push(` "r2_buckets": [`);
569
+ for (const [i, binding] of infra.r2.entries()) {
570
+ const comma = i < infra.r2.length - 1 ? "," : "";
571
+ parts.push(` { "binding": "${binding.binding}", "bucket_name": "${binding.bucket}" }${comma}`);
572
+ }
573
+ parts.push(` ],`);
574
+ }
575
+ if (infra.ai) {
576
+ parts.push(` "ai": { "binding": "AI" },`);
577
+ }
578
+ if (infra.analyticsEngine) {
579
+ parts.push(` "analytics_engine_datasets": [{ "binding": "ANALYTICS_ENGINE", "dataset": "hoox-analytics" }],`);
580
+ }
581
+ if (infra.vectorize && infra.vectorize.length > 0) {
582
+ parts.push(` "vectorize": [`);
583
+ for (const [i, binding] of infra.vectorize.entries()) {
584
+ const comma = i < infra.vectorize.length - 1 ? "," : "";
585
+ parts.push(` { "binding": "${binding.binding}", "index_name": "${binding.index}" }${comma}`);
586
+ }
587
+ parts.push(` ],`);
588
+ }
589
+ if (infra.queues) {
590
+ if (infra.queues.producer && infra.queues.producer.length > 0) {
591
+ parts.push(` "queues": { "producers": [`);
592
+ for (const [i, q] of infra.queues.producer.entries()) {
593
+ const comma = i < infra.queues.producer.length - 1 ? "," : "";
594
+ parts.push(` { "queue": "${q}", "binding": "" }${comma}`);
595
+ }
596
+ parts.push(` ] },`);
597
+ }
598
+ if (infra.queues.consumer && infra.queues.consumer.length > 0) {
599
+ parts.push(` "queues": { "consumers": [`);
600
+ for (const [i, q] of infra.queues.consumer.entries()) {
601
+ const comma = i < infra.queues.consumer.length - 1 ? "," : "";
602
+ parts.push(` { "queue": "${q}" }${comma}`);
603
+ }
604
+ parts.push(` ] },`);
605
+ }
606
+ }
607
+ if (infra.durableObjects && infra.durableObjects.length > 0) {
608
+ parts.push(` "durable_objects": { "bindings": [`);
609
+ for (const [i, doBinding] of infra.durableObjects.entries()) {
610
+ const comma = i < infra.durableObjects.length - 1 ? "," : "";
611
+ parts.push(` { "name": "${doBinding.name}", "class_name": "${doBinding.className}" }${comma}`);
612
+ }
613
+ parts.push(` ] },`);
614
+ }
615
+ parts.push(`}`);
616
+ return parts.join(`
617
+ `) + `
618
+ `;
619
+ }
620
+ function generateDevVars(manifest) {
621
+ const lines = [];
622
+ lines.push(`# ${manifest.name} \u2014 Environment Variables`);
623
+ lines.push(`# Auto-generated from worker manifest schema`);
624
+ lines.push(``);
625
+ for (const [name, def] of Object.entries(manifest.vars)) {
626
+ if (def.type === "secret") {
627
+ lines.push(`${name}=placeholder_${name.toLowerCase()}`);
628
+ }
629
+ }
630
+ lines.push(``);
631
+ return lines.join(`
632
+ `);
633
+ }
634
+ function validateAll(workerName, manifest, files) {
635
+ const errors = [
636
+ ...validateWranglerJsonc(workerName, manifest, files.wranglerJsonc),
637
+ ...validateRootSecrets(workerName, manifest, files.rootWranglerJsonc),
638
+ ...validateDevVars(workerName, manifest, files.devVars)
639
+ ];
640
+ return {
641
+ worker: workerName,
642
+ passed: errors.filter((e) => e.severity === "error").length === 0,
643
+ errors
644
+ };
645
+ }
646
+ export {
647
+ validateWranglerJsonc,
648
+ validateRootSecrets,
649
+ validateDevVars,
650
+ validateAll,
651
+ generateWranglerJsonc,
652
+ generateDevVars,
653
+ WORKER_NAMES,
654
+ WORKER_MANIFESTS,
655
+ CALLED_BY
656
+ };
@@ -0,0 +1,8 @@
1
+ import type { WorkerManifest } from "./types.js";
2
+ /** Map of worker-name -> list-of-workers-that-call-it (computed). */
3
+ export declare const CALLED_BY: Record<string, string[]>;
4
+ /** The canonical registry of all worker manifests. */
5
+ export declare const WORKER_MANIFESTS: Record<string, WorkerManifest>;
6
+ /** List of all worker names in the registry. */
7
+ export declare const WORKER_NAMES: string[];
8
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/schemas/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0XjD,qEAAqE;AACrE,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAA6B,CAAC;AAE7E,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAa,CAAC;AAE1E,gDAAgD;AAChD,eAAO,MAAM,YAAY,EAAE,MAAM,EAAkC,CAAC"}