neon 8.11.1 → 8.11.2

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 (105) hide show
  1. package/README.md +1 -1
  2. package/dist/_chunks/api-GbEaBZJ5.js +388 -0
  3. package/dist/_chunks/api_keys-CNnnugbQ.js +281 -0
  4. package/dist/_chunks/ask-DVwy0eUL.js +155 -0
  5. package/dist/_chunks/auth-CIUtXByB.js +495 -0
  6. package/dist/_chunks/bootstrap-wPZWa1sT.js +499 -0
  7. package/dist/_chunks/branches-BNa1xX1L.js +460 -0
  8. package/dist/_chunks/bucket-BCdryTkD.js +409 -0
  9. package/dist/_chunks/checkout-CXIOydqZ.js +348 -0
  10. package/dist/_chunks/claim-DqAvAvDm.js +473 -0
  11. package/dist/_chunks/config-BH_qRHiG.js +1113 -0
  12. package/dist/_chunks/connection_string-DB4awPzZ.js +154 -0
  13. package/dist/_chunks/credentials-BSjE9fRR.js +146 -0
  14. package/dist/_chunks/data_api-Djxj5ZQD.js +263 -0
  15. package/dist/_chunks/databases-Dok4wru7.js +84 -0
  16. package/dist/_chunks/deploy-D7B0Xfjg.js +33 -0
  17. package/dist/_chunks/dev-CSvxAecE.js +945 -0
  18. package/dist/_chunks/diff-DhxxbdQE.js +178 -0
  19. package/dist/_chunks/docs-CrVybkTP.js +197 -0
  20. package/dist/_chunks/env-5HS5qQGd.js +284 -0
  21. package/dist/_chunks/feedback-CMayyTa8.js +88 -0
  22. package/dist/_chunks/functions-Q0zuvtnk.js +464 -0
  23. package/dist/_chunks/git-H32TNt6M.js +356 -0
  24. package/dist/_chunks/init-BkA6RilG.js +111 -0
  25. package/dist/_chunks/inspect-g0wekylj.js +90 -0
  26. package/dist/_chunks/ip_allow-5lLFvIuE.js +106 -0
  27. package/dist/_chunks/link-BgtkOBws.js +936 -0
  28. package/dist/_chunks/logs-DWkpjzIH.js +291 -0
  29. package/dist/_chunks/mcp-Bo-7TKc7.js +253 -0
  30. package/dist/_chunks/neon_auth-CBs1_3qu.js +822 -0
  31. package/dist/_chunks/open-CX3BT3Tp.js +33 -0
  32. package/dist/_chunks/operations-D4I-AxVs.js +37 -0
  33. package/dist/_chunks/orgs-xGfANwHQ.js +52 -0
  34. package/dist/_chunks/plugins-DqD7BDO1.js +169 -0
  35. package/dist/_chunks/profile-yXOiKk9R.js +672 -0
  36. package/dist/_chunks/projects-BwI2Uo0z.js +439 -0
  37. package/dist/_chunks/psql-BM-doe8e.js +64 -0
  38. package/dist/_chunks/realtime-BRqIyGR-.js +79 -0
  39. package/dist/_chunks/roles-B4w3YT_7.js +79 -0
  40. package/dist/_chunks/set_context-DbrwoImy.js +38 -0
  41. package/dist/_chunks/skills-DyiBXKS3.js +255 -0
  42. package/dist/_chunks/snapshots-RJBzW8GM.js +338 -0
  43. package/dist/_chunks/status-DV8Z2kw3.js +44 -0
  44. package/dist/_chunks/triggers-BrRo1z4b.js +302 -0
  45. package/dist/_chunks/user-dlOGXbX9.js +60 -0
  46. package/dist/_chunks/vpc_endpoints-CNb0YfMo.js +105 -0
  47. package/dist/auth_recovery.js +1 -1
  48. package/dist/commands/api.js +1 -388
  49. package/dist/commands/api_keys.js +1 -281
  50. package/dist/commands/ask.js +1 -155
  51. package/dist/commands/auth.js +1 -495
  52. package/dist/commands/bootstrap.js +1 -499
  53. package/dist/commands/branches.js +1 -460
  54. package/dist/commands/bucket.js +1 -409
  55. package/dist/commands/checkout.js +1 -348
  56. package/dist/commands/claim.js +1 -473
  57. package/dist/commands/config.js +1 -1113
  58. package/dist/commands/connection_string.js +1 -154
  59. package/dist/commands/credentials.js +1 -146
  60. package/dist/commands/data_api.js +1 -263
  61. package/dist/commands/databases.js +1 -84
  62. package/dist/commands/deploy.js +1 -33
  63. package/dist/commands/dev.js +1 -945
  64. package/dist/commands/diff.js +1 -178
  65. package/dist/commands/docs.js +1 -197
  66. package/dist/commands/env.js +1 -284
  67. package/dist/commands/feedback.js +1 -88
  68. package/dist/commands/functions.js +1 -464
  69. package/dist/commands/functions_new.js +1 -1
  70. package/dist/commands/git.js +1 -356
  71. package/dist/commands/index.js +45 -45
  72. package/dist/commands/init.js +1 -111
  73. package/dist/commands/inspect.js +1 -90
  74. package/dist/commands/ip_allow.js +1 -106
  75. package/dist/commands/link.js +1 -936
  76. package/dist/commands/logs.js +1 -291
  77. package/dist/commands/mcp.js +1 -253
  78. package/dist/commands/neon_auth.js +1 -822
  79. package/dist/commands/open.js +1 -33
  80. package/dist/commands/operations.js +1 -37
  81. package/dist/commands/orgs.js +1 -52
  82. package/dist/commands/plugins.js +1 -169
  83. package/dist/commands/profile.js +1 -672
  84. package/dist/commands/projects.js +1 -439
  85. package/dist/commands/psql.js +1 -64
  86. package/dist/commands/realtime.js +1 -79
  87. package/dist/commands/roles.js +1 -79
  88. package/dist/commands/set_context.js +1 -38
  89. package/dist/commands/skills.js +1 -255
  90. package/dist/commands/snapshots.js +1 -338
  91. package/dist/commands/status.js +1 -44
  92. package/dist/commands/subscribe.js +1 -1
  93. package/dist/commands/triggers.js +1 -302
  94. package/dist/commands/user.js +1 -60
  95. package/dist/commands/vpc_endpoints.js +1 -105
  96. package/dist/functions/registry.js +29 -151
  97. package/dist/functions/source.js +42 -2
  98. package/dist/index.js +1 -1
  99. package/dist/init/auth.js +3 -3
  100. package/dist/init/link.js +2 -2
  101. package/dist/init/run.js +3 -3
  102. package/dist/init/tooling.js +3 -3
  103. package/dist/mcp/mint.js +1 -1
  104. package/dist/test_utils/registry.js +1 -2
  105. package/package.json +8 -6
@@ -0,0 +1,409 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
+ import { log } from "../log.js";
3
+ import { isNeonApiError, retryOnLock } from "../api.js";
4
+ import { createProjectBranchBucket, deleteProjectBranchBucket, deleteProjectBranchBucketObject, deleteProjectBranchBucketObjectsByPrefix, getProjectBranchBucketObject, listProjectBranchBucketObjects, listProjectBranchBuckets, presignUpload } from "../storage_api.js";
5
+ import { writer } from "../writer.js";
6
+ import { branchIdFromProps, fillSingleProject } from "../utils/enrichers.js";
7
+ import { createReadStream, createWriteStream } from "node:fs";
8
+ import { basename } from "node:path";
9
+ import { stat, unlink } from "node:fs/promises";
10
+ import { pipeline } from "node:stream/promises";
11
+ //#region src/commands/bucket.ts
12
+ var bucket_exports = /* @__PURE__ */ __exportAll({
13
+ aliases: () => aliases,
14
+ builder: () => builder,
15
+ command: () => command,
16
+ describe: () => describe,
17
+ handler: () => handler,
18
+ resolveListDelimiter: () => resolveListDelimiter,
19
+ splitBucketTarget: () => splitBucketTarget
20
+ });
21
+ const OBJECT_FIELDS = [
22
+ "key",
23
+ "size",
24
+ "last_modified",
25
+ "etag"
26
+ ];
27
+ const BUCKET_FIELDS = ["name", "access_level"];
28
+ const ACCESS_LEVELS = ["private", "public_read"];
29
+ const MAX_OBJECT_BYTES = 104857600;
30
+ const scopeOptions = {
31
+ "project-id": {
32
+ describe: "Project ID",
33
+ type: "string"
34
+ },
35
+ branch: {
36
+ describe: "Branch ID or name",
37
+ type: "string"
38
+ }
39
+ };
40
+ const splitBucketTarget = (target) => {
41
+ const slash = target.indexOf("/");
42
+ if (slash === -1) return {
43
+ bucket: target,
44
+ rest: ""
45
+ };
46
+ return {
47
+ bucket: target.slice(0, slash),
48
+ rest: target.slice(slash + 1)
49
+ };
50
+ };
51
+ const command = "buckets";
52
+ const describe = "Manage branch object-storage buckets and their objects";
53
+ const aliases = ["bucket"];
54
+ const builder = (argv) => argv.usage("$0 bucket <sub-command> [options]").options({ "project-id": {
55
+ describe: "Project ID",
56
+ type: "string"
57
+ } }).middleware(fillSingleProject).command("create <name>", "Create a bucket on a branch", (yargs) => yargs.usage("$0 bucket create <name> [options]").positional("name", {
58
+ describe: "The bucket name to create",
59
+ type: "string",
60
+ demandOption: true
61
+ }).options({
62
+ ...scopeOptions,
63
+ "access-level": {
64
+ describe: "The visibility of the bucket",
65
+ type: "string",
66
+ choices: ACCESS_LEVELS,
67
+ default: "private"
68
+ }
69
+ }), (args) => createBucket(args)).command({
70
+ command: "list",
71
+ aliases: ["ls"],
72
+ describe: "List the buckets on a branch",
73
+ builder: (yargs) => yargs.usage("$0 bucket list [options]").options(scopeOptions),
74
+ handler: (args) => listBuckets(args)
75
+ }).command({
76
+ command: "delete <name>",
77
+ aliases: ["rm"],
78
+ describe: "Delete a bucket from a branch",
79
+ builder: (yargs) => yargs.usage("$0 bucket delete <name> [options]").positional("name", {
80
+ describe: "The bucket name to delete",
81
+ type: "string",
82
+ demandOption: true
83
+ }).options(scopeOptions),
84
+ handler: (args) => deleteBucket(args)
85
+ }).command("object", "List, download, upload or delete objects in a bucket", (yargs) => yargs.usage("$0 bucket object <sub-command> [options]").command({
86
+ command: "list <target>",
87
+ aliases: ["ls"],
88
+ describe: "List objects in a bucket. By default folders are collapsed (like \"aws s3 ls\"); pass --recursive for a flat listing of every key",
89
+ builder: (yargs) => yargs.usage("$0 bucket object list <bucket>[/<prefix>] [options]").positional("target", {
90
+ describe: "The bucket to list, optionally with a key prefix: <bucket>[/<prefix>]",
91
+ type: "string",
92
+ demandOption: true
93
+ }).options({
94
+ ...scopeOptions,
95
+ recursive: {
96
+ describe: "List every key flat, descending into nested folders (no delimiter). Mutually exclusive with --delimiter. Mirrors \"aws s3 ls --recursive\"",
97
+ type: "boolean",
98
+ default: false
99
+ },
100
+ delimiter: {
101
+ describe: "Collapse keys sharing this prefix separator into folders. Defaults to \"/\" (folder view); ignored when --recursive is set",
102
+ type: "string"
103
+ },
104
+ cursor: {
105
+ describe: "Pagination cursor returned as next_cursor by a previous call",
106
+ type: "string"
107
+ },
108
+ limit: {
109
+ describe: "Maximum number of items (objects + folders) to return",
110
+ type: "number"
111
+ }
112
+ }),
113
+ handler: (args) => listObjects(args)
114
+ }).command("get <target>", "Download an object from a bucket to a local file", (yargs) => yargs.usage("$0 bucket object get <bucket>/<key> [options]").positional("target", {
115
+ describe: "The object to download: <bucket>/<key>",
116
+ type: "string",
117
+ demandOption: true
118
+ }).options({
119
+ ...scopeOptions,
120
+ file: {
121
+ describe: "Path to write the downloaded object to (defaults to the object filename in the current directory)",
122
+ type: "string"
123
+ }
124
+ }), (args) => getObject(args)).command("put <target>", "Upload a local file to a bucket as an object", (yargs) => yargs.usage("$0 bucket object put <bucket>/<key> [options]").positional("target", {
125
+ describe: "The object to upload to: <bucket>/<key>",
126
+ type: "string",
127
+ demandOption: true
128
+ }).options({
129
+ ...scopeOptions,
130
+ file: {
131
+ describe: "Path to the local file to upload",
132
+ type: "string",
133
+ demandOption: true
134
+ },
135
+ "content-type": {
136
+ describe: "Content-Type to store the object with (e.g. text/plain)",
137
+ type: "string"
138
+ }
139
+ }), (args) => putObject(args)).command({
140
+ command: "delete <target>",
141
+ aliases: ["rm"],
142
+ describe: "Delete an object, or every object under a prefix",
143
+ builder: (yargs) => yargs.usage("$0 bucket object delete <bucket>/<key> [options]").positional("target", {
144
+ describe: "The object to delete: <bucket>/<key>, or <bucket>/<prefix>/ with --recursive",
145
+ type: "string",
146
+ demandOption: true
147
+ }).options({
148
+ ...scopeOptions,
149
+ recursive: {
150
+ describe: "Delete every object under the given prefix. The prefix must end with \"/\"",
151
+ type: "boolean",
152
+ default: false
153
+ }
154
+ }),
155
+ handler: (args) => deleteObject(args)
156
+ }).strictCommands());
157
+ const handler = (args) => {
158
+ return args;
159
+ };
160
+ const createBucket = async (props) => {
161
+ const branchId = await branchIdFromProps(props);
162
+ const { data } = await retryOnLock(() => createProjectBranchBucket(props.apiClient, {
163
+ projectId: props.projectId,
164
+ branchId,
165
+ name: props.name,
166
+ accessLevel: props.accessLevel
167
+ }));
168
+ log.info(`Bucket "${data.bucket.name}" (${data.bucket.access_level}) created on branch ${branchId}`);
169
+ };
170
+ const listBuckets = async (props) => {
171
+ const branchId = await branchIdFromProps(props);
172
+ const { data } = await listProjectBranchBuckets(props.apiClient, {
173
+ projectId: props.projectId,
174
+ branchId
175
+ });
176
+ if (props.output === "json" || props.output === "yaml") {
177
+ writer(props).end(data.buckets, { fields: BUCKET_FIELDS });
178
+ return;
179
+ }
180
+ writer(props).end(data.buckets, {
181
+ fields: BUCKET_FIELDS,
182
+ title: "buckets",
183
+ emptyMessage: "No buckets found."
184
+ });
185
+ };
186
+ const deleteBucket = async (props) => {
187
+ const branchId = await branchIdFromProps(props);
188
+ try {
189
+ await retryOnLock(() => deleteProjectBranchBucket(props.apiClient, {
190
+ projectId: props.projectId,
191
+ branchId,
192
+ bucketName: props.name
193
+ }));
194
+ } catch (err) {
195
+ if (isNeonApiError(err) && err.status === 404) throw new Error(`Bucket "${props.name}" not found on branch ${branchId}.`);
196
+ throw err;
197
+ }
198
+ log.info(`Bucket "${props.name}" deleted from branch ${branchId}`);
199
+ };
200
+ const resolveListDelimiter = (props) => {
201
+ if (props.recursive && props.delimiter !== void 0) throw new Error("--recursive and --delimiter cannot be used together. Use --recursive for a flat listing, or --delimiter to collapse on a separator.");
202
+ if (props.recursive) return;
203
+ if (props.delimiter !== void 0) return props.delimiter;
204
+ return "/";
205
+ };
206
+ const listObjects = async (props) => {
207
+ const delimiter = resolveListDelimiter(props);
208
+ const branchId = await branchIdFromProps(props);
209
+ const { bucket, rest } = splitBucketTarget(props.target);
210
+ const { data } = await listProjectBranchBucketObjects(props.apiClient, {
211
+ projectId: props.projectId,
212
+ branchId,
213
+ bucketName: bucket,
214
+ prefix: rest === "" ? void 0 : rest,
215
+ delimiter,
216
+ cursor: props.cursor,
217
+ limit: props.limit
218
+ });
219
+ if (props.output === "json" || props.output === "yaml") {
220
+ writer(props).end(data, { fields: [
221
+ "folders",
222
+ "objects",
223
+ "prefix",
224
+ "next_cursor",
225
+ "is_truncated"
226
+ ] });
227
+ return;
228
+ }
229
+ const w = writer(props);
230
+ if (data.folders.length > 0) w.write(data.folders.map((name) => ({ name })), {
231
+ fields: ["name"],
232
+ title: "folders"
233
+ });
234
+ w.write(data.objects, {
235
+ fields: OBJECT_FIELDS,
236
+ title: "objects",
237
+ emptyMessage: "No objects found."
238
+ });
239
+ w.end();
240
+ if (data.is_truncated && data.next_cursor) log.info(`More results available. Re-run with --cursor ${data.next_cursor} to fetch the next page.`);
241
+ };
242
+ const filenameFromContentDisposition = (contentDisposition, key) => {
243
+ if (contentDisposition) {
244
+ const extended = /filename\*=(?:UTF-8'')?([^;]+)/i.exec(contentDisposition);
245
+ if (extended?.[1]) try {
246
+ return basename(decodeURIComponent(extended[1].trim()));
247
+ } catch {}
248
+ const plain = /filename="?([^";]+)"?/i.exec(contentDisposition);
249
+ if (plain?.[1]) return basename(plain[1].trim());
250
+ }
251
+ return basename(key) || key;
252
+ };
253
+ const serverErrorMessage = (body) => {
254
+ const message = body?.message;
255
+ return typeof message === "string" && message.trim() !== "" ? message : void 0;
256
+ };
257
+ const streamErrorMessage = async (stream) => {
258
+ if (typeof stream?.[Symbol.asyncIterator] !== "function") return;
259
+ try {
260
+ const chunks = [];
261
+ for await (const chunk of stream) chunks.push(Buffer.from(chunk));
262
+ return serverErrorMessage(JSON.parse(Buffer.concat(chunks).toString()));
263
+ } catch {
264
+ return;
265
+ }
266
+ };
267
+ const objectNotFoundFallback = (key, bucket, branchId) => `Object "${key}" not found in bucket "${bucket}" on branch ${branchId}.`;
268
+ const objectNotFoundMessage = (err, key, bucket, branchId) => {
269
+ if (isNeonApiError(err)) {
270
+ const serverMessage = serverErrorMessage(err.data);
271
+ if (serverMessage !== void 0) return serverMessage;
272
+ }
273
+ return objectNotFoundFallback(key, bucket, branchId);
274
+ };
275
+ const fileToWebStream = (path) => {
276
+ const source = createReadStream(path);
277
+ return new ReadableStream({
278
+ start(controller) {
279
+ source.on("data", (chunk) => {
280
+ const bytes = typeof chunk === "string" ? new TextEncoder().encode(chunk) : new Uint8Array(chunk);
281
+ controller.enqueue(bytes);
282
+ if ((controller.desiredSize ?? 0) <= 0) source.pause();
283
+ });
284
+ source.on("end", () => {
285
+ controller.close();
286
+ });
287
+ source.on("error", (err) => {
288
+ controller.error(err instanceof Error ? err : new Error(String(err)));
289
+ });
290
+ },
291
+ pull() {
292
+ source.resume();
293
+ },
294
+ cancel() {
295
+ source.destroy();
296
+ }
297
+ });
298
+ };
299
+ const getObject = async (props) => {
300
+ const branchId = await branchIdFromProps(props);
301
+ const { bucket, rest: key } = splitBucketTarget(props.target);
302
+ if (key === "") throw new Error("Object target must be in the form <bucket>/<key>.");
303
+ let response;
304
+ try {
305
+ response = await getProjectBranchBucketObject(props.apiClient, {
306
+ projectId: props.projectId,
307
+ branchId,
308
+ bucketName: bucket,
309
+ objectKey: key
310
+ });
311
+ } catch (err) {
312
+ if (isNeonApiError(err) && err.status === 404) {
313
+ const serverMessage = await streamErrorMessage(err.data);
314
+ throw new Error(serverMessage ?? objectNotFoundFallback(key, bucket, branchId));
315
+ }
316
+ throw err;
317
+ }
318
+ const contentDisposition = response.headers["content-disposition"];
319
+ const destination = props.file ?? filenameFromContentDisposition(contentDisposition, key);
320
+ try {
321
+ await pipeline(response.data, createWriteStream(destination));
322
+ } catch (err) {
323
+ await unlink(destination).catch(() => void 0);
324
+ throw err;
325
+ }
326
+ log.info(`Object "${key}" downloaded from bucket "${bucket}" on branch ${branchId} to ${destination}`);
327
+ };
328
+ const putObject = async (props) => {
329
+ const branchId = await branchIdFromProps(props);
330
+ const { bucket, rest: key } = splitBucketTarget(props.target);
331
+ if (bucket === "" || key === "") throw new Error("Object target must be in the form <bucket>/<key>.");
332
+ let fileSize;
333
+ try {
334
+ const fileStat = await stat(props.file);
335
+ if (!fileStat.isFile()) throw new Error(`"${props.file}" is not a regular file.`);
336
+ fileSize = fileStat.size;
337
+ } catch (err) {
338
+ if (err?.code === "ENOENT") throw new Error(`File "${props.file}" does not exist.`);
339
+ throw err;
340
+ }
341
+ if (fileSize > MAX_OBJECT_BYTES) throw new Error(`File "${props.file}" is ${fileSize} bytes, which exceeds the ${MAX_OBJECT_BYTES}-byte (100 MB) single-upload limit. Larger objects are not supported yet.`);
342
+ let presign;
343
+ try {
344
+ ({data: presign} = await presignUpload(props.apiClient, {
345
+ projectId: props.projectId,
346
+ branchId,
347
+ bucketName: bucket,
348
+ objectKey: key,
349
+ contentType: props.contentType
350
+ }));
351
+ } catch (err) {
352
+ if (isNeonApiError(err)) {
353
+ const status = err.status;
354
+ if (status === 404) throw new Error(objectNotFoundMessage(err, key, bucket, branchId));
355
+ const serverMessage = serverErrorMessage(err.data);
356
+ throw new Error(serverMessage ?? `Failed to presign upload for "${key}" in bucket "${bucket}" on branch ${branchId}${status !== void 0 ? ` (HTTP ${status})` : ""}: ${err.message}`);
357
+ }
358
+ throw err;
359
+ }
360
+ const upload = {
361
+ method: "PUT",
362
+ headers: {
363
+ ...presign.headers,
364
+ "Content-Length": String(fileSize)
365
+ },
366
+ body: fileToWebStream(props.file),
367
+ redirect: "error",
368
+ duplex: "half"
369
+ };
370
+ let uploadResponse;
371
+ try {
372
+ uploadResponse = await fetch(presign.url, upload);
373
+ } catch (err) {
374
+ throw new Error(`Failed to upload "${props.file}" to "${key}" in bucket "${bucket}" on branch ${branchId}: ${err instanceof Error ? err.message : String(err)}`);
375
+ }
376
+ if (!uploadResponse.ok) throw new Error(`Failed to upload "${props.file}" to "${key}" in bucket "${bucket}" on branch ${branchId} (HTTP ${uploadResponse.status}): Request failed with status code ${uploadResponse.status}`);
377
+ log.info(`File "${props.file}" uploaded to "${key}" in bucket "${bucket}" on branch ${branchId}`);
378
+ };
379
+ const deleteObject = async (props) => {
380
+ const branchId = await branchIdFromProps(props);
381
+ const { bucket, rest } = splitBucketTarget(props.target);
382
+ if (props.recursive) {
383
+ if (rest === "") throw new Error("Recursive delete requires a non-empty prefix ending in \"/\".");
384
+ if (!rest.endsWith("/")) throw new Error(`Recursive delete requires a prefix ending in "/" (got "${rest}").`);
385
+ const { data } = await retryOnLock(() => deleteProjectBranchBucketObjectsByPrefix(props.apiClient, {
386
+ projectId: props.projectId,
387
+ branchId,
388
+ bucketName: bucket,
389
+ prefix: rest
390
+ }));
391
+ log.info(`Deleted ${data.deleted} object(s) under prefix "${rest}" from bucket "${bucket}" on branch ${branchId}`);
392
+ return;
393
+ }
394
+ if (rest === "") throw new Error("Object target must be in the form <bucket>/<key>.");
395
+ try {
396
+ await retryOnLock(() => deleteProjectBranchBucketObject(props.apiClient, {
397
+ projectId: props.projectId,
398
+ branchId,
399
+ bucketName: bucket,
400
+ objectKey: rest
401
+ }));
402
+ } catch (err) {
403
+ if (isNeonApiError(err) && err.status === 404) throw new Error(objectNotFoundMessage(err, rest, bucket, branchId));
404
+ throw err;
405
+ }
406
+ log.info(`Object "${rest}" deleted from bucket "${bucket}" on branch ${branchId}`);
407
+ };
408
+ //#endregion
409
+ export { describe as a, splitBucketTarget as c, command as i, bucket_exports as n, handler as o, builder as r, resolveListDelimiter as s, aliases as t };