Skip to content

Commit 901764c

Browse files
committed
fix KV namespace ID
1 parent c37e1f5 commit 901764c

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

packages/wrangler/src/deployment-bundle/bindings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ export async function provisionBindings(
546546
}
547547
}
548548

549-
function getSettings(
549+
export function getSettings(
550550
complianceConfig: ComplianceConfig,
551551
accountId: string,
552552
scriptName: string

packages/wrangler/src/kv/helpers.ts

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import assert from "node:assert";
12
import { Blob } from "node:buffer";
23
import { URLSearchParams } from "node:url";
34
import { type KVNamespace } from "@cloudflare/workers-types/experimental";
45
import { Miniflare } from "miniflare";
56
import { FormData } from "undici";
67
import { fetchKVGetValue, fetchListResult, fetchResult } from "../cfetch";
8+
import { getSettings } from "../deployment-bundle/bindings";
79
import { getLocalPersistencePath } from "../dev/get-local-persistence-path";
810
import { getDefaultPersistRoot } from "../dev/miniflare";
911
import { UserError } from "../errors";
12+
import { getFlag } from "../experimental-flags";
1013
import { logger } from "../logger";
14+
import { requireAuth } from "../user";
1115
import type { Config } from "../config";
1216
import type { ComplianceConfig } from "../environment-variables/misc-variables";
1317
import type { ReplaceWorkersTypes } from "miniflare";
@@ -420,10 +424,38 @@ export async function deleteKVBulkKeyValue(
420424
}
421425
}
422426

423-
export function getKVNamespaceId(
427+
async function getIdFromSettings(
428+
config: Config,
429+
binding: string,
430+
isLocal: boolean
431+
) {
432+
// Don't do any network stuff when local, instead respect what
433+
// Wrangler dev does, which is to use the binding name as a fallback
434+
// for the namespace ID
435+
if (isLocal) {
436+
return binding;
437+
}
438+
const accountId = await requireAuth(config);
439+
if (!config.name) {
440+
throw new UserError("No Worker name found in config");
441+
}
442+
const settings = await getSettings(config, accountId, config.name);
443+
const existingKV = settings?.bindings.find(
444+
(existing) => existing.type === "kv_namespace" && existing.name === binding
445+
);
446+
if (!existingKV || !("namespace_id" in existingKV)) {
447+
throw new UserError(
448+
`No namespace ID found for binding "${binding}". Add one to your wrangler config file or pass it via \`--namespace-id\`.`
449+
);
450+
}
451+
return existingKV.namespace_id as string;
452+
}
453+
454+
export async function getKVNamespaceId(
424455
{ preview, binding, "namespace-id": namespaceId }: KvArgs,
425-
config: Config
426-
): string {
456+
config: Config,
457+
isLocal: boolean
458+
): Promise<string> {
427459
// nice
428460
if (namespaceId) {
429461
return namespaceId;
@@ -483,8 +515,12 @@ export function getKVNamespaceId(
483515
// We don't want to execute code below if preview is set to true, so we just return. Otherwise we can get error!
484516
return namespaceId;
485517
} else if (previewIsDefined) {
518+
if (getFlag("RESOURCES_PROVISION")) {
519+
assert(binding);
520+
return getIdFromSettings(config, binding, isLocal);
521+
}
486522
throw new UserError(
487-
`No namespace ID found for ${binding}. Add one to your wrangler config file to use a separate namespace for previewing your worker.`
523+
`No namespace ID found for ${binding}. Add one to your wrangler config file or pass it via \`--namespace-id\`.`
488524
);
489525
}
490526

@@ -494,6 +530,13 @@ export function getKVNamespaceId(
494530
(!namespace.id && namespace.preview_id);
495531
if (bindingHasOnlyOneId) {
496532
namespaceId = namespace.id || namespace.preview_id;
533+
} else if (
534+
getFlag("RESOURCES_PROVISION") &&
535+
!namespace.id &&
536+
!namespace.preview_id
537+
) {
538+
assert(binding);
539+
return getIdFromSettings(config, binding, isLocal);
497540
} else {
498541
throw new UserError(
499542
`${binding} has both a namespace ID and a preview ID. Specify "--preview" or "--preview false" to avoid writing data to the wrong namespace.`

packages/wrangler/src/kv/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export const kvNamespaceDeleteCommand = createCommand({
188188
printResourceLocation("remote");
189189
let id;
190190
try {
191-
id = getKVNamespaceId(args, config);
191+
id = await getKVNamespaceId(args, config, false);
192192
} catch (e) {
193193
throw new CommandLineArgsError(
194194
"Not able to delete namespace.\n" + ((e as Error).message ?? e)
@@ -383,7 +383,7 @@ export const kvKeyPutCommand = createCommand({
383383
async handler({ key, ttl, expiration, metadata, ...args }) {
384384
const localMode = isLocal(args);
385385
const config = readConfig(args);
386-
const namespaceId = getKVNamespaceId(args, config);
386+
const namespaceId = await getKVNamespaceId(args, config, localMode);
387387
// One of `args.path` and `args.value` must be defined
388388
const value = args.path
389389
? readFileSyncToBuffer(args.path)
@@ -495,7 +495,7 @@ export const kvKeyListCommand = createCommand({
495495
const localMode = isLocal(args);
496496
// TODO: support for limit+cursor (pagination)
497497
const config = readConfig(args);
498-
const namespaceId = getKVNamespaceId(args, config);
498+
const namespaceId = await getKVNamespaceId(args, config, localMode);
499499

500500
let result: NamespaceKeyInfo[];
501501
let metricEvent: EventNames;
@@ -586,7 +586,7 @@ export const kvKeyGetCommand = createCommand({
586586
async handler({ key, ...args }) {
587587
const localMode = isLocal(args);
588588
const config = readConfig(args);
589-
const namespaceId = getKVNamespaceId(args, config);
589+
const namespaceId = await getKVNamespaceId(args, config, localMode);
590590

591591
let bufferKVValue;
592592
let metricEvent: EventNames;
@@ -678,7 +678,7 @@ export const kvKeyDeleteCommand = createCommand({
678678
async handler({ key, ...args }) {
679679
const localMode = isLocal(args);
680680
const config = readConfig(args);
681-
const namespaceId = getKVNamespaceId(args, config);
681+
const namespaceId = await getKVNamespaceId(args, config, localMode);
682682

683683
logger.log(`Deleting the key "${key}" on namespace ${namespaceId}.`);
684684

@@ -753,7 +753,7 @@ export const kvBulkGetCommand = createCommand({
753753
async handler({ filename, ...args }) {
754754
const localMode = isLocal(args);
755755
const config = readConfig(args);
756-
const namespaceId = getKVNamespaceId(args, config);
756+
const namespaceId = await getKVNamespaceId(args, config, localMode);
757757

758758
const content = parseJSON(readFileSync(filename), filename) as (
759759
| string
@@ -895,7 +895,7 @@ export const kvBulkPutCommand = createCommand({
895895
// but we'll do that in the future if needed.
896896

897897
const config = readConfig(args);
898-
const namespaceId = getKVNamespaceId(args, config);
898+
const namespaceId = await getKVNamespaceId(args, config, localMode);
899899
const content = parseJSON(readFileSync(filename), filename);
900900

901901
if (!Array.isArray(content)) {
@@ -1045,7 +1045,7 @@ export const kvBulkDeleteCommand = createCommand({
10451045
async handler({ filename, ...args }) {
10461046
const localMode = isLocal(args);
10471047
const config = readConfig(args);
1048-
const namespaceId = getKVNamespaceId(args, config);
1048+
const namespaceId = await getKVNamespaceId(args, config, localMode);
10491049

10501050
if (!args.force) {
10511051
const result = await confirm(

0 commit comments

Comments
 (0)