@neon/sdk 1.4.0 → 1.5.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 (168) hide show
  1. package/README.md +64 -3
  2. package/dist/_virtual/_rolldown/runtime.js +1 -2
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +2 -2
  5. package/dist/neon/config.d.ts +13 -0
  6. package/dist/neon/config.d.ts.map +1 -1
  7. package/dist/neon/config.js +2 -0
  8. package/dist/neon/config.js.map +1 -1
  9. package/dist/neon/context.d.ts +26 -6
  10. package/dist/neon/context.d.ts.map +1 -1
  11. package/dist/neon/context.js +59 -10
  12. package/dist/neon/context.js.map +1 -1
  13. package/dist/neon/deadline.d.ts +81 -0
  14. package/dist/neon/deadline.d.ts.map +1 -0
  15. package/dist/neon/deadline.js +143 -0
  16. package/dist/neon/deadline.js.map +1 -0
  17. package/dist/neon/errors.d.ts +22 -3
  18. package/dist/neon/errors.d.ts.map +1 -1
  19. package/dist/neon/errors.js +22 -2
  20. package/dist/neon/errors.js.map +1 -1
  21. package/dist/neon/paginate.d.ts +6 -1
  22. package/dist/neon/paginate.d.ts.map +1 -1
  23. package/dist/neon/paginate.js +59 -24
  24. package/dist/neon/paginate.js.map +1 -1
  25. package/dist/neon/raw-wrap.d.ts.map +1 -1
  26. package/dist/neon/raw-wrap.js +17 -2
  27. package/dist/neon/raw-wrap.js.map +1 -1
  28. package/dist/neon/resources/account.d.ts.map +1 -1
  29. package/dist/neon/resources/account.js +18 -12
  30. package/dist/neon/resources/account.js.map +1 -1
  31. package/dist/neon/resources/ai-gateway.js +3 -2
  32. package/dist/neon/resources/ai-gateway.js.map +1 -1
  33. package/dist/neon/resources/auth.d.ts.map +1 -1
  34. package/dist/neon/resources/auth.js +42 -28
  35. package/dist/neon/resources/auth.js.map +1 -1
  36. package/dist/neon/resources/branches.d.ts +1 -1
  37. package/dist/neon/resources/branches.d.ts.map +1 -1
  38. package/dist/neon/resources/branches.js +29 -20
  39. package/dist/neon/resources/branches.js.map +1 -1
  40. package/dist/neon/resources/bucket-objects.d.ts.map +1 -1
  41. package/dist/neon/resources/bucket-objects.js +15 -10
  42. package/dist/neon/resources/bucket-objects.js.map +1 -1
  43. package/dist/neon/resources/buckets.d.ts.map +1 -1
  44. package/dist/neon/resources/buckets.js +9 -6
  45. package/dist/neon/resources/buckets.js.map +1 -1
  46. package/dist/neon/resources/consumption.d.ts +4 -4
  47. package/dist/neon/resources/consumption.d.ts.map +1 -1
  48. package/dist/neon/resources/consumption.js +6 -6
  49. package/dist/neon/resources/consumption.js.map +1 -1
  50. package/dist/neon/resources/credentials.d.ts.map +1 -1
  51. package/dist/neon/resources/credentials.js +9 -6
  52. package/dist/neon/resources/credentials.js.map +1 -1
  53. package/dist/neon/resources/dataapi.d.ts.map +1 -1
  54. package/dist/neon/resources/dataapi.js +12 -8
  55. package/dist/neon/resources/dataapi.js.map +1 -1
  56. package/dist/neon/resources/databases.d.ts.map +1 -1
  57. package/dist/neon/resources/databases.js +15 -10
  58. package/dist/neon/resources/databases.js.map +1 -1
  59. package/dist/neon/resources/endpoints.d.ts.map +1 -1
  60. package/dist/neon/resources/endpoints.js +27 -18
  61. package/dist/neon/resources/endpoints.js.map +1 -1
  62. package/dist/neon/resources/functions.d.ts +1 -1
  63. package/dist/neon/resources/functions.d.ts.map +1 -1
  64. package/dist/neon/resources/functions.js +14 -10
  65. package/dist/neon/resources/functions.js.map +1 -1
  66. package/dist/neon/resources/operations.d.ts +12 -3
  67. package/dist/neon/resources/operations.d.ts.map +1 -1
  68. package/dist/neon/resources/operations.js +5 -4
  69. package/dist/neon/resources/operations.js.map +1 -1
  70. package/dist/neon/resources/postgres.d.ts.map +1 -1
  71. package/dist/neon/resources/postgres.js +9 -1
  72. package/dist/neon/resources/postgres.js.map +1 -1
  73. package/dist/neon/resources/projects.d.ts +1 -1
  74. package/dist/neon/resources/projects.d.ts.map +1 -1
  75. package/dist/neon/resources/projects.js +35 -24
  76. package/dist/neon/resources/projects.js.map +1 -1
  77. package/dist/neon/resources/roles.d.ts.map +1 -1
  78. package/dist/neon/resources/roles.js +18 -12
  79. package/dist/neon/resources/roles.js.map +1 -1
  80. package/dist/neon/resources/snapshots.d.ts +10 -1
  81. package/dist/neon/resources/snapshots.d.ts.map +1 -1
  82. package/dist/neon/resources/snapshots.js +37 -19
  83. package/dist/neon/resources/snapshots.js.map +1 -1
  84. package/dist/neon/resources/storage.js +3 -2
  85. package/dist/neon/resources/storage.js.map +1 -1
  86. package/dist/neon/retry.d.ts +30 -8
  87. package/dist/neon/retry.d.ts.map +1 -1
  88. package/dist/neon/retry.js +59 -20
  89. package/dist/neon/retry.js.map +1 -1
  90. package/dist/neon/wait.d.ts +7 -1
  91. package/dist/neon/wait.d.ts.map +1 -1
  92. package/dist/neon/wait.js +53 -34
  93. package/dist/neon/wait.js.map +1 -1
  94. package/package.json +3 -2
  95. package/dist/neon/client.test-d.d.ts +0 -1
  96. package/dist/neon/client.test-d.js +0 -98
  97. package/dist/neon/client.test-d.js.map +0 -1
  98. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.0.9/node_modules/@vitest/pretty-format/dist/index.js +0 -879
  99. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.0.9/node_modules/@vitest/pretty-format/dist/index.js.map +0 -1
  100. package/dist/node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/chunk-tasks.js +0 -30
  101. package/dist/node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/chunk-tasks.js.map +0 -1
  102. package/dist/node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/index.js +0 -579
  103. package/dist/node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/index.js.map +0 -1
  104. package/dist/node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/utils.js +0 -2
  105. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +0 -92
  106. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +0 -1
  107. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/helpers.js +0 -43
  108. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/helpers.js.map +0 -1
  109. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/index.js +0 -450
  110. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/index.js.map +0 -1
  111. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/source-map.js +0 -168
  112. package/dist/node_modules/.pnpm/@vitest_utils@3.0.9/node_modules/@vitest/utils/dist/source-map.js.map +0 -1
  113. package/dist/node_modules/.pnpm/chai@5.2.0/node_modules/chai/chai.js +0 -3101
  114. package/dist/node_modules/.pnpm/chai@5.2.0/node_modules/chai/chai.js.map +0 -1
  115. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/branding.js +0 -10
  116. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/branding.js.map +0 -1
  117. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/index.js +0 -109
  118. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/index.js.map +0 -1
  119. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/messages.js +0 -10
  120. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/messages.js.map +0 -1
  121. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/overloads.js +0 -10
  122. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/overloads.js.map +0 -1
  123. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/utils.js +0 -10
  124. package/dist/node_modules/.pnpm/expect-type@1.2.1/node_modules/expect-type/dist/utils.js.map +0 -1
  125. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +0 -11
  126. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +0 -1
  127. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +0 -16
  128. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +0 -1
  129. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +0 -11
  130. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +0 -1
  131. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +0 -15
  132. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +0 -1
  133. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +0 -13
  134. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +0 -1
  135. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +0 -34
  136. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +0 -1
  137. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +0 -12
  138. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +0 -1
  139. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +0 -122
  140. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +0 -1
  141. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +0 -39
  142. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +0 -1
  143. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +0 -99
  144. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +0 -1
  145. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +0 -25
  146. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +0 -1
  147. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +0 -14
  148. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +0 -1
  149. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +0 -21
  150. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +0 -1
  151. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +0 -6
  152. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +0 -1
  153. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +0 -12
  154. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +0 -1
  155. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +0 -18
  156. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +0 -1
  157. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +0 -24
  158. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +0 -1
  159. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +0 -9
  160. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +0 -1
  161. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +0 -30
  162. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +0 -1
  163. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +0 -82
  164. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +0 -1
  165. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.js +0 -7
  166. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.js.map +0 -1
  167. package/dist/node_modules/.pnpm/vitest@3.0.9_@types_debug@4.1.13_@types_node@20.19.17_jiti@2.7.0_jsdom@26.1.0_lightning_fb7ae83398b95c49208c9194029bba02/node_modules/vitest/dist/index.js +0 -10
  168. package/dist/node_modules/.pnpm/vitest@3.0.9_@types_debug@4.1.13_@types_node@20.19.17_jiti@2.7.0_jsdom@26.1.0_lightning_fb7ae83398b95c49208c9194029bba02/node_modules/vitest/dist/index.js.map +0 -1
@@ -7,68 +7,74 @@ var Roles = class {
7
7
  this.#ctx = ctx;
8
8
  }
9
9
  list(projectId, branchId, opts) {
10
- return this.#ctx.run(opts, (client) => listProjectBranchRoles({
10
+ return this.#ctx.run(opts, (client, signal) => listProjectBranchRoles({
11
11
  client,
12
12
  path: {
13
13
  project_id: projectId,
14
14
  branch_id: branchId
15
15
  },
16
- throwOnError: false
16
+ throwOnError: false,
17
+ signal
17
18
  }), (data) => data.roles);
18
19
  }
19
20
  get(projectId, branchId, name, opts) {
20
- return this.#ctx.run(opts, (client) => getProjectBranchRole({
21
+ return this.#ctx.run(opts, (client, signal) => getProjectBranchRole({
21
22
  client,
22
23
  path: {
23
24
  project_id: projectId,
24
25
  branch_id: branchId,
25
26
  role_name: name
26
27
  },
27
- throwOnError: false
28
+ throwOnError: false,
29
+ signal
28
30
  }), (data) => data.role);
29
31
  }
30
32
  create(projectId, branchId, input, opts) {
31
- return this.#ctx.run(opts, (client) => createProjectBranchRole({
33
+ return this.#ctx.run(opts, (client, signal) => createProjectBranchRole({
32
34
  client,
33
35
  path: {
34
36
  project_id: projectId,
35
37
  branch_id: branchId
36
38
  },
37
39
  body: { role: input },
38
- throwOnError: false
40
+ throwOnError: false,
41
+ signal
39
42
  }), (data) => data.role);
40
43
  }
41
44
  delete(projectId, branchId, name, opts) {
42
- return this.#ctx.runVoid(opts, (client) => deleteProjectBranchRole({
45
+ return this.#ctx.runVoid(opts, (client, signal) => deleteProjectBranchRole({
43
46
  client,
44
47
  path: {
45
48
  project_id: projectId,
46
49
  branch_id: branchId,
47
50
  role_name: name
48
51
  },
49
- throwOnError: false
52
+ throwOnError: false,
53
+ signal
50
54
  }));
51
55
  }
52
56
  password(projectId, branchId, name, opts) {
53
- return this.#ctx.run(opts, (client) => getProjectBranchRolePassword({
57
+ return this.#ctx.run(opts, (client, signal) => getProjectBranchRolePassword({
54
58
  client,
55
59
  path: {
56
60
  project_id: projectId,
57
61
  branch_id: branchId,
58
62
  role_name: name
59
63
  },
60
- throwOnError: false
64
+ throwOnError: false,
65
+ signal
61
66
  }), (data) => data.password);
62
67
  }
63
68
  resetPassword(projectId, branchId, name, opts) {
64
- return this.#ctx.run(opts, (client) => resetProjectBranchRolePassword({
69
+ return this.#ctx.run(opts, (client, signal) => resetProjectBranchRolePassword({
65
70
  client,
66
71
  path: {
67
72
  project_id: projectId,
68
73
  branch_id: branchId,
69
74
  role_name: name
70
75
  },
71
- throwOnError: false
76
+ throwOnError: false,
77
+ signal
72
78
  }), (data) => data.role);
73
79
  }
74
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"roles.js","names":["#ctx"],"sources":["../../../src/neon/resources/roles.ts"],"sourcesContent":["import {\n\tcreateProjectBranchRole,\n\tdeleteProjectBranchRole,\n\tgetProjectBranchRole,\n\tgetProjectBranchRolePassword,\n\tlistProjectBranchRoles,\n\tresetProjectBranchRolePassword,\n} from \"../../client/sdk.gen.js\";\nimport type { Role, RoleCreateRequest } from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport type { NeonResult, Outcome } from \"../result.js\";\n\ntype CreateInput = RoleCreateRequest[\"role\"];\n\n/** Role resource (branch-scoped). */\nexport class Roles<DThrow extends boolean> {\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/roles */\n\tlist(projectId: string, branchId: string): Promise<Outcome<Role[], DThrow>>;\n\tlist<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role[], Throw>>;\n\tlist(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<Role[] | NeonResult<Role[]>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tlistProjectBranchRoles({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.roles,\n\t\t);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/roles/{role_name} */\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<Role, DThrow>>;\n\tget<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tgetProjectBranchRole({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n\n\t/** @apiCall POST /projects/{project_id}/branches/{branch_id}/roles */\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t): Promise<Outcome<Role, DThrow>>;\n\tcreate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tcreateProjectBranchRole({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tbody: { role: input },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n\n\t/** @apiCall DELETE /projects/{project_id}/branches/{branch_id}/roles/{role_name} */\n\tdelete(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<void, DThrow>>;\n\tdelete<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tdelete(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.runVoid(opts, (client) =>\n\t\t\tdeleteProjectBranchRole({\n\t\t\t\tclient,\n\t\t\t\tpath: {\n\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\trole_name: name,\n\t\t\t\t},\n\t\t\t\tthrowOnError: false,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Reveal the role's password.\n\t *\n\t * @apiCall GET /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reveal_password\n\t */\n\tpassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<string, DThrow>>;\n\tpassword<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<string, Throw>>;\n\tpassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<string | NeonResult<string>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tgetProjectBranchRolePassword({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.password,\n\t\t);\n\t}\n\n\t/**\n\t * Reset the role's password; the returned `Role` carries the new `password`.\n\t *\n\t * @apiCall POST /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reset_password\n\t */\n\tresetPassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<Role, DThrow>>;\n\tresetPassword<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tresetPassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tresetProjectBranchRolePassword({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n}\n"],"mappings":";;;AAeA,IAAa,QAAb,MAA2C;CAC1C;CAEA,YAAY,KAAqB;EAChC,KAAKA,OAAO;CACb;CASA,KACC,WACA,UACA,MACuC;EACvC,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,uBAAuB;GACtB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,cAAc;EACf,CAAC,IACD,SAAS,KAAK,KAChB;CACD;CAcA,IACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,qBAAqB;GACpB;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;EACf,CAAC,IACD,SAAS,KAAK,IAChB;CACD;CAcA,OACC,WACA,UACA,OACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,wBAAwB;GACvB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,MAAM,EAAE,MAAM,MAAM;GACpB,cAAc;EACf,CAAC,IACD,SAAS,KAAK,IAChB;CACD;CAcA,OACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,QAAQ,OAAO,WAC/B,wBAAwB;GACvB;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;EACf,CAAC,CACF;CACD;CAkBA,SACC,WACA,UACA,MACA,MACuC;EACvC,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,6BAA6B;GAC5B;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;EACf,CAAC,IACD,SAAS,KAAK,QAChB;CACD;CAkBA,cACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,+BAA+B;GAC9B;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;EACf,CAAC,IACD,SAAS,KAAK,IAChB;CACD;AACD"}
1
+ {"version":3,"file":"roles.js","names":["#ctx"],"sources":["../../../src/neon/resources/roles.ts"],"sourcesContent":["import {\n\tcreateProjectBranchRole,\n\tdeleteProjectBranchRole,\n\tgetProjectBranchRole,\n\tgetProjectBranchRolePassword,\n\tlistProjectBranchRoles,\n\tresetProjectBranchRolePassword,\n} from \"../../client/sdk.gen.js\";\nimport type { Role, RoleCreateRequest } from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport type { NeonResult, Outcome } from \"../result.js\";\n\ntype CreateInput = RoleCreateRequest[\"role\"];\n\n/** Role resource (branch-scoped). */\nexport class Roles<DThrow extends boolean> {\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/roles */\n\tlist(projectId: string, branchId: string): Promise<Outcome<Role[], DThrow>>;\n\tlist<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role[], Throw>>;\n\tlist(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<Role[] | NeonResult<Role[]>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tlistProjectBranchRoles({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.roles,\n\t\t);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/roles/{role_name} */\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<Role, DThrow>>;\n\tget<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tgetProjectBranchRole({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n\n\t/** @apiCall POST /projects/{project_id}/branches/{branch_id}/roles */\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t): Promise<Outcome<Role, DThrow>>;\n\tcreate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateInput,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tcreateProjectBranchRole({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tbody: { role: input },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n\n\t/** @apiCall DELETE /projects/{project_id}/branches/{branch_id}/roles/{role_name} */\n\tdelete(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<void, DThrow>>;\n\tdelete<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tdelete(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.runVoid(opts, (client, signal) =>\n\t\t\tdeleteProjectBranchRole({\n\t\t\t\tclient,\n\t\t\t\tpath: {\n\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\trole_name: name,\n\t\t\t\t},\n\t\t\t\tthrowOnError: false,\n\t\t\t\tsignal,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Reveal the role's password.\n\t *\n\t * @apiCall GET /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reveal_password\n\t */\n\tpassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<string, DThrow>>;\n\tpassword<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<string, Throw>>;\n\tpassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<string | NeonResult<string>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tgetProjectBranchRolePassword({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.password,\n\t\t);\n\t}\n\n\t/**\n\t * Reset the role's password; the returned `Role` carries the new `password`.\n\t *\n\t * @apiCall POST /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reset_password\n\t */\n\tresetPassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t): Promise<Outcome<Role, DThrow>>;\n\tresetPassword<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Role, Throw>>;\n\tresetPassword(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tname: string,\n\t\topts?: CallOptions,\n\t): Promise<Role | NeonResult<Role>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tresetProjectBranchRolePassword({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: {\n\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\tbranch_id: branchId,\n\t\t\t\t\t\trole_name: name,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.role,\n\t\t);\n\t}\n}\n"],"mappings":";;;AAeA,IAAa,QAAb,MAA2C;CAC1C;CAEA,YAAY,KAAqB;EAChC,KAAKA,OAAO;CACb;CASA,KACC,WACA,UACA,MACuC;EACvC,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,uBAAuB;GACtB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,cAAc;GACd;EACD,CAAC,IACD,SAAS,KAAK,KAChB;CACD;CAcA,IACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,qBAAqB;GACpB;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;GACd;EACD,CAAC,IACD,SAAS,KAAK,IAChB;CACD;CAcA,OACC,WACA,UACA,OACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,wBAAwB;GACvB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,MAAM,EAAE,MAAM,MAAM;GACpB,cAAc;GACd;EACD,CAAC,IACD,SAAS,KAAK,IAChB;CACD;CAcA,OACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,QAAQ,OAAO,QAAQ,WACvC,wBAAwB;GACvB;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;GACd;EACD,CAAC,CACF;CACD;CAkBA,SACC,WACA,UACA,MACA,MACuC;EACvC,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,6BAA6B;GAC5B;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;GACd;EACD,CAAC,IACD,SAAS,KAAK,QAChB;CACD;CAkBA,cACC,WACA,UACA,MACA,MACmC;EACnC,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,+BAA+B;GAC9B;GACA,MAAM;IACL,YAAY;IACZ,WAAW;IACX,WAAW;GACZ;GACA,cAAc;GACd;EACD,CAAC,IACD,SAAS,KAAK,IAChB;CACD;AACD"}
@@ -8,7 +8,16 @@ import { CallOptions, RequestContext } from "../context.js";
8
8
  * Inspect a freshly restored (not-yet-finalized) branch and decide whether to commit.
9
9
  * Return `true` to finalize the restore, `false` to abort it.
10
10
  */
11
- type RestorePreview = (branch: Branch) => boolean | Promise<boolean>;
11
+ /**
12
+ * Inspect a restored-but-un-finalized branch and decide whether to commit it.
13
+ *
14
+ * The second argument carries the call's `signal`. The SDK cannot interrupt this callback
15
+ * — it is the caller's own code — so long-running checks should honour the signal
16
+ * themselves; the restore is left un-finalized if the call is cancelled around it.
17
+ */
18
+ type RestorePreview = (branch: Branch, context: {
19
+ signal?: AbortSignal;
20
+ }) => boolean | Promise<boolean>;
12
21
  /** Options for {@link Snapshots.create} (point-in-time + naming). */
13
22
  interface CreateSnapshotInput {
14
23
  /** A name for the snapshot. */
@@ -1 +1 @@
1
- {"version":3,"file":"snapshots.d.ts","names":[],"sources":["../../../src/neon/resources/snapshots.ts"],"mappings":"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"}
1
+ {"version":3,"file":"snapshots.d.ts","names":[],"sources":["../../../src/neon/resources/snapshots.ts"],"mappings":";;;;;;;;AAgCA;AAA0B;AACjB;AACY;AACN;AAAO;AAGtB;AAYA;AAYA;AA6BY,KA3DA,cAAA,GA2DiB,CAAA,MAAA,EA1DpB,MA0DoB,EAAA,OAAA,EAAA;EAOjB,MAAA,CAAA,EAhES,WAgET;AAAuB,CAAA,EAAA,GAAA,OAAA,GA/DpB,OA+DoB,CAAA,OAAA,CAAA;AAAQ;AAAL,UA5DrB,mBAAA,CA4DqB;EAC1B;EAAiB,IAAA,CAAA,EAAA,MAAA;EAIZ;EAMJ,SAAA,CAAA,EAAS,MAAA;EAAA;EAGJ,GAAA,CAAA,EAAA,MAAA;EAKwB;EAAY,SAAA,CAAA,EAAA,MAAA;AAApB;AAAR;AACI,UApEb,mBAAA,CAoEa;EAEV;EAAZ,IAAA,CAAA,EAAA,MAAA;EACY;AAAY;AAApB;AAAR;AAsBM;EACU,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;AAAU;AAAlB;AAAR,UAlFa,oBAAA,CAkFb;EAC4B;EAGvB,IAAA,CAAA,EAAA,MAAA;EACW;EAAZ,cAAA,CAAA,EAAA,MAAA;EACY;AAAU;AAAlB;AAAR;AA8BK;AACW;EAAU,QAAA,CAAA,EAAA,OAAA;EAAlB;AAAR;AAC4B;AAGvB;AACW;EAAZ,OAAA,CAAA,EA3GG,cA2GH;EACY;EAAU,WAAA,CAAA,EAAA,OAAA;AAAlB;AAAR;AAiCsB;AAAd;AAAR;AAC4B;AAGZ;AAAZ;AACkB,KAtId,iBAAA,GAsIc,OAAA,GAAA,QAAA,GAAA,SAAA;AAAd;AAAR;AAoCM;AACU;AAAQ;AAAhB,KApKA,uBAAA,GAA0B,IAoK1B,CApK+B,kBAoK/B,EAAA,WAAA,CAAA,GAAA;EAAR,SAAA,EAnKQ,iBAmKR;AAC6B,CAAA;AAGxB;AACW,UApKH,gBAAA,CAoKG;EAAZ;EACY,QAAA,EAnKT,uBAmKS,EAAA;AAAQ;AAAhB;AAAR,cA/JS,SA+JT,CAAA,eAAA,OAAA,CAAA,CAAA;EAgIgB,CAAA,OAAA;EAAgB,WAAA,CAAA,GAAA,EA5RlB,cA4RkB;EAAxB;EAAR,IAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAvRsB,OAuRtB,CAvR8B,OAuR9B,CAvRsC,QAuRtC,EAAA,EAvRkD,MAuRlD,CAAA,CAAA;EACiC,IAAA,CAAA,cAAA,OAAA,GAvRP,MAuRO,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,IAAA,EArR7B,WAqR6B,CArRjB,KAqRiB,CAAA,CAAA,EApRjC,OAoRiC,CApRzB,OAoRyB,CApRjB,QAoRiB,EAAA,EApRL,KAoRK,CAAA,CAAA;EAGjB;EAAZ,MAAA,CAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAjQE,mBAiQF,CAAA,EAhQJ,OAgQI,CAhQI,OAgQJ,CAhQY,QAgQZ,EAhQsB,MAgQtB,CAAA,CAAA;EACY,MAAA,CAAA,cAAA,OAAA,GAhQY,MAgQZ,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,KAAA,EA7PX,mBA6PW,GAAA,SAAA,EAAA,IAAA,EA5PZ,WA4PY,CA5PA,KA4PA,CAAA,CAAA,EA3PhB,OA2PgB,CA3PR,OA2PQ,CA3PA,QA2PA,EA3PU,KA2PV,CAAA,CAAA;EAAgB;EAAxB,MAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,KAAA,EA7NH,mBA6NG,CAAA,EA5NR,OA4NQ,CA5NA,OA4NA,CA5NQ,QA4NR,EA5NkB,MA4NlB,CAAA,CAAA;EAAR,MAAA,CAAA,cAAA,OAAA,GA3N4B,MA2N5B,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,KAAA,EAxNK,mBAwNL,EAAA,IAAA,EAvNI,WAuNJ,CAvNgB,KAuNhB,CAAA,CAAA,EAtNA,OAsNA,CAtNQ,OAsNR,CAtNgB,QAsNhB,EAtN0B,KAsN1B,CAAA,CAAA;EAiCQ;EACc,MAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,CAAA,EAvNtB,OAuNsB,CAvNd,OAuNc,CAAA,IAAA,EAvNA,MAuNA,CAAA,CAAA;EAAd,MAAA,CAAA,cAAA,OAAA,GAtNoB,MAsNpB,CAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,IAAA,EAnNJ,WAmNI,CAnNQ,KAmNR,CAAA,CAAA,EAlNR,OAkNQ,CAlNA,OAkNA,CAAA,IAAA,EAlNc,KAkNd,CAAA,CAAA;EAAR;AACiC;AAGzB;AACQ;AAAZ;AACkB;AAAd;AAAR;AAAO;;;;;;yDApLD,uBACN,QAAQ,QAAQ,QAAQ;kCACK,sDAGxB,wCACD,YAAY,SAChB,QAAQ,QAAQ,QAAQ;;oDAgIxB,QAAQ,QAAQ,gBAAgB;sCACC,mDAG7B,YAAY,SAChB,QAAQ,QAAQ,gBAAgB;;;;;;;;;;;;6DAiCxB,mBACR,QAAQ,cAAc;sCACW,uDAGzB,wBACJ,YAAY,SAChB,QAAQ,cAAc"}
@@ -1,3 +1,4 @@
1
+ import { NeonAbortError, NeonError } from "../errors.js";
1
2
  import { err, finalize, ok } from "../result.js";
2
3
  import { createSnapshot, deleteProjectBranch, deleteSnapshot, finalizeRestoreBranch, getSnapshotSchedule, listSnapshots, restoreSnapshot, setSnapshotSchedule, updateSnapshot } from "../../client/sdk.gen.js";
3
4
  //#region src/neon/resources/snapshots.ts
@@ -8,14 +9,15 @@ var Snapshots = class {
8
9
  this.#ctx = ctx;
9
10
  }
10
11
  list(projectId, opts) {
11
- return this.#ctx.run(opts, (client) => listSnapshots({
12
+ return this.#ctx.run(opts, (client, signal) => listSnapshots({
12
13
  client,
13
14
  path: { project_id: projectId },
14
- throwOnError: false
15
+ throwOnError: false,
16
+ signal
15
17
  }), (data) => data.snapshots);
16
18
  }
17
19
  create(projectId, branchId, input, opts) {
18
- return this.#ctx.run(opts, (client) => createSnapshot({
20
+ return this.#ctx.run(opts, (client, signal) => createSnapshot({
19
21
  client,
20
22
  path: {
21
23
  project_id: projectId,
@@ -27,11 +29,12 @@ var Snapshots = class {
27
29
  lsn: input?.lsn,
28
30
  expires_at: input?.expiresAt
29
31
  },
30
- throwOnError: false
32
+ throwOnError: false,
33
+ signal
31
34
  }), (data) => data.snapshot);
32
35
  }
33
36
  update(projectId, snapshotId, input, opts) {
34
- return this.#ctx.run(opts, (client) => updateSnapshot({
37
+ return this.#ctx.run(opts, (client, signal) => updateSnapshot({
35
38
  client,
36
39
  path: {
37
40
  project_id: projectId,
@@ -41,17 +44,19 @@ var Snapshots = class {
41
44
  name: input.name,
42
45
  expires_at: input.expiresAt
43
46
  } },
44
- throwOnError: false
47
+ throwOnError: false,
48
+ signal
45
49
  }), (data) => data.snapshot);
46
50
  }
47
51
  delete(projectId, snapshotId, opts) {
48
- return this.#ctx.run(opts, (client) => deleteSnapshot({
52
+ return this.#ctx.run(opts, (client, signal) => deleteSnapshot({
49
53
  client,
50
54
  path: {
51
55
  project_id: projectId,
52
56
  snapshot_id: snapshotId
53
57
  },
54
- throwOnError: false
58
+ throwOnError: false,
59
+ signal
55
60
  }), () => void 0);
56
61
  }
57
62
  async restore(projectId, snapshotId, input, opts) {
@@ -61,7 +66,7 @@ var Snapshots = class {
61
66
  const restored = await this.#ctx.execute({
62
67
  ...opts,
63
68
  waitForReadiness: preview ? true : opts?.waitForReadiness
64
- }, (client) => restoreSnapshot({
69
+ }, (client, signal) => restoreSnapshot({
65
70
  client,
66
71
  path: {
67
72
  project_id: projectId,
@@ -72,53 +77,66 @@ var Snapshots = class {
72
77
  target_branch_id: input?.targetBranchId,
73
78
  finalize_restore: finalizeNow
74
79
  },
75
- throwOnError: false
80
+ throwOnError: false,
81
+ signal
76
82
  }), (data) => data.branch);
77
83
  if (restored.error || !preview) return finalize(restored, shouldThrow);
78
84
  const branch = restored.data;
79
- const step = await preview(branch) ? await this.#ctx.execute({
85
+ if (opts?.signal?.aborted) return finalize(err(new NeonAbortError("The restore was aborted before its preview callback ran; the restored branch is left un-finalized.")), shouldThrow);
86
+ let commit;
87
+ try {
88
+ commit = await preview(branch, { signal: opts?.signal });
89
+ } catch (error) {
90
+ return finalize(err(opts?.signal?.aborted ? new NeonAbortError("The restore was aborted while its preview callback ran; the restored branch is left un-finalized.", { cause: error }) : new NeonError(`The restore's preview callback threw; the restored branch is left un-finalized: ${error instanceof Error ? error.message : String(error)}`, "client", { cause: error })), shouldThrow);
91
+ }
92
+ if (opts?.signal?.aborted) return finalize(err(new NeonAbortError("The restore was aborted after its preview callback ran; the restored branch is left un-finalized.")), shouldThrow);
93
+ const step = commit ? await this.#ctx.execute({
80
94
  ...opts,
81
95
  waitForReadiness: true
82
- }, (client) => finalizeRestoreBranch({
96
+ }, (client, signal) => finalizeRestoreBranch({
83
97
  client,
84
98
  path: {
85
99
  project_id: projectId,
86
100
  branch_id: branch.id
87
101
  },
88
- throwOnError: false
102
+ throwOnError: false,
103
+ signal
89
104
  }), () => void 0) : input?.keepOnAbort ? ok(void 0) : await this.#ctx.execute({
90
105
  ...opts,
91
106
  waitForReadiness: true
92
- }, (client) => deleteProjectBranch({
107
+ }, (client, signal) => deleteProjectBranch({
93
108
  client,
94
109
  path: {
95
110
  project_id: projectId,
96
111
  branch_id: branch.id
97
112
  },
98
- throwOnError: false
113
+ throwOnError: false,
114
+ signal
99
115
  }), () => void 0);
100
116
  if (step.error) return finalize(err(step.error), shouldThrow);
101
117
  return finalize(ok(branch), shouldThrow);
102
118
  }
103
119
  getSchedule(projectId, branchId, opts) {
104
- return this.#ctx.run(opts, (client) => getSnapshotSchedule({
120
+ return this.#ctx.run(opts, (client, signal) => getSnapshotSchedule({
105
121
  client,
106
122
  path: {
107
123
  project_id: projectId,
108
124
  branch_id: branchId
109
125
  },
110
- throwOnError: false
126
+ throwOnError: false,
127
+ signal
111
128
  }), (data) => data);
112
129
  }
113
130
  setSchedule(projectId, branchId, schedule, opts) {
114
- return this.#ctx.run(opts, (client) => setSnapshotSchedule({
131
+ return this.#ctx.run(opts, (client, signal) => setSnapshotSchedule({
115
132
  client,
116
133
  path: {
117
134
  project_id: projectId,
118
135
  branch_id: branchId
119
136
  },
120
137
  body: schedule,
121
- throwOnError: false
138
+ throwOnError: false,
139
+ signal
122
140
  }), () => void 0);
123
141
  }
124
142
  };
@@ -1 +1 @@
1
- {"version":3,"file":"snapshots.js","names":["#ctx"],"sources":["../../../src/neon/resources/snapshots.ts"],"sourcesContent":["import {\n\tcreateSnapshot,\n\tdeleteProjectBranch,\n\tdeleteSnapshot,\n\tfinalizeRestoreBranch,\n\tgetSnapshotSchedule,\n\tlistSnapshots,\n\trestoreSnapshot,\n\tsetSnapshotSchedule,\n\tupdateSnapshot,\n} from \"../../client/sdk.gen.js\";\nimport type {\n\tBackupSchedule,\n\tBackupScheduleItem,\n\tBranch,\n\tSnapshot,\n} from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport { err, finalize, type NeonResult, type Outcome, ok } from \"../result.js\";\n\n/**\n * Inspect a freshly restored (not-yet-finalized) branch and decide whether to commit.\n * Return `true` to finalize the restore, `false` to abort it.\n */\nexport type RestorePreview = (branch: Branch) => boolean | Promise<boolean>;\n\n/** Options for {@link Snapshots.create} (point-in-time + naming). */\nexport interface CreateSnapshotInput {\n\t/** A name for the snapshot. */\n\tname?: string;\n\t/** Take the snapshot at this timestamp (ISO 8601). Mutually exclusive with `lsn`. */\n\ttimestamp?: string;\n\t/** Take the snapshot at this LSN. Mutually exclusive with `timestamp`. */\n\tlsn?: string;\n\t/** When the snapshot is automatically deleted (ISO 8601). */\n\texpiresAt?: string;\n}\n\n/** Input for {@link Snapshots.update}. */\nexport interface UpdateSnapshotInput {\n\t/** Rename the snapshot. */\n\tname?: string;\n\t/**\n\t * Change when the snapshot expires (ISO 8601). Omit to leave the current\n\t * expiration unchanged, pass `null` to clear it so the snapshot never\n\t * expires, or a future timestamp to set an absolute expiration.\n\t */\n\texpiresAt?: string | null;\n}\n\n/** Input for {@link Snapshots.restore}. */\nexport interface RestoreSnapshotInput {\n\t/** Name for the restored branch. Auto-generated when omitted. */\n\tname?: string;\n\t/** Branch to restore onto. Defaults to the snapshot's source branch. */\n\ttargetBranchId?: string;\n\t/**\n\t * Finalize immediately (move computes onto the restored branch). Defaults to `true`\n\t * when restoring as a new branch (nothing to clobber) and `false` when restoring\n\t * **onto** an existing branch (`targetBranchId`), so you can preview before the swap.\n\t * Ignored when `preview` is set (the preview flow always restores un-finalized first).\n\t */\n\tfinalize?: boolean;\n\t/**\n\t * Transaction-style restore: receives the restored (un-finalized) branch; return `true`\n\t * to finalize (commit) or `false` to abort. On abort the preview branch is deleted\n\t * unless `keepOnAbort` is set. Either way `restore` resolves to the restored `Branch`.\n\t */\n\tpreview?: RestorePreview;\n\t/** Keep the preview branch when `preview` returns `false` (default: delete it). */\n\tkeepOnAbort?: boolean;\n}\n\n/**\n * How often the automatic snapshot (backup) schedule takes a snapshot. These are\n * the values the Neon API accepts, per the OpenAPI spec's `BackupScheduleItem`\n * description. The generated `BackupScheduleItem.frequency` is a broad `string`\n * (the spec documents the allowed values in prose rather than an `enum`), so this\n * union narrows what {@link Snapshots.setSchedule} sends.\n */\nexport type SnapshotFrequency = \"daily\" | \"weekly\" | \"monthly\";\n\n/**\n * A single entry to write to an automatic snapshot (backup) schedule. Identical\n * to the generated {@link BackupScheduleItem} except `frequency` is narrowed to\n * {@link SnapshotFrequency} — the values the API actually accepts.\n */\nexport type BackupScheduleItemInput = Omit<BackupScheduleItem, \"frequency\"> & {\n\tfrequency: SnapshotFrequency;\n};\n\n/** Input for {@link Snapshots.setSchedule}. */\nexport interface SetScheduleInput {\n\t/** The ordered list of schedule entries to apply to the branch. */\n\tschedule: BackupScheduleItemInput[];\n}\n\n/** Snapshot resource. */\nexport class Snapshots<DThrow extends boolean> {\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/snapshots */\n\tlist(projectId: string): Promise<Outcome<Snapshot[], DThrow>>;\n\tlist<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot[], Throw>>;\n\tlist(\n\t\tprojectId: string,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot[] | NeonResult<Snapshot[]>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tlistSnapshots({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshots,\n\t\t);\n\t}\n\n\t/** @apiCall POST /projects/{project_id}/branches/{branch_id}/snapshot */\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: CreateSnapshotInput,\n\t): Promise<Outcome<Snapshot, DThrow>>;\n\tcreate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateSnapshotInput | undefined,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot, Throw>>;\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: CreateSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot | NeonResult<Snapshot>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tcreateSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tquery: {\n\t\t\t\t\t\tname: input?.name,\n\t\t\t\t\t\ttimestamp: input?.timestamp,\n\t\t\t\t\t\tlsn: input?.lsn,\n\t\t\t\t\t\texpires_at: input?.expiresAt,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshot,\n\t\t);\n\t}\n\n\t/** @apiCall PATCH /projects/{project_id}/snapshots/{snapshot_id} */\n\tupdate(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t): Promise<Outcome<Snapshot, DThrow>>;\n\tupdate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot, Throw>>;\n\tupdate(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot | NeonResult<Snapshot>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tupdateSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\t// `undefined` fields are dropped by JSON serialization, so an\n\t\t\t\t\t// omitted `expiresAt` leaves the expiration unchanged while an\n\t\t\t\t\t// explicit `null` clears it.\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tsnapshot: {\n\t\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\t\texpires_at: input.expiresAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshot,\n\t\t);\n\t}\n\n\t/** @apiCall DELETE /projects/{project_id}/snapshots/{snapshot_id} */\n\tdelete(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t): Promise<Outcome<void, DThrow>>;\n\tdelete<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tdelete(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tdeleteSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t() => undefined,\n\t\t);\n\t}\n\n\t/**\n\t * Restore a snapshot into a branch. Returns the restored branch.\n\t *\n\t * - **As a new branch** (no `targetBranchId`): finalizes by default — ready to use.\n\t * - **Onto an existing branch** (`targetBranchId`): does **not** finalize by default,\n\t * so you can preview before the compute swap. Finish later with\n\t * `branches.finalizeRestore`, or pass a `preview` callback to do it transactionally.\n\t *\n\t * With `preview`, this restores un-finalized, runs your callback against the restored\n\t * branch, then finalizes (commit) or deletes the preview branch (abort, unless\n\t * `keepOnAbort`). Either way it resolves to the restored `Branch`.\n\t *\n\t * @apiCall POST /projects/{project_id}/snapshots/{snapshot_id}/restore\n\t */\n\trestore(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput?: RestoreSnapshotInput,\n\t): Promise<Outcome<Branch, DThrow>>;\n\trestore<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: RestoreSnapshotInput | undefined,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Branch, Throw>>;\n\tasync restore(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput?: RestoreSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Branch | NeonResult<Branch>> {\n\t\tconst shouldThrow =\n\t\t\topts?.throwOnError ?? this.#ctx.defaults.throwOnError;\n\t\tconst preview = input?.preview;\n\t\t// New branch → finalize by default; onto existing → preview-first by default.\n\t\t// The preview flow always restores un-finalized so it can inspect first.\n\t\tconst finalizeNow = preview\n\t\t\t? false\n\t\t\t: (input?.finalize ?? input?.targetBranchId === undefined);\n\n\t\tconst restored = await this.#ctx.execute(\n\t\t\t{\n\t\t\t\t...opts,\n\t\t\t\twaitForReadiness: preview ? true : opts?.waitForReadiness,\n\t\t\t},\n\t\t\t(client) =>\n\t\t\t\trestoreSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input?.name,\n\t\t\t\t\t\ttarget_branch_id: input?.targetBranchId,\n\t\t\t\t\t\tfinalize_restore: finalizeNow,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data.branch,\n\t\t);\n\t\tif (restored.error || !preview) {\n\t\t\treturn finalize(restored, shouldThrow);\n\t\t}\n\n\t\tconst branch = restored.data;\n\t\tconst commit = await preview(branch);\n\t\tconst step = commit\n\t\t\t? await this.#ctx.execute(\n\t\t\t\t\t{ ...opts, waitForReadiness: true },\n\t\t\t\t\t(client) =>\n\t\t\t\t\t\tfinalizeRestoreBranch({\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branch.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\t\t}),\n\t\t\t\t\t() => undefined,\n\t\t\t\t)\n\t\t\t: input?.keepOnAbort\n\t\t\t\t? ok(undefined)\n\t\t\t\t: await this.#ctx.execute(\n\t\t\t\t\t\t{ ...opts, waitForReadiness: true },\n\t\t\t\t\t\t(client) =>\n\t\t\t\t\t\t\tdeleteProjectBranch({\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\t\tbranch_id: branch.id,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t);\n\n\t\tif (step.error) return finalize(err<Branch>(step.error), shouldThrow);\n\t\treturn finalize(ok(branch), shouldThrow);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/backup_schedule */\n\tgetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<Outcome<BackupSchedule, DThrow>>;\n\tgetSchedule<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<BackupSchedule, Throw>>;\n\tgetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<BackupSchedule | NeonResult<BackupSchedule>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tgetSnapshotSchedule({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data,\n\t\t);\n\t}\n\n\t/**\n\t * Replace a branch's automatic snapshot schedule.\n\t *\n\t * `frequency` is narrowed to {@link SnapshotFrequency}, so a value the API\n\t * rejects fails to compile. {@link Snapshots.getSchedule} deliberately keeps\n\t * the wider generated type, because a branch can still hold a schedule\n\t * created when the API accepted other frequencies; feeding one straight back\n\t * here is a type error rather than a runtime rejection.\n\t *\n\t * @apiCall PUT /projects/{project_id}/branches/{branch_id}/backup_schedule\n\t */\n\tsetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t): Promise<Outcome<void, DThrow>>;\n\tsetSchedule<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tsetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tsetSnapshotSchedule({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tbody: schedule,\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t() => undefined,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"snapshots.js","names":["#ctx"],"sources":["../../../src/neon/resources/snapshots.ts"],"sourcesContent":["import {\n\tcreateSnapshot,\n\tdeleteProjectBranch,\n\tdeleteSnapshot,\n\tfinalizeRestoreBranch,\n\tgetSnapshotSchedule,\n\tlistSnapshots,\n\trestoreSnapshot,\n\tsetSnapshotSchedule,\n\tupdateSnapshot,\n} from \"../../client/sdk.gen.js\";\nimport type {\n\tBackupSchedule,\n\tBackupScheduleItem,\n\tBranch,\n\tSnapshot,\n} from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport { NeonAbortError, NeonError } from \"../errors.js\";\nimport { err, finalize, type NeonResult, type Outcome, ok } from \"../result.js\";\n\n/**\n * Inspect a freshly restored (not-yet-finalized) branch and decide whether to commit.\n * Return `true` to finalize the restore, `false` to abort it.\n */\n/**\n * Inspect a restored-but-un-finalized branch and decide whether to commit it.\n *\n * The second argument carries the call's `signal`. The SDK cannot interrupt this callback\n * — it is the caller's own code — so long-running checks should honour the signal\n * themselves; the restore is left un-finalized if the call is cancelled around it.\n */\nexport type RestorePreview = (\n\tbranch: Branch,\n\tcontext: { signal?: AbortSignal },\n) => boolean | Promise<boolean>;\n\n/** Options for {@link Snapshots.create} (point-in-time + naming). */\nexport interface CreateSnapshotInput {\n\t/** A name for the snapshot. */\n\tname?: string;\n\t/** Take the snapshot at this timestamp (ISO 8601). Mutually exclusive with `lsn`. */\n\ttimestamp?: string;\n\t/** Take the snapshot at this LSN. Mutually exclusive with `timestamp`. */\n\tlsn?: string;\n\t/** When the snapshot is automatically deleted (ISO 8601). */\n\texpiresAt?: string;\n}\n\n/** Input for {@link Snapshots.update}. */\nexport interface UpdateSnapshotInput {\n\t/** Rename the snapshot. */\n\tname?: string;\n\t/**\n\t * Change when the snapshot expires (ISO 8601). Omit to leave the current\n\t * expiration unchanged, pass `null` to clear it so the snapshot never\n\t * expires, or a future timestamp to set an absolute expiration.\n\t */\n\texpiresAt?: string | null;\n}\n\n/** Input for {@link Snapshots.restore}. */\nexport interface RestoreSnapshotInput {\n\t/** Name for the restored branch. Auto-generated when omitted. */\n\tname?: string;\n\t/** Branch to restore onto. Defaults to the snapshot's source branch. */\n\ttargetBranchId?: string;\n\t/**\n\t * Finalize immediately (move computes onto the restored branch). Defaults to `true`\n\t * when restoring as a new branch (nothing to clobber) and `false` when restoring\n\t * **onto** an existing branch (`targetBranchId`), so you can preview before the swap.\n\t * Ignored when `preview` is set (the preview flow always restores un-finalized first).\n\t */\n\tfinalize?: boolean;\n\t/**\n\t * Transaction-style restore: receives the restored (un-finalized) branch; return `true`\n\t * to finalize (commit) or `false` to abort. On abort the preview branch is deleted\n\t * unless `keepOnAbort` is set. Either way `restore` resolves to the restored `Branch`.\n\t */\n\tpreview?: RestorePreview;\n\t/** Keep the preview branch when `preview` returns `false` (default: delete it). */\n\tkeepOnAbort?: boolean;\n}\n\n/**\n * How often the automatic snapshot (backup) schedule takes a snapshot. These are\n * the values the Neon API accepts, per the OpenAPI spec's `BackupScheduleItem`\n * description. The generated `BackupScheduleItem.frequency` is a broad `string`\n * (the spec documents the allowed values in prose rather than an `enum`), so this\n * union narrows what {@link Snapshots.setSchedule} sends.\n */\nexport type SnapshotFrequency = \"daily\" | \"weekly\" | \"monthly\";\n\n/**\n * A single entry to write to an automatic snapshot (backup) schedule. Identical\n * to the generated {@link BackupScheduleItem} except `frequency` is narrowed to\n * {@link SnapshotFrequency} — the values the API actually accepts.\n */\nexport type BackupScheduleItemInput = Omit<BackupScheduleItem, \"frequency\"> & {\n\tfrequency: SnapshotFrequency;\n};\n\n/** Input for {@link Snapshots.setSchedule}. */\nexport interface SetScheduleInput {\n\t/** The ordered list of schedule entries to apply to the branch. */\n\tschedule: BackupScheduleItemInput[];\n}\n\n/** Snapshot resource. */\nexport class Snapshots<DThrow extends boolean> {\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/snapshots */\n\tlist(projectId: string): Promise<Outcome<Snapshot[], DThrow>>;\n\tlist<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot[], Throw>>;\n\tlist(\n\t\tprojectId: string,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot[] | NeonResult<Snapshot[]>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tlistSnapshots({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshots,\n\t\t);\n\t}\n\n\t/** @apiCall POST /projects/{project_id}/branches/{branch_id}/snapshot */\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: CreateSnapshotInput,\n\t): Promise<Outcome<Snapshot, DThrow>>;\n\tcreate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput: CreateSnapshotInput | undefined,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot, Throw>>;\n\tcreate(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tinput?: CreateSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot | NeonResult<Snapshot>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tcreateSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tquery: {\n\t\t\t\t\t\tname: input?.name,\n\t\t\t\t\t\ttimestamp: input?.timestamp,\n\t\t\t\t\t\tlsn: input?.lsn,\n\t\t\t\t\t\texpires_at: input?.expiresAt,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshot,\n\t\t);\n\t}\n\n\t/** @apiCall PATCH /projects/{project_id}/snapshots/{snapshot_id} */\n\tupdate(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t): Promise<Outcome<Snapshot, DThrow>>;\n\tupdate<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Snapshot, Throw>>;\n\tupdate(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: UpdateSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Snapshot | NeonResult<Snapshot>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tupdateSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\t// `undefined` fields are dropped by JSON serialization, so an\n\t\t\t\t\t// omitted `expiresAt` leaves the expiration unchanged while an\n\t\t\t\t\t// explicit `null` clears it.\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tsnapshot: {\n\t\t\t\t\t\t\tname: input.name,\n\t\t\t\t\t\t\texpires_at: input.expiresAt,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.snapshot,\n\t\t);\n\t}\n\n\t/** @apiCall DELETE /projects/{project_id}/snapshots/{snapshot_id} */\n\tdelete(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t): Promise<Outcome<void, DThrow>>;\n\tdelete<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tdelete(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tdeleteSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t() => undefined,\n\t\t);\n\t}\n\n\t/**\n\t * Restore a snapshot into a branch. Returns the restored branch.\n\t *\n\t * - **As a new branch** (no `targetBranchId`): finalizes by default — ready to use.\n\t * - **Onto an existing branch** (`targetBranchId`): does **not** finalize by default,\n\t * so you can preview before the compute swap. Finish later with\n\t * `branches.finalizeRestore`, or pass a `preview` callback to do it transactionally.\n\t *\n\t * With `preview`, this restores un-finalized, runs your callback against the restored\n\t * branch, then finalizes (commit) or deletes the preview branch (abort, unless\n\t * `keepOnAbort`). Either way it resolves to the restored `Branch`.\n\t *\n\t * @apiCall POST /projects/{project_id}/snapshots/{snapshot_id}/restore\n\t */\n\trestore(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput?: RestoreSnapshotInput,\n\t): Promise<Outcome<Branch, DThrow>>;\n\trestore<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput: RestoreSnapshotInput | undefined,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<Branch, Throw>>;\n\tasync restore(\n\t\tprojectId: string,\n\t\tsnapshotId: string,\n\t\tinput?: RestoreSnapshotInput,\n\t\topts?: CallOptions,\n\t): Promise<Branch | NeonResult<Branch>> {\n\t\tconst shouldThrow =\n\t\t\topts?.throwOnError ?? this.#ctx.defaults.throwOnError;\n\t\tconst preview = input?.preview;\n\t\t// New branch → finalize by default; onto existing → preview-first by default.\n\t\t// The preview flow always restores un-finalized so it can inspect first.\n\t\tconst finalizeNow = preview\n\t\t\t? false\n\t\t\t: (input?.finalize ?? input?.targetBranchId === undefined);\n\n\t\tconst restored = await this.#ctx.execute(\n\t\t\t{\n\t\t\t\t...opts,\n\t\t\t\twaitForReadiness: preview ? true : opts?.waitForReadiness,\n\t\t\t},\n\t\t\t(client, signal) =>\n\t\t\t\trestoreSnapshot({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, snapshot_id: snapshotId },\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input?.name,\n\t\t\t\t\t\ttarget_branch_id: input?.targetBranchId,\n\t\t\t\t\t\tfinalize_restore: finalizeNow,\n\t\t\t\t\t},\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data.branch,\n\t\t);\n\t\tif (restored.error || !preview) {\n\t\t\treturn finalize(restored, shouldThrow);\n\t\t}\n\n\t\tconst branch = restored.data;\n\t\t// The callback is the caller's own code, so the SDK cannot bound it — a callback\n\t\t// that never settles leaves the restore un-finalized however the signal is set.\n\t\t// It gets the signal so it can cooperate, and the abort is honoured either side\n\t\t// of it rather than pretending to interrupt it.\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn finalize(\n\t\t\t\terr<Branch>(\n\t\t\t\t\tnew NeonAbortError(\n\t\t\t\t\t\t\"The restore was aborted before its preview callback ran; the restored branch is left un-finalized.\",\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tshouldThrow,\n\t\t\t);\n\t\t}\n\t\tlet commit: boolean;\n\t\ttry {\n\t\t\tcommit = await preview(branch, { signal: opts?.signal });\n\t\t} catch (error) {\n\t\t\t// A callback that honours the signal by throwing is cooperating correctly, so\n\t\t\t// its `DOMException` must not escape a client that promised `{ data, error }`.\n\t\t\t// Any other throw is the caller's own failure, reported as such rather than\n\t\t\t// swallowed.\n\t\t\treturn finalize(\n\t\t\t\terr<Branch>(\n\t\t\t\t\topts?.signal?.aborted\n\t\t\t\t\t\t? new NeonAbortError(\n\t\t\t\t\t\t\t\t\"The restore was aborted while its preview callback ran; the restored branch is left un-finalized.\",\n\t\t\t\t\t\t\t\t{ cause: error },\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: new NeonError(\n\t\t\t\t\t\t\t\t`The restore's preview callback threw; the restored branch is left un-finalized: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\t\t\"client\",\n\t\t\t\t\t\t\t\t{ cause: error },\n\t\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tshouldThrow,\n\t\t\t);\n\t\t}\n\t\tif (opts?.signal?.aborted) {\n\t\t\treturn finalize(\n\t\t\t\terr<Branch>(\n\t\t\t\t\tnew NeonAbortError(\n\t\t\t\t\t\t\"The restore was aborted after its preview callback ran; the restored branch is left un-finalized.\",\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tshouldThrow,\n\t\t\t);\n\t\t}\n\t\tconst step = commit\n\t\t\t? await this.#ctx.execute(\n\t\t\t\t\t{ ...opts, waitForReadiness: true },\n\t\t\t\t\t(client, signal) =>\n\t\t\t\t\t\tfinalizeRestoreBranch({\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\tbranch_id: branch.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t}),\n\t\t\t\t\t() => undefined,\n\t\t\t\t)\n\t\t\t: input?.keepOnAbort\n\t\t\t\t? ok(undefined)\n\t\t\t\t: await this.#ctx.execute(\n\t\t\t\t\t\t{ ...opts, waitForReadiness: true },\n\t\t\t\t\t\t(client, signal) =>\n\t\t\t\t\t\t\tdeleteProjectBranch({\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\t\t\tproject_id: projectId,\n\t\t\t\t\t\t\t\t\tbranch_id: branch.id,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t);\n\n\t\tif (step.error) return finalize(err<Branch>(step.error), shouldThrow);\n\t\treturn finalize(ok(branch), shouldThrow);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/backup_schedule */\n\tgetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<Outcome<BackupSchedule, DThrow>>;\n\tgetSchedule<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<BackupSchedule, Throw>>;\n\tgetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<BackupSchedule | NeonResult<BackupSchedule>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tgetSnapshotSchedule({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data,\n\t\t);\n\t}\n\n\t/**\n\t * Replace a branch's automatic snapshot schedule.\n\t *\n\t * `frequency` is narrowed to {@link SnapshotFrequency}, so a value the API\n\t * rejects fails to compile. {@link Snapshots.getSchedule} deliberately keeps\n\t * the wider generated type, because a branch can still hold a schedule\n\t * created when the API accepted other frequencies; feeding one straight back\n\t * here is a type error rather than a runtime rejection.\n\t *\n\t * @apiCall PUT /projects/{project_id}/branches/{branch_id}/backup_schedule\n\t */\n\tsetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t): Promise<Outcome<void, DThrow>>;\n\tsetSchedule<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<void, Throw>>;\n\tsetSchedule(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\tschedule: SetScheduleInput,\n\t\topts?: CallOptions,\n\t): Promise<void | NeonResult<void>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tsetSnapshotSchedule({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tbody: schedule,\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t() => undefined,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
@@ -16,13 +16,14 @@ var Storage = class {
16
16
  this.objects = new BucketObjects(ctx);
17
17
  }
18
18
  get(projectId, branchId, opts) {
19
- return this.#ctx.run(opts, (client) => getProjectBranchStorage({
19
+ return this.#ctx.run(opts, (client, signal) => getProjectBranchStorage({
20
20
  client,
21
21
  path: {
22
22
  project_id: projectId,
23
23
  branch_id: branchId
24
24
  },
25
- throwOnError: false
25
+ throwOnError: false,
26
+ signal
26
27
  }), (data) => data);
27
28
  }
28
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","names":["#ctx"],"sources":["../../../src/neon/resources/storage.ts"],"sourcesContent":["import { getProjectBranchStorage } from \"../../client/sdk.gen.js\";\nimport type { BranchStorage } from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport type { NeonResult, Outcome } from \"../result.js\";\nimport { BucketObjects } from \"./bucket-objects.js\";\nimport { Buckets } from \"./buckets.js\";\n\n/**\n * Branch-scoped object storage: branch storage state, buckets, and bucket objects.\n * Grouped under `neon.storage.*` so it stays distinct from the Postgres data plane.\n */\nexport class Storage<DThrow extends boolean> {\n\treadonly buckets: Buckets<DThrow>;\n\treadonly objects: BucketObjects<DThrow>;\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t\tthis.buckets = new Buckets(ctx);\n\t\tthis.objects = new BucketObjects(ctx);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/storage */\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<Outcome<BranchStorage, DThrow>>;\n\tget<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<BranchStorage, Throw>>;\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<BranchStorage | NeonResult<BranchStorage>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client) =>\n\t\t\t\tgetProjectBranchStorage({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t}),\n\t\t\t(data) => data,\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;AAWA,IAAa,UAAb,MAA6C;CAC5C;CACA;CACA;CAEA,YAAY,KAAqB;EAChC,KAAKA,OAAO;EACZ,KAAK,UAAU,IAAI,QAAQ,GAAG;EAC9B,KAAK,UAAU,IAAI,cAAc,GAAG;CACrC;CAYA,IACC,WACA,UACA,MACqD;EACrD,OAAO,KAAKA,KAAK,IAChB,OACC,WACA,wBAAwB;GACvB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,cAAc;EACf,CAAC,IACD,SAAS,IACX;CACD;AACD"}
1
+ {"version":3,"file":"storage.js","names":["#ctx"],"sources":["../../../src/neon/resources/storage.ts"],"sourcesContent":["import { getProjectBranchStorage } from \"../../client/sdk.gen.js\";\nimport type { BranchStorage } from \"../../client/types.gen.js\";\nimport type { CallOptions, RequestContext } from \"../context.js\";\nimport type { NeonResult, Outcome } from \"../result.js\";\nimport { BucketObjects } from \"./bucket-objects.js\";\nimport { Buckets } from \"./buckets.js\";\n\n/**\n * Branch-scoped object storage: branch storage state, buckets, and bucket objects.\n * Grouped under `neon.storage.*` so it stays distinct from the Postgres data plane.\n */\nexport class Storage<DThrow extends boolean> {\n\treadonly buckets: Buckets<DThrow>;\n\treadonly objects: BucketObjects<DThrow>;\n\treadonly #ctx: RequestContext;\n\n\tconstructor(ctx: RequestContext) {\n\t\tthis.#ctx = ctx;\n\t\tthis.buckets = new Buckets(ctx);\n\t\tthis.objects = new BucketObjects(ctx);\n\t}\n\n\t/** @apiCall GET /projects/{project_id}/branches/{branch_id}/storage */\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t): Promise<Outcome<BranchStorage, DThrow>>;\n\tget<Throw extends boolean = DThrow>(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts: CallOptions<Throw>,\n\t): Promise<Outcome<BranchStorage, Throw>>;\n\tget(\n\t\tprojectId: string,\n\t\tbranchId: string,\n\t\topts?: CallOptions,\n\t): Promise<BranchStorage | NeonResult<BranchStorage>> {\n\t\treturn this.#ctx.run(\n\t\t\topts,\n\t\t\t(client, signal) =>\n\t\t\t\tgetProjectBranchStorage({\n\t\t\t\t\tclient,\n\t\t\t\t\tpath: { project_id: projectId, branch_id: branchId },\n\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\tsignal,\n\t\t\t\t}),\n\t\t\t(data) => data,\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;AAWA,IAAa,UAAb,MAA6C;CAC5C;CACA;CACA;CAEA,YAAY,KAAqB;EAChC,KAAKA,OAAO;EACZ,KAAK,UAAU,IAAI,QAAQ,GAAG;EAC9B,KAAK,UAAU,IAAI,cAAc,GAAG;CACrC;CAYA,IACC,WACA,UACA,MACqD;EACrD,OAAO,KAAKA,KAAK,IAChB,OACC,QAAQ,WACR,wBAAwB;GACvB;GACA,MAAM;IAAE,YAAY;IAAW,WAAW;GAAS;GACnD,cAAc;GACd;EACD,CAAC,IACD,SAAS,IACX;CACD;AACD"}
@@ -1,17 +1,39 @@
1
+ import { Deadline } from "./deadline.js";
2
+
1
3
  //#region src/neon/retry.d.ts
2
- /**
3
- * Minimal retry-with-backoff for idempotent reads and 429s. The raw layer does no
4
- * retries; the ergonomic client opts in via `retries` config.
5
- */
4
+
6
5
  interface RawOutcome {
7
6
  error?: unknown;
8
7
  response?: Response | undefined;
9
8
  }
9
+ /** Ceiling on generated backoff, and on how long a `Retry-After` is worth honouring. */
10
+ declare const MAX_RETRY_WAIT_MS = 10000;
11
+ /**
12
+ * `Retry-After` in milliseconds, or `undefined` when absent or unparseable.
13
+ *
14
+ * The header comes in two forms and only one of them is a number. Reading just the
15
+ * numeric form leaves an HTTP-date parsing as `NaN`, which silently falls through to
16
+ * generated backoff — retrying far sooner than the server asked.
17
+ */
18
+ declare function parseRetryAfterMs(header: string | null | undefined, now: number): number | undefined;
19
+ /** Exponential backoff with full jitter: base 250ms, capped at {@link MAX_RETRY_WAIT_MS}. */
20
+ declare function backoffMs(attempt: number, random?: () => number): number;
21
+ /**
22
+ * How long to wait before the next attempt, or `undefined` to stop retrying.
23
+ *
24
+ * `Retry-After` is the server's requested **minimum** delay, so it is never shortened —
25
+ * retrying earlier than instructed is worse than not retrying at all. When honouring it
26
+ * would cost more than {@link MAX_RETRY_WAIT_MS}, or more budget than the call has left,
27
+ * the answer is to stop and let the caller see the real `423`/`429`/`503` rather than to
28
+ * wait for minutes or to report a timeout that hides the status.
29
+ */
30
+ declare function nextRetryDelayMs(attempt: number, retryAfterMs: number | undefined, remainingMs: number, random?: () => number): number | undefined;
10
31
  /**
11
- * Run `exec` up to `retries + 1` times, retrying only on retryable HTTP statuses
12
- * (`423`, `429`, `5xx`). Non-retryable errors and successes return immediately.
32
+ * Run `exec` up to `retries + 1` times, retrying only on `423`, `429` and `503`.
33
+ * Non-retryable errors and successes return immediately, as does a cancelled deadline —
34
+ * the caller inspects {@link Deadline.source} to tell cancellation from the last result.
13
35
  */
14
- declare function withRetries<T extends RawOutcome>(exec: () => Promise<T>, retries: number, signal?: AbortSignal): Promise<T>;
36
+ declare function withRetries<T extends RawOutcome>(exec: () => Promise<T>, retries: number, deadline: Deadline): Promise<T>;
15
37
  //#endregion
16
- export { RawOutcome, withRetries };
38
+ export { MAX_RETRY_WAIT_MS, RawOutcome, backoffMs, nextRetryDelayMs, parseRetryAfterMs, withRetries };
17
39
  //# sourceMappingURL=retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","names":[],"sources":["../../src/neon/retry.ts"],"mappings":";;AAKA;AAuCA;AAAiC;AAAW,UAvC3B,UAAA,CAuC2B;EACvB,KAAA,CAAA,EAAA,OAAA;EAAR,QAAA,CAAA,EAtCD,QAsCC,GAAA,SAAA;AAEH;AACC;AAAR;AAAO;;iBAJY,sBAAsB,wBAC/B,QAAQ,8BAEX,cACP,QAAQ"}
1
+ {"version":3,"file":"retry.d.ts","names":[],"sources":["../../src/neon/retry.ts"],"mappings":";;;;AA2F4C,UA/E3B,UAAA,CA+E2B;EACvB,KAAA,CAAA,EAAA,OAAA;EAAR,QAAA,CAAA,EA9ED,QA8EC,GAAA,SAAA;AAEF;AACA;AAAR,cAxEU,iBAAA,GAwEV,KAAA;AAAO;;;;;;;iBA/DM,iBAAA;;iBA4BA,SAAA;;;;;;;;;;iBAcA,gBAAA;;;;;;iBAiBM,sBAAsB,wBAC/B,QAAQ,+BAEV,WACR,QAAQ"}
@@ -1,42 +1,81 @@
1
+ import { delay } from "./deadline.js";
1
2
  //#region src/neon/retry.ts
3
+ /**
4
+ * Retry-with-backoff for the statuses Neon documents as always safe to replay. The raw
5
+ * layer does no retries; the ergonomic client opts in via `retries`.
6
+ *
7
+ * The scheduling decisions are pure functions so they can be tested directly, without
8
+ * fake timers or a stopwatch: {@link parseRetryAfterMs} reads the header,
9
+ * {@link backoffMs} picks a delay, and {@link nextRetryDelayMs} decides whether a retry
10
+ * is worth waiting for at all.
11
+ */
2
12
  const RETRYABLE_STATUS = /* @__PURE__ */ new Set([
3
13
  423,
4
14
  429,
5
15
  503
6
16
  ]);
7
- function backoffMs(attempt, response) {
8
- const retryAfter = response?.headers.get("retry-after");
9
- if (retryAfter) {
10
- const seconds = Number(retryAfter);
11
- if (Number.isFinite(seconds)) return seconds * 1e3;
17
+ /** Ceiling on generated backoff, and on how long a `Retry-After` is worth honouring. */
18
+ const MAX_RETRY_WAIT_MS = 1e4;
19
+ /**
20
+ * `Retry-After` in milliseconds, or `undefined` when absent or unparseable.
21
+ *
22
+ * The header comes in two forms and only one of them is a number. Reading just the
23
+ * numeric form leaves an HTTP-date parsing as `NaN`, which silently falls through to
24
+ * generated backoff — retrying far sooner than the server asked.
25
+ */
26
+ function parseRetryAfterMs(header, now) {
27
+ if (!header) return void 0;
28
+ const trimmed = header.trim();
29
+ if (trimmed === "") return void 0;
30
+ if (/^\d+$/.test(trimmed)) {
31
+ const seconds = Number(trimmed);
32
+ return Number.isFinite(seconds * 1e3) ? seconds * 1e3 : Number.POSITIVE_INFINITY;
12
33
  }
13
- const ceiling = Math.min(1e4, 250 * 2 ** attempt);
14
- return Math.random() * ceiling;
34
+ if (Number.isFinite(Number(trimmed))) return void 0;
35
+ const at = Date.parse(trimmed);
36
+ if (Number.isNaN(at)) return void 0;
37
+ return Math.max(0, at - now);
38
+ }
39
+ /** Exponential backoff with full jitter: base 250ms, capped at {@link MAX_RETRY_WAIT_MS}. */
40
+ function backoffMs(attempt, random = Math.random) {
41
+ const ceiling = Math.min(MAX_RETRY_WAIT_MS, 250 * 2 ** attempt);
42
+ return random() * ceiling;
43
+ }
44
+ /**
45
+ * How long to wait before the next attempt, or `undefined` to stop retrying.
46
+ *
47
+ * `Retry-After` is the server's requested **minimum** delay, so it is never shortened —
48
+ * retrying earlier than instructed is worse than not retrying at all. When honouring it
49
+ * would cost more than {@link MAX_RETRY_WAIT_MS}, or more budget than the call has left,
50
+ * the answer is to stop and let the caller see the real `423`/`429`/`503` rather than to
51
+ * wait for minutes or to report a timeout that hides the status.
52
+ */
53
+ function nextRetryDelayMs(attempt, retryAfterMs, remainingMs, random) {
54
+ const wait = retryAfterMs ?? backoffMs(attempt, random);
55
+ if (wait > 1e4) return void 0;
56
+ if (wait >= remainingMs) return void 0;
57
+ return wait;
15
58
  }
16
- const sleep = (ms, signal) => new Promise((resolve, reject) => {
17
- if (signal?.aborted) return reject(signal.reason);
18
- const id = setTimeout(resolve, ms);
19
- signal?.addEventListener("abort", () => {
20
- clearTimeout(id);
21
- reject(signal.reason);
22
- }, { once: true });
23
- });
24
59
  /**
25
- * Run `exec` up to `retries + 1` times, retrying only on retryable HTTP statuses
26
- * (`423`, `429`, `5xx`). Non-retryable errors and successes return immediately.
60
+ * Run `exec` up to `retries + 1` times, retrying only on `423`, `429` and `503`.
61
+ * Non-retryable errors and successes return immediately, as does a cancelled deadline —
62
+ * the caller inspects {@link Deadline.source} to tell cancellation from the last result.
27
63
  */
28
- async function withRetries(exec, retries, signal) {
64
+ async function withRetries(exec, retries, deadline) {
29
65
  let attempt = 0;
30
66
  for (;;) {
31
67
  const result = await exec();
32
68
  const status = result.response?.status;
33
69
  const retryable = status !== void 0 && RETRYABLE_STATUS.has(status);
34
70
  if (!result.error || !retryable || attempt >= retries) return result;
35
- await sleep(backoffMs(attempt, result.response), signal);
71
+ if (deadline.source()) return result;
72
+ const wait = nextRetryDelayMs(attempt, parseRetryAfterMs(result.response?.headers.get("retry-after"), Date.now()), deadline.remainingMs());
73
+ if (wait === void 0) return result;
74
+ if (await delay(wait, deadline.signal) === "cancelled") return result;
36
75
  attempt += 1;
37
76
  }
38
77
  }
39
78
  //#endregion
40
- export { withRetries };
79
+ export { MAX_RETRY_WAIT_MS, backoffMs, nextRetryDelayMs, parseRetryAfterMs, withRetries };
41
80
 
42
81
  //# sourceMappingURL=retry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","names":[],"sources":["../../src/neon/retry.ts"],"sourcesContent":["/**\n * Minimal retry-with-backoff for idempotent reads and 429s. The raw layer does no\n * retries; the ergonomic client opts in via `retries` config.\n */\n\nexport interface RawOutcome {\n\terror?: unknown;\n\tresponse?: Response | undefined;\n}\n\n// Only statuses Neon documents as always-safe to retry (no work performed / locked /\n// rate limited) — safe for non-idempotent methods too. 5xx is intentionally excluded\n// from the default since a mutating request may have partially applied.\nconst RETRYABLE_STATUS = new Set([423, 429, 503]);\n\nfunction backoffMs(attempt: number, response: Response | undefined): number {\n\tconst retryAfter = response?.headers.get(\"retry-after\");\n\tif (retryAfter) {\n\t\tconst seconds = Number(retryAfter);\n\t\tif (Number.isFinite(seconds)) return seconds * 1000;\n\t}\n\t// exponential backoff with full jitter: base 250ms, capped at 10s\n\tconst ceiling = Math.min(10_000, 250 * 2 ** attempt);\n\treturn Math.random() * ceiling;\n}\n\nconst sleep = (ms: number, signal?: AbortSignal): Promise<void> =>\n\tnew Promise((resolve, reject) => {\n\t\tif (signal?.aborted) return reject(signal.reason);\n\t\tconst id = setTimeout(resolve, ms);\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(id);\n\t\t\t\treject(signal.reason);\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n\n/**\n * Run `exec` up to `retries + 1` times, retrying only on retryable HTTP statuses\n * (`423`, `429`, `5xx`). Non-retryable errors and successes return immediately.\n */\nexport async function withRetries<T extends RawOutcome>(\n\texec: () => Promise<T>,\n\tretries: number,\n\tsignal?: AbortSignal,\n): Promise<T> {\n\tlet attempt = 0;\n\tfor (;;) {\n\t\tconst result = await exec();\n\t\tconst status = result.response?.status;\n\t\tconst retryable = status !== undefined && RETRYABLE_STATUS.has(status);\n\t\tif (!result.error || !retryable || attempt >= retries) return result;\n\t\tawait sleep(backoffMs(attempt, result.response), signal);\n\t\tattempt += 1;\n\t}\n}\n"],"mappings":";AAaA,MAAM,mCAAmB,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC;AAEhD,SAAS,UAAU,SAAiB,UAAwC;CAC3E,MAAM,aAAa,UAAU,QAAQ,IAAI,aAAa;CACtD,IAAI,YAAY;EACf,MAAM,UAAU,OAAO,UAAU;EACjC,IAAI,OAAO,SAAS,OAAO,GAAG,OAAO,UAAU;CAChD;CAEA,MAAM,UAAU,KAAK,IAAI,KAAQ,MAAM,KAAK,OAAO;CACnD,OAAO,KAAK,OAAO,IAAI;AACxB;AAEA,MAAM,SAAS,IAAY,WAC1B,IAAI,SAAS,SAAS,WAAW;CAChC,IAAI,QAAQ,SAAS,OAAO,OAAO,OAAO,MAAM;CAChD,MAAM,KAAK,WAAW,SAAS,EAAE;CACjC,QAAQ,iBACP,eACM;EACL,aAAa,EAAE;EACf,OAAO,OAAO,MAAM;CACrB,GACA,EAAE,MAAM,KAAK,CACd;AACD,CAAC;;;;;AAMF,eAAsB,YACrB,MACA,SACA,QACa;CACb,IAAI,UAAU;CACd,SAAS;EACR,MAAM,SAAS,MAAM,KAAK;EAC1B,MAAM,SAAS,OAAO,UAAU;EAChC,MAAM,YAAY,WAAW,KAAA,KAAa,iBAAiB,IAAI,MAAM;EACrE,IAAI,CAAC,OAAO,SAAS,CAAC,aAAa,WAAW,SAAS,OAAO;EAC9D,MAAM,MAAM,UAAU,SAAS,OAAO,QAAQ,GAAG,MAAM;EACvD,WAAW;CACZ;AACD"}
1
+ {"version":3,"file":"retry.js","names":[],"sources":["../../src/neon/retry.ts"],"sourcesContent":["/**\n * Retry-with-backoff for the statuses Neon documents as always safe to replay. The raw\n * layer does no retries; the ergonomic client opts in via `retries`.\n *\n * The scheduling decisions are pure functions so they can be tested directly, without\n * fake timers or a stopwatch: {@link parseRetryAfterMs} reads the header,\n * {@link backoffMs} picks a delay, and {@link nextRetryDelayMs} decides whether a retry\n * is worth waiting for at all.\n */\n\nimport { type Deadline, delay } from \"./deadline.js\";\n\nexport interface RawOutcome {\n\terror?: unknown;\n\tresponse?: Response | undefined;\n}\n\n// Only statuses Neon documents as always-safe to retry (no work performed / locked /\n// rate limited) — safe for non-idempotent methods too. 5xx other than 503 is\n// intentionally excluded, since a mutating request may have partially applied.\nconst RETRYABLE_STATUS = new Set([423, 429, 503]);\n\n/** Ceiling on generated backoff, and on how long a `Retry-After` is worth honouring. */\nexport const MAX_RETRY_WAIT_MS = 10_000;\n\n/**\n * `Retry-After` in milliseconds, or `undefined` when absent or unparseable.\n *\n * The header comes in two forms and only one of them is a number. Reading just the\n * numeric form leaves an HTTP-date parsing as `NaN`, which silently falls through to\n * generated backoff — retrying far sooner than the server asked.\n */\nexport function parseRetryAfterMs(\n\theader: string | null | undefined,\n\tnow: number,\n): number | undefined {\n\tif (!header) return undefined;\n\tconst trimmed = header.trim();\n\tif (trimmed === \"\") return undefined;\n\n\t// RFC 9110 delta-seconds is a non-negative integer.\n\tif (/^\\d+$/.test(trimmed)) {\n\t\tconst seconds = Number(trimmed);\n\t\treturn Number.isFinite(seconds * 1000)\n\t\t\t? seconds * 1000\n\t\t\t: Number.POSITIVE_INFINITY;\n\t}\n\n\t// A malformed number must be rejected here rather than fall through to the date\n\t// parser. `Date.parse` is permissive enough to read \"-1\", \"1.5\" and \"+5\" as dates in\n\t// 2001 — all in the past, so the delay clamped to 0 and a malformed header became an\n\t// immediate retry, which is the opposite of what it asks for.\n\tif (Number.isFinite(Number(trimmed))) return undefined;\n\n\tconst at = Date.parse(trimmed);\n\tif (Number.isNaN(at)) return undefined;\n\treturn Math.max(0, at - now);\n}\n\n/** Exponential backoff with full jitter: base 250ms, capped at {@link MAX_RETRY_WAIT_MS}. */\nexport function backoffMs(attempt: number, random = Math.random): number {\n\tconst ceiling = Math.min(MAX_RETRY_WAIT_MS, 250 * 2 ** attempt);\n\treturn random() * ceiling;\n}\n\n/**\n * How long to wait before the next attempt, or `undefined` to stop retrying.\n *\n * `Retry-After` is the server's requested **minimum** delay, so it is never shortened —\n * retrying earlier than instructed is worse than not retrying at all. When honouring it\n * would cost more than {@link MAX_RETRY_WAIT_MS}, or more budget than the call has left,\n * the answer is to stop and let the caller see the real `423`/`429`/`503` rather than to\n * wait for minutes or to report a timeout that hides the status.\n */\nexport function nextRetryDelayMs(\n\tattempt: number,\n\tretryAfterMs: number | undefined,\n\tremainingMs: number,\n\trandom?: () => number,\n): number | undefined {\n\tconst wait = retryAfterMs ?? backoffMs(attempt, random);\n\tif (wait > MAX_RETRY_WAIT_MS) return undefined;\n\tif (wait >= remainingMs) return undefined;\n\treturn wait;\n}\n\n/**\n * Run `exec` up to `retries + 1` times, retrying only on `423`, `429` and `503`.\n * Non-retryable errors and successes return immediately, as does a cancelled deadline —\n * the caller inspects {@link Deadline.source} to tell cancellation from the last result.\n */\nexport async function withRetries<T extends RawOutcome>(\n\texec: () => Promise<T>,\n\tretries: number,\n\tdeadline: Deadline,\n): Promise<T> {\n\tlet attempt = 0;\n\tfor (;;) {\n\t\tconst result = await exec();\n\t\tconst status = result.response?.status;\n\t\tconst retryable = status !== undefined && RETRYABLE_STATUS.has(status);\n\t\tif (!result.error || !retryable || attempt >= retries) return result;\n\t\tif (deadline.source()) return result;\n\n\t\tconst wait = nextRetryDelayMs(\n\t\t\tattempt,\n\t\t\tparseRetryAfterMs(\n\t\t\t\tresult.response?.headers.get(\"retry-after\"),\n\t\t\t\tDate.now(),\n\t\t\t),\n\t\t\tdeadline.remainingMs(),\n\t\t);\n\t\tif (wait === undefined) return result;\n\n\t\tif ((await delay(wait, deadline.signal)) === \"cancelled\") return result;\n\t\tattempt += 1;\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAoBA,MAAM,mCAAmB,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC;;AAGhD,MAAa,oBAAoB;;;;;;;;AASjC,SAAgB,kBACf,QACA,KACqB;CACrB,IAAI,CAAC,QAAQ,OAAO,KAAA;CACpB,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,YAAY,IAAI,OAAO,KAAA;CAG3B,IAAI,QAAQ,KAAK,OAAO,GAAG;EAC1B,MAAM,UAAU,OAAO,OAAO;EAC9B,OAAO,OAAO,SAAS,UAAU,GAAI,IAClC,UAAU,MACV,OAAO;CACX;CAMA,IAAI,OAAO,SAAS,OAAO,OAAO,CAAC,GAAG,OAAO,KAAA;CAE7C,MAAM,KAAK,KAAK,MAAM,OAAO;CAC7B,IAAI,OAAO,MAAM,EAAE,GAAG,OAAO,KAAA;CAC7B,OAAO,KAAK,IAAI,GAAG,KAAK,GAAG;AAC5B;;AAGA,SAAgB,UAAU,SAAiB,SAAS,KAAK,QAAgB;CACxE,MAAM,UAAU,KAAK,IAAI,mBAAmB,MAAM,KAAK,OAAO;CAC9D,OAAO,OAAO,IAAI;AACnB;;;;;;;;;;AAWA,SAAgB,iBACf,SACA,cACA,aACA,QACqB;CACrB,MAAM,OAAO,gBAAgB,UAAU,SAAS,MAAM;CACtD,IAAI,OAAA,KAA0B,OAAO,KAAA;CACrC,IAAI,QAAQ,aAAa,OAAO,KAAA;CAChC,OAAO;AACR;;;;;;AAOA,eAAsB,YACrB,MACA,SACA,UACa;CACb,IAAI,UAAU;CACd,SAAS;EACR,MAAM,SAAS,MAAM,KAAK;EAC1B,MAAM,SAAS,OAAO,UAAU;EAChC,MAAM,YAAY,WAAW,KAAA,KAAa,iBAAiB,IAAI,MAAM;EACrE,IAAI,CAAC,OAAO,SAAS,CAAC,aAAa,WAAW,SAAS,OAAO;EAC9D,IAAI,SAAS,OAAO,GAAG,OAAO;EAE9B,MAAM,OAAO,iBACZ,SACA,kBACC,OAAO,UAAU,QAAQ,IAAI,aAAa,GAC1C,KAAK,IAAI,CACV,GACA,SAAS,YAAY,CACtB;EACA,IAAI,SAAS,KAAA,GAAW,OAAO;EAE/B,IAAK,MAAM,MAAM,MAAM,SAAS,MAAM,MAAO,aAAa,OAAO;EACjE,WAAW;CACZ;AACD"}