devflare 1.0.0-next.59 → 1.0.0-next.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{build-IR-IaQN1.js → build-Dp8k2SWa.js} +1 -1
- package/dist/_chunks/{build-artifacts-C7JfIRnw.js → build-artifacts-DLEYfdVL.js} +2 -2
- package/dist/_chunks/{cli-yOO5yCaf.js → cli-BlVetiEh.js} +5 -5
- package/dist/_chunks/{compiler-okj8qvCh.js → compiler-CgIFPfRA.js} +23 -1
- package/dist/_chunks/{config-C8Qux0NR.js → config-BwRb2_vD.js} +1 -1
- package/dist/_chunks/{deploy-BG2PHaWu.js → deploy-Blrdr3Gv.js} +2 -2
- package/dist/_chunks/{dev-BgQl56Bd.js → dev-DRP6LR2H.js} +42 -7
- package/dist/_chunks/{previews-fTFp1WkQ.js → previews-D-GPVCeq.js} +1 -1
- package/dist/_chunks/r2-presign-runtime-zTOLS0Ea.js +291 -0
- package/dist/_chunks/{runtime-DL-Nz3k8.js → runtime-RekfD_2X.js} +325 -1
- package/dist/_chunks/{vite-De7bGxC6.js → vite-CtvgOi1c.js} +2 -2
- package/dist/bridge/miniflare-gateway.d.ts +45 -0
- package/dist/bridge/miniflare-gateway.d.ts.map +1 -0
- package/dist/bridge/miniflare.d.ts +8 -1
- package/dist/bridge/miniflare.d.ts.map +1 -1
- package/dist/bridge/r2-presign-runtime.d.ts +9 -0
- package/dist/bridge/r2-presign-runtime.d.ts.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/config/compiler.d.ts.map +1 -1
- package/dist/dev-server/gateway-script.d.ts +2 -1
- package/dist/dev-server/gateway-script.d.ts.map +1 -1
- package/dist/dev-server/miniflare-dev-config.d.ts +13 -0
- package/dist/dev-server/miniflare-dev-config.d.ts.map +1 -1
- package/dist/dev-server/miniflare-worker-config.d.ts +7 -0
- package/dist/dev-server/miniflare-worker-config.d.ts.map +1 -1
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-process.d.ts +9 -0
- package/dist/dev-server/vite-process.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +2 -2
- package/dist/runtime/r2-presign.d.ts +164 -0
- package/dist/runtime/r2-presign.d.ts.map +1 -0
- package/dist/test/index.js +41 -4
- package/dist/test/simple-context-gateway-script.d.ts.map +1 -1
- package/dist/test/simple-context-mfconfig.d.ts +8 -0
- package/dist/test/simple-context-mfconfig.d.ts.map +1 -1
- package/dist/test/simple-context-multi-worker.d.ts.map +1 -1
- package/dist/test/simple-context-runtime.d.ts.map +1 -1
- package/dist/test/simple-context-startup.d.ts.map +1 -1
- package/dist/test/simple-context.d.ts.map +1 -1
- package/dist/vite/index.js +1 -1
- package/package.json +3 -2
- package/dist/_chunks/local-workflow-entrypoints-ZIL7apIa.js +0 -90
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as cyanBold, f as logLine, o as dim, r as createCliTheme } from "./ui-BUoZApvE.js";
|
|
2
|
-
import { t as prepareBuildArtifacts } from "./build-artifacts-
|
|
2
|
+
import { t as prepareBuildArtifacts } from "./build-artifacts-DLEYfdVL.js";
|
|
3
3
|
//#region src/cli/commands/build.ts
|
|
4
4
|
async function runBuildCommand(parsed, logger, options) {
|
|
5
5
|
const theme = createCliTheme(parsed.options);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { d as resolveConfigEnvVars } from "./preview-C3Cdr8an.js";
|
|
2
2
|
import { r as loadConfig, u as resolveConfigForEnvironment } from "./loader-E_UGyTrJ.js";
|
|
3
|
-
import { c as writeWranglerConfig, i as isolateViteBuildOutputPaths$1, o as rebaseWranglerConfigPaths, t as compileBuildConfig } from "./compiler-
|
|
3
|
+
import { c as writeWranglerConfig, i as isolateViteBuildOutputPaths$1, o as rebaseWranglerConfigPaths, t as compileBuildConfig } from "./compiler-CgIFPfRA.js";
|
|
4
4
|
import { f as logLine } from "./ui-BUoZApvE.js";
|
|
5
5
|
import { n as getPackageVersion } from "./package-metadata-DjHBLB-z.js";
|
|
6
6
|
import { t as resolvePackageSpecifier } from "./resolve-package-qizBfCIm.js";
|
|
7
|
-
import { i as writeGeneratedViteConfig, l as prepareComposedWorkerEntrypoint, n as resolveEffectiveViteProject } from "./vite-
|
|
7
|
+
import { i as writeGeneratedViteConfig, l as prepareComposedWorkerEntrypoint, n as resolveEffectiveViteProject } from "./vite-CtvgOi1c.js";
|
|
8
8
|
import { t as bundleWorkerEntry } from "./worker-bundler-dTTnYU3n.js";
|
|
9
9
|
import { t as detectViteProject } from "./vite-utils-OVLMV605.js";
|
|
10
10
|
import { t as getDependencies } from "./dependencies-C2oxFjU_.js";
|
|
@@ -1101,15 +1101,15 @@ async function runInit(parsed, logger, options) {
|
|
|
1101
1101
|
return runInitCommand(parsed, logger, options);
|
|
1102
1102
|
}
|
|
1103
1103
|
async function runDev(parsed, logger, options) {
|
|
1104
|
-
const { runDevCommand } = await import("./dev-
|
|
1104
|
+
const { runDevCommand } = await import("./dev-DRP6LR2H.js");
|
|
1105
1105
|
return runDevCommand(parsed, logger, options);
|
|
1106
1106
|
}
|
|
1107
1107
|
async function runBuild(parsed, logger, options) {
|
|
1108
|
-
const { runBuildCommand } = await import("./build-
|
|
1108
|
+
const { runBuildCommand } = await import("./build-Dp8k2SWa.js");
|
|
1109
1109
|
return runBuildCommand(parsed, logger, options);
|
|
1110
1110
|
}
|
|
1111
1111
|
async function runDeploy(parsed, logger, options) {
|
|
1112
|
-
const { runDeployCommand } = await import("./deploy-
|
|
1112
|
+
const { runDeployCommand } = await import("./deploy-Blrdr3Gv.js");
|
|
1113
1113
|
return runDeployCommand(parsed, logger, {
|
|
1114
1114
|
...options,
|
|
1115
1115
|
requireExplicitDeployTarget: true
|
|
@@ -1124,7 +1124,7 @@ async function runDoctor(parsed, logger, options) {
|
|
|
1124
1124
|
return runDoctorCommand(parsed, logger, options);
|
|
1125
1125
|
}
|
|
1126
1126
|
async function runConfig(parsed, logger, options) {
|
|
1127
|
-
const { runConfigCommand } = await import("./config-
|
|
1127
|
+
const { runConfigCommand } = await import("./config-BwRb2_vD.js");
|
|
1128
1128
|
return runConfigCommand(parsed, logger, options);
|
|
1129
1129
|
}
|
|
1130
1130
|
async function runAccount(parsed, logger, options) {
|
|
@@ -1136,7 +1136,7 @@ async function runLogin(parsed, logger, options) {
|
|
|
1136
1136
|
return runLoginCommand(parsed, logger, options);
|
|
1137
1137
|
}
|
|
1138
1138
|
async function runPreviews(parsed, logger, options) {
|
|
1139
|
-
const { runPreviewsCommand } = await import("./previews-
|
|
1139
|
+
const { runPreviewsCommand } = await import("./previews-D-GPVCeq.js");
|
|
1140
1140
|
return runPreviewsCommand(parsed, logger, options);
|
|
1141
1141
|
}
|
|
1142
1142
|
async function runProductions(parsed, logger, options) {
|
|
@@ -458,7 +458,11 @@ function compileConfigInternal(config, environment, options = {}) {
|
|
|
458
458
|
...consumer.environment && { environment: consumer.environment }
|
|
459
459
|
});
|
|
460
460
|
if (mergedConfig.streamingTailConsumers && mergedConfig.streamingTailConsumers.length > 0) result.streaming_tail_consumers = mergedConfig.streamingTailConsumers.map((consumer) => typeof consumer === "string" ? { service: consumer } : { service: consumer.service });
|
|
461
|
-
|
|
461
|
+
const r2BucketsVar = buildR2BucketsVar(mergedConfig.bindings?.r2);
|
|
462
|
+
if (mergedConfig.vars && Object.keys(mergedConfig.vars).length > 0 || r2BucketsVar) result.vars = {
|
|
463
|
+
...r2BucketsVar && { DEVFLARE_R2_BUCKETS: r2BucketsVar },
|
|
464
|
+
...mergedConfig.vars
|
|
465
|
+
};
|
|
462
466
|
const secrets = toWranglerSecretsConfig(mergedConfig.secrets);
|
|
463
467
|
if (secrets) result.secrets = secrets;
|
|
464
468
|
if (mergedConfig.routes && mergedConfig.routes.length > 0) result.routes = mergedConfig.routes.map((route) => ({
|
|
@@ -485,6 +489,24 @@ function compileConfigInternal(config, environment, options = {}) {
|
|
|
485
489
|
return result;
|
|
486
490
|
}
|
|
487
491
|
/**
|
|
492
|
+
* Build the JSON value of the injected `DEVFLARE_R2_BUCKETS` var: a mapping
|
|
493
|
+
* of R2 binding name → `{ bucketName, jurisdiction? }` that `presignR2Put`/
|
|
494
|
+
* `presignR2Get` read at runtime to presign against the right bucket without
|
|
495
|
+
* the app hardcoding bucket names. Returns `undefined` when the config has
|
|
496
|
+
* no R2 bindings.
|
|
497
|
+
*/
|
|
498
|
+
function buildR2BucketsVar(r2Bindings) {
|
|
499
|
+
if (!r2Bindings || Object.keys(r2Bindings).length === 0) return;
|
|
500
|
+
const mapping = Object.fromEntries(Object.entries(r2Bindings).map(([bindingName, bindingConfig]) => {
|
|
501
|
+
const normalized = normalizeR2Binding(bindingConfig);
|
|
502
|
+
return [bindingName, {
|
|
503
|
+
bucketName: normalized.bucketName,
|
|
504
|
+
...normalized.jurisdiction && { jurisdiction: normalized.jurisdiction }
|
|
505
|
+
}];
|
|
506
|
+
}));
|
|
507
|
+
return JSON.stringify(mapping);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
488
510
|
* Compile DevflareConfig to programmatic config for @cloudflare/vite-plugin.
|
|
489
511
|
* This is used instead of wrangler.jsonc in dev mode.
|
|
490
512
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as resolveConfigEnvVars } from "./preview-C3Cdr8an.js";
|
|
2
2
|
import { a as ConfigResourceResolutionError, o as loadResolvedConfig, r as loadConfig, s as resolveResources } from "./loader-E_UGyTrJ.js";
|
|
3
|
-
import { n as compileConfig, t as compileBuildConfig } from "./compiler-
|
|
3
|
+
import { n as compileConfig, t as compileBuildConfig } from "./compiler-CgIFPfRA.js";
|
|
4
4
|
//#region src/cli/commands/config.ts
|
|
5
5
|
function isSupportedFormat(value) {
|
|
6
6
|
return value === "devflare" || value === "wrangler";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { a as resolvePreviewIdentifier, d as resolveConfigEnvVars } from "./preview-C3Cdr8an.js";
|
|
2
2
|
import { c as prepareConfigResourcesForDeploy, r as loadConfig, u as resolveConfigForEnvironment } from "./loader-E_UGyTrJ.js";
|
|
3
|
-
import { a as readWranglerConfig, c as writeWranglerConfig, n as compileConfig, o as rebaseWranglerConfigPaths, s as stringifyConfig, t as compileBuildConfig } from "./compiler-
|
|
3
|
+
import { a as readWranglerConfig, c as writeWranglerConfig, n as compileConfig, o as rebaseWranglerConfigPaths, s as stringifyConfig, t as compileBuildConfig } from "./compiler-CgIFPfRA.js";
|
|
4
4
|
import { d as getPrimaryAccount, n as getEffectiveAccountId } from "./preferences-BKp_7XJx.js";
|
|
5
5
|
import { D as listWorkerVersions, E as listWorkerDeployments, O as listWorkers, T as getWorkersSubdomain, c as reconcilePreviewRegistry, w as getWorkerVersionDetail, x as formatWorkersDevUrl } from "./preview-registry-ClAbLTHH.js";
|
|
6
6
|
import { _ as yellowBold, d as green, f as logLine, g as yellow, o as dim, r as createCliTheme } from "./ui-BUoZApvE.js";
|
|
7
7
|
import { n as getPackageVersion } from "./package-metadata-DjHBLB-z.js";
|
|
8
8
|
import { t as resolvePackageSpecifier } from "./resolve-package-qizBfCIm.js";
|
|
9
9
|
import { t as asOptionalString } from "./command-utils-CSnoFdxM.js";
|
|
10
|
-
import { a as createBuildManifest, i as compareManifests, n as applyDeploymentStrategy, o as formatDriftWarning, r as describeDeploymentStrategy, s as readBuildManifest, t as prepareBuildArtifacts } from "./build-artifacts-
|
|
10
|
+
import { a as createBuildManifest, i as compareManifests, n as applyDeploymentStrategy, o as formatDriftWarning, r as describeDeploymentStrategy, s as readBuildManifest, t as prepareBuildArtifacts } from "./build-artifacts-DLEYfdVL.js";
|
|
11
11
|
import { t as getDependencies } from "./dependencies-C2oxFjU_.js";
|
|
12
12
|
import { n as preparePreviewScopedResourcesForDeploy } from "./preview-resources-D_aFwtZR.js";
|
|
13
13
|
import { mkdir, open, readFile, rm, writeFile } from "node:fs/promises";
|
|
@@ -7,9 +7,9 @@ import { clearLocalSendEmailBindings, setLocalSendEmailBindings } from "../utils
|
|
|
7
7
|
import { C as buildSendEmailConfig, D as buildVersionMetadataConfig, E as buildTailConsumersConfig, O as buildWorkerLoadersConfig, S as buildSecretsStoreConfig, T as buildStreamingTailConsumersConfig, _ as buildMtlsCertificatesConfig, b as buildQueueProducers, c as buildAiSearchInstancesConfig, d as buildArtifactsConfig, f as buildDispatchNamespacesConfig, g as buildMediaConfig, h as buildImagesConfig, k as buildWorkflowsConfig, l as buildAiSearchNamespacesConfig, m as buildHyperdrivesConfig, n as getRouteDirectoryCandidate, p as buildFlagshipConfig, s as resolveServiceBindings, t as discoverRoutes, u as buildAnalyticsEngineConfig, v as buildPipelinesConfig, w as buildStreamConfig, x as buildRateLimitsConfig, y as buildQueueConsumers } from "./routes-BMU7ga_l.js";
|
|
8
8
|
import { r as transformDurableObject } from "./durable-object-DMtH0XYX.js";
|
|
9
9
|
import { i as findFiles } from "./glob-CmQOvunB.js";
|
|
10
|
-
import { d as DEFAULT_FETCH_ENTRY_FILES, f as DEFAULT_QUEUE_ENTRY_FILES, g as discoverDurableObjectFiles, h as resolveWorkerSurfacePaths, i as writeGeneratedViteConfig, l as prepareComposedWorkerEntrypoint, m as hasWorkerSurfacePaths, n as resolveEffectiveViteProject, p as DEFAULT_SCHEDULED_ENTRY_FILES, u as DEFAULT_EMAIL_ENTRY_FILES } from "./vite-
|
|
10
|
+
import { d as DEFAULT_FETCH_ENTRY_FILES, f as DEFAULT_QUEUE_ENTRY_FILES, g as discoverDurableObjectFiles, h as resolveWorkerSurfacePaths, i as writeGeneratedViteConfig, l as prepareComposedWorkerEntrypoint, m as hasWorkerSurfacePaths, n as resolveEffectiveViteProject, p as DEFAULT_SCHEDULED_ENTRY_FILES, u as DEFAULT_EMAIL_ENTRY_FILES } from "./vite-CtvgOi1c.js";
|
|
11
11
|
import { a as createWorkerdBundlerDefaults, i as writeWorkerCompatibleBundle, n as ensureDebugShim, r as resolveWorkerCompatibleRolldownConfig, t as bundleWorkerEntry } from "./worker-bundler-dTTnYU3n.js";
|
|
12
|
-
import {
|
|
12
|
+
import { n as bundleWorkflowEntrypointScript, t as R2_PRESIGN_RUNTIME_JS } from "./r2-presign-runtime-zTOLS0Ea.js";
|
|
13
13
|
import { n as buildLocalSecretWrappedBindingConfig } from "./local-secrets-6sMstHXw.js";
|
|
14
14
|
import { t as buildLocalBindingShimServiceConfig } from "./local-media-bindings-DsAW4AMF.js";
|
|
15
15
|
import { i as waitForViteReady, n as resolveViteMode, r as stopSpawnedProcessTree, t as detectViteProject } from "./vite-utils-OVLMV605.js";
|
|
@@ -1592,7 +1592,8 @@ async function handleDevToolsWebSocket(request, url) {
|
|
|
1592
1592
|
* All in-sandbox RPC behavior (method dispatch, error envelope, serialization,
|
|
1593
1593
|
* WebSocket bridge, HTTP transfer) lives in `GATEWAY_RUNTIME_JS` and is shared
|
|
1594
1594
|
* with `src/bridge/miniflare.ts`. The canonical TypeScript equivalent lives in
|
|
1595
|
-
* `src/bridge/server.ts`.
|
|
1595
|
+
* `src/bridge/server.ts`. The local presigned-R2 endpoint handler is shared
|
|
1596
|
+
* via `R2_PRESIGN_RUNTIME_JS` (`src/bridge/r2-presign-runtime.ts`).
|
|
1596
1597
|
*
|
|
1597
1598
|
* This file only owns the pieces that are genuinely dev-server-specific:
|
|
1598
1599
|
* - WebSocket route matching & DO WebSocket forwarding (`WS_ROUTES`)
|
|
@@ -1608,6 +1609,8 @@ function getGatewayScript(wsRoutes = [], debug = false, appServiceBindingName =
|
|
|
1608
1609
|
return `
|
|
1609
1610
|
${GATEWAY_RUNTIME_JS}
|
|
1610
1611
|
|
|
1612
|
+
${R2_PRESIGN_RUNTIME_JS}
|
|
1613
|
+
|
|
1611
1614
|
// Bridge Gateway Worker — Dev Server
|
|
1612
1615
|
// Dev-server-specific overlay on top of the shared GATEWAY_RUNTIME_JS:
|
|
1613
1616
|
// WS route DO forwarding, D1 migration, email ingest, app-worker fallthrough.
|
|
@@ -1635,6 +1638,11 @@ export default {
|
|
|
1635
1638
|
return handleHttpTransfer(request, env, url)
|
|
1636
1639
|
}
|
|
1637
1640
|
|
|
1641
|
+
const presignResponse = await __devflareR2PresignHandle(request, env, url)
|
|
1642
|
+
if (presignResponse) {
|
|
1643
|
+
return presignResponse
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1638
1646
|
if (url.pathname === '/_devflare/migrate' && request.method === 'POST') {
|
|
1639
1647
|
return handleMigration(request, env)
|
|
1640
1648
|
}
|
|
@@ -1909,7 +1917,10 @@ function makeMiniflareWorker(context, options) {
|
|
|
1909
1917
|
const { cwd, loadedConfig, bindings, sendEmailConfig, rateLimitsConfig, versionMetadataConfig, workerLoadersConfig, mtlsCertificatesConfig, dispatchNamespacesConfig, workflowsConfig, pipelinesConfig, hyperdrivesConfig, imagesConfig, mediaConfig, streamConfig, flagshipConfig, analyticsEngineConfig, tailConsumersConfig, streamingTailConsumersConfig, artifactsConfig, aiSearchNamespacesConfig, aiSearchInstancesConfig, secretsStoreConfig, localSecretWrappedBindingConfig, queueProducers } = context;
|
|
1910
1918
|
const baseFlags = loadedConfig.compatibilityFlags ?? [];
|
|
1911
1919
|
const compatFlags = baseFlags.includes("nodejs_compat") ? baseFlags : [...baseFlags, "nodejs_compat"];
|
|
1912
|
-
const workerBindings =
|
|
1920
|
+
const workerBindings = {
|
|
1921
|
+
...loadedConfig.vars ?? {},
|
|
1922
|
+
...context.injectedVars ?? {}
|
|
1923
|
+
};
|
|
1913
1924
|
const localWrappedBindings = { ...localSecretWrappedBindingConfig?.wrappedBindings ?? {} };
|
|
1914
1925
|
const workerConfig = {
|
|
1915
1926
|
name: options.name,
|
|
@@ -1995,6 +2006,16 @@ function collectWorkerWatchRoots(cwd, config, mainWorkerSurfacePaths) {
|
|
|
1995
2006
|
//#region src/dev-server/miniflare-dev-config.ts
|
|
1996
2007
|
const INTERNAL_APP_SERVICE_BINDING = "__DEVFLARE_APP";
|
|
1997
2008
|
/**
|
|
2009
|
+
* Resolve the browser-facing origin of the local dev runtime, used inside
|
|
2010
|
+
* locally-presigned R2 URLs. Honors `server.publicUrl` (reverse proxy /
|
|
2011
|
+
* tunnel setups); otherwise derives `http(s)://<host>:<port>` from the
|
|
2012
|
+
* Miniflare listen address, normalizing wildcard hosts to `localhost`.
|
|
2013
|
+
*/
|
|
2014
|
+
function resolveR2PresignOrigin(serverConfig, miniflareHost, miniflarePort) {
|
|
2015
|
+
if (serverConfig?.publicUrl) return serverConfig.publicUrl.replace(/\/$/, "");
|
|
2016
|
+
return `${serverConfig?.https ? "https" : "http"}://${miniflareHost === "0.0.0.0" || miniflareHost === "::" ? "localhost" : miniflareHost}:${miniflarePort}`;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
1998
2019
|
* Build the complete Miniflare configuration for the dev server.
|
|
1999
2020
|
*
|
|
2000
2021
|
* IMPORTANT: When using multi-worker setup, ALL workers must go in the
|
|
@@ -2003,7 +2024,7 @@ const INTERNAL_APP_SERVICE_BINDING = "__DEVFLARE_APP";
|
|
|
2003
2024
|
* workers array is present.
|
|
2004
2025
|
*/
|
|
2005
2026
|
function buildMiniflareDevConfig(input) {
|
|
2006
|
-
const { config: loadedConfig, cwd, miniflarePort, miniflareHost = "127.0.0.1", persist, enableVite, debug, mainWorkerSurfacePaths, mainWorkerRoutes, mainWorkerScriptPath, bundledMainWorkerScriptPath, workflowEntrypointScript, browserShimPort, doResult, serviceBindingResolution, logger } = input;
|
|
2027
|
+
const { config: loadedConfig, cwd, miniflarePort, miniflareHost = "127.0.0.1", persist, enableVite, debug, mainWorkerSurfacePaths, mainWorkerRoutes, mainWorkerScriptPath, bundledMainWorkerScriptPath, workflowEntrypointScript, browserShimPort, doResult, serviceBindingResolution, r2PresignSecret, logger } = input;
|
|
2007
2028
|
const bindings = loadedConfig.bindings ?? {};
|
|
2008
2029
|
const persistPath = resolve(cwd, ".devflare/data");
|
|
2009
2030
|
const appWorkerName = loadedConfig.name;
|
|
@@ -2086,7 +2107,11 @@ function buildMiniflareDevConfig(input) {
|
|
|
2086
2107
|
aiSearchInstancesConfig,
|
|
2087
2108
|
secretsStoreConfig: buildSecretsStoreConfig(bindings, loadedConfig.secretsStoreId, localSecretBindingNames),
|
|
2088
2109
|
localSecretWrappedBindingConfig,
|
|
2089
|
-
queueProducers
|
|
2110
|
+
queueProducers,
|
|
2111
|
+
injectedVars: bindings.r2 && r2PresignSecret ? {
|
|
2112
|
+
DEVFLARE_R2_PRESIGN_SECRET: r2PresignSecret,
|
|
2113
|
+
DEVFLARE_R2_PRESIGN_ORIGIN: resolveR2PresignOrigin(serverConfig, miniflareHost, miniflarePort)
|
|
2114
|
+
} : void 0
|
|
2090
2115
|
};
|
|
2091
2116
|
const createWorkerConfig = (options) => makeMiniflareWorker(workerContext, options);
|
|
2092
2117
|
const gatewayWorker = createWorkerConfig({
|
|
@@ -2902,7 +2927,7 @@ async function resolveViteIntegration(options) {
|
|
|
2902
2927
|
* Start the Vite dev server process.
|
|
2903
2928
|
*/
|
|
2904
2929
|
async function startViteProcess(options) {
|
|
2905
|
-
const { cwd, configPath, vitePort, miniflarePort, generatedViteConfigPath, logger } = options;
|
|
2930
|
+
const { cwd, configPath, vitePort, miniflarePort, generatedViteConfigPath, r2Presign, logger } = options;
|
|
2906
2931
|
const args = [
|
|
2907
2932
|
"vite",
|
|
2908
2933
|
"dev",
|
|
@@ -2923,6 +2948,10 @@ async function startViteProcess(options) {
|
|
|
2923
2948
|
DEVFLARE_DEV: "true",
|
|
2924
2949
|
DEVFLARE_BRIDGE_PORT: String(miniflarePort),
|
|
2925
2950
|
...configPath ? { DEVFLARE_CONFIG_PATH: configPath } : {},
|
|
2951
|
+
...r2Presign ? {
|
|
2952
|
+
DEVFLARE_R2_PRESIGN_SECRET: r2Presign.secret,
|
|
2953
|
+
DEVFLARE_R2_PRESIGN_ORIGIN: r2Presign.origin
|
|
2954
|
+
} : {},
|
|
2926
2955
|
FORCE_COLOR: "1"
|
|
2927
2956
|
}
|
|
2928
2957
|
});
|
|
@@ -3050,6 +3079,7 @@ async function applyWatcherTargetDiff(watcher, currentTargets, nextTargets) {
|
|
|
3050
3079
|
function createDevServer(options) {
|
|
3051
3080
|
const { cwd, configPath, vitePort = 5173, miniflarePort = 8787, miniflareHost = "127.0.0.1", enableVite: enableViteRequested = true, persist = true, logger, verbose = false, debug = process.env.DEVFLARE_DEBUG === "true" } = options;
|
|
3052
3081
|
const state = createDevServerState({ enableVite: enableViteRequested });
|
|
3082
|
+
const r2PresignSecret = `${crypto.randomUUID()}${crypto.randomUUID()}`;
|
|
3053
3083
|
const reloadQueue = createReloadQueue({
|
|
3054
3084
|
reload: async () => {
|
|
3055
3085
|
if (!state.miniflare) return;
|
|
@@ -3098,6 +3128,7 @@ function createDevServer(options) {
|
|
|
3098
3128
|
browserShimPort: state.browserShimPort,
|
|
3099
3129
|
doResult,
|
|
3100
3130
|
serviceBindingResolution: state.serviceBindingResolution,
|
|
3131
|
+
r2PresignSecret,
|
|
3101
3132
|
logger
|
|
3102
3133
|
});
|
|
3103
3134
|
}
|
|
@@ -3269,6 +3300,10 @@ function createDevServer(options) {
|
|
|
3269
3300
|
vitePort,
|
|
3270
3301
|
miniflarePort,
|
|
3271
3302
|
generatedViteConfigPath: state.generatedViteConfigPath,
|
|
3303
|
+
r2Presign: state.config.bindings?.r2 ? {
|
|
3304
|
+
secret: r2PresignSecret,
|
|
3305
|
+
origin: resolveR2PresignOrigin(state.config.server, miniflareHost, miniflarePort)
|
|
3306
|
+
} : null,
|
|
3272
3307
|
logger
|
|
3273
3308
|
});
|
|
3274
3309
|
else logger?.info("Vite startup skipped (no effective Vite config found for this package)");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as resolvePreviewIdentifier } from "./preview-C3Cdr8an.js";
|
|
2
2
|
import { i as resolveConfigPath, o as loadResolvedConfig, r as loadConfig, t as ConfigNotFoundError } from "./loader-E_UGyTrJ.js";
|
|
3
|
-
import { t as compileBuildConfig } from "./compiler-
|
|
3
|
+
import { t as compileBuildConfig } from "./compiler-CgIFPfRA.js";
|
|
4
4
|
import { t as account } from "./cloudflare-BaloqI3H.js";
|
|
5
5
|
import { _ as yellowBold, a as cyanBold, d as green, f as logLine, g as yellow, h as whiteDim, m as red, n as bold, o as dim, r as createCliTheme, u as formatTableLine } from "./ui-BUoZApvE.js";
|
|
6
6
|
import { i as resolveNamedSelection, r as resolveCloudflareAccountId, t as asOptionalString } from "./command-utils-CSnoFdxM.js";
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { x as normalizeWorkflowBinding } from "./schema-normalization-Zgm4W6O6.js";
|
|
2
|
+
import { i as findFiles, r as DEFAULT_WORKFLOW_PATTERN } from "./glob-CmQOvunB.js";
|
|
3
|
+
import { t as bundleWorkerEntry } from "./worker-bundler-dTTnYU3n.js";
|
|
4
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
import { join, relative, resolve } from "pathe";
|
|
6
|
+
//#region src/workflows/local-workflow-entrypoints.ts
|
|
7
|
+
function findExportedClasses(code) {
|
|
8
|
+
const classes = [];
|
|
9
|
+
const classPattern = /export\s+class\s+(\w+)/g;
|
|
10
|
+
let match = classPattern.exec(code);
|
|
11
|
+
while (match !== null) {
|
|
12
|
+
classes.push(match[1]);
|
|
13
|
+
match = classPattern.exec(code);
|
|
14
|
+
}
|
|
15
|
+
return classes;
|
|
16
|
+
}
|
|
17
|
+
function toImportSpecifier(fromDir, filePath) {
|
|
18
|
+
const relativePath = relative(fromDir, filePath).replace(/\\/g, "/");
|
|
19
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
20
|
+
}
|
|
21
|
+
async function discoverWorkflowClasses(config, configDir) {
|
|
22
|
+
const classToFilePath = /* @__PURE__ */ new Map();
|
|
23
|
+
const workflowPatternConfig = config.files?.workflows;
|
|
24
|
+
const workflowPattern = typeof workflowPatternConfig === "string" ? workflowPatternConfig : DEFAULT_WORKFLOW_PATTERN;
|
|
25
|
+
if (workflowPatternConfig === false) return classToFilePath;
|
|
26
|
+
const files = await findFiles(workflowPattern, { cwd: configDir });
|
|
27
|
+
for (const filePath of files) try {
|
|
28
|
+
const code = await readFile(filePath, "utf-8");
|
|
29
|
+
for (const className of findExportedClasses(code)) classToFilePath.set(className, filePath);
|
|
30
|
+
} catch {}
|
|
31
|
+
return classToFilePath;
|
|
32
|
+
}
|
|
33
|
+
async function resolveLocalWorkflowEntrypoints(config, configDir) {
|
|
34
|
+
const workflows = config.bindings?.workflows;
|
|
35
|
+
if (!workflows || Object.keys(workflows).length === 0) return [];
|
|
36
|
+
const classToFilePath = await discoverWorkflowClasses(config, configDir);
|
|
37
|
+
const entrypoints = [];
|
|
38
|
+
for (const [bindingName, binding] of Object.entries(workflows)) {
|
|
39
|
+
const normalized = normalizeWorkflowBinding(binding);
|
|
40
|
+
if (normalized.scriptName) continue;
|
|
41
|
+
const scriptPath = classToFilePath.get(normalized.className);
|
|
42
|
+
if (!scriptPath) throw new Error(`Workflow binding ${bindingName} (className: '${normalized.className}') not found.\nEither set files.workflows to match the workflow source file, or set scriptName when the workflow lives in another worker.`);
|
|
43
|
+
entrypoints.push({
|
|
44
|
+
bindingName,
|
|
45
|
+
className: normalized.className,
|
|
46
|
+
scriptPath
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return entrypoints;
|
|
50
|
+
}
|
|
51
|
+
function buildWorkflowVirtualEntry(entrypoints, entryDir) {
|
|
52
|
+
const imports = entrypoints.map((entrypoint, index) => {
|
|
53
|
+
const importName = `__DevflareWorkflow${index}`;
|
|
54
|
+
const importPath = toImportSpecifier(entryDir, entrypoint.scriptPath);
|
|
55
|
+
return {
|
|
56
|
+
importName,
|
|
57
|
+
className: entrypoint.className,
|
|
58
|
+
line: `import { ${entrypoint.className} as ${importName} } from '${importPath}'`
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
const exports = imports.map((entrypoint) => {
|
|
62
|
+
return `export { ${entrypoint.importName} as ${entrypoint.className} }`;
|
|
63
|
+
});
|
|
64
|
+
return [
|
|
65
|
+
...imports.map((entrypoint) => entrypoint.line),
|
|
66
|
+
"",
|
|
67
|
+
...exports
|
|
68
|
+
].join("\n");
|
|
69
|
+
}
|
|
70
|
+
async function bundleWorkflowEntrypointScript(config, configDir, options = {}) {
|
|
71
|
+
const entrypoints = await resolveLocalWorkflowEntrypoints(config, configDir);
|
|
72
|
+
if (entrypoints.length === 0) return "";
|
|
73
|
+
const entryDir = resolve(configDir, ".devflare", "workflow-entrypoints");
|
|
74
|
+
const entryPath = join(entryDir, "__entry.ts");
|
|
75
|
+
const outFile = join(entryDir, "index.js");
|
|
76
|
+
await mkdir(entryDir, { recursive: true });
|
|
77
|
+
await writeFile(entryPath, buildWorkflowVirtualEntry(entrypoints, entryDir));
|
|
78
|
+
await bundleWorkerEntry({
|
|
79
|
+
cwd: configDir,
|
|
80
|
+
inputFile: entryPath,
|
|
81
|
+
outFile,
|
|
82
|
+
rolldownOptions: config.rolldown?.options,
|
|
83
|
+
sourcemap: config.rolldown?.sourcemap,
|
|
84
|
+
minify: config.rolldown?.minify,
|
|
85
|
+
logger: options.logger
|
|
86
|
+
});
|
|
87
|
+
return await readFile(outFile, "utf-8");
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/bridge/r2-presign-runtime.ts
|
|
91
|
+
/**
|
|
92
|
+
* Inline JS defining `__devflareR2PresignHandle(request, env, url)`, which
|
|
93
|
+
* returns a `Response` when the request targets the local presign endpoint
|
|
94
|
+
* and `null` otherwise. Enforces signature, expiry, method, content type and
|
|
95
|
+
* size against the per-boot secret in `env.DEVFLARE_R2_PRESIGN_SECRET`, then
|
|
96
|
+
* executes the object operation on the local R2 binding.
|
|
97
|
+
*/
|
|
98
|
+
const R2_PRESIGN_RUNTIME_JS = `
|
|
99
|
+
const __devflareR2PresignPrefix = '/_devflare/r2/presigned/'
|
|
100
|
+
|
|
101
|
+
const __devflareR2PresignCors = {
|
|
102
|
+
'Access-Control-Allow-Origin': '*',
|
|
103
|
+
'Access-Control-Allow-Methods': 'GET, HEAD, PUT, OPTIONS',
|
|
104
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
105
|
+
'Access-Control-Expose-Headers': 'ETag, Content-Type, Content-Length'
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function __devflareR2PresignError(status, code, message) {
|
|
109
|
+
return new Response(JSON.stringify({ error: { code, message } }), {
|
|
110
|
+
status,
|
|
111
|
+
headers: { 'Content-Type': 'application/json', ...__devflareR2PresignCors }
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function __devflareR2PresignHmacHex(secret, message) {
|
|
116
|
+
const encoder = new TextEncoder()
|
|
117
|
+
const key = await crypto.subtle.importKey(
|
|
118
|
+
'raw',
|
|
119
|
+
encoder.encode(secret),
|
|
120
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
121
|
+
false,
|
|
122
|
+
['sign']
|
|
123
|
+
)
|
|
124
|
+
const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(message))
|
|
125
|
+
return [...new Uint8Array(signature)].map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Constant-time hex comparison (uses workerd's timingSafeEqual when present).
|
|
129
|
+
function __devflareR2PresignEqual(expectedHex, actualHex) {
|
|
130
|
+
if (typeof actualHex !== 'string' || actualHex.length !== expectedHex.length) return false
|
|
131
|
+
const encoder = new TextEncoder()
|
|
132
|
+
const expected = encoder.encode(expectedHex)
|
|
133
|
+
const actual = encoder.encode(actualHex)
|
|
134
|
+
const subtle = crypto.subtle
|
|
135
|
+
if (subtle && typeof subtle.timingSafeEqual === 'function') {
|
|
136
|
+
return subtle.timingSafeEqual(expected, actual)
|
|
137
|
+
}
|
|
138
|
+
let diff = 0
|
|
139
|
+
for (let i = 0; i < expected.length; i++) diff |= expected[i] ^ actual[i]
|
|
140
|
+
return diff === 0
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// MUST match buildLocalCanonicalString in src/runtime/r2-presign.ts.
|
|
144
|
+
function __devflareR2PresignCanonical(method, binding, key, expires, contentType, contentLength, maxSize) {
|
|
145
|
+
return [
|
|
146
|
+
'devflare:r2-presign:v1',
|
|
147
|
+
method,
|
|
148
|
+
binding,
|
|
149
|
+
key,
|
|
150
|
+
expires,
|
|
151
|
+
contentType || '',
|
|
152
|
+
contentLength || '',
|
|
153
|
+
maxSize || ''
|
|
154
|
+
].join('\\n')
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Handle a request to the local presigned R2 endpoint; returns null when the
|
|
159
|
+
* path does not match so gateways can fall through to their other routes.
|
|
160
|
+
*/
|
|
161
|
+
async function __devflareR2PresignHandle(request, env, url) {
|
|
162
|
+
if (!url.pathname.startsWith(__devflareR2PresignPrefix)) return null
|
|
163
|
+
|
|
164
|
+
if (request.method === 'OPTIONS') {
|
|
165
|
+
return new Response(null, {
|
|
166
|
+
status: 204,
|
|
167
|
+
headers: { ...__devflareR2PresignCors, 'Access-Control-Max-Age': '86400' }
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const rest = url.pathname.slice(__devflareR2PresignPrefix.length)
|
|
172
|
+
const slashIndex = rest.indexOf('/')
|
|
173
|
+
if (slashIndex <= 0 || slashIndex === rest.length - 1) {
|
|
174
|
+
return __devflareR2PresignError(400, 'bad_request', 'Expected /_devflare/r2/presigned/<binding>/<key>.')
|
|
175
|
+
}
|
|
176
|
+
const binding = decodeURIComponent(rest.slice(0, slashIndex))
|
|
177
|
+
const key = rest
|
|
178
|
+
.slice(slashIndex + 1)
|
|
179
|
+
.split('/')
|
|
180
|
+
.map((segment) => decodeURIComponent(segment))
|
|
181
|
+
.join('/')
|
|
182
|
+
|
|
183
|
+
const secret = env.DEVFLARE_R2_PRESIGN_SECRET
|
|
184
|
+
if (typeof secret !== 'string' || secret.length === 0) {
|
|
185
|
+
return __devflareR2PresignError(
|
|
186
|
+
500,
|
|
187
|
+
'presign_unconfigured',
|
|
188
|
+
'DEVFLARE_R2_PRESIGN_SECRET is not configured on the devflare gateway. '
|
|
189
|
+
+ 'This endpoint is only served for configs with R2 bindings.'
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const params = url.searchParams
|
|
194
|
+
const signedMethod = params.get('X-Devflare-Method')
|
|
195
|
+
const expires = params.get('X-Devflare-Expires')
|
|
196
|
+
const providedSignature = params.get('X-Devflare-Signature')
|
|
197
|
+
const signedContentType = params.get('X-Devflare-Content-Type')
|
|
198
|
+
const signedContentLength = params.get('X-Devflare-Content-Length')
|
|
199
|
+
const signedMaxSize = params.get('X-Devflare-Max-Size')
|
|
200
|
+
|
|
201
|
+
if (!signedMethod || !expires || !providedSignature) {
|
|
202
|
+
return __devflareR2PresignError(403, 'missing_parameters', 'Missing presign query parameters.')
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const expectedSignature = await __devflareR2PresignHmacHex(
|
|
206
|
+
secret,
|
|
207
|
+
__devflareR2PresignCanonical(
|
|
208
|
+
signedMethod, binding, key, expires, signedContentType, signedContentLength, signedMaxSize
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
if (!__devflareR2PresignEqual(expectedSignature, providedSignature)) {
|
|
212
|
+
return __devflareR2PresignError(403, 'invalid_signature', 'Presigned URL signature mismatch.')
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (Math.floor(Date.now() / 1000) > Number(expires)) {
|
|
216
|
+
return __devflareR2PresignError(403, 'expired', 'Presigned URL has expired.')
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const methodAllowed = signedMethod === 'GET'
|
|
220
|
+
? request.method === 'GET' || request.method === 'HEAD'
|
|
221
|
+
: request.method === signedMethod
|
|
222
|
+
if (!methodAllowed) {
|
|
223
|
+
return __devflareR2PresignError(
|
|
224
|
+
403,
|
|
225
|
+
'method_mismatch',
|
|
226
|
+
'URL was presigned for ' + signedMethod + ', got ' + request.method + '.'
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const bucket = env[binding]
|
|
231
|
+
if (!bucket || typeof bucket.put !== 'function' || typeof bucket.head !== 'function') {
|
|
232
|
+
return __devflareR2PresignError(404, 'unknown_binding', 'R2 binding not found: ' + binding)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (request.method === 'PUT') {
|
|
236
|
+
const sentContentType = request.headers.get('Content-Type')
|
|
237
|
+
if (signedContentType !== null && sentContentType !== signedContentType) {
|
|
238
|
+
return __devflareR2PresignError(
|
|
239
|
+
403,
|
|
240
|
+
'content_type_mismatch',
|
|
241
|
+
'URL was presigned for Content-Type "' + signedContentType + '", got "' + sentContentType + '".'
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const body = await request.arrayBuffer()
|
|
246
|
+
if (signedContentLength !== null && body.byteLength !== Number(signedContentLength)) {
|
|
247
|
+
return __devflareR2PresignError(
|
|
248
|
+
403,
|
|
249
|
+
'content_length_mismatch',
|
|
250
|
+
'URL was presigned for exactly ' + signedContentLength + ' bytes, got ' + body.byteLength + '.'
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
if (signedMaxSize !== null && body.byteLength > Number(signedMaxSize)) {
|
|
254
|
+
return __devflareR2PresignError(
|
|
255
|
+
413,
|
|
256
|
+
'too_large',
|
|
257
|
+
'Body of ' + body.byteLength + ' bytes exceeds the presigned maximum of ' + signedMaxSize + '.'
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const putContentType = sentContentType || signedContentType || undefined
|
|
262
|
+
const result = await bucket.put(key, body, {
|
|
263
|
+
...(putContentType && { httpMetadata: { contentType: putContentType } })
|
|
264
|
+
})
|
|
265
|
+
return new Response(null, {
|
|
266
|
+
status: 200,
|
|
267
|
+
headers: { ...__devflareR2PresignCors, ...(result?.httpEtag && { ETag: result.httpEtag }) }
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// GET / HEAD
|
|
272
|
+
const objectHeaders = (object) => ({
|
|
273
|
+
...__devflareR2PresignCors,
|
|
274
|
+
'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
|
|
275
|
+
'Content-Length': String(object.size),
|
|
276
|
+
...(object.httpEtag && { ETag: object.httpEtag })
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
if (request.method === 'HEAD') {
|
|
280
|
+
const object = await bucket.head(key)
|
|
281
|
+
if (!object) return __devflareR2PresignError(404, 'not_found', 'Object not found: ' + key)
|
|
282
|
+
return new Response(null, { status: 200, headers: objectHeaders(object) })
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const object = await bucket.get(key)
|
|
286
|
+
if (!object) return __devflareR2PresignError(404, 'not_found', 'Object not found: ' + key)
|
|
287
|
+
return new Response(object.body, { status: 200, headers: objectHeaders(object) })
|
|
288
|
+
}
|
|
289
|
+
`;
|
|
290
|
+
//#endregion
|
|
291
|
+
export { bundleWorkflowEntrypointScript as n, R2_PRESIGN_RUNTIME_JS as t };
|