@infracraft/pulumi 1.0.0 → 1.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 (97) hide show
  1. package/dist/neon/branch.cjs +3 -3
  2. package/dist/neon/branch.cjs.map +1 -1
  3. package/dist/neon/branch.d.cts +1 -1
  4. package/dist/neon/branch.d.cts.map +1 -1
  5. package/dist/neon/branch.d.mts +1 -1
  6. package/dist/neon/branch.d.mts.map +1 -1
  7. package/dist/neon/branch.mjs +3 -3
  8. package/dist/neon/branch.mjs.map +1 -1
  9. package/dist/neon/database.cjs +2 -2
  10. package/dist/neon/database.cjs.map +1 -1
  11. package/dist/neon/database.mjs +2 -2
  12. package/dist/neon/database.mjs.map +1 -1
  13. package/dist/neon/endpoint.cjs +2 -2
  14. package/dist/neon/endpoint.cjs.map +1 -1
  15. package/dist/neon/endpoint.mjs +2 -2
  16. package/dist/neon/endpoint.mjs.map +1 -1
  17. package/dist/neon/project.cjs +2 -2
  18. package/dist/neon/project.cjs.map +1 -1
  19. package/dist/neon/project.d.cts +1 -1
  20. package/dist/neon/project.d.cts.map +1 -1
  21. package/dist/neon/project.d.mts +1 -1
  22. package/dist/neon/project.d.mts.map +1 -1
  23. package/dist/neon/project.mjs +2 -2
  24. package/dist/neon/project.mjs.map +1 -1
  25. package/dist/neon/role.cjs +2 -2
  26. package/dist/neon/role.cjs.map +1 -1
  27. package/dist/neon/role.mjs +2 -2
  28. package/dist/neon/role.mjs.map +1 -1
  29. package/dist/railway/deploy.cjs +1 -1
  30. package/dist/railway/deploy.cjs.map +1 -1
  31. package/dist/railway/deploy.mjs +1 -1
  32. package/dist/railway/deploy.mjs.map +1 -1
  33. package/dist/railway/domain.cjs +3 -3
  34. package/dist/railway/domain.cjs.map +1 -1
  35. package/dist/railway/domain.mjs +3 -3
  36. package/dist/railway/domain.mjs.map +1 -1
  37. package/dist/railway/environment.cjs +3 -3
  38. package/dist/railway/environment.cjs.map +1 -1
  39. package/dist/railway/environment.d.cts +1 -1
  40. package/dist/railway/environment.d.cts.map +1 -1
  41. package/dist/railway/environment.d.mts +1 -1
  42. package/dist/railway/environment.d.mts.map +1 -1
  43. package/dist/railway/environment.mjs +3 -3
  44. package/dist/railway/environment.mjs.map +1 -1
  45. package/dist/railway/project.cjs +2 -2
  46. package/dist/railway/project.cjs.map +1 -1
  47. package/dist/railway/project.d.cts +1 -1
  48. package/dist/railway/project.d.cts.map +1 -1
  49. package/dist/railway/project.d.mts +1 -1
  50. package/dist/railway/project.d.mts.map +1 -1
  51. package/dist/railway/project.mjs +2 -2
  52. package/dist/railway/project.mjs.map +1 -1
  53. package/dist/railway/service.cjs +4 -4
  54. package/dist/railway/service.cjs.map +1 -1
  55. package/dist/railway/service.d.cts +1 -1
  56. package/dist/railway/service.d.cts.map +1 -1
  57. package/dist/railway/service.d.mts +1 -1
  58. package/dist/railway/service.d.mts.map +1 -1
  59. package/dist/railway/service.mjs +4 -4
  60. package/dist/railway/service.mjs.map +1 -1
  61. package/dist/railway/variable.cjs +3 -3
  62. package/dist/railway/variable.cjs.map +1 -1
  63. package/dist/railway/variable.mjs +3 -3
  64. package/dist/railway/variable.mjs.map +1 -1
  65. package/dist/railway/volume.cjs +3 -3
  66. package/dist/railway/volume.cjs.map +1 -1
  67. package/dist/railway/volume.mjs +3 -3
  68. package/dist/railway/volume.mjs.map +1 -1
  69. package/dist/vercel/deploy.cjs +4 -2
  70. package/dist/vercel/deploy.cjs.map +1 -1
  71. package/dist/vercel/deploy.d.cts +11 -2
  72. package/dist/vercel/deploy.d.cts.map +1 -1
  73. package/dist/vercel/deploy.d.mts +11 -2
  74. package/dist/vercel/deploy.d.mts.map +1 -1
  75. package/dist/vercel/deploy.mjs +4 -2
  76. package/dist/vercel/deploy.mjs.map +1 -1
  77. package/dist/vercel/index.cjs +2 -0
  78. package/dist/vercel/index.d.cts +2 -1
  79. package/dist/vercel/index.d.mts +2 -1
  80. package/dist/vercel/index.mjs +2 -1
  81. package/dist/vercel/project.cjs +162 -0
  82. package/dist/vercel/project.cjs.map +1 -0
  83. package/dist/vercel/project.d.cts +72 -0
  84. package/dist/vercel/project.d.cts.map +1 -0
  85. package/dist/vercel/project.d.mts +72 -0
  86. package/dist/vercel/project.d.mts.map +1 -0
  87. package/dist/vercel/project.mjs +160 -0
  88. package/dist/vercel/project.mjs.map +1 -0
  89. package/dist/vercel/variable.cjs +4 -2
  90. package/dist/vercel/variable.cjs.map +1 -1
  91. package/dist/vercel/variable.d.cts +11 -2
  92. package/dist/vercel/variable.d.cts.map +1 -1
  93. package/dist/vercel/variable.d.mts +11 -2
  94. package/dist/vercel/variable.d.mts.map +1 -1
  95. package/dist/vercel/variable.mjs +4 -2
  96. package/dist/vercel/variable.mjs.map +1 -1
  97. package/package.json +1 -1
@@ -78,11 +78,11 @@ var NeonBranch = class extends _pulumi_pulumi.ComponentResource {
78
78
  super("infracraft:neon:Branch", name, {}, pulumiOpts);
79
79
  const resource = new NeonBranchResource(`${name}-resource`, {
80
80
  apiKey: provider.apiKey,
81
- projectId: project.projectId,
81
+ projectId: project.id,
82
82
  name: args.name
83
83
  }, { parent: this });
84
- this.branchId = resource.id;
85
- this.registerOutputs({ branchId: this.branchId });
84
+ this.id = resource.id;
85
+ this.registerOutputs({ id: this.id });
86
86
  }
87
87
  };
88
88
 
@@ -1 +1 @@
1
- {"version":3,"file":"branch.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/branch.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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.\n */\nclass NeonBranchResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonBranchResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonBranchResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonBranch — replaces Pulumi's native `provider` field. */\ntype NeonBranchOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n};\n\n/** Args for NeonBranch. */\nexport interface NeonBranchArgs {\n\t/** Branch display name. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon branch with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonBranch extends pulumi.ComponentResource {\n\t/** Neon branch ID. */\n\tpublic readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonBranchArgs,\n\t\topts: NeonBranchOptions,\n\t) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Branch\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonBranchResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.branchId = resource.id;\n\n\t\tthis.registerOutputs({ branchId: this.branchId });\n\t}\n}\n"],"mappings":";;;;;;;;;;AAiDA,eAAe,iBACd,QACA,WACA,MAC8B;CAO9B,QAFc,MAJO,OAAO,IAC3B,aAAa,UAAU,UACxB,GAEqB,SAAS,MAAM,MAAM,EAAE,SAAS,IAE1C,GAAG;AACf;;;;;;;AAQA,IAAM,6BAAN,MAA4E;CAC3E,MAAM,OAAO,QAAgE;EAC5E,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAE3C,IAAI,WAAW,MAAM,iBACpB,QACA,OAAO,WACP,OAAO,IACR;EAEA,IAAI,UACH,eAAO,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;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,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;CAEA,MAAM,OAAO,IAAY,OAAyC;EACjE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OAAO,aAAa,MAAM,UAAU,YAAY,IAAI;EAClE,QAAQ;GACP,eAAO,IAAI,KAAK,uDAAuD;EACxE;CACD;CAEA,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;;AAGA,IAAM,qBAAN,cAAiCC,eAAO,QAAQ,SAAS;CAGxD,YACC,MACA,MAKA,MACC;EACD,MAAM,IAAI,2BAA2B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAChE;AACD;;;;;;;;;;;AA2BA,IAAa,aAAb,cAAgCA,eAAO,kBAAkB;CAIxD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,0BAA0B,MAAM,CAAC,GAAG,UAAU;EAEpD,MAAM,WAAW,IAAI,mBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,WAAW,SAAS;EAEzB,KAAK,gBAAgB,EAAE,UAAU,KAAK,SAAS,CAAC;CACjD;AACD"}
1
+ {"version":3,"file":"branch.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/branch.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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.\n */\nclass NeonBranchResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonBranchResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonBranchResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonBranch — replaces Pulumi's native `provider` field. */\ntype NeonBranchOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n};\n\n/** Args for NeonBranch. */\nexport interface NeonBranchArgs {\n\t/** Branch display name. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon branch with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonBranch extends pulumi.ComponentResource {\n\t/** Neon branch ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonBranchArgs,\n\t\topts: NeonBranchOptions,\n\t) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Branch\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonBranchResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.id;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;AAiDA,eAAe,iBACd,QACA,WACA,MAC8B;CAO9B,QAFc,MAJO,OAAO,IAC3B,aAAa,UAAU,UACxB,GAEqB,SAAS,MAAM,MAAM,EAAE,SAAS,IAE1C,GAAG;AACf;;;;;;;AAQA,IAAM,6BAAN,MAA4E;CAC3E,MAAM,OAAO,QAAgE;EAC5E,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAE3C,IAAI,WAAW,MAAM,iBACpB,QACA,OAAO,WACP,OAAO,IACR;EAEA,IAAI,UACH,eAAO,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;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,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;CAEA,MAAM,OAAO,IAAY,OAAyC;EACjE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OAAO,aAAa,MAAM,UAAU,YAAY,IAAI;EAClE,QAAQ;GACP,eAAO,IAAI,KAAK,uDAAuD;EACxE;CACD;CAEA,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;;AAGA,IAAM,qBAAN,cAAiCC,eAAO,QAAQ,SAAS;CAGxD,YACC,MACA,MAKA,MACC;EACD,MAAM,IAAI,2BAA2B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAChE;AACD;;;;;;;;;;;AA2BA,IAAa,aAAb,cAAgCA,eAAO,kBAAkB;CAIxD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,0BAA0B,MAAM,CAAC,GAAG,UAAU;EAEpD,MAAM,WAAW,IAAI,mBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
@@ -35,7 +35,7 @@ interface NeonBranchArgs {
35
35
  */
36
36
  declare class NeonBranch extends pulumi.ComponentResource {
37
37
  /** Neon branch ID. */
38
- readonly branchId: pulumi.Output<string>;
38
+ readonly id: pulumi.Output<string>;
39
39
  constructor(name: string, args: NeonBranchArgs, opts: NeonBranchOptions);
40
40
  }
41
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"branch.d.cts","names":[],"sources":["../../src/neon/branch.ts"],"mappings":";;;;;;;UAMiB,gBAAA;;EAEhB,MAAA;EAFgC;EAKhC,SAAA;EALgC;EAQhC,IAAA;AAAA;;KAgJI,iBAAA,GAAoB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhJhC,mCAkJJ,QAAA,EAAU,YAAA,EAFW;EAKrB,OAAA,EAAS,WAAA;AAAA;;UAIO,cAAA;EAJP;EAMT,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;AANE;AAIrB;cAea,UAAA,SAAmB,MAAA,CAAO,iBAAA;;WAEtB,QAAA,EAAU,MAAA,CAAO,MAAA;cAGhC,IAAA,UACA,IAAA,EAAM,cAAA,EACN,IAAA,EAAM,iBAAA;AAAA"}
1
+ {"version":3,"file":"branch.d.cts","names":[],"sources":["../../src/neon/branch.ts"],"mappings":";;;;;;;UAMiB,gBAAA;;EAEhB,MAAA;EAFgC;EAKhC,SAAA;EALgC;EAQhC,IAAA;AAAA;;KAgJI,iBAAA,GAAoB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhJhC,mCAkJJ,QAAA,EAAU,YAAA,EAFW;EAKrB,OAAA,EAAS,WAAA;AAAA;;UAIO,cAAA;EAJP;EAMT,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;AANE;AAIrB;cAea,UAAA,SAAmB,MAAA,CAAO,iBAAA;;WAEtB,EAAA,EAAI,MAAA,CAAO,MAAA;cAG1B,IAAA,UACA,IAAA,EAAM,cAAA,EACN,IAAA,EAAM,iBAAA;AAAA"}
@@ -35,7 +35,7 @@ interface NeonBranchArgs {
35
35
  */
36
36
  declare class NeonBranch extends pulumi.ComponentResource {
37
37
  /** Neon branch ID. */
38
- readonly branchId: pulumi.Output<string>;
38
+ readonly id: pulumi.Output<string>;
39
39
  constructor(name: string, args: NeonBranchArgs, opts: NeonBranchOptions);
40
40
  }
41
41
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"branch.d.mts","names":[],"sources":["../../src/neon/branch.ts"],"mappings":";;;;;;;UAMiB,gBAAA;;EAEhB,MAAA;EAFgC;EAKhC,SAAA;EALgC;EAQhC,IAAA;AAAA;;KAgJI,iBAAA,GAAoB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhJhC,mCAkJJ,QAAA,EAAU,YAAA,EAFW;EAKrB,OAAA,EAAS,WAAA;AAAA;;UAIO,cAAA;EAJP;EAMT,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;AANE;AAIrB;cAea,UAAA,SAAmB,MAAA,CAAO,iBAAA;;WAEtB,QAAA,EAAU,MAAA,CAAO,MAAA;cAGhC,IAAA,UACA,IAAA,EAAM,cAAA,EACN,IAAA,EAAM,iBAAA;AAAA"}
1
+ {"version":3,"file":"branch.d.mts","names":[],"sources":["../../src/neon/branch.ts"],"mappings":";;;;;;;UAMiB,gBAAA;;EAEhB,MAAA;EAFgC;EAKhC,SAAA;EALgC;EAQhC,IAAA;AAAA;;KAgJI,iBAAA,GAAoB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAhJhC,mCAkJJ,QAAA,EAAU,YAAA,EAFW;EAKrB,OAAA,EAAS,WAAA;AAAA;;UAIO,cAAA;EAJP;EAMT,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;;AANE;AAIrB;cAea,UAAA,SAAmB,MAAA,CAAO,iBAAA;;WAEtB,EAAA,EAAI,MAAA,CAAO,MAAA;cAG1B,IAAA,UACA,IAAA,EAAM,cAAA,EACN,IAAA,EAAM,iBAAA;AAAA"}
@@ -76,11 +76,11 @@ var NeonBranch = class extends pulumi.ComponentResource {
76
76
  super("infracraft:neon:Branch", name, {}, pulumiOpts);
77
77
  const resource = new NeonBranchResource(`${name}-resource`, {
78
78
  apiKey: provider.apiKey,
79
- projectId: project.projectId,
79
+ projectId: project.id,
80
80
  name: args.name
81
81
  }, { parent: this });
82
- this.branchId = resource.id;
83
- this.registerOutputs({ branchId: this.branchId });
82
+ this.id = resource.id;
83
+ this.registerOutputs({ id: this.id });
84
84
  }
85
85
  };
86
86
 
@@ -1 +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\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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.\n */\nclass NeonBranchResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonBranchResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonBranchResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonBranch — replaces Pulumi's native `provider` field. */\ntype NeonBranchOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n};\n\n/** Args for NeonBranch. */\nexport interface NeonBranchArgs {\n\t/** Branch display name. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon branch with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonBranch extends pulumi.ComponentResource {\n\t/** Neon branch ID. */\n\tpublic readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonBranchArgs,\n\t\topts: NeonBranchOptions,\n\t) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Branch\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonBranchResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.branchId = resource.id;\n\n\t\tthis.registerOutputs({ branchId: this.branchId });\n\t}\n}\n"],"mappings":";;;;;;;;AAiDA,eAAe,iBACd,QACA,WACA,MAC8B;CAO9B,QAFc,MAJO,OAAO,IAC3B,aAAa,UAAU,UACxB,GAEqB,SAAS,MAAM,MAAM,EAAE,SAAS,IAE1C,GAAG;AACf;;;;;;;AAQA,IAAM,6BAAN,MAA4E;CAC3E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,qBAAN,cAAiC,OAAO,QAAQ,SAAS;CAGxD,YACC,MACA,MAKA,MACC;EACD,MAAM,IAAI,2BAA2B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAChE;AACD;;;;;;;;;;;AA2BA,IAAa,aAAb,cAAgC,OAAO,kBAAkB;CAIxD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,0BAA0B,MAAM,CAAC,GAAG,UAAU;EAEpD,MAAM,WAAW,IAAI,mBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,WAAW,SAAS;EAEzB,KAAK,gBAAgB,EAAE,UAAU,KAAK,SAAS,CAAC;CACjD;AACD"}
1
+ {"version":3,"file":"branch.mjs","names":[],"sources":["../../src/neon/branch.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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.\n */\nclass NeonBranchResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonBranchResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly branchId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonBranchResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonBranch — replaces Pulumi's native `provider` field. */\ntype NeonBranchOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n};\n\n/** Args for NeonBranch. */\nexport interface NeonBranchArgs {\n\t/** Branch display name. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon branch with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonBranch extends pulumi.ComponentResource {\n\t/** Neon branch ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonBranchArgs,\n\t\topts: NeonBranchOptions,\n\t) {\n\t\tconst { provider, project, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Branch\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonBranchResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.id;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;AAiDA,eAAe,iBACd,QACA,WACA,MAC8B;CAO9B,QAFc,MAJO,OAAO,IAC3B,aAAa,UAAU,UACxB,GAEqB,SAAS,MAAM,MAAM,EAAE,SAAS,IAE1C,GAAG;AACf;;;;;;;AAQA,IAAM,6BAAN,MAA4E;CAC3E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,qBAAN,cAAiC,OAAO,QAAQ,SAAS;CAGxD,YACC,MACA,MAKA,MACC;EACD,MAAM,IAAI,2BAA2B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAChE;AACD;;;;;;;;;;;AA2BA,IAAa,aAAb,cAAgC,OAAO,kBAAkB;CAIxD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,GAAG,eAAe;EAE7C,MAAM,0BAA0B,MAAM,CAAC,GAAG,UAAU;EAEpD,MAAM,WAAW,IAAI,mBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
@@ -83,8 +83,8 @@ var NeonDatabase = class extends _pulumi_pulumi.ComponentResource {
83
83
  super("infracraft:neon:Database", name, {}, pulumiOpts);
84
84
  new NeonDatabaseResource(`${name}-resource`, {
85
85
  apiKey: provider.apiKey,
86
- projectId: project.projectId,
87
- branchId: branch.branchId,
86
+ projectId: project.id,
87
+ branchId: branch.id,
88
88
  name: args.name,
89
89
  ownerName: args.ownerName
90
90
  }, { parent: this });
@@ -1 +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\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonDatabaseResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonDatabaseResource extends pulumi.dynamic.Resource {\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\townerName: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonDatabaseResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonDatabase — replaces Pulumi's native `provider` field. */\ntype NeonDatabaseOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonDatabase. */\nexport interface NeonDatabaseArgs {\n\t/** Database name. */\n\tname: pulumi.Input<string>;\n\n\t/** Owner role name. */\n\townerName: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new NeonDatabase(\"main\", {\n * name: \"neondb\",\n * ownerName: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonDatabase extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonDatabaseArgs,\n\t\topts: NeonDatabaseOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Database\", name, {}, pulumiOpts);\n\n\t\tnew NeonDatabaseResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tbranchId: branch.branchId,\n\t\t\t\tname: args.name,\n\t\t\t\townerName: args.ownerName,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;AAiDA,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,+BAAN,MAA8E;CAC7E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,uBAAN,cAAmCC,eAAO,QAAQ,SAAS;CAC1D,YACC,MACA,MAOA,MACC;EACD,MAAM,IAAI,6BAA6B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAClE;AACD;;;;;;;;;;;;AAqCA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,IAAI,qBACH,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;GACX,WAAW,KAAK;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
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\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonDatabaseResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonDatabaseResource extends pulumi.dynamic.Resource {\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\townerName: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonDatabaseResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonDatabase — replaces Pulumi's native `provider` field. */\ntype NeonDatabaseOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonDatabase. */\nexport interface NeonDatabaseArgs {\n\t/** Database name. */\n\tname: pulumi.Input<string>;\n\n\t/** Owner role name. */\n\townerName: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new NeonDatabase(\"main\", {\n * name: \"neondb\",\n * ownerName: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonDatabase extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonDatabaseArgs,\n\t\topts: NeonDatabaseOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Database\", name, {}, pulumiOpts);\n\n\t\tnew NeonDatabaseResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\tname: args.name,\n\t\t\t\townerName: args.ownerName,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;;;AAiDA,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,+BAAN,MAA8E;CAC7E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,uBAAN,cAAmCC,eAAO,QAAQ,SAAS;CAC1D,YACC,MACA,MAOA,MACC;EACD,MAAM,IAAI,6BAA6B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAClE;AACD;;;;;;;;;;;;AAqCA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,IAAI,qBACH,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;GACX,WAAW,KAAK;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -81,8 +81,8 @@ var NeonDatabase = class extends pulumi.ComponentResource {
81
81
  super("infracraft:neon:Database", name, {}, pulumiOpts);
82
82
  new NeonDatabaseResource(`${name}-resource`, {
83
83
  apiKey: provider.apiKey,
84
- projectId: project.projectId,
85
- branchId: branch.branchId,
84
+ projectId: project.id,
85
+ branchId: branch.id,
86
86
  name: args.name,
87
87
  ownerName: args.ownerName
88
88
  }, { parent: this });
@@ -1 +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\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonDatabaseResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonDatabaseResource extends pulumi.dynamic.Resource {\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\townerName: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonDatabaseResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonDatabase — replaces Pulumi's native `provider` field. */\ntype NeonDatabaseOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonDatabase. */\nexport interface NeonDatabaseArgs {\n\t/** Database name. */\n\tname: pulumi.Input<string>;\n\n\t/** Owner role name. */\n\townerName: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new NeonDatabase(\"main\", {\n * name: \"neondb\",\n * ownerName: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonDatabase extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonDatabaseArgs,\n\t\topts: NeonDatabaseOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Database\", name, {}, pulumiOpts);\n\n\t\tnew NeonDatabaseResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tbranchId: branch.branchId,\n\t\t\t\tname: args.name,\n\t\t\t\townerName: args.ownerName,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;AAiDA,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,+BAAN,MAA8E;CAC7E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,uBAAN,cAAmC,OAAO,QAAQ,SAAS;CAC1D,YACC,MACA,MAOA,MACC;EACD,MAAM,IAAI,6BAA6B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAClE;AACD;;;;;;;;;;;;AAqCA,IAAa,eAAb,cAAkC,OAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,IAAI,qBACH,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;GACX,WAAW,KAAK;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
1
+ {"version":3,"file":"database.mjs","names":[],"sources":["../../src/neon/database.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonDatabaseResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonDatabaseResource extends pulumi.dynamic.Resource {\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\townerName: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonDatabaseResourceProvider(), name, { ...args }, opts);\n\t}\n}\n\n/** Options type for NeonDatabase — replaces Pulumi's native `provider` field. */\ntype NeonDatabaseOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonDatabase. */\nexport interface NeonDatabaseArgs {\n\t/** Database name. */\n\tname: pulumi.Input<string>;\n\n\t/** Owner role name. */\n\townerName: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * new NeonDatabase(\"main\", {\n * name: \"neondb\",\n * ownerName: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonDatabase extends pulumi.ComponentResource {\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonDatabaseArgs,\n\t\topts: NeonDatabaseOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Database\", name, {}, pulumiOpts);\n\n\t\tnew NeonDatabaseResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\tname: args.name,\n\t\t\t\townerName: args.ownerName,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.registerOutputs({});\n\t}\n}\n"],"mappings":";;;;;;;;AAiDA,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,+BAAN,MAA8E;CAC7E,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;CAEA,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;CAEA,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;CAEA,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;;AAGA,IAAM,uBAAN,cAAmC,OAAO,QAAQ,SAAS;CAC1D,YACC,MACA,MAOA,MACC;EACD,MAAM,IAAI,6BAA6B,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI;CAClE;AACD;;;;;;;;;;;;AAqCA,IAAa,eAAb,cAAkC,OAAO,kBAAkB;CAC1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,IAAI,qBACH,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;GACX,WAAW,KAAK;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,gBAAgB,CAAC,CAAC;CACxB;AACD"}
@@ -125,8 +125,8 @@ var NeonEndpoint = class extends _pulumi_pulumi.ComponentResource {
125
125
  super("infracraft:neon:Endpoint", name, {}, pulumiOpts);
126
126
  const resource = new NeonEndpointResource(`${name}-resource`, {
127
127
  apiKey: provider.apiKey,
128
- projectId: project.projectId,
129
- branchId: branch.branchId,
128
+ projectId: project.id,
129
+ branchId: branch.id,
130
130
  ...args
131
131
  }, { parent: this });
132
132
  this.host = resource.host;
@@ -1 +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\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonEndpointResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonEndpointResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tminCu: pulumi.Input<number>;\n\t\t\tmaxCu: pulumi.Input<number>;\n\t\t\tsuspendTimeout: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonEndpointResourceProvider(), name, { ...args, host: undefined }, opts);\n\t}\n}\n\n/** Options type for NeonEndpoint — replaces Pulumi's native `provider` field. */\ntype NeonEndpointOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonEndpoint. */\nexport interface NeonEndpointArgs {\n\t/** Minimum compute units. */\n\tminCu: pulumi.Input<number>;\n\n\t/** Maximum compute units. */\n\tmaxCu: pulumi.Input<number>;\n\n\t/** Seconds of inactivity before suspending. */\n\tsuspendTimeout: pulumi.Input<number>;\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(\"production\", {\n * minCu: 0.25,\n * maxCu: 1,\n * suspendTimeout: 0,\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonEndpoint extends pulumi.ComponentResource {\n\t/** Endpoint hostname for connection strings. */\n\tpublic readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonEndpointArgs,\n\t\topts: NeonEndpointOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Endpoint\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonEndpointResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tbranchId: branch.branchId,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.host = resource.host;\n\n\t\tthis.registerOutputs({ host: this.host });\n\t}\n}\n"],"mappings":";;;;;;;;;;AA0DA,eAAe,qBACd,QACA,WACA,UACoD;CAKpD,MAAM,SAAQ,MAJO,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,WAC7C,GAEqB,UAAU,MAAM,MAAM,EAAE,SAAS,YAAY;CAElE,OAAO,QAAQ;EAAE,IAAI,MAAM;EAAI,MAAM,MAAM;CAAK,IAAI;AACrD;;;;;;;AAQA,IAAM,+BAAN,MAA8E;CAC7E,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAE3C,MAAM,WAAW,MAAM,qBACtB,QACA,OAAO,WACP,OAAO,QACR;EAEA,IAAI,UAAU;GACb,eAAO,IAAI,KAAK,oCAAoC,SAAS,GAAG,EAAE;GAElE,MAAM,OAAO,MACZ,aAAa,OAAO,UAAU,aAAa,SAAS,MACpD,EACC,UAAU;IACT,0BAA0B,OAAO;IACjC,0BAA0B,OAAO;IACjC,yBAAyB,OAAO;GACjC,EACD,CACD;GAEA,OAAO;IACN,IAAI,SAAS;IACb,MAAM;KAAE,GAAG;KAAQ,MAAM,SAAS;IAAK;GACxC;EACD;EAEA,MAAM,SAAS,MAAM,OAAO,KAC3B,aAAa,OAAO,UAAU,YAAY,OAAO,SAAS,aAC1D,EACC,UAAU;GACT,MAAM;GACN,0BAA0B,OAAO;GACjC,0BAA0B,OAAO;GACjC,yBAAyB,OAAO;EACjC,EACD,CACD;EAEA,OAAO;GACN,IAAI,OAAO,SAAS;GACpB,MAAM;IAAE,GAAG;IAAQ,MAAM,OAAO,SAAS;GAAK;EAC/C;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EAGvC,MAAM,SAAS,MAAM,IAFFA,+BAAW,KAAK,MAET,EAAE,MAC3B,aAAa,KAAK,UAAU,aAAa,MACzC,EACC,UAAU;GACT,0BAA0B,KAAK;GAC/B,0BAA0B,KAAK;GAC/B,yBAAyB,KAAK;EAC/B,EACD,CACD;EAEA,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,MAAM,OAAO,SAAS;EAAK,EAAE;CACxD;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,MAAM,MAEV,EAAE,IAC3B,aAAa,MAAM,UAAU,aAAa,IAC3C;EAEA,OAAO;GACN,IAAI,OAAO,SAAS;GACpB,OAAO;IACN,GAAG;IACH,MAAM,OAAO,SAAS;IACtB,OAAO,OAAO,SAAS;IACvB,OAAO,OAAO,SAAS;IACvB,gBAAgB,OAAO,SAAS;GACjC;EACD;CACD;CAEA,MAAM,OAAO,IAAY,OAA2C;EACnE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OAAO,aAAa,MAAM,UAAU,aAAa,IAAI;EACnE,QAAQ;GACP,eAAO,IAAI,KACV,yDACD;EACD;CACD;CAEA,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;EASzB,OAAO;GAAE,SALR,SAAS,SAAS,KAClB,KAAK,UAAU,KAAK,SACpB,KAAK,UAAU,KAAK,SACpB,KAAK,mBAAmB,KAAK;GAEA;GAAU,qBAAqB;EAAK;CACnE;AACD;;AAGA,IAAM,uBAAN,cAAmCC,eAAO,QAAQ,SAAS;CAG1D,YACC,MACA,MAQA,MACC;EACD,MAAM,IAAI,6BAA6B,GAAG,MAAM;GAAE,GAAG;GAAM,MAAM;EAAU,GAAG,IAAI;CACnF;AACD;;;;;;;;;;;;;;AA0CA,IAAa,eAAb,cAAkCA,eAAO,kBAAkB;CAI1D,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,4BAA4B,MAAM,CAAC,GAAG,UAAU;EAEtD,MAAM,WAAW,IAAI,qBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,GAAG;EACJ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,OAAO,SAAS;EAErB,KAAK,gBAAgB,EAAE,MAAM,KAAK,KAAK,CAAC;CACzC;AACD"}
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\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonEndpointResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonEndpointResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tminCu: pulumi.Input<number>;\n\t\t\tmaxCu: pulumi.Input<number>;\n\t\t\tsuspendTimeout: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonEndpointResourceProvider(), name, { ...args, host: undefined }, opts);\n\t}\n}\n\n/** Options type for NeonEndpoint — replaces Pulumi's native `provider` field. */\ntype NeonEndpointOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonEndpoint. */\nexport interface NeonEndpointArgs {\n\t/** Minimum compute units. */\n\tminCu: pulumi.Input<number>;\n\n\t/** Maximum compute units. */\n\tmaxCu: pulumi.Input<number>;\n\n\t/** Seconds of inactivity before suspending. */\n\tsuspendTimeout: pulumi.Input<number>;\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(\"production\", {\n * minCu: 0.25,\n * maxCu: 1,\n * suspendTimeout: 0,\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonEndpoint extends pulumi.ComponentResource {\n\t/** Endpoint hostname for connection strings. */\n\tpublic readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonEndpointArgs,\n\t\topts: NeonEndpointOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Endpoint\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonEndpointResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.host = resource.host;\n\n\t\tthis.registerOutputs({ host: this.host });\n\t}\n}\n"],"mappings":"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"}
@@ -123,8 +123,8 @@ var NeonEndpoint = class extends pulumi.ComponentResource {
123
123
  super("infracraft:neon:Endpoint", name, {}, pulumiOpts);
124
124
  const resource = new NeonEndpointResource(`${name}-resource`, {
125
125
  apiKey: provider.apiKey,
126
- projectId: project.projectId,
127
- branchId: branch.branchId,
126
+ projectId: project.id,
127
+ branchId: branch.id,
128
128
  ...args
129
129
  }, { parent: this });
130
130
  this.host = resource.host;
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.mjs","names":[],"sources":["../../src/neon/endpoint.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonEndpointResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonEndpointResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tminCu: pulumi.Input<number>;\n\t\t\tmaxCu: pulumi.Input<number>;\n\t\t\tsuspendTimeout: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonEndpointResourceProvider(), name, { ...args, host: undefined }, opts);\n\t}\n}\n\n/** Options type for NeonEndpoint — replaces Pulumi's native `provider` field. */\ntype NeonEndpointOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonEndpoint. */\nexport interface NeonEndpointArgs {\n\t/** Minimum compute units. */\n\tminCu: pulumi.Input<number>;\n\n\t/** Maximum compute units. */\n\tmaxCu: pulumi.Input<number>;\n\n\t/** Seconds of inactivity before suspending. */\n\tsuspendTimeout: pulumi.Input<number>;\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(\"production\", {\n * minCu: 0.25,\n * maxCu: 1,\n * suspendTimeout: 0,\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonEndpoint extends pulumi.ComponentResource {\n\t/** Endpoint hostname for connection strings. */\n\tpublic readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonEndpointArgs,\n\t\topts: NeonEndpointOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Endpoint\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonEndpointResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tbranchId: branch.branchId,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.host = resource.host;\n\n\t\tthis.registerOutputs({ host: this.host });\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"endpoint.mjs","names":[],"sources":["../../src/neon/endpoint.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.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 */\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 NeonEndpointResourceProvider implements pulumi.dynamic.ResourceProvider {\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\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\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\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\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/** Internal dynamic resource — not part of the public API. */\nclass NeonEndpointResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tminCu: pulumi.Input<number>;\n\t\t\tmaxCu: pulumi.Input<number>;\n\t\t\tsuspendTimeout: pulumi.Input<number>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(new NeonEndpointResourceProvider(), name, { ...args, host: undefined }, opts);\n\t}\n}\n\n/** Options type for NeonEndpoint — replaces Pulumi's native `provider` field. */\ntype NeonEndpointOptions = Omit<\n\tpulumi.ComponentResourceOptions,\n\t\"provider\"\n> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonEndpoint. */\nexport interface NeonEndpointArgs {\n\t/** Minimum compute units. */\n\tminCu: pulumi.Input<number>;\n\n\t/** Maximum compute units. */\n\tmaxCu: pulumi.Input<number>;\n\n\t/** Seconds of inactivity before suspending. */\n\tsuspendTimeout: pulumi.Input<number>;\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(\"production\", {\n * minCu: 0.25,\n * maxCu: 1,\n * suspendTimeout: 0,\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonEndpoint extends pulumi.ComponentResource {\n\t/** Endpoint hostname for connection strings. */\n\tpublic readonly host: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonEndpointArgs,\n\t\topts: NeonEndpointOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Endpoint\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonEndpointResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\t...args,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.host = resource.host;\n\n\t\tthis.registerOutputs({ host: this.host });\n\t}\n}\n"],"mappings":"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"}
@@ -99,8 +99,8 @@ var NeonProject = class extends _pulumi_pulumi.ComponentResource {
99
99
  name: args.name,
100
100
  orgId: provider.orgId
101
101
  }, { parent: this });
102
- this.projectId = resource.projectId;
103
- this.registerOutputs({ projectId: this.projectId });
102
+ this.id = resource.projectId;
103
+ this.registerOutputs({ id: this.id });
104
104
  }
105
105
  };
106
106
 
@@ -1 +1 @@
1
- {"version":3,"file":"project.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/project.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon project dynamic provider. */\nexport interface NeonProjectInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Exact project display name to adopt or create. */\n\tname: string;\n\n\t/** Optional Neon organization ID to scope the project search. */\n\torgId?: string;\n}\n\n/** Persisted state for the Neon project. */\ninterface NeonProjectOutputs extends NeonProjectInputs {\n\t/** Neon-assigned project ID (e.g. `\"quiet-forest-69719462\"`). */\n\tprojectId: string;\n}\n\n/** Neon API response for listing projects. */\ninterface ProjectListResponse {\n\tprojects: Array<{ id: string; name: string }>;\n}\n\n/** Neon API response for project creation. */\ninterface ProjectCreateResponse {\n\tproject: { id: string; name: string };\n}\n\n/** Neon API response for reading a single project. */\ninterface ProjectReadResponse {\n\tproject: { id: string; name: string };\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Neon projects.\n *\n * On `create()`, queries `GET /projects` and performs an exact name match.\n * If found, adopts the existing project. If not, creates a new one via\n * `POST /projects`. Deletion is a no-op to protect production databases.\n */\nclass NeonProjectResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(\n\t\tinputs: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst query = inputs.orgId\n\t\t\t? `/projects?org_id=${inputs.orgId}&search=${encodeURIComponent(inputs.name)}`\n\t\t\t: \"/projects\";\n\n\t\tconst result = await client.get<ProjectListResponse>(query);\n\n\t\tconst existing = result.projects.find((p) => p.name === inputs.name);\n\n\t\tlet projectId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Neon project \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tprojectId = existing.id;\n\t\t} else {\n\t\t\tpulumi.log.info(`Neon project \"${inputs.name}\" not found — creating...`);\n\n\t\t\tconst created = await client.post<ProjectCreateResponse>(\"/projects\", {\n\t\t\t\tproject: { name: inputs.name },\n\t\t\t});\n\n\t\t\tprojectId = created.project.id;\n\t\t}\n\n\t\tconst outs: NeonProjectOutputs = { ...inputs, projectId };\n\n\t\treturn { id: projectId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonProjectOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<ProjectReadResponse>(`/projects/${id}`);\n\n\t\treturn {\n\t\t\tid: result.project.id,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: result.project.name,\n\t\t\t\tprojectId: result.project.id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst client = new NeonClient(news.apiKey);\n\n\t\tawait client.patch(`/projects/${id}`, {\n\t\t\tproject: { name: news.name },\n\t\t});\n\n\t\treturn { outs: { ...news, projectId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Neon project deletion skipped — projects are not deleted by Pulumi\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\t\tconst changes: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\tchanges.push(\"name\");\n\t\t}\n\n\t\tif (olds.orgId !== news.orgId) {\n\t\t\treplaces.push(\"orgId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || changes.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonProjectResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torgId?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonProjectResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, projectId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonProject — replaces Pulumi's native `provider` field. */\ntype NeonProjectOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n};\n\n/** Args for NeonProject. */\nexport interface NeonProjectArgs {\n\t/** Exact project display name to adopt or create. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon project with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const project = new NeonProject(\"db\", {\n * name: \"my-app\",\n * }, { provider });\n *\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonProject extends pulumi.ComponentResource {\n\t/** Neon-assigned project ID. */\n\tpublic readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonProjectArgs,\n\t\topts: NeonProjectOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Project\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonProjectResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tname: args.name,\n\t\t\t\torgId: provider.orgId,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.projectId = resource.projectId;\n\n\t\tthis.registerOutputs({ projectId: this.projectId });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;AA4CA,IAAM,8BAAN,MAA6E;CAC5E,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAE3C,MAAM,QAAQ,OAAO,QAClB,oBAAoB,OAAO,MAAM,UAAU,mBAAmB,OAAO,IAAI,MACzE;EAIH,MAAM,YAAW,MAFI,OAAO,IAAyB,KAAK,GAElC,SAAS,MAAM,MAAM,EAAE,SAAS,OAAO,IAAI;EAEnE,IAAI;EAEJ,IAAI,UAAU;GACb,eAAO,IAAI,KACV,mCAAmC,OAAO,KAAK,KAAK,SAAS,GAAG,EACjE;GAEA,YAAY,SAAS;EACtB,OAAO;GACN,eAAO,IAAI,KAAK,iBAAiB,OAAO,KAAK,0BAA0B;GAMvE,aAAY,MAJU,OAAO,KAA4B,aAAa,EACrE,SAAS,EAAE,MAAM,OAAO,KAAK,EAC9B,CAAC,GAEmB,QAAQ;EAC7B;EAEA,MAAM,OAA2B;GAAE,GAAG;GAAQ;EAAU;EAExD,OAAO;GAAE,IAAI;GAAW;EAAK;CAC9B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,MAAM,MAEV,EAAE,IAAyB,aAAa,IAAI;EAEtE,OAAO;GACN,IAAI,OAAO,QAAQ;GACnB,OAAO;IACN,GAAG;IACH,MAAM,OAAO,QAAQ;IACrB,WAAW,OAAO,QAAQ;GAC3B;EACD;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EAGvC,MAAM,IAFaA,+BAAW,KAAK,MAExB,EAAE,MAAM,aAAa,MAAM,EACrC,SAAS,EAAE,MAAM,KAAK,KAAK,EAC5B,CAAC;EAED,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,WAAW;EAAG,EAAE;CAC3C;CAEA,MAAM,SAAwB;EAC7B,eAAO,IAAI,KACV,oEACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAC5B,MAAM,UAAoB,CAAC;EAE3B,IAAI,KAAK,SAAS,KAAK,MACtB,QAAQ,KAAK,MAAM;EAGpB,IAAI,KAAK,UAAU,KAAK,OACvB,SAAS,KAAK,OAAO;EAGtB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS;GACjD;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,sBAAN,cAAkCC,eAAO,QAAQ,SAAS;CAGzD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,4BAA4B,GAChC,MACA;GAAE,GAAG;GAAM,WAAW;EAAU,GAChC,IACD;CACD;AACD;;;;;;;;;;;;;;;AA4BA,IAAa,cAAb,cAAiCA,eAAO,kBAAkB;CAIzD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,2BAA2B,MAAM,CAAC,GAAG,UAAU;EAErD,MAAM,WAAW,IAAI,oBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,MAAM,KAAK;GACX,OAAO,SAAS;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,YAAY,SAAS;EAE1B,KAAK,gBAAgB,EAAE,WAAW,KAAK,UAAU,CAAC;CACnD;AACD"}
1
+ {"version":3,"file":"project.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/project.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon project dynamic provider. */\nexport interface NeonProjectInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Exact project display name to adopt or create. */\n\tname: string;\n\n\t/** Optional Neon organization ID to scope the project search. */\n\torgId?: string;\n}\n\n/** Persisted state for the Neon project. */\ninterface NeonProjectOutputs extends NeonProjectInputs {\n\t/** Neon-assigned project ID (e.g. `\"quiet-forest-69719462\"`). */\n\tprojectId: string;\n}\n\n/** Neon API response for listing projects. */\ninterface ProjectListResponse {\n\tprojects: Array<{ id: string; name: string }>;\n}\n\n/** Neon API response for project creation. */\ninterface ProjectCreateResponse {\n\tproject: { id: string; name: string };\n}\n\n/** Neon API response for reading a single project. */\ninterface ProjectReadResponse {\n\tproject: { id: string; name: string };\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Neon projects.\n *\n * On `create()`, queries `GET /projects` and performs an exact name match.\n * If found, adopts the existing project. If not, creates a new one via\n * `POST /projects`. Deletion is a no-op to protect production databases.\n */\nclass NeonProjectResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(\n\t\tinputs: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst query = inputs.orgId\n\t\t\t? `/projects?org_id=${inputs.orgId}&search=${encodeURIComponent(inputs.name)}`\n\t\t\t: \"/projects\";\n\n\t\tconst result = await client.get<ProjectListResponse>(query);\n\n\t\tconst existing = result.projects.find((p) => p.name === inputs.name);\n\n\t\tlet projectId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Neon project \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tprojectId = existing.id;\n\t\t} else {\n\t\t\tpulumi.log.info(`Neon project \"${inputs.name}\" not found — creating...`);\n\n\t\t\tconst created = await client.post<ProjectCreateResponse>(\"/projects\", {\n\t\t\t\tproject: { name: inputs.name },\n\t\t\t});\n\n\t\t\tprojectId = created.project.id;\n\t\t}\n\n\t\tconst outs: NeonProjectOutputs = { ...inputs, projectId };\n\n\t\treturn { id: projectId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonProjectOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<ProjectReadResponse>(`/projects/${id}`);\n\n\t\treturn {\n\t\t\tid: result.project.id,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: result.project.name,\n\t\t\t\tprojectId: result.project.id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst client = new NeonClient(news.apiKey);\n\n\t\tawait client.patch(`/projects/${id}`, {\n\t\t\tproject: { name: news.name },\n\t\t});\n\n\t\treturn { outs: { ...news, projectId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Neon project deletion skipped — projects are not deleted by Pulumi\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\t\tconst changes: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\tchanges.push(\"name\");\n\t\t}\n\n\t\tif (olds.orgId !== news.orgId) {\n\t\t\treplaces.push(\"orgId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || changes.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonProjectResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torgId?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonProjectResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, projectId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonProject — replaces Pulumi's native `provider` field. */\ntype NeonProjectOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n};\n\n/** Args for NeonProject. */\nexport interface NeonProjectArgs {\n\t/** Exact project display name to adopt or create. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon project with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const project = new NeonProject(\"db\", {\n * name: \"my-app\",\n * }, { provider });\n *\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonProject extends pulumi.ComponentResource {\n\t/** Neon-assigned project ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonProjectArgs,\n\t\topts: NeonProjectOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Project\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonProjectResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tname: args.name,\n\t\t\t\torgId: provider.orgId,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.projectId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;AA4CA,IAAM,8BAAN,MAA6E;CAC5E,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAE3C,MAAM,QAAQ,OAAO,QAClB,oBAAoB,OAAO,MAAM,UAAU,mBAAmB,OAAO,IAAI,MACzE;EAIH,MAAM,YAAW,MAFI,OAAO,IAAyB,KAAK,GAElC,SAAS,MAAM,MAAM,EAAE,SAAS,OAAO,IAAI;EAEnE,IAAI;EAEJ,IAAI,UAAU;GACb,eAAO,IAAI,KACV,mCAAmC,OAAO,KAAK,KAAK,SAAS,GAAG,EACjE;GAEA,YAAY,SAAS;EACtB,OAAO;GACN,eAAO,IAAI,KAAK,iBAAiB,OAAO,KAAK,0BAA0B;GAMvE,aAAY,MAJU,OAAO,KAA4B,aAAa,EACrE,SAAS,EAAE,MAAM,OAAO,KAAK,EAC9B,CAAC,GAEmB,QAAQ;EAC7B;EAEA,MAAM,OAA2B;GAAE,GAAG;GAAQ;EAAU;EAExD,OAAO;GAAE,IAAI;GAAW;EAAK;CAC9B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFFA,+BAAW,MAAM,MAEV,EAAE,IAAyB,aAAa,IAAI;EAEtE,OAAO;GACN,IAAI,OAAO,QAAQ;GACnB,OAAO;IACN,GAAG;IACH,MAAM,OAAO,QAAQ;IACrB,WAAW,OAAO,QAAQ;GAC3B;EACD;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EAGvC,MAAM,IAFaA,+BAAW,KAAK,MAExB,EAAE,MAAM,aAAa,MAAM,EACrC,SAAS,EAAE,MAAM,KAAK,KAAK,EAC5B,CAAC;EAED,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,WAAW;EAAG,EAAE;CAC3C;CAEA,MAAM,SAAwB;EAC7B,eAAO,IAAI,KACV,oEACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAC5B,MAAM,UAAoB,CAAC;EAE3B,IAAI,KAAK,SAAS,KAAK,MACtB,QAAQ,KAAK,MAAM;EAGpB,IAAI,KAAK,UAAU,KAAK,OACvB,SAAS,KAAK,OAAO;EAGtB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS;GACjD;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,sBAAN,cAAkCC,eAAO,QAAQ,SAAS;CAGzD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,4BAA4B,GAChC,MACA;GAAE,GAAG;GAAM,WAAW;EAAU,GAChC,IACD;CACD;AACD;;;;;;;;;;;;;;;AA4BA,IAAa,cAAb,cAAiCA,eAAO,kBAAkB;CAIzD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,2BAA2B,MAAM,CAAC,GAAG,UAAU;EAErD,MAAM,WAAW,IAAI,oBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,MAAM,KAAK;GACX,OAAO,SAAS;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
@@ -37,7 +37,7 @@ interface NeonProjectArgs {
37
37
  */
38
38
  declare class NeonProject extends pulumi.ComponentResource {
39
39
  /** Neon-assigned project ID. */
40
- readonly projectId: pulumi.Output<string>;
40
+ readonly id: pulumi.Output<string>;
41
41
  constructor(name: string, args: NeonProjectArgs, opts: NeonProjectOptions);
42
42
  }
43
43
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.cts","names":[],"sources":["../../src/neon/project.ts"],"mappings":";;;;;;UAKiB,iBAAA;;EAEhB,MAAA;EAFiC;EAKjC,IAAA;EALiC;EAQjC,KAAA;AAAA;;KAyJI,kBAAA,GAAqB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAzJhC,mCA2JL,QAAA,EAAU,YAAA;AAAA;;UAIM,eAAA;EANS;EAQzB,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;AANI;AAIvB;;;;;;cAmBa,WAAA,SAAoB,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBF,SAAA,EAAW,MAAA,CAAO,MAAA;cAGjC,IAAA,UACA,IAAA,EAAM,eAAA,EACN,IAAA,EAAM,kBAAA;AAAA"}
1
+ {"version":3,"file":"project.d.cts","names":[],"sources":["../../src/neon/project.ts"],"mappings":";;;;;;UAKiB,iBAAA;;EAEhB,MAAA;EAFiC;EAKjC,IAAA;EALiC;EAQjC,KAAA;AAAA;;KAyJI,kBAAA,GAAqB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAzJhC,mCA2JL,QAAA,EAAU,YAAA;AAAA;;UAIM,eAAA;EANS;EAQzB,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;AANI;AAIvB;;;;;;cAmBa,WAAA,SAAoB,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBF,EAAA,EAAI,MAAA,CAAO,MAAA;cAG1B,IAAA,UACA,IAAA,EAAM,eAAA,EACN,IAAA,EAAM,kBAAA;AAAA"}
@@ -37,7 +37,7 @@ interface NeonProjectArgs {
37
37
  */
38
38
  declare class NeonProject extends pulumi.ComponentResource {
39
39
  /** Neon-assigned project ID. */
40
- readonly projectId: pulumi.Output<string>;
40
+ readonly id: pulumi.Output<string>;
41
41
  constructor(name: string, args: NeonProjectArgs, opts: NeonProjectOptions);
42
42
  }
43
43
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"project.d.mts","names":[],"sources":["../../src/neon/project.ts"],"mappings":";;;;;;UAKiB,iBAAA;;EAEhB,MAAA;EAFiC;EAKjC,IAAA;EALiC;EAQjC,KAAA;AAAA;;KAyJI,kBAAA,GAAqB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAzJhC,mCA2JL,QAAA,EAAU,YAAA;AAAA;;UAIM,eAAA;EANS;EAQzB,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;AANI;AAIvB;;;;;;cAmBa,WAAA,SAAoB,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBF,SAAA,EAAW,MAAA,CAAO,MAAA;cAGjC,IAAA,UACA,IAAA,EAAM,eAAA,EACN,IAAA,EAAM,kBAAA;AAAA"}
1
+ {"version":3,"file":"project.d.mts","names":[],"sources":["../../src/neon/project.ts"],"mappings":";;;;;;UAKiB,iBAAA;;EAEhB,MAAA;EAFiC;EAKjC,IAAA;EALiC;EAQjC,KAAA;AAAA;;KAyJI,kBAAA,GAAqB,IAAA,CAAK,MAAA,CAAO,wBAAA;EAzJhC,mCA2JL,QAAA,EAAU,YAAA;AAAA;;UAIM,eAAA;EANS;EAQzB,IAAA,EAAM,MAAA,CAAO,KAAK;AAAA;;;;;;;;AANI;AAIvB;;;;;;cAmBa,WAAA,SAAoB,MAAA,CAAO,iBAAA;EAjBrB;EAAA,SAmBF,EAAA,EAAI,MAAA,CAAO,MAAA;cAG1B,IAAA,UACA,IAAA,EAAM,eAAA,EACN,IAAA,EAAM,kBAAA;AAAA"}
@@ -97,8 +97,8 @@ var NeonProject = class extends pulumi.ComponentResource {
97
97
  name: args.name,
98
98
  orgId: provider.orgId
99
99
  }, { parent: this });
100
- this.projectId = resource.projectId;
101
- this.registerOutputs({ projectId: this.projectId });
100
+ this.id = resource.projectId;
101
+ this.registerOutputs({ id: this.id });
102
102
  }
103
103
  };
104
104
 
@@ -1 +1 @@
1
- {"version":3,"file":"project.mjs","names":[],"sources":["../../src/neon/project.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon project dynamic provider. */\nexport interface NeonProjectInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Exact project display name to adopt or create. */\n\tname: string;\n\n\t/** Optional Neon organization ID to scope the project search. */\n\torgId?: string;\n}\n\n/** Persisted state for the Neon project. */\ninterface NeonProjectOutputs extends NeonProjectInputs {\n\t/** Neon-assigned project ID (e.g. `\"quiet-forest-69719462\"`). */\n\tprojectId: string;\n}\n\n/** Neon API response for listing projects. */\ninterface ProjectListResponse {\n\tprojects: Array<{ id: string; name: string }>;\n}\n\n/** Neon API response for project creation. */\ninterface ProjectCreateResponse {\n\tproject: { id: string; name: string };\n}\n\n/** Neon API response for reading a single project. */\ninterface ProjectReadResponse {\n\tproject: { id: string; name: string };\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Neon projects.\n *\n * On `create()`, queries `GET /projects` and performs an exact name match.\n * If found, adopts the existing project. If not, creates a new one via\n * `POST /projects`. Deletion is a no-op to protect production databases.\n */\nclass NeonProjectResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(\n\t\tinputs: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst query = inputs.orgId\n\t\t\t? `/projects?org_id=${inputs.orgId}&search=${encodeURIComponent(inputs.name)}`\n\t\t\t: \"/projects\";\n\n\t\tconst result = await client.get<ProjectListResponse>(query);\n\n\t\tconst existing = result.projects.find((p) => p.name === inputs.name);\n\n\t\tlet projectId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Neon project \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tprojectId = existing.id;\n\t\t} else {\n\t\t\tpulumi.log.info(`Neon project \"${inputs.name}\" not found — creating...`);\n\n\t\t\tconst created = await client.post<ProjectCreateResponse>(\"/projects\", {\n\t\t\t\tproject: { name: inputs.name },\n\t\t\t});\n\n\t\t\tprojectId = created.project.id;\n\t\t}\n\n\t\tconst outs: NeonProjectOutputs = { ...inputs, projectId };\n\n\t\treturn { id: projectId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonProjectOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<ProjectReadResponse>(`/projects/${id}`);\n\n\t\treturn {\n\t\t\tid: result.project.id,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: result.project.name,\n\t\t\t\tprojectId: result.project.id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst client = new NeonClient(news.apiKey);\n\n\t\tawait client.patch(`/projects/${id}`, {\n\t\t\tproject: { name: news.name },\n\t\t});\n\n\t\treturn { outs: { ...news, projectId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Neon project deletion skipped — projects are not deleted by Pulumi\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\t\tconst changes: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\tchanges.push(\"name\");\n\t\t}\n\n\t\tif (olds.orgId !== news.orgId) {\n\t\t\treplaces.push(\"orgId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || changes.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonProjectResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torgId?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonProjectResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, projectId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonProject — replaces Pulumi's native `provider` field. */\ntype NeonProjectOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n};\n\n/** Args for NeonProject. */\nexport interface NeonProjectArgs {\n\t/** Exact project display name to adopt or create. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon project with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const project = new NeonProject(\"db\", {\n * name: \"my-app\",\n * }, { provider });\n *\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonProject extends pulumi.ComponentResource {\n\t/** Neon-assigned project ID. */\n\tpublic readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonProjectArgs,\n\t\topts: NeonProjectOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Project\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonProjectResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tname: args.name,\n\t\t\t\torgId: provider.orgId,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.projectId = resource.projectId;\n\n\t\tthis.registerOutputs({ projectId: this.projectId });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;AA4CA,IAAM,8BAAN,MAA6E;CAC5E,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAI,WAAW,OAAO,MAAM;EAE3C,MAAM,QAAQ,OAAO,QAClB,oBAAoB,OAAO,MAAM,UAAU,mBAAmB,OAAO,IAAI,MACzE;EAIH,MAAM,YAAW,MAFI,OAAO,IAAyB,KAAK,GAElC,SAAS,MAAM,MAAM,EAAE,SAAS,OAAO,IAAI;EAEnE,IAAI;EAEJ,IAAI,UAAU;GACb,OAAO,IAAI,KACV,mCAAmC,OAAO,KAAK,KAAK,SAAS,GAAG,EACjE;GAEA,YAAY,SAAS;EACtB,OAAO;GACN,OAAO,IAAI,KAAK,iBAAiB,OAAO,KAAK,0BAA0B;GAMvE,aAAY,MAJU,OAAO,KAA4B,aAAa,EACrE,SAAS,EAAE,MAAM,OAAO,KAAK,EAC9B,CAAC,GAEmB,QAAQ;EAC7B;EAEA,MAAM,OAA2B;GAAE,GAAG;GAAQ;EAAU;EAExD,OAAO;GAAE,IAAI;GAAW;EAAK;CAC9B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFF,WAAW,MAAM,MAEV,EAAE,IAAyB,aAAa,IAAI;EAEtE,OAAO;GACN,IAAI,OAAO,QAAQ;GACnB,OAAO;IACN,GAAG;IACH,MAAM,OAAO,QAAQ;IACrB,WAAW,OAAO,QAAQ;GAC3B;EACD;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EAGvC,MAAM,IAFa,WAAW,KAAK,MAExB,EAAE,MAAM,aAAa,MAAM,EACrC,SAAS,EAAE,MAAM,KAAK,KAAK,EAC5B,CAAC;EAED,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,WAAW;EAAG,EAAE;CAC3C;CAEA,MAAM,SAAwB;EAC7B,OAAO,IAAI,KACV,oEACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAC5B,MAAM,UAAoB,CAAC;EAE3B,IAAI,KAAK,SAAS,KAAK,MACtB,QAAQ,KAAK,MAAM;EAGpB,IAAI,KAAK,UAAU,KAAK,OACvB,SAAS,KAAK,OAAO;EAGtB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS;GACjD;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,sBAAN,cAAkC,OAAO,QAAQ,SAAS;CAGzD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,4BAA4B,GAChC,MACA;GAAE,GAAG;GAAM,WAAW;EAAU,GAChC,IACD;CACD;AACD;;;;;;;;;;;;;;;AA4BA,IAAa,cAAb,cAAiC,OAAO,kBAAkB;CAIzD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,2BAA2B,MAAM,CAAC,GAAG,UAAU;EAErD,MAAM,WAAW,IAAI,oBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,MAAM,KAAK;GACX,OAAO,SAAS;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,YAAY,SAAS;EAE1B,KAAK,gBAAgB,EAAE,WAAW,KAAK,UAAU,CAAC;CACnD;AACD"}
1
+ {"version":3,"file":"project.mjs","names":[],"sources":["../../src/neon/project.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon project dynamic provider. */\nexport interface NeonProjectInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Exact project display name to adopt or create. */\n\tname: string;\n\n\t/** Optional Neon organization ID to scope the project search. */\n\torgId?: string;\n}\n\n/** Persisted state for the Neon project. */\ninterface NeonProjectOutputs extends NeonProjectInputs {\n\t/** Neon-assigned project ID (e.g. `\"quiet-forest-69719462\"`). */\n\tprojectId: string;\n}\n\n/** Neon API response for listing projects. */\ninterface ProjectListResponse {\n\tprojects: Array<{ id: string; name: string }>;\n}\n\n/** Neon API response for project creation. */\ninterface ProjectCreateResponse {\n\tproject: { id: string; name: string };\n}\n\n/** Neon API response for reading a single project. */\ninterface ProjectReadResponse {\n\tproject: { id: string; name: string };\n}\n\n/**\n * Dynamic provider implementing adopt-or-create for Neon projects.\n *\n * On `create()`, queries `GET /projects` and performs an exact name match.\n * If found, adopts the existing project. If not, creates a new one via\n * `POST /projects`. Deletion is a no-op to protect production databases.\n */\nclass NeonProjectResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(\n\t\tinputs: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst query = inputs.orgId\n\t\t\t? `/projects?org_id=${inputs.orgId}&search=${encodeURIComponent(inputs.name)}`\n\t\t\t: \"/projects\";\n\n\t\tconst result = await client.get<ProjectListResponse>(query);\n\n\t\tconst existing = result.projects.find((p) => p.name === inputs.name);\n\n\t\tlet projectId: string;\n\n\t\tif (existing) {\n\t\t\tpulumi.log.info(\n\t\t\t\t`Adopting existing Neon project \"${inputs.name}\" (${existing.id})`,\n\t\t\t);\n\n\t\t\tprojectId = existing.id;\n\t\t} else {\n\t\t\tpulumi.log.info(`Neon project \"${inputs.name}\" not found — creating...`);\n\n\t\t\tconst created = await client.post<ProjectCreateResponse>(\"/projects\", {\n\t\t\t\tproject: { name: inputs.name },\n\t\t\t});\n\n\t\t\tprojectId = created.project.id;\n\t\t}\n\n\t\tconst outs: NeonProjectOutputs = { ...inputs, projectId };\n\n\t\treturn { id: projectId, outs };\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonProjectOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst result = await client.get<ProjectReadResponse>(`/projects/${id}`);\n\n\t\treturn {\n\t\t\tid: result.project.id,\n\t\t\tprops: {\n\t\t\t\t...props,\n\t\t\t\tname: result.project.name,\n\t\t\t\tprojectId: result.project.id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync update(\n\t\tid: string,\n\t\t_olds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.UpdateResult> {\n\t\tconst client = new NeonClient(news.apiKey);\n\n\t\tawait client.patch(`/projects/${id}`, {\n\t\t\tproject: { name: news.name },\n\t\t});\n\n\t\treturn { outs: { ...news, projectId: id } };\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tpulumi.log.warn(\n\t\t\t\"Neon project deletion skipped — projects are not deleted by Pulumi\",\n\t\t);\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonProjectOutputs,\n\t\tnews: NeonProjectInputs,\n\t): Promise<pulumi.dynamic.DiffResult> {\n\t\tconst replaces: string[] = [];\n\t\tconst changes: string[] = [];\n\n\t\tif (olds.name !== news.name) {\n\t\t\tchanges.push(\"name\");\n\t\t}\n\n\t\tif (olds.orgId !== news.orgId) {\n\t\t\treplaces.push(\"orgId\");\n\t\t}\n\n\t\treturn {\n\t\t\tchanges: replaces.length > 0 || changes.length > 0,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonProjectResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly projectId: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t\torgId?: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonProjectResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, projectId: undefined },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonProject — replaces Pulumi's native `provider` field. */\ntype NeonProjectOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n};\n\n/** Args for NeonProject. */\nexport interface NeonProjectArgs {\n\t/** Exact project display name to adopt or create. */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon project with adopt-or-create semantics.\n *\n * @example\n * ```typescript\n * const project = new NeonProject(\"db\", {\n * name: \"my-app\",\n * }, { provider });\n *\n * const branch = new NeonBranch(\"production\", {\n * name: \"production\",\n * }, { provider, project });\n * ```\n */\nexport class NeonProject extends pulumi.ComponentResource {\n\t/** Neon-assigned project ID. */\n\tpublic readonly id: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonProjectArgs,\n\t\topts: NeonProjectOptions,\n\t) {\n\t\tconst { provider, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Project\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonProjectResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tname: args.name,\n\t\t\t\torgId: provider.orgId,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.id = resource.projectId;\n\n\t\tthis.registerOutputs({ id: this.id });\n\t}\n}\n"],"mappings":";;;;;;;;;;;;AA4CA,IAAM,8BAAN,MAA6E;CAC5E,MAAM,OACL,QACuC;EACvC,MAAM,SAAS,IAAI,WAAW,OAAO,MAAM;EAE3C,MAAM,QAAQ,OAAO,QAClB,oBAAoB,OAAO,MAAM,UAAU,mBAAmB,OAAO,IAAI,MACzE;EAIH,MAAM,YAAW,MAFI,OAAO,IAAyB,KAAK,GAElC,SAAS,MAAM,MAAM,EAAE,SAAS,OAAO,IAAI;EAEnE,IAAI;EAEJ,IAAI,UAAU;GACb,OAAO,IAAI,KACV,mCAAmC,OAAO,KAAK,KAAK,SAAS,GAAG,EACjE;GAEA,YAAY,SAAS;EACtB,OAAO;GACN,OAAO,IAAI,KAAK,iBAAiB,OAAO,KAAK,0BAA0B;GAMvE,aAAY,MAJU,OAAO,KAA4B,aAAa,EACrE,SAAS,EAAE,MAAM,OAAO,KAAK,EAC9B,CAAC,GAEmB,QAAQ;EAC7B;EAEA,MAAM,OAA2B;GAAE,GAAG;GAAQ;EAAU;EAExD,OAAO;GAAE,IAAI;GAAW;EAAK;CAC9B;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,SAAS,MAAM,IAFF,WAAW,MAAM,MAEV,EAAE,IAAyB,aAAa,IAAI;EAEtE,OAAO;GACN,IAAI,OAAO,QAAQ;GACnB,OAAO;IACN,GAAG;IACH,MAAM,OAAO,QAAQ;IACrB,WAAW,OAAO,QAAQ;GAC3B;EACD;CACD;CAEA,MAAM,OACL,IACA,OACA,MACuC;EAGvC,MAAM,IAFa,WAAW,KAAK,MAExB,EAAE,MAAM,aAAa,MAAM,EACrC,SAAS,EAAE,MAAM,KAAK,KAAK,EAC5B,CAAC;EAED,OAAO,EAAE,MAAM;GAAE,GAAG;GAAM,WAAW;EAAG,EAAE;CAC3C;CAEA,MAAM,SAAwB;EAC7B,OAAO,IAAI,KACV,oEACD;CACD;CAEA,MAAM,KACL,KACA,MACA,MACqC;EACrC,MAAM,WAAqB,CAAC;EAC5B,MAAM,UAAoB,CAAC;EAE3B,IAAI,KAAK,SAAS,KAAK,MACtB,QAAQ,KAAK,MAAM;EAGpB,IAAI,KAAK,UAAU,KAAK,OACvB,SAAS,KAAK,OAAO;EAGtB,OAAO;GACN,SAAS,SAAS,SAAS,KAAK,QAAQ,SAAS;GACjD;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,sBAAN,cAAkC,OAAO,QAAQ,SAAS;CAGzD,YACC,MACA,MAKA,MACC;EACD,MACC,IAAI,4BAA4B,GAChC,MACA;GAAE,GAAG;GAAM,WAAW;EAAU,GAChC,IACD;CACD;AACD;;;;;;;;;;;;;;;AA4BA,IAAa,cAAb,cAAiC,OAAO,kBAAkB;CAIzD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,GAAG,eAAe;EAEpC,MAAM,2BAA2B,MAAM,CAAC,GAAG,UAAU;EAErD,MAAM,WAAW,IAAI,oBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,MAAM,KAAK;GACX,OAAO,SAAS;EACjB,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,KAAK,SAAS;EAEnB,KAAK,gBAAgB,EAAE,IAAI,KAAK,GAAG,CAAC;CACrC;AACD"}
@@ -93,8 +93,8 @@ var NeonRole = class extends _pulumi_pulumi.ComponentResource {
93
93
  super("infracraft:neon:Role", name, {}, pulumiOpts);
94
94
  const resource = new NeonRoleResource(`${name}-resource`, {
95
95
  apiKey: provider.apiKey,
96
- projectId: project.projectId,
97
- branchId: branch.branchId,
96
+ projectId: project.id,
97
+ branchId: branch.id,
98
98
  name: args.name
99
99
  }, { parent: this });
100
100
  this.password = resource.password;
@@ -1 +1 @@
1
- {"version":3,"file":"role.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/role.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon role dynamic provider. */\nexport interface NeonRoleInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Neon project ID. */\n\tprojectId: string;\n\n\t/** Branch ID the role belongs to. */\n\tbranchId: string;\n\n\t/** Role name (e.g. `\"neondb_owner\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Neon role. */\ninterface NeonRoleOutputs extends NeonRoleInputs {\n\t/** Role password (auto-generated by Neon). */\n\tpassword: string;\n}\n\n/** Neon API response for the reveal_password endpoint. */\ninterface PasswordResponse {\n\tpassword: string;\n}\n\n/** Neon API response for listing roles. */\ninterface RoleListResponse {\n\troles: Array<{\n\t\tname: string;\n\t}>;\n}\n\n/**\n * Checks if a role exists by name on a branch.\n */\nasync function roleExists(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n\tname: string,\n): Promise<boolean> {\n\tconst result = await client.get<RoleListResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/roles`,\n\t);\n\n\treturn result.roles.some((r) => r.name === name);\n}\n\n/**\n * Reveals the password for an existing role via the dedicated API endpoint.\n */\nasync function revealPassword(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n\tname: string,\n): Promise<string> {\n\tconst result = await client.get<PasswordResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/roles/${name}/reveal_password`,\n\t);\n\n\treturn result.password;\n}\n\n/**\n * Dynamic provider implementing CRUD for Neon database roles.\n *\n * Uses adopt-or-create on `create()`: finds an existing role by name\n * before creating a new one.\n */\nclass NeonRoleResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: NeonRoleInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst exists = await roleExists(\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\tawait client.post(\n\t\t\t\t`/projects/${inputs.projectId}/branches/${inputs.branchId}/roles`,\n\t\t\t\t{ role: { name: inputs.name } },\n\t\t\t);\n\t\t} else {\n\t\t\tpulumi.log.info(`Adopting existing Neon role \"${inputs.name}\"`);\n\t\t}\n\n\t\tconst password = await revealPassword(\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\treturn {\n\t\t\tid: `${inputs.branchId}/${inputs.name}`,\n\t\t\touts: { ...inputs, password },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonRoleOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst password = await revealPassword(\n\t\t\tclient,\n\t\t\tprops.projectId,\n\t\t\tprops.branchId,\n\t\t\tprops.name,\n\t\t);\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: { ...props, password },\n\t\t};\n\t}\n\n\tasync delete(_id: string, props: NeonRoleOutputs): 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}/roles/${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 role \"${props.name}\" (may already be deleted)`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonRoleOutputs,\n\t\tnews: NeonRoleInputs,\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,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonRoleResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly password: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonRoleResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, password: pulumi.secret(undefined as unknown as string) },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonRole — replaces Pulumi's native `provider` field. */\ntype NeonRoleOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonRole. */\nexport interface NeonRoleArgs {\n\t/** Role name (e.g. `\"neondb_owner\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database role with adopt-or-create semantics.\n * Exposes `password` as a secret output for connection string composition.\n *\n * @example\n * ```typescript\n * const role = new NeonRole(\"owner\", {\n * name: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonRole extends pulumi.ComponentResource {\n\t/** Role password (secret). */\n\tpublic readonly password: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonRoleArgs,\n\t\topts: NeonRoleOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Role\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonRoleResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.projectId,\n\t\t\t\tbranchId: branch.branchId,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.password = resource.password;\n\n\t\tthis.registerOutputs({ password: this.password });\n\t}\n}\n"],"mappings":";;;;;;;;;;AA0CA,eAAe,WACd,QACA,WACA,UACA,MACmB;CAKnB,QAAO,MAJc,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,OAC7C,GAEc,MAAM,MAAM,MAAM,EAAE,SAAS,IAAI;AAChD;;;;AAKA,eAAe,eACd,QACA,WACA,UACA,MACkB;CAKlB,QAAO,MAJc,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,SAAS,KAAK,iBAC3D,GAEc;AACf;;;;;;;AAQA,IAAM,2BAAN,MAA0E;CACzE,MAAM,OAAO,QAA8D;EAC1E,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAS3C,IAAI,CAAC,MAPgB,WACpB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR,GAGC,MAAM,OAAO,KACZ,aAAa,OAAO,UAAU,YAAY,OAAO,SAAS,SAC1D,EAAE,MAAM,EAAE,MAAM,OAAO,KAAK,EAAE,CAC/B;OAEA,eAAO,IAAI,KAAK,gCAAgC,OAAO,KAAK,EAAE;EAG/D,MAAM,WAAW,MAAM,eACtB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR;EAEA,OAAO;GACN,IAAI,GAAG,OAAO,SAAS,GAAG,OAAO;GACjC,MAAM;IAAE,GAAG;IAAQ;GAAS;EAC7B;CACD;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,WAAW,MAAM,eACtB,IAHkBA,+BAAW,MAAM,MAG9B,GACL,MAAM,WACN,MAAM,UACN,MAAM,IACP;EAEA,OAAO;GACN;GACA,OAAO;IAAE,GAAG;IAAO;GAAS;EAC7B;CACD;CAEA,MAAM,OAAO,KAAa,OAAuC;EAChE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OACZ,aAAa,MAAM,UAAU,YAAY,MAAM,SAAS,SAAS,MAAM,MACxE;EACD,QAAQ;GACP,eAAO,IAAI,KACV,+BAA+B,MAAM,KAAK,2BAC3C;EACD;CACD;CAEA,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;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,mBAAN,cAA+BC,eAAO,QAAQ,SAAS;CAGtD,YACC,MACA,MAMA,MACC;EACD,MACC,IAAI,yBAAyB,GAC7B,MACA;GAAE,GAAG;GAAM,UAAUA,eAAO,OAAO,MAA8B;EAAE,GACnE,IACD;CACD;AACD;;;;;;;;;;;;AA+BA,IAAa,WAAb,cAA8BA,eAAO,kBAAkB;CAItD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,wBAAwB,MAAM,CAAC,GAAG,UAAU;EAElD,MAAM,WAAW,IAAI,iBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,WAAW,SAAS;EAEzB,KAAK,gBAAgB,EAAE,UAAU,KAAK,SAAS,CAAC;CACjD;AACD"}
1
+ {"version":3,"file":"role.cjs","names":["NeonClient","pulumi"],"sources":["../../src/neon/role.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport { NeonClient } from \"./client.js\";\nimport type { NeonBranch } from \"./branch.js\";\nimport type { NeonProject } from \"./project.js\";\nimport type { NeonProvider } from \"./provider.js\";\n\n/** Resolved inputs for the Neon role dynamic provider. */\nexport interface NeonRoleInputs {\n\t/** Neon API key. */\n\tapiKey: string;\n\n\t/** Neon project ID. */\n\tprojectId: string;\n\n\t/** Branch ID the role belongs to. */\n\tbranchId: string;\n\n\t/** Role name (e.g. `\"neondb_owner\"`). */\n\tname: string;\n}\n\n/** Persisted state for the Neon role. */\ninterface NeonRoleOutputs extends NeonRoleInputs {\n\t/** Role password (auto-generated by Neon). */\n\tpassword: string;\n}\n\n/** Neon API response for the reveal_password endpoint. */\ninterface PasswordResponse {\n\tpassword: string;\n}\n\n/** Neon API response for listing roles. */\ninterface RoleListResponse {\n\troles: Array<{\n\t\tname: string;\n\t}>;\n}\n\n/**\n * Checks if a role exists by name on a branch.\n */\nasync function roleExists(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n\tname: string,\n): Promise<boolean> {\n\tconst result = await client.get<RoleListResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/roles`,\n\t);\n\n\treturn result.roles.some((r) => r.name === name);\n}\n\n/**\n * Reveals the password for an existing role via the dedicated API endpoint.\n */\nasync function revealPassword(\n\tclient: NeonClient,\n\tprojectId: string,\n\tbranchId: string,\n\tname: string,\n): Promise<string> {\n\tconst result = await client.get<PasswordResponse>(\n\t\t`/projects/${projectId}/branches/${branchId}/roles/${name}/reveal_password`,\n\t);\n\n\treturn result.password;\n}\n\n/**\n * Dynamic provider implementing CRUD for Neon database roles.\n *\n * Uses adopt-or-create on `create()`: finds an existing role by name\n * before creating a new one.\n */\nclass NeonRoleResourceProvider implements pulumi.dynamic.ResourceProvider {\n\tasync create(inputs: NeonRoleInputs): Promise<pulumi.dynamic.CreateResult> {\n\t\tconst client = new NeonClient(inputs.apiKey);\n\n\t\tconst exists = await roleExists(\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\tawait client.post(\n\t\t\t\t`/projects/${inputs.projectId}/branches/${inputs.branchId}/roles`,\n\t\t\t\t{ role: { name: inputs.name } },\n\t\t\t);\n\t\t} else {\n\t\t\tpulumi.log.info(`Adopting existing Neon role \"${inputs.name}\"`);\n\t\t}\n\n\t\tconst password = await revealPassword(\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\treturn {\n\t\t\tid: `${inputs.branchId}/${inputs.name}`,\n\t\t\touts: { ...inputs, password },\n\t\t};\n\t}\n\n\tasync read(\n\t\tid: string,\n\t\tprops: NeonRoleOutputs,\n\t): Promise<pulumi.dynamic.ReadResult> {\n\t\tconst client = new NeonClient(props.apiKey);\n\n\t\tconst password = await revealPassword(\n\t\t\tclient,\n\t\t\tprops.projectId,\n\t\t\tprops.branchId,\n\t\t\tprops.name,\n\t\t);\n\n\t\treturn {\n\t\t\tid,\n\t\t\tprops: { ...props, password },\n\t\t};\n\t}\n\n\tasync delete(_id: string, props: NeonRoleOutputs): 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}/roles/${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 role \"${props.name}\" (may already be deleted)`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync diff(\n\t\t_id: string,\n\t\tolds: NeonRoleOutputs,\n\t\tnews: NeonRoleInputs,\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,\n\t\t\treplaces,\n\t\t\tdeleteBeforeReplace: true,\n\t\t};\n\t}\n}\n\n/** Internal dynamic resource — not part of the public API. */\nclass NeonRoleResource extends pulumi.dynamic.Resource {\n\tpublic declare readonly password: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: {\n\t\t\tapiKey: pulumi.Input<string>;\n\t\t\tprojectId: pulumi.Input<string>;\n\t\t\tbranchId: pulumi.Input<string>;\n\t\t\tname: pulumi.Input<string>;\n\t\t},\n\t\topts?: pulumi.CustomResourceOptions,\n\t) {\n\t\tsuper(\n\t\t\tnew NeonRoleResourceProvider(),\n\t\t\tname,\n\t\t\t{ ...args, password: pulumi.secret(undefined as unknown as string) },\n\t\t\topts,\n\t\t);\n\t}\n}\n\n/** Options type for NeonRole — replaces Pulumi's native `provider` field. */\ntype NeonRoleOptions = Omit<pulumi.ComponentResourceOptions, \"provider\"> & {\n\t/** Neon authentication context. */\n\tprovider: NeonProvider;\n\n\t/** Neon project context. */\n\tproject: NeonProject;\n\n\t/** Neon branch context. */\n\tbranch: NeonBranch;\n};\n\n/** Args for NeonRole. */\nexport interface NeonRoleArgs {\n\t/** Role name (e.g. `\"neondb_owner\"`). */\n\tname: pulumi.Input<string>;\n}\n\n/**\n * Manages a Neon database role with adopt-or-create semantics.\n * Exposes `password` as a secret output for connection string composition.\n *\n * @example\n * ```typescript\n * const role = new NeonRole(\"owner\", {\n * name: \"neondb_owner\",\n * }, { provider, project, branch });\n * ```\n */\nexport class NeonRole extends pulumi.ComponentResource {\n\t/** Role password (secret). */\n\tpublic readonly password: pulumi.Output<string>;\n\n\tconstructor(\n\t\tname: string,\n\t\targs: NeonRoleArgs,\n\t\topts: NeonRoleOptions,\n\t) {\n\t\tconst { provider, project, branch, ...pulumiOpts } = opts;\n\n\t\tsuper(\"infracraft:neon:Role\", name, {}, pulumiOpts);\n\n\t\tconst resource = new NeonRoleResource(\n\t\t\t`${name}-resource`,\n\t\t\t{\n\t\t\t\tapiKey: provider.apiKey,\n\t\t\t\tprojectId: project.id,\n\t\t\t\tbranchId: branch.id,\n\t\t\t\tname: args.name,\n\t\t\t},\n\t\t\t{ parent: this },\n\t\t);\n\n\t\tthis.password = resource.password;\n\n\t\tthis.registerOutputs({ password: this.password });\n\t}\n}\n"],"mappings":";;;;;;;;;;AA0CA,eAAe,WACd,QACA,WACA,UACA,MACmB;CAKnB,QAAO,MAJc,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,OAC7C,GAEc,MAAM,MAAM,MAAM,EAAE,SAAS,IAAI;AAChD;;;;AAKA,eAAe,eACd,QACA,WACA,UACA,MACkB;CAKlB,QAAO,MAJc,OAAO,IAC3B,aAAa,UAAU,YAAY,SAAS,SAAS,KAAK,iBAC3D,GAEc;AACf;;;;;;;AAQA,IAAM,2BAAN,MAA0E;CACzE,MAAM,OAAO,QAA8D;EAC1E,MAAM,SAAS,IAAIA,+BAAW,OAAO,MAAM;EAS3C,IAAI,CAAC,MAPgB,WACpB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR,GAGC,MAAM,OAAO,KACZ,aAAa,OAAO,UAAU,YAAY,OAAO,SAAS,SAC1D,EAAE,MAAM,EAAE,MAAM,OAAO,KAAK,EAAE,CAC/B;OAEA,eAAO,IAAI,KAAK,gCAAgC,OAAO,KAAK,EAAE;EAG/D,MAAM,WAAW,MAAM,eACtB,QACA,OAAO,WACP,OAAO,UACP,OAAO,IACR;EAEA,OAAO;GACN,IAAI,GAAG,OAAO,SAAS,GAAG,OAAO;GACjC,MAAM;IAAE,GAAG;IAAQ;GAAS;EAC7B;CACD;CAEA,MAAM,KACL,IACA,OACqC;EAGrC,MAAM,WAAW,MAAM,eACtB,IAHkBA,+BAAW,MAAM,MAG9B,GACL,MAAM,WACN,MAAM,UACN,MAAM,IACP;EAEA,OAAO;GACN;GACA,OAAO;IAAE,GAAG;IAAO;GAAS;EAC7B;CACD;CAEA,MAAM,OAAO,KAAa,OAAuC;EAChE,MAAM,SAAS,IAAIA,+BAAW,MAAM,MAAM;EAE1C,IAAI;GACH,MAAM,OAAO,OACZ,aAAa,MAAM,UAAU,YAAY,MAAM,SAAS,SAAS,MAAM,MACxE;EACD,QAAQ;GACP,eAAO,IAAI,KACV,+BAA+B,MAAM,KAAK,2BAC3C;EACD;CACD;CAEA,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;GAC3B;GACA,qBAAqB;EACtB;CACD;AACD;;AAGA,IAAM,mBAAN,cAA+BC,eAAO,QAAQ,SAAS;CAGtD,YACC,MACA,MAMA,MACC;EACD,MACC,IAAI,yBAAyB,GAC7B,MACA;GAAE,GAAG;GAAM,UAAUA,eAAO,OAAO,MAA8B;EAAE,GACnE,IACD;CACD;AACD;;;;;;;;;;;;AA+BA,IAAa,WAAb,cAA8BA,eAAO,kBAAkB;CAItD,YACC,MACA,MACA,MACC;EACD,MAAM,EAAE,UAAU,SAAS,QAAQ,GAAG,eAAe;EAErD,MAAM,wBAAwB,MAAM,CAAC,GAAG,UAAU;EAElD,MAAM,WAAW,IAAI,iBACpB,GAAG,KAAK,YACR;GACC,QAAQ,SAAS;GACjB,WAAW,QAAQ;GACnB,UAAU,OAAO;GACjB,MAAM,KAAK;EACZ,GACA,EAAE,QAAQ,KAAK,CAChB;EAEA,KAAK,WAAW,SAAS;EAEzB,KAAK,gBAAgB,EAAE,UAAU,KAAK,SAAS,CAAC;CACjD;AACD"}
@@ -91,8 +91,8 @@ var NeonRole = class extends pulumi.ComponentResource {
91
91
  super("infracraft:neon:Role", name, {}, pulumiOpts);
92
92
  const resource = new NeonRoleResource(`${name}-resource`, {
93
93
  apiKey: provider.apiKey,
94
- projectId: project.projectId,
95
- branchId: branch.branchId,
94
+ projectId: project.id,
95
+ branchId: branch.id,
96
96
  name: args.name
97
97
  }, { parent: this });
98
98
  this.password = resource.password;