devflare 1.0.0-next.1 → 1.0.0-next.11

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 (123) hide show
  1. package/LLM.md +1424 -610
  2. package/R2.md +200 -0
  3. package/README.md +302 -505
  4. package/bin/devflare.js +8 -8
  5. package/dist/{account-rvrj687w.js → account-8psavtg6.js} +27 -4
  6. package/dist/bridge/miniflare.d.ts +6 -0
  7. package/dist/bridge/miniflare.d.ts.map +1 -1
  8. package/dist/bridge/proxy.d.ts +5 -6
  9. package/dist/bridge/proxy.d.ts.map +1 -1
  10. package/dist/bridge/server.d.ts.map +1 -1
  11. package/dist/browser.d.ts +50 -0
  12. package/dist/browser.d.ts.map +1 -0
  13. package/dist/{build-mnf6v8gd.js → build-ezksv2dd.js} +26 -7
  14. package/dist/bundler/do-bundler.d.ts +7 -0
  15. package/dist/bundler/do-bundler.d.ts.map +1 -1
  16. package/dist/cli/commands/account.d.ts.map +1 -1
  17. package/dist/cli/commands/build.d.ts.map +1 -1
  18. package/dist/cli/commands/deploy.d.ts.map +1 -1
  19. package/dist/cli/commands/dev.d.ts.map +1 -1
  20. package/dist/cli/commands/doctor.d.ts.map +1 -1
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/types.d.ts.map +1 -1
  23. package/dist/cli/config-path.d.ts +5 -0
  24. package/dist/cli/config-path.d.ts.map +1 -0
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/package-metadata.d.ts +16 -0
  27. package/dist/cli/package-metadata.d.ts.map +1 -0
  28. package/dist/config/compiler.d.ts +7 -0
  29. package/dist/config/compiler.d.ts.map +1 -1
  30. package/dist/config/index.d.ts +1 -1
  31. package/dist/config/index.d.ts.map +1 -1
  32. package/dist/config/schema.d.ts +2594 -1234
  33. package/dist/config/schema.d.ts.map +1 -1
  34. package/dist/{deploy-nhceck39.js → deploy-jdpy21t6.js} +33 -15
  35. package/dist/{dev-qnxet3j9.js → dev-9mq7zhww.js} +900 -234
  36. package/dist/dev-server/miniflare-log.d.ts +12 -0
  37. package/dist/dev-server/miniflare-log.d.ts.map +1 -0
  38. package/dist/dev-server/runtime-stdio.d.ts +8 -0
  39. package/dist/dev-server/runtime-stdio.d.ts.map +1 -0
  40. package/dist/dev-server/server.d.ts +2 -0
  41. package/dist/dev-server/server.d.ts.map +1 -1
  42. package/dist/dev-server/vite-utils.d.ts +37 -0
  43. package/dist/dev-server/vite-utils.d.ts.map +1 -0
  44. package/dist/{doctor-e8fy6fj5.js → doctor-z4ffybce.js} +73 -50
  45. package/dist/{durable-object-t4kbb0yt.js → durable-object-yt8v1dyn.js} +1 -1
  46. package/dist/index-1p814k7s.js +227 -0
  47. package/dist/{index-tk6ej9dj.js → index-2q3pmzrx.js} +12 -16
  48. package/dist/{index-67qcae0f.js → index-51s1hkw4.js} +16 -1
  49. package/dist/{index-ep3445yc.js → index-53xcakh8.js} +414 -171
  50. package/dist/{index-pf5s73n9.js → index-59df49vn.js} +11 -281
  51. package/dist/index-5yxg30va.js +304 -0
  52. package/dist/index-62b3gt2g.js +12 -0
  53. package/dist/index-6h8xbs75.js +44 -0
  54. package/dist/index-8gtqgb3q.js +529 -0
  55. package/dist/{index-gz1gndna.js → index-9wt9x09k.js} +42 -62
  56. package/dist/index-dr6sbp8d.js +39 -0
  57. package/dist/index-fef08w43.js +231 -0
  58. package/dist/index-k7r18na8.js +0 -0
  59. package/dist/{index-m2q41jwa.js → index-n932ytmq.js} +9 -1
  60. package/dist/{index-07q6yxyc.js → index-v8vvsn9x.js} +1 -0
  61. package/dist/index-vky23txa.js +70 -0
  62. package/dist/{index-z14anrqp.js → index-wfbfz02q.js} +14 -15
  63. package/dist/index-ws68xvq2.js +311 -0
  64. package/dist/{index-hcex3rgh.js → index-wyf3s77s.js} +85 -8
  65. package/dist/index-xqfbd9fx.js +195 -0
  66. package/dist/index-xxwbb2nt.js +322 -0
  67. package/dist/index-y1d8za14.js +196 -0
  68. package/dist/{init-f9mgmew3.js → init-na2atvz2.js} +42 -55
  69. package/dist/router/types.d.ts +24 -0
  70. package/dist/router/types.d.ts.map +1 -0
  71. package/dist/runtime/context.d.ts +249 -8
  72. package/dist/runtime/context.d.ts.map +1 -1
  73. package/dist/runtime/exports.d.ts +50 -55
  74. package/dist/runtime/exports.d.ts.map +1 -1
  75. package/dist/runtime/index.d.ts +8 -1
  76. package/dist/runtime/index.d.ts.map +1 -1
  77. package/dist/runtime/middleware.d.ts +77 -60
  78. package/dist/runtime/middleware.d.ts.map +1 -1
  79. package/dist/runtime/router.d.ts +7 -0
  80. package/dist/runtime/router.d.ts.map +1 -0
  81. package/dist/runtime/validation.d.ts +1 -1
  82. package/dist/runtime/validation.d.ts.map +1 -1
  83. package/dist/src/browser.js +150 -0
  84. package/dist/src/cli/index.js +10 -0
  85. package/dist/{cloudflare → src/cloudflare}/index.js +3 -3
  86. package/dist/{decorators → src/decorators}/index.js +2 -2
  87. package/dist/src/index.js +132 -0
  88. package/dist/src/runtime/index.js +111 -0
  89. package/dist/{sveltekit → src/sveltekit}/index.js +14 -6
  90. package/dist/{test → src/test}/index.js +22 -13
  91. package/dist/{vite → src/vite}/index.js +128 -59
  92. package/dist/sveltekit/platform.d.ts.map +1 -1
  93. package/dist/test/bridge-context.d.ts +5 -2
  94. package/dist/test/bridge-context.d.ts.map +1 -1
  95. package/dist/test/cf.d.ts +25 -11
  96. package/dist/test/cf.d.ts.map +1 -1
  97. package/dist/test/email.d.ts +16 -7
  98. package/dist/test/email.d.ts.map +1 -1
  99. package/dist/test/queue.d.ts.map +1 -1
  100. package/dist/test/resolve-service-bindings.d.ts.map +1 -1
  101. package/dist/test/scheduled.d.ts.map +1 -1
  102. package/dist/test/simple-context.d.ts +1 -1
  103. package/dist/test/simple-context.d.ts.map +1 -1
  104. package/dist/test/tail.d.ts +2 -1
  105. package/dist/test/tail.d.ts.map +1 -1
  106. package/dist/test/worker.d.ts +6 -0
  107. package/dist/test/worker.d.ts.map +1 -1
  108. package/dist/transform/durable-object.d.ts.map +1 -1
  109. package/dist/transform/worker-entrypoint.d.ts.map +1 -1
  110. package/dist/{types-5nyrz1sz.js → types-nq5acrwh.js} +30 -16
  111. package/dist/utils/entrypoint-discovery.d.ts +6 -3
  112. package/dist/utils/entrypoint-discovery.d.ts.map +1 -1
  113. package/dist/utils/send-email.d.ts +15 -0
  114. package/dist/utils/send-email.d.ts.map +1 -0
  115. package/dist/vite/plugin.d.ts.map +1 -1
  116. package/dist/worker-entry/composed-worker.d.ts +13 -0
  117. package/dist/worker-entry/composed-worker.d.ts.map +1 -0
  118. package/dist/worker-entry/routes.d.ts +22 -0
  119. package/dist/worker-entry/routes.d.ts.map +1 -0
  120. package/dist/{worker-entrypoint-m9th0rg0.js → worker-entrypoint-c259fmfs.js} +1 -1
  121. package/package.json +21 -19
  122. package/dist/index.js +0 -298
  123. package/dist/runtime/index.js +0 -111
@@ -0,0 +1,311 @@
1
+ import {
2
+ discoverRoutes
3
+ } from "./index-1p814k7s.js";
4
+ import {
5
+ __require
6
+ } from "./index-37x76zdn.js";
7
+
8
+ // src/worker-entry/composed-worker.ts
9
+ import { defu } from "defu";
10
+ import { dirname, relative, resolve } from "pathe";
11
+ var DEFAULT_FETCH_ENTRY_FILES = [
12
+ "src/fetch.ts",
13
+ "src/fetch.js",
14
+ "src/fetch.mts",
15
+ "src/fetch.mjs"
16
+ ];
17
+ var DEFAULT_QUEUE_ENTRY_FILES = [
18
+ "src/queue.ts",
19
+ "src/queue.js",
20
+ "src/queue.mts",
21
+ "src/queue.mjs"
22
+ ];
23
+ var DEFAULT_SCHEDULED_ENTRY_FILES = [
24
+ "src/scheduled.ts",
25
+ "src/scheduled.js",
26
+ "src/scheduled.mts",
27
+ "src/scheduled.mjs"
28
+ ];
29
+ var DEFAULT_EMAIL_ENTRY_FILES = [
30
+ "src/email.ts",
31
+ "src/email.js",
32
+ "src/email.mts",
33
+ "src/email.mjs"
34
+ ];
35
+ function resolveConfigForEnvironment(config, environment) {
36
+ if (environment && config.env?.[environment]) {
37
+ return defu(config.env[environment], config);
38
+ }
39
+ return config;
40
+ }
41
+ async function resolveWorkerHandlerPath(cwd, configuredPath, defaultEntries) {
42
+ if (configuredPath === false) {
43
+ return null;
44
+ }
45
+ const fs = await import("node:fs/promises");
46
+ const candidates = new Set;
47
+ if (typeof configuredPath === "string" && configuredPath) {
48
+ candidates.add(configuredPath);
49
+ }
50
+ for (const defaultEntry of defaultEntries) {
51
+ candidates.add(defaultEntry);
52
+ }
53
+ for (const candidate of candidates) {
54
+ const absolutePath = resolve(cwd, candidate);
55
+ try {
56
+ await fs.access(absolutePath);
57
+ return absolutePath;
58
+ } catch {
59
+ continue;
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ async function resolveWorkerSurfacePaths(cwd, config) {
65
+ return {
66
+ fetch: await resolveWorkerHandlerPath(cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES),
67
+ queue: await resolveWorkerHandlerPath(cwd, config.files?.queue, DEFAULT_QUEUE_ENTRY_FILES),
68
+ scheduled: await resolveWorkerHandlerPath(cwd, config.files?.scheduled, DEFAULT_SCHEDULED_ENTRY_FILES),
69
+ email: await resolveWorkerHandlerPath(cwd, config.files?.email, DEFAULT_EMAIL_ENTRY_FILES)
70
+ };
71
+ }
72
+ function toImportSpecifier(fromFilePath, toFilePath) {
73
+ const specifier = relative(dirname(fromFilePath), toFilePath).replace(/\\/g, "/");
74
+ return specifier.startsWith(".") ? specifier : `./${specifier}`;
75
+ }
76
+ function createGeneratedRouteModuleImports(entryPath, routeDiscovery) {
77
+ if (!routeDiscovery) {
78
+ return [];
79
+ }
80
+ return routeDiscovery.routes.map((route, index) => ({
81
+ identifier: `__devflareRouteModule${index}`,
82
+ importPath: toImportSpecifier(entryPath, route.absolutePath),
83
+ filePath: route.filePath,
84
+ routePath: route.routePath,
85
+ segmentsJson: JSON.stringify(route.segments)
86
+ }));
87
+ }
88
+ function needsComposedWorkerEntrypoint(surfacePaths, routeDiscovery) {
89
+ return Boolean(surfacePaths.fetch || surfacePaths.queue || surfacePaths.scheduled || surfacePaths.email || routeDiscovery?.routes.length);
90
+ }
91
+ function getComposedWorkerEntrypointSource(surfaceImportPaths, configuredLocalSendEmailBindings = {}, routeImports = [], options = {}) {
92
+ const importLines = [`import { createEmailEvent, createFetchEvent, createQueueEvent, createRouteResolve, createScheduledEvent, invokeFetchModule, matchFetchRoute, runWithEventContext, setLocalSendEmailBindings } from 'devflare/runtime'`];
93
+ const moduleFallbackLines = [];
94
+ const localSendEmailBindings = JSON.stringify(configuredLocalSendEmailBindings);
95
+ const routeManifestEntries = routeImports.map(({ identifier, filePath, routePath, segmentsJson }) => {
96
+ return ` { filePath: ${JSON.stringify(filePath)}, routePath: ${JSON.stringify(routePath)}, segments: ${segmentsJson}, module: ${identifier} }`;
97
+ });
98
+ const registerSurfaceModule = (identifier, importPath) => {
99
+ if (importPath) {
100
+ importLines.push(`import * as ${identifier} from '${importPath}'`);
101
+ return;
102
+ }
103
+ moduleFallbackLines.push(`const ${identifier} = {}`);
104
+ };
105
+ registerSurfaceModule("__devflareFetchModule", surfaceImportPaths.fetch);
106
+ registerSurfaceModule("__devflareQueueModule", surfaceImportPaths.queue);
107
+ registerSurfaceModule("__devflareScheduledModule", surfaceImportPaths.scheduled);
108
+ registerSurfaceModule("__devflareEmailModule", surfaceImportPaths.email);
109
+ for (const routeImport of routeImports) {
110
+ importLines.push(`import * as ${routeImport.identifier} from '${routeImport.importPath}'`);
111
+ }
112
+ const includeDevInternalEmail = options.devInternalEmail === true;
113
+ const devInternalEmailHelpers = includeDevInternalEmail ? `
114
+ function __devflareCreateEmailHeaders(rawBody) {
115
+ const headers = new Headers()
116
+ const lines = rawBody.split(/\\r?\\n/)
117
+
118
+ for (const line of lines) {
119
+ if (line.trim() === '') {
120
+ break
121
+ }
122
+
123
+ const colonIndex = line.indexOf(':')
124
+ if (colonIndex <= 0) {
125
+ continue
126
+ }
127
+
128
+ headers.append(line.slice(0, colonIndex).trim(), line.slice(colonIndex + 1).trim())
129
+ }
130
+
131
+ return headers
132
+ }
133
+
134
+ function __devflareCreateEmailRawStream(rawBody) {
135
+ return new ReadableStream({
136
+ start(controller) {
137
+ controller.enqueue(new TextEncoder().encode(rawBody))
138
+ controller.close()
139
+ }
140
+ })
141
+ }
142
+
143
+ async function __devflareHandleInternalEmail(request, env, ctx) {
144
+ if (!__devflareEmailHandler) {
145
+ return new Response('Email handler not configured', { status: 501 })
146
+ }
147
+
148
+ const from = request.headers.get('x-devflare-email-from') || 'unknown@example.com'
149
+ const to = request.headers.get('x-devflare-email-to') || 'worker@example.com'
150
+ const rawBody = await request.text()
151
+ const emailMessage = {
152
+ from,
153
+ to,
154
+ headers: __devflareCreateEmailHeaders(rawBody),
155
+ raw: __devflareCreateEmailRawStream(rawBody),
156
+ rawSize: rawBody.length,
157
+ setReject(reason) {
158
+ console.warn('[Devflare email rejected]', reason)
159
+ },
160
+ async forward(rcptTo) {
161
+ console.log('[Devflare email forwarded]', rcptTo)
162
+ return Promise.resolve()
163
+ },
164
+ async reply(message) {
165
+ console.log('[Devflare email reply sent]', message?.from)
166
+ return Promise.resolve()
167
+ }
168
+ }
169
+
170
+ const __devflareEvent = createEmailEvent(emailMessage, env, ctx)
171
+
172
+ await runWithEventContext(
173
+ __devflareEvent,
174
+ () => __devflareEmailHandler(__devflareEvent, env, ctx)
175
+ )
176
+
177
+ return new Response(JSON.stringify({ ok: true, from, to }), {
178
+ headers: { 'Content-Type': 'application/json' }
179
+ })
180
+ }
181
+ ` : "";
182
+ return `
183
+ ${importLines.join(`
184
+ `)}
185
+ ${moduleFallbackLines.join(`
186
+ `)}
187
+
188
+ setLocalSendEmailBindings(${localSendEmailBindings})
189
+
190
+ const __devflareHasFetchModule = ${surfaceImportPaths.fetch ? "true" : "false"}
191
+ const __devflareRoutes = [
192
+ ${routeManifestEntries.join(`,
193
+ `)}
194
+ ]
195
+ const __devflareHasRoutes = __devflareRoutes.length > 0
196
+
197
+ const __devflareResolveHandler = (module, namedExport) => {
198
+ const defaultExport = module.default
199
+
200
+ if (typeof defaultExport === 'function') {
201
+ return defaultExport
202
+ }
203
+
204
+ if (defaultExport && typeof defaultExport[namedExport] === 'function') {
205
+ return defaultExport[namedExport].bind(defaultExport)
206
+ }
207
+
208
+ if (typeof module[namedExport] === 'function') {
209
+ return module[namedExport]
210
+ }
211
+
212
+ return null
213
+ }
214
+
215
+ const __devflareQueueHandler = __devflareResolveHandler(__devflareQueueModule, 'queue')
216
+ const __devflareScheduledHandler = __devflareResolveHandler(__devflareScheduledModule, 'scheduled')
217
+ const __devflareEmailHandler = __devflareResolveHandler(__devflareEmailModule, 'email')
218
+ ${devInternalEmailHelpers}
219
+
220
+ export default {
221
+ ...(${surfaceImportPaths.fetch || routeImports.length > 0 || includeDevInternalEmail ? "true" : "false"}
222
+ ? {
223
+ async fetch(request, env, ctx) {
224
+ ${includeDevInternalEmail ? `const url = new URL(request.url)
225
+
226
+ if (
227
+ request.headers.get('x-devflare-event') === 'email'
228
+ && url.pathname === '/_devflare/internal/email'
229
+ ) {
230
+ return __devflareHandleInternalEmail(request, env, ctx)
231
+ }
232
+
233
+ ` : ""}const __devflareInitialRouteMatch = __devflareHasRoutes ? matchFetchRoute(__devflareRoutes, request) : null
234
+ const __devflareEvent = createFetchEvent(request, env, ctx, {
235
+ params: __devflareInitialRouteMatch?.params ?? {}
236
+ })
237
+ return runWithEventContext(
238
+ __devflareEvent,
239
+ () => invokeFetchModule(
240
+ __devflareFetchModule,
241
+ __devflareEvent,
242
+ __devflareHasRoutes
243
+ ? createRouteResolve(__devflareRoutes, __devflareEvent)
244
+ : undefined
245
+ )
246
+ )
247
+ }
248
+ }
249
+ : {}),
250
+ ...(__devflareQueueHandler
251
+ ? {
252
+ async queue(batch, env, ctx) {
253
+ const __devflareEvent = createQueueEvent(batch, env, ctx)
254
+ return runWithEventContext(
255
+ __devflareEvent,
256
+ () => __devflareQueueHandler(__devflareEvent, env, ctx)
257
+ )
258
+ }
259
+ }
260
+ : {}),
261
+ ...(__devflareScheduledHandler
262
+ ? {
263
+ async scheduled(controller, env, ctx) {
264
+ const __devflareEvent = createScheduledEvent(controller, env, ctx)
265
+ return runWithEventContext(
266
+ __devflareEvent,
267
+ () => __devflareScheduledHandler(__devflareEvent, env, ctx)
268
+ )
269
+ }
270
+ }
271
+ : {}),
272
+ ...(__devflareEmailHandler
273
+ ? {
274
+ async email(message, env, ctx) {
275
+ const __devflareEvent = createEmailEvent(message, env, ctx)
276
+ return runWithEventContext(
277
+ __devflareEvent,
278
+ () => __devflareEmailHandler(__devflareEvent, env, ctx)
279
+ )
280
+ }
281
+ }
282
+ : {})
283
+ }
284
+ `.trimStart();
285
+ }
286
+ async function prepareComposedWorkerEntrypoint(cwd, config, environment, options = {}) {
287
+ const resolvedConfig = resolveConfigForEnvironment(config, environment);
288
+ if (resolvedConfig.wrangler?.passthrough && Object.prototype.hasOwnProperty.call(resolvedConfig.wrangler.passthrough, "main")) {
289
+ return null;
290
+ }
291
+ const surfacePaths = await resolveWorkerSurfacePaths(cwd, resolvedConfig);
292
+ const routeDiscovery = await discoverRoutes(cwd, resolvedConfig);
293
+ if (!needsComposedWorkerEntrypoint(surfacePaths, routeDiscovery)) {
294
+ return null;
295
+ }
296
+ const fs = await import("node:fs/promises");
297
+ const entryDir = resolve(cwd, ".devflare", "worker-entrypoints");
298
+ const entryPath = resolve(entryDir, "main.ts");
299
+ await fs.mkdir(entryDir, { recursive: true });
300
+ const surfaceImportPaths = {
301
+ fetch: surfacePaths.fetch ? toImportSpecifier(entryPath, surfacePaths.fetch) : null,
302
+ queue: surfacePaths.queue ? toImportSpecifier(entryPath, surfacePaths.queue) : null,
303
+ scheduled: surfacePaths.scheduled ? toImportSpecifier(entryPath, surfacePaths.scheduled) : null,
304
+ email: surfacePaths.email ? toImportSpecifier(entryPath, surfacePaths.email) : null
305
+ };
306
+ const routeImports = createGeneratedRouteModuleImports(entryPath, routeDiscovery);
307
+ await fs.writeFile(entryPath, getComposedWorkerEntrypointSource(surfaceImportPaths, resolvedConfig.bindings?.sendEmail ?? {}, routeImports, options));
308
+ return ".devflare/worker-entrypoints/main.ts";
309
+ }
310
+
311
+ export { prepareComposedWorkerEntrypoint };
@@ -17,7 +17,7 @@ var filesSchema = z.object({
17
17
  entrypoints: z.union([z.string(), z.literal(false)]).optional(),
18
18
  workflows: z.union([z.string(), z.literal(false)]).optional(),
19
19
  routes: z.union([routesConfigSchema, z.literal(false)]).optional(),
20
- transport: z.string().optional()
20
+ transport: z.union([z.string(), z.null()]).optional()
21
21
  }).optional();
22
22
  var durableObjectBindingSchema = z.custom((val) => {
23
23
  if (typeof val === "string")
@@ -70,7 +70,14 @@ var analyticsBindingSchema = z.object({
70
70
  dataset: z.string()
71
71
  });
72
72
  var sendEmailBindingSchema = z.object({
73
- destinationAddress: z.string().optional()
73
+ destinationAddress: z.string().optional(),
74
+ allowedDestinationAddresses: z.array(z.string()).optional(),
75
+ allowedSenderAddresses: z.array(z.string()).optional()
76
+ }).refine((binding) => {
77
+ return !(binding.destinationAddress && binding.allowedDestinationAddresses);
78
+ }, {
79
+ message: "sendEmail bindings must use either destinationAddress or allowedDestinationAddresses, not both",
80
+ path: ["allowedDestinationAddresses"]
74
81
  });
75
82
  var bindingsSchema = z.object({
76
83
  kv: z.record(z.string(), z.string()).optional(),
@@ -115,12 +122,43 @@ var observabilitySchema = z.object({
115
122
  var limitsSchema = z.object({
116
123
  cpu_ms: z.number().optional()
117
124
  }).optional();
125
+ var rolldownOptionsSchema = z.custom((value) => {
126
+ return typeof value === "object" && value !== null && !Array.isArray(value);
127
+ }, {
128
+ message: "Expected Rolldown options object"
129
+ });
130
+ var rolldownConfigSchema = z.object({
131
+ target: z.string().optional(),
132
+ minify: z.boolean().optional(),
133
+ sourcemap: z.boolean().optional(),
134
+ options: rolldownOptionsSchema.optional()
135
+ }).optional();
136
+ var viteConfigSchema = z.object({
137
+ plugins: z.array(z.unknown()).optional()
138
+ }).catchall(z.unknown()).optional();
118
139
  var buildConfigSchema = z.object({
119
140
  target: z.string().optional(),
120
141
  minify: z.boolean().optional(),
121
142
  sourcemap: z.boolean().optional(),
122
- rolldownOptions: z.record(z.string(), z.unknown()).optional()
143
+ rolldownOptions: rolldownOptionsSchema.optional()
123
144
  }).optional();
145
+ function normalizeViteConfig(vite, plugins) {
146
+ const normalizedVite = {
147
+ ...plugins !== undefined ? { plugins } : {},
148
+ ...vite ?? {}
149
+ };
150
+ return Object.keys(normalizedVite).length > 0 ? normalizedVite : undefined;
151
+ }
152
+ function normalizeRolldownConfig(rolldown, build) {
153
+ const normalizedRolldown = {
154
+ ...build?.target !== undefined ? { target: build.target } : {},
155
+ ...build?.minify !== undefined ? { minify: build.minify } : {},
156
+ ...build?.sourcemap !== undefined ? { sourcemap: build.sourcemap } : {},
157
+ ...build?.rolldownOptions !== undefined ? { options: build.rolldownOptions } : {},
158
+ ...rolldown ?? {}
159
+ };
160
+ return Object.keys(normalizedRolldown).length > 0 ? normalizedRolldown : undefined;
161
+ }
124
162
  var migrationSchema = z.object({
125
163
  tag: z.string(),
126
164
  new_classes: z.array(z.string()).optional(),
@@ -134,7 +172,7 @@ var migrationSchema = z.object({
134
172
  var wranglerConfigSchema = z.object({
135
173
  passthrough: z.record(z.string(), z.unknown()).optional()
136
174
  }).optional();
137
- var envConfigSchemaInner = z.object({
175
+ var envConfigSchema = z.object({
138
176
  name: z.string().optional(),
139
177
  compatibilityDate: compatibilityDateSchema.optional(),
140
178
  compatibilityFlags: z.array(z.string()).optional(),
@@ -148,15 +186,35 @@ var envConfigSchemaInner = z.object({
148
186
  limits: limitsSchema,
149
187
  observability: observabilitySchema,
150
188
  migrations: z.array(migrationSchema).optional(),
151
- build: buildConfigSchema,
189
+ rolldown: rolldownConfigSchema,
190
+ vite: viteConfigSchema,
152
191
  wrangler: wranglerConfigSchema
153
192
  }).partial();
193
+ var envConfigSchemaInner = envConfigSchema.extend({
194
+ build: buildConfigSchema,
195
+ plugins: z.array(z.unknown()).optional()
196
+ }).transform((config) => {
197
+ const normalizedVite = normalizeViteConfig(config.vite, config.plugins);
198
+ const normalizedRolldown = normalizeRolldownConfig(config.rolldown, config.build);
199
+ const {
200
+ build: _legacyBuild,
201
+ plugins: _legacyPlugins,
202
+ vite: _vite,
203
+ rolldown: _rolldown,
204
+ ...rest
205
+ } = config;
206
+ return {
207
+ ...rest,
208
+ ...normalizedVite ? { vite: normalizedVite } : {},
209
+ ...normalizedRolldown ? { rolldown: normalizedRolldown } : {}
210
+ };
211
+ });
154
212
  function getCurrentDate() {
155
213
  const now = new Date;
156
214
  return now.toISOString().split("T")[0];
157
215
  }
158
216
  var FORCED_COMPATIBILITY_FLAGS = ["nodejs_compat", "nodejs_als"];
159
- var configSchema = z.object({
217
+ var canonicalConfigSchema = z.object({
160
218
  name: z.string({
161
219
  required_error: "Worker name is required"
162
220
  }),
@@ -177,11 +235,30 @@ var configSchema = z.object({
177
235
  limits: limitsSchema,
178
236
  observability: observabilitySchema,
179
237
  migrations: z.array(migrationSchema).optional(),
180
- build: buildConfigSchema,
181
- plugins: z.array(z.unknown()).optional(),
238
+ rolldown: rolldownConfigSchema,
239
+ vite: viteConfigSchema,
182
240
  env: z.record(z.string(), envConfigSchemaInner).optional(),
183
241
  wrangler: wranglerConfigSchema
184
242
  });
243
+ var configSchema = canonicalConfigSchema.extend({
244
+ build: buildConfigSchema,
245
+ plugins: z.array(z.unknown()).optional()
246
+ }).transform((config) => {
247
+ const normalizedVite = normalizeViteConfig(config.vite, config.plugins);
248
+ const normalizedRolldown = normalizeRolldownConfig(config.rolldown, config.build);
249
+ const {
250
+ build: _legacyBuild,
251
+ plugins: _legacyPlugins,
252
+ vite: _vite,
253
+ rolldown: _rolldown,
254
+ ...rest
255
+ } = config;
256
+ return {
257
+ ...rest,
258
+ ...normalizedVite ? { vite: normalizedVite } : {},
259
+ ...normalizedRolldown ? { rolldown: normalizedRolldown } : {}
260
+ };
261
+ });
185
262
  function normalizeDOBinding(config) {
186
263
  if (typeof config === "string") {
187
264
  return { className: config };
@@ -0,0 +1,195 @@
1
+ import {
2
+ getPackageVersion
3
+ } from "./index-6h8xbs75.js";
4
+ import {
5
+ __require
6
+ } from "./index-37x76zdn.js";
7
+
8
+ // src/cli/index.ts
9
+ import { createConsola } from "consola";
10
+ var COMMANDS = ["init", "dev", "build", "deploy", "types", "doctor", "account", "ai", "remote", "help", "version"];
11
+ function parseArgs(argv) {
12
+ const args = [];
13
+ const options = {};
14
+ let command = "help";
15
+ let unknownCommand;
16
+ let i = 0;
17
+ while (i < argv.length) {
18
+ const arg = argv[i];
19
+ if (arg === "--help" || arg === "-h") {
20
+ return { command: "help", args: [], options: {} };
21
+ }
22
+ if (arg === "--version" || arg === "-v") {
23
+ return { command: "version", args: [], options: {} };
24
+ }
25
+ if (arg.startsWith("-") && !/^-\d/.test(arg)) {
26
+ const isLongFlag = arg.startsWith("--");
27
+ const key = isLongFlag ? arg.slice(2) : arg.slice(1);
28
+ const nextArg = argv[i + 1];
29
+ if (nextArg && !nextArg.startsWith("-")) {
30
+ options[key] = nextArg;
31
+ i += 2;
32
+ } else {
33
+ options[key] = true;
34
+ i++;
35
+ }
36
+ } else if (!command || command === "help") {
37
+ if (COMMANDS.includes(arg)) {
38
+ command = arg;
39
+ } else {
40
+ command = "help";
41
+ unknownCommand = arg;
42
+ }
43
+ i++;
44
+ } else {
45
+ args.push(arg);
46
+ i++;
47
+ }
48
+ }
49
+ return { command, args, options, unknownCommand };
50
+ }
51
+ function getHelpText() {
52
+ return `
53
+ devflare - Config compiler + CLI orchestrator for Cloudflare Workers
54
+
55
+ Usage:
56
+ devflare <command> [options]
57
+
58
+ Commands:
59
+ init [name] Create a new devflare project
60
+ dev Start the development server
61
+ build Build for production
62
+ deploy Deploy to Cloudflare
63
+ types Generate TypeScript types
64
+ doctor Check project configuration
65
+ account View Cloudflare account info
66
+ ai View AI models and pricing
67
+ remote Manage remote test mode (AI, Vectorize)
68
+ help Show command overview
69
+ version Show the installed devflare version
70
+
71
+ Common Options:
72
+ --config <path> Used by dev, build, deploy, types, and doctor
73
+ --debug Enable debug output for supported commands
74
+ -h, --help Show help
75
+ -v, --version Show version
76
+
77
+ Dev Options:
78
+ --port <port> Preferred Vite dev server port (default: 5173)
79
+ --persist Persist Miniflare storage data
80
+ --verbose Enable verbose logging
81
+ --log Log all output to a timestamped .log-* file and the terminal
82
+ --log-temp Log all output to .log (overwritten) and the terminal
83
+
84
+ Build / Deploy:
85
+ build --env <name> Use config.env[name]
86
+ deploy --env <name> Use config.env[name]
87
+ deploy --dry-run Print the generated Wrangler config without deploying
88
+
89
+ Types / Doctor:
90
+ types --output <path> Write generated types to a custom path
91
+ doctor --config <path> Check a specific devflare config file
92
+
93
+ Account / Remote:
94
+ account --account <id> Use a specific Cloudflare account
95
+ remote status Show current remote-mode status
96
+ remote enable [minutes] Enable remote mode (default: 30 minutes)
97
+ remote disable Disable remote mode
98
+
99
+ Notes:
100
+ • Worker-only mode is the default when the current package has no local vite.config.*
101
+ • Vite is started only when the current package provides a local vite.config.*
102
+ • Higher-level build flows currently synthesize a composed worker entry when worker surfaces are discovered
103
+
104
+ Examples:
105
+ devflare init my-app
106
+ devflare dev # Start worker-only or unified dev server
107
+ devflare dev --port 3000 # Custom Vite port when Vite is enabled
108
+ devflare dev --persist # Persist storage between restarts
109
+ devflare dev --log-temp # Log output to .log file
110
+ devflare build
111
+ devflare deploy --env production
112
+ `.trim();
113
+ }
114
+ async function runCli(argv, options = {}) {
115
+ const logger = createConsola({
116
+ level: options.silent ? -999 : 3,
117
+ formatOptions: {
118
+ date: false
119
+ }
120
+ });
121
+ const parsed = parseArgs(argv);
122
+ if (parsed.unknownCommand) {
123
+ logger.error(`Unknown command: ${parsed.unknownCommand}`);
124
+ logger.info("Run `devflare --help` for available commands");
125
+ return { exitCode: 1 };
126
+ }
127
+ switch (parsed.command) {
128
+ case "help":
129
+ logger.info(getHelpText());
130
+ return { exitCode: 0, output: getHelpText() };
131
+ case "version":
132
+ const version = await getPackageVersion();
133
+ logger.info(`devflare v${version}`);
134
+ return { exitCode: 0, output: version };
135
+ case "init":
136
+ return runInit(parsed, logger, options);
137
+ case "dev":
138
+ return runDev(parsed, logger, options);
139
+ case "build":
140
+ return runBuild(parsed, logger, options);
141
+ case "deploy":
142
+ return runDeploy(parsed, logger, options);
143
+ case "types":
144
+ return runTypes(parsed, logger, options);
145
+ case "doctor":
146
+ return runDoctor(parsed, logger, options);
147
+ case "account":
148
+ return runAccount(parsed, logger, options);
149
+ case "ai":
150
+ return runAI();
151
+ case "remote":
152
+ return runRemote(parsed, logger, options);
153
+ default:
154
+ logger.error(`Unknown command: ${parsed.command}`);
155
+ return { exitCode: 1 };
156
+ }
157
+ }
158
+ async function runInit(parsed, logger, options) {
159
+ const { runInitCommand } = await import("./init-na2atvz2.js");
160
+ return runInitCommand(parsed, logger, options);
161
+ }
162
+ async function runDev(parsed, logger, options) {
163
+ const { runDevCommand } = await import("./dev-9mq7zhww.js");
164
+ return runDevCommand(parsed, logger, options);
165
+ }
166
+ async function runBuild(parsed, logger, options) {
167
+ const { runBuildCommand } = await import("./build-ezksv2dd.js");
168
+ return runBuildCommand(parsed, logger, options);
169
+ }
170
+ async function runDeploy(parsed, logger, options) {
171
+ const { runDeployCommand } = await import("./deploy-jdpy21t6.js");
172
+ return runDeployCommand(parsed, logger, options);
173
+ }
174
+ async function runTypes(parsed, logger, options) {
175
+ const { runTypesCommand } = await import("./types-nq5acrwh.js");
176
+ return runTypesCommand(parsed, logger, options);
177
+ }
178
+ async function runDoctor(parsed, logger, options) {
179
+ const { runDoctorCommand } = await import("./doctor-z4ffybce.js");
180
+ return runDoctorCommand(parsed, logger, options);
181
+ }
182
+ async function runAccount(parsed, logger, options) {
183
+ const { runAccountCommand } = await import("./account-8psavtg6.js");
184
+ return runAccountCommand(parsed, logger, options);
185
+ }
186
+ async function runAI() {
187
+ const { runAICommand } = await import("./ai-dx4fr9jh.js");
188
+ return runAICommand();
189
+ }
190
+ async function runRemote(parsed, logger, options) {
191
+ const { runRemoteCommand } = await import("./remote-q59qk463.js");
192
+ return runRemoteCommand(parsed, logger, options);
193
+ }
194
+
195
+ export { parseArgs, runCli };