alchemy 0.92.2 → 0.93.0

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.
Files changed (53) hide show
  1. package/bin/alchemy.js +1 -1
  2. package/lib/cloudflare/ai-search-namespace.d.ts +150 -0
  3. package/lib/cloudflare/ai-search-namespace.d.ts.map +1 -0
  4. package/lib/cloudflare/ai-search-namespace.js +281 -0
  5. package/lib/cloudflare/ai-search-namespace.js.map +1 -0
  6. package/lib/cloudflare/ai-search-token.d.ts +11 -1
  7. package/lib/cloudflare/ai-search-token.d.ts.map +1 -1
  8. package/lib/cloudflare/ai-search-token.js +35 -7
  9. package/lib/cloudflare/ai-search-token.js.map +1 -1
  10. package/lib/cloudflare/ai-search.d.ts +123 -18
  11. package/lib/cloudflare/ai-search.d.ts.map +1 -1
  12. package/lib/cloudflare/ai-search.js +239 -68
  13. package/lib/cloudflare/ai-search.js.map +1 -1
  14. package/lib/cloudflare/bindings.d.ts +29 -2
  15. package/lib/cloudflare/bindings.d.ts.map +1 -1
  16. package/lib/cloudflare/bindings.js.map +1 -1
  17. package/lib/cloudflare/bound.d.ts +4 -2
  18. package/lib/cloudflare/bound.d.ts.map +1 -1
  19. package/lib/cloudflare/container.d.ts +79 -6
  20. package/lib/cloudflare/container.d.ts.map +1 -1
  21. package/lib/cloudflare/container.js +117 -2
  22. package/lib/cloudflare/container.js.map +1 -1
  23. package/lib/cloudflare/index.d.ts +1 -0
  24. package/lib/cloudflare/index.d.ts.map +1 -1
  25. package/lib/cloudflare/index.js +1 -0
  26. package/lib/cloudflare/index.js.map +1 -1
  27. package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
  28. package/lib/cloudflare/miniflare/build-worker-options.js +37 -0
  29. package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
  30. package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
  31. package/lib/cloudflare/worker-metadata.js +25 -1
  32. package/lib/cloudflare/worker-metadata.js.map +1 -1
  33. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  34. package/lib/cloudflare/wrangler.json.js +32 -0
  35. package/lib/cloudflare/wrangler.json.js.map +1 -1
  36. package/lib/docker/api.d.ts +4 -1
  37. package/lib/docker/api.d.ts.map +1 -1
  38. package/lib/docker/api.js +8 -2
  39. package/lib/docker/api.js.map +1 -1
  40. package/package.json +2 -2
  41. package/src/cloudflare/ai-search-namespace.ts +439 -0
  42. package/src/cloudflare/ai-search-token.ts +43 -9
  43. package/src/cloudflare/ai-search.ts +353 -73
  44. package/src/cloudflare/bindings.ts +33 -0
  45. package/src/cloudflare/bound.ts +87 -74
  46. package/src/cloudflare/container.ts +228 -11
  47. package/src/cloudflare/index.ts +1 -0
  48. package/src/cloudflare/miniflare/build-worker-options.ts +39 -0
  49. package/src/cloudflare/worker-metadata.ts +25 -1
  50. package/src/cloudflare/wrangler.json.ts +32 -0
  51. package/src/docker/api.ts +11 -2
  52. package/workers/cloudflare-state-store.js +57 -57
  53. package/workers/tunnel-proxy.js +1 -1
package/bin/alchemy.js CHANGED
@@ -37053,7 +37053,7 @@ var FileSystemStateStore = class {
37053
37053
  //#endregion
37054
37054
  //#region package.json
37055
37055
  var name = "alchemy";
37056
- var version = "0.92.2";
37056
+ var version = "0.93.0";
37057
37057
  var license = "Apache-2.0";
37058
37058
  var author = "Sam Goodwin <sam@alchemy.run>";
37059
37059
  var homepage = "https://alchemy.run";
@@ -0,0 +1,150 @@
1
+ import type { Context } from "../context.ts";
2
+ import { type CloudflareApi, type CloudflareApiOptions } from "./api.ts";
3
+ /**
4
+ * Properties for creating or updating an AI Search Namespace
5
+ */
6
+ export interface AiSearchNamespaceProps extends CloudflareApiOptions {
7
+ /**
8
+ * Name of the namespace.
9
+ * Must match pattern: `^[a-z0-9]([a-z0-9-]{0,26}[a-z0-9])?$`
10
+ *
11
+ * @default `${app}-${stage}-${id}`
12
+ */
13
+ name?: string;
14
+ /**
15
+ * Optional description for the namespace (max 256 characters).
16
+ *
17
+ * Pass `null` to explicitly clear a previously-set description on update.
18
+ * Leaving this field undefined (absent from props) will NOT touch the
19
+ * existing description on update.
20
+ */
21
+ description?: string | null;
22
+ /**
23
+ * Whether to adopt an existing namespace with the same name if it exists
24
+ *
25
+ * @default false
26
+ */
27
+ adopt?: boolean;
28
+ /**
29
+ * Whether to delete the namespace when removed from Alchemy.
30
+ * Namespace must be empty (no instances) to be deleted.
31
+ *
32
+ * @default true
33
+ */
34
+ delete?: boolean;
35
+ }
36
+ /**
37
+ * Type guard for AiSearchNamespace
38
+ */
39
+ export declare function isAiSearchNamespace(resource: unknown): resource is AiSearchNamespace;
40
+ /**
41
+ * Output returned after AI Search Namespace creation/update
42
+ */
43
+ export type AiSearchNamespace = Omit<AiSearchNamespaceProps, "delete" | "adopt" | "description" | "name"> & {
44
+ /**
45
+ * Resource type identifier for binding resolution
46
+ */
47
+ type: "ai_search_namespace";
48
+ /**
49
+ * The stable identifier of the namespace (equal to `namespace`).
50
+ * Present because Alchemy's resource model expects every output to carry an `id`.
51
+ */
52
+ id: string;
53
+ /**
54
+ * The name of the namespace.
55
+ */
56
+ namespace: string;
57
+ /**
58
+ * Optional description of the namespace
59
+ */
60
+ description: string | null;
61
+ /**
62
+ * Time at which the namespace was created
63
+ */
64
+ createdAt: string;
65
+ };
66
+ /**
67
+ * API response for AI Search namespace
68
+ * @internal
69
+ */
70
+ interface AiSearchNamespaceApiResponse {
71
+ name: string;
72
+ description: string | null;
73
+ created_at: string;
74
+ }
75
+ /**
76
+ * An AI Search Namespace groups AI Search instances together,
77
+ * providing logical isolation and scoped access control.
78
+ *
79
+ * Namespaces are a first-class concept in the AI Search binding model.
80
+ * Instance names are unique within their namespace: `UNIQUE(account_id, namespace, name)`.
81
+ *
82
+ * @see https://developers.cloudflare.com/ai-search/
83
+ *
84
+ * @example
85
+ * ## Create a namespace
86
+ *
87
+ * ```ts
88
+ * const ns = await AiSearchNamespace("production", {
89
+ * name: "production",
90
+ * });
91
+ * ```
92
+ *
93
+ * @example
94
+ * ## Use as a Worker binding
95
+ *
96
+ * ```ts
97
+ * const ns = await AiSearchNamespace("docs", {
98
+ * name: "docs",
99
+ * });
100
+ *
101
+ * const worker = await Worker("my-worker", {
102
+ * bindings: {
103
+ * DOCS: ns,
104
+ * },
105
+ * // ...
106
+ * });
107
+ * ```
108
+ *
109
+ * @example
110
+ * ## Adopt an existing namespace
111
+ *
112
+ * ```ts
113
+ * const ns = await AiSearchNamespace("existing", {
114
+ * name: "production",
115
+ * adopt: true,
116
+ * });
117
+ * ```
118
+ */
119
+ export declare const AiSearchNamespace: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<AiSearchNamespace>, id: string, props?: AiSearchNamespaceProps) => Promise<AiSearchNamespace>);
120
+ /**
121
+ * Create an AI Search namespace
122
+ */
123
+ export declare function createAiSearchNamespace(api: CloudflareApi, payload: {
124
+ name: string;
125
+ description?: string | null;
126
+ }): Promise<AiSearchNamespaceApiResponse>;
127
+ /**
128
+ * Get an AI Search namespace by name
129
+ */
130
+ export declare function getAiSearchNamespace(api: CloudflareApi, name: string): Promise<AiSearchNamespaceApiResponse | undefined>;
131
+ /**
132
+ * Update an AI Search namespace.
133
+ *
134
+ * `description: null` clears a previously-set description. `description`
135
+ * absent from the payload leaves the current value untouched.
136
+ */
137
+ export declare function updateAiSearchNamespace(api: CloudflareApi, name: string, payload: {
138
+ description?: string | null;
139
+ }): Promise<AiSearchNamespaceApiResponse>;
140
+ /**
141
+ * Delete an AI Search namespace. Namespace must be empty (no instances).
142
+ * The reserved `default` namespace cannot be deleted and is skipped.
143
+ */
144
+ export declare function deleteAiSearchNamespace(api: CloudflareApi, name: string): Promise<void>;
145
+ /**
146
+ * List all AI Search namespaces in an account
147
+ */
148
+ export declare function listAiSearchNamespaces(api: CloudflareApi): Promise<AiSearchNamespaceApiResponse[]>;
149
+ export {};
150
+ //# sourceMappingURL=ai-search-namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-search-namespace.d.ts","sourceRoot":"","sources":["../../src/cloudflare/ai-search-namespace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAM7C,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,iBAAiB,CAM/B;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,sBAAsB,EACtB,QAAQ,GAAG,OAAO,GAAG,aAAa,GAAG,MAAM,CAC5C,GAAG;IACF;;OAEG;IACH,IAAI,EAAE,qBAAqB,CAAC;IAE5B;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,UAAU,4BAA4B;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,iBAAiB,yFAGpB,OAAO,CAAC,iBAAiB,CAAC,MAC5B,MAAM,UACH,sBAAsB,KAC5B,OAAO,CAAC,iBAAiB,CAAC,CA2J9B,CAAC;AAcF;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACrD,OAAO,CAAC,4BAA4B,CAAC,CAKvC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,4BAA4B,GAAG,SAAS,CAAC,CAYnD;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACvC,OAAO,CAAC,4BAA4B,CAAC,CAKvC;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,4BAA4B,EAAE,CAAC,CAKzC"}
@@ -0,0 +1,281 @@
1
+ import { Resource, ResourceKind } from "../resource.js";
2
+ import { logger } from "../util/logger.js";
3
+ import { poll } from "../util/poll.js";
4
+ import { CloudflareApiError } from "./api-error.js";
5
+ import { extractCloudflareResult } from "./api-response.js";
6
+ import { createCloudflareApi, } from "./api.js";
7
+ /**
8
+ * Type guard for AiSearchNamespace
9
+ */
10
+ export function isAiSearchNamespace(resource) {
11
+ return (typeof resource === "object" &&
12
+ resource !== null &&
13
+ resource[ResourceKind] === "cloudflare::AiSearchNamespace");
14
+ }
15
+ /**
16
+ * An AI Search Namespace groups AI Search instances together,
17
+ * providing logical isolation and scoped access control.
18
+ *
19
+ * Namespaces are a first-class concept in the AI Search binding model.
20
+ * Instance names are unique within their namespace: `UNIQUE(account_id, namespace, name)`.
21
+ *
22
+ * @see https://developers.cloudflare.com/ai-search/
23
+ *
24
+ * @example
25
+ * ## Create a namespace
26
+ *
27
+ * ```ts
28
+ * const ns = await AiSearchNamespace("production", {
29
+ * name: "production",
30
+ * });
31
+ * ```
32
+ *
33
+ * @example
34
+ * ## Use as a Worker binding
35
+ *
36
+ * ```ts
37
+ * const ns = await AiSearchNamespace("docs", {
38
+ * name: "docs",
39
+ * });
40
+ *
41
+ * const worker = await Worker("my-worker", {
42
+ * bindings: {
43
+ * DOCS: ns,
44
+ * },
45
+ * // ...
46
+ * });
47
+ * ```
48
+ *
49
+ * @example
50
+ * ## Adopt an existing namespace
51
+ *
52
+ * ```ts
53
+ * const ns = await AiSearchNamespace("existing", {
54
+ * name: "production",
55
+ * adopt: true,
56
+ * });
57
+ * ```
58
+ */
59
+ export const AiSearchNamespace = Resource("cloudflare::AiSearchNamespace", async function (id, props = {}) {
60
+ const adopt = props.adopt ?? this.scope.adopt;
61
+ const namespace = props.name ??
62
+ this.output?.namespace ??
63
+ this.scope.createPhysicalName(id, "-", 28);
64
+ // Validate namespace name against CF's documented pattern. We do this
65
+ // before any API calls so users get a clear local error rather than a
66
+ // generic API 400. Also guards against `createPhysicalName` truncation
67
+ // producing a name that begins/ends with "-".
68
+ //
69
+ // Skip validation during delete: `this.output?.namespace` is always a
70
+ // previously-accepted name (came from `toOutput(result)`), so there's
71
+ // nothing to re-validate. Critically, this also prevents a failed
72
+ // create (which throws from this guard without persisting state) from
73
+ // tripping the same guard during scope teardown — destroy would have
74
+ // nothing to delete anyway.
75
+ if (this.phase !== "delete" &&
76
+ !/^[a-z0-9]([a-z0-9-]{0,26}[a-z0-9])?$/.test(namespace)) {
77
+ throw new Error(`AI Search namespace name "${namespace}" is invalid. ` +
78
+ "Must match pattern: ^[a-z0-9]([a-z0-9-]{0,26}[a-z0-9])?$ " +
79
+ "(1-28 chars, lowercase alphanumerics and hyphens, cannot start or end with a hyphen).");
80
+ }
81
+ // The `default` namespace is reserved by Cloudflare — it is created
82
+ // automatically on every account and cannot be created, updated, or
83
+ // deleted via the API. Only allow binding to it via `adopt: true`.
84
+ if (namespace === "default" && !adopt && this.phase !== "delete") {
85
+ throw new Error('The "default" AI Search namespace is reserved by Cloudflare. ' +
86
+ "Use `adopt: true` to bind to it (it cannot be created, renamed, or deleted via the API).");
87
+ }
88
+ if (this.scope.local) {
89
+ // Local development mode — return mock output
90
+ return {
91
+ type: "ai_search_namespace",
92
+ id: namespace,
93
+ namespace,
94
+ description: props.description ?? null,
95
+ createdAt: new Date().toISOString(),
96
+ };
97
+ }
98
+ const api = await createCloudflareApi(props);
99
+ if (this.phase === "delete") {
100
+ const namespaceName = this.output?.namespace;
101
+ if (namespaceName && props.delete !== false) {
102
+ await deleteAiSearchNamespace(api, namespaceName);
103
+ }
104
+ return this.destroy();
105
+ }
106
+ // Immutable name — replace if changed. We use the default
107
+ // (pending-deletion) replace strategy: the old namespace is queued for
108
+ // deletion and flushed at scope finalize, matching the convention used
109
+ // by other Cloudflare resources in this repo. Forcing immediate
110
+ // deletion (`replace(true)`) interacts poorly with Cloudflare's
111
+ // namespace-delete consistency window and causes the old namespace to
112
+ // still appear in subsequent GETs.
113
+ if (this.phase === "update" && this.output?.namespace !== namespace) {
114
+ return this.replace();
115
+ }
116
+ if (this.phase === "update" && this.output) {
117
+ // Three-way semantics on `description`:
118
+ // - absent (undefined) → do not touch (preserves out-of-band edits)
119
+ // - string → set to that value
120
+ // - null → clear (explicit opt-in to clearing)
121
+ // We only PUT when the value differs from current state.
122
+ const hasDescriptionProp = "description" in props;
123
+ if (hasDescriptionProp && props.description !== this.output.description) {
124
+ const updated = await updateAiSearchNamespace(api, namespace, {
125
+ description: props.description,
126
+ });
127
+ return toOutput(updated);
128
+ }
129
+ return this.output;
130
+ }
131
+ // Adopting the reserved `default` namespace is a no-op creation: emit a
132
+ // warn so the behavior is visible (delete is silently skipped later).
133
+ if (namespace === "default" && adopt) {
134
+ logger.warn(`Adopting the reserved AI Search "default" namespace. It will not be deleted on teardown.`);
135
+ }
136
+ // Create (with adopt via pre-flight check when enabled)
137
+ const hasDescriptionProp = "description" in props;
138
+ let result;
139
+ if (adopt) {
140
+ // Pre-flight: if namespace exists, adopt it; otherwise create.
141
+ // `getAiSearchNamespace` internally returns `undefined` on 404 and
142
+ // rethrows all other errors (auth, 5xx, network) — no catch needed here.
143
+ const existing = await getAiSearchNamespace(api, namespace);
144
+ if (existing) {
145
+ if (hasDescriptionProp && props.description !== existing.description) {
146
+ result = await updateAiSearchNamespace(api, namespace, {
147
+ description: props.description,
148
+ });
149
+ }
150
+ else {
151
+ result = existing;
152
+ }
153
+ }
154
+ else if (namespace === "default") {
155
+ // The `default` namespace is implicit — treat GET 404 as "exists but
156
+ // not queryable" and return a synthetic adoption record. Use the
157
+ // current timestamp rather than epoch 0 to avoid a misleading
158
+ // "1970-01-01" createdAt in the state file.
159
+ result = {
160
+ name: "default",
161
+ description: null,
162
+ created_at: new Date().toISOString(),
163
+ };
164
+ }
165
+ else {
166
+ result = await createAiSearchNamespace(api, {
167
+ name: namespace,
168
+ description: props.description ?? undefined,
169
+ });
170
+ }
171
+ }
172
+ else {
173
+ try {
174
+ result = await createAiSearchNamespace(api, {
175
+ name: namespace,
176
+ description: props.description ?? undefined,
177
+ });
178
+ }
179
+ catch (error) {
180
+ // Wrap "already exists" errors with AGENTS.md-style messaging that
181
+ // points at `adopt: true`.
182
+ if (error instanceof CloudflareApiError &&
183
+ (error.status === 400 || error.status === 409)) {
184
+ const existing = await getAiSearchNamespace(api, namespace);
185
+ if (existing) {
186
+ throw new Error(`AI Search namespace "${namespace}" already exists. Use \`adopt: true\` to adopt it.`, { cause: error });
187
+ }
188
+ }
189
+ throw error;
190
+ }
191
+ }
192
+ return toOutput(result);
193
+ });
194
+ function toOutput(result) {
195
+ return {
196
+ type: "ai_search_namespace",
197
+ id: result.name,
198
+ namespace: result.name,
199
+ description: result.description ?? null,
200
+ createdAt: result.created_at,
201
+ };
202
+ }
203
+ // ─── API Helper Functions ────────────────────────────────────────────────────
204
+ /**
205
+ * Create an AI Search namespace
206
+ */
207
+ export async function createAiSearchNamespace(api, payload) {
208
+ return await extractCloudflareResult(`create AI Search namespace "${payload.name}"`, api.post(`/accounts/${api.accountId}/ai-search/namespaces`, payload));
209
+ }
210
+ /**
211
+ * Get an AI Search namespace by name
212
+ */
213
+ export async function getAiSearchNamespace(api, name) {
214
+ try {
215
+ return await extractCloudflareResult(`get AI Search namespace "${name}"`, api.get(`/accounts/${api.accountId}/ai-search/namespaces/${name}`));
216
+ }
217
+ catch (error) {
218
+ if (error instanceof CloudflareApiError && error.status === 404) {
219
+ return undefined;
220
+ }
221
+ throw error;
222
+ }
223
+ }
224
+ /**
225
+ * Update an AI Search namespace.
226
+ *
227
+ * `description: null` clears a previously-set description. `description`
228
+ * absent from the payload leaves the current value untouched.
229
+ */
230
+ export async function updateAiSearchNamespace(api, name, payload) {
231
+ return await extractCloudflareResult(`update AI Search namespace "${name}"`, api.put(`/accounts/${api.accountId}/ai-search/namespaces/${name}`, payload));
232
+ }
233
+ /**
234
+ * Delete an AI Search namespace. Namespace must be empty (no instances).
235
+ * The reserved `default` namespace cannot be deleted and is skipped.
236
+ */
237
+ export async function deleteAiSearchNamespace(api, name) {
238
+ // The `default` namespace is reserved and cannot be deleted by the API.
239
+ // Skip silently to allow clean teardown of resources that adopted it.
240
+ if (name === "default") {
241
+ return;
242
+ }
243
+ try {
244
+ await extractCloudflareResult(`delete AI Search namespace "${name}"`, api.delete(`/accounts/${api.accountId}/ai-search/namespaces/${name}`));
245
+ }
246
+ catch (error) {
247
+ if (error instanceof CloudflareApiError) {
248
+ if (error.status === 404) {
249
+ return;
250
+ }
251
+ // Namespace is likely non-empty — wrap with a clearer message.
252
+ if (error.status === 400 || error.status === 409) {
253
+ throw new Error(`Cannot delete AI Search namespace "${name}". ` +
254
+ "The namespace may contain instances — delete all instances first, " +
255
+ "or use { delete: false } on the AiSearchNamespace resource to preserve it.", { cause: error });
256
+ }
257
+ }
258
+ throw error;
259
+ }
260
+ // Cloudflare's namespace DELETE is eventually consistent — same-colo
261
+ // GETs are invalidated immediately via the edge cache, cross-colo GETs
262
+ // can surface the stale row for up to 60s (KV TTL). Wait until the
263
+ // namespace is truly gone so destroy phase presents a strongly-
264
+ // consistent contract to callers (user teardown assertions,
265
+ // downstream resources, rename-triggered replace flows).
266
+ await poll({
267
+ description: `wait for AI Search namespace "${name}" deletion to propagate`,
268
+ fn: () => api.get(`/accounts/${api.accountId}/ai-search/namespaces/${name}`),
269
+ predicate: (res) => res.status === 404,
270
+ initialDelay: 500,
271
+ maxDelay: 3000,
272
+ timeout: 90_000,
273
+ });
274
+ }
275
+ /**
276
+ * List all AI Search namespaces in an account
277
+ */
278
+ export async function listAiSearchNamespaces(api) {
279
+ return await extractCloudflareResult("list AI Search namespaces", api.get(`/accounts/${api.accountId}/ai-search/namespaces`));
280
+ }
281
+ //# sourceMappingURL=ai-search-namespace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-search-namespace.js","sourceRoot":"","sources":["../../src/cloudflare/ai-search-namespace.ts"],"names":[],"mappings":"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"}
@@ -139,7 +139,17 @@ export declare function createAiSearchToken(api: CloudflareApi, payload: {
139
139
  */
140
140
  export declare function listAiSearchTokens(api: CloudflareApi): Promise<AiSearchTokenApiResponse[]>;
141
141
  /**
142
- * Delete an AI Search token
142
+ * Delete an AI Search token.
143
+ *
144
+ * Retries briefly on `7076 token_in_use_by_instances` to cover residual
145
+ * cross-colo lag (CF's server retries the guard internally once after
146
+ * 500ms; the spurious-409 window is typically sub-second). We layer two
147
+ * client-side retries with 1s + 2s delays on top.
148
+ *
149
+ * A persistent 409 after the short retry window means the token is
150
+ * genuinely still referenced by another AI Search instance. We throw an
151
+ * actionable error rather than silently leaking the token — shared tokens
152
+ * should be modeled explicitly via an `AiSearchToken` resource.
143
153
  */
144
154
  export declare function deleteAiSearchToken(api: CloudflareApi, tokenId: string): Promise<void>;
145
155
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ai-search-token.d.ts","sourceRoot":"","sources":["../../src/cloudflare/ai-search-token.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EACL,aAAa,EAEb,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;OAGG;IACH,IAAI,EAAE,iBAAiB,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,UAAU,wBAAwB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,aAAa,CAO5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,aAAa,yFAGhB,OAAO,CAAC,aAAa,CAAC,MACxB,MAAM,SACH,kBAAkB,KACxB,OAAO,CAAC,aAAa,CAAC,CAmG1B,CAAC;AAEF;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,wBAAwB,CAAC,CAKnC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAKrC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAKnC"}
1
+ {"version":3,"file":"ai-search-token.d.ts","sourceRoot":"","sources":["../../src/cloudflare/ai-search-token.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,EACL,aAAa,EAEb,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;OAGG;IACH,IAAI,EAAE,iBAAiB,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,UAAU,wBAAwB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,aAAa,CAO5E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,aAAa,yFAGhB,OAAO,CAAC,aAAa,CAAC,MACxB,MAAM,SACH,kBAAkB,KACxB,OAAO,CAAC,aAAa,CAAC,CAmG1B,CAAC;AAEF;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,wBAAwB,CAAC,CAKnC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAKrC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAKnC"}
@@ -149,17 +149,45 @@ export async function listAiSearchTokens(api) {
149
149
  return await extractCloudflareResult(`list AI Search tokens`, api.get(`/accounts/${api.accountId}/ai-search/tokens`));
150
150
  }
151
151
  /**
152
- * Delete an AI Search token
152
+ * Delete an AI Search token.
153
+ *
154
+ * Retries briefly on `7076 token_in_use_by_instances` to cover residual
155
+ * cross-colo lag (CF's server retries the guard internally once after
156
+ * 500ms; the spurious-409 window is typically sub-second). We layer two
157
+ * client-side retries with 1s + 2s delays on top.
158
+ *
159
+ * A persistent 409 after the short retry window means the token is
160
+ * genuinely still referenced by another AI Search instance. We throw an
161
+ * actionable error rather than silently leaking the token — shared tokens
162
+ * should be modeled explicitly via an `AiSearchToken` resource.
153
163
  */
154
164
  export async function deleteAiSearchToken(api, tokenId) {
155
- try {
156
- await extractCloudflareResult(`delete AI Search token "${tokenId}"`, api.delete(`/accounts/${api.accountId}/ai-search/tokens/${tokenId}`));
157
- }
158
- catch (error) {
159
- if (error instanceof CloudflareApiError && error.status === 404) {
165
+ const retryDelaysMs = [1000, 2000]; // 2 retries, ~3s total
166
+ for (let attempt = 0; attempt <= retryDelaysMs.length; attempt++) {
167
+ try {
168
+ await extractCloudflareResult(`delete AI Search token "${tokenId}"`, api.delete(`/accounts/${api.accountId}/ai-search/tokens/${tokenId}`));
160
169
  return;
161
170
  }
162
- throw error;
171
+ catch (error) {
172
+ if (error instanceof CloudflareApiError && error.status === 404) {
173
+ return;
174
+ }
175
+ const isTokenInUse = error instanceof CloudflareApiError &&
176
+ error.status === 409 &&
177
+ Array.isArray(error.errorData) &&
178
+ error.errorData.some((e) => e?.code === 7076);
179
+ if (isTokenInUse && attempt < retryDelaysMs.length) {
180
+ await new Promise((resolve) => setTimeout(resolve, retryDelaysMs[attempt]));
181
+ continue;
182
+ }
183
+ if (isTokenInUse) {
184
+ throw new Error(`AI Search token "${tokenId}" is still referenced by another instance. ` +
185
+ "If the token is intentionally shared across instances, manage it " +
186
+ "explicitly via an `AiSearchToken` resource with `delete: false`, " +
187
+ "or delete all referencing instances before deleting the token.", { cause: error });
188
+ }
189
+ throw error;
190
+ }
163
191
  }
164
192
  }
165
193
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ai-search-token.js","sourceRoot":"","sources":["../../src/cloudflare/ai-search-token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-search-token.js","sourceRoot":"","sources":["../../src/cloudflare/ai-search-token.ts"],"names":[],"mappings":"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"}