wrangler 2.0.0 → 2.0.3
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 +21 -1
- package/package.json +6 -4
- package/pages/functions/buildWorker.ts +1 -1
- package/pages/functions/template-plugin.ts +3 -2
- package/src/__tests__/configuration.test.ts +1 -1
- package/src/__tests__/dev.test.tsx +77 -10
- package/src/__tests__/index.test.ts +51 -58
- package/src/__tests__/jest.setup.ts +8 -0
- package/src/__tests__/kv.test.ts +69 -48
- package/src/__tests__/pages.test.ts +12 -14
- package/src/__tests__/parse.test.ts +4 -0
- package/src/__tests__/publish.test.ts +127 -6
- package/src/__tests__/r2.test.ts +12 -16
- package/src/bundle.ts +1 -1
- package/src/config/config.ts +1 -1
- package/src/config/validation.ts +1 -1
- package/src/dev/dev.tsx +5 -2
- package/src/entry.ts +64 -9
- package/src/index.tsx +55 -21
- package/src/kv.ts +3 -1
- package/src/pages.tsx +61 -45
- package/src/parse.ts +3 -1
- package/src/proxy.ts +4 -9
- package/src/user.tsx +11 -1
- package/wrangler-dist/cli.js +1015 -784
package/src/index.tsx
CHANGED
|
@@ -73,6 +73,7 @@ type ConfigPath = string | undefined;
|
|
|
73
73
|
|
|
74
74
|
const resetColor = "\x1b[0m";
|
|
75
75
|
const fgGreenColor = "\x1b[32m";
|
|
76
|
+
const DEFAULT_LOCAL_PORT = 8787;
|
|
76
77
|
|
|
77
78
|
function getRules(config: Config): Config["rules"] {
|
|
78
79
|
const rules = config.rules ?? config.build?.upload?.rules ?? [];
|
|
@@ -406,7 +407,17 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
406
407
|
const isInsideGitProject = Boolean(
|
|
407
408
|
await findUp(".git", { cwd: creationDirectory, type: "directory" })
|
|
408
409
|
);
|
|
409
|
-
|
|
410
|
+
let isGitInstalled;
|
|
411
|
+
try {
|
|
412
|
+
isGitInstalled = (await execa("git", ["--version"])).exitCode === 0;
|
|
413
|
+
} catch (err) {
|
|
414
|
+
if ((err as { code: string | undefined }).code !== "ENOENT") {
|
|
415
|
+
// only throw if the error is not because git is not installed
|
|
416
|
+
throw err;
|
|
417
|
+
} else {
|
|
418
|
+
isGitInstalled = false;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
410
421
|
if (!isInsideGitProject && isGitInstalled) {
|
|
411
422
|
const shouldInitGit =
|
|
412
423
|
yesFlag ||
|
|
@@ -712,7 +723,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
712
723
|
() => {
|
|
713
724
|
// "[DEPRECATED] 🦀 Build your project (if applicable)",
|
|
714
725
|
throw new DeprecationError(
|
|
715
|
-
"`wrangler build` has been deprecated, please refer to https://
|
|
726
|
+
"`wrangler build` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#build for alternatives"
|
|
716
727
|
);
|
|
717
728
|
}
|
|
718
729
|
);
|
|
@@ -725,7 +736,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
725
736
|
() => {
|
|
726
737
|
// "🕵️ Authenticate Wrangler with a Cloudflare API Token",
|
|
727
738
|
throw new DeprecationError(
|
|
728
|
-
"`wrangler config` has been deprecated, please refer to https://
|
|
739
|
+
"`wrangler config` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#config for alternatives"
|
|
729
740
|
);
|
|
730
741
|
}
|
|
731
742
|
);
|
|
@@ -869,6 +880,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
869
880
|
describe: "Enable dev tools",
|
|
870
881
|
type: "boolean",
|
|
871
882
|
deprecated: true,
|
|
883
|
+
})
|
|
884
|
+
.option("legacy-env", {
|
|
885
|
+
type: "boolean",
|
|
886
|
+
describe: "Use legacy environments",
|
|
887
|
+
hidden: true,
|
|
872
888
|
});
|
|
873
889
|
},
|
|
874
890
|
async (args) => {
|
|
@@ -995,7 +1011,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
995
1011
|
const nodeCompat = args.nodeCompat ?? config.node_compat;
|
|
996
1012
|
if (nodeCompat) {
|
|
997
1013
|
logger.warn(
|
|
998
|
-
"Enabling node.js compatibility mode for
|
|
1014
|
+
"Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
|
|
999
1015
|
);
|
|
1000
1016
|
}
|
|
1001
1017
|
|
|
@@ -1027,7 +1043,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1027
1043
|
args.siteExclude
|
|
1028
1044
|
)}
|
|
1029
1045
|
port={
|
|
1030
|
-
args.port ||
|
|
1046
|
+
args.port ||
|
|
1047
|
+
config.dev.port ||
|
|
1048
|
+
(await getPort({ port: DEFAULT_LOCAL_PORT }))
|
|
1031
1049
|
}
|
|
1032
1050
|
ip={args.ip || config.dev.ip}
|
|
1033
1051
|
inspectorPort={
|
|
@@ -1206,6 +1224,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1206
1224
|
.option("dry-run", {
|
|
1207
1225
|
describe: "Don't actually publish",
|
|
1208
1226
|
type: "boolean",
|
|
1227
|
+
})
|
|
1228
|
+
.option("legacy-env", {
|
|
1229
|
+
type: "boolean",
|
|
1230
|
+
describe: "Use legacy environments",
|
|
1231
|
+
hidden: true,
|
|
1209
1232
|
});
|
|
1210
1233
|
},
|
|
1211
1234
|
async (args) => {
|
|
@@ -1327,6 +1350,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1327
1350
|
default: false,
|
|
1328
1351
|
describe:
|
|
1329
1352
|
"If a log would have been filtered out, send it through anyway alongside the filter which would have blocked it.",
|
|
1353
|
+
})
|
|
1354
|
+
.option("legacy-env", {
|
|
1355
|
+
type: "boolean",
|
|
1356
|
+
describe: "Use legacy environments",
|
|
1357
|
+
hidden: true,
|
|
1330
1358
|
});
|
|
1331
1359
|
},
|
|
1332
1360
|
async (args) => {
|
|
@@ -1476,7 +1504,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1476
1504
|
enableLocalPersistence={false}
|
|
1477
1505
|
accountId={accountId}
|
|
1478
1506
|
assetPaths={undefined}
|
|
1479
|
-
port={
|
|
1507
|
+
port={
|
|
1508
|
+
config.dev.port || (await getPort({ port: DEFAULT_LOCAL_PORT }))
|
|
1509
|
+
}
|
|
1480
1510
|
ip={config.dev.ip}
|
|
1481
1511
|
public={undefined}
|
|
1482
1512
|
compatibilityDate={getDevCompatibilityDate(config)}
|
|
@@ -1623,7 +1653,7 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1623
1653
|
},
|
|
1624
1654
|
() => {
|
|
1625
1655
|
throw new DeprecationError(
|
|
1626
|
-
"`wrangler subdomain` has been deprecated, please refer to https://
|
|
1656
|
+
"`wrangler subdomain` has been deprecated, please refer to https://developers.cloudflare.com/workers/wrangler/migration/deprecations/#subdomain for alternatives"
|
|
1627
1657
|
);
|
|
1628
1658
|
}
|
|
1629
1659
|
);
|
|
@@ -1635,6 +1665,11 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1635
1665
|
(secretYargs) => {
|
|
1636
1666
|
return secretYargs
|
|
1637
1667
|
.command(subHelp)
|
|
1668
|
+
.option("legacy-env", {
|
|
1669
|
+
type: "boolean",
|
|
1670
|
+
describe: "Use legacy environments",
|
|
1671
|
+
hidden: true,
|
|
1672
|
+
})
|
|
1638
1673
|
.command(
|
|
1639
1674
|
"put <key>",
|
|
1640
1675
|
"Create or update a secret variable for a script",
|
|
@@ -1981,7 +2016,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
1981
2016
|
const accountId = await requireAuth(config);
|
|
1982
2017
|
|
|
1983
2018
|
await fetchResult<{ id: string }>(
|
|
1984
|
-
`/accounts/${accountId}/storage/kv/namespaces/${
|
|
2019
|
+
`/accounts/${accountId}/storage/kv/namespaces/${encodeURIComponent(
|
|
2020
|
+
id
|
|
2021
|
+
)}`,
|
|
1985
2022
|
{ method: "DELETE" }
|
|
1986
2023
|
);
|
|
1987
2024
|
|
|
@@ -2235,7 +2272,9 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2235
2272
|
const accountId = await requireAuth(config);
|
|
2236
2273
|
|
|
2237
2274
|
await fetchResult(
|
|
2238
|
-
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${
|
|
2275
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
2276
|
+
key
|
|
2277
|
+
)}`,
|
|
2239
2278
|
{ method: "DELETE" }
|
|
2240
2279
|
);
|
|
2241
2280
|
}
|
|
@@ -2604,19 +2643,14 @@ export async function main(argv: string[]): Promise<void> {
|
|
|
2604
2643
|
}
|
|
2605
2644
|
);
|
|
2606
2645
|
|
|
2607
|
-
wrangler
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
alias: "c",
|
|
2614
|
-
describe: "Path to .toml configuration file",
|
|
2615
|
-
type: "string",
|
|
2616
|
-
requiresArg: true,
|
|
2617
|
-
});
|
|
2646
|
+
wrangler.option("config", {
|
|
2647
|
+
alias: "c",
|
|
2648
|
+
describe: "Path to .toml configuration file",
|
|
2649
|
+
type: "string",
|
|
2650
|
+
requiresArg: true,
|
|
2651
|
+
});
|
|
2618
2652
|
|
|
2619
|
-
wrangler.group(["config", "help", "version"
|
|
2653
|
+
wrangler.group(["config", "help", "version"], "Flags:");
|
|
2620
2654
|
wrangler.help().alias("h", "help");
|
|
2621
2655
|
wrangler.version(wranglerVersion).alias("v", "version");
|
|
2622
2656
|
wrangler.exitProcess(false);
|
package/src/kv.ts
CHANGED
|
@@ -151,7 +151,9 @@ export async function putKeyValue(
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
return await fetchResult(
|
|
154
|
-
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${
|
|
154
|
+
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
155
|
+
keyValue.key
|
|
156
|
+
)}`,
|
|
155
157
|
{ method: "PUT", body: keyValue.value },
|
|
156
158
|
searchParams
|
|
157
159
|
);
|
package/src/pages.tsx
CHANGED
|
@@ -82,6 +82,8 @@ const PAGES_CONFIG_CACHE_FILENAME = "pages.json";
|
|
|
82
82
|
export const pagesBetaWarning =
|
|
83
83
|
"🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose";
|
|
84
84
|
|
|
85
|
+
const isInPagesCI = !!process.env.CF_PAGES;
|
|
86
|
+
|
|
85
87
|
const CLEANUP_CALLBACKS: (() => void)[] = [];
|
|
86
88
|
const CLEANUP = () => {
|
|
87
89
|
CLEANUP_CALLBACKS.forEach((callback) => callback());
|
|
@@ -802,34 +804,30 @@ const createDeployment: CommandModule<
|
|
|
802
804
|
return yargs
|
|
803
805
|
.positional("directory", {
|
|
804
806
|
type: "string",
|
|
805
|
-
|
|
806
|
-
description: "The directory of
|
|
807
|
+
demandOption: true,
|
|
808
|
+
description: "The directory of static files to upload",
|
|
807
809
|
})
|
|
808
810
|
.options({
|
|
809
811
|
"project-name": {
|
|
810
812
|
type: "string",
|
|
811
|
-
description:
|
|
812
|
-
"The name of the project you want to list deployments for",
|
|
813
|
+
description: "The name of the project you want to deploy to",
|
|
813
814
|
},
|
|
814
815
|
branch: {
|
|
815
816
|
type: "string",
|
|
816
|
-
description:
|
|
817
|
-
"The branch of the project you want to list deployments for",
|
|
817
|
+
description: "The name of the branch you want to deploy to",
|
|
818
818
|
},
|
|
819
819
|
"commit-hash": {
|
|
820
820
|
type: "string",
|
|
821
|
-
description:
|
|
822
|
-
"The branch of the project you want to list deployments for",
|
|
821
|
+
description: "The SHA to attach to this deployment",
|
|
823
822
|
},
|
|
824
823
|
"commit-message": {
|
|
825
824
|
type: "string",
|
|
826
|
-
description:
|
|
827
|
-
"The branch of the project you want to list deployments for",
|
|
825
|
+
description: "The commit message to attach to this deployment",
|
|
828
826
|
},
|
|
829
827
|
"commit-dirty": {
|
|
830
828
|
type: "boolean",
|
|
831
829
|
description:
|
|
832
|
-
"
|
|
830
|
+
"Whether or not the workspace should be considered dirty for this deployment",
|
|
833
831
|
},
|
|
834
832
|
})
|
|
835
833
|
.epilogue(pagesBetaWarning);
|
|
@@ -842,6 +840,10 @@ const createDeployment: CommandModule<
|
|
|
842
840
|
commitMessage,
|
|
843
841
|
commitDirty,
|
|
844
842
|
}) => {
|
|
843
|
+
if (!directory) {
|
|
844
|
+
throw new FatalError("Must specify a directory.", 1);
|
|
845
|
+
}
|
|
846
|
+
|
|
845
847
|
const config = getConfigCache<PagesConfigCache>(
|
|
846
848
|
PAGES_CONFIG_CACHE_FILENAME
|
|
847
849
|
);
|
|
@@ -851,40 +853,45 @@ const createDeployment: CommandModule<
|
|
|
851
853
|
|
|
852
854
|
const isInteractive = process.stdin.isTTY;
|
|
853
855
|
if (!projectName && isInteractive) {
|
|
854
|
-
const
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
856
|
+
const projects = (await listProjects({ accountId })).filter(
|
|
857
|
+
(project) => !project.source
|
|
858
|
+
);
|
|
859
|
+
|
|
860
|
+
let existingOrNew: "existing" | "new" = "new";
|
|
861
|
+
|
|
862
|
+
if (projects.length > 0) {
|
|
863
|
+
existingOrNew = await new Promise<"new" | "existing">((resolve) => {
|
|
864
|
+
const { unmount } = render(
|
|
865
|
+
<>
|
|
866
|
+
<Text>
|
|
867
|
+
No project selected. Would you like to create one or use an
|
|
868
|
+
existing project?
|
|
869
|
+
</Text>
|
|
870
|
+
<SelectInput
|
|
871
|
+
items={[
|
|
872
|
+
{
|
|
873
|
+
key: "new",
|
|
874
|
+
label: "Create a new project",
|
|
875
|
+
value: "new",
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
key: "existing",
|
|
879
|
+
label: "Use an existing project",
|
|
880
|
+
value: "existing",
|
|
881
|
+
},
|
|
882
|
+
]}
|
|
883
|
+
onSelect={async (selected) => {
|
|
884
|
+
resolve(selected.value as "new" | "existing");
|
|
885
|
+
unmount();
|
|
886
|
+
}}
|
|
887
|
+
/>
|
|
888
|
+
</>
|
|
889
|
+
);
|
|
890
|
+
});
|
|
891
|
+
}
|
|
882
892
|
|
|
883
893
|
switch (existingOrNew) {
|
|
884
894
|
case "existing": {
|
|
885
|
-
const projects = (await listProjects({ accountId })).filter(
|
|
886
|
-
(project) => !project.source
|
|
887
|
-
);
|
|
888
895
|
projectName = await new Promise((resolve) => {
|
|
889
896
|
const { unmount } = render(
|
|
890
897
|
<>
|
|
@@ -1569,6 +1576,10 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
1569
1576
|
default: false,
|
|
1570
1577
|
description: "Build a plugin rather than a Worker script",
|
|
1571
1578
|
},
|
|
1579
|
+
"build-output-directory": {
|
|
1580
|
+
type: "string",
|
|
1581
|
+
description: "The directory to output static assets to",
|
|
1582
|
+
},
|
|
1572
1583
|
})
|
|
1573
1584
|
.epilogue(pagesBetaWarning),
|
|
1574
1585
|
async ({
|
|
@@ -1580,9 +1591,14 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
1580
1591
|
fallbackService,
|
|
1581
1592
|
watch,
|
|
1582
1593
|
plugin,
|
|
1594
|
+
"build-output-directory": buildOutputDirectory,
|
|
1583
1595
|
}) => {
|
|
1584
|
-
|
|
1585
|
-
|
|
1596
|
+
if (!isInPagesCI) {
|
|
1597
|
+
// Beta message for `wrangler pages <commands>` usage
|
|
1598
|
+
logger.log(pagesBetaWarning);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
buildOutputDirectory ??= dirname(outfile);
|
|
1586
1602
|
|
|
1587
1603
|
await buildFunctions({
|
|
1588
1604
|
outfile,
|
|
@@ -1593,7 +1609,7 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
1593
1609
|
fallbackService,
|
|
1594
1610
|
watch,
|
|
1595
1611
|
plugin,
|
|
1596
|
-
buildOutputDirectory
|
|
1612
|
+
buildOutputDirectory,
|
|
1597
1613
|
});
|
|
1598
1614
|
}
|
|
1599
1615
|
)
|
package/src/parse.ts
CHANGED
|
@@ -77,7 +77,9 @@ type TomlError = Error & {
|
|
|
77
77
|
*/
|
|
78
78
|
export function parseTOML(input: string, file?: string): TOML.JsonMap | never {
|
|
79
79
|
try {
|
|
80
|
-
|
|
80
|
+
// Normalize CRLF to LF to avoid hitting https://github.com/iarna/iarna-toml/issues/33.
|
|
81
|
+
const normalizedInput = input.replace(/\r\n$/g, "\n");
|
|
82
|
+
return TOML.parse(normalizedInput);
|
|
81
83
|
} catch (err) {
|
|
82
84
|
const { name, message, line, col } = err as TomlError;
|
|
83
85
|
if (name !== TOML_ERROR_NAME) {
|
package/src/proxy.ts
CHANGED
|
@@ -210,6 +210,10 @@ export function usePreviewServer({
|
|
|
210
210
|
const request = message.pipe(remote.request(headers));
|
|
211
211
|
request.on("response", (responseHeaders) => {
|
|
212
212
|
const status = responseHeaders[":status"] ?? 500;
|
|
213
|
+
|
|
214
|
+
// log all requests to terminal
|
|
215
|
+
logger.log(new Date().toLocaleTimeString(), method, url, status);
|
|
216
|
+
|
|
213
217
|
rewriteRemoteHostToLocalHostInHeaders(
|
|
214
218
|
responseHeaders,
|
|
215
219
|
previewToken.host,
|
|
@@ -349,15 +353,6 @@ async function createProxyServer(
|
|
|
349
353
|
: createHttpServer();
|
|
350
354
|
|
|
351
355
|
return server
|
|
352
|
-
.on("request", function (req, res) {
|
|
353
|
-
// log all requests
|
|
354
|
-
logger.log(
|
|
355
|
-
new Date().toLocaleTimeString(),
|
|
356
|
-
req.method,
|
|
357
|
-
req.url,
|
|
358
|
-
res.statusCode
|
|
359
|
-
);
|
|
360
|
-
})
|
|
361
356
|
.on("upgrade", (req) => {
|
|
362
357
|
// log all websocket connections
|
|
363
358
|
logger.log(
|
package/src/user.tsx
CHANGED
|
@@ -214,6 +214,7 @@ import path from "node:path";
|
|
|
214
214
|
import url from "node:url";
|
|
215
215
|
import { TextEncoder } from "node:util";
|
|
216
216
|
import TOML from "@iarna/toml";
|
|
217
|
+
import { HostURL } from "@webcontainer/env";
|
|
217
218
|
import { render, Text } from "ink";
|
|
218
219
|
import SelectInput from "ink-select-input";
|
|
219
220
|
import Table from "ink-table";
|
|
@@ -339,9 +340,18 @@ export function validateScopeKeys(
|
|
|
339
340
|
const CLIENT_ID = "54d11594-84e4-41aa-b438-e81b8fa78ee7";
|
|
340
341
|
const AUTH_URL = "https://dash.cloudflare.com/oauth2/auth";
|
|
341
342
|
const TOKEN_URL = "https://dash.cloudflare.com/oauth2/token";
|
|
342
|
-
const CALLBACK_URL = "http://localhost:8976/oauth/callback";
|
|
343
343
|
const REVOKE_URL = "https://dash.cloudflare.com/oauth2/revoke";
|
|
344
344
|
|
|
345
|
+
/**
|
|
346
|
+
* To allow OAuth callbacks in environments such as WebContainer we need to
|
|
347
|
+
* create a host URL which only resolves `localhost` to a WebContainer
|
|
348
|
+
* hostname if the process is running in a WebContainer. On local this will
|
|
349
|
+
* be a no-op and it leaves the URL unmodified.
|
|
350
|
+
*
|
|
351
|
+
* @see https://www.npmjs.com/package/@webcontainer/env
|
|
352
|
+
*/
|
|
353
|
+
const CALLBACK_URL = HostURL.parse("http://localhost:8976/oauth/callback").href;
|
|
354
|
+
|
|
345
355
|
let LocalState: State = getAuthTokens();
|
|
346
356
|
|
|
347
357
|
/**
|