@infracraft/pulumi 0.1.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.

Potentially problematic release.


This version of @infracraft/pulumi might be problematic. Click here for more details.

Files changed (151) hide show
  1. package/dist/chunk-BVYJZCqc.cjs +44 -0
  2. package/dist/chunk-OPjESj5l.mjs +9 -0
  3. package/dist/git-guard.cjs +62 -0
  4. package/dist/git-guard.cjs.map +1 -0
  5. package/dist/git-guard.d.cts +13 -0
  6. package/dist/git-guard.d.cts.map +1 -0
  7. package/dist/git-guard.d.mts +13 -0
  8. package/dist/git-guard.d.mts.map +1 -0
  9. package/dist/git-guard.mjs +56 -0
  10. package/dist/git-guard.mjs.map +1 -0
  11. package/dist/hash.cjs +40 -0
  12. package/dist/hash.cjs.map +1 -0
  13. package/dist/hash.d.cts +10 -0
  14. package/dist/hash.d.cts.map +1 -0
  15. package/dist/hash.d.mts +10 -0
  16. package/dist/hash.d.mts.map +1 -0
  17. package/dist/hash.mjs +36 -0
  18. package/dist/hash.mjs.map +1 -0
  19. package/dist/neon/branch.cjs +113 -0
  20. package/dist/neon/branch.cjs.map +1 -0
  21. package/dist/neon/branch.d.cts +40 -0
  22. package/dist/neon/branch.d.cts.map +1 -0
  23. package/dist/neon/branch.d.mts +40 -0
  24. package/dist/neon/branch.d.mts.map +1 -0
  25. package/dist/neon/branch.mjs +111 -0
  26. package/dist/neon/branch.mjs.map +1 -0
  27. package/dist/neon/client.cjs +85 -0
  28. package/dist/neon/client.cjs.map +1 -0
  29. package/dist/neon/client.d.cts +59 -0
  30. package/dist/neon/client.d.cts.map +1 -0
  31. package/dist/neon/client.d.mts +59 -0
  32. package/dist/neon/client.d.mts.map +1 -0
  33. package/dist/neon/client.mjs +84 -0
  34. package/dist/neon/client.mjs.map +1 -0
  35. package/dist/neon/database.cjs +117 -0
  36. package/dist/neon/database.cjs.map +1 -0
  37. package/dist/neon/database.d.cts +48 -0
  38. package/dist/neon/database.d.cts.map +1 -0
  39. package/dist/neon/database.d.mts +48 -0
  40. package/dist/neon/database.d.mts.map +1 -0
  41. package/dist/neon/database.mjs +115 -0
  42. package/dist/neon/database.mjs.map +1 -0
  43. package/dist/neon/endpoint.cjs +167 -0
  44. package/dist/neon/endpoint.cjs.map +1 -0
  45. package/dist/neon/endpoint.d.cts +57 -0
  46. package/dist/neon/endpoint.d.cts.map +1 -0
  47. package/dist/neon/endpoint.d.mts +57 -0
  48. package/dist/neon/endpoint.d.mts.map +1 -0
  49. package/dist/neon/endpoint.mjs +165 -0
  50. package/dist/neon/endpoint.mjs.map +1 -0
  51. package/dist/neon/index.cjs +14 -0
  52. package/dist/neon/index.d.cts +7 -0
  53. package/dist/neon/index.d.mts +7 -0
  54. package/dist/neon/index.mjs +8 -0
  55. package/dist/neon/project.cjs +120 -0
  56. package/dist/neon/project.cjs.map +1 -0
  57. package/dist/neon/project.d.cts +52 -0
  58. package/dist/neon/project.d.cts.map +1 -0
  59. package/dist/neon/project.d.mts +52 -0
  60. package/dist/neon/project.d.mts.map +1 -0
  61. package/dist/neon/project.mjs +118 -0
  62. package/dist/neon/project.mjs.map +1 -0
  63. package/dist/neon/role.cjs +135 -0
  64. package/dist/neon/role.cjs.map +1 -0
  65. package/dist/neon/role.d.cts +49 -0
  66. package/dist/neon/role.d.cts.map +1 -0
  67. package/dist/neon/role.d.mts +49 -0
  68. package/dist/neon/role.d.mts.map +1 -0
  69. package/dist/neon/role.mjs +133 -0
  70. package/dist/neon/role.mjs.map +1 -0
  71. package/dist/railway/client.cjs +59 -0
  72. package/dist/railway/client.cjs.map +1 -0
  73. package/dist/railway/client.d.cts +39 -0
  74. package/dist/railway/client.d.cts.map +1 -0
  75. package/dist/railway/client.d.mts +39 -0
  76. package/dist/railway/client.d.mts.map +1 -0
  77. package/dist/railway/client.mjs +58 -0
  78. package/dist/railway/client.mjs.map +1 -0
  79. package/dist/railway/deploy.cjs +40 -0
  80. package/dist/railway/deploy.cjs.map +1 -0
  81. package/dist/railway/deploy.d.cts +47 -0
  82. package/dist/railway/deploy.d.cts.map +1 -0
  83. package/dist/railway/deploy.d.mts +47 -0
  84. package/dist/railway/deploy.d.mts.map +1 -0
  85. package/dist/railway/deploy.mjs +37 -0
  86. package/dist/railway/deploy.mjs.map +1 -0
  87. package/dist/railway/domain.cjs +236 -0
  88. package/dist/railway/domain.cjs.map +1 -0
  89. package/dist/railway/domain.d.cts +52 -0
  90. package/dist/railway/domain.d.cts.map +1 -0
  91. package/dist/railway/domain.d.mts +52 -0
  92. package/dist/railway/domain.d.mts.map +1 -0
  93. package/dist/railway/domain.mjs +234 -0
  94. package/dist/railway/domain.mjs.map +1 -0
  95. package/dist/railway/index.cjs +16 -0
  96. package/dist/railway/index.d.cts +8 -0
  97. package/dist/railway/index.d.mts +8 -0
  98. package/dist/railway/index.mjs +9 -0
  99. package/dist/railway/project.cjs +231 -0
  100. package/dist/railway/project.cjs.map +1 -0
  101. package/dist/railway/project.d.cts +52 -0
  102. package/dist/railway/project.d.cts.map +1 -0
  103. package/dist/railway/project.d.mts +52 -0
  104. package/dist/railway/project.d.mts.map +1 -0
  105. package/dist/railway/project.mjs +229 -0
  106. package/dist/railway/project.mjs.map +1 -0
  107. package/dist/railway/service.cjs +268 -0
  108. package/dist/railway/service.cjs.map +1 -0
  109. package/dist/railway/service.d.cts +88 -0
  110. package/dist/railway/service.d.cts.map +1 -0
  111. package/dist/railway/service.d.mts +88 -0
  112. package/dist/railway/service.d.mts.map +1 -0
  113. package/dist/railway/service.mjs +266 -0
  114. package/dist/railway/service.mjs.map +1 -0
  115. package/dist/railway/variable.cjs +149 -0
  116. package/dist/railway/variable.cjs.map +1 -0
  117. package/dist/railway/variable.d.cts +52 -0
  118. package/dist/railway/variable.d.cts.map +1 -0
  119. package/dist/railway/variable.d.mts +52 -0
  120. package/dist/railway/variable.d.mts.map +1 -0
  121. package/dist/railway/variable.mjs +147 -0
  122. package/dist/railway/variable.mjs.map +1 -0
  123. package/dist/railway/volume.cjs +179 -0
  124. package/dist/railway/volume.cjs.map +1 -0
  125. package/dist/railway/volume.d.cts +52 -0
  126. package/dist/railway/volume.d.cts.map +1 -0
  127. package/dist/railway/volume.d.mts +52 -0
  128. package/dist/railway/volume.d.mts.map +1 -0
  129. package/dist/railway/volume.mjs +177 -0
  130. package/dist/railway/volume.mjs.map +1 -0
  131. package/dist/vercel/deploy.cjs +65 -0
  132. package/dist/vercel/deploy.cjs.map +1 -0
  133. package/dist/vercel/deploy.d.cts +54 -0
  134. package/dist/vercel/deploy.d.cts.map +1 -0
  135. package/dist/vercel/deploy.d.mts +54 -0
  136. package/dist/vercel/deploy.d.mts.map +1 -0
  137. package/dist/vercel/deploy.mjs +61 -0
  138. package/dist/vercel/deploy.mjs.map +1 -0
  139. package/dist/vercel/index.cjs +6 -0
  140. package/dist/vercel/index.d.cts +3 -0
  141. package/dist/vercel/index.d.mts +3 -0
  142. package/dist/vercel/index.mjs +4 -0
  143. package/dist/vercel/variable.cjs +280 -0
  144. package/dist/vercel/variable.cjs.map +1 -0
  145. package/dist/vercel/variable.d.cts +55 -0
  146. package/dist/vercel/variable.d.cts.map +1 -0
  147. package/dist/vercel/variable.d.mts +55 -0
  148. package/dist/vercel/variable.d.mts.map +1 -0
  149. package/dist/vercel/variable.mjs +278 -0
  150. package/dist/vercel/variable.mjs.map +1 -0
  151. package/package.json +62 -0
@@ -0,0 +1,111 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.mjs";
2
+ import { NeonClient } from "./client.mjs";
3
+ import * as pulumi from "@pulumi/pulumi";
4
+
5
+ //#region src/neon/branch.ts
6
+ /**
7
+ * Finds an existing Neon branch by name within a project.
8
+ *
9
+ * @param client Authenticated Neon API client
10
+ * @param projectId Neon project ID
11
+ * @param name Exact branch name to match
12
+ * @returns The branch ID if found, `undefined` otherwise
13
+ */
14
+ async function findBranchByName(client, projectId, name) {
15
+ return (await client.get(`/projects/${projectId}/branches`)).branches.find((b) => b.name === name)?.id;
16
+ }
17
+ /**
18
+ * Dynamic provider implementing CRUD for Neon branches.
19
+ *
20
+ * Uses adopt-or-create on `create()`: finds an existing branch by name
21
+ * before creating a new one, making `pulumi up` idempotent from zero.
22
+ */
23
+ var NeonBranchProvider = class {
24
+ /**
25
+ * Creates or adopts a Neon branch by name.
26
+ *
27
+ * @param inputs Resolved branch configuration
28
+ * @returns The Neon branch ID as the resource ID
29
+ */
30
+ async create(inputs) {
31
+ const client = new NeonClient(inputs.apiKey);
32
+ let branchId = await findBranchByName(client, inputs.projectId, inputs.name);
33
+ if (branchId) pulumi.log.info(`Adopting existing Neon branch "${inputs.name}" (${branchId})`);
34
+ else branchId = (await client.post(`/projects/${inputs.projectId}/branches`, { branch: { name: inputs.name } })).branch.id;
35
+ return {
36
+ id: branchId,
37
+ outs: inputs
38
+ };
39
+ }
40
+ /**
41
+ * Reads current state for `pulumi refresh`.
42
+ *
43
+ * @param id Current Neon branch ID
44
+ * @param props Last known persisted state
45
+ * @returns Refreshed resource ID and properties
46
+ * @throws {Error} If the branch no longer exists
47
+ */
48
+ async read(id, props) {
49
+ const result = await new NeonClient(props.apiKey).get(`/projects/${props.projectId}/branches/${id}`);
50
+ return {
51
+ id: result.branch.id,
52
+ props: {
53
+ ...props,
54
+ name: result.branch.name
55
+ }
56
+ };
57
+ }
58
+ /**
59
+ * Deletes the Neon branch. Silently succeeds if already deleted.
60
+ *
61
+ * @param id Neon branch ID to delete
62
+ * @param props Last known persisted state
63
+ */
64
+ async delete(id, props) {
65
+ const client = new NeonClient(props.apiKey);
66
+ try {
67
+ await client.delete(`/projects/${props.projectId}/branches/${id}`);
68
+ } catch {
69
+ pulumi.log.warn(`Failed to delete Neon branch (may already be deleted)`);
70
+ }
71
+ }
72
+ /**
73
+ * Compares old and new inputs to detect changes.
74
+ * Changing `projectId` triggers replacement.
75
+ */
76
+ async diff(_id, olds, news) {
77
+ const replaces = [];
78
+ if (olds.projectId !== news.projectId) replaces.push("projectId");
79
+ return {
80
+ changes: replaces.length > 0 || olds.name !== news.name,
81
+ replaces,
82
+ deleteBeforeReplace: true
83
+ };
84
+ }
85
+ };
86
+ /**
87
+ * Manages a Neon branch with adopt-or-create semantics.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * const branch = new NeonBranch("neon-branch-production", {
92
+ * apiKey: config.requireSecret("neonApiKey"),
93
+ * projectId: "quiet-forest-69719462",
94
+ * name: "production",
95
+ * });
96
+ * ```
97
+ */
98
+ var NeonBranch = class extends pulumi.dynamic.Resource {
99
+ /**
100
+ * @param name Pulumi resource name
101
+ * @param args Branch configuration inputs
102
+ * @param opts Standard Pulumi resource options
103
+ */
104
+ constructor(name, args, opts) {
105
+ super(new NeonBranchProvider(), name, { ...args }, opts);
106
+ }
107
+ };
108
+
109
+ //#endregion
110
+ export { NeonBranch };
111
+ //# sourceMappingURL=branch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch.mjs","names":[],"sources":["../../src/neon/branch.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\n\n/** Resolved inputs for the Neon branch dynamic provider. */\nexport interface NeonBranchInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Neon project ID (e.g. `\"quiet-forest-69719462\"`). */\n\tprojectId: string;\n\n\t/** Branch display name (e.g. `\"production\"`, `\"development\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Neon branch. */\ninterface NeonBranchOutputs extends NeonBranchInputs {}\n\n/** Neon API response for a branch. */\ninterface BranchResponse {\n\tbranch: {\n\t\tid: string;\n\t\tname: string;\n\t\tproject_id: string;\n\t};\n}\n\n/** Neon API response for branch creation. */\ninterface BranchCreateResponse {\n\tbranch: {\n\t\tid: string;\n\t\tname: string;\n\t\tproject_id: string;\n\t};\n}\n\n/** Neon API response for listing branches. */\ninterface BranchListResponse {\n\tbranches: Array<{\n\t\tid: string;\n\t\tname: string;\n\t}>;\n}\n\n/**\n * Finds an existing Neon branch by name within a project.\n *\n * @param client Authenticated Neon API client\n * @param projectId Neon project ID\n * @param name Exact branch name to match\n * @returns The branch ID if found, `undefined` otherwise\n */\nasync function findBranchByName(\n\tclient: NeonClient,\n\tprojectId: string,\n\tname: string,\n): Promise<string | undefined> {\n\tconst result = await client.get<BranchListResponse>(\n\t\t`/projects/${projectId}/branches`,\n\t);\n\n\tconst match = result.branches.find((b) => b.name === name);\n\n\treturn match?.id;\n}\n\n/**\n * Dynamic provider implementing CRUD for Neon branches.\n *\n * Uses adopt-or-create on `create()`: finds an existing branch by name\n * before creating a new one, making `pulumi up` idempotent from zero.\n */\nclass NeonBranchProvider implements pulumi.dynamic.ResourceProvider {\n\t/**\n\t * Creates or adopts a Neon branch by name.\n\t *\n\t * @param inputs Resolved branch configuration\n\t * @returns The Neon branch ID as the resource ID\n\t */\n\tasync create(inputs: NeonBranchInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tlet branchId = await findBranchByName(\n\t\t\tclient,\n\t\t\tinputs.projectId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (branchId) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Neon branch \"${inputs.name}\" (${branchId})`,\n\t\t\t);\n\t\t} else {\n\t\t\tconst result = await client.post<BranchCreateResponse>(\n\t\t\t\t`/projects/${inputs.projectId}/branches`,\n\t\t\t\t{ branch: { name: inputs.name } },\n\t\t\t);\n\n\t\t\tbranchId = result.branch.id;\n\t\t}\n\n\t\treturn { id: branchId, outs: inputs };\n\t}\n\n\t/**\n\t * Reads current state for `pulumi refresh`.\n\t *\n\t * @param id Current Neon branch ID\n\t * @param props Last known persisted state\n\t * @returns Refreshed resource ID and properties\n\t * @throws {Error} If the branch no longer exists\n\t */\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonBranchOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<BranchResponse>(\n\t\t\t`/projects/${props.projectId}/branches/${id}`,\n\t\t);\n\n\t\treturn {\n\t\t\tid: result.branch.id,\n\t\t\tprops: { ...props, name: result.branch.name },\n\t\t};\n\t}\n\n\t/**\n\t * Deletes the Neon branch. Silently succeeds if already deleted.\n\t *\n\t * @param id Neon branch ID to delete\n\t * @param props Last known persisted state\n\t */\n\tasync delete(id: string, props: NeonBranchOutputs): Promise<void> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\ttry {\n\t\t\tawait client.delete(`/projects/${props.projectId}/branches/${id}`);\n\t\t} catch {\n\t\t\tpulumi.log.warn(`Failed to delete Neon branch (may already be deleted)`);\n\t\t}\n\t}\n\n\t/**\n\t * Compares old and new inputs to detect changes.\n\t * Changing `projectId` triggers replacement.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonBranchOutputs,\n\t\tnews: NeonBranchInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || olds.name !== news.name,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/**\n * Manages a Neon branch with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const branch = new NeonBranch(\"neon-branch-production\", {\n * apiKey: config.requireSecret(\"neonApiKey\"),\n * projectId: \"quiet-forest-69719462\",\n * name: \"production\",\n * });\n * ```\n */\nexport class NeonBranch extends pulumi.dynamic.Resource {\n\t/**\n\t * @param name Pulumi resource name\n\t * @param args Branch configuration inputs\n\t * @param opts Standard Pulumi resource options\n\t */\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\t/** Neon API key. */\n\t\t\tapiKey: pulumi.Input<string>;\n\n\t\t\t/** Neon project ID. */\n\t\t\tprojectId: pulumi.Input<string>;\n\n\t\t\t/** Branch display name. */\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonBranchProvider(), name, { ...args }, opts);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAoDA,eAAe,iBACd,QACA,WACA,MAC8B;CAO9B,QAFc,MAJO,OAAO,IAC3B,aAAa,UAAU,UACxB,GAEqB,SAAS,MAAM,MAAM,EAAE,SAAS,IAE1C,GAAG;AACf;;;;;;;AAQA,IAAM,qBAAN,MAAoE;;;;;;;CAOnE,MAAM,OAAO,QAAgE;EAC5E,MAAM,SAAS,IAAI,WAAW,OAAO,MAAM;EAE3C,IAAI,WAAW,MAAM,iBACpB,QACA,OAAO,WACP,OAAO,IACR;EAEA,IAAI,UACH,OAAO,IAAI,KACV,kCAAkC,OAAO,KAAK,KAAK,SAAS,EAC7D;OAOA,YAAW,MALU,OAAO,KAC3B,aAAa,OAAO,UAAU,YAC9B,EAAE,QAAQ,EAAE,MAAM,OAAO,KAAK,EAAE,CACjC,GAEkB,OAAO;EAG1B,OAAO;GAAE,IAAI;GAAU,MAAM;EAAO;CACrC;;;;;;;;;CAUA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFF,WAAW,MAAM,MAEV,EAAE,IAC3B,aAAa,MAAM,UAAU,YAAY,IAC1C;EAEA,OAAO;GACN,IAAI,OAAO,OAAO;GAClB,OAAO;IAAE,GAAG;IAAO,MAAM,OAAO,OAAO;GAAK;EAC7C;CACD;;;;;;;CAQA,MAAM,OAAO,IAAY,OAAyC;EACjE,MAAM,SAAS,IAAI,WAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OAAO,aAAa,MAAM,UAAU,YAAY,IAAI;EAClE,QAAQ;GACP,OAAO,IAAI,KAAK,uDAAuD;EACxE;CACD;;;;;CAMA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,cAAc,KAAK,WAC3B,SAAS,KAAK,WAAW;EAG1B,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,KAAK,SAAS,KAAK;GACnD;GACA,qBAAqB;EACtB;CACD;AACD;;;;;;;;;;;;;AAcA,IAAa,aAAb,cAAgC,OAAO,QAAQ,SAAS;;;;;;CAMvD,YACC,MACA,MAUA,MACC;EACD,MAAM,IAAI,mBAAmB,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CACxD;AACD"}
@@ -0,0 +1,85 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../chunk-BVYJZCqc.cjs');
3
+
4
+ //#region src/neon/client.ts
5
+ const NEON_API_URL = "https://console.neon.tech/api/v2";
6
+ /**
7
+ * REST client for the Neon API.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const client = new NeonClient(apiKey);
12
+ * const branch = await client.get<{ branch: { id: string } }>(
13
+ * `/projects/abc/branches/br-xyz`
14
+ * );
15
+ * ```
16
+ */
17
+ var NeonClient = class {
18
+ /**
19
+ * @param apiKey Neon API key (project-scoped or account-scoped)
20
+ */
21
+ constructor(apiKey) {
22
+ this.apiKey = apiKey;
23
+ }
24
+ /**
25
+ * Performs a GET request against the Neon API.
26
+ *
27
+ * @param path API path (e.g. `/projects/abc/branches`)
28
+ * @returns Typed JSON response body
29
+ * @throws {Error} On non-2xx HTTP status
30
+ */
31
+ async get(path) {
32
+ return this.request("GET", path);
33
+ }
34
+ /**
35
+ * Performs a POST request against the Neon API.
36
+ *
37
+ * @param path API path
38
+ * @param body Request body (will be JSON-serialized)
39
+ * @returns Typed JSON response body
40
+ * @throws {Error} On non-2xx HTTP status
41
+ */
42
+ async post(path, body) {
43
+ return this.request("POST", path, body);
44
+ }
45
+ /**
46
+ * Performs a PATCH request against the Neon API.
47
+ *
48
+ * @param path API path
49
+ * @param body Request body (will be JSON-serialized)
50
+ * @returns Typed JSON response body
51
+ * @throws {Error} On non-2xx HTTP status
52
+ */
53
+ async patch(path, body) {
54
+ return this.request("PATCH", path, body);
55
+ }
56
+ /**
57
+ * Performs a DELETE request against the Neon API.
58
+ *
59
+ * @param path API path
60
+ * @throws {Error} On non-2xx HTTP status
61
+ */
62
+ async delete(path) {
63
+ await this.request("DELETE", path);
64
+ }
65
+ async request(method, path, body) {
66
+ const response = await fetch(`${NEON_API_URL}${path}`, {
67
+ method,
68
+ headers: {
69
+ "Content-Type": "application/json",
70
+ Authorization: `Bearer ${this.apiKey}`
71
+ },
72
+ body: body ? JSON.stringify(body) : void 0
73
+ });
74
+ if (!response.ok) {
75
+ const errorText = await response.text();
76
+ throw new Error(`Neon API error (${response.status}): ${errorText}`);
77
+ }
78
+ if (method === "DELETE") return;
79
+ return await response.json();
80
+ }
81
+ };
82
+
83
+ //#endregion
84
+ exports.NeonClient = NeonClient;
85
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.cjs","names":[],"sources":["../../src/neon/client.ts"],"sourcesContent":["const 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 {Error} On 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 {Error} On 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 {Error} On 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 {Error} On 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\tconst response = await fetch(`${NEON_API_URL}${path}`, {\n\t\t\tmethod,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t},\n\t\t\tbody: body ? JSON.stringify(body) : undefined,\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":";;;;AAAA,MAAM,eAAe;;;;;;;;;;;;AAarB,IAAa,aAAb,MAAwB;;;;CAOvB,YAAY,QAAgB;EAC3B,KAAK,SAAS;CACf;;;;;;;;CASA,MAAM,IAAO,MAA0B;EACtC,OAAO,KAAK,QAAW,OAAO,IAAI;CACnC;;;;;;;;;CAUA,MAAM,KAAQ,MAAc,MAA4B;EACvD,OAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;CAC1C;;;;;;;;;CAUA,MAAM,MAAS,MAAc,MAA4B;EACxD,OAAO,KAAK,QAAW,SAAS,MAAM,IAAI;CAC3C;;;;;;;CAQA,MAAM,OAAO,MAA6B;EACzC,MAAM,KAAK,QAAc,UAAU,IAAI;CACxC;CAEA,MAAc,QACb,QACA,MACA,MACa;EACb,MAAM,WAAW,MAAM,MAAM,GAAG,eAAe,QAAQ;GACtD;GACA,SAAS;IACR,gBAAgB;IAChB,eAAe,UAAU,KAAK;GAC/B;GACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;EACrC,CAAC;EAED,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"}
@@ -0,0 +1,59 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.cjs";
2
+
3
+ //#region src/neon/client.d.ts
4
+ /**
5
+ * REST client for the Neon API.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const client = new NeonClient(apiKey);
10
+ * const branch = await client.get<{ branch: { id: string } }>(
11
+ * `/projects/abc/branches/br-xyz`
12
+ * );
13
+ * ```
14
+ */
15
+ declare class NeonClient {
16
+ /** Neon API key for authentication. */
17
+ private readonly apiKey;
18
+ /**
19
+ * @param apiKey Neon API key (project-scoped or account-scoped)
20
+ */
21
+ constructor(apiKey: string);
22
+ /**
23
+ * Performs a GET request against the Neon API.
24
+ *
25
+ * @param path API path (e.g. `/projects/abc/branches`)
26
+ * @returns Typed JSON response body
27
+ * @throws {Error} On non-2xx HTTP status
28
+ */
29
+ get<T>(path: string): Promise<T>;
30
+ /**
31
+ * Performs a POST request against the Neon API.
32
+ *
33
+ * @param path API path
34
+ * @param body Request body (will be JSON-serialized)
35
+ * @returns Typed JSON response body
36
+ * @throws {Error} On non-2xx HTTP status
37
+ */
38
+ post<T>(path: string, body?: unknown): Promise<T>;
39
+ /**
40
+ * Performs a PATCH request against the Neon API.
41
+ *
42
+ * @param path API path
43
+ * @param body Request body (will be JSON-serialized)
44
+ * @returns Typed JSON response body
45
+ * @throws {Error} On non-2xx HTTP status
46
+ */
47
+ patch<T>(path: string, body?: unknown): Promise<T>;
48
+ /**
49
+ * Performs a DELETE request against the Neon API.
50
+ *
51
+ * @param path API path
52
+ * @throws {Error} On non-2xx HTTP status
53
+ */
54
+ delete(path: string): Promise<void>;
55
+ private request;
56
+ }
57
+ //#endregion
58
+ export { NeonClient };
59
+ //# sourceMappingURL=client.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.cts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;AAaA;;;;;;;;cAAa,UAAA;EAoDgB;EAAA,iBAlDX,MAAA;EAkDkB;;;cA7CvB,MAAA;EAWN;;;;;;;EAAA,GAAA,GAAA,CAAO,IAAA,WAAe,OAAA,CAAQ,CAAA;EAYR;;;;;;;;EAAtB,IAAA,GAAA,CAAQ,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAsB/C;;;;;AAIe;;;EAdf,KAAA,GAAA,CAAS,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;;;;;;;EAUhD,MAAA,CAAO,IAAA,WAAe,OAAA;EAAA,QAId,OAAA;AAAA"}
@@ -0,0 +1,59 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.mjs";
2
+
3
+ //#region src/neon/client.d.ts
4
+ /**
5
+ * REST client for the Neon API.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const client = new NeonClient(apiKey);
10
+ * const branch = await client.get<{ branch: { id: string } }>(
11
+ * `/projects/abc/branches/br-xyz`
12
+ * );
13
+ * ```
14
+ */
15
+ declare class NeonClient {
16
+ /** Neon API key for authentication. */
17
+ private readonly apiKey;
18
+ /**
19
+ * @param apiKey Neon API key (project-scoped or account-scoped)
20
+ */
21
+ constructor(apiKey: string);
22
+ /**
23
+ * Performs a GET request against the Neon API.
24
+ *
25
+ * @param path API path (e.g. `/projects/abc/branches`)
26
+ * @returns Typed JSON response body
27
+ * @throws {Error} On non-2xx HTTP status
28
+ */
29
+ get<T>(path: string): Promise<T>;
30
+ /**
31
+ * Performs a POST request against the Neon API.
32
+ *
33
+ * @param path API path
34
+ * @param body Request body (will be JSON-serialized)
35
+ * @returns Typed JSON response body
36
+ * @throws {Error} On non-2xx HTTP status
37
+ */
38
+ post<T>(path: string, body?: unknown): Promise<T>;
39
+ /**
40
+ * Performs a PATCH request against the Neon API.
41
+ *
42
+ * @param path API path
43
+ * @param body Request body (will be JSON-serialized)
44
+ * @returns Typed JSON response body
45
+ * @throws {Error} On non-2xx HTTP status
46
+ */
47
+ patch<T>(path: string, body?: unknown): Promise<T>;
48
+ /**
49
+ * Performs a DELETE request against the Neon API.
50
+ *
51
+ * @param path API path
52
+ * @throws {Error} On non-2xx HTTP status
53
+ */
54
+ delete(path: string): Promise<void>;
55
+ private request;
56
+ }
57
+ //#endregion
58
+ export { NeonClient };
59
+ //# sourceMappingURL=client.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/neon/client.ts"],"mappings":";;;;;;AAaA;;;;;;;;cAAa,UAAA;EAoDgB;EAAA,iBAlDX,MAAA;EAkDkB;;;cA7CvB,MAAA;EAWN;;;;;;;EAAA,GAAA,GAAA,CAAO,IAAA,WAAe,OAAA,CAAQ,CAAA;EAYR;;;;;;;;EAAtB,IAAA,GAAA,CAAQ,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;EAsB/C;;;;;AAIe;;;EAdf,KAAA,GAAA,CAAS,IAAA,UAAc,IAAA,aAAiB,OAAA,CAAQ,CAAA;;;;;;;EAUhD,MAAA,CAAO,IAAA,WAAe,OAAA;EAAA,QAId,OAAA;AAAA"}
@@ -0,0 +1,84 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.mjs";
2
+
3
+ //#region src/neon/client.ts
4
+ const NEON_API_URL = "https://console.neon.tech/api/v2";
5
+ /**
6
+ * REST client for the Neon API.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const client = new NeonClient(apiKey);
11
+ * const branch = await client.get<{ branch: { id: string } }>(
12
+ * `/projects/abc/branches/br-xyz`
13
+ * );
14
+ * ```
15
+ */
16
+ var NeonClient = class {
17
+ /**
18
+ * @param apiKey Neon API key (project-scoped or account-scoped)
19
+ */
20
+ constructor(apiKey) {
21
+ this.apiKey = apiKey;
22
+ }
23
+ /**
24
+ * Performs a GET request against the Neon API.
25
+ *
26
+ * @param path API path (e.g. `/projects/abc/branches`)
27
+ * @returns Typed JSON response body
28
+ * @throws {Error} On non-2xx HTTP status
29
+ */
30
+ async get(path) {
31
+ return this.request("GET", path);
32
+ }
33
+ /**
34
+ * Performs a POST request against the Neon API.
35
+ *
36
+ * @param path API path
37
+ * @param body Request body (will be JSON-serialized)
38
+ * @returns Typed JSON response body
39
+ * @throws {Error} On non-2xx HTTP status
40
+ */
41
+ async post(path, body) {
42
+ return this.request("POST", path, body);
43
+ }
44
+ /**
45
+ * Performs a PATCH request against the Neon API.
46
+ *
47
+ * @param path API path
48
+ * @param body Request body (will be JSON-serialized)
49
+ * @returns Typed JSON response body
50
+ * @throws {Error} On non-2xx HTTP status
51
+ */
52
+ async patch(path, body) {
53
+ return this.request("PATCH", path, body);
54
+ }
55
+ /**
56
+ * Performs a DELETE request against the Neon API.
57
+ *
58
+ * @param path API path
59
+ * @throws {Error} On non-2xx HTTP status
60
+ */
61
+ async delete(path) {
62
+ await this.request("DELETE", path);
63
+ }
64
+ async request(method, path, body) {
65
+ const response = await fetch(`${NEON_API_URL}${path}`, {
66
+ method,
67
+ headers: {
68
+ "Content-Type": "application/json",
69
+ Authorization: `Bearer ${this.apiKey}`
70
+ },
71
+ body: body ? JSON.stringify(body) : void 0
72
+ });
73
+ if (!response.ok) {
74
+ const errorText = await response.text();
75
+ throw new Error(`Neon API error (${response.status}): ${errorText}`);
76
+ }
77
+ if (method === "DELETE") return;
78
+ return await response.json();
79
+ }
80
+ };
81
+
82
+ //#endregion
83
+ export { NeonClient };
84
+ //# sourceMappingURL=client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../../src/neon/client.ts"],"sourcesContent":["const 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 {Error} On 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 {Error} On 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 {Error} On 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 {Error} On 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\tconst response = await fetch(`${NEON_API_URL}${path}`, {\n\t\t\tmethod,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t},\n\t\t\tbody: body ? JSON.stringify(body) : undefined,\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":";;;AAAA,MAAM,eAAe;;;;;;;;;;;;AAarB,IAAa,aAAb,MAAwB;;;;CAOvB,YAAY,QAAgB;EAC3B,KAAK,SAAS;CACf;;;;;;;;CASA,MAAM,IAAO,MAA0B;EACtC,OAAO,KAAK,QAAW,OAAO,IAAI;CACnC;;;;;;;;;CAUA,MAAM,KAAQ,MAAc,MAA4B;EACvD,OAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;CAC1C;;;;;;;;;CAUA,MAAM,MAAS,MAAc,MAA4B;EACxD,OAAO,KAAK,QAAW,SAAS,MAAM,IAAI;CAC3C;;;;;;;CAQA,MAAM,OAAO,MAA6B;EACzC,MAAM,KAAK,QAAc,UAAU,IAAI;CACxC;CAEA,MAAc,QACb,QACA,MACA,MACa;EACb,MAAM,WAAW,MAAM,MAAM,GAAG,eAAe,QAAQ;GACtD;GACA,SAAS;IACR,gBAAgB;IAChB,eAAe,UAAU,KAAK;GAC/B;GACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;EACrC,CAAC;EAED,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"}
@@ -0,0 +1,117 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../chunk-BVYJZCqc.cjs');
3
+ const require_neon_client = require('./client.cjs');
4
+ let _pulumi_pulumi = require("@pulumi/pulumi");
5
+ _pulumi_pulumi = require_chunk.__toESM(_pulumi_pulumi, 1);
6
+
7
+ //#region src/neon/database.ts
8
+ /**
9
+ * Finds an existing database by name on a branch.
10
+ *
11
+ * @param client Authenticated Neon API client
12
+ * @param projectId Neon project ID
13
+ * @param branchId Branch ID to search within
14
+ * @param name Exact database name to match
15
+ * @returns `true` if found, `false` otherwise
16
+ */
17
+ async function findDatabaseByName(client, projectId, branchId, name) {
18
+ return (await client.get(`/projects/${projectId}/branches/${branchId}/databases`)).databases.some((d) => d.name === name);
19
+ }
20
+ /**
21
+ * Dynamic provider implementing CRUD for Neon databases.
22
+ *
23
+ * Uses adopt-or-create on `create()`: checks if the database already exists
24
+ * before creating a new one.
25
+ */
26
+ var NeonDatabaseProvider = class {
27
+ /**
28
+ * Creates or adopts a Neon database by name.
29
+ *
30
+ * @param inputs Resolved database configuration
31
+ * @returns Composite ID `{branchId}/{databaseName}` as the resource ID
32
+ */
33
+ async create(inputs) {
34
+ const client = new require_neon_client.NeonClient(inputs.apiKey);
35
+ if (await findDatabaseByName(client, inputs.projectId, inputs.branchId, inputs.name)) _pulumi_pulumi.log.info(`Adopting existing Neon database "${inputs.name}"`);
36
+ else await client.post(`/projects/${inputs.projectId}/branches/${inputs.branchId}/databases`, { database: {
37
+ name: inputs.name,
38
+ owner_name: inputs.ownerName
39
+ } });
40
+ return {
41
+ id: `${inputs.branchId}/${inputs.name}`,
42
+ outs: inputs
43
+ };
44
+ }
45
+ /**
46
+ * Reads current state for `pulumi refresh`.
47
+ *
48
+ * @param id Current composite database ID
49
+ * @param props Last known persisted state
50
+ * @returns Refreshed resource ID and properties
51
+ * @throws {Error} If the database no longer exists
52
+ */
53
+ async read(id, props) {
54
+ const result = await new require_neon_client.NeonClient(props.apiKey).get(`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`);
55
+ return {
56
+ id,
57
+ props: {
58
+ ...props,
59
+ ownerName: result.database.owner_name
60
+ }
61
+ };
62
+ }
63
+ /**
64
+ * Deletes the Neon database. Silently succeeds if already deleted.
65
+ */
66
+ async delete(_id, props) {
67
+ const client = new require_neon_client.NeonClient(props.apiKey);
68
+ try {
69
+ await client.delete(`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`);
70
+ } catch {
71
+ _pulumi_pulumi.log.warn(`Failed to delete Neon database "${props.name}" (may already be deleted)`);
72
+ }
73
+ }
74
+ /**
75
+ * Compares old and new inputs. All fields trigger replacement
76
+ * since databases cannot be renamed or moved.
77
+ */
78
+ async diff(_id, olds, news) {
79
+ const replaces = [];
80
+ if (olds.projectId !== news.projectId) replaces.push("projectId");
81
+ if (olds.branchId !== news.branchId) replaces.push("branchId");
82
+ if (olds.name !== news.name) replaces.push("name");
83
+ return {
84
+ changes: replaces.length > 0 || olds.ownerName !== news.ownerName,
85
+ replaces,
86
+ deleteBeforeReplace: true
87
+ };
88
+ }
89
+ };
90
+ /**
91
+ * Manages a Neon database with adopt-or-create semantics.
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * new NeonDatabase("neon-database", {
96
+ * apiKey: config.requireSecret("neonApiKey"),
97
+ * projectId: "quiet-forest-69719462",
98
+ * branchId: branch.id,
99
+ * name: "neondb",
100
+ * ownerName: "neondb_owner",
101
+ * });
102
+ * ```
103
+ */
104
+ var NeonDatabase = class extends _pulumi_pulumi.dynamic.Resource {
105
+ /**
106
+ * @param name Pulumi resource name
107
+ * @param args Database configuration inputs
108
+ * @param opts Standard Pulumi resource options
109
+ */
110
+ constructor(name, args, opts) {
111
+ super(new NeonDatabaseProvider(), name, { ...args }, opts);
112
+ }
113
+ };
114
+
115
+ //#endregion
116
+ exports.NeonDatabase = NeonDatabase;
117
+ //# sourceMappingURL=database.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/database.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\n\n/** Resolved inputs for the Neon database dynamic provider. */\nexport interface NeonDatabaseInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Neon project ID. */\n\tprojectId: string;\n\n\t/** Branch ID the database belongs to. */\n\tbranchId: string;\n\n\t/** Database name (e.g. `\"neondb\"`). */\n\tname: string;\n\n\t/** Owner role name (e.g. `\"neondb_owner\"`). */\n\townerName: string;\n}\n\n/** Persisted state for the Neon database. */\ninterface NeonDatabaseOutputs extends NeonDatabaseInputs {}\n\n/** Neon API response for a database. */\ninterface DatabaseResponse {\n\tdatabase: {\n\t\tid: number;\n\t\tname: string;\n\t\towner_name: string;\n\t\tbranch_id: string;\n\t};\n}\n\n/** Neon API response for listing databases. */\ninterface DatabaseListResponse {\n\tdatabases: Array<{\n\t\tid: number;\n\t\tname: string;\n\t\towner_name: string;\n\t}>;\n}\n\n/**\n * Finds an existing database by name on a branch.\n *\n * @param client Authenticated Neon API client\n * @param projectId Neon project ID\n * @param branchId Branch ID to search within\n * @param name Exact database name to match\n * @returns `true` if found, `false` otherwise\n */\nasync function findDatabaseByName(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n\tname: string,\n): Promise<boolean> {\n\tconst result = await client.get<DatabaseListResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/databases`,\n\t);\n\n\treturn result.databases.some((d) => d.name === name);\n}\n\n/**\n * Dynamic provider implementing CRUD for Neon databases.\n *\n * Uses adopt-or-create on `create()`: checks if the database already exists\n * before creating a new one.\n */\nclass NeonDatabaseProvider implements pulumi.dynamic.ResourceProvider {\n\t/**\n\t * Creates or adopts a Neon database by name.\n\t *\n\t * @param inputs Resolved database configuration\n\t * @returns Composite ID `{branchId}/{databaseName}` as the resource ID\n\t */\n\tasync create(\n\t\tinputs: NeonDatabaseInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst exists = await findDatabaseByName(\n\t\t\tclient,\n\t\t\tinputs.projectId,\n\t\t\tinputs.branchId,\n\t\t\tinputs.name,\n\t\t);\n\n\t\tif (exists) {\n\t\t\tpulumi.log.info(`Adopting existing Neon database \"${inputs.name}\"`);\n\t\t} else {\n\t\t\tawait client.post(\n\t\t\t\t`/projects/${inputs.projectId}/branches/${inputs.branchId}/databases`,\n\t\t\t\t{ database: { name: inputs.name, owner_name: inputs.ownerName } },\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid: `${inputs.branchId}/${inputs.name}`,\n\t\t\touts: inputs,\n\t\t};\n\t}\n\n\t/**\n\t * Reads current state for `pulumi refresh`.\n\t *\n\t * @param id Current composite database ID\n\t * @param props Last known persisted state\n\t * @returns Refreshed resource ID and properties\n\t * @throws {Error} If the database no longer exists\n\t */\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonDatabaseOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<DatabaseResponse>(\n\t\t\t`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`,\n\t\t);\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: { ...props, ownerName: result.database.owner_name },\n\t\t};\n\t}\n\n\t/**\n\t * Deletes the Neon database. Silently succeeds if already deleted.\n\t */\n\tasync delete(_id: string, props: NeonDatabaseOutputs): Promise<void> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\ttry {\n\t\t\tawait client.delete(\n\t\t\t\t`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`,\n\t\t\t);\n\t\t} catch {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Failed to delete Neon database \"${props.name}\" (may already be deleted)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Compares old and new inputs. All fields trigger replacement\n\t * since databases cannot be renamed or moved.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonDatabaseOutputs,\n\t\tnews: NeonDatabaseInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\n\t\tif (olds.projectId !== news.projectId) {\n\t\t\treplaces.push(\"projectId\");\n\t\t}\n\n\t\tif (olds.branchId !== news.branchId) {\n\t\t\treplaces.push(\"branchId\");\n\t\t}\n\n\t\tif (olds.name !== news.name) {\n\t\t\treplaces.push(\"name\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || olds.ownerName !== news.ownerName,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/**\n * Manages a Neon database with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new NeonDatabase(\"neon-database\", {\n * apiKey: config.requireSecret(\"neonApiKey\"),\n * projectId: \"quiet-forest-69719462\",\n * branchId: branch.id,\n * name: \"neondb\",\n * ownerName: \"neondb_owner\",\n * });\n * ```\n */\nexport class NeonDatabase extends pulumi.dynamic.Resource {\n\t/**\n\t * @param name Pulumi resource name\n\t * @param args Database configuration inputs\n\t * @param opts Standard Pulumi resource options\n\t */\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\t/** Neon API key. */\n\t\t\tapiKey: pulumi.Input<string>;\n\n\t\t\t/** Neon project ID. */\n\t\t\tprojectId: pulumi.Input<string>;\n\n\t\t\t/** Branch ID the database belongs to. */\n\t\t\tbranchId: pulumi.Input<string>;\n\n\t\t\t/** Database name. */\n\t\t\tname: pulumi.Input<string>;\n\n\t\t\t/** Owner role name. */\n\t\t\townerName: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonDatabaseProvider(), name, { ...args }, opts);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAoDA,eAAe,mBACd,QACA,WACA,UACA,MACmB;CAKnB,QAAO,MAJc,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,WAC7C,GAEc,UAAU,MAAM,MAAM,EAAE,SAAS,IAAI;AACpD;;;;;;;AAQA,IAAM,uBAAN,MAAsE;;;;;;;CAOrE,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAS3C,IAAI,MAPiB,mBACpB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR,GAGC,eAAO,IAAI,KAAK,oCAAoC,OAAO,KAAK,EAAE;OAElE,MAAM,OAAO,KACZ,aAAa,OAAO,UAAU,YAAY,OAAO,SAAS,aAC1D,EAAE,UAAU;GAAE,MAAM,OAAO;GAAM,YAAY,OAAO;EAAU,EAAE,CACjE;EAGD,OAAO;GACN,IAAI,GAAG,OAAO,SAAS,GAAG,OAAO;GACjC,MAAM;EACP;CACD;;;;;;;;;CAUA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,MAAM,MAEV,EAAE,IAC3B,aAAa,MAAM,UAAU,YAAY,MAAM,SAAS,aAAa,MAAM,MAC5E;EAEA,OAAO;GACN;GACA,OAAO;IAAE,GAAG;IAAO,WAAW,OAAO,SAAS;GAAW;EAC1D;CACD;;;;CAKA,MAAM,OAAO,KAAa,OAA2C;EACpE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OACZ,aAAa,MAAM,UAAU,YAAY,MAAM,SAAS,aAAa,MAAM,MAC5E;EACD,QAAQ;GACP,eAAO,IAAI,KACV,mCAAmC,MAAM,KAAK,2BAC/C;EACD;CACD;;;;;CAMA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAE5B,IAAI,KAAK,cAAc,KAAK,WAC3B,SAAS,KAAK,WAAW;EAG1B,IAAI,KAAK,aAAa,KAAK,UAC1B,SAAS,KAAK,UAAU;EAGzB,IAAI,KAAK,SAAS,KAAK,MACtB,SAAS,KAAK,MAAM;EAGrB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,KAAK,cAAc,KAAK;GACxD;GACA,qBAAqB;EACtB;CACD;AACD;;;;;;;;;;;;;;;AAgBA,IAAa,eAAb,cAAkCC,eAAO,QAAQ,SAAS;;;;;;CAMzD,YACC,MACA,MAgBA,MACC;EACD,MAAM,IAAI,qBAAqB,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAC1D;AACD"}
@@ -0,0 +1,48 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.cjs";
2
+ import * as pulumi from "@pulumi/pulumi";
3
+
4
+ //#region src/neon/database.d.ts
5
+ /** Resolved inputs for the Neon database dynamic provider. */
6
+ interface NeonDatabaseInputs {
7
+ /** Neon API key. */
8
+ apiKey: string;
9
+ /** Neon project ID. */
10
+ projectId: string;
11
+ /** Branch ID the database belongs to. */
12
+ branchId: string;
13
+ /** Database name (e.g. `"neondb"`). */
14
+ name: string;
15
+ /** Owner role name (e.g. `"neondb_owner"`). */
16
+ ownerName: string;
17
+ }
18
+ /**
19
+ * Manages a Neon database with adopt-or-create semantics.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * new NeonDatabase("neon-database", {
24
+ * apiKey: config.requireSecret("neonApiKey"),
25
+ * projectId: "quiet-forest-69719462",
26
+ * branchId: branch.id,
27
+ * name: "neondb",
28
+ * ownerName: "neondb_owner",
29
+ * });
30
+ * ```
31
+ */
32
+ declare class NeonDatabase extends pulumi.dynamic.Resource {
33
+ /**
34
+ * @param name Pulumi resource name
35
+ * @param args Database configuration inputs
36
+ * @param opts Standard Pulumi resource options
37
+ */
38
+ constructor(name: string, args: {
39
+ /** Neon API key. */apiKey: pulumi.Input<string>; /** Neon project ID. */
40
+ projectId: pulumi.Input<string>; /** Branch ID the database belongs to. */
41
+ branchId: pulumi.Input<string>; /** Database name. */
42
+ name: pulumi.Input<string>; /** Owner role name. */
43
+ ownerName: pulumi.Input<string>;
44
+ }, opts?: pulumi.CustomResourceOptions);
45
+ }
46
+ //#endregion
47
+ export { NeonDatabase, NeonDatabaseInputs };
48
+ //# sourceMappingURL=database.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.cts","names":[],"sources":["../../src/neon/database.ts"],"mappings":";;;;;UAIiB,kBAAA;;EAEhB,MAAA;EAFkC;EAKlC,SAAA;EALkC;EAQlC,QAAA;EAHA;EAMA,IAAA;EAAA;EAGA,SAAA;AAAA;AAAS;AA6KV;;;;;;;;;;;;;AA7KU,cA6KG,YAAA,SAAqB,MAAA,CAAO,OAAA,CAAQ,QAAA;EAAA;;;;;cAO/C,IAAA,UACA,IAAA;IAKC,oBAHA,MAAA,EAAQ,MAAA,CAAO,KAAA,UAGG;IAAlB,SAAA,EAAW,MAAA,CAAO,KAAA,UAGR;IAAV,QAAA,EAAU,MAAA,CAAO,KAAA,UAGjB;IAAA,IAAA,EAAM,MAAA,CAAO,KAAA,UAAA;IAGb,SAAA,EAAW,MAAA,CAAO,KAAA;EAAA,GAEnB,IAAA,GAAO,MAAA,CAAO,qBAAA;AAAA"}