wrangler 2.0.3 → 2.0.7

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/src/kv.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { URLSearchParams } from "node:url";
2
2
  import { fetchListResult, fetchResult, fetchKVGetValue } from "./cfetch";
3
+ import { logger } from "./logger";
3
4
  import type { Config } from "./config";
4
5
 
5
6
  /** The largest number of kv items we can pass to the API in a single request. */
@@ -19,7 +20,7 @@ type KvArgs = {
19
20
  *
20
21
  * @returns the generated id of the created namespace.
21
22
  */
22
- export async function createNamespace(
23
+ export async function createKVNamespace(
23
24
  accountId: string,
24
25
  title: string
25
26
  ): Promise<string> {
@@ -51,7 +52,7 @@ export interface KVNamespaceInfo {
51
52
  /**
52
53
  * Fetch a list of all the namespaces under the given `accountId`.
53
54
  */
54
- export async function listNamespaces(
55
+ export async function listKVNamespaces(
55
56
  accountId: string
56
57
  ): Promise<KVNamespaceInfo[]> {
57
58
  const pageSize = 100;
@@ -83,7 +84,7 @@ export interface NamespaceKeyInfo {
83
84
  metadata?: { [key: string]: unknown };
84
85
  }
85
86
 
86
- export async function listNamespaceKeys(
87
+ export async function listKVNamespaceKeys(
87
88
  accountId: string,
88
89
  namespaceId: string,
89
90
  prefix = ""
@@ -95,6 +96,16 @@ export async function listNamespaceKeys(
95
96
  );
96
97
  }
97
98
 
99
+ export async function deleteKVNamespace(
100
+ accountId: string,
101
+ namespaceId: string
102
+ ) {
103
+ return await fetchResult<{ id: string }>(
104
+ `/accounts/${accountId}/storage/kv/namespaces/${namespaceId}`,
105
+ { method: "DELETE" }
106
+ );
107
+ }
108
+
98
109
  /**
99
110
  * Information about a key-value pair, including its "metadata" fields.
100
111
  */
@@ -116,12 +127,52 @@ const KeyValueKeys = new Set([
116
127
  "base64",
117
128
  ]);
118
129
 
130
+ /**
131
+ * The object has the specified property.
132
+ */
133
+ function hasProperty<T extends object>(
134
+ obj: object,
135
+ property: keyof T
136
+ ): obj is T {
137
+ return property in obj;
138
+ }
139
+
140
+ /**
141
+ * The object has a required property of the specified type.
142
+ */
143
+ function hasTypedProperty<T extends object>(
144
+ obj: object,
145
+ property: keyof T,
146
+ type: string
147
+ ): obj is T {
148
+ return hasProperty(obj, property) && typeof obj[property] === type;
149
+ }
150
+
151
+ /**
152
+ * The object an optional property, of the specified type.
153
+ */
154
+ function hasOptionalTypedProperty<T extends object>(
155
+ obj: object,
156
+ property: keyof T,
157
+ type: string
158
+ ): obj is Omit<T, typeof property> | T {
159
+ return !hasProperty(obj, property) || typeof obj[property] === type;
160
+ }
161
+
119
162
  /**
120
163
  * Is the given object a valid `KeyValue` type?
121
164
  */
122
- export function isKeyValue(keyValue: object): keyValue is KeyValue {
123
- const props = Object.keys(keyValue);
124
- if (!props.includes("key") || !props.includes("value")) {
165
+ export function isKVKeyValue(keyValue: unknown): keyValue is KeyValue {
166
+ if (
167
+ keyValue === null ||
168
+ typeof keyValue !== "object" ||
169
+ !hasTypedProperty(keyValue, "key", "string") ||
170
+ !hasTypedProperty(keyValue, "value", "string") ||
171
+ !hasOptionalTypedProperty(keyValue, "expiration", "number") ||
172
+ !hasOptionalTypedProperty(keyValue, "expiration_ttl", "number") ||
173
+ !hasOptionalTypedProperty(keyValue, "base64", "boolean") ||
174
+ !hasOptionalTypedProperty(keyValue, "metadata", "object")
175
+ ) {
125
176
  return false;
126
177
  }
127
178
  return true;
@@ -130,12 +181,12 @@ export function isKeyValue(keyValue: object): keyValue is KeyValue {
130
181
  /**
131
182
  * Get all the properties on the `keyValue` that are not expected.
132
183
  */
133
- export function unexpectedKeyValueProps(keyValue: KeyValue): string[] {
184
+ export function unexpectedKVKeyValueProps(keyValue: KeyValue): string[] {
134
185
  const props = Object.keys(keyValue);
135
186
  return props.filter((prop) => !KeyValueKeys.has(prop));
136
187
  }
137
188
 
138
- export async function putKeyValue(
189
+ export async function putKVKeyValue(
139
190
  accountId: string,
140
191
  namespaceId: string,
141
192
  keyValue: KeyValue
@@ -159,23 +210,58 @@ export async function putKeyValue(
159
210
  );
160
211
  }
161
212
 
162
- export async function getKeyValue(
213
+ export async function getKVKeyValue(
163
214
  accountId: string,
164
215
  namespaceId: string,
165
216
  key: string
166
217
  ): Promise<string> {
167
- return await fetchKVGetValue(accountId, namespaceId, key);
218
+ return await fetchKVGetValue(accountId, namespaceId, encodeURIComponent(key));
219
+ }
220
+
221
+ export async function deleteKVKeyValue(
222
+ accountId: string,
223
+ namespaceId: string,
224
+ key: string
225
+ ) {
226
+ return await fetchResult(
227
+ `/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(
228
+ key
229
+ )}`,
230
+ { method: "DELETE" }
231
+ );
168
232
  }
169
233
 
170
- export async function putBulkKeyValue(
234
+ /**
235
+ * Formatter for converting e.g. 5328 --> 5,328
236
+ */
237
+ const formatNumber = new Intl.NumberFormat("en-US", {
238
+ notation: "standard",
239
+ }).format;
240
+
241
+ /**
242
+ * Helper function for bulk requests, logs ongoing output to console.
243
+ */
244
+ function logBulkProgress(
245
+ operation: "put" | "delete",
246
+ index: number,
247
+ total: number
248
+ ) {
249
+ logger.log(
250
+ `${operation === "put" ? "Uploaded" : "Deleted"} ${Math.floor(
251
+ (100 * index) / total
252
+ )}% (${formatNumber(index)} out of ${formatNumber(total)})`
253
+ );
254
+ }
255
+
256
+ export async function putKVBulkKeyValue(
171
257
  accountId: string,
172
258
  namespaceId: string,
173
259
  keyValues: KeyValue[],
174
- progressCallback: (index: number, total: number) => void
260
+ quiet = false
175
261
  ) {
176
262
  for (let index = 0; index < keyValues.length; index += BATCH_KEY_MAX) {
177
- if (progressCallback && keyValues.length > BATCH_KEY_MAX) {
178
- progressCallback(index, keyValues.length);
263
+ if (!quiet && keyValues.length > BATCH_KEY_MAX) {
264
+ logBulkProgress("put", index, keyValues.length);
179
265
  }
180
266
 
181
267
  await fetchResult(
@@ -187,20 +273,21 @@ export async function putBulkKeyValue(
187
273
  }
188
274
  );
189
275
  }
190
- if (progressCallback && keyValues.length > BATCH_KEY_MAX) {
191
- progressCallback(keyValues.length, keyValues.length);
276
+
277
+ if (!quiet && keyValues.length > BATCH_KEY_MAX) {
278
+ logBulkProgress("put", keyValues.length, keyValues.length);
192
279
  }
193
280
  }
194
281
 
195
- export async function deleteBulkKeyValue(
282
+ export async function deleteKVBulkKeyValue(
196
283
  accountId: string,
197
284
  namespaceId: string,
198
285
  keys: string[],
199
- progressCallback: (index: number, total: number) => void
286
+ quiet = false
200
287
  ) {
201
288
  for (let index = 0; index < keys.length; index += BATCH_KEY_MAX) {
202
- if (progressCallback && keys.length > BATCH_KEY_MAX) {
203
- progressCallback(index, keys.length);
289
+ if (!quiet && keys.length > BATCH_KEY_MAX) {
290
+ logBulkProgress("delete", index, keys.length);
204
291
  }
205
292
 
206
293
  await fetchResult(
@@ -212,12 +299,12 @@ export async function deleteBulkKeyValue(
212
299
  }
213
300
  );
214
301
  }
215
- if (progressCallback && keys.length > BATCH_KEY_MAX) {
216
- progressCallback(keys.length, keys.length);
302
+ if (!quiet && keys.length > BATCH_KEY_MAX) {
303
+ logBulkProgress("delete", keys.length, keys.length);
217
304
  }
218
305
  }
219
306
 
220
- export function getNamespaceId(
307
+ export function getKVNamespaceId(
221
308
  { preview, binding, "namespace-id": namespaceId }: KvArgs,
222
309
  config: Config
223
310
  ): string {
@@ -312,7 +399,7 @@ export function getNamespaceId(
312
399
  /**
313
400
  * KV namespace binding names must be valid JS identifiers.
314
401
  */
315
- export function isValidNamespaceBinding(
402
+ export function isValidKVNamespaceBinding(
316
403
  binding: string | undefined
317
404
  ): binding is string {
318
405
  return (
@@ -8,19 +8,12 @@ import { logger } from "./logger";
8
8
  * StackBlitz, remote servers), it doesn't just crash the process.
9
9
  *
10
10
  * @param url the URL to point the browser at
11
- * @param options open a Chromium-based browser instead of the default
12
11
  */
13
- export default async function openInBrowser(
14
- url: string,
15
- { forceChromium }: { forceChromium: boolean } = { forceChromium: false }
16
- ): Promise<void> {
17
- const options: open.Options | undefined = forceChromium
18
- ? {
19
- app: [{ name: open.apps.chrome }, { name: open.apps.edge }],
20
- }
21
- : undefined;
22
- const childProcess = await open(url, options);
12
+ export default async function openInBrowser(url: string): Promise<void> {
13
+ const errorMessage = `Failed to open ${url} in a browser`;
14
+
15
+ const childProcess = await open(url);
23
16
  childProcess.on("error", () => {
24
- logger.warn(`Failed to open ${url} in a browser.`);
17
+ logger.warn(errorMessage);
25
18
  });
26
19
  }