devflare 1.0.0-next.39 → 1.0.0-next.40

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 (277) hide show
  1. package/dist/_chunks/account-BtWcv3X9.js +462 -0
  2. package/dist/_chunks/account-resources-CsmVowJp.js +159 -0
  3. package/dist/_chunks/ai-CBEuLdoP.js +322 -0
  4. package/dist/_chunks/api-TzdliH-6.js +568 -0
  5. package/dist/_chunks/build-3T6O4uIg.js +24 -0
  6. package/dist/_chunks/build-artifacts-8TqBSQkG.js +483 -0
  7. package/dist/_chunks/cli-BTF1X4SG.js +1128 -0
  8. package/dist/_chunks/cloudflare-BaloqI3H.js +157 -0
  9. package/dist/_chunks/colors-DiK6wPJ5.js +13 -0
  10. package/dist/_chunks/command-utils-BsfkmTqh.js +45 -0
  11. package/dist/_chunks/compiler-uoyAQ8zW.js +424 -0
  12. package/dist/_chunks/config-D5u-bEkn.js +78 -0
  13. package/dist/_chunks/config-path-DCPto4XB.js +42 -0
  14. package/dist/_chunks/context-CX50Y2Kb.js +2250 -0
  15. package/dist/_chunks/decorators-QmV57ixr.js +19 -0
  16. package/dist/_chunks/dependencies-C2oxFjU_.js +57 -0
  17. package/dist/_chunks/deploy-DMTr6JeR.js +915 -0
  18. package/dist/_chunks/dev-CvRHmRFZ.js +3456 -0
  19. package/dist/_chunks/doctor-DIG8DoFU.js +219 -0
  20. package/dist/_chunks/durable-object-DMtH0XYX.js +234 -0
  21. package/dist/_chunks/env-S0_nMVz1.js +125 -0
  22. package/dist/_chunks/family-DXC5SdFK.js +143 -0
  23. package/dist/_chunks/generated-artifacts-dMJY4KAt.js +32 -0
  24. package/dist/_chunks/glob-CmQOvunB.js +56 -0
  25. package/dist/_chunks/init-3moXTgpb.js +165 -0
  26. package/dist/_chunks/loader-DLXO60RO.js +1153 -0
  27. package/dist/_chunks/local-dev-vars-CTSa-wvF.js +81 -0
  28. package/dist/_chunks/local-hyperdrive-CJ90j46O.js +119 -0
  29. package/dist/_chunks/local-media-bindings-DsAW4AMF.js +335 -0
  30. package/dist/_chunks/local-secrets-DMmEOygL.js +123 -0
  31. package/dist/_chunks/local-workflow-entrypoints-Wip3o1u8.js +90 -0
  32. package/dist/_chunks/login-BmnDzDlH.js +51 -0
  33. package/dist/_chunks/package-metadata-DAuCkyvK.js +39 -0
  34. package/dist/_chunks/preferences-BKp_7XJx.js +241 -0
  35. package/dist/_chunks/preview-BhqDmq8I.js +456 -0
  36. package/dist/_chunks/preview-registry-ClAbLTHH.js +1186 -0
  37. package/dist/_chunks/preview-resources-DdXj8LMM.js +358 -0
  38. package/dist/_chunks/previews-Dlr13x5M.js +1134 -0
  39. package/dist/_chunks/productions-D3AnOHac.js +411 -0
  40. package/dist/_chunks/ref-CYJNAAe_.js +178 -0
  41. package/dist/_chunks/remote-CZnP-HLJ.js +79 -0
  42. package/dist/_chunks/remote-config-D39BY9ji.js +132 -0
  43. package/dist/_chunks/resolve-package-Y84HB3Nt.js +133 -0
  44. package/dist/_chunks/rolldown-runtime-CvQ6eiug.js +14 -0
  45. package/dist/_chunks/routes-C3FqES2W.js +796 -0
  46. package/dist/_chunks/runtime-FvXvfuZ2.js +550 -0
  47. package/dist/_chunks/schema-normalization-DWVleVxo.js +477 -0
  48. package/dist/_chunks/secrets-70eN0Q6C.js +95 -0
  49. package/dist/_chunks/token-kguIDmej.js +333 -0
  50. package/dist/_chunks/tokens-iVcgNXi-.js +221 -0
  51. package/dist/_chunks/types-OrLbzv4I.js +476 -0
  52. package/dist/_chunks/ui-BUoZApvE.js +103 -0
  53. package/dist/_chunks/usage-BBTGzjon.js +272 -0
  54. package/dist/_chunks/vite-CsI0E-uV.js +1235 -0
  55. package/dist/_chunks/vite-utils-OVLMV605.js +183 -0
  56. package/dist/_chunks/worker-CS1jgNFE.js +410 -0
  57. package/dist/_chunks/worker-bundler-dTTnYU3n.js +458 -0
  58. package/dist/_chunks/worker-entrypoint-CQW77lG8.js +247 -0
  59. package/dist/_chunks/workerName-CFJsLZA-.js +23 -0
  60. package/dist/bridge/index.d.ts +6 -6
  61. package/dist/bridge/miniflare.d.ts +2 -2
  62. package/dist/bridge/proxy.d.ts +1 -1
  63. package/dist/bridge/v2/body-streams.d.ts +1 -1
  64. package/dist/bridge/v2/codec.d.ts +4 -4
  65. package/dist/bridge/v2/index.d.ts +10 -10
  66. package/dist/bridge/v2/serialization.d.ts +1 -1
  67. package/dist/bridge/v2/value-codec.d.ts +1 -1
  68. package/dist/bridge/v2/value-serialization.d.ts.map +1 -1
  69. package/dist/bridge/v2/ws-relay.d.ts +3 -3
  70. package/dist/browser-shim/index.d.ts +2 -2
  71. package/dist/browser.d.ts +70 -70
  72. package/dist/browser.js +74 -2462
  73. package/dist/bundler/do-bundler.d.ts +1 -1
  74. package/dist/bundler/index.d.ts +3 -3
  75. package/dist/bundler/rolldown-shared.d.ts +1 -1
  76. package/dist/bundler/worker-bundler.d.ts +1 -1
  77. package/dist/cli/build-manifest.d.ts +1 -1
  78. package/dist/cli/command-utils.d.ts +1 -1
  79. package/dist/cli/commands/account.d.ts +1 -1
  80. package/dist/cli/commands/ai.d.ts +1 -1
  81. package/dist/cli/commands/build-artifacts.d.ts +5 -5
  82. package/dist/cli/commands/build.d.ts +1 -1
  83. package/dist/cli/commands/config.d.ts +1 -1
  84. package/dist/cli/commands/deploy/prepare.d.ts +2 -2
  85. package/dist/cli/commands/deploy/runtime.d.ts +1 -1
  86. package/dist/cli/commands/deploy/verification.d.ts +1 -1
  87. package/dist/cli/commands/deploy.d.ts +1 -1
  88. package/dist/cli/commands/dev.d.ts +1 -1
  89. package/dist/cli/commands/doctor.d.ts +1 -1
  90. package/dist/cli/commands/init.d.ts +1 -1
  91. package/dist/cli/commands/login.d.ts +1 -1
  92. package/dist/cli/commands/previews-support/cleanup.d.ts +1 -1
  93. package/dist/cli/commands/previews-support/family.d.ts +3 -3
  94. package/dist/cli/commands/previews-support/render.d.ts +3 -3
  95. package/dist/cli/commands/previews-support/theme.d.ts +2 -2
  96. package/dist/cli/commands/previews-support/types.d.ts +2 -2
  97. package/dist/cli/commands/previews.d.ts +1 -1
  98. package/dist/cli/commands/productions.d.ts +1 -1
  99. package/dist/cli/commands/remote.d.ts +1 -1
  100. package/dist/cli/commands/secrets.d.ts +1 -1
  101. package/dist/cli/commands/token.d.ts +1 -1
  102. package/dist/cli/commands/type-generation/discovery.d.ts +2 -2
  103. package/dist/cli/commands/type-generation/generator.d.ts +3 -3
  104. package/dist/cli/commands/type-generation/models.d.ts +1 -1
  105. package/dist/cli/commands/types.d.ts +1 -1
  106. package/dist/cli/commands/worker.d.ts +1 -1
  107. package/dist/cli/deploy-strategy.d.ts +1 -1
  108. package/dist/cli/deploy-target.d.ts +1 -1
  109. package/dist/cli/help-pages/pages/account.d.ts +1 -1
  110. package/dist/cli/help-pages/pages/core.d.ts +1 -1
  111. package/dist/cli/help-pages/pages/index.d.ts +1 -1
  112. package/dist/cli/help-pages/pages/misc.d.ts +1 -1
  113. package/dist/cli/help-pages/pages/previews.d.ts +1 -1
  114. package/dist/cli/help-pages/pages/productions.d.ts +1 -1
  115. package/dist/cli/help-pages/render.d.ts +2 -2
  116. package/dist/cli/help-pages/shared.d.ts +1 -1
  117. package/dist/cli/help.d.ts +2 -2
  118. package/dist/cli/index.js +2 -1383
  119. package/dist/cli/preview-bindings.d.ts +3 -3
  120. package/dist/cli/preview.d.ts +1 -1
  121. package/dist/cli/wrangler-auth.d.ts +1 -1
  122. package/dist/cloudflare/account-core.d.ts +2 -2
  123. package/dist/cloudflare/account-resources.d.ts +2 -2
  124. package/dist/cloudflare/account-status.d.ts +1 -1
  125. package/dist/cloudflare/account-workers.d.ts +2 -2
  126. package/dist/cloudflare/account.d.ts +7 -7
  127. package/dist/cloudflare/auth.d.ts +1 -1
  128. package/dist/cloudflare/index.d.ts +13 -13
  129. package/dist/cloudflare/index.js +4 -59
  130. package/dist/cloudflare/kv-namespace.d.ts +1 -1
  131. package/dist/cloudflare/preview-registry-cache.d.ts +1 -1
  132. package/dist/cloudflare/preview-registry-inference.d.ts +2 -2
  133. package/dist/cloudflare/preview-registry-records.d.ts +3 -3
  134. package/dist/cloudflare/preview-registry-shape.d.ts +2 -2
  135. package/dist/cloudflare/preview-registry-store.d.ts +3 -3
  136. package/dist/cloudflare/preview-registry-transport.d.ts +2 -2
  137. package/dist/cloudflare/preview-registry-types.d.ts +2 -2
  138. package/dist/cloudflare/preview-registry.d.ts +5 -5
  139. package/dist/cloudflare/tokens.d.ts +2 -2
  140. package/dist/cloudflare/usage.d.ts +2 -2
  141. package/dist/config/binding-resolution-helpers.d.ts +1 -1
  142. package/dist/config/compiler/bindings.d.ts +2 -2
  143. package/dist/config/compiler/core-helpers.d.ts +2 -2
  144. package/dist/config/compiler/do-workers.d.ts +2 -2
  145. package/dist/config/compiler/paths.d.ts +1 -1
  146. package/dist/config/compiler.d.ts +6 -6
  147. package/dist/config/define.d.ts +2 -2
  148. package/dist/config/deploy-resources.d.ts +5 -5
  149. package/dist/config/env-vars.d.ts +1 -1
  150. package/dist/config/framework-providers.d.ts +1 -1
  151. package/dist/config/index.d.ts +12 -12
  152. package/dist/config/loader.d.ts +2 -2
  153. package/dist/config/local-dev-vars.d.ts +1 -1
  154. package/dist/config/preview-resources.d.ts +4 -4
  155. package/dist/config/preview.d.ts +1 -1
  156. package/dist/config/ref.d.ts +2 -2
  157. package/dist/config/resolve-phased.d.ts +4 -4
  158. package/dist/config/resolve.d.ts +1 -1
  159. package/dist/config/resource-resolution.d.ts +6 -6
  160. package/dist/config/schema-env.d.ts +20 -20
  161. package/dist/config/schema-normalization.d.ts +1 -1
  162. package/dist/config/schema-types-bindings.d.ts +4 -4
  163. package/dist/config/schema-types-build.d.ts +1 -1
  164. package/dist/config/schema-types.d.ts +7 -7
  165. package/dist/config/schema.d.ts +46 -46
  166. package/dist/config/service-bindings-validation.d.ts +1 -1
  167. package/dist/config-entry.d.ts +6 -6
  168. package/dist/config-entry.js +3 -8
  169. package/dist/decorators/index.d.ts +2 -2
  170. package/dist/decorators/index.js +2 -9
  171. package/dist/dev-server/d1-migrations.d.ts +1 -1
  172. package/dist/dev-server/dev-server-state.d.ts +6 -6
  173. package/dist/dev-server/gateway-script.d.ts +1 -1
  174. package/dist/dev-server/index.d.ts +1 -1
  175. package/dist/dev-server/miniflare-bindings.d.ts +1 -1
  176. package/dist/dev-server/miniflare-dev-config.d.ts +5 -5
  177. package/dist/dev-server/miniflare-worker-config.d.ts +3 -3
  178. package/dist/dev-server/server-startup-helpers.d.ts +6 -6
  179. package/dist/dev-server/worker-surface-paths.d.ts +2 -2
  180. package/dist/index.d.ts +8 -8
  181. package/dist/index.js +9 -22
  182. package/dist/runtime/context-events.d.ts +1 -1
  183. package/dist/runtime/context.d.ts +3 -3
  184. package/dist/runtime/exports.d.ts +2 -2
  185. package/dist/runtime/index.d.ts +10 -10
  186. package/dist/runtime/index.js +5 -57
  187. package/dist/runtime/middleware.d.ts +1 -1
  188. package/dist/runtime/router/index.d.ts +3 -3
  189. package/dist/runtime/validation.d.ts +1 -1
  190. package/dist/secrets/local-secrets.d.ts +1 -1
  191. package/dist/shims/local-media-bindings.d.ts +1 -1
  192. package/dist/sveltekit/index.d.ts +1 -1
  193. package/dist/sveltekit/index.js +327 -9
  194. package/dist/sveltekit/local-bindings.d.ts +1 -1
  195. package/dist/sveltekit/platform.d.ts +1 -1
  196. package/dist/test/binding-hints.d.ts +2 -2
  197. package/dist/test/cf.d.ts +19 -19
  198. package/dist/test/index.d.ts +18 -18
  199. package/dist/test/index.js +4495 -46
  200. package/dist/test/offline-bindings.d.ts +3 -3
  201. package/dist/test/resolve-service-bindings.d.ts +1 -1
  202. package/dist/test/simple-context-bindings.d.ts +1 -1
  203. package/dist/test/simple-context-durable-objects.d.ts +1 -1
  204. package/dist/test/simple-context-env.d.ts +2 -2
  205. package/dist/test/simple-context-handlers.d.ts +2 -2
  206. package/dist/test/simple-context-lifecycle.d.ts +2 -2
  207. package/dist/test/simple-context-mfconfig.d.ts +1 -1
  208. package/dist/test/simple-context-multi-worker.d.ts +2 -2
  209. package/dist/test/simple-context-runtime.d.ts +1 -1
  210. package/dist/test/simple-context-startup.d.ts +1 -1
  211. package/dist/test/simple-context.d.ts +1 -1
  212. package/dist/test/utilities/env.d.ts +3 -3
  213. package/dist/test/utilities.d.ts +10 -10
  214. package/dist/test/worker.d.ts +1 -1
  215. package/dist/transform/index.d.ts +2 -2
  216. package/dist/utils/send-email.js +163 -19
  217. package/dist/vite/config-file.d.ts +2 -2
  218. package/dist/vite/index.d.ts +3 -3
  219. package/dist/vite/index.js +2 -31
  220. package/dist/vite/plugin-config-hook.d.ts +1 -1
  221. package/dist/vite/plugin-context.d.ts +3 -3
  222. package/dist/vite/plugin-durable-objects.d.ts +2 -2
  223. package/dist/vite/plugin-programmatic.d.ts +1 -1
  224. package/dist/vite/plugin-service-bindings.d.ts +2 -2
  225. package/dist/vite/plugin.d.ts +3 -3
  226. package/dist/worker-entry/composed-worker.d.ts +1 -1
  227. package/dist/worker-entry/routes.d.ts +2 -2
  228. package/dist/worker-entry/surface-paths.d.ts +1 -1
  229. package/dist/workflows/local-workflow-entrypoints.d.ts +1 -1
  230. package/package.json +5 -3
  231. package/dist/account-4tgh03a8.js +0 -484
  232. package/dist/ai-r3zqmxan.js +0 -261
  233. package/dist/api-6z01z734.js +0 -33
  234. package/dist/build-kw625v84.js +0 -51
  235. package/dist/config-ghk2bxj3.js +0 -102
  236. package/dist/deploy-9kee65n9.js +0 -1062
  237. package/dist/dev-x8zr249a.js +0 -3569
  238. package/dist/doctor-0ng5qrr1.js +0 -258
  239. package/dist/durable-object-0ybmg08a.js +0 -13
  240. package/dist/index-04wh9bxx.js +0 -514
  241. package/dist/index-0cc05hzv.js +0 -74
  242. package/dist/index-2yv7w548.js +0 -185
  243. package/dist/index-37x76zdn.js +0 -4
  244. package/dist/index-3cpzsr47.js +0 -125
  245. package/dist/index-3t6rypgc.js +0 -13
  246. package/dist/index-4mmpccrb.js +0 -309
  247. package/dist/index-5dkjffqz.js +0 -25
  248. package/dist/index-5hy7jmv3.js +0 -890
  249. package/dist/index-627srx16.js +0 -45
  250. package/dist/index-7m557715.js +0 -283
  251. package/dist/index-a8pnvg3r.js +0 -52
  252. package/dist/index-aabgympv.js +0 -39
  253. package/dist/index-atwc3csp.js +0 -256
  254. package/dist/index-cv4cvrxe.js +0 -2046
  255. package/dist/index-h7r11y4a.js +0 -539
  256. package/dist/index-hvtd936d.js +0 -1229
  257. package/dist/index-kcp7y951.js +0 -136
  258. package/dist/index-maw0jjnn.js +0 -147
  259. package/dist/index-mek9msfv.js +0 -705
  260. package/dist/index-n4xkaymm.js +0 -236
  261. package/dist/index-nkk59p3y.js +0 -579
  262. package/dist/index-phcrvs6d.js +0 -342
  263. package/dist/index-se4kw8tm.js +0 -460
  264. package/dist/index-x8s9rwfh.js +0 -2020
  265. package/dist/index-y7w3x9p1.js +0 -18
  266. package/dist/index-z9gy8w6b.js +0 -57
  267. package/dist/index-zdd0d9qa.js +0 -199
  268. package/dist/init-tb8jqgvr.js +0 -180
  269. package/dist/login-4h1sfsed.js +0 -75
  270. package/dist/previews-qr7c5j8h.js +0 -1336
  271. package/dist/productions-xpmd6bw8.js +0 -505
  272. package/dist/remote-kqcvhnfx.js +0 -192
  273. package/dist/secrets-6wbdsdek.js +0 -89
  274. package/dist/token-yp1qa70y.js +0 -419
  275. package/dist/types-15yv4cj3.js +0 -701
  276. package/dist/worker-1yg72jxg.js +0 -510
  277. package/dist/worker-entrypoint-y8s9kdcx.js +0 -15
@@ -1,1336 +0,0 @@
1
- import {
2
- buildPreviewScopeRowsFromLiveWorkers,
3
- buildPreviewWorkerCandidatesByScope,
4
- buildStableWorkerRowsFromLiveWorkers,
5
- collectConfiguredWorkerFamilies,
6
- orderPreviewWorkerNamesForDeletion
7
- } from "./index-2yv7w548.js";
8
- import {
9
- cleanupPreviewScopedResources
10
- } from "./index-se4kw8tm.js";
11
- import {
12
- findConfigPathsUnderDirectory
13
- } from "./index-a8pnvg3r.js";
14
- import {
15
- asOptionalString,
16
- resolveCloudflareAccountId,
17
- resolveNamedSelection
18
- } from "./index-0cc05hzv.js";
19
- import {
20
- account
21
- } from "./index-phcrvs6d.js";
22
- import"./index-atwc3csp.js";
23
- import"./index-hvtd936d.js";
24
- import {
25
- getDependencies
26
- } from "./index-z9gy8w6b.js";
27
- import {
28
- bold,
29
- createCliTheme,
30
- cyanBold,
31
- dim,
32
- formatTableLine,
33
- green,
34
- logLine,
35
- red,
36
- whiteDim,
37
- yellow,
38
- yellowBold
39
- } from "./index-maw0jjnn.js";
40
- import"./index-3t6rypgc.js";
41
- import"./index-5dkjffqz.js";
42
- import {
43
- compileBuildConfig
44
- } from "./index-mek9msfv.js";
45
- import {
46
- ConfigNotFoundError,
47
- loadConfig,
48
- loadResolvedConfig,
49
- resolveConfigPath,
50
- resolvePreviewIdentifier
51
- } from "./index-x8s9rwfh.js";
52
- import"./index-h7r11y4a.js";
53
- import"./index-04wh9bxx.js";
54
- import"./index-37x76zdn.js";
55
-
56
- // src/cli/preview-bindings.ts
57
- function normalizeCell(value) {
58
- return (value ?? "").trim().replace(/\s+/g, " ");
59
- }
60
- function buildAssociationKey(type, resource) {
61
- return `${normalizeCell(type).toLowerCase()}\x00${normalizeCell(resource).toLowerCase()}`;
62
- }
63
- function uniqueStrings(values) {
64
- return Array.from(new Set(values.filter((value) => value.trim().length > 0)));
65
- }
66
- function formatSendEmailResource(entry) {
67
- const destination = entry.destination_address?.trim();
68
- if (destination) {
69
- return destination;
70
- }
71
- const destinations = uniqueStrings(entry.allowed_destination_addresses ?? []);
72
- const senders = uniqueStrings(entry.allowed_sender_addresses ?? []);
73
- const destinationLabel = destinations.length > 0 ? destinations.join(", ") : "configured destinations";
74
- if (senders.length === 0) {
75
- return destinationLabel;
76
- }
77
- return `${destinationLabel} - senders: ${senders.join(", ")}`;
78
- }
79
- function addAssociationTarget(targets, input) {
80
- const type = normalizeCell(input.type);
81
- const resource = normalizeCell(input.resource);
82
- const key = buildAssociationKey(type, resource);
83
- const existing = targets.get(key);
84
- if (existing) {
85
- if (input.reference) {
86
- existing.referenceLabels = uniqueStrings([...existing.referenceLabels, input.reference]);
87
- }
88
- if (input.note) {
89
- existing.notes = uniqueStrings([...existing.notes, input.note]);
90
- }
91
- if (!existing.queueName && input.queueName) {
92
- existing.queueName = input.queueName;
93
- }
94
- return;
95
- }
96
- targets.set(key, {
97
- key,
98
- referenceLabels: input.reference ? [input.reference] : [],
99
- type,
100
- resource,
101
- notes: input.note ? [input.note] : [],
102
- queueName: input.queueName
103
- });
104
- }
105
- function collectBindingAssociationTargets(config) {
106
- const compiled = compileBuildConfig(config);
107
- const targets = new Map;
108
- for (const binding of compiled.kv_namespaces ?? []) {
109
- addAssociationTarget(targets, {
110
- reference: binding.binding,
111
- type: "KV Namespace",
112
- resource: "id" in binding ? binding.id : binding.name
113
- });
114
- }
115
- for (const binding of compiled.d1_databases ?? []) {
116
- addAssociationTarget(targets, {
117
- reference: binding.binding,
118
- type: "D1 Database",
119
- resource: "database_id" in binding ? binding.database_id : binding.database_name
120
- });
121
- }
122
- for (const binding of compiled.r2_buckets ?? []) {
123
- addAssociationTarget(targets, {
124
- reference: binding.binding,
125
- type: "R2 Bucket",
126
- resource: binding.bucket_name
127
- });
128
- }
129
- for (const binding of compiled.durable_objects?.bindings ?? []) {
130
- addAssociationTarget(targets, {
131
- reference: binding.name,
132
- type: "Durable Object Namespace",
133
- resource: binding.class_name,
134
- note: binding.script_name ? `script ${binding.script_name}` : undefined
135
- });
136
- }
137
- for (const binding of compiled.queues?.producers ?? []) {
138
- addAssociationTarget(targets, {
139
- reference: binding.binding,
140
- type: "Queue",
141
- resource: binding.queue,
142
- note: "producer binding",
143
- queueName: binding.queue
144
- });
145
- }
146
- for (const binding of compiled.queues?.consumers ?? []) {
147
- addAssociationTarget(targets, {
148
- type: "Queue",
149
- resource: binding.queue,
150
- note: "consumer attachment",
151
- queueName: binding.queue
152
- });
153
- if (binding.dead_letter_queue) {
154
- addAssociationTarget(targets, {
155
- type: "Queue",
156
- resource: binding.dead_letter_queue,
157
- note: "dead letter queue",
158
- queueName: binding.dead_letter_queue
159
- });
160
- }
161
- }
162
- for (const binding of compiled.ratelimits ?? []) {
163
- addAssociationTarget(targets, {
164
- reference: binding.name,
165
- type: "Rate Limiting",
166
- resource: binding.namespace_id
167
- });
168
- }
169
- if (compiled.version_metadata) {
170
- addAssociationTarget(targets, {
171
- reference: compiled.version_metadata.binding,
172
- type: "Version Metadata",
173
- resource: "Version Metadata"
174
- });
175
- }
176
- for (const binding of compiled.worker_loaders ?? []) {
177
- addAssociationTarget(targets, {
178
- reference: binding.binding,
179
- type: "Worker Loader",
180
- resource: "Worker Loader"
181
- });
182
- }
183
- for (const binding of compiled.mtls_certificates ?? []) {
184
- addAssociationTarget(targets, {
185
- reference: binding.binding,
186
- type: "mTLS Certificate",
187
- resource: binding.certificate_id
188
- });
189
- }
190
- for (const binding of compiled.dispatch_namespaces ?? []) {
191
- addAssociationTarget(targets, {
192
- reference: binding.binding,
193
- type: "Dispatch Namespace",
194
- resource: binding.namespace,
195
- note: binding.outbound ? `outbound ${binding.outbound.service}` : undefined
196
- });
197
- }
198
- for (const binding of compiled.workflows ?? []) {
199
- addAssociationTarget(targets, {
200
- reference: binding.binding,
201
- type: "Workflow",
202
- resource: binding.name,
203
- note: binding.script_name ? `script ${binding.script_name}` : binding.class_name
204
- });
205
- }
206
- for (const binding of compiled.pipelines ?? []) {
207
- addAssociationTarget(targets, {
208
- reference: binding.binding,
209
- type: "Pipeline",
210
- resource: binding.pipeline,
211
- note: binding.remote ? "remote local binding" : undefined
212
- });
213
- }
214
- if (compiled.images) {
215
- addAssociationTarget(targets, {
216
- reference: compiled.images.binding,
217
- type: "Images",
218
- resource: "Images",
219
- note: compiled.images.remote ? "remote local binding" : undefined
220
- });
221
- }
222
- if (compiled.media) {
223
- addAssociationTarget(targets, {
224
- reference: compiled.media.binding,
225
- type: "Media Transformations",
226
- resource: "Media Transformations",
227
- note: compiled.media.remote ? "remote local binding" : undefined
228
- });
229
- }
230
- for (const binding of compiled.artifacts ?? []) {
231
- addAssociationTarget(targets, {
232
- reference: binding.binding,
233
- type: "Artifacts",
234
- resource: binding.namespace,
235
- note: binding.remote ? "remote local binding" : undefined
236
- });
237
- }
238
- for (const binding of compiled.secrets_store_secrets ?? []) {
239
- addAssociationTarget(targets, {
240
- reference: binding.binding,
241
- type: "Secrets Store",
242
- resource: `${binding.store_id}/${binding.secret_name}`
243
- });
244
- }
245
- for (const consumer of compiled.tail_consumers ?? []) {
246
- addAssociationTarget(targets, {
247
- type: "Tail Consumer",
248
- resource: consumer.service,
249
- note: consumer.environment ? `env ${consumer.environment}` : undefined
250
- });
251
- }
252
- for (const binding of compiled.services ?? []) {
253
- addAssociationTarget(targets, {
254
- reference: binding.binding,
255
- type: "Worker",
256
- resource: binding.entrypoint ? `${binding.service}#${binding.entrypoint}` : binding.service,
257
- note: binding.environment ? `env ${binding.environment}` : undefined
258
- });
259
- }
260
- if (compiled.ai?.binding) {
261
- addAssociationTarget(targets, {
262
- reference: compiled.ai.binding,
263
- type: "AI",
264
- resource: "Workers AI"
265
- });
266
- }
267
- for (const binding of compiled.vectorize ?? []) {
268
- addAssociationTarget(targets, {
269
- reference: binding.binding,
270
- type: "Vectorize",
271
- resource: binding.index_name
272
- });
273
- }
274
- for (const binding of compiled.hyperdrive ?? []) {
275
- addAssociationTarget(targets, {
276
- reference: binding.binding,
277
- type: "Hyperdrive",
278
- resource: "id" in binding ? binding.id : binding.name
279
- });
280
- }
281
- if (compiled.browser?.binding) {
282
- addAssociationTarget(targets, {
283
- reference: compiled.browser.binding,
284
- type: "Browser",
285
- resource: "Browser Rendering"
286
- });
287
- }
288
- for (const binding of compiled.analytics_engine_datasets ?? []) {
289
- addAssociationTarget(targets, {
290
- reference: binding.binding,
291
- type: "Analytics Engine",
292
- resource: binding.dataset
293
- });
294
- }
295
- for (const binding of compiled.send_email ?? []) {
296
- addAssociationTarget(targets, {
297
- reference: binding.name,
298
- type: "Send Email",
299
- resource: formatSendEmailResource(binding)
300
- });
301
- }
302
- return Array.from(targets.values());
303
- }
304
- function getActiveVersionId(deployments) {
305
- const sortedDeployments = [...deployments].sort((left, right) => right.createdOn.getTime() - left.createdOn.getTime());
306
- for (const deployment of sortedDeployments) {
307
- const version = [...deployment.versions].sort((left, right) => right.percentage - left.percentage)[0];
308
- if (version?.versionId) {
309
- return version.versionId;
310
- }
311
- }
312
- return;
313
- }
314
- function extractWorkerNames(value) {
315
- return Array.from(value.matchAll(/worker:([^,\s]+)/gi), (match) => match[1]);
316
- }
317
- function parseWranglerQueueInfo(output) {
318
- const lines = output.split(/\r?\n/);
319
- let queueName = "";
320
- const producerWorkers = [];
321
- const consumerWorkers = [];
322
- let currentSection = null;
323
- for (const rawLine of lines) {
324
- const trimmed = rawLine.trim();
325
- if (!trimmed) {
326
- currentSection = null;
327
- continue;
328
- }
329
- const queueMatch = trimmed.match(/^Queue Name:\s*(.+)$/i);
330
- if (queueMatch) {
331
- queueName = normalizeCell(queueMatch[1]);
332
- currentSection = null;
333
- continue;
334
- }
335
- const producerMatch = trimmed.match(/^Producers:\s*(.*)$/i);
336
- if (producerMatch) {
337
- producerWorkers.push(...extractWorkerNames(producerMatch[1]));
338
- currentSection = producerMatch[1] ? null : "producers";
339
- continue;
340
- }
341
- const consumerMatch = trimmed.match(/^Consumers:\s*(.*)$/i);
342
- if (consumerMatch) {
343
- consumerWorkers.push(...extractWorkerNames(consumerMatch[1]));
344
- currentSection = consumerMatch[1] ? null : "consumers";
345
- continue;
346
- }
347
- if (!currentSection) {
348
- continue;
349
- }
350
- const extractedWorkers = extractWorkerNames(trimmed);
351
- if (currentSection === "producers") {
352
- producerWorkers.push(...extractedWorkers);
353
- } else {
354
- consumerWorkers.push(...extractedWorkers);
355
- }
356
- }
357
- if (!queueName) {
358
- return null;
359
- }
360
- return {
361
- queueName,
362
- producerWorkers: uniqueStrings(producerWorkers),
363
- consumerWorkers: uniqueStrings(consumerWorkers)
364
- };
365
- }
366
- function parseWranglerVersionBindings(jsonOutput) {
367
- let parsed;
368
- try {
369
- parsed = JSON.parse(jsonOutput);
370
- } catch {
371
- return [];
372
- }
373
- const bindings = extractBindingsArray(parsed);
374
- if (!bindings) {
375
- return [];
376
- }
377
- const rows = [];
378
- for (const raw of bindings) {
379
- const row = mapWranglerBindingToRow(raw);
380
- if (row) {
381
- rows.push(row);
382
- }
383
- }
384
- return rows;
385
- }
386
- function extractBindingsArray(parsed) {
387
- if (!parsed || typeof parsed !== "object") {
388
- return null;
389
- }
390
- const root = parsed;
391
- const bindings = root.resources?.bindings;
392
- return Array.isArray(bindings) ? bindings : null;
393
- }
394
- function mapWranglerBindingToRow(raw) {
395
- if (!raw || typeof raw !== "object") {
396
- return null;
397
- }
398
- const binding = raw;
399
- const type = typeof binding.type === "string" ? binding.type : "";
400
- const bindingName = typeof binding.name === "string" ? binding.name : "";
401
- if (!type || !bindingName) {
402
- return null;
403
- }
404
- const mapped = mapWranglerBindingType(type, binding);
405
- if (!mapped) {
406
- return null;
407
- }
408
- return {
409
- type: mapped.friendlyType,
410
- bindingName,
411
- resource: mapped.resource
412
- };
413
- }
414
- function mapWranglerBindingType(type, binding) {
415
- const stringField = (key) => typeof binding[key] === "string" ? binding[key] : "";
416
- switch (type) {
417
- case "kv_namespace":
418
- return { friendlyType: "KV Namespace", resource: stringField("namespace_id") };
419
- case "d1":
420
- return { friendlyType: "D1 Database", resource: stringField("id") };
421
- case "r2_bucket":
422
- return { friendlyType: "R2 Bucket", resource: stringField("bucket_name") };
423
- case "durable_object_namespace":
424
- return {
425
- friendlyType: "Durable Object Namespace",
426
- resource: stringField("class_name")
427
- };
428
- case "queue":
429
- return { friendlyType: "Queue", resource: stringField("queue_name") };
430
- case "ratelimit":
431
- return { friendlyType: "Rate Limiting", resource: stringField("namespace_id") };
432
- case "service": {
433
- const service = stringField("service") || binding.name;
434
- const entrypoint = stringField("entrypoint");
435
- return {
436
- friendlyType: "Worker",
437
- resource: entrypoint ? `${service}#${entrypoint}` : service
438
- };
439
- }
440
- case "ai":
441
- return { friendlyType: "AI", resource: "Workers AI" };
442
- case "vectorize":
443
- return { friendlyType: "Vectorize", resource: stringField("index_name") };
444
- case "hyperdrive":
445
- return { friendlyType: "Hyperdrive", resource: stringField("id") };
446
- case "browser":
447
- return { friendlyType: "Browser", resource: "Browser Rendering" };
448
- case "analytics_engine":
449
- return { friendlyType: "Analytics Engine", resource: stringField("dataset") };
450
- case "send_email":
451
- return {
452
- friendlyType: "Send Email",
453
- resource: stringField("destination_address") || stringField("name") || binding.name
454
- };
455
- case "mtls_certificate":
456
- return { friendlyType: "mTLS Certificate", resource: stringField("certificate_id") };
457
- case "dispatch_namespace":
458
- return { friendlyType: "Dispatch Namespace", resource: stringField("namespace") };
459
- case "workflow":
460
- return {
461
- friendlyType: "Workflow",
462
- resource: stringField("workflow_name") || stringField("name")
463
- };
464
- case "pipeline":
465
- return { friendlyType: "Pipeline", resource: stringField("pipeline") };
466
- case "images":
467
- return { friendlyType: "Images", resource: "Images" };
468
- case "media":
469
- return { friendlyType: "Media Transformations", resource: "Media Transformations" };
470
- case "artifacts":
471
- return { friendlyType: "Artifacts", resource: stringField("namespace") };
472
- case "version_metadata":
473
- return { friendlyType: "Version Metadata", resource: "Version Metadata" };
474
- case "worker_loader":
475
- return { friendlyType: "Worker Loader", resource: "Worker Loader" };
476
- case "secrets_store_secret":
477
- return {
478
- friendlyType: "Secrets Store",
479
- resource: `${stringField("store_id")}/${stringField("secret_name")}`
480
- };
481
- case "plain_text":
482
- case "json":
483
- case "secret_text":
484
- return null;
485
- default:
486
- return { friendlyType: type, resource: stringField("id") || stringField("name") || "" };
487
- }
488
- }
489
- async function inspectWorkerBindings(exec, options) {
490
- const output = await runWranglerInspectionCommand(exec, ["wrangler", "versions", "view", options.versionId, "--name", options.workerName, "--json"], options, "Wrangler versions view failed");
491
- return parseWranglerVersionBindings(output);
492
- }
493
- async function runWranglerInspectionCommand(exec, args, options, failureMessage) {
494
- const result = await exec.exec("bunx", args, {
495
- cwd: options.cwd,
496
- env: {
497
- ...process.env,
498
- CLOUDFLARE_ACCOUNT_ID: options.accountId,
499
- FORCE_COLOR: process.env.FORCE_COLOR ?? "0"
500
- }
501
- });
502
- if (result.exitCode !== 0) {
503
- throw new Error(result.stderr || result.stdout || failureMessage);
504
- }
505
- return `${result.stdout}
506
- ${result.stderr}`;
507
- }
508
- async function inspectQueueAssociation(exec, options) {
509
- const output = await runWranglerInspectionCommand(exec, ["wrangler", "queues", "info", options.queueName], options, "Wrangler queues info failed");
510
- return parseWranglerQueueInfo(output);
511
- }
512
- function formatReference(target) {
513
- return target.referenceLabels.length > 0 ? target.referenceLabels.join(", ") : "—";
514
- }
515
- function formatResource(target) {
516
- return target.resource || "—";
517
- }
518
- function buildRowNotes(target, queueAssociation) {
519
- const notes = [...target.notes];
520
- if (queueAssociation) {
521
- notes.push(`producers ${queueAssociation.producerWorkers.length}`);
522
- notes.push(`consumers ${queueAssociation.consumerWorkers.length}`);
523
- }
524
- return uniqueStrings(notes);
525
- }
526
- async function inspectBindingAssociations(options) {
527
- const targets = collectBindingAssociationTargets(options.config);
528
- const warnings = [];
529
- const bindingUsage = new Map;
530
- const scannedWorkers = [];
531
- const queueTargets = uniqueStrings(targets.map((target) => target.queueName).filter((queueName) => typeof queueName === "string" && queueName.length > 0));
532
- const queueAssociations = new Map;
533
- const workers = await account.workers(options.accountId, options.apiOptions);
534
- for (const worker of workers) {
535
- let versionId;
536
- try {
537
- const deployments = await account.workerDeployments(options.accountId, worker.name, options.apiOptions);
538
- versionId = getActiveVersionId(deployments);
539
- } catch (error) {
540
- const message = error instanceof Error ? error.message : String(error);
541
- warnings.push(`Could not resolve active deployment for ${worker.name}: ${message}`);
542
- continue;
543
- }
544
- if (!versionId) {
545
- continue;
546
- }
547
- scannedWorkers.push(worker.name);
548
- try {
549
- const bindings = await inspectWorkerBindings(options.exec, {
550
- accountId: options.accountId,
551
- workerName: worker.name,
552
- versionId,
553
- cwd: options.cwd
554
- });
555
- for (const binding of bindings) {
556
- const key = buildAssociationKey(binding.type, binding.resource);
557
- const connectedWorkers = bindingUsage.get(key) ?? new Set;
558
- connectedWorkers.add(worker.name);
559
- bindingUsage.set(key, connectedWorkers);
560
- }
561
- } catch (error) {
562
- const message = error instanceof Error ? error.message : String(error);
563
- warnings.push(`Could not inspect bindings for ${worker.name}: ${message}`);
564
- }
565
- }
566
- for (const queueName of queueTargets) {
567
- try {
568
- const queueAssociation = await inspectQueueAssociation(options.exec, {
569
- accountId: options.accountId,
570
- queueName,
571
- cwd: options.cwd
572
- });
573
- if (queueAssociation) {
574
- queueAssociations.set(queueName, queueAssociation);
575
- }
576
- } catch (error) {
577
- const message = error instanceof Error ? error.message : String(error);
578
- warnings.push(`Could not inspect queue ${queueName}: ${message}`);
579
- }
580
- }
581
- const rows = targets.map((target) => {
582
- const queueAssociation = target.queueName ? queueAssociations.get(target.queueName) : undefined;
583
- const directlyConnectedWorkers = Array.from(bindingUsage.get(target.key) ?? []);
584
- const connectedWorkers = uniqueStrings([
585
- ...directlyConnectedWorkers,
586
- ...queueAssociation?.producerWorkers ?? [],
587
- ...queueAssociation?.consumerWorkers ?? []
588
- ]).sort((left, right) => left.localeCompare(right));
589
- return {
590
- reference: formatReference(target),
591
- type: target.type,
592
- resource: formatResource(target),
593
- workerCount: connectedWorkers.length,
594
- connectedWorkers,
595
- notes: buildRowNotes(target, queueAssociation),
596
- producerWorkers: queueAssociation?.producerWorkers,
597
- consumerWorkers: queueAssociation?.consumerWorkers
598
- };
599
- });
600
- return {
601
- workerName: options.workerName ?? options.config.name,
602
- rows,
603
- targets: targets.length,
604
- scannedWorkers,
605
- warnings
606
- };
607
- }
608
-
609
- // src/cli/commands/previews-support/theme.ts
610
- function shouldUseColor(options) {
611
- return createCliTheme(options).useColor;
612
- }
613
- function formatRecordDate(date) {
614
- return date ? date.toISOString().slice(0, 19).replace("T", " ") : "N/A";
615
- }
616
- function formatStatus(value, theme) {
617
- switch (value) {
618
- case "active":
619
- return green(value, theme);
620
- case "superseded":
621
- case "reassigned":
622
- case "orphaned":
623
- return yellow(value, theme);
624
- case "deleted":
625
- case "rolled_back":
626
- return red(value, theme);
627
- default:
628
- return value;
629
- }
630
- }
631
- function formatOverviewStatus(value, theme) {
632
- switch (value) {
633
- case "ready":
634
- return green(value, theme);
635
- case "partial":
636
- return yellow(value, theme);
637
- case "missing":
638
- return red(value, theme);
639
- default:
640
- return formatStatus(value, theme);
641
- }
642
- }
643
-
644
- // src/cli/commands/previews-support/cleanup.ts
645
- function comparePreviewCleanupScopeNames(left, right) {
646
- if (left === "preview" && right !== "preview") {
647
- return 1;
648
- }
649
- if (left !== "preview" && right === "preview") {
650
- return -1;
651
- }
652
- return left.localeCompare(right);
653
- }
654
- function buildPreviewCleanupTarget(scope, workerCandidatesByScope, environment) {
655
- const strategies = new Set;
656
- const workerNames = [...workerCandidatesByScope.get(scope) ?? []];
657
- if (workerNames.length > 0) {
658
- strategies.add("dedicated workers");
659
- }
660
- if (scope === "preview" && environment === "preview") {
661
- strategies.add("default preview scope");
662
- }
663
- return {
664
- scope,
665
- strategies: Array.from(strategies),
666
- workerNames
667
- };
668
- }
669
- function buildPreviewCleanupTargets(workerCandidatesByScope, environment) {
670
- const scopeNames = new Set;
671
- for (const scope of workerCandidatesByScope.keys()) {
672
- scopeNames.add(scope);
673
- }
674
- return Array.from(scopeNames).sort(comparePreviewCleanupScopeNames).map((scope) => buildPreviewCleanupTarget(scope, workerCandidatesByScope, environment));
675
- }
676
- function getPreviewCleanupResourceCandidateCount(result) {
677
- return result.candidates.kv.length + result.candidates.d1.length + result.candidates.r2.length + result.candidates.queues.length + result.candidates.vectorize.length + result.candidates.hyperdrive.length;
678
- }
679
- function buildPreviewCleanupResourceSummary(result) {
680
- return [
681
- result.candidates.kv.length > 0 ? `KV ${result.candidates.kv.length}` : null,
682
- result.candidates.d1.length > 0 ? `D1 ${result.candidates.d1.length}` : null,
683
- result.candidates.r2.length > 0 ? `R2 ${result.candidates.r2.length}` : null,
684
- result.candidates.queues.length > 0 ? `Queues ${result.candidates.queues.length}` : null,
685
- result.candidates.vectorize.length > 0 ? `Vectorize ${result.candidates.vectorize.length}` : null,
686
- result.candidates.hyperdrive.length > 0 ? `Hyperdrive ${result.candidates.hyperdrive.length}` : null
687
- ].filter((segment) => segment !== null);
688
- }
689
- function logResolvedPreviewScopes(logger, targets, theme) {
690
- if (targets.length === 0) {
691
- logLine(logger, `${dim("preview scopes", theme)} ${dim("none discovered (--all)", theme)}`);
692
- logLine(logger);
693
- return;
694
- }
695
- logLine(logger, `${dim("preview scopes", theme)} ${green(targets.map((target) => target.scope).join(", "), theme)} ${dim("(--all)", theme)}`);
696
- logLine(logger);
697
- }
698
- function logPreviewCleanupScopeBreakdown(logger, executions, theme) {
699
- const scopedExecutions = executions.filter((execution) => execution.target);
700
- if (scopedExecutions.length === 0) {
701
- return;
702
- }
703
- logLine(logger, `${dim("scope breakdown", theme)}`);
704
- for (const execution of scopedExecutions) {
705
- const target = execution.target;
706
- const strategies = target.strategies.length > 0 ? dim(`(${target.strategies.join(" + ")})`, theme) : "";
707
- const summary = [
708
- target.workerNames.length > 0 ? `Workers ${target.workerNames.length}` : null,
709
- ...buildPreviewCleanupResourceSummary(execution.result)
710
- ].filter((segment) => segment !== null);
711
- logLine(logger, ` ${green(target.scope, theme)} ${strategies} ${dim("—", theme)} ${summary.length > 0 ? summary.join(" · ") : dim("none", theme)}`);
712
- }
713
- logLine(logger);
714
- }
715
- function showNoPreviewCleanupCandidatesHint(logger, selection, includeAll, theme) {
716
- if (includeAll) {
717
- logger.warn("No preview-only resources or dedicated preview Worker scripts were discovered across the live preview scopes Devflare could resolve. This usually means those previews were already cleaned up or the remaining previews only share stable Workers and shared account resources.");
718
- return;
719
- }
720
- if (!selection?.identifier) {
721
- return;
722
- }
723
- if (selection.source === "environment") {
724
- logger.warn(`No preview-only resources or dedicated preview Worker scripts matched the default "${selection.identifier}" scope. If your previews use branch-style scopes such as "next" or "pr-1", rerun with --scope <name>, use --all, or set DEVFLARE_PREVIEW_BRANCH, DEVFLARE_PREVIEW_PR, or DEVFLARE_PREVIEW_IDENTIFIER.`);
725
- return;
726
- }
727
- logger.warn(`No preview-only resources or dedicated preview Worker scripts matched the resolved "${selection.identifier}" scope. This usually means that scope was already cleaned up or the preview shares stable Workers without preview.scope() resources of its own.`);
728
- }
729
-
730
- // src/cli/commands/previews-support/render.ts
731
- function logWorkerFamilyHeader(logger, families, theme) {
732
- const primaryFamily = families.find((family) => family.role === "primary") ?? families[0];
733
- const relatedFamilies = families.filter((family) => family.role !== "primary");
734
- logLine(logger, `${dim("worker family", theme)} ${green(primaryFamily?.baseName ?? "unknown", theme)}`);
735
- if (relatedFamilies.length > 0) {
736
- logLine(logger, `${dim("related workers", theme)} ${whiteDim(String(relatedFamilies.length), theme)}`);
737
- }
738
- logLine(logger);
739
- }
740
- function logSection(logger, title, records, columns, theme) {
741
- for (const line of buildSectionLines(title, records, columns, theme)) {
742
- logLine(logger, line);
743
- }
744
- }
745
- function logLiveWorkerFamilyOverview(logger, families, workers, workersSubdomain, theme) {
746
- const stableRows = buildStableWorkerRowsFromLiveWorkers(families, workers, workersSubdomain);
747
- const previewScopeRows = buildPreviewScopeRowsFromLiveWorkers(families, workers, workersSubdomain);
748
- logWorkerFamilyHeader(logger, families, theme);
749
- logSection(logger, "Stable workers", stableRows, buildStableWorkerColumns(theme), theme);
750
- logLine(logger);
751
- if (previewScopeRows.length === 0) {
752
- logLine(logger, dim("No dedicated preview scopes found for this worker family.", theme));
753
- } else {
754
- logSection(logger, "Preview scopes", previewScopeRows, buildPreviewScopeColumns(theme), theme);
755
- }
756
- }
757
- function buildStableWorkerColumns(theme) {
758
- return [
759
- {
760
- label: "Worker",
761
- width: 34,
762
- value: (row) => row.workerName
763
- },
764
- {
765
- label: "Role",
766
- width: 20,
767
- value: (row) => row.role
768
- },
769
- {
770
- label: "Status",
771
- width: 8,
772
- value: (row) => formatOverviewStatus(row.status, theme)
773
- },
774
- {
775
- label: "Updated",
776
- width: 19,
777
- value: (row) => whiteDim(formatRecordDate(row.updatedAt), theme)
778
- },
779
- {
780
- label: "URL",
781
- value: (row) => row.url ?? "N/A"
782
- }
783
- ];
784
- }
785
- function buildPreviewScopeColumns(theme) {
786
- return [
787
- {
788
- label: "Scope",
789
- width: 18,
790
- value: (row) => row.scope
791
- },
792
- {
793
- label: "Strategy",
794
- width: 18,
795
- value: (row) => row.strategy
796
- },
797
- {
798
- label: "Workers",
799
- width: 7,
800
- value: (row) => row.workersLabel
801
- },
802
- {
803
- label: "Status",
804
- width: 10,
805
- value: (row) => formatOverviewStatus(row.status, theme)
806
- },
807
- {
808
- label: "Updated",
809
- width: 19,
810
- value: (row) => whiteDim(formatRecordDate(row.updatedAt), theme)
811
- },
812
- {
813
- label: "Notes",
814
- width: 30,
815
- value: (row) => row.notes ?? dim("—", theme)
816
- },
817
- {
818
- label: "Entry URL",
819
- value: (row) => row.entryUrl ?? "N/A"
820
- }
821
- ];
822
- }
823
- function buildSectionLines(title, records, columns, theme) {
824
- if (records.length === 0) {
825
- return [];
826
- }
827
- const widths = columns.map((column) => column.width);
828
- const coloredTitle = title === "Preview scopes" ? cyanBold(title, theme) : title === "Stable workers" ? bold(title, theme) : yellowBold(title, theme);
829
- return [
830
- `${coloredTitle} ${dim(`(${records.length})`, theme)}`,
831
- formatTableLine(columns.map((column) => dim(column.label, theme)), widths),
832
- ...records.map((record) => formatTableLine(columns.map((column) => column.value(record)), widths))
833
- ];
834
- }
835
- function showWorkerFamilyOverviewFromLiveWorkers(families, workers, workersSubdomain, logger, theme) {
836
- logLine(logger);
837
- logLiveWorkerFamilyOverview(logger, families, workers, workersSubdomain, theme);
838
- logLine(logger);
839
- logLine(logger, dim("Preview scopes are derived from live dedicated preview Worker names and the current config family.", theme));
840
- logLine(logger, dim("Use `devflare previews cleanup --scope <name>` to delete one scope or `--all` to clean every discovered scope.", theme));
841
- logLine(logger);
842
- }
843
- function showWorkspaceWorkerFamilyOverviewFromLiveWorkers(familyGroups, workers, workersSubdomain, logger, theme) {
844
- logLine(logger);
845
- logLine(logger, `${dim("configured worker families", theme)} ${whiteDim(String(familyGroups.length), theme)}`);
846
- logLine(logger);
847
- for (const [index, families] of familyGroups.entries()) {
848
- if (index > 0) {
849
- logLine(logger);
850
- }
851
- logLiveWorkerFamilyOverview(logger, families, workers, workersSubdomain, theme);
852
- }
853
- logLine(logger);
854
- logLine(logger, dim("Preview scopes are derived from live dedicated preview Worker names and each discovered config family.", theme));
855
- logLine(logger, dim("Run inside a configured package or pass `--config <path>` to narrow the summary or clean one family.", theme));
856
- logLine(logger);
857
- }
858
- function buildBindingAssociationColumns(theme) {
859
- return [
860
- {
861
- label: "Reference",
862
- width: 24,
863
- value: (row) => row.reference
864
- },
865
- {
866
- label: "Type",
867
- width: 24,
868
- value: (row) => row.type
869
- },
870
- {
871
- label: "Resource",
872
- width: 36,
873
- value: (row) => row.resource
874
- },
875
- {
876
- label: "Workers",
877
- width: 7,
878
- value: (row) => String(row.workerCount)
879
- },
880
- {
881
- label: "Notes",
882
- width: 28,
883
- value: (row) => row.notes.length > 0 ? row.notes.join(" · ") : dim("—", theme)
884
- },
885
- {
886
- label: "Connected workers",
887
- value: (row) => row.connectedWorkers.length > 0 ? row.connectedWorkers.join(", ") : dim("—", theme)
888
- }
889
- ];
890
- }
891
- function showBindingAssociations(logger, inspection, theme) {
892
- logLine(logger);
893
- logLine(logger, `${dim("worker family", theme)} ${green(inspection.workerName, theme)}`);
894
- logLine(logger, `${dim("resolved targets", theme)} ${whiteDim(String(inspection.targets), theme)}`);
895
- logLine(logger, `${dim("active deployments scanned", theme)} ${whiteDim(String(inspection.scannedWorkers.length), theme)}`);
896
- if (inspection.rows.length === 0) {
897
- logLine(logger);
898
- logLine(logger, dim("No binding or resource targets were resolved from the current config.", theme));
899
- logLine(logger);
900
- return;
901
- }
902
- logLine(logger);
903
- logSection(logger, "Bindings", inspection.rows, buildBindingAssociationColumns(theme), theme);
904
- if (inspection.warnings.length > 0) {
905
- logLine(logger);
906
- for (const warning of inspection.warnings) {
907
- logger.warn(warning);
908
- }
909
- }
910
- logLine(logger);
911
- }
912
-
913
- // src/cli/commands/previews-support/types.ts
914
- var PREVIEW_SUBCOMMANDS = ["list", "bindings", "cleanup"];
915
-
916
- // src/cli/commands/previews.ts
917
- var CLI_API_OPTIONS = {
918
- timeout: 1e4
919
- };
920
- function compareConfiguredWorkerFamilies(left, right) {
921
- if (left.role === "primary" && right.role !== "primary") {
922
- return -1;
923
- }
924
- if (left.role !== "primary" && right.role === "primary") {
925
- return 1;
926
- }
927
- return left.baseName.localeCompare(right.baseName);
928
- }
929
- function sortConfiguredWorkerFamilies(families) {
930
- return [...families].sort(compareConfiguredWorkerFamilies);
931
- }
932
- function resolvePrimaryWorkerFamilyName(families) {
933
- return families.find((family) => family.role === "primary")?.baseName ?? families[0]?.baseName;
934
- }
935
- function shouldReplaceConfiguredWorkerFamily(existing, candidate) {
936
- return !existing || candidate.role === "primary" && existing.role !== "primary";
937
- }
938
- function mergeConfiguredWorkerFamilies(existing, candidates) {
939
- const merged = new Map(existing.map((family) => [family.baseName, family]));
940
- for (const candidate of candidates) {
941
- if (shouldReplaceConfiguredWorkerFamily(merged.get(candidate.baseName), candidate)) {
942
- merged.set(candidate.baseName, candidate);
943
- }
944
- }
945
- return sortConfiguredWorkerFamilies(Array.from(merged.values()));
946
- }
947
- function comparePreviewConfiguredFamilyGroups(left, right) {
948
- const leftName = resolvePrimaryWorkerFamilyName(left.families) ?? left.configPath ?? "";
949
- const rightName = resolvePrimaryWorkerFamilyName(right.families) ?? right.configPath ?? "";
950
- return leftName.localeCompare(rightName);
951
- }
952
- function upsertPreviewConfiguredFamilyGroup(groups, candidate) {
953
- const primaryFamilyName = resolvePrimaryWorkerFamilyName(candidate.families);
954
- const groupKey = primaryFamilyName ?? candidate.configPath ?? `group-${groups.size}`;
955
- const existing = groups.get(groupKey);
956
- if (!existing) {
957
- groups.set(groupKey, {
958
- ...candidate,
959
- families: sortConfiguredWorkerFamilies(candidate.families)
960
- });
961
- return;
962
- }
963
- groups.set(groupKey, {
964
- accountId: existing.accountId ?? candidate.accountId,
965
- configPath: existing.configPath ?? candidate.configPath,
966
- families: mergeConfiguredWorkerFamilies(existing.families, candidate.families)
967
- });
968
- }
969
- async function discoverPreviewListConfigs(cwd, configFile, environment) {
970
- const groups = new Map;
971
- const accountIds = new Set;
972
- const loadAndCollect = async (candidateConfigFile) => {
973
- try {
974
- const config = await loadConfig({ cwd, configFile: candidateConfigFile });
975
- const families = collectConfiguredWorkerFamilies(config, environment);
976
- const accountId = config.accountId?.trim() || undefined;
977
- if (accountId) {
978
- accountIds.add(accountId);
979
- }
980
- upsertPreviewConfiguredFamilyGroup(groups, {
981
- accountId,
982
- configPath: candidateConfigFile,
983
- families
984
- });
985
- return true;
986
- } catch (error) {
987
- if (error instanceof ConfigNotFoundError) {
988
- return false;
989
- }
990
- throw error;
991
- }
992
- };
993
- if (configFile) {
994
- await loadAndCollect(configFile);
995
- } else {
996
- const directConfigPath = await resolveConfigPath(cwd);
997
- const loadedDirectly = directConfigPath ? await loadAndCollect() : false;
998
- if (!loadedDirectly) {
999
- const configPaths = await findConfigPathsUnderDirectory(cwd);
1000
- for (const configPath of configPaths) {
1001
- await loadAndCollect(configPath);
1002
- }
1003
- }
1004
- }
1005
- return {
1006
- accountIds: Array.from(accountIds).sort((left, right) => left.localeCompare(right)),
1007
- familyGroups: Array.from(groups.values()).sort(comparePreviewConfiguredFamilyGroups)
1008
- };
1009
- }
1010
- function isPreviewSubcommand(value) {
1011
- return PREVIEW_SUBCOMMANDS.includes(value);
1012
- }
1013
- function resolvePreviewScopeSelection(parsed, environment) {
1014
- const explicitScope = asOptionalString(parsed.options.scope) || asOptionalString(parsed.options.identifier);
1015
- if (explicitScope) {
1016
- return {
1017
- identifier: resolvePreviewIdentifier({ identifier: explicitScope }).identifier,
1018
- source: "scope-option"
1019
- };
1020
- }
1021
- const resolved = resolvePreviewIdentifier({
1022
- environment,
1023
- env: process.env
1024
- });
1025
- return {
1026
- identifier: resolved.identifier,
1027
- source: resolved.source
1028
- };
1029
- }
1030
- function formatPreviewScopeSource(source) {
1031
- switch (source) {
1032
- case "scope-option":
1033
- return "--scope";
1034
- case "identifier":
1035
- return "explicit identifier";
1036
- case "env-identifier":
1037
- return "DEVFLARE_PREVIEW_IDENTIFIER";
1038
- case "env-pr":
1039
- return "DEVFLARE_PREVIEW_PR";
1040
- case "env-branch":
1041
- return "DEVFLARE_PREVIEW_BRANCH";
1042
- case "environment":
1043
- return "default preview scope";
1044
- default:
1045
- return "no explicit preview scope";
1046
- }
1047
- }
1048
- function logResolvedPreviewScope(logger, selection, theme) {
1049
- if (!selection.identifier) {
1050
- return;
1051
- }
1052
- logLine(logger, `${dim("preview scope", theme)} ${green(selection.identifier, theme)} ${dim(`(${formatPreviewScopeSource(selection.source)})`, theme)}`);
1053
- logLine(logger);
1054
- }
1055
- async function loadLocalConfig(cwd, configFile, needsConfig) {
1056
- if (!needsConfig) {
1057
- return;
1058
- }
1059
- if (!configFile) {
1060
- const resolvedConfigPath = await resolveConfigPath(cwd);
1061
- if (!resolvedConfigPath) {
1062
- return;
1063
- }
1064
- try {
1065
- const config = await loadConfig({
1066
- cwd
1067
- });
1068
- return {
1069
- accountId: config.accountId,
1070
- name: config.name
1071
- };
1072
- } catch (error) {
1073
- if (error instanceof ConfigNotFoundError) {
1074
- return;
1075
- }
1076
- throw error;
1077
- }
1078
- }
1079
- try {
1080
- const config = await loadConfig({
1081
- cwd,
1082
- configFile
1083
- });
1084
- return {
1085
- accountId: config.accountId,
1086
- name: config.name
1087
- };
1088
- } catch (error) {
1089
- if (error instanceof ConfigNotFoundError) {
1090
- return;
1091
- }
1092
- throw error;
1093
- }
1094
- }
1095
- async function resolveAccountId(parsed, config) {
1096
- return resolveCloudflareAccountId({
1097
- explicitAccountId: asOptionalString(parsed.options.account),
1098
- configuredAccountId: config?.accountId,
1099
- apiOptions: CLI_API_OPTIONS
1100
- });
1101
- }
1102
- function resolveWorkerName(parsed, config) {
1103
- const selection = resolveNamedSelection({
1104
- explicitValue: asOptionalString(parsed.options.worker),
1105
- configuredValue: config?.name
1106
- });
1107
- return {
1108
- workerName: selection.value,
1109
- source: selection.source
1110
- };
1111
- }
1112
- async function resolveContext(parsed, options, subcommand) {
1113
- const cwd = options.cwd ?? process.cwd();
1114
- const configFile = asOptionalString(parsed.options.config);
1115
- const explicitAccountId = asOptionalString(parsed.options.account);
1116
- const environment = asOptionalString(parsed.options.env);
1117
- if (subcommand === "list") {
1118
- const listDiscovery = await discoverPreviewListConfigs(cwd, configFile, environment);
1119
- if (!explicitAccountId && listDiscovery.accountIds.length > 1) {
1120
- throw new Error("Multiple Cloudflare account ids were discovered across local Devflare configs. Pass --account to select one account explicitly for `devflare previews`.");
1121
- }
1122
- const accountId2 = await resolveCloudflareAccountId({
1123
- explicitAccountId,
1124
- configuredAccountId: listDiscovery.accountIds[0],
1125
- apiOptions: CLI_API_OPTIONS
1126
- });
1127
- if (!accountId2) {
1128
- throw new Error("No Cloudflare account could be resolved. Use --account or configure accountId in devflare.config.*.");
1129
- }
1130
- return {
1131
- accountId: accountId2,
1132
- workerName: undefined,
1133
- workerNameSource: "none",
1134
- config: undefined,
1135
- listDiscovery
1136
- };
1137
- }
1138
- const needsConfig = subcommand === "cleanup" || subcommand === "bindings" || !explicitAccountId;
1139
- const config = await loadLocalConfig(cwd, configFile, needsConfig);
1140
- if (needsConfig && !config) {
1141
- throw new Error("Preview commands now inspect and clean dedicated preview workers for the current package. Run inside a configured package or pass --config <path>.");
1142
- }
1143
- const accountId = await resolveAccountId(parsed, config);
1144
- const workerSelection = resolveWorkerName(parsed, config);
1145
- if (!accountId) {
1146
- throw new Error("No Cloudflare account could be resolved. Use --account or configure accountId in devflare.config.*.");
1147
- }
1148
- return {
1149
- accountId,
1150
- workerName: workerSelection.workerName,
1151
- workerNameSource: workerSelection.source,
1152
- config
1153
- };
1154
- }
1155
- async function runBindingsSubcommand(parsed, context, logger, options, environment, configFile, theme) {
1156
- const cwd = options.cwd ?? process.cwd();
1157
- const previewScope = resolvePreviewScopeSelection(parsed, environment);
1158
- logResolvedPreviewScope(logger, previewScope, theme);
1159
- const resolvedConfig = await loadResolvedConfig({
1160
- cwd,
1161
- configFile,
1162
- environment,
1163
- identifier: previewScope.identifier,
1164
- accountId: context.accountId
1165
- });
1166
- const deps = await getDependencies();
1167
- const inspection = await inspectBindingAssociations({
1168
- accountId: context.accountId,
1169
- config: resolvedConfig,
1170
- workerName: context.workerName ?? resolvedConfig.name,
1171
- cwd,
1172
- exec: deps.exec,
1173
- apiOptions: CLI_API_OPTIONS
1174
- });
1175
- showBindingAssociations(logger, inspection, theme);
1176
- return { exitCode: 0 };
1177
- }
1178
- async function runCleanupSubcommand(parsed, context, logger, options, environment, configFile, includeAll, theme) {
1179
- const cwd = options.cwd ?? process.cwd();
1180
- const resolvedEnvironment = environment ?? "preview";
1181
- const explicitScope = asOptionalString(parsed.options.scope) || asOptionalString(parsed.options.identifier);
1182
- if (includeAll && explicitScope) {
1183
- logger.error("Choose either --scope <name> or --all for preview cleanup, not both.");
1184
- return { exitCode: 1 };
1185
- }
1186
- const previewScope = resolvePreviewScopeSelection(parsed, resolvedEnvironment);
1187
- const config = await loadConfig({ cwd, configFile });
1188
- const configuredFamilies = collectConfiguredWorkerFamilies(config, resolvedEnvironment);
1189
- const liveWorkers = await account.workers(context.accountId, CLI_API_OPTIONS);
1190
- const workerCandidatesByScope = buildPreviewWorkerCandidatesByScope(configuredFamilies, liveWorkers);
1191
- const cleanupTargets = includeAll ? buildPreviewCleanupTargets(workerCandidatesByScope, resolvedEnvironment) : previewScope.identifier ? [
1192
- buildPreviewCleanupTarget(previewScope.identifier, workerCandidatesByScope, resolvedEnvironment)
1193
- ] : [];
1194
- const cleanupRuns = includeAll ? cleanupTargets.map((target) => ({
1195
- scope: target.scope,
1196
- target
1197
- })) : previewScope.identifier ? [
1198
- {
1199
- scope: previewScope.identifier,
1200
- target: cleanupTargets[0]
1201
- }
1202
- ] : [];
1203
- const applyCleanup = parsed.options.apply === true;
1204
- const executions = [];
1205
- if (includeAll) {
1206
- logResolvedPreviewScopes(logger, cleanupTargets, theme);
1207
- } else {
1208
- logResolvedPreviewScope(logger, previewScope, theme);
1209
- }
1210
- for (const cleanupRun of cleanupRuns) {
1211
- if (applyCleanup) {
1212
- const orderedWorkerNames = cleanupRun.target ? orderPreviewWorkerNamesForDeletion(cleanupRun.target.workerNames, cleanupRun.target.scope, configuredFamilies) : [];
1213
- for (const workerName of orderedWorkerNames) {
1214
- await account.deleteWorker(context.accountId, workerName, CLI_API_OPTIONS);
1215
- }
1216
- }
1217
- const result = await cleanupPreviewScopedResources(config, {
1218
- environment: resolvedEnvironment,
1219
- identifier: cleanupRun.scope,
1220
- accountId: context.accountId,
1221
- apply: applyCleanup
1222
- });
1223
- executions.push({
1224
- target: cleanupRun.target,
1225
- result
1226
- });
1227
- }
1228
- const totalWorkerCandidates = executions.reduce((sum, execution) => {
1229
- return sum + (execution.target?.workerNames.length ?? 0);
1230
- }, 0);
1231
- const totalKvCandidates = executions.reduce((sum, execution) => sum + execution.result.candidates.kv.length, 0);
1232
- const totalD1Candidates = executions.reduce((sum, execution) => sum + execution.result.candidates.d1.length, 0);
1233
- const totalR2Candidates = executions.reduce((sum, execution) => sum + execution.result.candidates.r2.length, 0);
1234
- const totalQueueCandidates = executions.reduce((sum, execution) => sum + execution.result.candidates.queues.length, 0);
1235
- const totalVectorizeCandidates = executions.reduce((sum, execution) => sum + execution.result.candidates.vectorize.length, 0);
1236
- const totalHyperdriveCandidates = executions.reduce((sum, execution) => sum + execution.result.candidates.hyperdrive.length, 0);
1237
- const totalResourceCandidates = executions.reduce((sum, execution) => {
1238
- return sum + getPreviewCleanupResourceCandidateCount(execution.result);
1239
- }, 0);
1240
- const totalCandidates = totalWorkerCandidates + totalResourceCandidates;
1241
- const scopeCountSuffix = cleanupRuns.length > 0 ? ` across ${cleanupRuns.length} preview scope${cleanupRuns.length === 1 ? "" : "s"}` : "";
1242
- logger.success(applyCleanup ? `Deleted ${totalCandidates} preview-only cleanup candidate${totalCandidates === 1 ? "" : "s"}${scopeCountSuffix}` : `Preview cleanup dry run complete with ${totalCandidates} candidate${totalCandidates === 1 ? "" : "s"}${scopeCountSuffix}`);
1243
- const resourceSummary = [
1244
- totalWorkerCandidates > 0 ? `Workers ${totalWorkerCandidates}` : null,
1245
- totalKvCandidates > 0 ? `KV ${totalKvCandidates}` : null,
1246
- totalD1Candidates > 0 ? `D1 ${totalD1Candidates}` : null,
1247
- totalR2Candidates > 0 ? `R2 ${totalR2Candidates}` : null,
1248
- totalQueueCandidates > 0 ? `Queues ${totalQueueCandidates}` : null,
1249
- totalVectorizeCandidates > 0 ? `Vectorize ${totalVectorizeCandidates}` : null,
1250
- totalHyperdriveCandidates > 0 ? `Hyperdrive ${totalHyperdriveCandidates}` : null
1251
- ].filter((segment) => segment !== null);
1252
- if (resourceSummary.length > 0) {
1253
- logger.info(`Candidates: ${resourceSummary.join(" · ")}`);
1254
- } else {
1255
- logger.info("Candidates: none");
1256
- showNoPreviewCleanupCandidatesHint(logger, previewScope, includeAll, theme);
1257
- }
1258
- if (includeAll || executions.some((execution) => Boolean(execution.target?.workerNames.length))) {
1259
- logPreviewCleanupScopeBreakdown(logger, executions, theme);
1260
- }
1261
- const warnings = Array.from(new Set(executions.flatMap((execution) => execution.result.warnings)));
1262
- for (const warning of warnings) {
1263
- logger.warn(warning);
1264
- }
1265
- return { exitCode: 0 };
1266
- }
1267
- async function runListSubcommand(context, logger, theme) {
1268
- const discoveredFamilyGroups = context.listDiscovery?.familyGroups ?? [];
1269
- if (discoveredFamilyGroups.length === 0) {
1270
- throw new Error("Preview listing needs a resolvable devflare config in the current package or workspace so Devflare can identify worker families.");
1271
- }
1272
- const matchingFamilyGroups = discoveredFamilyGroups.filter((group) => {
1273
- return !group.accountId || group.accountId === context.accountId;
1274
- });
1275
- if (matchingFamilyGroups.length === 0) {
1276
- throw new Error(`No configured preview worker families matched Cloudflare account ${context.accountId}. Pass --account or --config <path> to narrow the selection.`);
1277
- }
1278
- const liveWorkers = await account.workers(context.accountId, CLI_API_OPTIONS);
1279
- const workersSubdomain = await account.workersSubdomain(context.accountId, CLI_API_OPTIONS);
1280
- if (matchingFamilyGroups.length === 1) {
1281
- showWorkerFamilyOverviewFromLiveWorkers(matchingFamilyGroups[0].families, liveWorkers, workersSubdomain, logger, theme);
1282
- return { exitCode: 0 };
1283
- }
1284
- showWorkspaceWorkerFamilyOverviewFromLiveWorkers(matchingFamilyGroups.map((group) => group.families), liveWorkers, workersSubdomain, logger, theme);
1285
- return { exitCode: 0 };
1286
- }
1287
- function resolvePreviewSubcommand(rawSubcommand) {
1288
- if (!rawSubcommand) {
1289
- return;
1290
- }
1291
- if (isPreviewSubcommand(rawSubcommand)) {
1292
- return rawSubcommand;
1293
- }
1294
- return;
1295
- }
1296
- async function runPreviewsCommand(parsed, logger, options) {
1297
- const isAuth = await account.isAuthenticated();
1298
- if (!isAuth) {
1299
- logger.error("Not authenticated with Cloudflare");
1300
- logger.info("Run `devflare login` first.");
1301
- return { exitCode: 1 };
1302
- }
1303
- const rawSubcommand = parsed.args[0];
1304
- const subcommand = resolvePreviewSubcommand(rawSubcommand) ?? "list";
1305
- const includeAll = parsed.options.all === true;
1306
- const theme = {
1307
- useColor: shouldUseColor(parsed.options)
1308
- };
1309
- if (rawSubcommand && !resolvePreviewSubcommand(rawSubcommand)) {
1310
- logger.error(`Unknown previews subcommand: ${rawSubcommand}`);
1311
- logger.info(`Available previews subcommands: ${PREVIEW_SUBCOMMANDS.join(", ")}`);
1312
- return { exitCode: 1 };
1313
- }
1314
- try {
1315
- const context = await resolveContext(parsed, options, subcommand);
1316
- const environment = asOptionalString(parsed.options.env);
1317
- const configFile = asOptionalString(parsed.options.config);
1318
- switch (subcommand) {
1319
- case "bindings":
1320
- return runBindingsSubcommand(parsed, context, logger, options, environment, configFile, theme);
1321
- case "cleanup":
1322
- return runCleanupSubcommand(parsed, context, logger, options, environment, configFile, includeAll, theme);
1323
- default:
1324
- return runListSubcommand(context, logger, theme);
1325
- }
1326
- } catch (error) {
1327
- if (error instanceof Error) {
1328
- logger.error(error.message);
1329
- return { exitCode: 1 };
1330
- }
1331
- throw error;
1332
- }
1333
- }
1334
- export {
1335
- runPreviewsCommand
1336
- };