wrangler 2.0.16 → 2.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/wrangler.js +42 -8
- package/miniflare-dist/index.mjs +1 -0
- package/package.json +65 -63
- package/src/__tests__/configuration.test.ts +11 -7
- package/src/__tests__/helpers/run-in-tmp.ts +22 -23
- package/src/__tests__/https-options.test.ts +51 -18
- package/src/__tests__/index.test.ts +13 -13
- package/src/__tests__/jest.setup.ts +13 -0
- package/src/__tests__/kv.test.ts +33 -2
- package/src/__tests__/metrics.test.ts +415 -0
- package/src/__tests__/pages.test.ts +15 -8
- package/src/__tests__/publish.test.ts +49 -23
- package/src/__tests__/secret.test.ts +84 -78
- package/src/__tests__/tail.test.ts +8 -0
- package/src/__tests__/test-old-node-version.js +31 -0
- package/src/__tests__/user.test.ts +7 -7
- package/src/__tests__/whoami.test.tsx +11 -1
- package/src/api/dev.ts +4 -1
- package/src/cli.ts +1 -1
- package/src/config/config.ts +8 -0
- package/src/config/validation.ts +9 -0
- package/src/config-cache.ts +2 -1
- package/src/dev/local.tsx +31 -25
- package/src/dev/remote.tsx +2 -2
- package/src/dev.tsx +6 -0
- package/src/entry.ts +1 -1
- package/src/{__tests__/helpers/faye-websocket.d.ts → faye-websocket.d.ts} +0 -0
- package/src/global-wrangler-config-path.ts +26 -0
- package/src/https-options.ts +8 -4
- package/src/index.tsx +120 -22
- package/src/kv.ts +23 -1
- package/src/metrics/index.ts +4 -0
- package/src/metrics/metrics-config.ts +222 -0
- package/src/metrics/metrics-dispatcher.ts +93 -0
- package/src/metrics/send-event.ts +80 -0
- package/src/miniflare-cli/index.ts +1 -0
- package/src/package-manager.ts +45 -0
- package/src/pages/build.tsx +2 -0
- package/src/pages/deployments.tsx +2 -0
- package/src/pages/dev.tsx +4 -0
- package/src/pages/projects.tsx +3 -0
- package/src/pages/publish.tsx +3 -0
- package/src/pages/upload.tsx +26 -14
- package/src/publish.ts +28 -15
- package/src/pubsub/pubsub-commands.tsx +43 -0
- package/src/user/user.tsx +29 -20
- package/src/worker-namespace.ts +16 -0
- package/templates/static-asset-facade.js +11 -5
- package/templates/tsconfig.json +2 -2
- package/wrangler-dist/cli.d.ts +298 -0
- package/wrangler-dist/cli.js +2589 -1659
package/src/dev.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import { getVarsForDev } from "./dev/dev-vars";
|
|
|
10
10
|
|
|
11
11
|
import { getEntry } from "./entry";
|
|
12
12
|
import { logger } from "./logger";
|
|
13
|
+
import * as metrics from "./metrics";
|
|
13
14
|
import { getAssetPaths, getSiteAssetPaths } from "./sites";
|
|
14
15
|
import { getAccountFromCache } from "./user";
|
|
15
16
|
import { getZoneIdFromHost, getZoneForRoute, getHostFromRoute } from "./zones";
|
|
@@ -264,6 +265,11 @@ export async function startDev(args: ArgumentsCamelCase<DevArgs>) {
|
|
|
264
265
|
((args.script &&
|
|
265
266
|
findWranglerToml(path.dirname(args.script))) as ConfigPath);
|
|
266
267
|
let config = readConfig(configPath, args);
|
|
268
|
+
metrics.sendMetricsEvent(
|
|
269
|
+
"run dev",
|
|
270
|
+
{ local: args.local },
|
|
271
|
+
{ sendMetrics: config.send_metrics, offline: args.local }
|
|
272
|
+
);
|
|
267
273
|
|
|
268
274
|
if (config.configPath) {
|
|
269
275
|
watcher = watch(config.configPath, {
|
package/src/entry.ts
CHANGED
|
@@ -39,7 +39,7 @@ export async function getEntry(
|
|
|
39
39
|
? path.resolve(config.site?.["entry-point"])
|
|
40
40
|
: // site.entry-point could be a directory
|
|
41
41
|
path.resolve(config.site?.["entry-point"], "index.js");
|
|
42
|
-
} else if (args.assets) {
|
|
42
|
+
} else if (args.assets || config.assets) {
|
|
43
43
|
file = path.resolve(__dirname, "../templates/no-op-worker.js");
|
|
44
44
|
} else {
|
|
45
45
|
throw new Error(
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import xdgAppPaths from "xdg-app-paths";
|
|
5
|
+
|
|
6
|
+
function isDirectory(configPath: string) {
|
|
7
|
+
try {
|
|
8
|
+
return fs.statSync(configPath).isDirectory();
|
|
9
|
+
} catch (error) {
|
|
10
|
+
// ignore error
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getGlobalWranglerConfigPath() {
|
|
16
|
+
//TODO: We should implement a custom path --global-config and/or the WRANGLER_HOME type environment variable
|
|
17
|
+
const configDir = xdgAppPaths(".wrangler").config(); // New XDG compliant config path
|
|
18
|
+
const legacyConfigDir = path.join(os.homedir(), ".wrangler"); // Legacy config in user's home directory
|
|
19
|
+
|
|
20
|
+
// Check for the .wrangler directory in root if it is not there then use the XDG compliant path.
|
|
21
|
+
if (isDirectory(legacyConfigDir)) {
|
|
22
|
+
return legacyConfigDir;
|
|
23
|
+
} else {
|
|
24
|
+
return configDir;
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/https-options.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
-
import
|
|
2
|
+
import os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
|
+
import { getGlobalWranglerConfigPath } from "./global-wrangler-config-path";
|
|
5
6
|
import { logger } from "./logger";
|
|
6
7
|
import type { Attributes, Options } from "selfsigned";
|
|
7
8
|
|
|
@@ -17,7 +18,7 @@ const ONE_DAY_IN_MS = 86400000;
|
|
|
17
18
|
* The certificates are self-signed and generated locally, and cached in the `CERT_ROOT` directory.
|
|
18
19
|
*/
|
|
19
20
|
export async function getHttpsOptions() {
|
|
20
|
-
const certDirectory = path.join(
|
|
21
|
+
const certDirectory = path.join(getGlobalWranglerConfigPath(), "local-cert");
|
|
21
22
|
const keyPath = path.join(certDirectory, "key.pem");
|
|
22
23
|
const certPath = path.join(certDirectory, "cert.pem");
|
|
23
24
|
|
|
@@ -37,7 +38,10 @@ export async function getHttpsOptions() {
|
|
|
37
38
|
} catch (e) {
|
|
38
39
|
const message = e instanceof Error ? e.message : `${e}`;
|
|
39
40
|
logger.warn(
|
|
40
|
-
`Unable to cache generated self-signed certificate in ${
|
|
41
|
+
`Unable to cache generated self-signed certificate in ${path.relative(
|
|
42
|
+
process.cwd(),
|
|
43
|
+
certDirectory
|
|
44
|
+
)}.\n${message}`
|
|
41
45
|
);
|
|
42
46
|
}
|
|
43
47
|
return { key, cert };
|
|
@@ -114,7 +118,7 @@ async function generateCertificate() {
|
|
|
114
118
|
*/
|
|
115
119
|
function getAccessibleHosts(ipv4 = false): string[] {
|
|
116
120
|
const hosts: string[] = [];
|
|
117
|
-
Object.values(networkInterfaces()).forEach((net) =>
|
|
121
|
+
Object.values(os.networkInterfaces()).forEach((net) =>
|
|
118
122
|
net?.forEach(({ family, address }) => {
|
|
119
123
|
if (!ipv4 || family === "IPv4") hosts.push(address);
|
|
120
124
|
})
|
package/src/index.tsx
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
deleteKVKeyValue,
|
|
34
34
|
} from "./kv";
|
|
35
35
|
import { logger } from "./logger";
|
|
36
|
+
import * as metrics from "./metrics";
|
|
36
37
|
import { pages } from "./pages";
|
|
37
38
|
import {
|
|
38
39
|
formatMessage,
|
|
@@ -64,6 +65,7 @@ import { whoami } from "./whoami";
|
|
|
64
65
|
|
|
65
66
|
import { workerNamespaceCommands } from "./worker-namespace";
|
|
66
67
|
import type { Config } from "./config";
|
|
68
|
+
import type { KeyValue } from "./kv";
|
|
67
69
|
import type { TailCLIFilters } from "./tail";
|
|
68
70
|
import type { RawData } from "ws";
|
|
69
71
|
import type { CommandModule } from "yargs";
|
|
@@ -382,7 +384,7 @@ function createCLIParser(argv: string[]) {
|
|
|
382
384
|
hidden: true,
|
|
383
385
|
})
|
|
384
386
|
.option("no-bundle", {
|
|
385
|
-
describe: "Skip internal build steps and directly publish
|
|
387
|
+
describe: "Skip internal build steps and directly publish Worker",
|
|
386
388
|
type: "boolean",
|
|
387
389
|
default: false,
|
|
388
390
|
})
|
|
@@ -474,7 +476,7 @@ function createCLIParser(argv: string[]) {
|
|
|
474
476
|
requiresArg: true,
|
|
475
477
|
})
|
|
476
478
|
.option("minify", {
|
|
477
|
-
describe: "Minify the
|
|
479
|
+
describe: "Minify the Worker",
|
|
478
480
|
type: "boolean",
|
|
479
481
|
})
|
|
480
482
|
.option("node-compat", {
|
|
@@ -499,6 +501,9 @@ function createCLIParser(argv: string[]) {
|
|
|
499
501
|
(args.config as ConfigPath) ||
|
|
500
502
|
(args.script && findWranglerToml(path.dirname(args.script)));
|
|
501
503
|
const config = readConfig(configPath, args);
|
|
504
|
+
metrics.sendMetricsEvent("deploy worker script", {
|
|
505
|
+
sendMetrics: config.send_metrics,
|
|
506
|
+
});
|
|
502
507
|
const entry = await getEntry(args, config, "publish");
|
|
503
508
|
|
|
504
509
|
if (args.public) {
|
|
@@ -639,11 +644,16 @@ function createCLIParser(argv: string[]) {
|
|
|
639
644
|
await printWranglerBanner();
|
|
640
645
|
}
|
|
641
646
|
const config = readConfig(args.config as ConfigPath, args);
|
|
647
|
+
metrics.sendMetricsEvent("begin log stream", {
|
|
648
|
+
sendMetrics: config.send_metrics,
|
|
649
|
+
});
|
|
642
650
|
|
|
643
651
|
const scriptName = getLegacyScriptName(args, config);
|
|
644
652
|
|
|
645
653
|
if (!scriptName) {
|
|
646
|
-
throw new Error(
|
|
654
|
+
throw new Error(
|
|
655
|
+
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `wrangler tail <worker-name>`"
|
|
656
|
+
);
|
|
647
657
|
}
|
|
648
658
|
|
|
649
659
|
const accountId = await requireAuth(config);
|
|
@@ -682,6 +692,9 @@ function createCLIParser(argv: string[]) {
|
|
|
682
692
|
onExit(async () => {
|
|
683
693
|
tail.terminate();
|
|
684
694
|
await deleteTail();
|
|
695
|
+
metrics.sendMetricsEvent("end log stream", {
|
|
696
|
+
sendMetrics: config.send_metrics,
|
|
697
|
+
});
|
|
685
698
|
});
|
|
686
699
|
|
|
687
700
|
const printLog: (data: RawData) => void =
|
|
@@ -698,6 +711,9 @@ function createCLIParser(argv: string[]) {
|
|
|
698
711
|
await setTimeout(100);
|
|
699
712
|
break;
|
|
700
713
|
case tail.CLOSED:
|
|
714
|
+
metrics.sendMetricsEvent("end log stream", {
|
|
715
|
+
sendMetrics: config.send_metrics,
|
|
716
|
+
});
|
|
701
717
|
throw new Error(
|
|
702
718
|
`Connection to ${scriptDisplayName} closed unexpectedly.`
|
|
703
719
|
);
|
|
@@ -711,6 +727,9 @@ function createCLIParser(argv: string[]) {
|
|
|
711
727
|
tail.on("close", async () => {
|
|
712
728
|
tail.terminate();
|
|
713
729
|
await deleteTail();
|
|
730
|
+
metrics.sendMetricsEvent("end log stream", {
|
|
731
|
+
sendMetrics: config.send_metrics,
|
|
732
|
+
});
|
|
714
733
|
});
|
|
715
734
|
}
|
|
716
735
|
);
|
|
@@ -820,7 +839,7 @@ function createCLIParser(argv: string[]) {
|
|
|
820
839
|
// secret
|
|
821
840
|
wrangler.command(
|
|
822
841
|
"secret",
|
|
823
|
-
"🤫 Generate a secret that can be referenced in
|
|
842
|
+
"🤫 Generate a secret that can be referenced in a Worker",
|
|
824
843
|
(secretYargs) => {
|
|
825
844
|
return secretYargs
|
|
826
845
|
.command(subHelp)
|
|
@@ -831,15 +850,15 @@ function createCLIParser(argv: string[]) {
|
|
|
831
850
|
})
|
|
832
851
|
.command(
|
|
833
852
|
"put <key>",
|
|
834
|
-
"Create or update a secret variable for a
|
|
853
|
+
"Create or update a secret variable for a Worker",
|
|
835
854
|
(yargs) => {
|
|
836
855
|
return yargs
|
|
837
856
|
.positional("key", {
|
|
838
|
-
describe: "The variable name to be accessible in the
|
|
857
|
+
describe: "The variable name to be accessible in the Worker",
|
|
839
858
|
type: "string",
|
|
840
859
|
})
|
|
841
860
|
.option("name", {
|
|
842
|
-
describe: "Name of the
|
|
861
|
+
describe: "Name of the Worker",
|
|
843
862
|
type: "string",
|
|
844
863
|
requiresArg: true,
|
|
845
864
|
})
|
|
@@ -857,7 +876,9 @@ function createCLIParser(argv: string[]) {
|
|
|
857
876
|
|
|
858
877
|
const scriptName = getLegacyScriptName(args, config);
|
|
859
878
|
if (!scriptName) {
|
|
860
|
-
throw new Error(
|
|
879
|
+
throw new Error(
|
|
880
|
+
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
881
|
+
);
|
|
861
882
|
}
|
|
862
883
|
|
|
863
884
|
const accountId = await requireAuth(config);
|
|
@@ -870,7 +891,7 @@ function createCLIParser(argv: string[]) {
|
|
|
870
891
|
);
|
|
871
892
|
|
|
872
893
|
logger.log(
|
|
873
|
-
`🌀 Creating the secret for
|
|
894
|
+
`🌀 Creating the secret for the Worker "${scriptName}" ${
|
|
874
895
|
args.env && !isLegacyEnv(config) ? `(${args.env})` : ""
|
|
875
896
|
}`
|
|
876
897
|
);
|
|
@@ -939,6 +960,9 @@ function createCLIParser(argv: string[]) {
|
|
|
939
960
|
|
|
940
961
|
try {
|
|
941
962
|
await submitSecret();
|
|
963
|
+
metrics.sendMetricsEvent("create encrypted variable", {
|
|
964
|
+
sendMetrics: config.send_metrics,
|
|
965
|
+
});
|
|
942
966
|
} catch (e) {
|
|
943
967
|
if (isMissingWorkerError(e)) {
|
|
944
968
|
// create a draft worker and try again
|
|
@@ -955,16 +979,16 @@ function createCLIParser(argv: string[]) {
|
|
|
955
979
|
)
|
|
956
980
|
.command(
|
|
957
981
|
"delete <key>",
|
|
958
|
-
"Delete a secret variable from a
|
|
982
|
+
"Delete a secret variable from a Worker",
|
|
959
983
|
async (yargs) => {
|
|
960
984
|
await printWranglerBanner();
|
|
961
985
|
return yargs
|
|
962
986
|
.positional("key", {
|
|
963
|
-
describe: "The variable name to be accessible in the
|
|
987
|
+
describe: "The variable name to be accessible in the Worker",
|
|
964
988
|
type: "string",
|
|
965
989
|
})
|
|
966
990
|
.option("name", {
|
|
967
|
-
describe: "Name of the
|
|
991
|
+
describe: "Name of the Worker",
|
|
968
992
|
type: "string",
|
|
969
993
|
requiresArg: true,
|
|
970
994
|
})
|
|
@@ -981,22 +1005,26 @@ function createCLIParser(argv: string[]) {
|
|
|
981
1005
|
|
|
982
1006
|
const scriptName = getLegacyScriptName(args, config);
|
|
983
1007
|
if (!scriptName) {
|
|
984
|
-
throw new Error(
|
|
1008
|
+
throw new Error(
|
|
1009
|
+
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
1010
|
+
);
|
|
985
1011
|
}
|
|
986
1012
|
|
|
987
1013
|
const accountId = await requireAuth(config);
|
|
988
1014
|
|
|
989
1015
|
if (
|
|
990
1016
|
await confirm(
|
|
991
|
-
`Are you sure you want to permanently delete the
|
|
1017
|
+
`Are you sure you want to permanently delete the secret ${
|
|
992
1018
|
args.key
|
|
993
|
-
} on the
|
|
1019
|
+
} on the Worker ${scriptName}${
|
|
994
1020
|
args.env && !isLegacyEnv(config) ? ` (${args.env})` : ""
|
|
995
1021
|
}?`
|
|
996
1022
|
)
|
|
997
1023
|
) {
|
|
998
1024
|
logger.log(
|
|
999
|
-
`🌀 Deleting the secret ${
|
|
1025
|
+
`🌀 Deleting the secret ${
|
|
1026
|
+
args.key
|
|
1027
|
+
} on the Worker ${scriptName}${
|
|
1000
1028
|
args.env && !isLegacyEnv(config) ? ` (${args.env})` : ""
|
|
1001
1029
|
}`
|
|
1002
1030
|
);
|
|
@@ -1007,17 +1035,20 @@ function createCLIParser(argv: string[]) {
|
|
|
1007
1035
|
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1008
1036
|
|
|
1009
1037
|
await fetchResult(`${url}/${args.key}`, { method: "DELETE" });
|
|
1038
|
+
metrics.sendMetricsEvent("delete encrypted variable", {
|
|
1039
|
+
sendMetrics: config.send_metrics,
|
|
1040
|
+
});
|
|
1010
1041
|
logger.log(`✨ Success! Deleted secret ${args.key}`);
|
|
1011
1042
|
}
|
|
1012
1043
|
}
|
|
1013
1044
|
)
|
|
1014
1045
|
.command(
|
|
1015
1046
|
"list",
|
|
1016
|
-
"List all secrets for a
|
|
1047
|
+
"List all secrets for a Worker",
|
|
1017
1048
|
(yargs) => {
|
|
1018
1049
|
return yargs
|
|
1019
1050
|
.option("name", {
|
|
1020
|
-
describe: "Name of the
|
|
1051
|
+
describe: "Name of the Worker",
|
|
1021
1052
|
type: "string",
|
|
1022
1053
|
requiresArg: true,
|
|
1023
1054
|
})
|
|
@@ -1034,7 +1065,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1034
1065
|
|
|
1035
1066
|
const scriptName = getLegacyScriptName(args, config);
|
|
1036
1067
|
if (!scriptName) {
|
|
1037
|
-
throw new Error(
|
|
1068
|
+
throw new Error(
|
|
1069
|
+
"Required Worker name missing. Please specify the Worker name in wrangler.toml, or pass it as an argument with `--name <worker-name>`"
|
|
1070
|
+
);
|
|
1038
1071
|
}
|
|
1039
1072
|
|
|
1040
1073
|
const accountId = await requireAuth(config);
|
|
@@ -1045,6 +1078,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1045
1078
|
: `/accounts/${accountId}/workers/services/${scriptName}/environments/${args.env}/secrets`;
|
|
1046
1079
|
|
|
1047
1080
|
logger.log(JSON.stringify(await fetchResult(url), null, " "));
|
|
1081
|
+
metrics.sendMetricsEvent("list encrypted variables", {
|
|
1082
|
+
sendMetrics: config.send_metrics,
|
|
1083
|
+
});
|
|
1048
1084
|
}
|
|
1049
1085
|
);
|
|
1050
1086
|
}
|
|
@@ -1106,6 +1142,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1106
1142
|
|
|
1107
1143
|
logger.log(`🌀 Creating namespace with title "${title}"`);
|
|
1108
1144
|
const namespaceId = await createKVNamespace(accountId, title);
|
|
1145
|
+
metrics.sendMetricsEvent("create kv namespace", {
|
|
1146
|
+
sendMetrics: config.send_metrics,
|
|
1147
|
+
});
|
|
1109
1148
|
|
|
1110
1149
|
logger.log("✨ Success!");
|
|
1111
1150
|
const envString = args.env ? ` under [env.${args.env}]` : "";
|
|
@@ -1134,6 +1173,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1134
1173
|
logger.log(
|
|
1135
1174
|
JSON.stringify(await listKVNamespaces(accountId), null, " ")
|
|
1136
1175
|
);
|
|
1176
|
+
metrics.sendMetricsEvent("list kv namespaces", {
|
|
1177
|
+
sendMetrics: config.send_metrics,
|
|
1178
|
+
});
|
|
1137
1179
|
}
|
|
1138
1180
|
)
|
|
1139
1181
|
.command(
|
|
@@ -1179,6 +1221,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1179
1221
|
const accountId = await requireAuth(config);
|
|
1180
1222
|
|
|
1181
1223
|
await deleteKVNamespace(accountId, id);
|
|
1224
|
+
metrics.sendMetricsEvent("delete kv namespace", {
|
|
1225
|
+
sendMetrics: config.send_metrics,
|
|
1226
|
+
});
|
|
1182
1227
|
|
|
1183
1228
|
// TODO: recommend they remove it from wrangler.toml
|
|
1184
1229
|
|
|
@@ -1253,6 +1298,15 @@ function createCLIParser(argv: string[]) {
|
|
|
1253
1298
|
describe:
|
|
1254
1299
|
"Time since the UNIX epoch after which the entry expires",
|
|
1255
1300
|
})
|
|
1301
|
+
.option("metadata", {
|
|
1302
|
+
type: "string",
|
|
1303
|
+
describe: "Arbitrary JSON that is associated with a key",
|
|
1304
|
+
coerce: (jsonStr: string): KeyValue["metadata"] => {
|
|
1305
|
+
try {
|
|
1306
|
+
return JSON.parse(jsonStr);
|
|
1307
|
+
} catch (_) {}
|
|
1308
|
+
},
|
|
1309
|
+
})
|
|
1256
1310
|
.option("path", {
|
|
1257
1311
|
type: "string",
|
|
1258
1312
|
requiresArg: true,
|
|
@@ -1260,7 +1314,7 @@ function createCLIParser(argv: string[]) {
|
|
|
1260
1314
|
})
|
|
1261
1315
|
.check(demandOneOfOption("value", "path"));
|
|
1262
1316
|
},
|
|
1263
|
-
async ({ key, ttl, expiration, ...args }) => {
|
|
1317
|
+
async ({ key, ttl, expiration, metadata, ...args }) => {
|
|
1264
1318
|
await printWranglerBanner();
|
|
1265
1319
|
const config = readConfig(args.config as ConfigPath, args);
|
|
1266
1320
|
const namespaceId = getKVNamespaceId(args, config);
|
|
@@ -1270,13 +1324,17 @@ function createCLIParser(argv: string[]) {
|
|
|
1270
1324
|
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1271
1325
|
args.value!;
|
|
1272
1326
|
|
|
1327
|
+
const metadataLog = metadata
|
|
1328
|
+
? ` with metadata "${JSON.stringify(metadata)}"`
|
|
1329
|
+
: "";
|
|
1330
|
+
|
|
1273
1331
|
if (args.path) {
|
|
1274
1332
|
logger.log(
|
|
1275
|
-
`Writing the contents of ${args.path} to the key "${key}" on namespace ${namespaceId}.`
|
|
1333
|
+
`Writing the contents of ${args.path} to the key "${key}" on namespace ${namespaceId}${metadataLog}.`
|
|
1276
1334
|
);
|
|
1277
1335
|
} else {
|
|
1278
1336
|
logger.log(
|
|
1279
|
-
`Writing the value "${value}" to key "${key}" on namespace ${namespaceId}.`
|
|
1337
|
+
`Writing the value "${value}" to key "${key}" on namespace ${namespaceId}${metadataLog}.`
|
|
1280
1338
|
);
|
|
1281
1339
|
}
|
|
1282
1340
|
|
|
@@ -1287,6 +1345,10 @@ function createCLIParser(argv: string[]) {
|
|
|
1287
1345
|
value,
|
|
1288
1346
|
expiration,
|
|
1289
1347
|
expiration_ttl: ttl,
|
|
1348
|
+
metadata: metadata as KeyValue["metadata"],
|
|
1349
|
+
});
|
|
1350
|
+
metrics.sendMetricsEvent("write kv key-value", {
|
|
1351
|
+
sendMetrics: config.send_metrics,
|
|
1290
1352
|
});
|
|
1291
1353
|
}
|
|
1292
1354
|
)
|
|
@@ -1337,6 +1399,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1337
1399
|
prefix
|
|
1338
1400
|
);
|
|
1339
1401
|
logger.log(JSON.stringify(results, undefined, 2));
|
|
1402
|
+
metrics.sendMetricsEvent("list kv keys", {
|
|
1403
|
+
sendMetrics: config.send_metrics,
|
|
1404
|
+
});
|
|
1340
1405
|
}
|
|
1341
1406
|
)
|
|
1342
1407
|
.command(
|
|
@@ -1397,6 +1462,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1397
1462
|
} else {
|
|
1398
1463
|
process.stdout.write(bufferKVValue);
|
|
1399
1464
|
}
|
|
1465
|
+
metrics.sendMetricsEvent("read kv value", {
|
|
1466
|
+
sendMetrics: config.send_metrics,
|
|
1467
|
+
});
|
|
1400
1468
|
}
|
|
1401
1469
|
)
|
|
1402
1470
|
.command(
|
|
@@ -1443,6 +1511,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1443
1511
|
const accountId = await requireAuth(config);
|
|
1444
1512
|
|
|
1445
1513
|
await deleteKVKeyValue(accountId, namespaceId, key);
|
|
1514
|
+
metrics.sendMetricsEvent("delete kv key-value", {
|
|
1515
|
+
sendMetrics: config.send_metrics,
|
|
1516
|
+
});
|
|
1446
1517
|
}
|
|
1447
1518
|
);
|
|
1448
1519
|
}
|
|
@@ -1547,6 +1618,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1547
1618
|
|
|
1548
1619
|
const accountId = await requireAuth(config);
|
|
1549
1620
|
await putKVBulkKeyValue(accountId, namespaceId, content);
|
|
1621
|
+
metrics.sendMetricsEvent("write kv key-values (bulk)", {
|
|
1622
|
+
sendMetrics: config.send_metrics,
|
|
1623
|
+
});
|
|
1550
1624
|
|
|
1551
1625
|
logger.log("Success!");
|
|
1552
1626
|
}
|
|
@@ -1637,6 +1711,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1637
1711
|
const accountId = await requireAuth(config);
|
|
1638
1712
|
|
|
1639
1713
|
await deleteKVBulkKeyValue(accountId, namespaceId, content);
|
|
1714
|
+
metrics.sendMetricsEvent("delete kv key-values (bulk)", {
|
|
1715
|
+
sendMetrics: config.send_metrics,
|
|
1716
|
+
});
|
|
1640
1717
|
|
|
1641
1718
|
logger.log("Success!");
|
|
1642
1719
|
}
|
|
@@ -1676,6 +1753,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1676
1753
|
logger.log(`Creating bucket ${args.name}.`);
|
|
1677
1754
|
await createR2Bucket(accountId, args.name);
|
|
1678
1755
|
logger.log(`Created bucket ${args.name}.`);
|
|
1756
|
+
metrics.sendMetricsEvent("create r2 bucket", {
|
|
1757
|
+
sendMetrics: config.send_metrics,
|
|
1758
|
+
});
|
|
1679
1759
|
}
|
|
1680
1760
|
);
|
|
1681
1761
|
|
|
@@ -1685,6 +1765,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1685
1765
|
const accountId = await requireAuth(config);
|
|
1686
1766
|
|
|
1687
1767
|
logger.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
|
|
1768
|
+
metrics.sendMetricsEvent("list r2 buckets", {
|
|
1769
|
+
sendMetrics: config.send_metrics,
|
|
1770
|
+
});
|
|
1688
1771
|
});
|
|
1689
1772
|
|
|
1690
1773
|
r2BucketYargs.command(
|
|
@@ -1707,6 +1790,9 @@ function createCLIParser(argv: string[]) {
|
|
|
1707
1790
|
logger.log(`Deleting bucket ${args.name}.`);
|
|
1708
1791
|
await deleteR2Bucket(accountId, args.name);
|
|
1709
1792
|
logger.log(`Deleted bucket ${args.name}.`);
|
|
1793
|
+
metrics.sendMetricsEvent("delete r2 bucket", {
|
|
1794
|
+
sendMetrics: config.send_metrics,
|
|
1795
|
+
});
|
|
1710
1796
|
}
|
|
1711
1797
|
);
|
|
1712
1798
|
return r2BucketYargs;
|
|
@@ -1775,6 +1861,10 @@ function createCLIParser(argv: string[]) {
|
|
|
1775
1861
|
return;
|
|
1776
1862
|
}
|
|
1777
1863
|
await login();
|
|
1864
|
+
const config = readConfig(args.config as ConfigPath, args);
|
|
1865
|
+
metrics.sendMetricsEvent("login user", {
|
|
1866
|
+
sendMetrics: config.send_metrics,
|
|
1867
|
+
});
|
|
1778
1868
|
|
|
1779
1869
|
// TODO: would be nice if it optionally saved login
|
|
1780
1870
|
// credentials inside node_modules/.cache or something
|
|
@@ -1791,6 +1881,10 @@ function createCLIParser(argv: string[]) {
|
|
|
1791
1881
|
async () => {
|
|
1792
1882
|
await printWranglerBanner();
|
|
1793
1883
|
await logout();
|
|
1884
|
+
const config = readConfig(undefined, {});
|
|
1885
|
+
metrics.sendMetricsEvent("logout user", {
|
|
1886
|
+
sendMetrics: config.send_metrics,
|
|
1887
|
+
});
|
|
1794
1888
|
}
|
|
1795
1889
|
);
|
|
1796
1890
|
|
|
@@ -1802,6 +1896,10 @@ function createCLIParser(argv: string[]) {
|
|
|
1802
1896
|
async () => {
|
|
1803
1897
|
await printWranglerBanner();
|
|
1804
1898
|
await whoami();
|
|
1899
|
+
const config = readConfig(undefined, {});
|
|
1900
|
+
metrics.sendMetricsEvent("view accounts", {
|
|
1901
|
+
sendMetrics: config.send_metrics,
|
|
1902
|
+
});
|
|
1805
1903
|
}
|
|
1806
1904
|
);
|
|
1807
1905
|
|
package/src/kv.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { URLSearchParams } from "node:url";
|
|
2
|
+
import { FormData } from "undici";
|
|
2
3
|
import { fetchListResult, fetchResult, fetchKVGetValue } from "./cfetch";
|
|
3
4
|
import { logger } from "./logger";
|
|
4
5
|
import type { Config } from "./config";
|
|
@@ -186,6 +187,19 @@ export function unexpectedKVKeyValueProps(keyValue: KeyValue): string[] {
|
|
|
186
187
|
return props.filter((prop) => !KeyValueKeys.has(prop));
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Turn object with fields into FormData
|
|
192
|
+
*/
|
|
193
|
+
function asFormData(fields: Record<string, unknown>): FormData {
|
|
194
|
+
const formData = new FormData();
|
|
195
|
+
|
|
196
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
197
|
+
formData.append(name, value);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return formData;
|
|
201
|
+
}
|
|
202
|
+
|
|
189
203
|
export async function putKVKeyValue(
|
|
190
204
|
accountId: string,
|
|
191
205
|
namespaceId: string,
|
|
@@ -205,7 +219,15 @@ export async function putKVKeyValue(
|
|
|
205
219
|
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
|
|
206
220
|
keyValue.key
|
|
207
221
|
)}`,
|
|
208
|
-
{
|
|
222
|
+
{
|
|
223
|
+
method: "PUT",
|
|
224
|
+
body: keyValue.metadata
|
|
225
|
+
? asFormData({
|
|
226
|
+
value: keyValue.value,
|
|
227
|
+
metadata: JSON.stringify(keyValue.metadata),
|
|
228
|
+
})
|
|
229
|
+
: keyValue.value,
|
|
230
|
+
},
|
|
209
231
|
searchParams
|
|
210
232
|
);
|
|
211
233
|
}
|