@infracraft/pulumi 1.30.1 → 1.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/neon/client.cjs
CHANGED
|
@@ -2,10 +2,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
const require_chunk = require('../chunk-BVYJZCqc.cjs');
|
|
3
3
|
const require_errors_api_not_found_error = require('../errors/api-not-found-error.cjs');
|
|
4
4
|
const require_http_resilient_fetch = require('../http/resilient-fetch.cjs');
|
|
5
|
+
let _pulumi_pulumi = require("@pulumi/pulumi");
|
|
6
|
+
_pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
|
|
5
7
|
|
|
6
8
|
//#region src/neon/client.ts
|
|
7
9
|
const NEON_API_URL = "https://console.neon.tech/api/v2";
|
|
8
10
|
/**
|
|
11
|
+
* Neon runs project mutations as ASYNC operations and answers 423 ("project
|
|
12
|
+
* already has running conflicting operations, scheduling of new ones is
|
|
13
|
+
* prohibited") while earlier ones settle — its docs prescribe waiting for
|
|
14
|
+
* completion before the next request. A destroy immediately followed by an
|
|
15
|
+
* `up` on the same project hits this deterministically (live: branch/endpoint
|
|
16
|
+
* deletion still settling 30s later). Waiting until the lock clears is the
|
|
17
|
+
* documented protocol, bounded so a genuinely wedged project still fails.
|
|
18
|
+
*/
|
|
19
|
+
const OPERATION_LOCK_WAIT = {
|
|
20
|
+
/** Delay between lock probes. */
|
|
21
|
+
intervalMs: 5e3,
|
|
22
|
+
/** Upper bound on probes (~2 minutes total). */
|
|
23
|
+
maxAttempts: 24
|
|
24
|
+
};
|
|
25
|
+
function sleep(ms) {
|
|
26
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
9
29
|
* REST client for the Neon API.
|
|
10
30
|
*
|
|
11
31
|
* @example
|
|
@@ -69,14 +89,20 @@ var NeonClient = class {
|
|
|
69
89
|
await this.request("DELETE", path);
|
|
70
90
|
}
|
|
71
91
|
async request(method, path, body) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
92
|
+
let response;
|
|
93
|
+
for (let attempt = 1;; attempt++) {
|
|
94
|
+
response = await require_http_resilient_fetch.resilientFetch(`${NEON_API_URL}${path}`, {
|
|
95
|
+
method,
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json",
|
|
98
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
99
|
+
},
|
|
100
|
+
body: body ? JSON.stringify(body) : void 0
|
|
101
|
+
});
|
|
102
|
+
if (response.status !== 423 || attempt >= OPERATION_LOCK_WAIT.maxAttempts) break;
|
|
103
|
+
_pulumi_pulumi.log.info(`[infracraft] Neon project operations still settling (423) — waiting ${OPERATION_LOCK_WAIT.intervalMs / 1e3}s (attempt ${attempt}/${OPERATION_LOCK_WAIT.maxAttempts})`);
|
|
104
|
+
await sleep(OPERATION_LOCK_WAIT.intervalMs);
|
|
105
|
+
}
|
|
80
106
|
if (response.status === 404) throw new require_errors_api_not_found_error.ApiNotFoundError("neon", path);
|
|
81
107
|
if (!response.ok) {
|
|
82
108
|
const errorText = await response.text();
|
package/dist/neon/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":["resilientFetch","ApiNotFoundError"],"sources":["../../src/neon/client.ts"],"sourcesContent":["import { ApiNotFoundError } from \"../errors/api-not-found-error\";\nimport { resilientFetch } from \"../http/resilient-fetch\";\n\nconst NEON_API_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * REST client for the Neon API.\n *\n * @example\n * ```typescript\n * const client = new NeonClient(apiKey);\n * const branch = await client.get<{ branch: { id: string } }>(\n * `/projects/abc/branches/br-xyz`\n * );\n * ```\n */\nexport class NeonClient {\n\t/** Neon API key for authentication. */\n\tprivate readonly apiKey: string;\n\n\t/**\n\t * @param apiKey Neon API key (project-scoped or account-scoped)\n\t */\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\t/**\n\t * Performs a GET request against the Neon API.\n\t *\n\t * @param path API path (e.g. `/projects/abc/branches`)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync get<T>(path: string): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path);\n\t}\n\n\t/**\n\t * Performs a POST request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, body);\n\t}\n\n\t/**\n\t * Performs a PATCH request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync patch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"PATCH\", path, body);\n\t}\n\n\t/**\n\t * Performs a DELETE request against the Neon API.\n\t *\n\t * @param path API path\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync delete(path: string): Promise<void> {\n\t\tawait this.request<void>(\"DELETE\", path);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\
|
|
1
|
+
{"version":3,"file":"client.cjs","names":["resilientFetch","ApiNotFoundError"],"sources":["../../src/neon/client.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { ApiNotFoundError } from \"../errors/api-not-found-error\";\nimport { resilientFetch } from \"../http/resilient-fetch\";\n\nconst NEON_API_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * Neon runs project mutations as ASYNC operations and answers 423 (\"project\n * already has running conflicting operations, scheduling of new ones is\n * prohibited\") while earlier ones settle — its docs prescribe waiting for\n * completion before the next request. A destroy immediately followed by an\n * `up` on the same project hits this deterministically (live: branch/endpoint\n * deletion still settling 30s later). Waiting until the lock clears is the\n * documented protocol, bounded so a genuinely wedged project still fails.\n */\nconst OPERATION_LOCK_WAIT = {\n\t/** Delay between lock probes. */\n\tintervalMs: 5_000,\n\t/** Upper bound on probes (~2 minutes total). */\n\tmaxAttempts: 24,\n} as const;\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * REST client for the Neon API.\n *\n * @example\n * ```typescript\n * const client = new NeonClient(apiKey);\n * const branch = await client.get<{ branch: { id: string } }>(\n * `/projects/abc/branches/br-xyz`\n * );\n * ```\n */\nexport class NeonClient {\n\t/** Neon API key for authentication. */\n\tprivate readonly apiKey: string;\n\n\t/**\n\t * @param apiKey Neon API key (project-scoped or account-scoped)\n\t */\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\t/**\n\t * Performs a GET request against the Neon API.\n\t *\n\t * @param path API path (e.g. `/projects/abc/branches`)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync get<T>(path: string): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path);\n\t}\n\n\t/**\n\t * Performs a POST request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, body);\n\t}\n\n\t/**\n\t * Performs a PATCH request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync patch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"PATCH\", path, body);\n\t}\n\n\t/**\n\t * Performs a DELETE request against the Neon API.\n\t *\n\t * @param path API path\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync delete(path: string): Promise<void> {\n\t\tawait this.request<void>(\"DELETE\", path);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tlet response: Response;\n\n\t\tfor (let attempt = 1; ; attempt++) {\n\t\t\tresponse = await resilientFetch(`${NEON_API_URL}${path}`, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t});\n\n\t\t\tif (\n\t\t\t\tresponse.status !== 423 ||\n\t\t\t\tattempt >= OPERATION_LOCK_WAIT.maxAttempts\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tpulumi.log.info(\n\t\t\t\t`[infracraft] Neon project operations still settling (423) — waiting ${OPERATION_LOCK_WAIT.intervalMs / 1000}s (attempt ${attempt}/${OPERATION_LOCK_WAIT.maxAttempts})`,\n\t\t\t);\n\n\t\t\tawait sleep(OPERATION_LOCK_WAIT.intervalMs);\n\t\t}\n\n\t\tif (response.status === 404) {\n\t\t\tthrow new ApiNotFoundError(\"neon\", path);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\n\t\t\tthrow new Error(`Neon API error (${response.status}): ${errorText}`);\n\t\t}\n\n\t\tif (method === \"DELETE\") {\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\treturn (await response.json()) as T;\n\t}\n}\n"],"mappings":";;;;;;;;AAIA,MAAM,eAAe;;;;;;;;;;AAWrB,MAAM,sBAAsB;;CAE3B,YAAY;;CAEZ,aAAa;AACd;AAEA,SAAS,MAAM,IAA2B;CACzC,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACxD;;;;;;;;;;;;AAaA,IAAa,aAAb,MAAwB;;;;CAOvB,YAAY,QAAgB;EAC3B,KAAK,SAAS;CACf;;;;;;;;;CAUA,MAAM,IAAO,MAA0B;EACtC,OAAO,KAAK,QAAW,OAAO,IAAI;CACnC;;;;;;;;;;CAWA,MAAM,KAAQ,MAAc,MAA4B;EACvD,OAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;CAC1C;;;;;;;;;;CAWA,MAAM,MAAS,MAAc,MAA4B;EACxD,OAAO,KAAK,QAAW,SAAS,MAAM,IAAI;CAC3C;;;;;;;;CASA,MAAM,OAAO,MAA6B;EACzC,MAAM,KAAK,QAAc,UAAU,IAAI;CACxC;CAEA,MAAc,QACb,QACA,MACA,MACa;EACb,IAAI;EAEJ,KAAK,IAAI,UAAU,IAAK,WAAW;GAClC,WAAW,MAAMA,4CAAe,GAAG,eAAe,QAAQ;IACzD;IACA,SAAS;KACR,gBAAgB;KAChB,eAAe,UAAU,KAAK;IAC/B;IACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;GACrC,CAAC;GAED,IACC,SAAS,WAAW,OACpB,WAAW,oBAAoB,aAE/B;GAGD,eAAO,IAAI,KACV,uEAAuE,oBAAoB,aAAa,IAAK,aAAa,QAAQ,GAAG,oBAAoB,YAAY,EACtK;GAEA,MAAM,MAAM,oBAAoB,UAAU;EAC3C;EAEA,IAAI,SAAS,WAAW,KACvB,MAAM,IAAIC,oDAAiB,QAAQ,IAAI;EAGxC,IAAI,CAAC,SAAS,IAAI;GACjB,MAAM,YAAY,MAAM,SAAS,KAAK;GAEtC,MAAM,IAAI,MAAM,mBAAmB,SAAS,OAAO,KAAK,WAAW;EACpE;EAEA,IAAI,WAAW,UACd;EAGD,OAAQ,MAAM,SAAS,KAAK;CAC7B;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.cts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.cts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;AAqCA;;;;;;;;cAAa,UAAA;EAwDgB;EAAA,iBAtDX,MAAA;EAsDkB;;;cAjDvB,MAAA;EAYN;;;;;;;;EAAA,GAAA,GAAA,CAAO,IAAA,WAAe,OAAA,CAAQ,CAAA;EAaS;;;;;;;;;EAAvC,IAAA,GAAA,CAAQ,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAwBzB;;;AAIP;;;;;;EAff,KAAA,GAAA,CAAS,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;;;;;;;;EAWhD,MAAA,CAAO,IAAA,WAAe,OAAA;EAAA,QAId,OAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.mts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.mts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;AAqCA;;;;;;;;cAAa,UAAA;EAwDgB;EAAA,iBAtDX,MAAA;EAsDkB;;;cAjDvB,MAAA;EAYN;;;;;;;;EAAA,GAAA,GAAA,CAAO,IAAA,WAAe,OAAA,CAAQ,CAAA;EAaS;;;;;;;;;EAAvC,IAAA,GAAA,CAAQ,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAwBzB;;;AAIP;;;;;;EAff,KAAA,GAAA,CAAS,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;;;;;;;;EAWhD,MAAA,CAAO,IAAA,WAAe,OAAA;EAAA,QAId,OAAA;AAAA"}
|
package/dist/neon/client.mjs
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import { t as __name } from "../chunk-OPjESj5l.mjs";
|
|
2
2
|
import { ApiNotFoundError } from "../errors/api-not-found-error.mjs";
|
|
3
3
|
import { resilientFetch } from "../http/resilient-fetch.mjs";
|
|
4
|
+
import * as pulumi from "@pulumi/pulumi";
|
|
4
5
|
|
|
5
6
|
//#region src/neon/client.ts
|
|
6
7
|
const NEON_API_URL = "https://console.neon.tech/api/v2";
|
|
7
8
|
/**
|
|
9
|
+
* Neon runs project mutations as ASYNC operations and answers 423 ("project
|
|
10
|
+
* already has running conflicting operations, scheduling of new ones is
|
|
11
|
+
* prohibited") while earlier ones settle — its docs prescribe waiting for
|
|
12
|
+
* completion before the next request. A destroy immediately followed by an
|
|
13
|
+
* `up` on the same project hits this deterministically (live: branch/endpoint
|
|
14
|
+
* deletion still settling 30s later). Waiting until the lock clears is the
|
|
15
|
+
* documented protocol, bounded so a genuinely wedged project still fails.
|
|
16
|
+
*/
|
|
17
|
+
const OPERATION_LOCK_WAIT = {
|
|
18
|
+
/** Delay between lock probes. */
|
|
19
|
+
intervalMs: 5e3,
|
|
20
|
+
/** Upper bound on probes (~2 minutes total). */
|
|
21
|
+
maxAttempts: 24
|
|
22
|
+
};
|
|
23
|
+
function sleep(ms) {
|
|
24
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
8
27
|
* REST client for the Neon API.
|
|
9
28
|
*
|
|
10
29
|
* @example
|
|
@@ -68,14 +87,20 @@ var NeonClient = class {
|
|
|
68
87
|
await this.request("DELETE", path);
|
|
69
88
|
}
|
|
70
89
|
async request(method, path, body) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
let response;
|
|
91
|
+
for (let attempt = 1;; attempt++) {
|
|
92
|
+
response = await resilientFetch(`${NEON_API_URL}${path}`, {
|
|
93
|
+
method,
|
|
94
|
+
headers: {
|
|
95
|
+
"Content-Type": "application/json",
|
|
96
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
97
|
+
},
|
|
98
|
+
body: body ? JSON.stringify(body) : void 0
|
|
99
|
+
});
|
|
100
|
+
if (response.status !== 423 || attempt >= OPERATION_LOCK_WAIT.maxAttempts) break;
|
|
101
|
+
pulumi.log.info(`[infracraft] Neon project operations still settling (423) — waiting ${OPERATION_LOCK_WAIT.intervalMs / 1e3}s (attempt ${attempt}/${OPERATION_LOCK_WAIT.maxAttempts})`);
|
|
102
|
+
await sleep(OPERATION_LOCK_WAIT.intervalMs);
|
|
103
|
+
}
|
|
79
104
|
if (response.status === 404) throw new ApiNotFoundError("neon", path);
|
|
80
105
|
if (!response.ok) {
|
|
81
106
|
const errorText = await response.text();
|
package/dist/neon/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/neon/client.ts"],"sourcesContent":["import { ApiNotFoundError } from \"../errors/api-not-found-error\";\nimport { resilientFetch } from \"../http/resilient-fetch\";\n\nconst NEON_API_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * REST client for the Neon API.\n *\n * @example\n * ```typescript\n * const client = new NeonClient(apiKey);\n * const branch = await client.get<{ branch: { id: string } }>(\n * `/projects/abc/branches/br-xyz`\n * );\n * ```\n */\nexport class NeonClient {\n\t/** Neon API key for authentication. */\n\tprivate readonly apiKey: string;\n\n\t/**\n\t * @param apiKey Neon API key (project-scoped or account-scoped)\n\t */\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\t/**\n\t * Performs a GET request against the Neon API.\n\t *\n\t * @param path API path (e.g. `/projects/abc/branches`)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync get<T>(path: string): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path);\n\t}\n\n\t/**\n\t * Performs a POST request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, body);\n\t}\n\n\t/**\n\t * Performs a PATCH request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync patch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"PATCH\", path, body);\n\t}\n\n\t/**\n\t * Performs a DELETE request against the Neon API.\n\t *\n\t * @param path API path\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync delete(path: string): Promise<void> {\n\t\tawait this.request<void>(\"DELETE\", path);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/neon/client.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { ApiNotFoundError } from \"../errors/api-not-found-error\";\nimport { resilientFetch } from \"../http/resilient-fetch\";\n\nconst NEON_API_URL = \"https://console.neon.tech/api/v2\";\n\n/**\n * Neon runs project mutations as ASYNC operations and answers 423 (\"project\n * already has running conflicting operations, scheduling of new ones is\n * prohibited\") while earlier ones settle — its docs prescribe waiting for\n * completion before the next request. A destroy immediately followed by an\n * `up` on the same project hits this deterministically (live: branch/endpoint\n * deletion still settling 30s later). Waiting until the lock clears is the\n * documented protocol, bounded so a genuinely wedged project still fails.\n */\nconst OPERATION_LOCK_WAIT = {\n\t/** Delay between lock probes. */\n\tintervalMs: 5_000,\n\t/** Upper bound on probes (~2 minutes total). */\n\tmaxAttempts: 24,\n} as const;\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * REST client for the Neon API.\n *\n * @example\n * ```typescript\n * const client = new NeonClient(apiKey);\n * const branch = await client.get<{ branch: { id: string } }>(\n * `/projects/abc/branches/br-xyz`\n * );\n * ```\n */\nexport class NeonClient {\n\t/** Neon API key for authentication. */\n\tprivate readonly apiKey: string;\n\n\t/**\n\t * @param apiKey Neon API key (project-scoped or account-scoped)\n\t */\n\tconstructor(apiKey: string) {\n\t\tthis.apiKey = apiKey;\n\t}\n\n\t/**\n\t * Performs a GET request against the Neon API.\n\t *\n\t * @param path API path (e.g. `/projects/abc/branches`)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync get<T>(path: string): Promise<T> {\n\t\treturn this.request<T>(\"GET\", path);\n\t}\n\n\t/**\n\t * Performs a POST request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync post<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"POST\", path, body);\n\t}\n\n\t/**\n\t * Performs a PATCH request against the Neon API.\n\t *\n\t * @param path API path\n\t * @param body Request body (will be JSON-serialized)\n\t * @returns Typed JSON response body\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync patch<T>(path: string, body?: unknown): Promise<T> {\n\t\treturn this.request<T>(\"PATCH\", path, body);\n\t}\n\n\t/**\n\t * Performs a DELETE request against the Neon API.\n\t *\n\t * @param path API path\n\t * @throws {ApiNotFoundError} On 404\n\t * @throws {Error} On any other non-2xx HTTP status\n\t */\n\tasync delete(path: string): Promise<void> {\n\t\tawait this.request<void>(\"DELETE\", path);\n\t}\n\n\tprivate async request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tbody?: unknown,\n\t): Promise<T> {\n\t\tlet response: Response;\n\n\t\tfor (let attempt = 1; ; attempt++) {\n\t\t\tresponse = await resilientFetch(`${NEON_API_URL}${path}`, {\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t});\n\n\t\t\tif (\n\t\t\t\tresponse.status !== 423 ||\n\t\t\t\tattempt >= OPERATION_LOCK_WAIT.maxAttempts\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tpulumi.log.info(\n\t\t\t\t`[infracraft] Neon project operations still settling (423) — waiting ${OPERATION_LOCK_WAIT.intervalMs / 1000}s (attempt ${attempt}/${OPERATION_LOCK_WAIT.maxAttempts})`,\n\t\t\t);\n\n\t\t\tawait sleep(OPERATION_LOCK_WAIT.intervalMs);\n\t\t}\n\n\t\tif (response.status === 404) {\n\t\t\tthrow new ApiNotFoundError(\"neon\", path);\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\n\t\t\tthrow new Error(`Neon API error (${response.status}): ${errorText}`);\n\t\t}\n\n\t\tif (method === \"DELETE\") {\n\t\t\treturn undefined as T;\n\t\t}\n\n\t\treturn (await response.json()) as T;\n\t}\n}\n"],"mappings":";;;;;;AAIA,MAAM,eAAe;;;;;;;;;;AAWrB,MAAM,sBAAsB;;CAE3B,YAAY;;CAEZ,aAAa;AACd;AAEA,SAAS,MAAM,IAA2B;CACzC,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACxD;;;;;;;;;;;;AAaA,IAAa,aAAb,MAAwB;;;;CAOvB,YAAY,QAAgB;EAC3B,KAAK,SAAS;CACf;;;;;;;;;CAUA,MAAM,IAAO,MAA0B;EACtC,OAAO,KAAK,QAAW,OAAO,IAAI;CACnC;;;;;;;;;;CAWA,MAAM,KAAQ,MAAc,MAA4B;EACvD,OAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;CAC1C;;;;;;;;;;CAWA,MAAM,MAAS,MAAc,MAA4B;EACxD,OAAO,KAAK,QAAW,SAAS,MAAM,IAAI;CAC3C;;;;;;;;CASA,MAAM,OAAO,MAA6B;EACzC,MAAM,KAAK,QAAc,UAAU,IAAI;CACxC;CAEA,MAAc,QACb,QACA,MACA,MACa;EACb,IAAI;EAEJ,KAAK,IAAI,UAAU,IAAK,WAAW;GAClC,WAAW,MAAM,eAAe,GAAG,eAAe,QAAQ;IACzD;IACA,SAAS;KACR,gBAAgB;KAChB,eAAe,UAAU,KAAK;IAC/B;IACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;GACrC,CAAC;GAED,IACC,SAAS,WAAW,OACpB,WAAW,oBAAoB,aAE/B;GAGD,OAAO,IAAI,KACV,uEAAuE,oBAAoB,aAAa,IAAK,aAAa,QAAQ,GAAG,oBAAoB,YAAY,EACtK;GAEA,MAAM,MAAM,oBAAoB,UAAU;EAC3C;EAEA,IAAI,SAAS,WAAW,KACvB,MAAM,IAAI,iBAAiB,QAAQ,IAAI;EAGxC,IAAI,CAAC,SAAS,IAAI;GACjB,MAAM,YAAY,MAAM,SAAS,KAAK;GAEtC,MAAM,IAAI,MAAM,mBAAmB,SAAS,OAAO,KAAK,WAAW;EACpE;EAEA,IAAI,WAAW,UACd;EAGD,OAAQ,MAAM,SAAS,KAAK;CAC7B;AACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infracraft/pulumi",
|
|
3
|
-
"version": "1.30.
|
|
3
|
+
"version": "1.30.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Native Pulumi providers for Railway, Neon, Vercel, and Fly.io with adopt-or-create semantics and deploy orchestration. No Terraform bridge.",
|