@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
@@ -13,7 +13,13 @@ interface WaitForOptions {
13
13
  /**
14
14
  * Poll the given operations until each reaches a terminal `finished`/`skipped` state.
15
15
  * Returns an error result carrying {@link NeonOperationError} if any operation ends in
16
- * `failed`/`error`/`cancelled`, or {@link NeonTimeoutError} if the deadline is exceeded.
16
+ * `failed`/`error`/`cancelled`, {@link NeonTimeoutError} if the deadline is exceeded, or
17
+ * {@link NeonAbortError} if the caller's signal fired.
18
+ *
19
+ * `timeoutMs` is a real deadline rather than a check between polls. Each poll runs under
20
+ * it, so a request that hangs cannot outlast the budget, and the budget is re-examined
21
+ * after every operation rather than once per round — a round polls each pending operation
22
+ * in turn, so checking only at the top let a long round overrun the timeout arbitrarily.
17
23
  *
18
24
  * Composable: usable directly with operations obtained from the raw layer.
19
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"wait.d.ts","names":[],"sources":["../../src/neon/wait.ts"],"mappings":";;;;;UAaiB,cAAA;;EAAA,cAAA,CAAA,EAAc,MAAA;EA6BT;EAAiB,SAAA,CAAA,EAAA,MAAA;EAC9B,MAAA,CAAA,EAzBC,WAyBD;AACa;AACZ;AACC;AAAR;AAAO;AAqDV;;;iBAzDsB,iBAAA,SACb,6BACa,uBACZ,iBACP,QAAQ;;iBAqDK,aAAA;cAES"}
1
+ {"version":3,"file":"wait.d.ts","names":[],"sources":["../../src/neon/wait.ts"],"mappings":";;;;;UAyBiB,cAAA;;EAAA,cAAA,CAAA,EAAc,MAAA;EA4CT;EAAiB,SAAA,CAAA,EAAA,MAAA;EAC9B,MAAA,CAAA,EAxCC,WAwCD;AACa;AACZ;AACC;AAAR;AAAO;AAmFV;;;;;;;;;iBAvFsB,iBAAA,SACb,6BACa,uBACZ,iBACP,QAAQ;;iBAmFK,aAAA;cAES"}
package/dist/neon/wait.js CHANGED
@@ -1,4 +1,5 @@
1
- import { NeonOperationError, NeonTimeoutError, toNeonError } from "./errors.js";
1
+ import { NeonAbortError, NeonOperationError, NeonTimeoutError, toNeonError } from "./errors.js";
2
+ import { createDeadline, delay, runBounded } from "./deadline.js";
2
3
  import { err, ok } from "./result.js";
3
4
  import { getProjectOperation } from "../client/sdk.gen.js";
4
5
  //#region src/neon/wait.ts
@@ -8,50 +9,68 @@ const FAILURE = /* @__PURE__ */ new Set([
8
9
  "error",
9
10
  "cancelled"
10
11
  ]);
11
- const sleep = (ms, signal) => new Promise((resolve, reject) => {
12
- if (signal?.aborted) return reject(signal.reason);
13
- const id = setTimeout(resolve, ms);
14
- signal?.addEventListener("abort", () => {
15
- clearTimeout(id);
16
- reject(signal.reason);
17
- }, { once: true });
18
- });
12
+ /**
13
+ * Why waiting stopped, with a message about readiness rather than about a request.
14
+ * Returns `undefined` while the wait may continue.
15
+ */
16
+ function readinessEnded(deadline, timeoutMs, pending) {
17
+ const source = deadline.source();
18
+ if (source === "caller") return new NeonAbortError("Waiting for operations was aborted by its signal.");
19
+ if (source === "timeout") return new NeonTimeoutError(`Timed out after ${timeoutMs}ms waiting for ${pending} operation(s) to finish.`);
20
+ }
19
21
  /**
20
22
  * Poll the given operations until each reaches a terminal `finished`/`skipped` state.
21
23
  * Returns an error result carrying {@link NeonOperationError} if any operation ends in
22
- * `failed`/`error`/`cancelled`, or {@link NeonTimeoutError} if the deadline is exceeded.
24
+ * `failed`/`error`/`cancelled`, {@link NeonTimeoutError} if the deadline is exceeded, or
25
+ * {@link NeonAbortError} if the caller's signal fired.
26
+ *
27
+ * `timeoutMs` is a real deadline rather than a check between polls. Each poll runs under
28
+ * it, so a request that hangs cannot outlast the budget, and the budget is re-examined
29
+ * after every operation rather than once per round — a round polls each pending operation
30
+ * in turn, so checking only at the top let a long round overrun the timeout arbitrarily.
23
31
  *
24
32
  * Composable: usable directly with operations obtained from the raw layer.
25
33
  */
26
34
  async function waitForOperations(client, operations, options = {}) {
27
35
  const pollIntervalMs = options.pollIntervalMs ?? 1e3;
28
36
  const timeoutMs = options.timeoutMs ?? 3e5;
29
- const deadline = Date.now() + timeoutMs;
30
- let pending = operations.filter((op) => !SUCCESS.has(op.status));
31
- for (const op of pending) if (FAILURE.has(op.status)) return err(operationFailed(op));
32
- pending = pending.filter((op) => !FAILURE.has(op.status));
33
- while (pending.length > 0) {
34
- if (Date.now() > deadline) return err(new NeonTimeoutError(`Timed out after ${timeoutMs}ms waiting for ${pending.length} operation(s) to finish.`));
35
- await sleep(pollIntervalMs, options.signal);
36
- const stillPending = [];
37
- for (const op of pending) {
38
- const { data, error, response } = await getProjectOperation({
39
- client,
40
- path: {
41
- project_id: op.project_id,
42
- operation_id: op.id
43
- },
44
- throwOnError: false,
45
- signal: options.signal
46
- });
47
- if (error || !data) return err(toNeonError(error, response));
48
- const current = data.operation;
49
- if (FAILURE.has(current.status)) return err(operationFailed(current));
50
- if (!SUCCESS.has(current.status)) stillPending.push(current);
37
+ const deadline = createDeadline(timeoutMs, options.signal);
38
+ try {
39
+ let pending = operations.filter((op) => !SUCCESS.has(op.status));
40
+ for (const op of pending) if (FAILURE.has(op.status)) return err(operationFailed(op));
41
+ pending = pending.filter((op) => !FAILURE.has(op.status));
42
+ while (pending.length > 0) {
43
+ const ended = readinessEnded(deadline, timeoutMs, pending.length);
44
+ if (ended) return err(ended);
45
+ if (await delay(pollIntervalMs, deadline.signal) === "cancelled") return err(readinessEnded(deadline, timeoutMs, pending.length) ?? new NeonAbortError("Waiting for operations was aborted by its signal."));
46
+ const stillPending = [];
47
+ let remaining = pending.length;
48
+ for (const op of pending) {
49
+ const polled = await runBounded(deadline, () => getProjectOperation({
50
+ client,
51
+ path: {
52
+ project_id: op.project_id,
53
+ operation_id: op.id
54
+ },
55
+ throwOnError: false,
56
+ signal: deadline.signal
57
+ }));
58
+ const stopped = readinessEnded(deadline, timeoutMs, remaining);
59
+ if (stopped) return err(stopped);
60
+ if (polled === void 0) return err(toNeonError(void 0, void 0));
61
+ const { data, error, response } = polled;
62
+ if (error || !data) return err(toNeonError(error, response));
63
+ const current = data.operation;
64
+ if (FAILURE.has(current.status)) return err(operationFailed(current));
65
+ if (SUCCESS.has(current.status)) remaining -= 1;
66
+ else stillPending.push(current);
67
+ }
68
+ pending = stillPending;
51
69
  }
52
- pending = stillPending;
70
+ return ok(void 0);
71
+ } finally {
72
+ deadline.dispose();
53
73
  }
54
- return ok(void 0);
55
74
  }
56
75
  function operationFailed(op) {
57
76
  const detail = op.error ? `: ${op.error}` : "";
@@ -1 +1 @@
1
- {"version":3,"file":"wait.js","names":[],"sources":["../../src/neon/wait.ts"],"sourcesContent":["import type { Client } from \"../client/client/index.js\";\nimport { getProjectOperation } from \"../client/sdk.gen.js\";\nimport type { Operation, OperationStatus } from \"../client/types.gen.js\";\nimport { NeonOperationError, NeonTimeoutError, toNeonError } from \"./errors.js\";\nimport { err, type NeonResult, ok } from \"./result.js\";\n\nconst SUCCESS: ReadonlySet<OperationStatus> = new Set([\"finished\", \"skipped\"]);\nconst FAILURE: ReadonlySet<OperationStatus> = new Set([\n\t\"failed\",\n\t\"error\",\n\t\"cancelled\",\n]);\n\nexport interface WaitForOptions {\n\t/** How often to poll each pending operation. Default 1000ms. */\n\tpollIntervalMs?: number;\n\t/** Overall deadline before giving up. Default 300000ms (5 min). */\n\ttimeoutMs?: number;\n\tsignal?: AbortSignal;\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 * Poll the given operations until each reaches a terminal `finished`/`skipped` state.\n * Returns an error result carrying {@link NeonOperationError} if any operation ends in\n * `failed`/`error`/`cancelled`, or {@link NeonTimeoutError} if the deadline is exceeded.\n *\n * Composable: usable directly with operations obtained from the raw layer.\n */\nexport async function waitForOperations(\n\tclient: Client,\n\toperations: readonly Operation[],\n\toptions: WaitForOptions = {},\n): Promise<NeonResult<void>> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 1000;\n\tconst timeoutMs = options.timeoutMs ?? 300_000;\n\tconst deadline = Date.now() + timeoutMs;\n\n\t// Track only operations that aren't already in a terminal state.\n\tlet pending = operations.filter((op) => !SUCCESS.has(op.status));\n\n\tfor (const op of pending) {\n\t\tif (FAILURE.has(op.status)) return err(operationFailed(op));\n\t}\n\tpending = pending.filter((op) => !FAILURE.has(op.status));\n\n\twhile (pending.length > 0) {\n\t\tif (Date.now() > deadline) {\n\t\t\treturn err(\n\t\t\t\tnew NeonTimeoutError(\n\t\t\t\t\t`Timed out after ${timeoutMs}ms waiting for ${pending.length} operation(s) to finish.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tawait sleep(pollIntervalMs, options.signal);\n\n\t\tconst stillPending: Operation[] = [];\n\t\tfor (const op of pending) {\n\t\t\tconst { data, error, response } = await getProjectOperation({\n\t\t\t\tclient,\n\t\t\t\tpath: { project_id: op.project_id, operation_id: op.id },\n\t\t\t\tthrowOnError: false,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\t\t\tif (error || !data) return err(toNeonError(error, response));\n\n\t\t\tconst current = data.operation;\n\t\t\tif (FAILURE.has(current.status))\n\t\t\t\treturn err(operationFailed(current));\n\t\t\tif (!SUCCESS.has(current.status)) stillPending.push(current);\n\t\t}\n\t\tpending = stillPending;\n\t}\n\n\treturn ok(undefined);\n}\n\nfunction operationFailed(op: Operation): NeonOperationError {\n\tconst detail = op.error ? `: ${op.error}` : \"\";\n\treturn new NeonOperationError(\n\t\t`Operation ${op.id} (${op.action}) ended with status \"${op.status}\"${detail}.`,\n\t\t{ operationId: op.id, status: op.status },\n\t);\n}\n\n/** Type guard: does a response body carry an `operations` array we can wait on? */\nexport function hasOperations(\n\tdata: unknown,\n): data is { operations: Operation[] } {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"operations\" in data &&\n\t\tArray.isArray(data.operations)\n\t);\n}\n"],"mappings":";;;;AAMA,MAAM,0BAAwC,IAAI,IAAI,CAAC,YAAY,SAAS,CAAC;AAC7E,MAAM,0BAAwC,IAAI,IAAI;CACrD;CACA;CACA;AACD,CAAC;AAUD,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;;;;;;;;AASF,eAAsB,kBACrB,QACA,YACA,UAA0B,CAAC,GACC;CAC5B,MAAM,iBAAiB,QAAQ,kBAAkB;CACjD,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,WAAW,KAAK,IAAI,IAAI;CAG9B,IAAI,UAAU,WAAW,QAAQ,OAAO,CAAC,QAAQ,IAAI,GAAG,MAAM,CAAC;CAE/D,KAAK,MAAM,MAAM,SAChB,IAAI,QAAQ,IAAI,GAAG,MAAM,GAAG,OAAO,IAAI,gBAAgB,EAAE,CAAC;CAE3D,UAAU,QAAQ,QAAQ,OAAO,CAAC,QAAQ,IAAI,GAAG,MAAM,CAAC;CAExD,OAAO,QAAQ,SAAS,GAAG;EAC1B,IAAI,KAAK,IAAI,IAAI,UAChB,OAAO,IACN,IAAI,iBACH,mBAAmB,UAAU,iBAAiB,QAAQ,OAAO,yBAC9D,CACD;EAED,MAAM,MAAM,gBAAgB,QAAQ,MAAM;EAE1C,MAAM,eAA4B,CAAC;EACnC,KAAK,MAAM,MAAM,SAAS;GACzB,MAAM,EAAE,MAAM,OAAO,aAAa,MAAM,oBAAoB;IAC3D;IACA,MAAM;KAAE,YAAY,GAAG;KAAY,cAAc,GAAG;IAAG;IACvD,cAAc;IACd,QAAQ,QAAQ;GACjB,CAAC;GACD,IAAI,SAAS,CAAC,MAAM,OAAO,IAAI,YAAY,OAAO,QAAQ,CAAC;GAE3D,MAAM,UAAU,KAAK;GACrB,IAAI,QAAQ,IAAI,QAAQ,MAAM,GAC7B,OAAO,IAAI,gBAAgB,OAAO,CAAC;GACpC,IAAI,CAAC,QAAQ,IAAI,QAAQ,MAAM,GAAG,aAAa,KAAK,OAAO;EAC5D;EACA,UAAU;CACX;CAEA,OAAO,GAAG,KAAA,CAAS;AACpB;AAEA,SAAS,gBAAgB,IAAmC;CAC3D,MAAM,SAAS,GAAG,QAAQ,KAAK,GAAG,UAAU;CAC5C,OAAO,IAAI,mBACV,aAAa,GAAG,GAAG,IAAI,GAAG,OAAO,uBAAuB,GAAG,OAAO,GAAG,OAAO,IAC5E;EAAE,aAAa,GAAG;EAAI,QAAQ,GAAG;CAAO,CACzC;AACD;;AAGA,SAAgB,cACf,MACsC;CACtC,OACC,OAAO,SAAS,YAChB,SAAS,QACT,gBAAgB,QAChB,MAAM,QAAQ,KAAK,UAAU;AAE/B"}
1
+ {"version":3,"file":"wait.js","names":[],"sources":["../../src/neon/wait.ts"],"sourcesContent":["import type { Client } from \"../client/client/index.js\";\nimport { getProjectOperation } from \"../client/sdk.gen.js\";\nimport type { Operation, OperationStatus } from \"../client/types.gen.js\";\nimport {\n\tcreateDeadline,\n\ttype Deadline,\n\tdelay,\n\trunBounded,\n} from \"./deadline.js\";\nimport {\n\tNeonAbortError,\n\ttype NeonError,\n\tNeonOperationError,\n\tNeonTimeoutError,\n\ttoNeonError,\n} from \"./errors.js\";\nimport { err, type NeonResult, ok } from \"./result.js\";\n\nconst SUCCESS: ReadonlySet<OperationStatus> = new Set([\"finished\", \"skipped\"]);\nconst FAILURE: ReadonlySet<OperationStatus> = new Set([\n\t\"failed\",\n\t\"error\",\n\t\"cancelled\",\n]);\n\nexport interface WaitForOptions {\n\t/** How often to poll each pending operation. Default 1000ms. */\n\tpollIntervalMs?: number;\n\t/** Overall deadline before giving up. Default 300000ms (5 min). */\n\ttimeoutMs?: number;\n\tsignal?: AbortSignal;\n}\n\n/**\n * Why waiting stopped, with a message about readiness rather than about a request.\n * Returns `undefined` while the wait may continue.\n */\nfunction readinessEnded(\n\tdeadline: Deadline,\n\ttimeoutMs: number,\n\tpending: number,\n): NeonError | undefined {\n\tconst source = deadline.source();\n\tif (source === \"caller\") {\n\t\treturn new NeonAbortError(\n\t\t\t\"Waiting for operations was aborted by its signal.\",\n\t\t);\n\t}\n\tif (source === \"timeout\") {\n\t\treturn new NeonTimeoutError(\n\t\t\t`Timed out after ${timeoutMs}ms waiting for ${pending} operation(s) to finish.`,\n\t\t);\n\t}\n\treturn undefined;\n}\n\n/**\n * Poll the given operations until each reaches a terminal `finished`/`skipped` state.\n * Returns an error result carrying {@link NeonOperationError} if any operation ends in\n * `failed`/`error`/`cancelled`, {@link NeonTimeoutError} if the deadline is exceeded, or\n * {@link NeonAbortError} if the caller's signal fired.\n *\n * `timeoutMs` is a real deadline rather than a check between polls. Each poll runs under\n * it, so a request that hangs cannot outlast the budget, and the budget is re-examined\n * after every operation rather than once per round — a round polls each pending operation\n * in turn, so checking only at the top let a long round overrun the timeout arbitrarily.\n *\n * Composable: usable directly with operations obtained from the raw layer.\n */\nexport async function waitForOperations(\n\tclient: Client,\n\toperations: readonly Operation[],\n\toptions: WaitForOptions = {},\n): Promise<NeonResult<void>> {\n\tconst pollIntervalMs = options.pollIntervalMs ?? 1000;\n\tconst timeoutMs = options.timeoutMs ?? 300_000;\n\tconst deadline = createDeadline(timeoutMs, options.signal);\n\n\ttry {\n\t\t// Track only operations that aren't already in a terminal state.\n\t\tlet pending = operations.filter((op) => !SUCCESS.has(op.status));\n\n\t\tfor (const op of pending) {\n\t\t\tif (FAILURE.has(op.status)) return err(operationFailed(op));\n\t\t}\n\t\tpending = pending.filter((op) => !FAILURE.has(op.status));\n\n\t\twhile (pending.length > 0) {\n\t\t\tconst ended = readinessEnded(deadline, timeoutMs, pending.length);\n\t\t\tif (ended) return err(ended);\n\n\t\t\tif (\n\t\t\t\t(await delay(pollIntervalMs, deadline.signal)) === \"cancelled\"\n\t\t\t) {\n\t\t\t\treturn err(\n\t\t\t\t\treadinessEnded(deadline, timeoutMs, pending.length) ??\n\t\t\t\t\t\tnew NeonAbortError(\n\t\t\t\t\t\t\t\"Waiting for operations was aborted by its signal.\",\n\t\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst stillPending: Operation[] = [];\n\t\t\t// Counted from what is left rather than from the round's starting size, so a\n\t\t\t// timeout part-way through a round reports the operations actually outstanding.\n\t\t\tlet remaining = pending.length;\n\t\t\tfor (const op of pending) {\n\t\t\t\tconst polled = await runBounded(deadline, () =>\n\t\t\t\t\tgetProjectOperation({\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tpath: {\n\t\t\t\t\t\t\tproject_id: op.project_id,\n\t\t\t\t\t\t\toperation_id: op.id,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthrowOnError: false,\n\t\t\t\t\t\tsignal: deadline.signal,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\t// Cancellation is read from the deadline before the response is\n\t\t\t\t// classified: an aborted poll comes back as a transport failure with no\n\t\t\t\t// response, which `toNeonError` would otherwise report as a network error.\n\t\t\t\tconst stopped = readinessEnded(deadline, timeoutMs, remaining);\n\t\t\t\tif (stopped) return err(stopped);\n\t\t\t\tif (polled === undefined) {\n\t\t\t\t\treturn err(toNeonError(undefined, undefined));\n\t\t\t\t}\n\n\t\t\t\tconst { data, error, response } = polled;\n\t\t\t\tif (error || !data) return err(toNeonError(error, response));\n\n\t\t\t\tconst current = data.operation;\n\t\t\t\tif (FAILURE.has(current.status)) {\n\t\t\t\t\treturn err(operationFailed(current));\n\t\t\t\t}\n\t\t\t\tif (SUCCESS.has(current.status)) remaining -= 1;\n\t\t\t\telse stillPending.push(current);\n\t\t\t}\n\t\t\tpending = stillPending;\n\t\t}\n\n\t\treturn ok(undefined);\n\t} finally {\n\t\tdeadline.dispose();\n\t}\n}\n\nfunction operationFailed(op: Operation): NeonOperationError {\n\tconst detail = op.error ? `: ${op.error}` : \"\";\n\treturn new NeonOperationError(\n\t\t`Operation ${op.id} (${op.action}) ended with status \"${op.status}\"${detail}.`,\n\t\t{ operationId: op.id, status: op.status },\n\t);\n}\n\n/** Type guard: does a response body carry an `operations` array we can wait on? */\nexport function hasOperations(\n\tdata: unknown,\n): data is { operations: Operation[] } {\n\treturn (\n\t\ttypeof data === \"object\" &&\n\t\tdata !== null &&\n\t\t\"operations\" in data &&\n\t\tArray.isArray(data.operations)\n\t);\n}\n"],"mappings":";;;;;AAkBA,MAAM,0BAAwC,IAAI,IAAI,CAAC,YAAY,SAAS,CAAC;AAC7E,MAAM,0BAAwC,IAAI,IAAI;CACrD;CACA;CACA;AACD,CAAC;;;;;AAcD,SAAS,eACR,UACA,WACA,SACwB;CACxB,MAAM,SAAS,SAAS,OAAO;CAC/B,IAAI,WAAW,UACd,OAAO,IAAI,eACV,mDACD;CAED,IAAI,WAAW,WACd,OAAO,IAAI,iBACV,mBAAmB,UAAU,iBAAiB,QAAQ,yBACvD;AAGF;;;;;;;;;;;;;;AAeA,eAAsB,kBACrB,QACA,YACA,UAA0B,CAAC,GACC;CAC5B,MAAM,iBAAiB,QAAQ,kBAAkB;CACjD,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,WAAW,eAAe,WAAW,QAAQ,MAAM;CAEzD,IAAI;EAEH,IAAI,UAAU,WAAW,QAAQ,OAAO,CAAC,QAAQ,IAAI,GAAG,MAAM,CAAC;EAE/D,KAAK,MAAM,MAAM,SAChB,IAAI,QAAQ,IAAI,GAAG,MAAM,GAAG,OAAO,IAAI,gBAAgB,EAAE,CAAC;EAE3D,UAAU,QAAQ,QAAQ,OAAO,CAAC,QAAQ,IAAI,GAAG,MAAM,CAAC;EAExD,OAAO,QAAQ,SAAS,GAAG;GAC1B,MAAM,QAAQ,eAAe,UAAU,WAAW,QAAQ,MAAM;GAChE,IAAI,OAAO,OAAO,IAAI,KAAK;GAE3B,IACE,MAAM,MAAM,gBAAgB,SAAS,MAAM,MAAO,aAEnD,OAAO,IACN,eAAe,UAAU,WAAW,QAAQ,MAAM,KACjD,IAAI,eACH,mDACD,CACF;GAGD,MAAM,eAA4B,CAAC;GAGnC,IAAI,YAAY,QAAQ;GACxB,KAAK,MAAM,MAAM,SAAS;IACzB,MAAM,SAAS,MAAM,WAAW,gBAC/B,oBAAoB;KACnB;KACA,MAAM;MACL,YAAY,GAAG;MACf,cAAc,GAAG;KAClB;KACA,cAAc;KACd,QAAQ,SAAS;IAClB,CAAC,CACF;IAKA,MAAM,UAAU,eAAe,UAAU,WAAW,SAAS;IAC7D,IAAI,SAAS,OAAO,IAAI,OAAO;IAC/B,IAAI,WAAW,KAAA,GACd,OAAO,IAAI,YAAY,KAAA,GAAW,KAAA,CAAS,CAAC;IAG7C,MAAM,EAAE,MAAM,OAAO,aAAa;IAClC,IAAI,SAAS,CAAC,MAAM,OAAO,IAAI,YAAY,OAAO,QAAQ,CAAC;IAE3D,MAAM,UAAU,KAAK;IACrB,IAAI,QAAQ,IAAI,QAAQ,MAAM,GAC7B,OAAO,IAAI,gBAAgB,OAAO,CAAC;IAEpC,IAAI,QAAQ,IAAI,QAAQ,MAAM,GAAG,aAAa;SACzC,aAAa,KAAK,OAAO;GAC/B;GACA,UAAU;EACX;EAEA,OAAO,GAAG,KAAA,CAAS;CACpB,UAAU;EACT,SAAS,QAAQ;CAClB;AACD;AAEA,SAAS,gBAAgB,IAAmC;CAC3D,MAAM,SAAS,GAAG,QAAQ,KAAK,GAAG,UAAU;CAC5C,OAAO,IAAI,mBACV,aAAa,GAAG,GAAG,IAAI,GAAG,OAAO,uBAAuB,GAAG,OAAO,GAAG,OAAO,IAC5E;EAAE,aAAa,GAAG;EAAI,QAAQ,GAAG;CAAO,CACzC;AACD;;AAGA,SAAgB,cACf,MACsC;CACtC,OACC,OAAO,SAAS,YAChB,SAAS,QACT,gBAAgB,QAChB,MAAM,QAAQ,KAAK,UAAU;AAE/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neon/sdk",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "The official TypeScript SDK for the Neon API, generated from Neon's OpenAPI specification. A modern, fetch-based replacement for @neondatabase/api-client.",
5
5
  "keywords": [
6
6
  "neon",
@@ -50,6 +50,7 @@
50
50
  "@types/node": "^20.19.0",
51
51
  "@vitest/coverage-v8": "^3.0.9",
52
52
  "console-fail-test": "0.5.0",
53
+ "es-module-lexer": "2.3.1",
53
54
  "tsdown": "^0.14.1",
54
55
  "typescript": "^5.9.0",
55
56
  "vitest": "^3.0.9",
@@ -62,7 +63,7 @@
62
63
  "provenance": false
63
64
  },
64
65
  "scripts": {
65
- "build": "tsc --noEmit && tsdown",
66
+ "build": "tsc --noEmit && tsdown && node scripts/check-dist.mjs",
66
67
  "generate": "openapi-ts && node scripts/generate-raw.mjs",
67
68
  "spec:pull": "curl -fsSL https://neon.com/api_spec/release/v2.json -o spec/neon-openapi.json",
68
69
  "test": "vitest --passWithNoTests",
@@ -1 +0,0 @@
1
- export {};
@@ -1,98 +0,0 @@
1
- import { createNeonClient } from "./client.js";
2
- import { it } from "../node_modules/.pnpm/@vitest_runner@3.0.9/node_modules/@vitest/runner/dist/index.js";
3
- import { import_dist } from "../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";
4
- //#region src/neon/client.test-d.ts
5
- it("default client returns the { data, error } envelope", () => {
6
- const neon = createNeonClient({ apiKey: "x" });
7
- (0, import_dist.expectTypeOf)(neon.projects.get("p")).resolves.toEqualTypeOf();
8
- (0, import_dist.expectTypeOf)(neon.projects.create()).resolves.toEqualTypeOf();
9
- });
10
- it("throwOnError on the client narrows methods to the bare resource", () => {
11
- (0, import_dist.expectTypeOf)(createNeonClient({
12
- apiKey: "x",
13
- throwOnError: true
14
- }).projects.get("p")).resolves.toEqualTypeOf();
15
- });
16
- it("per-call throwOnError overrides the client default and narrows", () => {
17
- (0, import_dist.expectTypeOf)(createNeonClient({ apiKey: "x" }).projects.get("p", { throwOnError: true })).resolves.toEqualTypeOf();
18
- (0, import_dist.expectTypeOf)(createNeonClient({
19
- apiKey: "x",
20
- throwOnError: true
21
- }).projects.get("p", { throwOnError: false })).resolves.toEqualTypeOf();
22
- });
23
- it("branches + workflows carry the envelope and narrow under throwOnError", () => {
24
- const neon = createNeonClient({ apiKey: "x" });
25
- (0, import_dist.expectTypeOf)(neon.branches.list("p")).toEqualTypeOf();
26
- (0, import_dist.expectTypeOf)(neon.branches.get("p", "br")).resolves.toEqualTypeOf();
27
- (0, import_dist.expectTypeOf)(neon.branches.createWithCompute("p", { name: "x" })).resolves.toEqualTypeOf();
28
- (0, import_dist.expectTypeOf)(neon.projects.createAndConnect({ name: "x" })).resolves.toEqualTypeOf();
29
- const throwing = createNeonClient({
30
- apiKey: "x",
31
- throwOnError: true
32
- });
33
- (0, import_dist.expectTypeOf)(throwing.branches.createWithCompute("p", { name: "x" })).resolves.toEqualTypeOf();
34
- (0, import_dist.expectTypeOf)(throwing.branches.delete("p", "br")).resolves.toEqualTypeOf();
35
- });
36
- it("postgres namespace + tier-2/3 resources are reachable and typed", () => {
37
- const neon = createNeonClient({ apiKey: "x" });
38
- (0, import_dist.expectTypeOf)(neon.postgres.endpoints.list("p")).resolves.toEqualTypeOf();
39
- (0, import_dist.expectTypeOf)(neon.postgres.roles.password("p", "br", "neondb_owner")).resolves.toEqualTypeOf();
40
- (0, import_dist.expectTypeOf)(neon.postgres.connectionString({ projectId: "p" })).resolves.toEqualTypeOf();
41
- (0, import_dist.expectTypeOf)(neon.snapshots.list("p")).resolves.toEqualTypeOf();
42
- const throwing = createNeonClient({
43
- apiKey: "x",
44
- throwOnError: true
45
- });
46
- (0, import_dist.expectTypeOf)(throwing.postgres.connectionString({ projectId: "p" })).resolves.toEqualTypeOf();
47
- (0, import_dist.expectTypeOf)(throwing.postgres.dataApi.delete("p", "br", "neondb")).resolves.toEqualTypeOf();
48
- });
49
- it("agent-platform helpers (default org, default branch, transfer, finalize) are typed", () => {
50
- const neon = createNeonClient({
51
- apiKey: "x",
52
- orgId: "org-123"
53
- });
54
- (0, import_dist.expectTypeOf)(neon.branches.getDefault("p")).resolves.toEqualTypeOf();
55
- (0, import_dist.expectTypeOf)(neon.branches.setDefault("p", "br")).resolves.toEqualTypeOf();
56
- (0, import_dist.expectTypeOf)(neon.branches.finalizeRestore("p", "br")).resolves.toEqualTypeOf();
57
- (0, import_dist.expectTypeOf)(neon.projects.transfer({
58
- toOrgId: "org-paid",
59
- projectIds: ["p"]
60
- })).resolves.toEqualTypeOf();
61
- (0, import_dist.expectTypeOf)(neon.snapshots.create("p", "br", {
62
- name: "baseline",
63
- timestamp: "2026-01-01T00:00:00Z"
64
- })).resolves.toEqualTypeOf();
65
- (0, import_dist.expectTypeOf)(neon.snapshots.restore("p", "snap", {
66
- targetBranchId: "br",
67
- preview: (restored) => {
68
- (0, import_dist.expectTypeOf)(restored).toEqualTypeOf();
69
- return true;
70
- }
71
- })).resolves.toEqualTypeOf();
72
- (0, import_dist.expectTypeOf)(neon.snapshots.setSchedule("p", "br", { schedule: [{
73
- frequency: "daily",
74
- hour: 3
75
- }] })).resolves.toEqualTypeOf();
76
- neon.snapshots.setSchedule("p", "br", { schedule: [{ frequency: "hourly" }] });
77
- });
78
- it("phase-1 namespaces (auth, permissions, recover, branch endpoints) are typed", () => {
79
- const neon = createNeonClient({ apiKey: "x" });
80
- (0, import_dist.expectTypeOf)(neon.auth.get("p", "br")).resolves.toEqualTypeOf();
81
- (0, import_dist.expectTypeOf)(neon.auth.oauthProviders.list("p", "br")).resolves.toEqualTypeOf();
82
- (0, import_dist.expectTypeOf)(neon.auth.oauthProviders.add("p", "br", { id: "google" })).resolves.toEqualTypeOf();
83
- (0, import_dist.expectTypeOf)(neon.projects.permissions.list("p")).resolves.toEqualTypeOf();
84
- (0, import_dist.expectTypeOf)(neon.projects.permissions.grant("p", "user@example.com")).resolves.toEqualTypeOf();
85
- (0, import_dist.expectTypeOf)(neon.projects.recover("p")).resolves.toEqualTypeOf();
86
- (0, import_dist.expectTypeOf)(neon.postgres.endpoints.listByBranch("p", "br")).resolves.toEqualTypeOf();
87
- const throwing = createNeonClient({
88
- apiKey: "x",
89
- throwOnError: true
90
- });
91
- (0, import_dist.expectTypeOf)(throwing.auth.get("p", "br")).resolves.toEqualTypeOf();
92
- (0, import_dist.expectTypeOf)(throwing.auth.oauthProviders.delete("p", "br", "google")).resolves.toEqualTypeOf();
93
- (0, import_dist.expectTypeOf)(throwing.projects.permissions.list("p")).resolves.toEqualTypeOf();
94
- });
95
- //#endregion
96
- export {};
97
-
98
- //# sourceMappingURL=client.test-d.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.test-d.js","names":[],"sources":["../../src/neon/client.test-d.ts"],"sourcesContent":["import { expectTypeOf, it } from \"vitest\";\nimport type {\n\tBranch,\n\tEndpoint,\n\tNeonAuthIntegration,\n\tNeonAuthOauthProvider,\n\tProject,\n\tProjectPermission,\n\tSnapshot,\n} from \"../client/types.gen.js\";\nimport { createNeonClient } from \"./client.js\";\nimport type { Paginated } from \"./paginate.js\";\nimport type { BranchWithCompute } from \"./resources/branches.js\";\nimport type { ProjectConnection } from \"./resources/projects.js\";\nimport type { NeonResult } from \"./result.js\";\n\nit(\"default client returns the { data, error } envelope\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\" });\n\texpectTypeOf(neon.projects.get(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Project>\n\t>();\n\texpectTypeOf(neon.projects.create()).resolves.toEqualTypeOf<\n\t\tNeonResult<Project>\n\t>();\n});\n\nit(\"throwOnError on the client narrows methods to the bare resource\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\", throwOnError: true });\n\texpectTypeOf(neon.projects.get(\"p\")).resolves.toEqualTypeOf<Project>();\n});\n\nit(\"per-call throwOnError overrides the client default and narrows\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\" });\n\texpectTypeOf(\n\t\tneon.projects.get(\"p\", { throwOnError: true }),\n\t).resolves.toEqualTypeOf<Project>();\n\n\tconst throwing = createNeonClient({ apiKey: \"x\", throwOnError: true });\n\texpectTypeOf(\n\t\tthrowing.projects.get(\"p\", { throwOnError: false }),\n\t).resolves.toEqualTypeOf<NeonResult<Project>>();\n});\n\nit(\"branches + workflows carry the envelope and narrow under throwOnError\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\" });\n\texpectTypeOf(neon.branches.list(\"p\")).toEqualTypeOf<Paginated<Branch>>();\n\texpectTypeOf(neon.branches.get(\"p\", \"br\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Branch>\n\t>();\n\texpectTypeOf(\n\t\tneon.branches.createWithCompute(\"p\", { name: \"x\" }),\n\t).resolves.toEqualTypeOf<NeonResult<BranchWithCompute>>();\n\texpectTypeOf(\n\t\tneon.projects.createAndConnect({ name: \"x\" }),\n\t).resolves.toEqualTypeOf<NeonResult<ProjectConnection>>();\n\n\tconst throwing = createNeonClient({ apiKey: \"x\", throwOnError: true });\n\texpectTypeOf(\n\t\tthrowing.branches.createWithCompute(\"p\", { name: \"x\" }),\n\t).resolves.toEqualTypeOf<BranchWithCompute>();\n\texpectTypeOf(\n\t\tthrowing.branches.delete(\"p\", \"br\"),\n\t).resolves.toEqualTypeOf<void>();\n});\n\nit(\"postgres namespace + tier-2/3 resources are reachable and typed\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\" });\n\texpectTypeOf(neon.postgres.endpoints.list(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Endpoint[]>\n\t>();\n\texpectTypeOf(\n\t\tneon.postgres.roles.password(\"p\", \"br\", \"neondb_owner\"),\n\t).resolves.toEqualTypeOf<NeonResult<string>>();\n\texpectTypeOf(\n\t\tneon.postgres.connectionString({ projectId: \"p\" }),\n\t).resolves.toEqualTypeOf<NeonResult<string>>();\n\texpectTypeOf(neon.snapshots.list(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Snapshot[]>\n\t>();\n\n\tconst throwing = createNeonClient({ apiKey: \"x\", throwOnError: true });\n\texpectTypeOf(\n\t\tthrowing.postgres.connectionString({ projectId: \"p\" }),\n\t).resolves.toEqualTypeOf<string>();\n\texpectTypeOf(\n\t\tthrowing.postgres.dataApi.delete(\"p\", \"br\", \"neondb\"),\n\t).resolves.toEqualTypeOf<void>();\n});\n\nit(\"agent-platform helpers (default org, default branch, transfer, finalize) are typed\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\", orgId: \"org-123\" });\n\texpectTypeOf(neon.branches.getDefault(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Branch>\n\t>();\n\texpectTypeOf(neon.branches.setDefault(\"p\", \"br\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Branch>\n\t>();\n\texpectTypeOf(\n\t\tneon.branches.finalizeRestore(\"p\", \"br\"),\n\t).resolves.toEqualTypeOf<NeonResult<void>>();\n\texpectTypeOf(\n\t\tneon.projects.transfer({ toOrgId: \"org-paid\", projectIds: [\"p\"] }),\n\t).resolves.toEqualTypeOf<NeonResult<void>>();\n\texpectTypeOf(\n\t\tneon.snapshots.create(\"p\", \"br\", {\n\t\t\tname: \"baseline\",\n\t\t\ttimestamp: \"2026-01-01T00:00:00Z\",\n\t\t}),\n\t).resolves.toEqualTypeOf<NeonResult<Snapshot>>();\n\texpectTypeOf(\n\t\tneon.snapshots.restore(\"p\", \"snap\", {\n\t\t\ttargetBranchId: \"br\",\n\t\t\tpreview: (restored) => {\n\t\t\t\texpectTypeOf(restored).toEqualTypeOf<Branch>();\n\t\t\t\treturn true;\n\t\t\t},\n\t\t}),\n\t).resolves.toEqualTypeOf<NeonResult<Branch>>();\n\n\t// setSchedule narrows `frequency` to the API-accepted values.\n\texpectTypeOf(\n\t\tneon.snapshots.setSchedule(\"p\", \"br\", {\n\t\t\tschedule: [{ frequency: \"daily\", hour: 3 }],\n\t\t}),\n\t).resolves.toEqualTypeOf<NeonResult<void>>();\n\tneon.snapshots.setSchedule(\"p\", \"br\", {\n\t\t// @ts-expect-error — \"hourly\" is not an accepted SnapshotFrequency\n\t\tschedule: [{ frequency: \"hourly\" }],\n\t});\n});\n\nit(\"phase-1 namespaces (auth, permissions, recover, branch endpoints) are typed\", () => {\n\tconst neon = createNeonClient({ apiKey: \"x\" });\n\texpectTypeOf(neon.auth.get(\"p\", \"br\")).resolves.toEqualTypeOf<\n\t\tNeonResult<NeonAuthIntegration>\n\t>();\n\texpectTypeOf(\n\t\tneon.auth.oauthProviders.list(\"p\", \"br\"),\n\t).resolves.toEqualTypeOf<NeonResult<NeonAuthOauthProvider[]>>();\n\texpectTypeOf(\n\t\tneon.auth.oauthProviders.add(\"p\", \"br\", { id: \"google\" }),\n\t).resolves.toEqualTypeOf<NeonResult<NeonAuthOauthProvider>>();\n\texpectTypeOf(neon.projects.permissions.list(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<ProjectPermission[]>\n\t>();\n\texpectTypeOf(\n\t\tneon.projects.permissions.grant(\"p\", \"user@example.com\"),\n\t).resolves.toEqualTypeOf<NeonResult<ProjectPermission>>();\n\texpectTypeOf(neon.projects.recover(\"p\")).resolves.toEqualTypeOf<\n\t\tNeonResult<Project>\n\t>();\n\texpectTypeOf(\n\t\tneon.postgres.endpoints.listByBranch(\"p\", \"br\"),\n\t).resolves.toEqualTypeOf<NeonResult<Endpoint[]>>();\n\n\tconst throwing = createNeonClient({ apiKey: \"x\", throwOnError: true });\n\texpectTypeOf(\n\t\tthrowing.auth.get(\"p\", \"br\"),\n\t).resolves.toEqualTypeOf<NeonAuthIntegration>();\n\texpectTypeOf(\n\t\tthrowing.auth.oauthProviders.delete(\"p\", \"br\", \"google\"),\n\t).resolves.toEqualTypeOf<void>();\n\texpectTypeOf(\n\t\tthrowing.projects.permissions.list(\"p\"),\n\t).resolves.toEqualTypeOf<ProjectPermission[]>();\n});\n"],"mappings":"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"}