wrangler 0.0.0-ea7ee45 → 0.0.0-eab9542
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/bin/wrangler.js +6 -3
- package/miniflare-dist/index.mjs +1 -0
- package/package.json +1 -1
- package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
- package/src/__tests__/config-cache.test.ts +6 -0
- package/src/__tests__/configuration.test.ts +117 -0
- package/src/__tests__/dev.test.tsx +1 -1
- package/src/__tests__/publish.test.ts +59 -3
- package/src/__tests__/pubsub.test.ts +91 -0
- package/src/api/dev.ts +16 -3
- package/src/cli.ts +1 -1
- package/src/config/environment.ts +23 -0
- package/src/config/index.ts +13 -0
- package/src/config/validation.ts +52 -0
- package/src/config-cache.ts +70 -31
- package/src/create-worker-upload-form.ts +9 -0
- package/src/dev/dev.tsx +2 -2
- package/src/dev/local.tsx +24 -22
- package/src/dev/remote.tsx +20 -5
- package/src/dev/use-esbuild.ts +6 -6
- package/src/dev.tsx +23 -11
- package/src/index.tsx +7 -7
- package/src/is-interactive.ts +12 -0
- package/src/miniflare-cli/index.ts +1 -0
- package/src/publish.ts +4 -3
- package/src/pubsub/pubsub-commands.tsx +386 -403
- package/src/user/choose-account.tsx +2 -2
- package/src/user/user.tsx +53 -22
- package/src/worker.ts +6 -0
- package/wrangler-dist/cli.js +15146 -15048
package/src/config/validation.ts
CHANGED
|
@@ -832,6 +832,7 @@ function normalizeAndValidateEnvironment(
|
|
|
832
832
|
|
|
833
833
|
experimental(diagnostics, rawEnv, "unsafe");
|
|
834
834
|
experimental(diagnostics, rawEnv, "services");
|
|
835
|
+
experimental(diagnostics, rawEnv, "worker_namespaces");
|
|
835
836
|
|
|
836
837
|
const route = normalizeAndValidateRoute(diagnostics, topLevelEnv, rawEnv);
|
|
837
838
|
|
|
@@ -1017,6 +1018,16 @@ function normalizeAndValidateEnvironment(
|
|
|
1017
1018
|
validateBindingArray(envName, validateServiceBinding),
|
|
1018
1019
|
[]
|
|
1019
1020
|
),
|
|
1021
|
+
worker_namespaces: notInheritable(
|
|
1022
|
+
diagnostics,
|
|
1023
|
+
topLevelEnv,
|
|
1024
|
+
rawConfig,
|
|
1025
|
+
rawEnv,
|
|
1026
|
+
envName,
|
|
1027
|
+
"worker_namespaces",
|
|
1028
|
+
validateBindingArray(envName, validateWorkerNamespaceBinding),
|
|
1029
|
+
[]
|
|
1030
|
+
),
|
|
1020
1031
|
unsafe: notInheritable(
|
|
1021
1032
|
diagnostics,
|
|
1022
1033
|
topLevelEnv,
|
|
@@ -1030,6 +1041,14 @@ function normalizeAndValidateEnvironment(
|
|
|
1030
1041
|
}
|
|
1031
1042
|
),
|
|
1032
1043
|
zone_id: rawEnv.zone_id,
|
|
1044
|
+
no_bundle: inheritable(
|
|
1045
|
+
diagnostics,
|
|
1046
|
+
topLevelEnv,
|
|
1047
|
+
rawEnv,
|
|
1048
|
+
"no_bundle",
|
|
1049
|
+
isBoolean,
|
|
1050
|
+
undefined
|
|
1051
|
+
),
|
|
1033
1052
|
minify: inheritable(
|
|
1034
1053
|
diagnostics,
|
|
1035
1054
|
topLevelEnv,
|
|
@@ -1656,6 +1675,7 @@ const validateBindingsHaveUniqueNames = (
|
|
|
1656
1675
|
|
|
1657
1676
|
return !hasDuplicates;
|
|
1658
1677
|
};
|
|
1678
|
+
|
|
1659
1679
|
const validateServiceBinding: ValidatorFn = (diagnostics, field, value) => {
|
|
1660
1680
|
if (typeof value !== "object" || value === null) {
|
|
1661
1681
|
diagnostics.errors.push(
|
|
@@ -1691,3 +1711,35 @@ const validateServiceBinding: ValidatorFn = (diagnostics, field, value) => {
|
|
|
1691
1711
|
}
|
|
1692
1712
|
return isValid;
|
|
1693
1713
|
};
|
|
1714
|
+
|
|
1715
|
+
const validateWorkerNamespaceBinding: ValidatorFn = (
|
|
1716
|
+
diagnostics,
|
|
1717
|
+
field,
|
|
1718
|
+
value
|
|
1719
|
+
) => {
|
|
1720
|
+
if (typeof value !== "object" || value === null) {
|
|
1721
|
+
diagnostics.errors.push(
|
|
1722
|
+
`"${field}" binding should be objects, but got ${JSON.stringify(value)}`
|
|
1723
|
+
);
|
|
1724
|
+
return false;
|
|
1725
|
+
}
|
|
1726
|
+
let isValid = true;
|
|
1727
|
+
// Worker namespace bindings must have a binding, and a namespace.
|
|
1728
|
+
if (!isRequiredProperty(value, "binding", "string")) {
|
|
1729
|
+
diagnostics.errors.push(
|
|
1730
|
+
`"${field}" should have a string "binding" field but got ${JSON.stringify(
|
|
1731
|
+
value
|
|
1732
|
+
)}.`
|
|
1733
|
+
);
|
|
1734
|
+
isValid = false;
|
|
1735
|
+
}
|
|
1736
|
+
if (!isRequiredProperty(value, "namespace", "string")) {
|
|
1737
|
+
diagnostics.errors.push(
|
|
1738
|
+
`"${field}" should have a string "namespace" field but got ${JSON.stringify(
|
|
1739
|
+
value
|
|
1740
|
+
)}.`
|
|
1741
|
+
);
|
|
1742
|
+
isValid = false;
|
|
1743
|
+
}
|
|
1744
|
+
return isValid;
|
|
1745
|
+
};
|
package/src/config-cache.ts
CHANGED
|
@@ -1,44 +1,83 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
2
|
-
import
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { findUpSync } from "find-up";
|
|
4
|
+
import isInteractive from "./is-interactive";
|
|
5
|
+
import { logger } from "./logger";
|
|
3
6
|
|
|
4
7
|
let cacheMessageShown = false;
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
let __cacheFolder: string | null;
|
|
10
|
+
function getCacheFolder() {
|
|
11
|
+
if (__cacheFolder || __cacheFolder === null) return __cacheFolder;
|
|
7
12
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
)
|
|
13
|
-
|
|
13
|
+
const closestNodeModulesDirectory = findUpSync("node_modules", {
|
|
14
|
+
type: "directory",
|
|
15
|
+
});
|
|
16
|
+
__cacheFolder = closestNodeModulesDirectory
|
|
17
|
+
? path.join(closestNodeModulesDirectory, ".cache/wrangler")
|
|
18
|
+
: null;
|
|
19
|
+
|
|
20
|
+
if (!__cacheFolder) {
|
|
21
|
+
logger.debug("No folder available to cache configuration");
|
|
22
|
+
}
|
|
23
|
+
return __cacheFolder;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const arrayFormatter = new Intl.ListFormat("en", {
|
|
27
|
+
style: "long",
|
|
28
|
+
type: "conjunction",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function showCacheMessage(fields: string[], folder: string) {
|
|
32
|
+
if (!cacheMessageShown && isInteractive()) {
|
|
33
|
+
if (fields.length > 0) {
|
|
34
|
+
logger.log(
|
|
35
|
+
`Retrieving cached values for ${arrayFormatter.format(
|
|
36
|
+
fields
|
|
37
|
+
)} from ${path.relative(process.cwd(), folder)}`
|
|
38
|
+
);
|
|
39
|
+
cacheMessageShown = true;
|
|
40
|
+
}
|
|
14
41
|
}
|
|
15
|
-
}
|
|
42
|
+
}
|
|
16
43
|
|
|
17
|
-
export
|
|
44
|
+
export function getConfigCache<T>(fileName: string): Partial<T> {
|
|
18
45
|
try {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
46
|
+
const cacheFolder = getCacheFolder();
|
|
47
|
+
if (cacheFolder) {
|
|
48
|
+
const configCacheLocation = path.join(cacheFolder, fileName);
|
|
49
|
+
const configCache = JSON.parse(
|
|
50
|
+
readFileSync(configCacheLocation, "utf-8")
|
|
51
|
+
);
|
|
52
|
+
showCacheMessage(Object.keys(configCache), cacheFolder);
|
|
53
|
+
return configCache;
|
|
54
|
+
} else return {};
|
|
55
|
+
} catch (err) {
|
|
24
56
|
return {};
|
|
25
57
|
}
|
|
26
|
-
}
|
|
58
|
+
}
|
|
27
59
|
|
|
28
|
-
export
|
|
60
|
+
export function saveToConfigCache<T>(
|
|
29
61
|
fileName: string,
|
|
30
62
|
newValues: Partial<T>
|
|
31
|
-
)
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
63
|
+
): void {
|
|
64
|
+
const cacheFolder = getCacheFolder();
|
|
65
|
+
if (cacheFolder) {
|
|
66
|
+
logger.debug(`Saving to cache: ${JSON.stringify(newValues)}`);
|
|
67
|
+
const configCacheLocation = path.join(cacheFolder, fileName);
|
|
68
|
+
const existingValues = getConfigCache(fileName);
|
|
69
|
+
|
|
70
|
+
mkdirSync(path.dirname(configCacheLocation), { recursive: true });
|
|
71
|
+
writeFileSync(
|
|
72
|
+
configCacheLocation,
|
|
73
|
+
JSON.stringify({ ...existingValues, ...newValues }, null, 2)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function purgeConfigCaches() {
|
|
79
|
+
const cacheFolder = getCacheFolder();
|
|
80
|
+
if (cacheFolder) {
|
|
81
|
+
rmSync(cacheFolder, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -50,6 +50,7 @@ export interface WorkerMetadata {
|
|
|
50
50
|
}
|
|
51
51
|
| { type: "r2_bucket"; name: string; bucket_name: string }
|
|
52
52
|
| { type: "service"; name: string; service: string; environment?: string }
|
|
53
|
+
| { type: "namespace"; name: string; namespace: string }
|
|
53
54
|
)[];
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -116,6 +117,14 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
|
|
|
116
117
|
});
|
|
117
118
|
});
|
|
118
119
|
|
|
120
|
+
bindings.worker_namespaces?.forEach(({ binding, namespace }) => {
|
|
121
|
+
metadataBindings.push({
|
|
122
|
+
name: binding,
|
|
123
|
+
type: "namespace",
|
|
124
|
+
namespace,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
119
128
|
for (const [name, filePath] of Object.entries(bindings.wasm_modules || {})) {
|
|
120
129
|
metadataBindings.push({
|
|
121
130
|
name,
|
package/src/dev/dev.tsx
CHANGED
|
@@ -24,7 +24,7 @@ import type { CfWorkerInit } from "../worker";
|
|
|
24
24
|
|
|
25
25
|
export type DevProps = {
|
|
26
26
|
name: string | undefined;
|
|
27
|
-
|
|
27
|
+
noBundle: boolean;
|
|
28
28
|
entry: Entry;
|
|
29
29
|
port: number;
|
|
30
30
|
ip: string;
|
|
@@ -155,7 +155,7 @@ function DevSession(props: DevSessionProps) {
|
|
|
155
155
|
minify: props.minify,
|
|
156
156
|
nodeCompat: props.nodeCompat,
|
|
157
157
|
define: props.define,
|
|
158
|
-
|
|
158
|
+
noBundle: props.noBundle,
|
|
159
159
|
});
|
|
160
160
|
|
|
161
161
|
return props.local ? (
|
package/src/dev/local.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fork } from "node:child_process";
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
3
|
import { writeFile } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
@@ -13,7 +13,7 @@ import type { AssetPaths } from "../sites";
|
|
|
13
13
|
import type { CfWorkerInit, CfScriptFormat } from "../worker";
|
|
14
14
|
import type { EsbuildBundle } from "./use-esbuild";
|
|
15
15
|
import type { MiniflareOptions } from "miniflare";
|
|
16
|
-
|
|
16
|
+
import type { ChildProcess } from "node:child_process";
|
|
17
17
|
interface LocalProps {
|
|
18
18
|
name: string | undefined;
|
|
19
19
|
bundle: EsbuildBundle | undefined;
|
|
@@ -67,7 +67,7 @@ function useLocalWorker({
|
|
|
67
67
|
logLevel,
|
|
68
68
|
}: LocalProps) {
|
|
69
69
|
// TODO: pass vars via command line
|
|
70
|
-
const local = useRef<
|
|
70
|
+
const local = useRef<ChildProcess>();
|
|
71
71
|
const removeSignalExitListener = useRef<() => void>();
|
|
72
72
|
const [inspectorUrl, setInspectorUrl] = useState<string | undefined>();
|
|
73
73
|
// if we're using local persistence for data, we should use the cwd
|
|
@@ -236,43 +236,45 @@ function useLocalWorker({
|
|
|
236
236
|
__dirname,
|
|
237
237
|
"../miniflare-dist/index.mjs"
|
|
238
238
|
);
|
|
239
|
-
const
|
|
239
|
+
const miniflareOptions = JSON.stringify(options, null);
|
|
240
240
|
|
|
241
241
|
logger.log("⎔ Starting a local server...");
|
|
242
|
-
const
|
|
242
|
+
const nodeOptions = [
|
|
243
243
|
"--experimental-vm-modules", // ensures that Miniflare can run ESM Workers
|
|
244
244
|
"--no-warnings", // hide annoying Node warnings
|
|
245
|
-
miniflareCLIPath,
|
|
246
|
-
optionsArg,
|
|
247
245
|
// "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
|
|
248
246
|
];
|
|
249
247
|
if (inspect) {
|
|
250
|
-
|
|
248
|
+
nodeOptions.push("--inspect"); // start Miniflare listening for a debugger to attach
|
|
251
249
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
250
|
+
const child = (local.current = fork(
|
|
251
|
+
miniflareCLIPath,
|
|
252
|
+
[miniflareOptions],
|
|
253
|
+
{
|
|
254
|
+
cwd: path.dirname(scriptPath),
|
|
255
|
+
execArgv: nodeOptions,
|
|
256
|
+
}
|
|
257
|
+
));
|
|
258
|
+
child.on("message", (message) => {
|
|
259
|
+
if (message === "ready") {
|
|
260
|
+
onReady?.();
|
|
261
|
+
}
|
|
255
262
|
});
|
|
256
|
-
//TODO: instead of being lucky with spawn's timing, have miniflare-cli notify wrangler that it's ready in packages/wrangler/src/miniflare-cli/index.ts, after the mf.startScheduler promise resolves
|
|
257
|
-
if (onReady) {
|
|
258
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
259
|
-
onReady();
|
|
260
|
-
}
|
|
261
263
|
|
|
262
|
-
|
|
264
|
+
child.on("close", (code) => {
|
|
263
265
|
if (code) {
|
|
264
266
|
logger.log(`Miniflare process exited with code ${code}`);
|
|
265
267
|
}
|
|
266
268
|
});
|
|
267
269
|
|
|
268
|
-
|
|
270
|
+
child.stdout?.on("data", (data: Buffer) => {
|
|
269
271
|
process.stdout.write(data);
|
|
270
272
|
});
|
|
271
273
|
|
|
272
274
|
// parse the node inspector url (which may be received in chunks) from stderr
|
|
273
275
|
let stderrData = "";
|
|
274
276
|
let inspectorUrlFound = false;
|
|
275
|
-
|
|
277
|
+
child.stderr?.on("data", (data: Buffer) => {
|
|
276
278
|
if (!inspectorUrlFound) {
|
|
277
279
|
stderrData += data.toString();
|
|
278
280
|
const matches =
|
|
@@ -288,20 +290,20 @@ function useLocalWorker({
|
|
|
288
290
|
process.stderr.write(data);
|
|
289
291
|
});
|
|
290
292
|
|
|
291
|
-
|
|
293
|
+
child.on("exit", (code) => {
|
|
292
294
|
if (code) {
|
|
293
295
|
logger.error(`Miniflare process exited with code ${code}`);
|
|
294
296
|
}
|
|
295
297
|
});
|
|
296
298
|
|
|
297
|
-
|
|
299
|
+
child.on("error", (error: Error) => {
|
|
298
300
|
logger.error(`Miniflare process failed to spawn`);
|
|
299
301
|
logger.error(error);
|
|
300
302
|
});
|
|
301
303
|
|
|
302
304
|
removeSignalExitListener.current = onExit((_code, _signal) => {
|
|
303
305
|
logger.log("⎔ Shutting down local server.");
|
|
304
|
-
|
|
306
|
+
child.kill();
|
|
305
307
|
local.current = undefined;
|
|
306
308
|
});
|
|
307
309
|
}
|
package/src/dev/remote.tsx
CHANGED
|
@@ -11,7 +11,12 @@ import useInspector from "../inspect";
|
|
|
11
11
|
import { logger } from "../logger";
|
|
12
12
|
import { usePreviewServer } from "../proxy";
|
|
13
13
|
import { syncAssets } from "../sites";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ChooseAccount,
|
|
16
|
+
getAccountChoices,
|
|
17
|
+
requireApiToken,
|
|
18
|
+
saveAccountToCache,
|
|
19
|
+
} from "../user";
|
|
15
20
|
import type { Route } from "../config/environment";
|
|
16
21
|
import type {
|
|
17
22
|
CfPreviewToken,
|
|
@@ -48,7 +53,7 @@ export function Remote(props: {
|
|
|
48
53
|
zone: string | undefined;
|
|
49
54
|
host: string | undefined;
|
|
50
55
|
routes: Route[] | undefined;
|
|
51
|
-
onReady?: () => void;
|
|
56
|
+
onReady?: (() => void) | undefined;
|
|
52
57
|
}) {
|
|
53
58
|
const [accountId, setAccountId] = useState(props.accountId);
|
|
54
59
|
const accountChoicesRef = useRef<Promise<ChooseAccountItem[]>>();
|
|
@@ -96,13 +101,20 @@ export function Remote(props: {
|
|
|
96
101
|
// This effect handles the async step of fetching the available accounts for the current user.
|
|
97
102
|
// If only one account is available then it is just used by calling `setAccountId()`.
|
|
98
103
|
useEffect(() => {
|
|
99
|
-
if (
|
|
104
|
+
if (
|
|
105
|
+
accountChoicesRef.current !== undefined ||
|
|
106
|
+
props.accountId !== undefined
|
|
107
|
+
) {
|
|
100
108
|
return;
|
|
101
109
|
}
|
|
102
110
|
accountChoicesRef.current = getAccountChoices();
|
|
103
111
|
accountChoicesRef.current.then(
|
|
104
112
|
(accounts) => {
|
|
105
113
|
if (accounts.length === 1) {
|
|
114
|
+
saveAccountToCache({
|
|
115
|
+
id: accounts[0].id,
|
|
116
|
+
name: accounts[0].name,
|
|
117
|
+
});
|
|
106
118
|
setAccountId(accounts[0].id);
|
|
107
119
|
} else {
|
|
108
120
|
setAccountChoices(accounts);
|
|
@@ -119,7 +131,10 @@ export function Remote(props: {
|
|
|
119
131
|
return accountId === undefined && accountChoices !== undefined ? (
|
|
120
132
|
<ChooseAccount
|
|
121
133
|
accounts={accountChoices}
|
|
122
|
-
onSelect={(
|
|
134
|
+
onSelect={(selectedAccount) => {
|
|
135
|
+
saveAccountToCache(selectedAccount);
|
|
136
|
+
setAccountId(selectedAccount.id);
|
|
137
|
+
}}
|
|
123
138
|
onError={(err) => errorHandler(err)}
|
|
124
139
|
></ChooseAccount>
|
|
125
140
|
) : null;
|
|
@@ -143,7 +158,7 @@ export function useWorker(props: {
|
|
|
143
158
|
zone: string | undefined;
|
|
144
159
|
host: string | undefined;
|
|
145
160
|
routes: Route[] | undefined;
|
|
146
|
-
onReady
|
|
161
|
+
onReady: (() => void) | undefined;
|
|
147
162
|
}): CfPreviewToken | undefined {
|
|
148
163
|
const {
|
|
149
164
|
name,
|
package/src/dev/use-esbuild.ts
CHANGED
|
@@ -28,7 +28,7 @@ export function useEsbuild({
|
|
|
28
28
|
minify,
|
|
29
29
|
nodeCompat,
|
|
30
30
|
define,
|
|
31
|
-
|
|
31
|
+
noBundle,
|
|
32
32
|
}: {
|
|
33
33
|
entry: Entry;
|
|
34
34
|
destination: string | undefined;
|
|
@@ -40,7 +40,7 @@ export function useEsbuild({
|
|
|
40
40
|
tsconfig: string | undefined;
|
|
41
41
|
minify: boolean | undefined;
|
|
42
42
|
nodeCompat: boolean | undefined;
|
|
43
|
-
|
|
43
|
+
noBundle: boolean;
|
|
44
44
|
}): EsbuildBundle | undefined {
|
|
45
45
|
const [bundle, setBundle] = useState<EsbuildBundle>();
|
|
46
46
|
const { exit } = useApp();
|
|
@@ -76,7 +76,7 @@ export function useEsbuild({
|
|
|
76
76
|
bundleType,
|
|
77
77
|
modules,
|
|
78
78
|
stop,
|
|
79
|
-
}: Awaited<ReturnType<typeof bundleWorker>> =
|
|
79
|
+
}: Awaited<ReturnType<typeof bundleWorker>> = noBundle
|
|
80
80
|
? {
|
|
81
81
|
modules: [],
|
|
82
82
|
resolvedEntryPointPath: entry.file,
|
|
@@ -99,9 +99,9 @@ export function useEsbuild({
|
|
|
99
99
|
// Capture the `stop()` method to use as the `useEffect()` destructor.
|
|
100
100
|
stopWatching = stop;
|
|
101
101
|
|
|
102
|
-
// if "
|
|
102
|
+
// if "noBundle" is true, then we need to manually watch the entry point and
|
|
103
103
|
// trigger "builds" when it changes
|
|
104
|
-
if (
|
|
104
|
+
if (noBundle) {
|
|
105
105
|
const watcher = watch(entry.file, {
|
|
106
106
|
persistent: true,
|
|
107
107
|
}).on("change", async (_event) => {
|
|
@@ -141,7 +141,7 @@ export function useEsbuild({
|
|
|
141
141
|
rules,
|
|
142
142
|
tsconfig,
|
|
143
143
|
exit,
|
|
144
|
-
|
|
144
|
+
noBundle,
|
|
145
145
|
minify,
|
|
146
146
|
nodeCompat,
|
|
147
147
|
define,
|
package/src/dev.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { watch } from "chokidar";
|
|
|
3
3
|
import getPort from "get-port";
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
import React from "react";
|
|
6
|
+
import { fetch } from "undici";
|
|
6
7
|
import { findWranglerToml, printBindings, readConfig } from "./config";
|
|
7
8
|
import Dev from "./dev/dev";
|
|
8
9
|
import { getVarsForDev } from "./dev/dev-vars";
|
|
@@ -10,6 +11,7 @@ import { getVarsForDev } from "./dev/dev-vars";
|
|
|
10
11
|
import { getEntry } from "./entry";
|
|
11
12
|
import { logger } from "./logger";
|
|
12
13
|
import { getAssetPaths, getSiteAssetPaths } from "./sites";
|
|
14
|
+
import { getAccountFromCache } from "./user";
|
|
13
15
|
import { getZoneIdFromHost, getZoneForRoute, getHostFromRoute } from "./zones";
|
|
14
16
|
import {
|
|
15
17
|
printWranglerBanner,
|
|
@@ -23,12 +25,15 @@ import {
|
|
|
23
25
|
|
|
24
26
|
import type { Config } from "./config";
|
|
25
27
|
import type { Route } from "./config/environment";
|
|
28
|
+
import type { CfWorkerInit } from "./worker";
|
|
29
|
+
import type { RequestInit } from "undici";
|
|
26
30
|
import type { Argv, ArgumentsCamelCase } from "yargs";
|
|
27
31
|
|
|
28
32
|
interface DevArgs {
|
|
29
33
|
config?: string;
|
|
30
34
|
script?: string;
|
|
31
35
|
name?: string;
|
|
36
|
+
bundle?: boolean;
|
|
32
37
|
build?: boolean;
|
|
33
38
|
format?: string;
|
|
34
39
|
env?: string;
|
|
@@ -74,17 +79,16 @@ export function devOptions(yargs: Argv): Argv<DevArgs> {
|
|
|
74
79
|
type: "string",
|
|
75
80
|
requiresArg: true,
|
|
76
81
|
})
|
|
77
|
-
// We want to have a --no-
|
|
78
|
-
// we also have a --
|
|
79
|
-
// So we make a --
|
|
82
|
+
// We want to have a --no-bundle flag, but yargs requires that
|
|
83
|
+
// we also have a --bundle flag (that it adds the --no to by itself)
|
|
84
|
+
// So we make a --bundle flag, but hide it, and then add a --no-bundle flag
|
|
80
85
|
// that's visible to the user but doesn't "do" anything.
|
|
81
|
-
.option("
|
|
86
|
+
.option("bundle", {
|
|
82
87
|
describe: "Run wrangler's compilation step before publishing",
|
|
83
88
|
type: "boolean",
|
|
84
|
-
default: true,
|
|
85
89
|
hidden: true,
|
|
86
90
|
})
|
|
87
|
-
.option("no-
|
|
91
|
+
.option("no-bundle", {
|
|
88
92
|
describe: "Skip internal build steps and directly publish script",
|
|
89
93
|
type: "boolean",
|
|
90
94
|
default: false,
|
|
@@ -368,7 +372,9 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
368
372
|
}
|
|
369
373
|
|
|
370
374
|
// eslint-disable-next-line no-inner-declarations
|
|
371
|
-
async function getBindings(
|
|
375
|
+
async function getBindings(
|
|
376
|
+
configParam: Config
|
|
377
|
+
): Promise<CfWorkerInit["bindings"]> {
|
|
372
378
|
return {
|
|
373
379
|
kv_namespaces: configParam.kv_namespaces?.map(
|
|
374
380
|
({ binding, preview_id, id: _id }) => {
|
|
@@ -412,6 +418,7 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
412
418
|
};
|
|
413
419
|
}
|
|
414
420
|
),
|
|
421
|
+
worker_namespaces: configParam.worker_namespaces,
|
|
415
422
|
services: configParam.services,
|
|
416
423
|
unsafe: configParam.unsafe?.bindings,
|
|
417
424
|
};
|
|
@@ -453,7 +460,7 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
453
460
|
return (
|
|
454
461
|
<Dev
|
|
455
462
|
name={getScriptName({ name: args.name, env: args.env }, config)}
|
|
456
|
-
|
|
463
|
+
noBundle={!(args.bundle ?? !config.no_bundle)}
|
|
457
464
|
entry={entry}
|
|
458
465
|
env={args.env}
|
|
459
466
|
zone={zoneId}
|
|
@@ -475,7 +482,7 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
475
482
|
enableLocalPersistence={
|
|
476
483
|
args["experimental-enable-local-persistence"] || false
|
|
477
484
|
}
|
|
478
|
-
accountId={config.account_id}
|
|
485
|
+
accountId={config.account_id || getAccountFromCache()?.id}
|
|
479
486
|
assetPaths={assetPaths}
|
|
480
487
|
port={args.port || config.dev.port || (await getLocalPort())}
|
|
481
488
|
ip={args.ip || config.dev.ip}
|
|
@@ -505,9 +512,14 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
505
512
|
watcher,
|
|
506
513
|
stop: async () => {
|
|
507
514
|
devReactElement.unmount();
|
|
508
|
-
await devReactElement.waitUntilExit();
|
|
509
515
|
await watcher?.close();
|
|
510
|
-
|
|
516
|
+
},
|
|
517
|
+
fetch: async (init?: RequestInit) => {
|
|
518
|
+
//TODO: we are not guaranteed to be assigned this port, we should fix this ASAP
|
|
519
|
+
const port = args.port || config.dev.port || (await getLocalPort());
|
|
520
|
+
const address = args.ip || config.dev.ip || "localhost";
|
|
521
|
+
|
|
522
|
+
return await fetch(`http://${address}:${port}/`, init);
|
|
511
523
|
},
|
|
512
524
|
};
|
|
513
525
|
} finally {
|
package/src/index.tsx
CHANGED
|
@@ -372,17 +372,16 @@ function createCLIParser(argv: string[]) {
|
|
|
372
372
|
type: "string",
|
|
373
373
|
requiresArg: true,
|
|
374
374
|
})
|
|
375
|
-
// We want to have a --no-
|
|
376
|
-
// we also have a --
|
|
377
|
-
// So we make a --
|
|
375
|
+
// We want to have a --no-bundle flag, but yargs requires that
|
|
376
|
+
// we also have a --bundle flag (that it adds the --no to by itself)
|
|
377
|
+
// So we make a --bundle flag, but hide it, and then add a --no-bundle flag
|
|
378
378
|
// that's visible to the user but doesn't "do" anything.
|
|
379
|
-
.option("
|
|
379
|
+
.option("bundle", {
|
|
380
380
|
describe: "Run wrangler's compilation step before publishing",
|
|
381
381
|
type: "boolean",
|
|
382
|
-
default: true,
|
|
383
382
|
hidden: true,
|
|
384
383
|
})
|
|
385
|
-
.option("no-
|
|
384
|
+
.option("no-bundle", {
|
|
386
385
|
describe: "Skip internal build steps and directly publish script",
|
|
387
386
|
type: "boolean",
|
|
388
387
|
default: false,
|
|
@@ -564,7 +563,7 @@ function createCLIParser(argv: string[]) {
|
|
|
564
563
|
isWorkersSite: Boolean(args.site || config.site),
|
|
565
564
|
outDir: args.outdir,
|
|
566
565
|
dryRun: args.dryRun,
|
|
567
|
-
|
|
566
|
+
noBundle: !(args.bundle ?? !config.no_bundle),
|
|
568
567
|
});
|
|
569
568
|
}
|
|
570
569
|
);
|
|
@@ -917,6 +916,7 @@ function createCLIParser(argv: string[]) {
|
|
|
917
916
|
wasm_modules: {},
|
|
918
917
|
text_blobs: {},
|
|
919
918
|
data_blobs: {},
|
|
919
|
+
worker_namespaces: [],
|
|
920
920
|
unsafe: [],
|
|
921
921
|
},
|
|
922
922
|
modules: [],
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test whether the process is "interactive".
|
|
3
|
+
* Reasons it may not be interactive: it could be running in CI,
|
|
4
|
+
* or you're piping values from / to another process, etc
|
|
5
|
+
*/
|
|
6
|
+
export default function isInteractive(): boolean {
|
|
7
|
+
try {
|
|
8
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
9
|
+
} catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/src/publish.ts
CHANGED
|
@@ -46,7 +46,7 @@ type Props = {
|
|
|
46
46
|
nodeCompat: boolean | undefined;
|
|
47
47
|
outDir: string | undefined;
|
|
48
48
|
dryRun: boolean | undefined;
|
|
49
|
-
|
|
49
|
+
noBundle: boolean | undefined;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
type RouteObject = ZoneIdRoute | ZoneNameRoute | CustomDomainRoute;
|
|
@@ -341,7 +341,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
|
|
|
341
341
|
);
|
|
342
342
|
}
|
|
343
343
|
try {
|
|
344
|
-
if (props.
|
|
344
|
+
if (props.noBundle) {
|
|
345
345
|
// if we're not building, let's just copy the entry to the destination directory
|
|
346
346
|
const destinationDir =
|
|
347
347
|
typeof destination === "string" ? destination : destination.path;
|
|
@@ -356,7 +356,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
|
|
|
356
356
|
modules,
|
|
357
357
|
resolvedEntryPointPath,
|
|
358
358
|
bundleType,
|
|
359
|
-
}: Awaited<ReturnType<typeof bundleWorker>> = props.
|
|
359
|
+
}: Awaited<ReturnType<typeof bundleWorker>> = props.noBundle
|
|
360
360
|
? // we can skip the whole bundling step and mock a bundle here
|
|
361
361
|
{
|
|
362
362
|
modules: [],
|
|
@@ -426,6 +426,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
|
|
|
426
426
|
durable_objects: config.durable_objects,
|
|
427
427
|
r2_buckets: config.r2_buckets,
|
|
428
428
|
services: config.services,
|
|
429
|
+
worker_namespaces: config.worker_namespaces,
|
|
429
430
|
unsafe: config.unsafe?.bindings,
|
|
430
431
|
};
|
|
431
432
|
|