wrangler 0.0.0-e978986 → 0.0.0-e9e9872
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/README.md +7 -1
- package/bin/wrangler.js +114 -57
- package/kv-asset-handler.js +1 -0
- package/miniflare-dist/index.mjs +10 -2
- package/package.json +159 -152
- package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
- package/src/__tests__/config-cache.test.ts +30 -24
- package/src/__tests__/configuration.test.ts +3935 -3363
- package/src/__tests__/dev.test.tsx +1128 -949
- package/src/__tests__/guess-worker-format.test.ts +68 -68
- package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
- package/src/__tests__/helpers/mock-account-id.ts +24 -24
- package/src/__tests__/helpers/mock-bin.ts +20 -20
- package/src/__tests__/helpers/mock-cfetch.ts +92 -92
- package/src/__tests__/helpers/mock-console.ts +49 -39
- package/src/__tests__/helpers/mock-dialogs.ts +94 -71
- package/src/__tests__/helpers/mock-http-server.ts +30 -30
- package/src/__tests__/helpers/mock-istty.ts +65 -18
- package/src/__tests__/helpers/mock-kv.ts +26 -26
- package/src/__tests__/helpers/mock-oauth-flow.ts +223 -228
- package/src/__tests__/helpers/mock-process.ts +39 -0
- package/src/__tests__/helpers/mock-stdin.ts +82 -77
- package/src/__tests__/helpers/mock-web-socket.ts +21 -21
- package/src/__tests__/helpers/run-in-tmp.ts +27 -28
- package/src/__tests__/helpers/run-wrangler.ts +8 -8
- package/src/__tests__/helpers/write-worker-source.ts +16 -16
- package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
- package/src/__tests__/https-options.test.ts +142 -109
- package/src/__tests__/index.test.ts +239 -233
- package/src/__tests__/init.test.ts +1605 -1180
- package/src/__tests__/jest.setup.ts +76 -33
- package/src/__tests__/kv.test.ts +1160 -991
- package/src/__tests__/logger.test.ts +100 -74
- package/src/__tests__/package-manager.test.ts +303 -303
- package/src/__tests__/pages.test.ts +1160 -563
- package/src/__tests__/parse.test.ts +252 -252
- package/src/__tests__/publish.test.ts +6426 -5299
- package/src/__tests__/pubsub.test.ts +367 -0
- package/src/__tests__/r2.test.ts +133 -133
- package/src/__tests__/route.test.ts +18 -18
- package/src/__tests__/secret.test.ts +470 -459
- package/src/__tests__/tail.test.ts +538 -530
- package/src/__tests__/user.test.ts +124 -112
- package/src/__tests__/whoami.test.tsx +208 -83
- package/src/__tests__/worker-namespace.test.ts +327 -0
- package/src/abort.d.ts +1 -1
- package/src/api/dev.ts +52 -0
- package/src/api/index.ts +1 -0
- package/src/bundle-reporter.tsx +29 -0
- package/src/bundle.ts +158 -146
- package/src/cfetch/index.ts +80 -80
- package/src/cfetch/internal.ts +92 -88
- package/src/cli.ts +21 -7
- package/src/config/config.ts +204 -195
- package/src/config/diagnostics.ts +61 -61
- package/src/config/environment.ts +390 -357
- package/src/config/index.ts +206 -193
- package/src/config/validation-helpers.ts +366 -357
- package/src/config/validation.ts +1573 -1367
- package/src/config-cache.ts +79 -41
- package/src/create-worker-preview.ts +206 -136
- package/src/create-worker-upload-form.ts +247 -238
- package/src/dev/dev-vars.ts +13 -13
- package/src/dev/dev.tsx +334 -336
- package/src/dev/local.tsx +310 -274
- package/src/dev/remote.tsx +366 -211
- package/src/dev/use-esbuild.ts +126 -94
- package/src/dev.tsx +538 -0
- package/src/dialogs.tsx +97 -97
- package/src/durable.ts +87 -87
- package/src/entry.ts +234 -228
- package/src/environment-variables.ts +23 -23
- package/src/errors.ts +6 -6
- package/src/faye-websocket.d.ts +6 -0
- package/src/generate.ts +33 -0
- package/src/git-client.ts +42 -0
- package/src/global-wrangler-config-path.ts +26 -0
- package/src/https-options.ts +84 -80
- package/src/index.tsx +1800 -2752
- package/src/init.ts +549 -0
- package/src/inspect.ts +593 -593
- package/src/intl-polyfill.d.ts +123 -123
- package/src/is-interactive.ts +12 -0
- package/src/kv.ts +299 -277
- package/src/logger.ts +46 -39
- package/src/miniflare-cli/enum-keys.ts +8 -8
- package/src/miniflare-cli/index.ts +43 -31
- package/src/miniflare-cli/request-context.ts +18 -18
- package/src/module-collection.ts +212 -212
- package/src/open-in-browser.ts +4 -6
- package/src/package-manager.ts +173 -128
- package/src/pages/build.tsx +202 -0
- package/src/pages/constants.ts +7 -0
- package/src/pages/deployments.tsx +101 -0
- package/src/pages/dev.tsx +964 -0
- package/src/pages/functions/buildPlugin.ts +105 -0
- package/src/pages/functions/buildWorker.ts +151 -0
- package/{pages → src/pages}/functions/filepath-routing.test.ts +113 -113
- package/src/pages/functions/filepath-routing.ts +189 -0
- package/src/pages/functions/identifiers.ts +78 -0
- package/src/pages/functions/routes.ts +151 -0
- package/src/pages/index.tsx +84 -0
- package/src/pages/projects.tsx +157 -0
- package/src/pages/publish.tsx +335 -0
- package/src/pages/types.ts +40 -0
- package/src/pages/upload.tsx +396 -0
- package/src/pages/utils.ts +12 -0
- package/src/parse.ts +209 -125
- package/src/paths.ts +6 -6
- package/src/preview.ts +31 -0
- package/src/proxy.ts +400 -389
- package/src/publish.ts +702 -505
- package/src/pubsub/index.ts +286 -0
- package/src/pubsub/pubsub-commands.tsx +577 -0
- package/src/r2.ts +19 -19
- package/src/selfsigned.d.ts +23 -23
- package/src/sites.tsx +278 -201
- package/src/tail/filters.ts +108 -108
- package/src/tail/index.ts +217 -217
- package/src/tail/printing.ts +45 -45
- package/src/update-check.ts +11 -11
- package/src/user/choose-account.tsx +60 -0
- package/src/user/env-vars.ts +46 -0
- package/src/user/generate-auth-url.ts +33 -0
- package/src/user/generate-random-state.ts +16 -0
- package/src/user/index.ts +3 -0
- package/src/user/user.tsx +1170 -0
- package/src/whoami.tsx +61 -41
- package/src/worker-namespace.ts +190 -0
- package/src/worker.ts +110 -99
- package/src/zones.ts +76 -0
- package/templates/checked-fetch.js +17 -0
- package/templates/new-worker-scheduled.js +4 -4
- package/templates/new-worker-scheduled.ts +16 -16
- package/templates/new-worker.js +3 -3
- package/templates/new-worker.ts +15 -15
- package/templates/no-op-worker.js +10 -0
- package/templates/pages-template-plugin.ts +155 -0
- package/templates/pages-template-worker.ts +161 -0
- package/templates/static-asset-facade.js +38 -36
- package/templates/tsconfig.json +95 -95
- package/wrangler-dist/cli.d.ts +298 -0
- package/wrangler-dist/cli.js +33496 -31370
- package/pages/functions/buildPlugin.ts +0 -105
- package/pages/functions/buildWorker.ts +0 -151
- package/pages/functions/filepath-routing.ts +0 -189
- package/pages/functions/identifiers.ts +0 -78
- package/pages/functions/routes.ts +0 -156
- package/pages/functions/template-plugin.ts +0 -147
- package/pages/functions/template-worker.ts +0 -143
- package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
- package/src/pages.tsx +0 -2027
- package/src/user.tsx +0 -1203
- package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
- package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
- package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
- package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
- package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
- package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
- package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
- package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
- package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
- package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
- package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
- package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
- package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
- package/vendor/wrangler-mime/CHANGELOG.md +0 -289
- package/vendor/wrangler-mime/LICENSE +0 -21
- package/vendor/wrangler-mime/Mime.js +0 -97
- package/vendor/wrangler-mime/README.md +0 -187
- package/vendor/wrangler-mime/cli.js +0 -46
- package/vendor/wrangler-mime/index.js +0 -4
- package/vendor/wrangler-mime/lite.js +0 -4
- package/vendor/wrangler-mime/package.json +0 -52
- package/vendor/wrangler-mime/types/other.js +0 -1
- package/vendor/wrangler-mime/types/standard.js +0 -1
package/src/dev/dev.tsx
CHANGED
|
@@ -13,272 +13,270 @@ import { runCustomBuild } from "../entry";
|
|
|
13
13
|
import { openInspector } from "../inspect";
|
|
14
14
|
import { logger } from "../logger";
|
|
15
15
|
import openInBrowser from "../open-in-browser";
|
|
16
|
-
import { getAPIToken } from "../user";
|
|
17
16
|
import { Local } from "./local";
|
|
18
17
|
import { Remote } from "./remote";
|
|
19
18
|
import { useEsbuild } from "./use-esbuild";
|
|
20
19
|
import type { Config } from "../config";
|
|
20
|
+
import type { Route } from "../config/environment";
|
|
21
21
|
import type { Entry } from "../entry";
|
|
22
22
|
import type { AssetPaths } from "../sites";
|
|
23
23
|
import type { CfWorkerInit } from "../worker";
|
|
24
|
-
import type { EsbuildBundle } from "./use-esbuild";
|
|
25
24
|
|
|
26
25
|
export type DevProps = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
26
|
+
name: string | undefined;
|
|
27
|
+
noBundle: boolean;
|
|
28
|
+
entry: Entry;
|
|
29
|
+
port: number;
|
|
30
|
+
ip: string;
|
|
31
|
+
inspectorPort: number;
|
|
32
|
+
rules: Config["rules"];
|
|
33
|
+
accountId: string | undefined;
|
|
34
|
+
initialMode: "local" | "remote";
|
|
35
|
+
jsxFactory: string | undefined;
|
|
36
|
+
jsxFragment: string | undefined;
|
|
37
|
+
tsconfig: string | undefined;
|
|
38
|
+
upstreamProtocol: "https" | "http";
|
|
39
|
+
localProtocol: "https" | "http";
|
|
40
|
+
localUpstream: string | undefined;
|
|
41
|
+
enableLocalPersistence: boolean;
|
|
42
|
+
bindings: CfWorkerInit["bindings"];
|
|
43
|
+
define: Config["define"];
|
|
44
|
+
crons: Config["triggers"]["crons"];
|
|
45
|
+
isWorkersSite: boolean;
|
|
46
|
+
assetPaths: AssetPaths | undefined;
|
|
47
|
+
compatibilityDate: string;
|
|
48
|
+
compatibilityFlags: string[] | undefined;
|
|
49
|
+
usageModel: "bundled" | "unbound" | undefined;
|
|
50
|
+
minify: boolean | undefined;
|
|
51
|
+
nodeCompat: boolean | undefined;
|
|
52
|
+
build: Config["build"];
|
|
53
|
+
env: string | undefined;
|
|
54
|
+
legacyEnv: boolean;
|
|
55
|
+
zone: string | undefined;
|
|
56
|
+
host: string | undefined;
|
|
57
|
+
routes: Route[] | undefined;
|
|
58
|
+
inspect: boolean | undefined;
|
|
59
|
+
logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
|
|
60
|
+
onReady: (() => void) | undefined;
|
|
61
|
+
showInteractiveDevSession: boolean | undefined;
|
|
63
62
|
};
|
|
64
63
|
|
|
65
64
|
export function DevImplementation(props: DevProps): JSX.Element {
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (
|
|
66
|
+
!props.isWorkersSite &&
|
|
67
|
+
props.assetPaths &&
|
|
68
|
+
props.entry.format === "service-worker"
|
|
69
|
+
) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
"You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
|
|
72
|
+
);
|
|
73
|
+
}
|
|
68
74
|
|
|
69
|
-
|
|
75
|
+
if (props.bindings.wasm_modules && props.entry.format === "modules") {
|
|
76
|
+
throw new Error(
|
|
77
|
+
"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
70
80
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
if (props.bindings.text_blobs && props.entry.format === "modules") {
|
|
82
|
+
throw new Error(
|
|
83
|
+
"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml"
|
|
84
|
+
);
|
|
85
|
+
}
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
if (props.bindings.data_blobs && props.entry.format === "modules") {
|
|
88
|
+
throw new Error(
|
|
89
|
+
"You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml"
|
|
90
|
+
);
|
|
91
|
+
}
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml"
|
|
86
|
-
);
|
|
87
|
-
}
|
|
93
|
+
// only load the UI if we're running in a supported environment
|
|
94
|
+
const { isRawModeSupported } = useStdin();
|
|
88
95
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
return props.showInteractiveDevSession ?? isRawModeSupported ? (
|
|
97
|
+
<InteractiveDevSession {...props} />
|
|
98
|
+
) : (
|
|
99
|
+
<DevSession {...props} local={props.initialMode === "local"} />
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function InteractiveDevSession(props: DevProps) {
|
|
104
|
+
const toggles = useHotkeys(
|
|
105
|
+
{
|
|
106
|
+
local: props.initialMode === "local",
|
|
107
|
+
tunnel: false,
|
|
108
|
+
},
|
|
109
|
+
props.port,
|
|
110
|
+
props.ip,
|
|
111
|
+
props.inspectorPort,
|
|
112
|
+
props.localProtocol
|
|
113
|
+
);
|
|
94
114
|
|
|
95
|
-
|
|
96
|
-
entry: props.entry,
|
|
97
|
-
destination: directory,
|
|
98
|
-
staticRoot: props.public,
|
|
99
|
-
jsxFactory: props.jsxFactory,
|
|
100
|
-
rules: props.rules,
|
|
101
|
-
jsxFragment: props.jsxFragment,
|
|
102
|
-
serveAssetsFromWorker: !!props.public,
|
|
103
|
-
tsconfig: props.tsconfig,
|
|
104
|
-
minify: props.minify,
|
|
105
|
-
nodeCompat: props.nodeCompat,
|
|
106
|
-
});
|
|
115
|
+
useTunnel(toggles.tunnel);
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
return (
|
|
118
|
+
<>
|
|
119
|
+
<DevSession {...props} local={toggles.local} />
|
|
120
|
+
<Box borderStyle="round" paddingLeft={1} paddingRight={1}>
|
|
121
|
+
<Text bold={true}>[b]</Text>
|
|
122
|
+
<Text> open a browser, </Text>
|
|
123
|
+
<Text bold={true}>[d]</Text>
|
|
124
|
+
<Text> open Devtools, </Text>
|
|
125
|
+
<Text bold={true}>[l]</Text>
|
|
126
|
+
<Text> {toggles.local ? "turn off" : "turn on"} local mode, </Text>
|
|
127
|
+
<Text bold={true}>[c]</Text>
|
|
128
|
+
<Text> clear console, </Text>
|
|
129
|
+
<Text bold={true}>[x]</Text>
|
|
130
|
+
<Text> to exit</Text>
|
|
131
|
+
</Box>
|
|
132
|
+
</>
|
|
133
|
+
);
|
|
120
134
|
}
|
|
121
135
|
|
|
122
|
-
type
|
|
123
|
-
|
|
124
|
-
bundle: EsbuildBundle | undefined;
|
|
136
|
+
type DevSessionProps = DevProps & {
|
|
137
|
+
local: boolean;
|
|
125
138
|
};
|
|
126
139
|
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
local: props.initialMode === "local",
|
|
131
|
-
tunnel: false,
|
|
132
|
-
},
|
|
133
|
-
props.port,
|
|
134
|
-
props.ip,
|
|
135
|
-
props.inspectorPort,
|
|
136
|
-
props.localProtocol
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
useTunnel(toggles.tunnel);
|
|
140
|
+
function DevSession(props: DevSessionProps) {
|
|
141
|
+
useCustomBuild(props.entry, props.build);
|
|
140
142
|
|
|
141
|
-
|
|
142
|
-
<>
|
|
143
|
-
<DevSession {...props} local={toggles.local} />
|
|
144
|
-
<Box borderStyle="round" paddingLeft={1} paddingRight={1}>
|
|
145
|
-
<Text bold={true}>[b]</Text>
|
|
146
|
-
<Text> open a browser, </Text>
|
|
147
|
-
<Text bold={true}>[d]</Text>
|
|
148
|
-
<Text> open Devtools, </Text>
|
|
149
|
-
<Text bold={true}>[l]</Text>
|
|
150
|
-
<Text> {toggles.local ? "turn off" : "turn on"} local mode, </Text>
|
|
151
|
-
<Text bold={true}>[c]</Text>
|
|
152
|
-
<Text> clear console, </Text>
|
|
153
|
-
<Text bold={true}>[x]</Text>
|
|
154
|
-
<Text> to exit</Text>
|
|
155
|
-
</Box>
|
|
156
|
-
</>
|
|
157
|
-
);
|
|
158
|
-
}
|
|
143
|
+
const directory = useTmpDir();
|
|
159
144
|
|
|
160
|
-
|
|
145
|
+
const bundle = useEsbuild({
|
|
146
|
+
entry: props.entry,
|
|
147
|
+
destination: directory,
|
|
148
|
+
jsxFactory: props.jsxFactory,
|
|
149
|
+
rules: props.rules,
|
|
150
|
+
jsxFragment: props.jsxFragment,
|
|
151
|
+
serveAssetsFromWorker: Boolean(
|
|
152
|
+
props.assetPaths && !props.isWorkersSite && props.local
|
|
153
|
+
),
|
|
154
|
+
tsconfig: props.tsconfig,
|
|
155
|
+
minify: props.minify,
|
|
156
|
+
nodeCompat: props.nodeCompat,
|
|
157
|
+
define: props.define,
|
|
158
|
+
noBundle: props.noBundle,
|
|
159
|
+
});
|
|
161
160
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
161
|
+
return props.local ? (
|
|
162
|
+
<Local
|
|
163
|
+
name={props.name}
|
|
164
|
+
bundle={bundle}
|
|
165
|
+
format={props.entry.format}
|
|
166
|
+
compatibilityDate={props.compatibilityDate}
|
|
167
|
+
compatibilityFlags={props.compatibilityFlags}
|
|
168
|
+
bindings={props.bindings}
|
|
169
|
+
assetPaths={props.assetPaths}
|
|
170
|
+
isWorkersSite={props.isWorkersSite}
|
|
171
|
+
port={props.port}
|
|
172
|
+
ip={props.ip}
|
|
173
|
+
rules={props.rules}
|
|
174
|
+
inspectorPort={props.inspectorPort}
|
|
175
|
+
enableLocalPersistence={props.enableLocalPersistence}
|
|
176
|
+
crons={props.crons}
|
|
177
|
+
localProtocol={props.localProtocol}
|
|
178
|
+
localUpstream={props.localUpstream}
|
|
179
|
+
logLevel={props.logLevel}
|
|
180
|
+
inspect={props.inspect}
|
|
181
|
+
onReady={props.onReady}
|
|
182
|
+
/>
|
|
183
|
+
) : (
|
|
184
|
+
<Remote
|
|
185
|
+
name={props.name}
|
|
186
|
+
bundle={bundle}
|
|
187
|
+
format={props.entry.format}
|
|
188
|
+
accountId={props.accountId}
|
|
189
|
+
bindings={props.bindings}
|
|
190
|
+
assetPaths={props.assetPaths}
|
|
191
|
+
isWorkersSite={props.isWorkersSite}
|
|
192
|
+
port={props.port}
|
|
193
|
+
ip={props.ip}
|
|
194
|
+
localProtocol={props.localProtocol}
|
|
195
|
+
inspectorPort={props.inspectorPort}
|
|
196
|
+
compatibilityDate={props.compatibilityDate}
|
|
197
|
+
compatibilityFlags={props.compatibilityFlags}
|
|
198
|
+
usageModel={props.usageModel}
|
|
199
|
+
env={props.env}
|
|
200
|
+
legacyEnv={props.legacyEnv}
|
|
201
|
+
zone={props.zone}
|
|
202
|
+
host={props.host}
|
|
203
|
+
routes={props.routes}
|
|
204
|
+
onReady={props.onReady}
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
202
207
|
}
|
|
203
208
|
|
|
204
209
|
export interface DirectorySyncResult {
|
|
205
|
-
|
|
206
|
-
|
|
210
|
+
name: string;
|
|
211
|
+
removeCallback: () => void;
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
function useTmpDir(): string | undefined {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
215
|
+
const [directory, setDirectory] = useState<DirectorySyncResult>();
|
|
216
|
+
const handleError = useErrorHandler();
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
let dir: DirectorySyncResult | undefined;
|
|
219
|
+
try {
|
|
220
|
+
dir = tmp.dirSync({ unsafeCleanup: true });
|
|
221
|
+
setDirectory(dir);
|
|
222
|
+
return;
|
|
223
|
+
} catch (err) {
|
|
224
|
+
logger.error(
|
|
225
|
+
"Failed to create temporary directory to store built files."
|
|
226
|
+
);
|
|
227
|
+
handleError(err);
|
|
228
|
+
}
|
|
229
|
+
return () => {
|
|
230
|
+
dir?.removeCallback();
|
|
231
|
+
};
|
|
232
|
+
}, [handleError]);
|
|
233
|
+
return directory?.name;
|
|
229
234
|
}
|
|
230
235
|
|
|
231
|
-
function useCustomBuild(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
//TODO: we should buffer requests to the proxy until this completes
|
|
250
|
-
logger.log(`The file ${filePath} changed, restarting build...`);
|
|
251
|
-
runCustomBuild(expectedEntry.file, relativeFile, build).catch((err) => {
|
|
252
|
-
logger.error("Custom build failed:", err);
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
}
|
|
236
|
+
function useCustomBuild(expectedEntry: Entry, build: Config["build"]): void {
|
|
237
|
+
useEffect(() => {
|
|
238
|
+
if (!build.command) return;
|
|
239
|
+
let watcher: ReturnType<typeof watch> | undefined;
|
|
240
|
+
if (build.watch_dir) {
|
|
241
|
+
watcher = watch(build.watch_dir, {
|
|
242
|
+
persistent: true,
|
|
243
|
+
ignoreInitial: true,
|
|
244
|
+
}).on("all", (_event, filePath) => {
|
|
245
|
+
const relativeFile =
|
|
246
|
+
path.relative(expectedEntry.directory, expectedEntry.file) || ".";
|
|
247
|
+
//TODO: we should buffer requests to the proxy until this completes
|
|
248
|
+
logger.log(`The file ${filePath} changed, restarting build...`);
|
|
249
|
+
runCustomBuild(expectedEntry.file, relativeFile, build).catch((err) => {
|
|
250
|
+
logger.error("Custom build failed:", err);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
256
254
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
255
|
+
return () => {
|
|
256
|
+
watcher?.close();
|
|
257
|
+
};
|
|
258
|
+
}, [build, expectedEntry]);
|
|
261
259
|
}
|
|
262
260
|
|
|
263
261
|
function sleep(period: number) {
|
|
264
|
-
|
|
262
|
+
return new Promise((resolve) => setTimeout(resolve, period));
|
|
265
263
|
}
|
|
266
264
|
const SLEEP_DURATION = 2000;
|
|
267
265
|
// really need a first class api for this
|
|
268
266
|
const hostNameRegex = /userHostname="(.*)"/g;
|
|
269
267
|
async function findTunnelHostname() {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
268
|
+
let hostName: string | undefined;
|
|
269
|
+
while (!hostName) {
|
|
270
|
+
try {
|
|
271
|
+
const resp = await fetch("http://localhost:8789/metrics");
|
|
272
|
+
const data = await resp.text();
|
|
273
|
+
const matches = Array.from(data.matchAll(hostNameRegex));
|
|
274
|
+
hostName = matches[0][1];
|
|
275
|
+
} catch (err) {
|
|
276
|
+
await sleep(SLEEP_DURATION);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return hostName;
|
|
282
280
|
}
|
|
283
281
|
|
|
284
282
|
/**
|
|
@@ -286,134 +284,134 @@ async function findTunnelHostname() {
|
|
|
286
284
|
* We've disabled this for now until we figure out a better user experience.
|
|
287
285
|
*/
|
|
288
286
|
function useTunnel(toggle: boolean) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
287
|
+
const tunnel = useRef<ReturnType<typeof spawn>>();
|
|
288
|
+
const removeSignalExitListener = useRef<() => void>();
|
|
289
|
+
// TODO: test if cloudflared is available, if not
|
|
290
|
+
// point them to a url where they can get docs to install it
|
|
291
|
+
useEffect(() => {
|
|
292
|
+
async function startTunnel() {
|
|
293
|
+
if (toggle) {
|
|
294
|
+
try {
|
|
295
|
+
await commandExists("cloudflared");
|
|
296
|
+
} catch (e) {
|
|
297
|
+
logger.warn(
|
|
298
|
+
"To share your worker on the Internet, please install `cloudflared` from https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation"
|
|
299
|
+
);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
logger.log("⎔ Starting a tunnel...");
|
|
303
|
+
tunnel.current = spawn("cloudflared", [
|
|
304
|
+
"tunnel",
|
|
305
|
+
"--url",
|
|
306
|
+
"http://localhost:8787",
|
|
307
|
+
"--metrics",
|
|
308
|
+
"localhost:8789",
|
|
309
|
+
]);
|
|
312
310
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
311
|
+
tunnel.current.on("close", (code) => {
|
|
312
|
+
if (code) {
|
|
313
|
+
logger.log(`Tunnel process exited with code ${code}`);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
318
316
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
317
|
+
removeSignalExitListener.current = onExit((_code, _signal) => {
|
|
318
|
+
logger.log("⎔ Shutting down local tunnel.");
|
|
319
|
+
tunnel.current?.kill();
|
|
320
|
+
tunnel.current = undefined;
|
|
321
|
+
});
|
|
324
322
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
323
|
+
const hostName = await findTunnelHostname();
|
|
324
|
+
await clipboardy.write(hostName);
|
|
325
|
+
logger.log(`⬣ Sharing at ${hostName}, copied to clipboard.`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
330
328
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
329
|
+
startTunnel().catch(async (err) => {
|
|
330
|
+
logger.error("tunnel:", err);
|
|
331
|
+
});
|
|
334
332
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
333
|
+
return () => {
|
|
334
|
+
if (tunnel.current) {
|
|
335
|
+
logger.log("⎔ Shutting down tunnel.");
|
|
336
|
+
tunnel.current?.kill();
|
|
337
|
+
tunnel.current = undefined;
|
|
338
|
+
removeSignalExitListener.current && removeSignalExitListener.current();
|
|
339
|
+
removeSignalExitListener.current = undefined;
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}, [toggle]);
|
|
345
343
|
}
|
|
346
344
|
|
|
347
345
|
type useHotkeysInitialState = {
|
|
348
|
-
|
|
349
|
-
|
|
346
|
+
local: boolean;
|
|
347
|
+
tunnel: boolean;
|
|
350
348
|
};
|
|
351
349
|
function useHotkeys(
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
350
|
+
initial: useHotkeysInitialState,
|
|
351
|
+
port: number,
|
|
352
|
+
ip: string,
|
|
353
|
+
inspectorPort: number,
|
|
354
|
+
localProtocol: "http" | "https"
|
|
357
355
|
) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
356
|
+
// UGH, we should put port in context instead
|
|
357
|
+
const [toggles, setToggles] = useState(initial);
|
|
358
|
+
const { exit } = useApp();
|
|
359
|
+
useInput(
|
|
360
|
+
async (
|
|
361
|
+
input,
|
|
362
|
+
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
363
|
+
key
|
|
364
|
+
) => {
|
|
365
|
+
switch (input.toLowerCase()) {
|
|
366
|
+
// clear console
|
|
367
|
+
case "c":
|
|
368
|
+
console.clear();
|
|
369
|
+
// This console.log causes Ink to re-render the `DevSession` component.
|
|
370
|
+
// Couldn't find a better way to tell it to do so...
|
|
371
|
+
console.log();
|
|
372
|
+
break;
|
|
373
|
+
// open browser
|
|
374
|
+
case "b": {
|
|
375
|
+
await openInBrowser(`${localProtocol}://${ip}:${port}`);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
// toggle inspector
|
|
379
|
+
case "d": {
|
|
380
|
+
await openInspector(inspectorPort);
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
// toggle local
|
|
384
|
+
case "l":
|
|
385
|
+
setToggles((previousToggles) => ({
|
|
386
|
+
...previousToggles,
|
|
387
|
+
local: !previousToggles.local,
|
|
388
|
+
}));
|
|
389
|
+
break;
|
|
390
|
+
// shut down
|
|
391
|
+
case "q":
|
|
392
|
+
case "x":
|
|
393
|
+
exit();
|
|
394
|
+
break;
|
|
395
|
+
default:
|
|
396
|
+
// nothing?
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
return toggles;
|
|
404
402
|
}
|
|
405
403
|
|
|
406
404
|
function ErrorFallback(props: { error: Error }) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
405
|
+
const { exit } = useApp();
|
|
406
|
+
useEffect(() => exit(props.error));
|
|
407
|
+
return (
|
|
408
|
+
<>
|
|
409
|
+
<Text>Something went wrong:</Text>
|
|
410
|
+
<Text>{props.error.stack}</Text>
|
|
411
|
+
</>
|
|
412
|
+
);
|
|
415
413
|
}
|
|
416
414
|
|
|
417
415
|
export default withErrorBoundary(DevImplementation, {
|
|
418
|
-
|
|
416
|
+
FallbackComponent: ErrorFallback,
|
|
419
417
|
});
|