wrangler 0.0.0-e95e5a0 → 0.0.0-e978986
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/Cloudflare_CA.pem +18 -0
- package/README.md +3 -1
- package/bin/wrangler.js +36 -4
- package/package.json +11 -7
- package/pages/functions/buildPlugin.ts +13 -0
- package/pages/functions/buildWorker.ts +14 -1
- package/pages/functions/template-plugin.ts +3 -2
- package/src/__tests__/configuration.test.ts +336 -87
- package/src/__tests__/dev.test.tsx +243 -25
- package/src/__tests__/helpers/mock-dialogs.ts +41 -1
- package/src/__tests__/index.test.ts +79 -72
- package/src/__tests__/init.test.ts +182 -131
- package/src/__tests__/jest.setup.ts +8 -0
- package/src/__tests__/kv.test.ts +173 -146
- package/src/__tests__/package-manager.test.ts +154 -7
- package/src/__tests__/pages.test.ts +381 -53
- package/src/__tests__/parse.test.ts +8 -0
- package/src/__tests__/publish.test.ts +682 -89
- package/src/__tests__/r2.test.ts +55 -36
- package/src/__tests__/secret.test.ts +39 -4
- package/src/abort.d.ts +3 -0
- package/src/bundle.ts +33 -2
- package/src/cfetch/index.ts +21 -4
- package/src/cfetch/internal.ts +17 -9
- package/src/config/config.ts +1 -1
- package/src/config/environment.ts +40 -14
- package/src/config/index.ts +162 -0
- package/src/config/validation.ts +180 -65
- package/src/create-worker-preview.ts +17 -7
- package/src/create-worker-upload-form.ts +22 -8
- package/src/dev/dev.tsx +7 -6
- package/src/dev/local.tsx +6 -0
- package/src/dev/remote.tsx +15 -1
- package/src/dialogs.tsx +48 -0
- package/src/durable.ts +102 -0
- package/src/entry.ts +64 -9
- package/src/index.tsx +357 -177
- package/src/inspect.ts +39 -0
- package/src/kv.ts +114 -25
- package/src/open-in-browser.ts +5 -12
- package/src/package-manager.ts +50 -3
- package/src/pages.tsx +271 -110
- package/src/parse.ts +23 -4
- package/src/proxy.ts +38 -22
- package/src/publish.ts +227 -113
- package/src/sites.tsx +19 -17
- package/src/user.tsx +11 -1
- package/src/worker.ts +8 -0
- package/templates/new-worker-scheduled.js +17 -0
- package/templates/new-worker-scheduled.ts +32 -0
- package/templates/new-worker.ts +16 -1
- package/wrangler-dist/cli.js +36017 -22687
package/src/inspect.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { createServer } from "node:http";
|
|
3
|
+
import os from "node:os";
|
|
3
4
|
import { URL } from "node:url";
|
|
4
5
|
|
|
6
|
+
import open from "open";
|
|
5
7
|
import { useEffect, useRef, useState } from "react";
|
|
6
8
|
import WebSocket, { WebSocketServer } from "ws";
|
|
7
9
|
import { version } from "../package.json";
|
|
@@ -621,3 +623,40 @@ function logConsoleMessage(evt: Protocol.Runtime.ConsoleAPICalledEvent): void {
|
|
|
621
623
|
logger.warn("console event:", evt);
|
|
622
624
|
}
|
|
623
625
|
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Opens the chrome debugger
|
|
629
|
+
*/
|
|
630
|
+
export const openInspector = async (inspectorPort: number) => {
|
|
631
|
+
const url = `https://built-devtools.pages.dev/js_app?experiments=true&v8only=true&ws=localhost:${inspectorPort}/ws`;
|
|
632
|
+
const errorMessage =
|
|
633
|
+
"Failed to open inspector.\nInspector depends on having a Chromium-based browser installed, maybe you need to install one?";
|
|
634
|
+
|
|
635
|
+
// see: https://github.com/sindresorhus/open/issues/177#issue-610016699
|
|
636
|
+
let braveBrowser: string;
|
|
637
|
+
switch (os.platform()) {
|
|
638
|
+
case "darwin":
|
|
639
|
+
case "win32":
|
|
640
|
+
braveBrowser = "Brave";
|
|
641
|
+
break;
|
|
642
|
+
default:
|
|
643
|
+
braveBrowser = "brave";
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const childProcess = await open(url, {
|
|
647
|
+
app: [
|
|
648
|
+
{
|
|
649
|
+
name: open.apps.chrome,
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: braveBrowser,
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
name: open.apps.edge,
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
});
|
|
659
|
+
childProcess.on("error", () => {
|
|
660
|
+
logger.warn(errorMessage);
|
|
661
|
+
});
|
|
662
|
+
};
|
package/src/kv.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { URLSearchParams } from "node:url";
|
|
2
2
|
import { fetchListResult, fetchResult, fetchKVGetValue } from "./cfetch";
|
|
3
|
+
import { logger } from "./logger";
|
|
3
4
|
import type { Config } from "./config";
|
|
4
5
|
|
|
5
6
|
/** The largest number of kv items we can pass to the API in a single request. */
|
|
@@ -19,7 +20,7 @@ type KvArgs = {
|
|
|
19
20
|
*
|
|
20
21
|
* @returns the generated id of the created namespace.
|
|
21
22
|
*/
|
|
22
|
-
export async function
|
|
23
|
+
export async function createKVNamespace(
|
|
23
24
|
accountId: string,
|
|
24
25
|
title: string
|
|
25
26
|
): Promise<string> {
|
|
@@ -51,7 +52,7 @@ export interface KVNamespaceInfo {
|
|
|
51
52
|
/**
|
|
52
53
|
* Fetch a list of all the namespaces under the given `accountId`.
|
|
53
54
|
*/
|
|
54
|
-
export async function
|
|
55
|
+
export async function listKVNamespaces(
|
|
55
56
|
accountId: string
|
|
56
57
|
): Promise<KVNamespaceInfo[]> {
|
|
57
58
|
const pageSize = 100;
|
|
@@ -83,7 +84,7 @@ export interface NamespaceKeyInfo {
|
|
|
83
84
|
metadata?: { [key: string]: unknown };
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
export async function
|
|
87
|
+
export async function listKVNamespaceKeys(
|
|
87
88
|
accountId: string,
|
|
88
89
|
namespaceId: string,
|
|
89
90
|
prefix = ""
|
|
@@ -95,6 +96,16 @@ export async function listNamespaceKeys(
|
|
|
95
96
|
);
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
export async function deleteKVNamespace(
|
|
100
|
+
accountId: string,
|
|
101
|
+
namespaceId: string
|
|
102
|
+
) {
|
|
103
|
+
return await fetchResult<{ id: string }>(
|
|
104
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}`,
|
|
105
|
+
{ method: "DELETE" }
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
98
109
|
/**
|
|
99
110
|
* Information about a key-value pair, including its "metadata" fields.
|
|
100
111
|
*/
|
|
@@ -116,12 +127,52 @@ const KeyValueKeys = new Set([
|
|
|
116
127
|
"base64",
|
|
117
128
|
]);
|
|
118
129
|
|
|
130
|
+
/**
|
|
131
|
+
* The object has the specified property.
|
|
132
|
+
*/
|
|
133
|
+
function hasProperty<T extends object>(
|
|
134
|
+
obj: object,
|
|
135
|
+
property: keyof T
|
|
136
|
+
): obj is T {
|
|
137
|
+
return property in obj;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The object has a required property of the specified type.
|
|
142
|
+
*/
|
|
143
|
+
function hasTypedProperty<T extends object>(
|
|
144
|
+
obj: object,
|
|
145
|
+
property: keyof T,
|
|
146
|
+
type: string
|
|
147
|
+
): obj is T {
|
|
148
|
+
return hasProperty(obj, property) && typeof obj[property] === type;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The object an optional property, of the specified type.
|
|
153
|
+
*/
|
|
154
|
+
function hasOptionalTypedProperty<T extends object>(
|
|
155
|
+
obj: object,
|
|
156
|
+
property: keyof T,
|
|
157
|
+
type: string
|
|
158
|
+
): obj is Omit<T, typeof property> | T {
|
|
159
|
+
return !hasProperty(obj, property) || typeof obj[property] === type;
|
|
160
|
+
}
|
|
161
|
+
|
|
119
162
|
/**
|
|
120
163
|
* Is the given object a valid `KeyValue` type?
|
|
121
164
|
*/
|
|
122
|
-
export function
|
|
123
|
-
|
|
124
|
-
|
|
165
|
+
export function isKVKeyValue(keyValue: unknown): keyValue is KeyValue {
|
|
166
|
+
if (
|
|
167
|
+
keyValue === null ||
|
|
168
|
+
typeof keyValue !== "object" ||
|
|
169
|
+
!hasTypedProperty(keyValue, "key", "string") ||
|
|
170
|
+
!hasTypedProperty(keyValue, "value", "string") ||
|
|
171
|
+
!hasOptionalTypedProperty(keyValue, "expiration", "number") ||
|
|
172
|
+
!hasOptionalTypedProperty(keyValue, "expiration_ttl", "number") ||
|
|
173
|
+
!hasOptionalTypedProperty(keyValue, "base64", "boolean") ||
|
|
174
|
+
!hasOptionalTypedProperty(keyValue, "metadata", "object")
|
|
175
|
+
) {
|
|
125
176
|
return false;
|
|
126
177
|
}
|
|
127
178
|
return true;
|
|
@@ -130,12 +181,12 @@ export function isKeyValue(keyValue: object): keyValue is KeyValue {
|
|
|
130
181
|
/**
|
|
131
182
|
* Get all the properties on the `keyValue` that are not expected.
|
|
132
183
|
*/
|
|
133
|
-
export function
|
|
184
|
+
export function unexpectedKVKeyValueProps(keyValue: KeyValue): string[] {
|
|
134
185
|
const props = Object.keys(keyValue);
|
|
135
186
|
return props.filter((prop) => !KeyValueKeys.has(prop));
|
|
136
187
|
}
|
|
137
188
|
|
|
138
|
-
export async function
|
|
189
|
+
export async function putKVKeyValue(
|
|
139
190
|
accountId: string,
|
|
140
191
|
namespaceId: string,
|
|
141
192
|
keyValue: KeyValue
|
|
@@ -151,29 +202,66 @@ export async function putKeyValue(
|
|
|
151
202
|
}
|
|
152
203
|
}
|
|
153
204
|
return await fetchResult(
|
|
154
|
-
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${
|
|
205
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
206
|
+
keyValue.key
|
|
207
|
+
)}`,
|
|
155
208
|
{ method: "PUT", body: keyValue.value },
|
|
156
209
|
searchParams
|
|
157
210
|
);
|
|
158
211
|
}
|
|
159
212
|
|
|
160
|
-
export async function
|
|
213
|
+
export async function getKVKeyValue(
|
|
161
214
|
accountId: string,
|
|
162
215
|
namespaceId: string,
|
|
163
216
|
key: string
|
|
164
217
|
): Promise<string> {
|
|
165
|
-
return await fetchKVGetValue(accountId, namespaceId, key);
|
|
218
|
+
return await fetchKVGetValue(accountId, namespaceId, encodeURIComponent(key));
|
|
166
219
|
}
|
|
167
220
|
|
|
168
|
-
export async function
|
|
221
|
+
export async function deleteKVKeyValue(
|
|
222
|
+
accountId: string,
|
|
223
|
+
namespaceId: string,
|
|
224
|
+
key: string
|
|
225
|
+
) {
|
|
226
|
+
return await fetchResult(
|
|
227
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
228
|
+
key
|
|
229
|
+
)}`,
|
|
230
|
+
{ method: "DELETE" }
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Formatter for converting e.g. 5328 --> 5,328
|
|
236
|
+
*/
|
|
237
|
+
const formatNumber = new Intl.NumberFormat("en-US", {
|
|
238
|
+
notation: "standard",
|
|
239
|
+
}).format;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Helper function for bulk requests, logs ongoing output to console.
|
|
243
|
+
*/
|
|
244
|
+
function logBulkProgress(
|
|
245
|
+
operation: "put" | "delete",
|
|
246
|
+
index: number,
|
|
247
|
+
total: number
|
|
248
|
+
) {
|
|
249
|
+
logger.log(
|
|
250
|
+
`${operation === "put" ? "Uploaded" : "Deleted"} ${Math.floor(
|
|
251
|
+
(100 * index) / total
|
|
252
|
+
)}% (${formatNumber(index)} out of ${formatNumber(total)})`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export async function putKVBulkKeyValue(
|
|
169
257
|
accountId: string,
|
|
170
258
|
namespaceId: string,
|
|
171
259
|
keyValues: KeyValue[],
|
|
172
|
-
|
|
260
|
+
quiet = false
|
|
173
261
|
) {
|
|
174
262
|
for (let index = 0; index < keyValues.length; index += BATCH_KEY_MAX) {
|
|
175
|
-
if (
|
|
176
|
-
|
|
263
|
+
if (!quiet && keyValues.length > BATCH_KEY_MAX) {
|
|
264
|
+
logBulkProgress("put", index, keyValues.length);
|
|
177
265
|
}
|
|
178
266
|
|
|
179
267
|
await fetchResult(
|
|
@@ -185,20 +273,21 @@ export async function putBulkKeyValue(
|
|
|
185
273
|
}
|
|
186
274
|
);
|
|
187
275
|
}
|
|
188
|
-
|
|
189
|
-
|
|
276
|
+
|
|
277
|
+
if (!quiet && keyValues.length > BATCH_KEY_MAX) {
|
|
278
|
+
logBulkProgress("put", keyValues.length, keyValues.length);
|
|
190
279
|
}
|
|
191
280
|
}
|
|
192
281
|
|
|
193
|
-
export async function
|
|
282
|
+
export async function deleteKVBulkKeyValue(
|
|
194
283
|
accountId: string,
|
|
195
284
|
namespaceId: string,
|
|
196
285
|
keys: string[],
|
|
197
|
-
|
|
286
|
+
quiet = false
|
|
198
287
|
) {
|
|
199
288
|
for (let index = 0; index < keys.length; index += BATCH_KEY_MAX) {
|
|
200
|
-
if (
|
|
201
|
-
|
|
289
|
+
if (!quiet && keys.length > BATCH_KEY_MAX) {
|
|
290
|
+
logBulkProgress("delete", index, keys.length);
|
|
202
291
|
}
|
|
203
292
|
|
|
204
293
|
await fetchResult(
|
|
@@ -210,12 +299,12 @@ export async function deleteBulkKeyValue(
|
|
|
210
299
|
}
|
|
211
300
|
);
|
|
212
301
|
}
|
|
213
|
-
if (
|
|
214
|
-
|
|
302
|
+
if (!quiet && keys.length > BATCH_KEY_MAX) {
|
|
303
|
+
logBulkProgress("delete", keys.length, keys.length);
|
|
215
304
|
}
|
|
216
305
|
}
|
|
217
306
|
|
|
218
|
-
export function
|
|
307
|
+
export function getKVNamespaceId(
|
|
219
308
|
{ preview, binding, "namespace-id": namespaceId }: KvArgs,
|
|
220
309
|
config: Config
|
|
221
310
|
): string {
|
|
@@ -310,7 +399,7 @@ export function getNamespaceId(
|
|
|
310
399
|
/**
|
|
311
400
|
* KV namespace binding names must be valid JS identifiers.
|
|
312
401
|
*/
|
|
313
|
-
export function
|
|
402
|
+
export function isValidKVNamespaceBinding(
|
|
314
403
|
binding: string | undefined
|
|
315
404
|
): binding is string {
|
|
316
405
|
return (
|
package/src/open-in-browser.ts
CHANGED
|
@@ -8,19 +8,12 @@ import { logger } from "./logger";
|
|
|
8
8
|
* StackBlitz, remote servers), it doesn't just crash the process.
|
|
9
9
|
*
|
|
10
10
|
* @param url the URL to point the browser at
|
|
11
|
-
* @param options open a Chromium-based browser instead of the default
|
|
12
11
|
*/
|
|
13
|
-
export default async function openInBrowser(
|
|
14
|
-
url
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const options: open.Options | undefined = forceChromium
|
|
18
|
-
? {
|
|
19
|
-
app: [{ name: open.apps.chrome }, { name: open.apps.edge }],
|
|
20
|
-
}
|
|
21
|
-
: undefined;
|
|
22
|
-
const childProcess = await open(url, options);
|
|
12
|
+
export default async function openInBrowser(url: string): Promise<void> {
|
|
13
|
+
const errorMessage = `Failed to open ${url} in a browser`;
|
|
14
|
+
|
|
15
|
+
const childProcess = await open(url);
|
|
23
16
|
childProcess.on("error", () => {
|
|
24
|
-
logger.warn(
|
|
17
|
+
logger.warn(errorMessage);
|
|
25
18
|
});
|
|
26
19
|
}
|
package/src/package-manager.ts
CHANGED
|
@@ -5,15 +5,20 @@ import { logger } from "./logger";
|
|
|
5
5
|
|
|
6
6
|
export interface PackageManager {
|
|
7
7
|
cwd: string;
|
|
8
|
-
type: "npm" | "yarn";
|
|
8
|
+
type: "npm" | "yarn" | "pnpm";
|
|
9
9
|
addDevDeps(...packages: string[]): Promise<void>;
|
|
10
10
|
install(): Promise<void>;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export async function getPackageManager(cwd: string): Promise<PackageManager> {
|
|
14
|
-
const [hasYarn, hasNpm] = await Promise.all([
|
|
14
|
+
const [hasYarn, hasNpm, hasPnpm] = await Promise.all([
|
|
15
|
+
supportsYarn(),
|
|
16
|
+
supportsNpm(),
|
|
17
|
+
supportsPnpm(),
|
|
18
|
+
]);
|
|
15
19
|
const hasYarnLock = existsSync(join(cwd, "yarn.lock"));
|
|
16
20
|
const hasNpmLock = existsSync(join(cwd, "package-lock.json"));
|
|
21
|
+
const hasPnpmLock = existsSync(join(cwd, "pnpm-lock.yaml"));
|
|
17
22
|
|
|
18
23
|
if (hasNpmLock) {
|
|
19
24
|
if (hasNpm) {
|
|
@@ -28,6 +33,18 @@ export async function getPackageManager(cwd: string): Promise<PackageManager> {
|
|
|
28
33
|
);
|
|
29
34
|
return { ...YarnPackageManager, cwd };
|
|
30
35
|
}
|
|
36
|
+
} else if (hasPnpmLock) {
|
|
37
|
+
if (hasPnpm) {
|
|
38
|
+
logger.log(
|
|
39
|
+
"Using pnpm as package manager, as there is already a pnpm-lock.yaml file."
|
|
40
|
+
);
|
|
41
|
+
return { ...PnpmPackageManager, cwd };
|
|
42
|
+
} else {
|
|
43
|
+
logger.warn(
|
|
44
|
+
"There is already a pnpm-lock.yaml file but could not find pnpm on the PATH."
|
|
45
|
+
);
|
|
46
|
+
// will simply fallback to the first found of [npm, yaml, pnpm] in the next if round.
|
|
47
|
+
}
|
|
31
48
|
} else if (hasYarnLock) {
|
|
32
49
|
if (hasYarn) {
|
|
33
50
|
logger.log(
|
|
@@ -49,9 +66,12 @@ export async function getPackageManager(cwd: string): Promise<PackageManager> {
|
|
|
49
66
|
} else if (hasYarn) {
|
|
50
67
|
logger.log("Using yarn as package manager.");
|
|
51
68
|
return { ...YarnPackageManager, cwd };
|
|
69
|
+
} else if (hasPnpm) {
|
|
70
|
+
logger.log("Using pnpm as package manager.");
|
|
71
|
+
return { ...PnpmPackageManager, cwd };
|
|
52
72
|
} else {
|
|
53
73
|
throw new Error(
|
|
54
|
-
"Unable to find a package manager. Supported managers are: npm and
|
|
74
|
+
"Unable to find a package manager. Supported managers are: npm, yarn, and pnpm."
|
|
55
75
|
);
|
|
56
76
|
}
|
|
57
77
|
}
|
|
@@ -86,6 +106,29 @@ const NpmPackageManager: PackageManager = {
|
|
|
86
106
|
},
|
|
87
107
|
};
|
|
88
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Manage packages using pnpm
|
|
111
|
+
*/
|
|
112
|
+
const PnpmPackageManager: PackageManager = {
|
|
113
|
+
cwd: process.cwd(),
|
|
114
|
+
type: "pnpm",
|
|
115
|
+
/** Add and install a new devDependency into the local package.json. */
|
|
116
|
+
async addDevDeps(...packages: string[]): Promise<void> {
|
|
117
|
+
await execa("pnpm", ["install", ...packages, "--save-dev"], {
|
|
118
|
+
stdio: "inherit",
|
|
119
|
+
cwd: this.cwd,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
/** Install all the dependencies in the local package.json. */
|
|
124
|
+
async install(): Promise<void> {
|
|
125
|
+
await execa("pnpm", ["install"], {
|
|
126
|
+
stdio: "inherit",
|
|
127
|
+
cwd: this.cwd,
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
89
132
|
/**
|
|
90
133
|
* Manage packages using yarn
|
|
91
134
|
*/
|
|
@@ -125,3 +168,7 @@ function supportsYarn(): Promise<boolean> {
|
|
|
125
168
|
function supportsNpm(): Promise<boolean> {
|
|
126
169
|
return supports("npm");
|
|
127
170
|
}
|
|
171
|
+
|
|
172
|
+
function supportsPnpm(): Promise<boolean> {
|
|
173
|
+
return supports("pnpm");
|
|
174
|
+
}
|