wrangler 2.0.7 → 2.0.11
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 +1 -1
- package/bin/wrangler.js +16 -4
- package/package.json +2 -2
- package/src/__tests__/configuration.test.ts +165 -70
- package/src/__tests__/dev.test.tsx +158 -66
- package/src/__tests__/helpers/mock-dialogs.ts +41 -1
- package/src/__tests__/init.test.ts +191 -111
- package/src/__tests__/kv.test.ts +8 -8
- package/src/__tests__/package-manager.test.ts +154 -7
- package/src/__tests__/pages.test.ts +115 -18
- package/src/__tests__/publish.test.ts +431 -140
- package/src/__tests__/secret.test.ts +4 -4
- package/src/__tests__/whoami.test.tsx +34 -0
- package/src/cfetch/index.ts +17 -2
- package/src/cfetch/internal.ts +12 -9
- package/src/config/config.ts +1 -1
- package/src/config/validation-helpers.ts +10 -1
- package/src/config/validation.ts +59 -33
- package/src/create-worker-preview.ts +15 -15
- package/src/dev/dev.tsx +4 -15
- package/src/dev/remote.tsx +26 -16
- package/src/dialogs.tsx +48 -0
- package/src/index.tsx +181 -167
- package/src/package-manager.ts +50 -3
- package/src/pages.tsx +298 -228
- package/src/publish.ts +148 -15
- package/src/sites.tsx +52 -14
- package/src/user.tsx +12 -1
- package/src/whoami.tsx +3 -2
- package/src/worker.ts +2 -1
- package/src/zones.ts +73 -0
- package/templates/new-worker-scheduled.js +17 -0
- package/templates/new-worker-scheduled.ts +32 -0
- package/wrangler-dist/cli.js +707 -407
package/src/index.tsx
CHANGED
|
@@ -15,11 +15,11 @@ import { setGlobalDispatcher, ProxyAgent } from "undici";
|
|
|
15
15
|
import makeCLI from "yargs";
|
|
16
16
|
import { version as wranglerVersion } from "../package.json";
|
|
17
17
|
import { fetchResult } from "./cfetch";
|
|
18
|
-
import { findWranglerToml, readConfig } from "./config";
|
|
18
|
+
import { findWranglerToml, printBindings, readConfig } from "./config";
|
|
19
19
|
import { createWorkerUploadForm } from "./create-worker-upload-form";
|
|
20
20
|
import Dev from "./dev/dev";
|
|
21
21
|
import { getVarsForDev } from "./dev/dev-vars";
|
|
22
|
-
import { confirm, prompt } from "./dialogs";
|
|
22
|
+
import { confirm, prompt, select } from "./dialogs";
|
|
23
23
|
import { getEntry } from "./entry";
|
|
24
24
|
import { DeprecationError } from "./errors";
|
|
25
25
|
import {
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
requireAuth,
|
|
67
67
|
} from "./user";
|
|
68
68
|
import { whoami } from "./whoami";
|
|
69
|
+
import { getZoneIdFromHost, getZoneForRoute } from "./zones";
|
|
69
70
|
|
|
70
71
|
import type { Config } from "./config";
|
|
71
72
|
import type { TailCLIFilters } from "./tail";
|
|
@@ -444,7 +445,10 @@ function createCLIParser(argv: string[]) {
|
|
|
444
445
|
yesFlag ||
|
|
445
446
|
(await confirm("Would you like to use git to manage this Worker?"));
|
|
446
447
|
if (shouldInitGit) {
|
|
447
|
-
await execa("git", ["init"
|
|
448
|
+
await execa("git", ["init"], {
|
|
449
|
+
cwd: creationDirectory,
|
|
450
|
+
});
|
|
451
|
+
await execa("git", ["branch", "-m", "main"], {
|
|
448
452
|
cwd: creationDirectory,
|
|
449
453
|
});
|
|
450
454
|
await writeFile(
|
|
@@ -628,21 +632,21 @@ function createCLIParser(argv: string[]) {
|
|
|
628
632
|
isWritingScripts: boolean,
|
|
629
633
|
isCreatingWranglerToml: boolean,
|
|
630
634
|
packagePath: string,
|
|
631
|
-
scriptPath: string
|
|
635
|
+
scriptPath: string,
|
|
636
|
+
extraToml: TOML.JsonMap
|
|
632
637
|
) {
|
|
633
638
|
if (isCreatingWranglerToml) {
|
|
634
|
-
// rewrite wrangler.toml with main = "path/to/script"
|
|
639
|
+
// rewrite wrangler.toml with main = "path/to/script" and any additional config specified in `extraToml`
|
|
635
640
|
const parsedWranglerToml = parseTOML(
|
|
636
641
|
readFileSync(wranglerTomlDestination)
|
|
637
642
|
);
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
);
|
|
643
|
+
const newToml = {
|
|
644
|
+
name: parsedWranglerToml.name,
|
|
645
|
+
main: scriptPath,
|
|
646
|
+
compatibility_date: parsedWranglerToml.compatibility_date,
|
|
647
|
+
...extraToml,
|
|
648
|
+
};
|
|
649
|
+
fs.writeFileSync(wranglerTomlDestination, TOML.stringify(newToml));
|
|
646
650
|
}
|
|
647
651
|
const isNamedWorker =
|
|
648
652
|
isCreatingWranglerToml && path.dirname(packagePath) !== process.cwd();
|
|
@@ -658,7 +662,7 @@ function createCLIParser(argv: string[]) {
|
|
|
658
662
|
start: isCreatingWranglerToml
|
|
659
663
|
? `wrangler dev`
|
|
660
664
|
: `wrangler dev ${scriptPath}`,
|
|
661
|
-
|
|
665
|
+
deploy: isCreatingWranglerToml
|
|
662
666
|
? `wrangler publish`
|
|
663
667
|
: `wrangler publish ${scriptPath}`,
|
|
664
668
|
},
|
|
@@ -673,7 +677,7 @@ function createCLIParser(argv: string[]) {
|
|
|
673
677
|
}npm start\``
|
|
674
678
|
);
|
|
675
679
|
instructions.push(
|
|
676
|
-
`To publish your Worker to the Internet, run \`npm run
|
|
680
|
+
`To publish your Worker to the Internet, run \`npm run deploy\``
|
|
677
681
|
);
|
|
678
682
|
} else {
|
|
679
683
|
instructions.push(
|
|
@@ -689,24 +693,75 @@ function createCLIParser(argv: string[]) {
|
|
|
689
693
|
}
|
|
690
694
|
}
|
|
691
695
|
|
|
696
|
+
async function getNewWorkerType(newWorkerFilename: string) {
|
|
697
|
+
return select(
|
|
698
|
+
`Would you like to create a Worker at ${newWorkerFilename}?`,
|
|
699
|
+
[
|
|
700
|
+
{
|
|
701
|
+
value: "none",
|
|
702
|
+
label: "None",
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
value: "fetch",
|
|
706
|
+
label: "Fetch handler",
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
value: "scheduled",
|
|
710
|
+
label: "Scheduled handler",
|
|
711
|
+
},
|
|
712
|
+
],
|
|
713
|
+
1
|
|
714
|
+
) as Promise<"none" | "fetch" | "scheduled">;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function getNewWorkerTemplate(
|
|
718
|
+
lang: "js" | "ts",
|
|
719
|
+
workerType: "fetch" | "scheduled"
|
|
720
|
+
) {
|
|
721
|
+
const templates = {
|
|
722
|
+
"js-fetch": "new-worker.js",
|
|
723
|
+
"js-scheduled": "new-worker-scheduled.js",
|
|
724
|
+
"ts-fetch": "new-worker.ts",
|
|
725
|
+
"ts-scheduled": "new-worker-scheduled.ts",
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
return templates[`${lang}-${workerType}`];
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
function getNewWorkerToml(
|
|
732
|
+
workerType: "fetch" | "scheduled"
|
|
733
|
+
): TOML.JsonMap {
|
|
734
|
+
if (workerType === "scheduled") {
|
|
735
|
+
return {
|
|
736
|
+
triggers: {
|
|
737
|
+
crons: ["1 * * * *"],
|
|
738
|
+
},
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return {};
|
|
743
|
+
}
|
|
744
|
+
|
|
692
745
|
if (isTypescriptProject) {
|
|
693
746
|
if (!fs.existsSync(path.join(creationDirectory, "./src/index.ts"))) {
|
|
694
|
-
const
|
|
695
|
-
|
|
696
|
-
(
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
)
|
|
747
|
+
const newWorkerFilename = path.relative(
|
|
748
|
+
process.cwd(),
|
|
749
|
+
path.join(creationDirectory, "./src/index.ts")
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
const newWorkerType = yesFlag
|
|
753
|
+
? "fetch"
|
|
754
|
+
: await getNewWorkerType(newWorkerFilename);
|
|
755
|
+
|
|
756
|
+
if (newWorkerType !== "none") {
|
|
757
|
+
const template = getNewWorkerTemplate("ts", newWorkerType);
|
|
702
758
|
|
|
703
|
-
if (shouldCreateSource) {
|
|
704
759
|
await mkdir(path.join(creationDirectory, "./src"), {
|
|
705
760
|
recursive: true,
|
|
706
761
|
});
|
|
707
762
|
await writeFile(
|
|
708
763
|
path.join(creationDirectory, "./src/index.ts"),
|
|
709
|
-
readFileSync(path.join(__dirname,
|
|
764
|
+
readFileSync(path.join(__dirname, `../templates/${template}`))
|
|
710
765
|
);
|
|
711
766
|
|
|
712
767
|
logger.log(
|
|
@@ -720,28 +775,31 @@ function createCLIParser(argv: string[]) {
|
|
|
720
775
|
shouldWritePackageJsonScripts,
|
|
721
776
|
justCreatedWranglerToml,
|
|
722
777
|
pathToPackageJson,
|
|
723
|
-
"src/index.ts"
|
|
778
|
+
"src/index.ts",
|
|
779
|
+
getNewWorkerToml(newWorkerType)
|
|
724
780
|
);
|
|
725
781
|
}
|
|
726
782
|
}
|
|
727
783
|
} else {
|
|
728
784
|
if (!fs.existsSync(path.join(creationDirectory, "./src/index.js"))) {
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
(
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
)
|
|
785
|
+
const newWorkerFilename = path.relative(
|
|
786
|
+
process.cwd(),
|
|
787
|
+
path.join(creationDirectory, "./src/index.js")
|
|
788
|
+
);
|
|
789
|
+
|
|
790
|
+
const newWorkerType = yesFlag
|
|
791
|
+
? "fetch"
|
|
792
|
+
: await getNewWorkerType(newWorkerFilename);
|
|
793
|
+
|
|
794
|
+
if (newWorkerType !== "none") {
|
|
795
|
+
const template = getNewWorkerTemplate("js", newWorkerType);
|
|
737
796
|
|
|
738
|
-
if (shouldCreateSource) {
|
|
739
797
|
await mkdir(path.join(creationDirectory, "./src"), {
|
|
740
798
|
recursive: true,
|
|
741
799
|
});
|
|
742
800
|
await writeFile(
|
|
743
801
|
path.join(creationDirectory, "./src/index.js"),
|
|
744
|
-
readFileSync(path.join(__dirname,
|
|
802
|
+
readFileSync(path.join(__dirname, `../templates/${template}`))
|
|
745
803
|
);
|
|
746
804
|
|
|
747
805
|
logger.log(
|
|
@@ -755,7 +813,8 @@ function createCLIParser(argv: string[]) {
|
|
|
755
813
|
shouldWritePackageJsonScripts,
|
|
756
814
|
justCreatedWranglerToml,
|
|
757
815
|
pathToPackageJson,
|
|
758
|
-
"src/index.js"
|
|
816
|
+
"src/index.js",
|
|
817
|
+
getNewWorkerToml(newWorkerType)
|
|
759
818
|
);
|
|
760
819
|
}
|
|
761
820
|
}
|
|
@@ -1024,92 +1083,25 @@ function createCLIParser(argv: string[]) {
|
|
|
1024
1083
|
);
|
|
1025
1084
|
}
|
|
1026
1085
|
|
|
1027
|
-
const accountId = !args.local ? await requireAuth(config) : undefined;
|
|
1028
|
-
|
|
1029
1086
|
// TODO: if worker_dev = false and no routes, then error (only for dev)
|
|
1030
1087
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
*/
|
|
1035
|
-
function getHost(urlLike: string): string | undefined {
|
|
1036
|
-
// strip leading * / *.
|
|
1037
|
-
urlLike = urlLike.replace(/^\*(\.)?/g, "");
|
|
1038
|
-
|
|
1039
|
-
if (
|
|
1040
|
-
!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))
|
|
1041
|
-
) {
|
|
1042
|
-
urlLike = "http://" + urlLike;
|
|
1043
|
-
}
|
|
1044
|
-
return new URL(urlLike).host;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
/**
|
|
1048
|
-
* Given something that resembles a host,
|
|
1049
|
-
* try to infer a zone id from it
|
|
1050
|
-
*/
|
|
1051
|
-
async function getZoneId(host: string): Promise<string | undefined> {
|
|
1052
|
-
const zones = await fetchResult<{ id: string }[]>(
|
|
1053
|
-
`/zones`,
|
|
1054
|
-
{},
|
|
1055
|
-
new URLSearchParams({ name: host })
|
|
1056
|
-
);
|
|
1057
|
-
return zones[0]?.id;
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
// When we're given a host (in one of the above ways), we do 2 things:
|
|
1061
|
-
// - We try to extract a host from it
|
|
1062
|
-
// - We try to get a zone id from the host
|
|
1063
|
-
//
|
|
1064
|
-
// So it turns out it's particularly hard to get a 'valid' domain
|
|
1065
|
-
// from a string, so we don't even try to validate TLDs, etc.
|
|
1066
|
-
// Once we get something that looks like w.x.y.z-ish, we then try to
|
|
1067
|
-
// get a zone id for it, by lopping off subdomains until we get a hit
|
|
1068
|
-
// from the API. That's it!
|
|
1069
|
-
|
|
1070
|
-
let zone: { host: string; id: string } | undefined;
|
|
1088
|
+
// Compute zone info from the `host` and `route` args and config;
|
|
1089
|
+
let host = args.host || config.dev.host;
|
|
1090
|
+
let zoneId: string | undefined;
|
|
1071
1091
|
|
|
1072
1092
|
if (!args.local) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
config.dev.host ||
|
|
1076
|
-
(args.routes && args.routes[0]) ||
|
|
1077
|
-
config.route ||
|
|
1078
|
-
(config.routes && config.routes[0]);
|
|
1079
|
-
|
|
1080
|
-
let zoneId: string | undefined =
|
|
1081
|
-
typeof hostLike === "object" && "zone_id" in hostLike
|
|
1082
|
-
? hostLike.zone_id
|
|
1083
|
-
: undefined;
|
|
1084
|
-
|
|
1085
|
-
const host =
|
|
1086
|
-
typeof hostLike === "string"
|
|
1087
|
-
? getHost(hostLike)
|
|
1088
|
-
: typeof hostLike === "object"
|
|
1089
|
-
? "zone_name" in hostLike
|
|
1090
|
-
? getHost(hostLike.zone_name)
|
|
1091
|
-
: getHost(hostLike.pattern)
|
|
1092
|
-
: undefined;
|
|
1093
|
-
|
|
1094
|
-
const hostPieces =
|
|
1095
|
-
typeof host === "string" ? host.split(".") : undefined;
|
|
1096
|
-
|
|
1097
|
-
while (!zoneId && hostPieces && hostPieces.length > 1) {
|
|
1098
|
-
zoneId = await getZoneId(hostPieces.join("."));
|
|
1099
|
-
hostPieces.shift();
|
|
1093
|
+
if (host) {
|
|
1094
|
+
zoneId = await getZoneIdFromHost(host);
|
|
1100
1095
|
}
|
|
1101
|
-
|
|
1102
|
-
if (
|
|
1103
|
-
|
|
1096
|
+
const routes = args.routes || config.route || config.routes;
|
|
1097
|
+
if (!zoneId && routes) {
|
|
1098
|
+
const firstRoute = Array.isArray(routes) ? routes[0] : routes;
|
|
1099
|
+
const zone = await getZoneForRoute(firstRoute);
|
|
1100
|
+
if (zone) {
|
|
1101
|
+
zoneId = zone.id;
|
|
1102
|
+
host = zone.host;
|
|
1103
|
+
}
|
|
1104
1104
|
}
|
|
1105
|
-
|
|
1106
|
-
zone =
|
|
1107
|
-
typeof zoneId === "string" && typeof host === "string"
|
|
1108
|
-
? {
|
|
1109
|
-
host,
|
|
1110
|
-
id: zoneId,
|
|
1111
|
-
}
|
|
1112
|
-
: undefined;
|
|
1113
1105
|
}
|
|
1114
1106
|
|
|
1115
1107
|
const nodeCompat = args.nodeCompat ?? config.node_compat;
|
|
@@ -1119,12 +1111,77 @@ function createCLIParser(argv: string[]) {
|
|
|
1119
1111
|
);
|
|
1120
1112
|
}
|
|
1121
1113
|
|
|
1114
|
+
const bindings = {
|
|
1115
|
+
kv_namespaces: config.kv_namespaces?.map(
|
|
1116
|
+
({ binding, preview_id, id: _id }) => {
|
|
1117
|
+
// In `dev`, we make folks use a separate kv namespace called
|
|
1118
|
+
// `preview_id` instead of `id` so that they don't
|
|
1119
|
+
// break production data. So here we check that a `preview_id`
|
|
1120
|
+
// has actually been configured.
|
|
1121
|
+
// This whole block of code will be obsoleted in the future
|
|
1122
|
+
// when we have copy-on-write for previews on edge workers.
|
|
1123
|
+
if (!preview_id) {
|
|
1124
|
+
// TODO: This error has to be a _lot_ better, ideally just asking
|
|
1125
|
+
// to create a preview namespace for the user automatically
|
|
1126
|
+
throw new Error(
|
|
1127
|
+
`In development, you should use a separate kv namespace than the one you'd use in production. Please create a new kv namespace with "wrangler kv:namespace create <name> --preview" and add its id as preview_id to the kv_namespace "${binding}" in your wrangler.toml`
|
|
1128
|
+
); // Ugh, I really don't like this message very much
|
|
1129
|
+
}
|
|
1130
|
+
return {
|
|
1131
|
+
binding,
|
|
1132
|
+
id: preview_id,
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
),
|
|
1136
|
+
// Use a copy of combinedVars since we're modifying it later
|
|
1137
|
+
vars: getVarsForDev(config),
|
|
1138
|
+
wasm_modules: config.wasm_modules,
|
|
1139
|
+
text_blobs: config.text_blobs,
|
|
1140
|
+
data_blobs: config.data_blobs,
|
|
1141
|
+
durable_objects: config.durable_objects,
|
|
1142
|
+
r2_buckets: config.r2_buckets?.map(
|
|
1143
|
+
({ binding, preview_bucket_name, bucket_name: _bucket_name }) => {
|
|
1144
|
+
// same idea as kv namespace preview id,
|
|
1145
|
+
// same copy-on-write TODO
|
|
1146
|
+
if (!preview_bucket_name) {
|
|
1147
|
+
throw new Error(
|
|
1148
|
+
`In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your wrangler.toml`
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
return {
|
|
1152
|
+
binding,
|
|
1153
|
+
bucket_name: preview_bucket_name,
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
),
|
|
1157
|
+
services: config.services,
|
|
1158
|
+
unsafe: config.unsafe?.bindings,
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1161
|
+
// mask anything that was overridden in .dev.vars
|
|
1162
|
+
// so that we don't log potential secrets into the terminal
|
|
1163
|
+
const maskedVars = { ...bindings.vars };
|
|
1164
|
+
for (const key of Object.keys(maskedVars)) {
|
|
1165
|
+
if (maskedVars[key] !== config.vars[key]) {
|
|
1166
|
+
// This means it was overridden in .dev.vars
|
|
1167
|
+
// so let's mask it
|
|
1168
|
+
maskedVars[key] = "(hidden)";
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
// now log all available bindings into the terminal
|
|
1173
|
+
printBindings({
|
|
1174
|
+
...bindings,
|
|
1175
|
+
vars: maskedVars,
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1122
1178
|
const { waitUntilExit } = render(
|
|
1123
1179
|
<Dev
|
|
1124
1180
|
name={getScriptName(args, config)}
|
|
1125
1181
|
entry={entry}
|
|
1126
1182
|
env={args.env}
|
|
1127
|
-
zone={
|
|
1183
|
+
zone={zoneId}
|
|
1184
|
+
host={host}
|
|
1128
1185
|
rules={getRules(config)}
|
|
1129
1186
|
legacyEnv={isLegacyEnv(config)}
|
|
1130
1187
|
minify={args.minify ?? config.minify}
|
|
@@ -1139,7 +1196,7 @@ function createCLIParser(argv: string[]) {
|
|
|
1139
1196
|
enableLocalPersistence={
|
|
1140
1197
|
args["experimental-enable-local-persistence"] || false
|
|
1141
1198
|
}
|
|
1142
|
-
accountId={
|
|
1199
|
+
accountId={config.account_id}
|
|
1143
1200
|
assetPaths={getAssetPaths(
|
|
1144
1201
|
config,
|
|
1145
1202
|
args.site,
|
|
@@ -1164,51 +1221,7 @@ function createCLIParser(argv: string[]) {
|
|
|
1164
1221
|
args["compatibility-flags"] || config.compatibility_flags
|
|
1165
1222
|
}
|
|
1166
1223
|
usageModel={config.usage_model}
|
|
1167
|
-
bindings={
|
|
1168
|
-
kv_namespaces: config.kv_namespaces?.map(
|
|
1169
|
-
({ binding, preview_id, id: _id }) => {
|
|
1170
|
-
// In `dev`, we make folks use a separate kv namespace called
|
|
1171
|
-
// `preview_id` instead of `id` so that they don't
|
|
1172
|
-
// break production data. So here we check that a `preview_id`
|
|
1173
|
-
// has actually been configured.
|
|
1174
|
-
// This whole block of code will be obsoleted in the future
|
|
1175
|
-
// when we have copy-on-write for previews on edge workers.
|
|
1176
|
-
if (!preview_id) {
|
|
1177
|
-
// TODO: This error has to be a _lot_ better, ideally just asking
|
|
1178
|
-
// to create a preview namespace for the user automatically
|
|
1179
|
-
throw new Error(
|
|
1180
|
-
`In development, you should use a separate kv namespace than the one you'd use in production. Please create a new kv namespace with "wrangler kv:namespace create <name> --preview" and add its id as preview_id to the kv_namespace "${binding}" in your wrangler.toml`
|
|
1181
|
-
); // Ugh, I really don't like this message very much
|
|
1182
|
-
}
|
|
1183
|
-
return {
|
|
1184
|
-
binding,
|
|
1185
|
-
id: preview_id,
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
),
|
|
1189
|
-
vars: getVarsForDev(config),
|
|
1190
|
-
wasm_modules: config.wasm_modules,
|
|
1191
|
-
text_blobs: config.text_blobs,
|
|
1192
|
-
data_blobs: config.data_blobs,
|
|
1193
|
-
durable_objects: config.durable_objects,
|
|
1194
|
-
r2_buckets: config.r2_buckets?.map(
|
|
1195
|
-
({ binding, preview_bucket_name, bucket_name: _bucket_name }) => {
|
|
1196
|
-
// same idea as kv namespace preview id,
|
|
1197
|
-
// same copy-on-write TODO
|
|
1198
|
-
if (!preview_bucket_name) {
|
|
1199
|
-
throw new Error(
|
|
1200
|
-
`In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your wrangler.toml`
|
|
1201
|
-
);
|
|
1202
|
-
}
|
|
1203
|
-
return {
|
|
1204
|
-
binding,
|
|
1205
|
-
bucket_name: preview_bucket_name,
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
),
|
|
1209
|
-
services: config.services,
|
|
1210
|
-
unsafe: config.unsafe?.bindings,
|
|
1211
|
-
}}
|
|
1224
|
+
bindings={bindings}
|
|
1212
1225
|
crons={config.triggers.crons}
|
|
1213
1226
|
/>
|
|
1214
1227
|
);
|
|
@@ -1597,6 +1610,7 @@ function createCLIParser(argv: string[]) {
|
|
|
1597
1610
|
rules={getRules(config)}
|
|
1598
1611
|
env={args.env}
|
|
1599
1612
|
zone={undefined}
|
|
1613
|
+
host={undefined}
|
|
1600
1614
|
legacyEnv={isLegacyEnv(config)}
|
|
1601
1615
|
build={config.build || {}}
|
|
1602
1616
|
minify={undefined}
|
|
@@ -2752,14 +2766,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2752
2766
|
await createCLIParser([...argv, "--help"]).parse();
|
|
2753
2767
|
} else if (e instanceof ParseError) {
|
|
2754
2768
|
e.notes.push({
|
|
2755
|
-
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new",
|
|
2769
|
+
text: "\nIf you think this is a bug, please open an issue at: https://github.com/cloudflare/wrangler2/issues/new/choose",
|
|
2756
2770
|
});
|
|
2757
|
-
logger.
|
|
2771
|
+
logger.log(formatMessage(e));
|
|
2758
2772
|
} else {
|
|
2759
2773
|
logger.error(e instanceof Error ? e.message : e);
|
|
2760
2774
|
logger.log(
|
|
2761
2775
|
`${fgGreenColor}%s${resetColor}`,
|
|
2762
|
-
"If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new
|
|
2776
|
+
"If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
2763
2777
|
);
|
|
2764
2778
|
}
|
|
2765
2779
|
throw e;
|
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
|
+
}
|