@jango-blockchained/hoox-cli 0.5.1 → 0.5.6

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 (106) hide show
  1. package/bin/hoox.js +3 -4
  2. package/dist/index.js +32545 -0
  3. package/package.json +10 -15
  4. package/src/commands/check/check-command.test.ts +0 -476
  5. package/src/commands/check/check-command.ts +0 -1144
  6. package/src/commands/check/index.ts +0 -10
  7. package/src/commands/check/prerequisites-command.test.ts +0 -19
  8. package/src/commands/check/prerequisites-command.ts +0 -96
  9. package/src/commands/check/types.ts +0 -103
  10. package/src/commands/clone/clone-command.test.ts +0 -442
  11. package/src/commands/clone/clone-command.ts +0 -431
  12. package/src/commands/clone/index.ts +0 -1
  13. package/src/commands/config/config-command.test.ts +0 -583
  14. package/src/commands/config/config-command.ts +0 -897
  15. package/src/commands/config/env-command.test.ts +0 -43
  16. package/src/commands/config/env-command.ts +0 -295
  17. package/src/commands/config/index.ts +0 -3
  18. package/src/commands/config/kv-command.test.ts +0 -14
  19. package/src/commands/config/kv-command.ts +0 -290
  20. package/src/commands/dashboard/dashboard-command.test.ts +0 -47
  21. package/src/commands/dashboard/dashboard-command.ts +0 -128
  22. package/src/commands/dashboard/index.ts +0 -1
  23. package/src/commands/db/db-command.test.ts +0 -21
  24. package/src/commands/db/db-command.ts +0 -312
  25. package/src/commands/db/index.ts +0 -1
  26. package/src/commands/deploy/deploy-command.test.ts +0 -304
  27. package/src/commands/deploy/deploy-command.ts +0 -1135
  28. package/src/commands/deploy/index.ts +0 -2
  29. package/src/commands/deploy/telegram-service.ts +0 -76
  30. package/src/commands/deploy/types.ts +0 -34
  31. package/src/commands/dev/dev-command.test.ts +0 -383
  32. package/src/commands/dev/dev-command.ts +0 -398
  33. package/src/commands/dev/index.ts +0 -1
  34. package/src/commands/infra/index.ts +0 -5
  35. package/src/commands/infra/infra-command.test.ts +0 -719
  36. package/src/commands/infra/infra-command.ts +0 -974
  37. package/src/commands/infra/types.ts +0 -23
  38. package/src/commands/init/__tests__/cli-provisioner.test.ts +0 -17
  39. package/src/commands/init/cli-provisioner.ts +0 -71
  40. package/src/commands/init/index.ts +0 -1
  41. package/src/commands/init/init-command.test.ts +0 -876
  42. package/src/commands/init/init-command.ts +0 -593
  43. package/src/commands/init/types.ts +0 -23
  44. package/src/commands/logs/index.ts +0 -1
  45. package/src/commands/logs/logs-command.test.ts +0 -294
  46. package/src/commands/logs/logs-command.ts +0 -452
  47. package/src/commands/monitor/index.ts +0 -2
  48. package/src/commands/monitor/monitor-command.test.ts +0 -263
  49. package/src/commands/monitor/monitor-command.ts +0 -269
  50. package/src/commands/monitor/monitor-service.ts +0 -65
  51. package/src/commands/monitor/types.ts +0 -13
  52. package/src/commands/repair/index.ts +0 -2
  53. package/src/commands/repair/repair-command.test.ts +0 -224
  54. package/src/commands/repair/repair-command.ts +0 -220
  55. package/src/commands/repair/repair-service.ts +0 -138
  56. package/src/commands/repair/types.ts +0 -13
  57. package/src/commands/test/index.ts +0 -2
  58. package/src/commands/test/test-command.test.ts +0 -319
  59. package/src/commands/test/test-command.ts +0 -406
  60. package/src/commands/tui/index.ts +0 -1
  61. package/src/commands/tui/tui-command.ts +0 -87
  62. package/src/commands/update/index.ts +0 -1
  63. package/src/commands/update/update-command.ts +0 -168
  64. package/src/commands/waf/index.ts +0 -2
  65. package/src/commands/waf/types.ts +0 -48
  66. package/src/commands/waf/waf-command.test.ts +0 -506
  67. package/src/commands/waf/waf-command.ts +0 -548
  68. package/src/index.ts +0 -269
  69. package/src/services/cloudflare/cloudflare-service.test.ts +0 -658
  70. package/src/services/cloudflare/cloudflare-service.ts +0 -433
  71. package/src/services/cloudflare/index.ts +0 -2
  72. package/src/services/cloudflare/types.ts +0 -30
  73. package/src/services/config/config-service.test.ts +0 -395
  74. package/src/services/config/config-service.ts +0 -207
  75. package/src/services/config/index.ts +0 -9
  76. package/src/services/config/types.ts +0 -66
  77. package/src/services/db/db-service.test.ts +0 -51
  78. package/src/services/db/db-service.ts +0 -131
  79. package/src/services/db/index.ts +0 -1
  80. package/src/services/docker/docker-service.ts +0 -155
  81. package/src/services/docker/index.ts +0 -1
  82. package/src/services/env/env-service.test.ts +0 -236
  83. package/src/services/env/env-service.ts +0 -386
  84. package/src/services/env/index.ts +0 -1
  85. package/src/services/kv/index.ts +0 -1
  86. package/src/services/kv/kv-sync-service.test.ts +0 -38
  87. package/src/services/kv/kv-sync-service.ts +0 -234
  88. package/src/services/prerequisites/index.ts +0 -1
  89. package/src/services/prerequisites/prerequisites-service.test.ts +0 -89
  90. package/src/services/prerequisites/prerequisites-service.ts +0 -377
  91. package/src/services/prerequisites/types.ts +0 -48
  92. package/src/services/secrets/index.ts +0 -11
  93. package/src/services/secrets/secrets-service.test.ts +0 -495
  94. package/src/services/secrets/secrets-service.ts +0 -287
  95. package/src/services/secrets/types.ts +0 -50
  96. package/src/services/update/index.ts +0 -2
  97. package/src/services/update/update-service.test.ts +0 -76
  98. package/src/services/update/update-service.ts +0 -193
  99. package/src/ui/banner.ts +0 -141
  100. package/src/ui/index.ts +0 -8
  101. package/src/ui/menu.ts +0 -490
  102. package/src/utils/errors.test.ts +0 -69
  103. package/src/utils/errors.ts +0 -23
  104. package/src/utils/formatters.test.ts +0 -180
  105. package/src/utils/formatters.ts +0 -269
  106. package/src/utils/theme.ts +0 -94
@@ -1,495 +0,0 @@
1
- import { describe, it, expect, mock } from "bun:test";
2
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import type { Result } from "./types.js";
6
- import { SecretsService } from "./secrets-service.js";
7
-
8
- // ---------------------------------------------------------------------------
9
- // Helpers
10
- // ---------------------------------------------------------------------------
11
-
12
- /**
13
- * Narrow a discriminated union Result<T> after checking ok.
14
- * Calling expect(result.ok).toBe(true) does not narrow the type,
15
- * so we use this to unwrap the value after asserting ok.
16
- */
17
- function expectOk<T>(result: Result<T>): T {
18
- expect(result.ok).toBe(true);
19
- return (result as { ok: true; value: T }).value;
20
- }
21
-
22
- /**
23
- * Assert a Result<T> is an error and return the error message.
24
- */
25
- function expectErr<T>(result: Result<T>): string {
26
- expect(result.ok).toBe(false);
27
- return (result as { ok: false; error: string }).error;
28
- }
29
-
30
- const WORKERS_JSONC = JSON.stringify({
31
- global: {},
32
- workers: {
33
- "telegram-worker": {
34
- enabled: true,
35
- path: "workers/telegram-worker",
36
- secrets: ["TELEGRAM_BOT_TOKEN"],
37
- },
38
- "trade-worker": {
39
- enabled: true,
40
- path: "workers/trade-worker",
41
- secrets: ["API_SERVICE_KEY", "BINANCE_API_KEY", "BINANCE_API_SECRET"],
42
- },
43
- "d1-worker": {
44
- enabled: true,
45
- path: "workers/d1-worker",
46
- },
47
- "no-secrets-worker": {
48
- enabled: true,
49
- path: "workers/no-secrets",
50
- secrets: [],
51
- },
52
- },
53
- });
54
-
55
- /**
56
- * Creates a SecretsService that reads from a synthetic wrangler.jsonc string
57
- * instead of hitting the real file-system. We override `Bun.file` for the
58
- * config path only and call the private constructor via a test-only subclass.
59
- */
60
- async function createService(workersJsonc?: string): Promise<SecretsService> {
61
- const jsonc = workersJsonc ?? WORKERS_JSONC;
62
-
63
- // Spy on Bun.file so we can intercept the config read while letting
64
- // real .dev.vars file-system calls through for the integration-style tests.
65
- const originalBunFile = Bun.file;
66
-
67
- // Use direct property assignment for Bun.file mock.
68
- // Object.defineProperty with configurable:true fails because Bun.file
69
- // is not configurable, but direct assignment (which requires only writable)
70
- // works in Bun 1.3.x for individual Bun properties.
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- (Bun as any).file = mock((path: string) => {
73
- if (typeof path === "string" && path.endsWith("wrangler.jsonc")) {
74
- return {
75
- exists: mock(async () => true),
76
- text: mock(async () => jsonc),
77
- };
78
- }
79
- // Fall through to the real Bun.file for everything else
80
- return originalBunFile(path);
81
- });
82
-
83
- const svc = await SecretsService.create("wrangler.jsonc");
84
-
85
- // Restore original so subsequent tests aren't polluted
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- (Bun as any).file = originalBunFile;
88
-
89
- return svc;
90
- }
91
-
92
- /** Returns a fresh temporary directory that is cleaned up after the test. */
93
- function tmpDir(): string {
94
- const dir = mkdtempSync(join(tmpdir(), "hoox-secrets-test-"));
95
- return dir;
96
- }
97
-
98
- // ---------------------------------------------------------------------------
99
- // Tests
100
- // ---------------------------------------------------------------------------
101
-
102
- describe("SecretsService", () => {
103
- // -- listSecrets ----------------------------------------------------------
104
-
105
- describe("listSecrets", () => {
106
- it("returns correct secret names for a worker that has secrets", async () => {
107
- const svc = await createService();
108
- expect(svc.listSecrets("trade-worker")).toEqual([
109
- "API_SERVICE_KEY",
110
- "BINANCE_API_KEY",
111
- "BINANCE_API_SECRET",
112
- ]);
113
- });
114
-
115
- it("returns single secret for telegram-worker", async () => {
116
- const svc = await createService();
117
- expect(svc.listSecrets("telegram-worker")).toEqual([
118
- "TELEGRAM_BOT_TOKEN",
119
- ]);
120
- });
121
-
122
- it("returns empty array for worker not in config", async () => {
123
- const svc = await createService();
124
- expect(svc.listSecrets("nonexistent")).toEqual([]);
125
- });
126
-
127
- it("returns empty array for worker with no secrets declared", async () => {
128
- const svc = await createService();
129
- expect(svc.listSecrets("d1-worker")).toEqual([]);
130
- });
131
-
132
- it("returns empty array for worker with explicitly empty secrets", async () => {
133
- const svc = await createService();
134
- expect(svc.listSecrets("no-secrets-worker")).toEqual([]);
135
- });
136
- });
137
-
138
- // -- listAllSecrets -------------------------------------------------------
139
-
140
- describe("listAllSecrets", () => {
141
- it("returns map of workers that have secrets", async () => {
142
- const svc = await createService();
143
- const all = svc.listAllSecrets();
144
-
145
- expect(Object.keys(all)).toHaveLength(2);
146
- expect(all["telegram-worker"]).toEqual(["TELEGRAM_BOT_TOKEN"]);
147
- expect(all["trade-worker"]).toEqual([
148
- "API_SERVICE_KEY",
149
- "BINANCE_API_KEY",
150
- "BINANCE_API_SECRET",
151
- ]);
152
- });
153
-
154
- it("omits workers without secrets", async () => {
155
- const svc = await createService();
156
- const all = svc.listAllSecrets();
157
- expect(all["d1-worker"]).toBeUndefined();
158
- expect(all["no-secrets-worker"]).toBeUndefined();
159
- });
160
- });
161
-
162
- // -- checkLocalSecrets ----------------------------------------------------
163
-
164
- describe("checkLocalSecrets", () => {
165
- it("reports all secrets missing when .dev.vars does not exist", async () => {
166
- const svc = await createService();
167
- // Use a temp dir so no .dev.vars file exists
168
- const dir = tmpDir();
169
- try {
170
- // Override the worker path to point at the temp dir
171
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
- (svc as any).config.workers["trade-worker"].path = dir;
173
-
174
- const result = await svc.checkLocalSecrets("trade-worker");
175
- expect(result.worker).toBe("trade-worker");
176
- expect(result.allSet).toBe(false);
177
- expect(result.missing).toEqual([
178
- "API_SERVICE_KEY",
179
- "BINANCE_API_KEY",
180
- "BINANCE_API_SECRET",
181
- ]);
182
- expect(result.secrets).toHaveLength(3);
183
- for (const s of result.secrets) {
184
- expect(s.set).toBe(false);
185
- }
186
- } finally {
187
- rmSync(dir, { recursive: true, force: true });
188
- }
189
- });
190
-
191
- it("reports secrets as set when .dev.vars has real values", async () => {
192
- const dir = tmpDir();
193
- try {
194
- writeFileSync(
195
- join(dir, ".dev.vars"),
196
- "API_SERVICE_KEY=abc123\nBINANCE_API_KEY=xyz789\nBINANCE_API_SECRET=sec456\n"
197
- );
198
-
199
- const svc = await createService();
200
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
201
- (svc as any).config.workers["trade-worker"].path = dir;
202
-
203
- const result = await svc.checkLocalSecrets("trade-worker");
204
- expect(result.allSet).toBe(true);
205
- expect(result.missing).toEqual([]);
206
- for (const s of result.secrets) {
207
- expect(s.set).toBe(true);
208
- expect(s.source).toBe(join(dir, ".dev.vars"));
209
- }
210
- } finally {
211
- rmSync(dir, { recursive: true, force: true });
212
- }
213
- });
214
-
215
- it("flags placeholder values as missing", async () => {
216
- const dir = tmpDir();
217
- try {
218
- writeFileSync(
219
- join(dir, ".dev.vars"),
220
- "API_SERVICE_KEY=placeholder_api_service_key\nBINANCE_API_KEY=binance-real-key\nBINANCE_API_SECRET=your_secret\n"
221
- );
222
-
223
- const svc = await createService();
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
225
- (svc as any).config.workers["trade-worker"].path = dir;
226
-
227
- const result = await svc.checkLocalSecrets("trade-worker");
228
- expect(result.allSet).toBe(false);
229
- // Only BINANCE_API_KEY should be set (not placeholder)
230
- expect(result.missing).toContain("API_SERVICE_KEY");
231
- expect(result.missing).toContain("BINANCE_API_SECRET");
232
- expect(result.missing).not.toContain("BINANCE_API_KEY");
233
- } finally {
234
- rmSync(dir, { recursive: true, force: true });
235
- }
236
- });
237
-
238
- it("handles comments and blank lines in .dev.vars", async () => {
239
- const dir = tmpDir();
240
- try {
241
- writeFileSync(
242
- join(dir, ".dev.vars"),
243
- "# This is a comment\nAPI_SERVICE_KEY=real-key\n\n# Another comment\nBINANCE_API_KEY=another-key\nBINANCE_API_SECRET=third-key\n"
244
- );
245
-
246
- const svc = await createService();
247
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
248
- (svc as any).config.workers["trade-worker"].path = dir;
249
-
250
- const result = await svc.checkLocalSecrets("trade-worker");
251
- expect(result.allSet).toBe(true);
252
- expect(result.missing).toEqual([]);
253
- } finally {
254
- rmSync(dir, { recursive: true, force: true });
255
- }
256
- });
257
-
258
- it("returns empty result for unknown worker", async () => {
259
- const svc = await createService();
260
- const result = await svc.checkLocalSecrets("unknown-worker");
261
- expect(result.worker).toBe("unknown-worker");
262
- expect(result.secrets).toEqual([]);
263
- expect(result.allSet).toBe(false);
264
- });
265
- });
266
-
267
- // -- generateDevVars ------------------------------------------------------
268
-
269
- describe("generateDevVars", () => {
270
- it("creates .dev.vars with placeholder entries", async () => {
271
- const dir = tmpDir();
272
- try {
273
- const svc = await createService();
274
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
275
- (svc as any).config.workers["telegram-worker"].path = dir;
276
-
277
- const result = await svc.generateDevVars("telegram-worker");
278
- expect(expectOk(result)).toBe(join(dir, ".dev.vars"));
279
-
280
- // Verify file content
281
- const content = await Bun.file(join(dir, ".dev.vars")).text();
282
- expect(content).toContain(
283
- "TELEGRAM_BOT_TOKEN=placeholder_telegram_bot_token"
284
- );
285
- } finally {
286
- rmSync(dir, { recursive: true, force: true });
287
- }
288
- });
289
-
290
- it("writes empty file for worker with no secrets", async () => {
291
- const dir = tmpDir();
292
- try {
293
- const svc = await createService();
294
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
295
- (svc as any).config.workers["no-secrets-worker"].path = dir;
296
-
297
- const result = await svc.generateDevVars("no-secrets-worker");
298
- expect(expectOk(result)).toBe(join(dir, ".dev.vars"));
299
-
300
- const content = await Bun.file(join(dir, ".dev.vars")).text();
301
- expect(content).toBe("");
302
- } finally {
303
- rmSync(dir, { recursive: true, force: true });
304
- }
305
- });
306
-
307
- it("returns error for unknown worker", async () => {
308
- const svc = await createService();
309
- const result = await svc.generateDevVars("unknown-worker");
310
- expect(expectErr(result)).toContain("not found in config");
311
- });
312
-
313
- it("overwrites existing .dev.vars", async () => {
314
- const dir = tmpDir();
315
- try {
316
- writeFileSync(join(dir, ".dev.vars"), "OLD_KEY=old_value\n");
317
-
318
- const svc = await createService();
319
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
320
- (svc as any).config.workers["telegram-worker"].path = dir;
321
-
322
- await svc.generateDevVars("telegram-worker");
323
-
324
- const content = await Bun.file(join(dir, ".dev.vars")).text();
325
- expect(content).toContain(
326
- "TELEGRAM_BOT_TOKEN=placeholder_telegram_bot_token"
327
- );
328
- expect(content).not.toContain("OLD_KEY");
329
- } finally {
330
- rmSync(dir, { recursive: true, force: true });
331
- }
332
- });
333
- });
334
-
335
- // -- syncToCloudflare -----------------------------------------------------
336
-
337
- describe("syncToCloudflare", () => {
338
- it("pushes secrets via wrangler when valid values are in .dev.vars", async () => {
339
- const dir = tmpDir();
340
- try {
341
- writeFileSync(
342
- join(dir, ".dev.vars"),
343
- "TELEGRAM_BOT_TOKEN=my-real-token\n"
344
- );
345
-
346
- const svc = await createService();
347
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
348
- (svc as any).config.workers["telegram-worker"].path = dir;
349
-
350
- // Stub execWranglerSecretPut to avoid real wrangler calls.
351
- const called: Array<[string, string]> = [];
352
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
- (svc as any).execWranglerSecretPut = mock(
354
- async (_path: string, name: string, value: string) => {
355
- called.push([name, value]);
356
- }
357
- );
358
-
359
- const result = await svc.syncToCloudflare("telegram-worker");
360
- expect(expectOk(result)).toEqual(["TELEGRAM_BOT_TOKEN"]);
361
- expect(called).toEqual([["TELEGRAM_BOT_TOKEN", "my-real-token"]]);
362
- } finally {
363
- rmSync(dir, { recursive: true, force: true });
364
- }
365
- });
366
-
367
- it("skips secrets that are placeholder values", async () => {
368
- const dir = tmpDir();
369
- try {
370
- writeFileSync(
371
- join(dir, ".dev.vars"),
372
- "API_SERVICE_KEY=placeholder_api_service_key\nBINANCE_API_KEY=real-binance-key\nBINANCE_API_SECRET=generate_something\n"
373
- );
374
-
375
- const svc = await createService();
376
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
377
- (svc as any).config.workers["trade-worker"].path = dir;
378
-
379
- const called: Array<[string, string]> = [];
380
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
- (svc as any).execWranglerSecretPut = mock(
382
- async (_path: string, name: string, value: string) => {
383
- called.push([name, value]);
384
- }
385
- );
386
-
387
- const result = await svc.syncToCloudflare("trade-worker");
388
- const errMsg = expectErr(result);
389
- // Only BINANCE_API_KEY was synced — but errors exist, so overall result is error
390
- expect(errMsg).toContain("API_SERVICE_KEY");
391
- expect(errMsg).toContain("BINANCE_API_SECRET");
392
- expect(called).toEqual([["BINANCE_API_KEY", "real-binance-key"]]);
393
- } finally {
394
- rmSync(dir, { recursive: true, force: true });
395
- }
396
- });
397
-
398
- it("returns error when no .dev.vars exists and all secrets are missing", async () => {
399
- const dir = tmpDir();
400
- try {
401
- const svc = await createService();
402
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
403
- (svc as any).config.workers["trade-worker"].path = dir;
404
-
405
- const called: Array<[string, string]> = [];
406
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
407
- (svc as any).execWranglerSecretPut = mock(
408
- async (_path: string, name: string, value: string) => {
409
- called.push([name, value]);
410
- }
411
- );
412
-
413
- const result = await svc.syncToCloudflare("trade-worker");
414
- const errMsg = expectErr(result);
415
- expect(errMsg).toContain("API_SERVICE_KEY");
416
- expect(errMsg).toContain("BINANCE_API_KEY");
417
- expect(errMsg).toContain("BINANCE_API_SECRET");
418
- expect(called).toHaveLength(0);
419
- } finally {
420
- rmSync(dir, { recursive: true, force: true });
421
- }
422
- });
423
-
424
- it("returns error for unknown worker", async () => {
425
- const svc = await createService();
426
- const result = await svc.syncToCloudflare("unknown-worker");
427
- expect(expectErr(result)).toContain("not found in config");
428
- });
429
-
430
- it("handles wrangler failures gracefully", async () => {
431
- const dir = tmpDir();
432
- try {
433
- writeFileSync(join(dir, ".dev.vars"), "TELEGRAM_BOT_TOKEN=my-token\n");
434
-
435
- const svc = await createService();
436
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
437
- (svc as any).config.workers["telegram-worker"].path = dir;
438
-
439
- // Stub execWranglerSecretPut to throw
440
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
441
- (svc as any).execWranglerSecretPut = mock(async () => {
442
- throw new Error("wrangler command failed");
443
- });
444
-
445
- const result = await svc.syncToCloudflare("telegram-worker");
446
- expect(expectErr(result)).toContain("wrangler command failed");
447
- } finally {
448
- rmSync(dir, { recursive: true, force: true });
449
- }
450
- });
451
-
452
- it("works for worker with no secrets", async () => {
453
- const dir = tmpDir();
454
- try {
455
- const svc = await createService();
456
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
457
- (svc as any).config.workers["no-secrets-worker"].path = dir;
458
-
459
- const result = await svc.syncToCloudflare("no-secrets-worker");
460
- expect(expectOk(result)).toEqual([]);
461
- } finally {
462
- rmSync(dir, { recursive: true, force: true });
463
- }
464
- });
465
- });
466
-
467
- // -- Edge cases -----------------------------------------------------------
468
-
469
- describe("edge cases", () => {
470
- it("throws when config file does not exist", async () => {
471
- await expect(
472
- SecretsService.create("/nonexistent/wrangler.jsonc")
473
- ).rejects.toThrow("Config file not found");
474
- });
475
-
476
- it("handles worker at path with trailing/leading whitespace in .dev.vars", async () => {
477
- const dir = tmpDir();
478
- try {
479
- writeFileSync(
480
- join(dir, ".dev.vars"),
481
- " TELEGRAM_BOT_TOKEN = my-token \n"
482
- );
483
-
484
- const svc = await createService();
485
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
486
- (svc as any).config.workers["telegram-worker"].path = dir;
487
-
488
- const result = await svc.checkLocalSecrets("telegram-worker");
489
- expect(result.allSet).toBe(true);
490
- } finally {
491
- rmSync(dir, { recursive: true, force: true });
492
- }
493
- });
494
- });
495
- });