wrangler 2.1.14 → 2.2.0
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/miniflare-dist/index.mjs +3 -1
- package/package.json +2 -1
- package/src/__tests__/access.test.ts +25 -0
- package/src/__tests__/api-dev.test.ts +1 -1
- package/src/__tests__/api-devregistry.test.js +2 -2
- package/src/__tests__/configuration.test.ts +119 -2
- package/src/__tests__/d1.test.ts +2 -0
- package/src/__tests__/deployments.test.ts +22 -22
- package/src/__tests__/dev.test.tsx +167 -15
- package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +22 -43
- package/src/__tests__/helpers/msw/handlers/zones.ts +22 -0
- package/src/__tests__/helpers/msw/index.ts +4 -0
- package/src/__tests__/index.test.ts +42 -33
- package/src/__tests__/init.test.ts +88 -4
- package/src/__tests__/jest.setup.ts +11 -0
- package/src/__tests__/kv.test.ts +400 -400
- package/src/__tests__/pages.test.ts +140 -28
- package/src/__tests__/publish.test.ts +1161 -647
- package/src/__tests__/pubsub.test.ts +3 -0
- package/src/__tests__/queues.test.ts +371 -0
- package/src/__tests__/r2.test.ts +57 -52
- package/src/__tests__/worker-namespace.test.ts +15 -10
- package/src/bundle-reporter.tsx +41 -2
- package/src/bundle.ts +59 -30
- package/src/cli.ts +0 -1
- package/src/config/environment.ts +50 -0
- package/src/config/index.ts +41 -0
- package/src/config/validation.ts +173 -0
- package/src/create-worker-preview.ts +10 -3
- package/src/create-worker-upload-form.ts +12 -0
- package/src/d1/backups.tsx +11 -5
- package/src/d1/execute.tsx +52 -47
- package/src/d1/index.ts +2 -1
- package/src/delete.ts +7 -10
- package/src/deployments.ts +73 -0
- package/src/deprecated/index.ts +9 -24
- package/src/dev/dev-vars.ts +11 -8
- package/src/dev/dev.tsx +12 -0
- package/src/dev/local.tsx +26 -0
- package/src/dev/remote.tsx +2 -0
- package/src/dev/start-server.ts +7 -0
- package/src/dev/use-esbuild.ts +12 -5
- package/src/dev.tsx +12 -9
- package/src/dispatch-namespace.ts +4 -3
- package/src/index.tsx +61 -45
- package/src/init.ts +4 -4
- package/src/inspect.ts +21 -1
- package/src/is-interactive.ts +4 -0
- package/src/kv/index.ts +5 -54
- package/src/logger.ts +12 -0
- package/src/pages/constants.ts +2 -0
- package/src/pages/upload.tsx +42 -15
- package/src/proxy.ts +38 -6
- package/src/publish/index.ts +11 -8
- package/src/publish/publish.ts +151 -30
- package/src/pubsub/pubsub-commands.tsx +3 -2
- package/src/queues/cli/commands/consumer/add.ts +71 -0
- package/src/queues/cli/commands/consumer/index.ts +22 -0
- package/src/queues/cli/commands/consumer/remove.ts +38 -0
- package/src/queues/cli/commands/create.ts +25 -0
- package/src/queues/cli/commands/delete.ts +26 -0
- package/src/queues/cli/commands/index.ts +33 -0
- package/src/queues/cli/commands/list.ts +25 -0
- package/src/queues/client.ts +135 -0
- package/src/secret/index.ts +14 -39
- package/src/tail/index.ts +5 -8
- package/src/user/access.ts +69 -0
- package/src/worker.ts +7 -0
- package/src/yargs-types.ts +15 -2
- package/src/zones.ts +31 -5
- package/templates/pages-template-plugin.ts +4 -0
- package/templates/pages-template-worker.ts +21 -4
- package/wrangler-dist/cli.d.ts +42 -0
- package/wrangler-dist/cli.js +4559 -3228
package/src/dev.tsx
CHANGED
|
@@ -31,6 +31,7 @@ import type { Config, Environment } from "./config";
|
|
|
31
31
|
import type { Route } from "./config/environment";
|
|
32
32
|
import type { EnablePagesAssetsServiceBindingOptions } from "./miniflare-cli";
|
|
33
33
|
import type { CfWorkerInit } from "./worker";
|
|
34
|
+
import type { CommonYargsOptions } from "./yargs-types";
|
|
34
35
|
import type { Argv, ArgumentsCamelCase } from "yargs";
|
|
35
36
|
|
|
36
37
|
interface DevArgs {
|
|
@@ -79,7 +80,7 @@ interface DevArgs {
|
|
|
79
80
|
"test-scheduled"?: boolean;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
export function devOptions(yargs: Argv): Argv<DevArgs> {
|
|
83
|
+
export function devOptions(yargs: Argv<CommonYargsOptions>): Argv<DevArgs> {
|
|
83
84
|
return (
|
|
84
85
|
yargs
|
|
85
86
|
.positional("script", {
|
|
@@ -111,12 +112,6 @@ export function devOptions(yargs: Argv): Argv<DevArgs> {
|
|
|
111
112
|
hidden: true,
|
|
112
113
|
deprecated: true,
|
|
113
114
|
})
|
|
114
|
-
.option("env", {
|
|
115
|
-
describe: "Perform on a specific environment",
|
|
116
|
-
type: "string",
|
|
117
|
-
requiresArg: true,
|
|
118
|
-
alias: "e",
|
|
119
|
-
})
|
|
120
115
|
.option("compatibility-date", {
|
|
121
116
|
describe: "Date to use for compatibility checks",
|
|
122
117
|
type: "string",
|
|
@@ -455,6 +450,7 @@ export async function startDev(args: StartDevOptions) {
|
|
|
455
450
|
usageModel={configParam.usage_model}
|
|
456
451
|
bindings={bindings}
|
|
457
452
|
crons={configParam.triggers.crons}
|
|
453
|
+
queueConsumers={configParam.queues.consumers}
|
|
458
454
|
logPrefix={args.logPrefix}
|
|
459
455
|
onReady={args.onReady}
|
|
460
456
|
inspect={args.inspect ?? true}
|
|
@@ -574,6 +570,7 @@ export async function startApiDev(args: StartDevOptions) {
|
|
|
574
570
|
usageModel: configParam.usage_model,
|
|
575
571
|
bindings: bindings,
|
|
576
572
|
crons: configParam.triggers.crons,
|
|
573
|
+
queueConsumers: configParam.queues.consumers,
|
|
577
574
|
logPrefix: args.logPrefix,
|
|
578
575
|
onReady: args.onReady,
|
|
579
576
|
inspect: args.inspect ?? true,
|
|
@@ -763,7 +760,7 @@ async function getBindingsAndAssetPaths(
|
|
|
763
760
|
const cliVars = collectKeyValues(args.var);
|
|
764
761
|
|
|
765
762
|
// now log all available bindings into the terminal
|
|
766
|
-
const bindings = await getBindings(configParam, {
|
|
763
|
+
const bindings = await getBindings(configParam, args.env, {
|
|
767
764
|
kv: args.kv,
|
|
768
765
|
vars: { ...args.vars, ...cliVars },
|
|
769
766
|
durableObjects: args.durableObjects,
|
|
@@ -792,6 +789,7 @@ async function getBindingsAndAssetPaths(
|
|
|
792
789
|
|
|
793
790
|
async function getBindings(
|
|
794
791
|
configParam: Config,
|
|
792
|
+
env: string | undefined,
|
|
795
793
|
args: AdditionalDevProps
|
|
796
794
|
): Promise<CfWorkerInit["bindings"]> {
|
|
797
795
|
const bindings = {
|
|
@@ -821,7 +819,7 @@ async function getBindings(
|
|
|
821
819
|
],
|
|
822
820
|
// Use a copy of combinedVars since we're modifying it later
|
|
823
821
|
vars: {
|
|
824
|
-
...getVarsForDev(configParam),
|
|
822
|
+
...getVarsForDev(configParam, env),
|
|
825
823
|
...args.vars,
|
|
826
824
|
},
|
|
827
825
|
wasm_modules: configParam.wasm_modules,
|
|
@@ -833,6 +831,11 @@ async function getBindings(
|
|
|
833
831
|
...(args.durableObjects || []),
|
|
834
832
|
],
|
|
835
833
|
},
|
|
834
|
+
queues: [
|
|
835
|
+
...(configParam.queues.producers || []).map((queue) => {
|
|
836
|
+
return { binding: queue.binding, queue_name: queue.queue };
|
|
837
|
+
}),
|
|
838
|
+
],
|
|
836
839
|
r2_buckets: [
|
|
837
840
|
...(configParam.r2_buckets?.map(
|
|
838
841
|
({ binding, preview_bucket_name, bucket_name: _bucket_name }) => {
|
|
@@ -5,6 +5,7 @@ import * as metrics from "./metrics";
|
|
|
5
5
|
import { requireAuth } from "./user";
|
|
6
6
|
import { printWranglerBanner } from ".";
|
|
7
7
|
import type { ConfigPath } from ".";
|
|
8
|
+
import type { CommonYargsOptions } from "./yargs-types";
|
|
8
9
|
import type { Argv, CommandModule } from "yargs";
|
|
9
10
|
|
|
10
11
|
type Namespace = {
|
|
@@ -105,9 +106,9 @@ async function renameWorkerNamespace(
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
export function workerNamespaceCommands(
|
|
108
|
-
workerNamespaceYargs: Argv
|
|
109
|
-
subHelp: CommandModule
|
|
110
|
-
)
|
|
109
|
+
workerNamespaceYargs: Argv<CommonYargsOptions>,
|
|
110
|
+
subHelp: CommandModule<CommonYargsOptions, CommonYargsOptions>
|
|
111
|
+
) {
|
|
111
112
|
return workerNamespaceYargs
|
|
112
113
|
.command(subHelp)
|
|
113
114
|
.command("list", "List all dispatch namespaces", {}, async (args) => {
|
package/src/index.tsx
CHANGED
|
@@ -5,10 +5,11 @@ import supportsColor from "supports-color";
|
|
|
5
5
|
import { ProxyAgent, setGlobalDispatcher } from "undici";
|
|
6
6
|
import makeCLI from "yargs";
|
|
7
7
|
import { version as wranglerVersion } from "../package.json";
|
|
8
|
-
import {
|
|
9
|
-
import { readConfig } from "./config";
|
|
8
|
+
import { isBuildFailure } from "./bundle";
|
|
9
|
+
import { loadDotEnv, readConfig } from "./config";
|
|
10
10
|
import { d1 } from "./d1";
|
|
11
11
|
import { deleteHandler, deleteOptions } from "./delete";
|
|
12
|
+
import { deployments } from "./deployments";
|
|
12
13
|
import {
|
|
13
14
|
buildHandler,
|
|
14
15
|
buildOptions,
|
|
@@ -27,12 +28,13 @@ import { devHandler, devOptions } from "./dev";
|
|
|
27
28
|
import { workerNamespaceCommands } from "./dispatch-namespace";
|
|
28
29
|
import { initHandler, initOptions } from "./init";
|
|
29
30
|
import { kvNamespace, kvKey, kvBulk } from "./kv";
|
|
30
|
-
import { logger } from "./logger";
|
|
31
|
+
import { logBuildFailure, logger } from "./logger";
|
|
31
32
|
import * as metrics from "./metrics";
|
|
32
33
|
import { pages } from "./pages";
|
|
33
34
|
import { formatMessage, ParseError } from "./parse";
|
|
34
35
|
import { publishOptions, publishHandler } from "./publish";
|
|
35
36
|
import { pubSubCommands } from "./pubsub/pubsub-commands";
|
|
37
|
+
import { queues } from "./queues/cli/commands";
|
|
36
38
|
import { r2 } from "./r2";
|
|
37
39
|
import { secret, secretBulkHandler, secretBulkOptions } from "./secret";
|
|
38
40
|
import { tailOptions, tailHandler } from "./tail";
|
|
@@ -47,10 +49,9 @@ import {
|
|
|
47
49
|
} from "./user";
|
|
48
50
|
import { whoami } from "./whoami";
|
|
49
51
|
|
|
50
|
-
import type { DeploymentListRes } from "./__tests__/helpers/msw/handlers/deployments";
|
|
51
52
|
import type { Config } from "./config";
|
|
52
|
-
import type { ServiceMetadataRes } from "./init";
|
|
53
53
|
import type { PartialConfigToDTS } from "./type-generation";
|
|
54
|
+
import type { CommonYargsOptions } from "./yargs-types";
|
|
54
55
|
import type { ArgumentsCamelCase } from "yargs";
|
|
55
56
|
import type Yargs from "yargs";
|
|
56
57
|
|
|
@@ -174,7 +175,9 @@ export function demandOneOfOption(...options: string[]) {
|
|
|
174
175
|
export class CommandLineArgsError extends Error {}
|
|
175
176
|
|
|
176
177
|
export function createCLIParser(argv: string[]) {
|
|
177
|
-
|
|
178
|
+
// Type check result against CommonYargsOptions to make sure we've included
|
|
179
|
+
// all common options
|
|
180
|
+
const wrangler: Yargs.Argv<CommonYargsOptions> = makeCLI(argv)
|
|
178
181
|
.strict()
|
|
179
182
|
// We handle errors ourselves in a try-catch around `yargs.parse`.
|
|
180
183
|
// If you want the "help info" to be displayed then throw an instance of `CommandLineArgsError`.
|
|
@@ -189,10 +192,41 @@ export function createCLIParser(argv: string[]) {
|
|
|
189
192
|
throw error;
|
|
190
193
|
})
|
|
191
194
|
.scriptName("wrangler")
|
|
192
|
-
.wrap(null)
|
|
195
|
+
.wrap(null)
|
|
196
|
+
// Define global options here, so they get included in the `Argv` type of
|
|
197
|
+
// the `wrangler` variable
|
|
198
|
+
.version(false)
|
|
199
|
+
.option("v", {
|
|
200
|
+
describe: "Show version number",
|
|
201
|
+
alias: "version",
|
|
202
|
+
type: "boolean",
|
|
203
|
+
})
|
|
204
|
+
.option("config", {
|
|
205
|
+
alias: "c",
|
|
206
|
+
describe: "Path to .toml configuration file",
|
|
207
|
+
type: "string",
|
|
208
|
+
requiresArg: true,
|
|
209
|
+
})
|
|
210
|
+
.option("env", {
|
|
211
|
+
alias: "e",
|
|
212
|
+
describe: "Environment to use for operations and .env files",
|
|
213
|
+
type: "string",
|
|
214
|
+
requiresArg: true,
|
|
215
|
+
})
|
|
216
|
+
.check((args) => {
|
|
217
|
+
// Grab locally specified env params from `.env` file
|
|
218
|
+
const loaded = loadDotEnv(".env", args.env);
|
|
219
|
+
for (const [key, value] of Object.entries(loaded?.parsed ?? {})) {
|
|
220
|
+
if (!(key in process.env)) process.env[key] = value;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
wrangler.group(["config", "env", "help", "version"], "Flags:");
|
|
226
|
+
wrangler.help().alias("h", "help");
|
|
193
227
|
|
|
194
228
|
// Default help command that supports the subcommands
|
|
195
|
-
const subHelp: Yargs.CommandModule = {
|
|
229
|
+
const subHelp: Yargs.CommandModule<CommonYargsOptions, CommonYargsOptions> = {
|
|
196
230
|
command: ["*"],
|
|
197
231
|
handler: async (args) => {
|
|
198
232
|
setImmediate(() =>
|
|
@@ -363,6 +397,11 @@ export function createCLIParser(argv: string[]) {
|
|
|
363
397
|
return pages(pagesYargs.command(subHelp));
|
|
364
398
|
});
|
|
365
399
|
|
|
400
|
+
// queues
|
|
401
|
+
wrangler.command("queues", "🆀 Configure Workers Queues", (queuesYargs) => {
|
|
402
|
+
return queues(queuesYargs.command(subHelp));
|
|
403
|
+
});
|
|
404
|
+
|
|
366
405
|
// r2
|
|
367
406
|
wrangler.command("r2", "📦 Interact with an R2 store", (r2Yargs) => {
|
|
368
407
|
return r2(r2Yargs.command(subHelp));
|
|
@@ -511,15 +550,20 @@ export function createCLIParser(argv: string[]) {
|
|
|
511
550
|
}
|
|
512
551
|
);
|
|
513
552
|
|
|
553
|
+
//deployments
|
|
554
|
+
const deploymentsWarning =
|
|
555
|
+
"🚧`wrangler deployments` is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
|
|
514
556
|
wrangler.command(
|
|
515
557
|
"deployments",
|
|
516
558
|
false,
|
|
517
559
|
// "🚢 Logs the 10 most recent deployments with 'Version ID', 'Version number','Author email', 'Created on' and 'Latest deploy'",
|
|
518
560
|
(yargs) => {
|
|
519
|
-
yargs
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
561
|
+
yargs
|
|
562
|
+
.option("name", {
|
|
563
|
+
describe: "The name of your worker",
|
|
564
|
+
type: "string",
|
|
565
|
+
})
|
|
566
|
+
.epilogue(deploymentsWarning);
|
|
523
567
|
},
|
|
524
568
|
async (deploymentsYargs: ArgumentsCamelCase<{ name: string }>) => {
|
|
525
569
|
await printWranglerBanner();
|
|
@@ -532,24 +576,9 @@ export function createCLIParser(argv: string[]) {
|
|
|
532
576
|
{ name: deploymentsYargs.name, env: undefined },
|
|
533
577
|
config
|
|
534
578
|
);
|
|
535
|
-
const scriptMetadata = await fetchResult<ServiceMetadataRes>(
|
|
536
|
-
`/accounts/${accountId}/workers/services/${scriptName}`
|
|
537
|
-
);
|
|
538
|
-
|
|
539
|
-
const scriptTag = scriptMetadata.default_environment.script.tag;
|
|
540
|
-
const deployments = await fetchResult<DeploymentListRes>(
|
|
541
|
-
`/accounts/${accountId}/workers/versions/by-script/${scriptTag}`
|
|
542
|
-
);
|
|
543
579
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
`\nVersion ID: ${versions.version_id}\nVersion number: ${
|
|
547
|
-
versions.version_number
|
|
548
|
-
}\nCreated on: ${versions.metadata.created_on}\nAuthor email: ${
|
|
549
|
-
versions.metadata.author_email
|
|
550
|
-
}\nLatest deploy: ${index === 0}\n`
|
|
551
|
-
);
|
|
552
|
-
logger.log(...versionMessages);
|
|
580
|
+
logger.log(`${deploymentsWarning}\n`);
|
|
581
|
+
await deployments(accountId, scriptName);
|
|
553
582
|
}
|
|
554
583
|
);
|
|
555
584
|
|
|
@@ -570,22 +599,6 @@ export function createCLIParser(argv: string[]) {
|
|
|
570
599
|
}
|
|
571
600
|
);
|
|
572
601
|
|
|
573
|
-
wrangler.option("v", {
|
|
574
|
-
describe: "Show version number",
|
|
575
|
-
alias: "version",
|
|
576
|
-
type: "boolean",
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
wrangler.option("config", {
|
|
580
|
-
alias: "c",
|
|
581
|
-
describe: "Path to .toml configuration file",
|
|
582
|
-
type: "string",
|
|
583
|
-
requiresArg: true,
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
wrangler.group(["config", "help", "version"], "Flags:");
|
|
587
|
-
wrangler.help().alias("h", "help");
|
|
588
|
-
|
|
589
602
|
wrangler.exitProcess(false);
|
|
590
603
|
|
|
591
604
|
return wrangler;
|
|
@@ -634,6 +647,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
634
647
|
logger.error(
|
|
635
648
|
`${thisTerminalIsUnsupported}\n${soWranglerWontWork}\n${tryRunningItIn}${oneOfThese}`
|
|
636
649
|
);
|
|
650
|
+
} else if (isBuildFailure(e)) {
|
|
651
|
+
logBuildFailure(e);
|
|
652
|
+
logger.error(e.message);
|
|
637
653
|
} else {
|
|
638
654
|
logger.error(e instanceof Error ? e.message : e);
|
|
639
655
|
logger.log(
|
package/src/init.ts
CHANGED
|
@@ -22,9 +22,10 @@ import type { Route, SimpleRoute } from "./config/environment";
|
|
|
22
22
|
import type { WorkerMetadata } from "./create-worker-upload-form";
|
|
23
23
|
import type { ConfigPath } from "./index";
|
|
24
24
|
import type { PackageManager } from "./package-manager";
|
|
25
|
+
import type { CommonYargsOptions } from "./yargs-types";
|
|
25
26
|
import type { Argv, ArgumentsCamelCase } from "yargs";
|
|
26
27
|
|
|
27
|
-
export async function initOptions(yargs: Argv) {
|
|
28
|
+
export async function initOptions(yargs: Argv<CommonYargsOptions>) {
|
|
28
29
|
return yargs
|
|
29
30
|
.positional("name", {
|
|
30
31
|
describe: "The name of your worker",
|
|
@@ -417,7 +418,7 @@ export async function initHandler(args: ArgumentsCamelCase<InitArgs>) {
|
|
|
417
418
|
);
|
|
418
419
|
instructions.push(
|
|
419
420
|
`\nTo start developing your Worker, run \`${
|
|
420
|
-
isNamedWorker ? `cd ${args.name} && ` : ""
|
|
421
|
+
isNamedWorker ? `cd ${args.name || fromDashScriptName} && ` : ""
|
|
421
422
|
}npm start\``
|
|
422
423
|
);
|
|
423
424
|
if (isAddingTestScripts) {
|
|
@@ -805,8 +806,7 @@ async function getWorkerConfig(
|
|
|
805
806
|
{
|
|
806
807
|
configObj.vars = {
|
|
807
808
|
...(configObj.vars ?? {}),
|
|
808
|
-
name: binding.
|
|
809
|
-
text: binding.text,
|
|
809
|
+
[binding.name]: binding.text,
|
|
810
810
|
};
|
|
811
811
|
}
|
|
812
812
|
break;
|
package/src/inspect.ts
CHANGED
|
@@ -11,6 +11,7 @@ import WebSocket, { WebSocketServer } from "ws";
|
|
|
11
11
|
import { version } from "../package.json";
|
|
12
12
|
import { logger } from "./logger";
|
|
13
13
|
import { waitForPortToBeAvailable } from "./proxy";
|
|
14
|
+
import { getAccessToken } from "./user/access";
|
|
14
15
|
import type Protocol from "devtools-protocol";
|
|
15
16
|
import type { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
16
17
|
import type { MessageEvent } from "ws";
|
|
@@ -58,6 +59,8 @@ interface InspectorProps {
|
|
|
58
59
|
* Sourcemap path, so that stacktraces can be interpretted
|
|
59
60
|
*/
|
|
60
61
|
sourceMapPath?: string | undefined;
|
|
62
|
+
|
|
63
|
+
host?: string;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
export default function useInspector(props: InspectorProps) {
|
|
@@ -204,14 +207,31 @@ export default function useInspector(props: InspectorProps) {
|
|
|
204
207
|
/** A simple incrementing id to attach to messages we send to devtools */
|
|
205
208
|
const messageCounterRef = useRef(1);
|
|
206
209
|
|
|
210
|
+
const cfAccessRef = useRef<string>();
|
|
211
|
+
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
const run = async () => {
|
|
214
|
+
if (props.host && !cfAccessRef.current) {
|
|
215
|
+
const token = await getAccessToken(props.host);
|
|
216
|
+
cfAccessRef.current = token;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
if (props.host) void run();
|
|
220
|
+
}, [props.host]);
|
|
221
|
+
|
|
207
222
|
// This effect tracks the connection to the remote websocket
|
|
208
223
|
// (stored in, no surprises here, `remoteWebSocket`)
|
|
209
224
|
useEffect(() => {
|
|
210
225
|
if (!props.inspectorUrl) {
|
|
211
226
|
return;
|
|
212
227
|
}
|
|
228
|
+
|
|
213
229
|
// The actual websocket instance
|
|
214
|
-
const ws = new WebSocket(props.inspectorUrl
|
|
230
|
+
const ws = new WebSocket(props.inspectorUrl, {
|
|
231
|
+
headers: {
|
|
232
|
+
cookie: `CF_Authorization=${cfAccessRef.current}`,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
215
235
|
setRemoteWebSocket(ws);
|
|
216
236
|
|
|
217
237
|
/**
|
package/src/is-interactive.ts
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* or you're piping values from / to another process, etc
|
|
5
5
|
*/
|
|
6
6
|
export default function isInteractive(): boolean {
|
|
7
|
+
if (process.env.CF_PAGES === "1") {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
try {
|
|
8
12
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
9
13
|
} catch {
|
package/src/kv/index.ts
CHANGED
|
@@ -26,12 +26,11 @@ import {
|
|
|
26
26
|
unexpectedKVKeyValueProps,
|
|
27
27
|
} from "./helpers";
|
|
28
28
|
import type { ConfigPath } from "../index";
|
|
29
|
+
import type { CommonYargsOptions } from "../yargs-types";
|
|
29
30
|
import type { KeyValue } from "./helpers";
|
|
30
|
-
import type {
|
|
31
|
+
import type { Argv } from "yargs";
|
|
31
32
|
|
|
32
|
-
export const kvNamespace:
|
|
33
|
-
kvYargs: Argv
|
|
34
|
-
) => {
|
|
33
|
+
export const kvNamespace = (kvYargs: Argv<CommonYargsOptions>) => {
|
|
35
34
|
return kvYargs
|
|
36
35
|
.command(
|
|
37
36
|
"create <namespace>",
|
|
@@ -43,12 +42,6 @@ export const kvNamespace: BuilderCallback<unknown, unknown> = (
|
|
|
43
42
|
type: "string",
|
|
44
43
|
demandOption: true,
|
|
45
44
|
})
|
|
46
|
-
.option("env", {
|
|
47
|
-
type: "string",
|
|
48
|
-
requiresArg: true,
|
|
49
|
-
describe: "Perform on a specific environment",
|
|
50
|
-
alias: "e",
|
|
51
|
-
})
|
|
52
45
|
.option("preview", {
|
|
53
46
|
type: "boolean",
|
|
54
47
|
describe: "Interact with a preview namespace",
|
|
@@ -133,12 +126,6 @@ export const kvNamespace: BuilderCallback<unknown, unknown> = (
|
|
|
133
126
|
describe: "The id of the namespace to delete",
|
|
134
127
|
})
|
|
135
128
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
136
|
-
.option("env", {
|
|
137
|
-
type: "string",
|
|
138
|
-
requiresArg: true,
|
|
139
|
-
describe: "Perform on a specific environment",
|
|
140
|
-
alias: "e",
|
|
141
|
-
})
|
|
142
129
|
.option("preview", {
|
|
143
130
|
type: "boolean",
|
|
144
131
|
describe: "Interact with a preview namespace",
|
|
@@ -187,7 +174,7 @@ export const kvNamespace: BuilderCallback<unknown, unknown> = (
|
|
|
187
174
|
);
|
|
188
175
|
};
|
|
189
176
|
|
|
190
|
-
export const kvKey
|
|
177
|
+
export const kvKey = (kvYargs: Argv<CommonYargsOptions>) => {
|
|
191
178
|
return kvYargs
|
|
192
179
|
.command(
|
|
193
180
|
"put <key> [value]",
|
|
@@ -214,12 +201,6 @@ export const kvKey: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
214
201
|
describe: "The id of the namespace to write to",
|
|
215
202
|
})
|
|
216
203
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
217
|
-
.option("env", {
|
|
218
|
-
type: "string",
|
|
219
|
-
requiresArg: true,
|
|
220
|
-
describe: "Perform on a specific environment",
|
|
221
|
-
alias: "e",
|
|
222
|
-
})
|
|
223
204
|
.option("preview", {
|
|
224
205
|
type: "boolean",
|
|
225
206
|
describe: "Interact with a preview namespace",
|
|
@@ -302,12 +283,6 @@ export const kvKey: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
302
283
|
describe: "The id of the namespace to list",
|
|
303
284
|
})
|
|
304
285
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
305
|
-
.option("env", {
|
|
306
|
-
type: "string",
|
|
307
|
-
requiresArg: true,
|
|
308
|
-
describe: "Perform on a specific environment",
|
|
309
|
-
alias: "e",
|
|
310
|
-
})
|
|
311
286
|
.option("preview", {
|
|
312
287
|
type: "boolean",
|
|
313
288
|
// In the case of listing keys we will default to non-preview mode
|
|
@@ -359,12 +334,6 @@ export const kvKey: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
359
334
|
describe: "The id of the namespace to get from",
|
|
360
335
|
})
|
|
361
336
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
362
|
-
.option("env", {
|
|
363
|
-
type: "string",
|
|
364
|
-
requiresArg: true,
|
|
365
|
-
describe: "Perform on a specific environment",
|
|
366
|
-
alias: "e",
|
|
367
|
-
})
|
|
368
337
|
.option("preview", {
|
|
369
338
|
type: "boolean",
|
|
370
339
|
describe: "Interact with a preview namespace",
|
|
@@ -422,12 +391,6 @@ export const kvKey: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
422
391
|
describe: "The id of the namespace to delete from",
|
|
423
392
|
})
|
|
424
393
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
425
|
-
.option("env", {
|
|
426
|
-
type: "string",
|
|
427
|
-
requiresArg: true,
|
|
428
|
-
describe: "Perform on a specific environment",
|
|
429
|
-
alias: "e",
|
|
430
|
-
})
|
|
431
394
|
.option("preview", {
|
|
432
395
|
type: "boolean",
|
|
433
396
|
describe: "Interact with a preview namespace",
|
|
@@ -450,7 +413,7 @@ export const kvKey: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
450
413
|
);
|
|
451
414
|
};
|
|
452
415
|
|
|
453
|
-
export const kvBulk
|
|
416
|
+
export const kvBulk = (kvYargs: Argv<CommonYargsOptions>) => {
|
|
454
417
|
return kvYargs
|
|
455
418
|
.command(
|
|
456
419
|
"put <filename>",
|
|
@@ -473,12 +436,6 @@ export const kvBulk: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
473
436
|
describe: "The id of the namespace to insert values into",
|
|
474
437
|
})
|
|
475
438
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
476
|
-
.option("env", {
|
|
477
|
-
type: "string",
|
|
478
|
-
requiresArg: true,
|
|
479
|
-
describe: "Perform on a specific environment",
|
|
480
|
-
alias: "e",
|
|
481
|
-
})
|
|
482
439
|
.option("preview", {
|
|
483
440
|
type: "boolean",
|
|
484
441
|
describe: "Interact with a preview namespace",
|
|
@@ -572,12 +529,6 @@ export const kvBulk: BuilderCallback<unknown, unknown> = (kvYargs: Argv) => {
|
|
|
572
529
|
describe: "The id of the namespace to delete from",
|
|
573
530
|
})
|
|
574
531
|
.check(demandOneOfOption("binding", "namespace-id"))
|
|
575
|
-
.option("env", {
|
|
576
|
-
type: "string",
|
|
577
|
-
requiresArg: true,
|
|
578
|
-
describe: "Perform on a specific environment",
|
|
579
|
-
alias: "e",
|
|
580
|
-
})
|
|
581
532
|
.option("preview", {
|
|
582
533
|
type: "boolean",
|
|
583
534
|
describe: "Interact with a preview namespace",
|
package/src/logger.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { format } from "node:util";
|
|
2
2
|
import { formatMessagesSync } from "esbuild";
|
|
3
3
|
import { getEnvironmentVariableFactory } from "./environment-variables";
|
|
4
|
+
import type { BuildFailure } from "esbuild";
|
|
4
5
|
|
|
5
6
|
export const LOGGER_LEVELS = {
|
|
6
7
|
none: -1,
|
|
@@ -78,3 +79,14 @@ class Logger {
|
|
|
78
79
|
* to filter out logging messages.
|
|
79
80
|
*/
|
|
80
81
|
export const logger = new Logger();
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Logs all errors/warnings associated with an esbuild BuildFailure in the same
|
|
85
|
+
* style esbuild would.
|
|
86
|
+
*/
|
|
87
|
+
export function logBuildFailure(failure: BuildFailure) {
|
|
88
|
+
let logs = formatMessagesSync(failure.errors, { kind: "error", color: true });
|
|
89
|
+
for (const log of logs) console.error(log);
|
|
90
|
+
logs = formatMessagesSync(failure.warnings, { kind: "warning", color: true });
|
|
91
|
+
for (const log of logs) console.warn(log);
|
|
92
|
+
}
|
package/src/pages/constants.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { version as wranglerVersion } from "../../package.json";
|
|
2
2
|
|
|
3
|
+
export const MAX_ASSET_COUNT = 20_000;
|
|
4
|
+
export const MAX_ASSET_SIZE = 25 * 1024 * 1024;
|
|
3
5
|
export const PAGES_CONFIG_CACHE_FILENAME = "pages.json";
|
|
4
6
|
export const MAX_BUCKET_SIZE = 50 * 1024 * 1024;
|
|
5
7
|
export const MAX_BUCKET_FILE_COUNT = 5000;
|
package/src/pages/upload.tsx
CHANGED
|
@@ -3,13 +3,17 @@ import { dirname, join, relative, resolve, sep } from "node:path";
|
|
|
3
3
|
import { render, Text } from "ink";
|
|
4
4
|
import Spinner from "ink-spinner";
|
|
5
5
|
import { getType } from "mime";
|
|
6
|
+
import { Minimatch } from "minimatch";
|
|
6
7
|
import PQueue from "p-queue";
|
|
7
8
|
import prettyBytes from "pretty-bytes";
|
|
8
9
|
import React from "react";
|
|
9
10
|
import { fetchResult } from "../cfetch";
|
|
10
11
|
import { FatalError } from "../errors";
|
|
12
|
+
import isInteractive from "../is-interactive";
|
|
11
13
|
import { logger } from "../logger";
|
|
12
14
|
import {
|
|
15
|
+
MAX_ASSET_COUNT,
|
|
16
|
+
MAX_ASSET_SIZE,
|
|
13
17
|
BULK_UPLOAD_CONCURRENCY,
|
|
14
18
|
MAX_BUCKET_FILE_COUNT,
|
|
15
19
|
MAX_BUCKET_SIZE,
|
|
@@ -96,10 +100,11 @@ export const upload = async (
|
|
|
96
100
|
"_redirects",
|
|
97
101
|
"_headers",
|
|
98
102
|
"_routes.json",
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
+
"functions",
|
|
104
|
+
"**/.DS_Store",
|
|
105
|
+
"**/node_modules",
|
|
106
|
+
"**/.git",
|
|
107
|
+
].map((pattern) => new Minimatch(pattern));
|
|
103
108
|
|
|
104
109
|
const directory = resolve(args.directory);
|
|
105
110
|
|
|
@@ -121,10 +126,13 @@ export const upload = async (
|
|
|
121
126
|
await Promise.all(
|
|
122
127
|
files.map(async (file) => {
|
|
123
128
|
const filepath = join(dir, file);
|
|
129
|
+
const relativeFilepath = relative(startingDir, filepath);
|
|
124
130
|
const filestat = await stat(filepath);
|
|
125
131
|
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
for (const minimatch of IGNORE_LIST) {
|
|
133
|
+
if (minimatch.match(relativeFilepath)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
if (filestat.isSymbolicLink()) {
|
|
@@ -134,12 +142,12 @@ export const upload = async (
|
|
|
134
142
|
if (filestat.isDirectory()) {
|
|
135
143
|
fileMap = await walk(filepath, fileMap, startingDir);
|
|
136
144
|
} else {
|
|
137
|
-
const name =
|
|
145
|
+
const name = relativeFilepath.split(sep).join("/");
|
|
138
146
|
|
|
139
|
-
if (filestat.size >
|
|
147
|
+
if (filestat.size > MAX_ASSET_SIZE) {
|
|
140
148
|
throw new FatalError(
|
|
141
149
|
`Error: Pages only supports files up to ${prettyBytes(
|
|
142
|
-
|
|
150
|
+
MAX_ASSET_SIZE
|
|
143
151
|
)} in size\n${name} is ${prettyBytes(filestat.size)} in size`,
|
|
144
152
|
1
|
|
145
153
|
);
|
|
@@ -161,9 +169,9 @@ export const upload = async (
|
|
|
161
169
|
|
|
162
170
|
const fileMap = await walk(directory);
|
|
163
171
|
|
|
164
|
-
if (fileMap.size >
|
|
172
|
+
if (fileMap.size > MAX_ASSET_COUNT) {
|
|
165
173
|
throw new FatalError(
|
|
166
|
-
`Error: Pages only supports up to
|
|
174
|
+
`Error: Pages only supports up to ${MAX_ASSET_COUNT.toLocaleString()} files in a deployment. Ensure you have specified your build output directory correctly.`,
|
|
167
175
|
1
|
|
168
176
|
);
|
|
169
177
|
}
|
|
@@ -289,7 +297,7 @@ export const upload = async (
|
|
|
289
297
|
setTimeout(resolvePromise, Math.pow(2, attempts++) * 1000)
|
|
290
298
|
);
|
|
291
299
|
|
|
292
|
-
if ((e as { code: number }).code === 8000013) {
|
|
300
|
+
if ((e as { code: number }).code === 8000013 || isJwtExpired(jwt)) {
|
|
293
301
|
// Looks like the JWT expired, fetch another one
|
|
294
302
|
jwt = await fetchJwt();
|
|
295
303
|
}
|
|
@@ -309,7 +317,9 @@ export const upload = async (
|
|
|
309
317
|
(error) => {
|
|
310
318
|
return Promise.reject(
|
|
311
319
|
new FatalError(
|
|
312
|
-
|
|
320
|
+
`Failed to upload files. Please try again. Error: ${JSON.stringify(
|
|
321
|
+
error
|
|
322
|
+
)})`,
|
|
313
323
|
error.code || 1
|
|
314
324
|
)
|
|
315
325
|
);
|
|
@@ -348,7 +358,7 @@ export const upload = async (
|
|
|
348
358
|
} catch (e) {
|
|
349
359
|
await new Promise((resolvePromise) => setTimeout(resolvePromise, 1000));
|
|
350
360
|
|
|
351
|
-
if ((e as { code: number }).code === 8000013) {
|
|
361
|
+
if ((e as { code: number }).code === 8000013 || isJwtExpired(jwt)) {
|
|
352
362
|
// Looks like the JWT expired, fetch another one
|
|
353
363
|
jwt = await fetchJwt();
|
|
354
364
|
}
|
|
@@ -382,6 +392,23 @@ export const upload = async (
|
|
|
382
392
|
);
|
|
383
393
|
};
|
|
384
394
|
|
|
395
|
+
// Decode and check that the current JWT has not expired
|
|
396
|
+
function isJwtExpired(token: string): boolean | undefined {
|
|
397
|
+
try {
|
|
398
|
+
const decodedJwt = JSON.parse(
|
|
399
|
+
Buffer.from(token.split(".")[1], "base64").toString()
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
const dateNow = new Date().getTime() / 1000;
|
|
403
|
+
|
|
404
|
+
return decodedJwt.exp <= dateNow;
|
|
405
|
+
} catch (e) {
|
|
406
|
+
if (e instanceof Error) {
|
|
407
|
+
throw new Error(`Invalid token: ${e.message}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
385
412
|
function formatTime(duration: number) {
|
|
386
413
|
return `(${(duration / 1000).toFixed(2)} sec)`;
|
|
387
414
|
}
|
|
@@ -390,7 +417,7 @@ function Progress({ done, total }: { done: number; total: number }) {
|
|
|
390
417
|
return (
|
|
391
418
|
<>
|
|
392
419
|
<Text>
|
|
393
|
-
<Spinner type="earth" />
|
|
420
|
+
{isInteractive() ? <Spinner type="earth" /> : null}
|
|
394
421
|
{` Uploading... (${done}/${total})\n`}
|
|
395
422
|
</Text>
|
|
396
423
|
</>
|