@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,48 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.mjs";
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.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.mts","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"}
@@ -0,0 +1,115 @@
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/database.ts
6
+ /**
7
+ * Finds an existing database by name on a branch.
8
+ *
9
+ * @param client Authenticated Neon API client
10
+ * @param projectId Neon project ID
11
+ * @param branchId Branch ID to search within
12
+ * @param name Exact database name to match
13
+ * @returns `true` if found, `false` otherwise
14
+ */
15
+ async function findDatabaseByName(client, projectId, branchId, name) {
16
+ return (await client.get(`/projects/${projectId}/branches/${branchId}/databases`)).databases.some((d) => d.name === name);
17
+ }
18
+ /**
19
+ * Dynamic provider implementing CRUD for Neon databases.
20
+ *
21
+ * Uses adopt-or-create on `create()`: checks if the database already exists
22
+ * before creating a new one.
23
+ */
24
+ var NeonDatabaseProvider = class {
25
+ /**
26
+ * Creates or adopts a Neon database by name.
27
+ *
28
+ * @param inputs Resolved database configuration
29
+ * @returns Composite ID `{branchId}/{databaseName}` as the resource ID
30
+ */
31
+ async create(inputs) {
32
+ const client = new NeonClient(inputs.apiKey);
33
+ if (await findDatabaseByName(client, inputs.projectId, inputs.branchId, inputs.name)) pulumi.log.info(`Adopting existing Neon database "${inputs.name}"`);
34
+ else await client.post(`/projects/${inputs.projectId}/branches/${inputs.branchId}/databases`, { database: {
35
+ name: inputs.name,
36
+ owner_name: inputs.ownerName
37
+ } });
38
+ return {
39
+ id: `${inputs.branchId}/${inputs.name}`,
40
+ outs: inputs
41
+ };
42
+ }
43
+ /**
44
+ * Reads current state for `pulumi refresh`.
45
+ *
46
+ * @param id Current composite database ID
47
+ * @param props Last known persisted state
48
+ * @returns Refreshed resource ID and properties
49
+ * @throws {Error} If the database no longer exists
50
+ */
51
+ async read(id, props) {
52
+ const result = await new NeonClient(props.apiKey).get(`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`);
53
+ return {
54
+ id,
55
+ props: {
56
+ ...props,
57
+ ownerName: result.database.owner_name
58
+ }
59
+ };
60
+ }
61
+ /**
62
+ * Deletes the Neon database. Silently succeeds if already deleted.
63
+ */
64
+ async delete(_id, props) {
65
+ const client = new NeonClient(props.apiKey);
66
+ try {
67
+ await client.delete(`/projects/${props.projectId}/branches/${props.branchId}/databases/${props.name}`);
68
+ } catch {
69
+ pulumi.log.warn(`Failed to delete Neon database "${props.name}" (may already be deleted)`);
70
+ }
71
+ }
72
+ /**
73
+ * Compares old and new inputs. All fields trigger replacement
74
+ * since databases cannot be renamed or moved.
75
+ */
76
+ async diff(_id, olds, news) {
77
+ const replaces = [];
78
+ if (olds.projectId !== news.projectId) replaces.push("projectId");
79
+ if (olds.branchId !== news.branchId) replaces.push("branchId");
80
+ if (olds.name !== news.name) replaces.push("name");
81
+ return {
82
+ changes: replaces.length > 0 || olds.ownerName !== news.ownerName,
83
+ replaces,
84
+ deleteBeforeReplace: true
85
+ };
86
+ }
87
+ };
88
+ /**
89
+ * Manages a Neon database with adopt-or-create semantics.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * new NeonDatabase("neon-database", {
94
+ * apiKey: config.requireSecret("neonApiKey"),
95
+ * projectId: "quiet-forest-69719462",
96
+ * branchId: branch.id,
97
+ * name: "neondb",
98
+ * ownerName: "neondb_owner",
99
+ * });
100
+ * ```
101
+ */
102
+ var NeonDatabase = class extends pulumi.dynamic.Resource {
103
+ /**
104
+ * @param name Pulumi resource name
105
+ * @param args Database configuration inputs
106
+ * @param opts Standard Pulumi resource options
107
+ */
108
+ constructor(name, args, opts) {
109
+ super(new NeonDatabaseProvider(), name, { ...args }, opts);
110
+ }
111
+ };
112
+
113
+ //#endregion
114
+ export { NeonDatabase };
115
+ //# sourceMappingURL=database.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.mjs","names":[],"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,IAAI,WAAW,OAAO,MAAM;EAS3C,IAAI,MAPiB,mBACpB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR,GAGC,OAAO,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,IAFF,WAAW,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,IAAI,WAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OACZ,aAAa,MAAM,UAAU,YAAY,MAAM,SAAS,aAAa,MAAM,MAC5E;EACD,QAAQ;GACP,OAAO,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,cAAkC,OAAO,QAAQ,SAAS;;;;;;CAMzD,YACC,MACA,MAgBA,MACC;EACD,MAAM,IAAI,qBAAqB,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAC1D;AACD"}
@@ -0,0 +1,167 @@
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/endpoint.ts
8
+ /**
9
+ * Finds an existing read-write endpoint for 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
+ * @returns The endpoint ID and host if found, `undefined` otherwise
15
+ */
16
+ async function findEndpointByBranch(client, projectId, branchId) {
17
+ const match = (await client.get(`/projects/${projectId}/branches/${branchId}/endpoints`)).endpoints.find((e) => e.type === "read_write");
18
+ return match ? {
19
+ id: match.id,
20
+ host: match.host
21
+ } : void 0;
22
+ }
23
+ /**
24
+ * Dynamic provider implementing CRUD for Neon compute endpoints.
25
+ *
26
+ * Uses adopt-or-create on `create()`: finds an existing read-write endpoint
27
+ * on the target branch before creating a new one.
28
+ */
29
+ var NeonEndpointProvider = class {
30
+ /**
31
+ * Creates or adopts a Neon endpoint on the target branch.
32
+ *
33
+ * @param inputs Resolved endpoint configuration
34
+ * @returns The Neon endpoint ID as the resource ID
35
+ */
36
+ async create(inputs) {
37
+ const client = new require_neon_client.NeonClient(inputs.apiKey);
38
+ const existing = await findEndpointByBranch(client, inputs.projectId, inputs.branchId);
39
+ if (existing) {
40
+ _pulumi_pulumi.log.info(`Adopting existing Neon endpoint (${existing.id})`);
41
+ await client.patch(`/projects/${inputs.projectId}/endpoints/${existing.id}`, { endpoint: {
42
+ autoscaling_limit_min_cu: inputs.minCu,
43
+ autoscaling_limit_max_cu: inputs.maxCu,
44
+ suspend_timeout_seconds: inputs.suspendTimeout
45
+ } });
46
+ return {
47
+ id: existing.id,
48
+ outs: {
49
+ ...inputs,
50
+ host: existing.host
51
+ }
52
+ };
53
+ }
54
+ const result = await client.post(`/projects/${inputs.projectId}/branches/${inputs.branchId}/endpoints`, { endpoint: {
55
+ type: "read_write",
56
+ autoscaling_limit_min_cu: inputs.minCu,
57
+ autoscaling_limit_max_cu: inputs.maxCu,
58
+ suspend_timeout_seconds: inputs.suspendTimeout
59
+ } });
60
+ return {
61
+ id: result.endpoint.id,
62
+ outs: {
63
+ ...inputs,
64
+ host: result.endpoint.host
65
+ }
66
+ };
67
+ }
68
+ /**
69
+ * Updates endpoint compute settings in place.
70
+ *
71
+ * @param id Current Neon endpoint ID
72
+ * @param _olds Previous persisted state
73
+ * @param news New desired configuration
74
+ * @returns Updated outputs with current host
75
+ */
76
+ async update(id, _olds, news) {
77
+ const result = await new require_neon_client.NeonClient(news.apiKey).patch(`/projects/${news.projectId}/endpoints/${id}`, { endpoint: {
78
+ autoscaling_limit_min_cu: news.minCu,
79
+ autoscaling_limit_max_cu: news.maxCu,
80
+ suspend_timeout_seconds: news.suspendTimeout
81
+ } });
82
+ return { outs: {
83
+ ...news,
84
+ host: result.endpoint.host
85
+ } };
86
+ }
87
+ /**
88
+ * Reads current state for `pulumi refresh`.
89
+ *
90
+ * @param id Current Neon endpoint ID
91
+ * @param props Last known persisted state
92
+ * @returns Refreshed resource ID and properties
93
+ * @throws {Error} If the endpoint no longer exists
94
+ */
95
+ async read(id, props) {
96
+ const result = await new require_neon_client.NeonClient(props.apiKey).get(`/projects/${props.projectId}/endpoints/${id}`);
97
+ return {
98
+ id: result.endpoint.id,
99
+ props: {
100
+ ...props,
101
+ host: result.endpoint.host,
102
+ minCu: result.endpoint.autoscaling_limit_min_cu,
103
+ maxCu: result.endpoint.autoscaling_limit_max_cu,
104
+ suspendTimeout: result.endpoint.suspend_timeout_seconds
105
+ }
106
+ };
107
+ }
108
+ /**
109
+ * Deletes the Neon endpoint. Silently succeeds if already deleted.
110
+ */
111
+ async delete(id, props) {
112
+ const client = new require_neon_client.NeonClient(props.apiKey);
113
+ try {
114
+ await client.delete(`/projects/${props.projectId}/endpoints/${id}`);
115
+ } catch {
116
+ _pulumi_pulumi.log.warn(`Failed to delete Neon endpoint (may already be deleted)`);
117
+ }
118
+ }
119
+ /**
120
+ * Compares old and new inputs. Changing `projectId` or `branchId` triggers replacement.
121
+ */
122
+ async diff(_id, olds, news) {
123
+ const replaces = [];
124
+ if (olds.projectId !== news.projectId) replaces.push("projectId");
125
+ if (olds.branchId !== news.branchId) replaces.push("branchId");
126
+ return {
127
+ changes: replaces.length > 0 || olds.minCu !== news.minCu || olds.maxCu !== news.maxCu || olds.suspendTimeout !== news.suspendTimeout,
128
+ replaces,
129
+ deleteBeforeReplace: true
130
+ };
131
+ }
132
+ };
133
+ /**
134
+ * Manages a Neon compute endpoint with adopt-or-create semantics.
135
+ * Exposes `host` as an output for connection string composition.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const endpoint = new NeonEndpoint("neon-endpoint-production", {
140
+ * apiKey: config.requireSecret("neonApiKey"),
141
+ * projectId: "quiet-forest-69719462",
142
+ * branchId: branch.id,
143
+ * minCu: 0.25,
144
+ * maxCu: 2,
145
+ * suspendTimeout: 0,
146
+ * });
147
+ *
148
+ * const host = endpoint.host;
149
+ * ```
150
+ */
151
+ var NeonEndpoint = class extends _pulumi_pulumi.dynamic.Resource {
152
+ /**
153
+ * @param name Pulumi resource name
154
+ * @param args Endpoint configuration inputs
155
+ * @param opts Standard Pulumi resource options
156
+ */
157
+ constructor(name, args, opts) {
158
+ super(new NeonEndpointProvider(), name, {
159
+ ...args,
160
+ host: void 0
161
+ }, opts);
162
+ }
163
+ };
164
+
165
+ //#endregion
166
+ exports.NeonEndpoint = NeonEndpoint;
167
+ //# sourceMappingURL=endpoint.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/endpoint.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\n\n/** Resolved inputs for the Neon endpoint dynamic provider. */\nexport interface NeonEndpointInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Neon project ID. */\n\tprojectId: string;\n\n\t/** Branch ID to attach the endpoint to. */\n\tbranchId: string;\n\n\t/** Minimum compute units (e.g. `0.25`). */\n\tminCu: number;\n\n\t/** Maximum compute units (e.g. `2`). */\n\tmaxCu: number;\n\n\t/** Seconds of inactivity before suspending. `0` means use global default. */\n\tsuspendTimeout: number;\n}\n\n/** Persisted state for the Neon endpoint. */\ninterface NeonEndpointOutputs extends NeonEndpointInputs {\n\t/** Endpoint hostname (e.g. `\"ep-delicate-union-ah0ekn7n.us-east-1.aws.neon.tech\"`). */\n\thost: string;\n}\n\n/** Neon API response for an endpoint. */\ninterface EndpointResponse {\n\tendpoint: {\n\t\tid: string;\n\t\thost: string;\n\t\tbranch_id: string;\n\t\tautoscaling_limit_min_cu: number;\n\t\tautoscaling_limit_max_cu: number;\n\t\tsuspend_timeout_seconds: number;\n\t};\n}\n\n/** Neon API response for listing endpoints. */\ninterface EndpointListResponse {\n\tendpoints: Array<{\n\t\tid: string;\n\t\thost: string;\n\t\tbranch_id: string;\n\t\ttype: string;\n\t}>;\n}\n\n/**\n * Finds an existing read-write endpoint for 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 * @returns The endpoint ID and host if found, `undefined` otherwise\n */\nasync function findEndpointByBranch(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n): Promise<{ id: string; host: string } | undefined> {\n\tconst result = await client.get<EndpointListResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/endpoints`,\n\t);\n\n\tconst match = result.endpoints.find((e) => e.type === \"read_write\");\n\n\treturn match ? { id: match.id, host: match.host } : undefined;\n}\n\n/**\n * Dynamic provider implementing CRUD for Neon compute endpoints.\n *\n * Uses adopt-or-create on `create()`: finds an existing read-write endpoint\n * on the target branch before creating a new one.\n */\nclass NeonEndpointProvider implements pulumi.dynamic.ResourceProvider {\n\t/**\n\t * Creates or adopts a Neon endpoint on the target branch.\n\t *\n\t * @param inputs Resolved endpoint configuration\n\t * @returns The Neon endpoint ID as the resource ID\n\t */\n\tasync create(\n\t\tinputs: NeonEndpointInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst existing = await findEndpointByBranch(\n\t\t\tclient,\n\t\t\tinputs.projectId,\n\t\t\tinputs.branchId,\n\t\t);\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(`Adopting existing Neon endpoint (${existing.id})`);\n\n\t\t\tawait client.patch(\n\t\t\t\t`/projects/${inputs.projectId}/endpoints/${existing.id}`,\n\t\t\t\t{\n\t\t\t\t\tendpoint: {\n\t\t\t\t\t\tautoscaling_limit_min_cu: inputs.minCu,\n\t\t\t\t\t\tautoscaling_limit_max_cu: inputs.maxCu,\n\t\t\t\t\t\tsuspend_timeout_seconds: inputs.suspendTimeout,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tid: existing.id,\n\t\t\t\touts: { ...inputs, host: existing.host },\n\t\t\t};\n\t\t}\n\n\t\tconst result = await client.post<EndpointResponse>(\n\t\t\t`/projects/${inputs.projectId}/branches/${inputs.branchId}/endpoints`,\n\t\t\t{\n\t\t\t\tendpoint: {\n\t\t\t\t\ttype: \"read_write\",\n\t\t\t\t\tautoscaling_limit_min_cu: inputs.minCu,\n\t\t\t\t\tautoscaling_limit_max_cu: inputs.maxCu,\n\t\t\t\t\tsuspend_timeout_seconds: inputs.suspendTimeout,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn {\n\t\t\tid: result.endpoint.id,\n\t\t\touts: { ...inputs, host: result.endpoint.host },\n\t\t};\n\t}\n\n\t/**\n\t * Updates endpoint compute settings in place.\n\t *\n\t * @param id Current Neon endpoint ID\n\t * @param _olds Previous persisted state\n\t * @param news New desired configuration\n\t * @returns Updated outputs with current host\n\t */\n\tasync update(\n\t\tid: string,\n\t\t_olds: NeonEndpointOutputs,\n\t\tnews: NeonEndpointInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst client = new NeonClient(news.apiKey);\n\n\t\tconst result = await client.patch<EndpointResponse>(\n\t\t\t`/projects/${news.projectId}/endpoints/${id}`,\n\t\t\t{\n\t\t\t\tendpoint: {\n\t\t\t\t\tautoscaling_limit_min_cu: news.minCu,\n\t\t\t\t\tautoscaling_limit_max_cu: news.maxCu,\n\t\t\t\t\tsuspend_timeout_seconds: news.suspendTimeout,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\treturn { outs: { ...news, host: result.endpoint.host } };\n\t}\n\n\t/**\n\t * Reads current state for `pulumi refresh`.\n\t *\n\t * @param id Current Neon endpoint ID\n\t * @param props Last known persisted state\n\t * @returns Refreshed resource ID and properties\n\t * @throws {Error} If the endpoint no longer exists\n\t */\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonEndpointOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<EndpointResponse>(\n\t\t\t`/projects/${props.projectId}/endpoints/${id}`,\n\t\t);\n\n\t\treturn {\n\t\t\tid: result.endpoint.id,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\thost: result.endpoint.host,\n\t\t\t\tminCu: result.endpoint.autoscaling_limit_min_cu,\n\t\t\t\tmaxCu: result.endpoint.autoscaling_limit_max_cu,\n\t\t\t\tsuspendTimeout: result.endpoint.suspend_timeout_seconds,\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Deletes the Neon endpoint. Silently succeeds if already deleted.\n\t */\n\tasync delete(id: string, props: NeonEndpointOutputs): Promise<void> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\ttry {\n\t\t\tawait client.delete(`/projects/${props.projectId}/endpoints/${id}`);\n\t\t} catch {\n\t\t\tpulumi.log.warn(\n\t\t\t\t`Failed to delete Neon endpoint (may already be deleted)`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Compares old and new inputs. Changing `projectId` or `branchId` triggers replacement.\n\t */\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonEndpointOutputs,\n\t\tnews: NeonEndpointInputs,\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\tconst hasChanges =\n\t\t\treplaces.length > 0 ||\n\t\t\tolds.minCu !== news.minCu ||\n\t\t\tolds.maxCu !== news.maxCu ||\n\t\t\tolds.suspendTimeout !== news.suspendTimeout;\n\n\t\treturn { changes: hasChanges, replaces, deleteBeforeReplace: true };\n\t}\n}\n\n/**\n * Manages a Neon compute endpoint with adopt-or-create semantics.\n * Exposes `host` as an output for connection string composition.\n *\n * @example\n * ```typescript\n * const endpoint = new NeonEndpoint(\"neon-endpoint-production\", {\n * apiKey: config.requireSecret(\"neonApiKey\"),\n * projectId: \"quiet-forest-69719462\",\n * branchId: branch.id,\n * minCu: 0.25,\n * maxCu: 2,\n * suspendTimeout: 0,\n * });\n *\n * const host = endpoint.host;\n * ```\n */\nexport class NeonEndpoint extends pulumi.dynamic.Resource {\n\t/** Endpoint hostname for connection strings. */\n\tpublic declare readonly host: pulumi.Output<string>;\n\n\t/**\n\t * @param name Pulumi resource name\n\t * @param args Endpoint 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 to attach the endpoint to. */\n\t\t\tbranchId: pulumi.Input<string>;\n\n\t\t\t/** Minimum compute units. */\n\t\t\tminCu: pulumi.Input<number>;\n\n\t\t\t/** Maximum compute units. */\n\t\t\tmaxCu: pulumi.Input<number>;\n\n\t\t\t/** Seconds of inactivity before suspending. */\n\t\t\tsuspendTimeout: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonEndpointProvider(), name, { ...args, host: undefined }, opts);\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.cjs";
2
+ import * as pulumi from "@pulumi/pulumi";
3
+
4
+ //#region src/neon/endpoint.d.ts
5
+ /** Resolved inputs for the Neon endpoint dynamic provider. */
6
+ interface NeonEndpointInputs {
7
+ /** Neon API key. */
8
+ apiKey: string;
9
+ /** Neon project ID. */
10
+ projectId: string;
11
+ /** Branch ID to attach the endpoint to. */
12
+ branchId: string;
13
+ /** Minimum compute units (e.g. `0.25`). */
14
+ minCu: number;
15
+ /** Maximum compute units (e.g. `2`). */
16
+ maxCu: number;
17
+ /** Seconds of inactivity before suspending. `0` means use global default. */
18
+ suspendTimeout: number;
19
+ }
20
+ /**
21
+ * Manages a Neon compute endpoint with adopt-or-create semantics.
22
+ * Exposes `host` as an output for connection string composition.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const endpoint = new NeonEndpoint("neon-endpoint-production", {
27
+ * apiKey: config.requireSecret("neonApiKey"),
28
+ * projectId: "quiet-forest-69719462",
29
+ * branchId: branch.id,
30
+ * minCu: 0.25,
31
+ * maxCu: 2,
32
+ * suspendTimeout: 0,
33
+ * });
34
+ *
35
+ * const host = endpoint.host;
36
+ * ```
37
+ */
38
+ declare class NeonEndpoint extends pulumi.dynamic.Resource {
39
+ /** Endpoint hostname for connection strings. */
40
+ readonly host: pulumi.Output<string>;
41
+ /**
42
+ * @param name Pulumi resource name
43
+ * @param args Endpoint configuration inputs
44
+ * @param opts Standard Pulumi resource options
45
+ */
46
+ constructor(name: string, args: {
47
+ /** Neon API key. */apiKey: pulumi.Input<string>; /** Neon project ID. */
48
+ projectId: pulumi.Input<string>; /** Branch ID to attach the endpoint to. */
49
+ branchId: pulumi.Input<string>; /** Minimum compute units. */
50
+ minCu: pulumi.Input<number>; /** Maximum compute units. */
51
+ maxCu: pulumi.Input<number>; /** Seconds of inactivity before suspending. */
52
+ suspendTimeout: pulumi.Input<number>;
53
+ }, opts?: pulumi.CustomResourceOptions);
54
+ }
55
+ //#endregion
56
+ export { NeonEndpoint, NeonEndpointInputs };
57
+ //# sourceMappingURL=endpoint.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.d.cts","names":[],"sources":["../../src/neon/endpoint.ts"],"mappings":";;;;;UAIiB,kBAAA;;EAEhB,MAAA;EAFkC;EAKlC,SAAA;EALkC;EAQlC,QAAA;EAHA;EAMA,KAAA;EAAA;EAGA,KAAA;EAGA;EAAA,cAAA;AAAA;AA2OD;;;;;;;;;;;;;;;;;;AAAA,cAAa,YAAA,SAAqB,MAAA,CAAO,OAAA,CAAQ,QAAA;EAEX;EAAA,SAAb,IAAA,EAAM,MAAA,CAAO,MAAA;EAQpC;;;;;cAAA,IAAA,UACA,IAAA;IAKmB,oBAHlB,MAAA,EAAQ,MAAA,CAAO,KAAA,UAML;IAHV,SAAA,EAAW,MAAA,CAAO,KAAA,UAMlB;IAHA,QAAA,EAAU,MAAA,CAAO,KAAA,UAGH;IAAd,KAAA,EAAO,MAAA,CAAO,KAAA,UAGP;IAAP,KAAA,EAAO,MAAA,CAAO,KAAA,UAGd;IAAA,cAAA,EAAgB,MAAA,CAAO,KAAA;EAAA,GAExB,IAAA,GAAO,MAAA,CAAO,qBAAA;AAAA"}
@@ -0,0 +1,57 @@
1
+ import { t as __name } from "../chunk-OPjESj5l.mjs";
2
+ import * as pulumi from "@pulumi/pulumi";
3
+
4
+ //#region src/neon/endpoint.d.ts
5
+ /** Resolved inputs for the Neon endpoint dynamic provider. */
6
+ interface NeonEndpointInputs {
7
+ /** Neon API key. */
8
+ apiKey: string;
9
+ /** Neon project ID. */
10
+ projectId: string;
11
+ /** Branch ID to attach the endpoint to. */
12
+ branchId: string;
13
+ /** Minimum compute units (e.g. `0.25`). */
14
+ minCu: number;
15
+ /** Maximum compute units (e.g. `2`). */
16
+ maxCu: number;
17
+ /** Seconds of inactivity before suspending. `0` means use global default. */
18
+ suspendTimeout: number;
19
+ }
20
+ /**
21
+ * Manages a Neon compute endpoint with adopt-or-create semantics.
22
+ * Exposes `host` as an output for connection string composition.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const endpoint = new NeonEndpoint("neon-endpoint-production", {
27
+ * apiKey: config.requireSecret("neonApiKey"),
28
+ * projectId: "quiet-forest-69719462",
29
+ * branchId: branch.id,
30
+ * minCu: 0.25,
31
+ * maxCu: 2,
32
+ * suspendTimeout: 0,
33
+ * });
34
+ *
35
+ * const host = endpoint.host;
36
+ * ```
37
+ */
38
+ declare class NeonEndpoint extends pulumi.dynamic.Resource {
39
+ /** Endpoint hostname for connection strings. */
40
+ readonly host: pulumi.Output<string>;
41
+ /**
42
+ * @param name Pulumi resource name
43
+ * @param args Endpoint configuration inputs
44
+ * @param opts Standard Pulumi resource options
45
+ */
46
+ constructor(name: string, args: {
47
+ /** Neon API key. */apiKey: pulumi.Input<string>; /** Neon project ID. */
48
+ projectId: pulumi.Input<string>; /** Branch ID to attach the endpoint to. */
49
+ branchId: pulumi.Input<string>; /** Minimum compute units. */
50
+ minCu: pulumi.Input<number>; /** Maximum compute units. */
51
+ maxCu: pulumi.Input<number>; /** Seconds of inactivity before suspending. */
52
+ suspendTimeout: pulumi.Input<number>;
53
+ }, opts?: pulumi.CustomResourceOptions);
54
+ }
55
+ //#endregion
56
+ export { NeonEndpoint, NeonEndpointInputs };
57
+ //# sourceMappingURL=endpoint.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.d.mts","names":[],"sources":["../../src/neon/endpoint.ts"],"mappings":";;;;;UAIiB,kBAAA;;EAEhB,MAAA;EAFkC;EAKlC,SAAA;EALkC;EAQlC,QAAA;EAHA;EAMA,KAAA;EAAA;EAGA,KAAA;EAGA;EAAA,cAAA;AAAA;AA2OD;;;;;;;;;;;;;;;;;;AAAA,cAAa,YAAA,SAAqB,MAAA,CAAO,OAAA,CAAQ,QAAA;EAEX;EAAA,SAAb,IAAA,EAAM,MAAA,CAAO,MAAA;EAQpC;;;;;cAAA,IAAA,UACA,IAAA;IAKmB,oBAHlB,MAAA,EAAQ,MAAA,CAAO,KAAA,UAML;IAHV,SAAA,EAAW,MAAA,CAAO,KAAA,UAMlB;IAHA,QAAA,EAAU,MAAA,CAAO,KAAA,UAGH;IAAd,KAAA,EAAO,MAAA,CAAO,KAAA,UAGP;IAAP,KAAA,EAAO,MAAA,CAAO,KAAA,UAGd;IAAA,cAAA,EAAgB,MAAA,CAAO,KAAA;EAAA,GAExB,IAAA,GAAO,MAAA,CAAO,qBAAA;AAAA"}
@@ -0,0 +1,165 @@
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/endpoint.ts
6
+ /**
7
+ * Finds an existing read-write endpoint for a branch.
8
+ *
9
+ * @param client Authenticated Neon API client
10
+ * @param projectId Neon project ID
11
+ * @param branchId Branch ID to search within
12
+ * @returns The endpoint ID and host if found, `undefined` otherwise
13
+ */
14
+ async function findEndpointByBranch(client, projectId, branchId) {
15
+ const match = (await client.get(`/projects/${projectId}/branches/${branchId}/endpoints`)).endpoints.find((e) => e.type === "read_write");
16
+ return match ? {
17
+ id: match.id,
18
+ host: match.host
19
+ } : void 0;
20
+ }
21
+ /**
22
+ * Dynamic provider implementing CRUD for Neon compute endpoints.
23
+ *
24
+ * Uses adopt-or-create on `create()`: finds an existing read-write endpoint
25
+ * on the target branch before creating a new one.
26
+ */
27
+ var NeonEndpointProvider = class {
28
+ /**
29
+ * Creates or adopts a Neon endpoint on the target branch.
30
+ *
31
+ * @param inputs Resolved endpoint configuration
32
+ * @returns The Neon endpoint ID as the resource ID
33
+ */
34
+ async create(inputs) {
35
+ const client = new NeonClient(inputs.apiKey);
36
+ const existing = await findEndpointByBranch(client, inputs.projectId, inputs.branchId);
37
+ if (existing) {
38
+ pulumi.log.info(`Adopting existing Neon endpoint (${existing.id})`);
39
+ await client.patch(`/projects/${inputs.projectId}/endpoints/${existing.id}`, { endpoint: {
40
+ autoscaling_limit_min_cu: inputs.minCu,
41
+ autoscaling_limit_max_cu: inputs.maxCu,
42
+ suspend_timeout_seconds: inputs.suspendTimeout
43
+ } });
44
+ return {
45
+ id: existing.id,
46
+ outs: {
47
+ ...inputs,
48
+ host: existing.host
49
+ }
50
+ };
51
+ }
52
+ const result = await client.post(`/projects/${inputs.projectId}/branches/${inputs.branchId}/endpoints`, { endpoint: {
53
+ type: "read_write",
54
+ autoscaling_limit_min_cu: inputs.minCu,
55
+ autoscaling_limit_max_cu: inputs.maxCu,
56
+ suspend_timeout_seconds: inputs.suspendTimeout
57
+ } });
58
+ return {
59
+ id: result.endpoint.id,
60
+ outs: {
61
+ ...inputs,
62
+ host: result.endpoint.host
63
+ }
64
+ };
65
+ }
66
+ /**
67
+ * Updates endpoint compute settings in place.
68
+ *
69
+ * @param id Current Neon endpoint ID
70
+ * @param _olds Previous persisted state
71
+ * @param news New desired configuration
72
+ * @returns Updated outputs with current host
73
+ */
74
+ async update(id, _olds, news) {
75
+ const result = await new NeonClient(news.apiKey).patch(`/projects/${news.projectId}/endpoints/${id}`, { endpoint: {
76
+ autoscaling_limit_min_cu: news.minCu,
77
+ autoscaling_limit_max_cu: news.maxCu,
78
+ suspend_timeout_seconds: news.suspendTimeout
79
+ } });
80
+ return { outs: {
81
+ ...news,
82
+ host: result.endpoint.host
83
+ } };
84
+ }
85
+ /**
86
+ * Reads current state for `pulumi refresh`.
87
+ *
88
+ * @param id Current Neon endpoint ID
89
+ * @param props Last known persisted state
90
+ * @returns Refreshed resource ID and properties
91
+ * @throws {Error} If the endpoint no longer exists
92
+ */
93
+ async read(id, props) {
94
+ const result = await new NeonClient(props.apiKey).get(`/projects/${props.projectId}/endpoints/${id}`);
95
+ return {
96
+ id: result.endpoint.id,
97
+ props: {
98
+ ...props,
99
+ host: result.endpoint.host,
100
+ minCu: result.endpoint.autoscaling_limit_min_cu,
101
+ maxCu: result.endpoint.autoscaling_limit_max_cu,
102
+ suspendTimeout: result.endpoint.suspend_timeout_seconds
103
+ }
104
+ };
105
+ }
106
+ /**
107
+ * Deletes the Neon endpoint. Silently succeeds if already deleted.
108
+ */
109
+ async delete(id, props) {
110
+ const client = new NeonClient(props.apiKey);
111
+ try {
112
+ await client.delete(`/projects/${props.projectId}/endpoints/${id}`);
113
+ } catch {
114
+ pulumi.log.warn(`Failed to delete Neon endpoint (may already be deleted)`);
115
+ }
116
+ }
117
+ /**
118
+ * Compares old and new inputs. Changing `projectId` or `branchId` triggers replacement.
119
+ */
120
+ async diff(_id, olds, news) {
121
+ const replaces = [];
122
+ if (olds.projectId !== news.projectId) replaces.push("projectId");
123
+ if (olds.branchId !== news.branchId) replaces.push("branchId");
124
+ return {
125
+ changes: replaces.length > 0 || olds.minCu !== news.minCu || olds.maxCu !== news.maxCu || olds.suspendTimeout !== news.suspendTimeout,
126
+ replaces,
127
+ deleteBeforeReplace: true
128
+ };
129
+ }
130
+ };
131
+ /**
132
+ * Manages a Neon compute endpoint with adopt-or-create semantics.
133
+ * Exposes `host` as an output for connection string composition.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const endpoint = new NeonEndpoint("neon-endpoint-production", {
138
+ * apiKey: config.requireSecret("neonApiKey"),
139
+ * projectId: "quiet-forest-69719462",
140
+ * branchId: branch.id,
141
+ * minCu: 0.25,
142
+ * maxCu: 2,
143
+ * suspendTimeout: 0,
144
+ * });
145
+ *
146
+ * const host = endpoint.host;
147
+ * ```
148
+ */
149
+ var NeonEndpoint = class extends pulumi.dynamic.Resource {
150
+ /**
151
+ * @param name Pulumi resource name
152
+ * @param args Endpoint configuration inputs
153
+ * @param opts Standard Pulumi resource options
154
+ */
155
+ constructor(name, args, opts) {
156
+ super(new NeonEndpointProvider(), name, {
157
+ ...args,
158
+ host: void 0
159
+ }, opts);
160
+ }
161
+ };
162
+
163
+ //#endregion
164
+ export { NeonEndpoint };
165
+ //# sourceMappingURL=endpoint.mjs.map