alchemy 0.12.20 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/lib/ai/client.d.ts.map +1 -1
  2. package/lib/ai/client.js +3 -5
  3. package/lib/ai/client.js.map +1 -1
  4. package/lib/alchemy.d.ts +2 -1
  5. package/lib/alchemy.d.ts.map +1 -1
  6. package/lib/alchemy.js +87 -92
  7. package/lib/alchemy.js.map +1 -1
  8. package/lib/apply.d.ts.map +1 -1
  9. package/lib/apply.js +6 -0
  10. package/lib/apply.js.map +1 -1
  11. package/lib/aws/bucket.d.ts.map +1 -1
  12. package/lib/aws/bucket.js +55 -57
  13. package/lib/aws/bucket.js.map +1 -1
  14. package/lib/aws/function.d.ts.map +1 -1
  15. package/lib/aws/function.js +250 -252
  16. package/lib/aws/function.js.map +1 -1
  17. package/lib/aws/policy-attachment.d.ts.map +1 -1
  18. package/lib/aws/policy-attachment.js +4 -6
  19. package/lib/aws/policy-attachment.js.map +1 -1
  20. package/lib/aws/policy.d.ts.map +1 -1
  21. package/lib/aws/policy.js +63 -65
  22. package/lib/aws/policy.js.map +1 -1
  23. package/lib/aws/queue.js +88 -90
  24. package/lib/aws/queue.js.map +1 -1
  25. package/lib/aws/table.d.ts.map +1 -1
  26. package/lib/aws/table.js +95 -99
  27. package/lib/aws/table.js.map +1 -1
  28. package/lib/cloudflare/account-api-token.d.ts +1 -1
  29. package/lib/cloudflare/account-api-token.d.ts.map +1 -1
  30. package/lib/cloudflare/account-api-token.js +0 -1
  31. package/lib/cloudflare/account-api-token.js.map +1 -1
  32. package/lib/cloudflare/ai-gateway.js.map +1 -1
  33. package/lib/cloudflare/ai.d.ts +1 -1
  34. package/lib/cloudflare/ai.d.ts.map +1 -1
  35. package/lib/cloudflare/ai.js.map +1 -1
  36. package/lib/cloudflare/api.js +1 -5
  37. package/lib/cloudflare/api.js.map +1 -1
  38. package/lib/cloudflare/bucket.d.ts +2 -2
  39. package/lib/cloudflare/bucket.d.ts.map +1 -1
  40. package/lib/cloudflare/bucket.js +22 -24
  41. package/lib/cloudflare/bucket.js.map +1 -1
  42. package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts +0 -3
  43. package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts.map +1 -1
  44. package/lib/cloudflare/bundle/hybrid-nodejs-compat.js +4 -7
  45. package/lib/cloudflare/bundle/hybrid-nodejs-compat.js.map +1 -1
  46. package/lib/cloudflare/custom-domain.d.ts.map +1 -1
  47. package/lib/cloudflare/custom-domain.js +3 -5
  48. package/lib/cloudflare/custom-domain.js.map +1 -1
  49. package/lib/cloudflare/d1-database.d.ts +1 -1
  50. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  51. package/lib/cloudflare/d1-database.js +70 -72
  52. package/lib/cloudflare/d1-database.js.map +1 -1
  53. package/lib/cloudflare/d1-migrations.d.ts +1 -1
  54. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  55. package/lib/cloudflare/d1-migrations.js +2 -3
  56. package/lib/cloudflare/d1-migrations.js.map +1 -1
  57. package/lib/cloudflare/dns-records.d.ts.map +1 -1
  58. package/lib/cloudflare/dns-records.js +2 -4
  59. package/lib/cloudflare/dns-records.js.map +1 -1
  60. package/lib/cloudflare/kv-namespace.d.ts +1 -1
  61. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  62. package/lib/cloudflare/kv-namespace.js +24 -27
  63. package/lib/cloudflare/kv-namespace.js.map +1 -1
  64. package/lib/cloudflare/pipeline.d.ts +1 -1
  65. package/lib/cloudflare/pipeline.d.ts.map +1 -1
  66. package/lib/cloudflare/pipeline.js +32 -34
  67. package/lib/cloudflare/pipeline.js.map +1 -1
  68. package/lib/cloudflare/queue-consumer.d.ts +1 -1
  69. package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
  70. package/lib/cloudflare/queue-consumer.js +31 -33
  71. package/lib/cloudflare/queue-consumer.js.map +1 -1
  72. package/lib/cloudflare/queue.d.ts +1 -1
  73. package/lib/cloudflare/queue.d.ts.map +1 -1
  74. package/lib/cloudflare/queue.js +36 -38
  75. package/lib/cloudflare/queue.js.map +1 -1
  76. package/lib/cloudflare/r2-rest-state-store.js +4 -8
  77. package/lib/cloudflare/r2-rest-state-store.js.map +1 -1
  78. package/lib/cloudflare/types.d.ts.map +1 -1
  79. package/lib/cloudflare/types.js +1 -3
  80. package/lib/cloudflare/types.js.map +1 -1
  81. package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
  82. package/lib/cloudflare/vectorize-index.js +37 -39
  83. package/lib/cloudflare/vectorize-index.js.map +1 -1
  84. package/lib/cloudflare/vectorize-metadata-index.d.ts +1 -1
  85. package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
  86. package/lib/cloudflare/vectorize-metadata-index.js +10 -13
  87. package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
  88. package/lib/cloudflare/worker.js +6 -12
  89. package/lib/cloudflare/worker.js.map +1 -1
  90. package/lib/cloudflare/workflow.d.ts +1 -1
  91. package/lib/cloudflare/workflow.d.ts.map +1 -1
  92. package/lib/cloudflare/workflow.js.map +1 -1
  93. package/lib/cloudflare/zone.d.ts.map +1 -1
  94. package/lib/cloudflare/zone.js +48 -50
  95. package/lib/cloudflare/zone.js.map +1 -1
  96. package/lib/dns/godaddy.js +1 -1
  97. package/lib/dns/import-dns.js +1 -1
  98. package/lib/dns/import-dns.js.map +1 -1
  99. package/lib/env.js +7 -9
  100. package/lib/env.js.map +1 -1
  101. package/lib/esbuild/bundle.js +8 -10
  102. package/lib/esbuild/bundle.js.map +1 -1
  103. package/lib/fs/copy-file.d.ts.map +1 -1
  104. package/lib/fs/copy-file.js +27 -29
  105. package/lib/fs/copy-file.js.map +1 -1
  106. package/lib/fs/file.d.ts +1 -1
  107. package/lib/fs/file.d.ts.map +1 -1
  108. package/lib/fs/file.js +1 -1
  109. package/lib/fs/file.js.map +1 -1
  110. package/lib/fs/folder.d.ts.map +1 -1
  111. package/lib/fs/folder.js +1 -3
  112. package/lib/fs/folder.js.map +1 -1
  113. package/lib/github/client.d.ts.map +1 -1
  114. package/lib/github/client.js +3 -5
  115. package/lib/github/client.js.map +1 -1
  116. package/lib/github/repository-environment.d.ts.map +1 -1
  117. package/lib/github/repository-environment.js +173 -176
  118. package/lib/github/repository-environment.js.map +1 -1
  119. package/lib/github/secret.d.ts.map +1 -1
  120. package/lib/github/secret.js +97 -99
  121. package/lib/github/secret.js.map +1 -1
  122. package/lib/internal/docs/providers.d.ts.map +1 -1
  123. package/lib/internal/docs/providers.js +5 -7
  124. package/lib/internal/docs/providers.js.map +1 -1
  125. package/lib/neon/api.js +1 -2
  126. package/lib/neon/api.js.map +1 -1
  127. package/lib/neon/project.js +2 -2
  128. package/lib/neon/project.js.map +1 -1
  129. package/lib/os/exec.d.ts +5 -0
  130. package/lib/os/exec.d.ts.map +1 -1
  131. package/lib/os/exec.js +88 -56
  132. package/lib/os/exec.js.map +1 -1
  133. package/lib/scope.d.ts +3 -0
  134. package/lib/scope.d.ts.map +1 -1
  135. package/lib/scope.js +10 -3
  136. package/lib/scope.js.map +1 -1
  137. package/lib/secret.d.ts.map +1 -1
  138. package/lib/secret.js +1 -3
  139. package/lib/secret.js.map +1 -1
  140. package/lib/serde.d.ts.map +1 -1
  141. package/lib/serde.js +13 -15
  142. package/lib/serde.js.map +1 -1
  143. package/lib/stripe/price.d.ts.map +1 -1
  144. package/lib/stripe/price.js +69 -73
  145. package/lib/stripe/price.js.map +1 -1
  146. package/lib/stripe/product.d.ts.map +1 -1
  147. package/lib/stripe/product.js +50 -52
  148. package/lib/stripe/product.js.map +1 -1
  149. package/lib/stripe/webhook.d.ts.map +1 -1
  150. package/lib/stripe/webhook.js +51 -53
  151. package/lib/stripe/webhook.js.map +1 -1
  152. package/lib/test/bun.d.ts +1 -1
  153. package/lib/test/bun.d.ts.map +1 -1
  154. package/lib/test/bun.js +1 -0
  155. package/lib/test/bun.js.map +1 -1
  156. package/lib/test/prune.d.ts.map +1 -1
  157. package/lib/test/prune.js.map +1 -1
  158. package/lib/util/dedent.js +4 -4
  159. package/lib/util/dedent.js.map +1 -1
  160. package/lib/web/astro.js +1 -1
  161. package/lib/web/shadcn.js +4 -4
  162. package/lib/web/shadcn.js.map +1 -1
  163. package/lib/web/tailwind.d.ts.map +1 -1
  164. package/lib/web/tailwind.js +0 -1
  165. package/lib/web/tailwind.js.map +1 -1
  166. package/lib/web/vite.js +3 -3
  167. package/lib/web/vitepress/home-page.d.ts.map +1 -1
  168. package/lib/web/vitepress/home-page.js +6 -8
  169. package/lib/web/vitepress/home-page.js.map +1 -1
  170. package/lib/web/vitepress/process-front-matter-files.js +1 -1
  171. package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
  172. package/lib/web/vitepress/vitepress.js +2 -2
  173. package/lib/web/vitepress/vitepress.js.map +1 -1
  174. package/package.json +1 -1
  175. package/src/ai/astro-file.ts +4 -4
  176. package/src/ai/client.ts +4 -5
  177. package/src/ai/css-file.ts +4 -4
  178. package/src/ai/document.ts +3 -3
  179. package/src/ai/html-file.ts +4 -4
  180. package/src/ai/json-file.ts +1 -1
  181. package/src/ai/typescript-file.ts +4 -4
  182. package/src/ai/vue-file.ts +4 -4
  183. package/src/ai/yaml-file.ts +1 -1
  184. package/src/alchemy.ts +111 -104
  185. package/src/apply.ts +13 -5
  186. package/src/aws/bucket.ts +72 -75
  187. package/src/aws/function.ts +296 -297
  188. package/src/aws/oidc/github-oidc-provider.ts +1 -1
  189. package/src/aws/oidc/oidc-provider.ts +15 -15
  190. package/src/aws/policy-attachment.ts +10 -11
  191. package/src/aws/policy.ts +91 -94
  192. package/src/aws/queue.ts +111 -111
  193. package/src/aws/role.ts +24 -24
  194. package/src/aws/ses.ts +17 -17
  195. package/src/aws/table.ts +114 -115
  196. package/src/cloudflare/account-api-token.ts +11 -11
  197. package/src/cloudflare/account-id.ts +1 -1
  198. package/src/cloudflare/ai-gateway.ts +4 -4
  199. package/src/cloudflare/ai.ts +1 -1
  200. package/src/cloudflare/api-error.ts +1 -1
  201. package/src/cloudflare/api.ts +7 -11
  202. package/src/cloudflare/assets.ts +4 -4
  203. package/src/cloudflare/auth.ts +13 -13
  204. package/src/cloudflare/bucket.ts +62 -63
  205. package/src/cloudflare/bundle/hybrid-nodejs-compat.ts +14 -17
  206. package/src/cloudflare/custom-domain.ts +27 -28
  207. package/src/cloudflare/d1-database.ts +101 -102
  208. package/src/cloudflare/d1-migrations.ts +10 -10
  209. package/src/cloudflare/dns-records.ts +23 -24
  210. package/src/cloudflare/durable-object-namespace.ts +1 -1
  211. package/src/cloudflare/event-source.ts +1 -1
  212. package/src/cloudflare/hyperdrive.ts +3 -3
  213. package/src/cloudflare/kv-namespace.ts +36 -37
  214. package/src/cloudflare/nuxt.ts +1 -1
  215. package/src/cloudflare/permission-groups.ts +7 -7
  216. package/src/cloudflare/pipeline.ts +55 -56
  217. package/src/cloudflare/queue-consumer.ts +53 -54
  218. package/src/cloudflare/queue.ts +56 -57
  219. package/src/cloudflare/r2-rest-state-store.ts +11 -11
  220. package/src/cloudflare/redwood.ts +1 -1
  221. package/src/cloudflare/tanstack-start.ts +1 -1
  222. package/src/cloudflare/types.ts +1 -2
  223. package/src/cloudflare/vectorize-index.ts +60 -61
  224. package/src/cloudflare/vectorize-metadata-index.ts +25 -25
  225. package/src/cloudflare/vite.ts +1 -1
  226. package/src/cloudflare/website.ts +3 -3
  227. package/src/cloudflare/worker.ts +61 -61
  228. package/src/cloudflare/workflow.ts +4 -4
  229. package/src/cloudflare/wrangler.json.ts +4 -4
  230. package/src/cloudflare/zone.ts +69 -70
  231. package/src/destroy.ts +4 -4
  232. package/src/dns/godaddy.ts +1 -1
  233. package/src/dns/import-dns.ts +5 -5
  234. package/src/encrypt.ts +6 -6
  235. package/src/env.ts +10 -10
  236. package/src/esbuild/bundle.ts +14 -14
  237. package/src/fs/copy-file.ts +35 -36
  238. package/src/fs/file-system-state-store.ts +4 -4
  239. package/src/fs/file.ts +9 -8
  240. package/src/fs/folder.ts +6 -7
  241. package/src/github/client.ts +15 -14
  242. package/src/github/repository-environment.ts +206 -210
  243. package/src/github/secret.ts +111 -116
  244. package/src/internal/docs/providers.ts +16 -17
  245. package/src/neon/api-error.ts +1 -1
  246. package/src/neon/api.ts +6 -6
  247. package/src/neon/project.ts +18 -17
  248. package/src/os/exec.ts +107 -66
  249. package/src/resource.ts +3 -3
  250. package/src/scope.ts +14 -4
  251. package/src/secret.ts +2 -3
  252. package/src/serde.ts +30 -22
  253. package/src/stripe/price.ts +74 -77
  254. package/src/stripe/product.ts +55 -56
  255. package/src/stripe/webhook.ts +56 -57
  256. package/src/test/bun.ts +7 -6
  257. package/src/test/prune.ts +4 -4
  258. package/src/util/dedent.ts +4 -4
  259. package/src/web/astro.ts +10 -10
  260. package/src/web/shadcn-component.ts +4 -4
  261. package/src/web/shadcn.ts +10 -10
  262. package/src/web/tailwind.ts +2 -3
  263. package/src/web/vite.ts +11 -11
  264. package/src/web/vitepress/config.ts +2 -2
  265. package/src/web/vitepress/custom-theme.ts +7 -7
  266. package/src/web/vitepress/dependencies.ts +4 -4
  267. package/src/web/vitepress/home-page.ts +8 -9
  268. package/src/web/vitepress/process-front-matter-files.ts +5 -5
  269. package/src/web/vitepress/vitepress.ts +7 -7
@@ -48,7 +48,7 @@ export async function getGitHubToken(token?: string): Promise<string | null> {
48
48
  * @returns An authenticated Octokit client
49
49
  */
50
50
  export async function createGitHubClient(
51
- options: { token?: string } = {}
51
+ options: { token?: string } = {},
52
52
  ): Promise<Octokit> {
53
53
  const token = await getGitHubToken(options.token);
54
54
 
@@ -67,7 +67,7 @@ export async function createGitHubClient(
67
67
  export async function verifyGitHubAuth(
68
68
  octokit: Octokit,
69
69
  owner: string,
70
- repo: string
70
+ repo: string,
71
71
  ): Promise<void> {
72
72
  try {
73
73
  // Make a test request to check authentication
@@ -78,38 +78,39 @@ export async function verifyGitHubAuth(
78
78
  } catch (error: any) {
79
79
  if (error.status === 401) {
80
80
  console.error(
81
- "\n⚠️ GitHub authentication failed. Please try one of the following:"
81
+ "\n⚠️ GitHub authentication failed. Please try one of the following:",
82
82
  );
83
83
  console.error(
84
- "1. Run 'gh auth login' to authenticate with the GitHub CLI"
84
+ "1. Run 'gh auth login' to authenticate with the GitHub CLI",
85
85
  );
86
86
  console.error(
87
- "2. Set the GITHUB_TOKEN environment variable with a personal access token"
87
+ "2. Set the GITHUB_TOKEN environment variable with a personal access token",
88
88
  );
89
89
  console.error("3. Pass a token directly to the constructor");
90
90
  console.error(
91
- "\nTo create a token, visit: https://github.com/settings/tokens"
91
+ "\nTo create a token, visit: https://github.com/settings/tokens",
92
92
  );
93
93
  console.error(
94
- "Required scopes: 'repo' for private repos or 'public_repo' for public repos\n"
94
+ "Required scopes: 'repo' for private repos or 'public_repo' for public repos\n",
95
95
  );
96
96
  throw new Error("GitHub authentication failed");
97
- } else if (error.status === 403) {
97
+ }
98
+ if (error.status === 403) {
98
99
  console.error(
99
- "\n⚠️ Insufficient permissions. You need admin access to the repository."
100
+ "\n⚠️ Insufficient permissions. You need admin access to the repository.",
100
101
  );
101
102
  console.error(
102
- "Make sure your token has the 'repo' scope for private repos or 'public_repo' for public repos\n"
103
+ "Make sure your token has the 'repo' scope for private repos or 'public_repo' for public repos\n",
103
104
  );
104
105
  throw new Error("Insufficient GitHub permissions");
105
- } else if (error.status === 404) {
106
+ }
107
+ if (error.status === 404) {
106
108
  console.error(`\n⚠️ Repository not found: ${owner}/${repo}`);
107
109
  console.error(
108
- "Make sure the repository exists and you have access to it\n"
110
+ "Make sure the repository exists and you have access to it\n",
109
111
  );
110
112
  throw new Error("GitHub repository not found");
111
- } else {
112
- throw error;
113
113
  }
114
+ throw error;
114
115
  }
115
116
  }
@@ -174,7 +174,7 @@ export const RepositoryEnvironment = Resource(
174
174
  async function (
175
175
  this: Context<RepositoryEnvironment>,
176
176
  id: string,
177
- props: RepositoryEnvironmentProps
177
+ props: RepositoryEnvironmentProps,
178
178
  ): Promise<RepositoryEnvironment> {
179
179
  // Create authenticated Octokit client
180
180
  const octokit = await createGitHubClient({
@@ -207,138 +207,98 @@ export const RepositoryEnvironment = Resource(
207
207
 
208
208
  // Return void (a deleted resource has no content)
209
209
  return this.destroy();
210
- } else {
210
+ }
211
+ try {
212
+ // Check if the environment already exists
213
+ let environmentId: number | undefined = undefined; // Use undefined instead of 0
211
214
  try {
212
- // Check if the environment already exists
213
- let environmentId: number | undefined = undefined; // Use undefined instead of 0
214
- try {
215
- const { data: environments } =
216
- await octokit.rest.repos.getAllEnvironments({
217
- owner: props.owner,
218
- repo: props.repository,
219
- });
215
+ const { data: environments } =
216
+ await octokit.rest.repos.getAllEnvironments({
217
+ owner: props.owner,
218
+ repo: props.repository,
219
+ });
220
220
 
221
- const existingEnv = environments.environments?.find(
222
- (env) => env.name.toLowerCase() === props.name.toLowerCase()
223
- );
221
+ const existingEnv = environments.environments?.find(
222
+ (env) => env.name.toLowerCase() === props.name.toLowerCase(),
223
+ );
224
224
 
225
- if (existingEnv?.id) {
226
- environmentId = existingEnv.id;
227
- }
228
- } catch (error: any) {
229
- // If it's a 404, the environment doesn't exist, which is fine
230
- if (error.status !== 404) {
231
- throw error;
232
- }
225
+ if (existingEnv?.id) {
226
+ environmentId = existingEnv.id;
233
227
  }
228
+ } catch (error: any) {
229
+ // If it's a 404, the environment doesn't exist, which is fine
230
+ if (error.status !== 404) {
231
+ throw error;
232
+ }
233
+ }
234
234
 
235
- // Convert reviewers to API format
236
- const reviewers: { type: "User" | "Team"; id: number }[] = [];
237
-
238
- // Process user reviewers
239
- if (props.reviewers?.users && props.reviewers.users.length > 0) {
240
- for (const user of props.reviewers.users) {
241
- if (typeof user === "number") {
242
- // If a numeric ID is provided, use it directly
243
- reviewers.push({
244
- type: "User" as const,
245
- id: user,
246
- });
247
- } else {
248
- // If a username string is provided, look up the ID
249
- const { data: userData } = await octokit.rest.users.getByUsername(
250
- {
251
- username: user,
252
- }
253
- );
235
+ // Convert reviewers to API format
236
+ const reviewers: { type: "User" | "Team"; id: number }[] = [];
237
+
238
+ // Process user reviewers
239
+ if (props.reviewers?.users && props.reviewers.users.length > 0) {
240
+ for (const user of props.reviewers.users) {
241
+ if (typeof user === "number") {
242
+ // If a numeric ID is provided, use it directly
243
+ reviewers.push({
244
+ type: "User" as const,
245
+ id: user,
246
+ });
247
+ } else {
248
+ // If a username string is provided, look up the ID
249
+ const { data: userData } = await octokit.rest.users.getByUsername({
250
+ username: user,
251
+ });
254
252
 
255
- reviewers.push({
256
- type: "User" as const,
257
- id: userData.id,
258
- });
259
- }
253
+ reviewers.push({
254
+ type: "User" as const,
255
+ id: userData.id,
256
+ });
260
257
  }
261
258
  }
259
+ }
262
260
 
263
- // Process team reviewers
264
- if (props.reviewers?.teams && props.reviewers.teams.length > 0) {
265
- for (const team of props.reviewers.teams) {
266
- if (typeof team === "number") {
267
- // If a numeric ID is provided, use it directly
268
- reviewers.push({
269
- type: "Team" as const,
270
- id: team,
271
- });
272
- } else {
273
- // If a team name string is provided, look up the ID
274
- // Check if team name is in the format 'org/team-name'
275
- const teamParts = team.includes("/")
276
- ? team.split("/")
277
- : [props.owner, team];
278
-
279
- if (teamParts.length !== 2) {
280
- throw new Error(
281
- `Invalid team format: ${team}. Expected format: "org/team-slug" or just "team-slug"`
282
- );
283
- }
261
+ // Process team reviewers
262
+ if (props.reviewers?.teams && props.reviewers.teams.length > 0) {
263
+ for (const team of props.reviewers.teams) {
264
+ if (typeof team === "number") {
265
+ // If a numeric ID is provided, use it directly
266
+ reviewers.push({
267
+ type: "Team" as const,
268
+ id: team,
269
+ });
270
+ } else {
271
+ // If a team name string is provided, look up the ID
272
+ // Check if team name is in the format 'org/team-name'
273
+ const teamParts = team.includes("/")
274
+ ? team.split("/")
275
+ : [props.owner, team];
276
+
277
+ if (teamParts.length !== 2) {
278
+ throw new Error(
279
+ `Invalid team format: ${team}. Expected format: "org/team-slug" or just "team-slug"`,
280
+ );
281
+ }
284
282
 
285
- const [org, teamSlug] = teamParts;
283
+ const [org, teamSlug] = teamParts;
286
284
 
287
- const { data: teamData } = await octokit.rest.teams.getByName({
288
- org,
289
- team_slug: teamSlug,
290
- });
285
+ const { data: teamData } = await octokit.rest.teams.getByName({
286
+ org,
287
+ team_slug: teamSlug,
288
+ });
291
289
 
292
- reviewers.push({
293
- type: "Team" as const,
294
- id: teamData.id,
295
- });
296
- }
290
+ reviewers.push({
291
+ type: "Team" as const,
292
+ id: teamData.id,
293
+ });
297
294
  }
298
295
  }
296
+ }
299
297
 
300
- // Create or update the environment
301
- if (environmentId === undefined) {
302
- // Create the environment
303
- const { data: createdEnv } =
304
- await octokit.rest.repos.createOrUpdateEnvironment({
305
- owner: props.owner,
306
- repo: props.repository,
307
- environment_name: props.name,
308
- wait_timer: props.waitTimer,
309
- prevent_self_review: props.preventSelfReview,
310
- reviewers: reviewers.length > 0 ? reviewers : undefined,
311
- deployment_branch_policy: props.deploymentBranchPolicy
312
- ? {
313
- protected_branches:
314
- props.deploymentBranchPolicy.protectedBranches ?? false,
315
- custom_branch_policies:
316
- props.deploymentBranchPolicy.customBranchPolicies ??
317
- false,
318
- }
319
- : undefined,
320
- });
321
-
322
- environmentId = createdEnv.id;
323
-
324
- // If there are specific branch patterns, set them
325
- if (
326
- props.deploymentBranchPolicy?.customBranchPolicies === true &&
327
- props.branchPatterns &&
328
- props.branchPatterns.length > 0
329
- ) {
330
- // Add branch patterns one by one
331
- for (const pattern of props.branchPatterns) {
332
- await octokit.rest.repos.createDeploymentBranchPolicy({
333
- owner: props.owner,
334
- repo: props.repository,
335
- environment_name: props.name,
336
- name: pattern,
337
- });
338
- }
339
- }
340
- } else {
341
- // Update the environment
298
+ // Create or update the environment
299
+ if (environmentId === undefined) {
300
+ // Create the environment
301
+ const { data: createdEnv } =
342
302
  await octokit.rest.repos.createOrUpdateEnvironment({
343
303
  owner: props.owner,
344
304
  repo: props.repository,
@@ -356,114 +316,150 @@ export const RepositoryEnvironment = Resource(
356
316
  : undefined,
357
317
  });
358
318
 
359
- // If there are specific branch patterns, update them
360
- if (props.deploymentBranchPolicy?.customBranchPolicies === true) {
361
- // Get existing branch policies to understand what's currently configured
362
- const { data: existingPolicies } =
363
- await octokit.rest.repos.listDeploymentBranchPolicies({
364
- owner: props.owner,
365
- repo: props.repository,
366
- environment_name: props.name,
367
- });
319
+ environmentId = createdEnv.id;
368
320
 
369
- const existingPatterns = existingPolicies.branch_policies.map(
370
- (policy) => policy.name!
371
- );
321
+ // If there are specific branch patterns, set them
322
+ if (
323
+ props.deploymentBranchPolicy?.customBranchPolicies === true &&
324
+ props.branchPatterns &&
325
+ props.branchPatterns.length > 0
326
+ ) {
327
+ // Add branch patterns one by one
328
+ for (const pattern of props.branchPatterns) {
329
+ await octokit.rest.repos.createDeploymentBranchPolicy({
330
+ owner: props.owner,
331
+ repo: props.repository,
332
+ environment_name: props.name,
333
+ name: pattern,
334
+ });
335
+ }
336
+ }
337
+ } else {
338
+ // Update the environment
339
+ await octokit.rest.repos.createOrUpdateEnvironment({
340
+ owner: props.owner,
341
+ repo: props.repository,
342
+ environment_name: props.name,
343
+ wait_timer: props.waitTimer,
344
+ prevent_self_review: props.preventSelfReview,
345
+ reviewers: reviewers.length > 0 ? reviewers : undefined,
346
+ deployment_branch_policy: props.deploymentBranchPolicy
347
+ ? {
348
+ protected_branches:
349
+ props.deploymentBranchPolicy.protectedBranches ?? false,
350
+ custom_branch_policies:
351
+ props.deploymentBranchPolicy.customBranchPolicies ?? false,
352
+ }
353
+ : undefined,
354
+ });
372
355
 
373
- const newPatterns: string[] = props.branchPatterns || [];
356
+ // If there are specific branch patterns, update them
357
+ if (props.deploymentBranchPolicy?.customBranchPolicies === true) {
358
+ // Get existing branch policies to understand what's currently configured
359
+ const { data: existingPolicies } =
360
+ await octokit.rest.repos.listDeploymentBranchPolicies({
361
+ owner: props.owner,
362
+ repo: props.repository,
363
+ environment_name: props.name,
364
+ });
374
365
 
375
- // For updates, keep track of which branch policies we should manage
376
- // This set identifies patterns that were previously managed by this resource
377
- // If we don't have previous props, use an empty set
378
- const previouslyManagedPatterns: Set<string> = new Set(
379
- this.phase === "update" &&
380
- this.props?.deploymentBranchPolicy?.customBranchPolicies === true
381
- ? this.props.branchPatterns || []
382
- : []
383
- );
366
+ const existingPatterns = existingPolicies.branch_policies.map(
367
+ (policy) => policy.name!,
368
+ );
384
369
 
385
- // Patterns to add (in new config but not in existing)
386
- const patternsToAdd = newPatterns.filter(
387
- (pattern) => !existingPatterns.includes(pattern)
388
- );
370
+ const newPatterns: string[] = props.branchPatterns || [];
389
371
 
390
- // Patterns to delete (were managed by us previously but not in new config)
391
- const patternsToDelete = existingPatterns.filter(
392
- (pattern) =>
393
- previouslyManagedPatterns.has(pattern) &&
394
- !newPatterns.includes(pattern)
395
- );
372
+ // For updates, keep track of which branch policies we should manage
373
+ // This set identifies patterns that were previously managed by this resource
374
+ // If we don't have previous props, use an empty set
375
+ const previouslyManagedPatterns: Set<string> = new Set(
376
+ this.phase === "update" &&
377
+ this.props?.deploymentBranchPolicy?.customBranchPolicies === true
378
+ ? this.props.branchPatterns || []
379
+ : [],
380
+ );
396
381
 
397
- // Delete policies that are no longer needed
398
- for (const patternToDelete of patternsToDelete) {
399
- const policy = existingPolicies.branch_policies.find(
400
- (p) => p.name === patternToDelete
401
- );
382
+ // Patterns to add (in new config but not in existing)
383
+ const patternsToAdd = newPatterns.filter(
384
+ (pattern) => !existingPatterns.includes(pattern),
385
+ );
402
386
 
403
- if (policy?.id) {
404
- await octokit.rest.repos.deleteDeploymentBranchPolicy({
405
- owner: props.owner,
406
- repo: props.repository,
407
- environment_name: props.name,
408
- branch_policy_id: policy.id,
409
- });
410
- }
411
- }
387
+ // Patterns to delete (were managed by us previously but not in new config)
388
+ const patternsToDelete = existingPatterns.filter(
389
+ (pattern) =>
390
+ previouslyManagedPatterns.has(pattern) &&
391
+ !newPatterns.includes(pattern),
392
+ );
412
393
 
413
- // Add new branch patterns
414
- for (const pattern of patternsToAdd) {
415
- await octokit.rest.repos.createDeploymentBranchPolicy({
394
+ // Delete policies that are no longer needed
395
+ for (const patternToDelete of patternsToDelete) {
396
+ const policy = existingPolicies.branch_policies.find(
397
+ (p) => p.name === patternToDelete,
398
+ );
399
+
400
+ if (policy?.id) {
401
+ await octokit.rest.repos.deleteDeploymentBranchPolicy({
416
402
  owner: props.owner,
417
403
  repo: props.repository,
418
404
  environment_name: props.name,
419
- name: pattern,
405
+ branch_policy_id: policy.id,
420
406
  });
421
407
  }
422
408
  }
423
- }
424
409
 
425
- // Get the updated environment details
426
- const { data: env } = await octokit.rest.repos.getEnvironment({
427
- owner: props.owner,
428
- repo: props.repository,
429
- environment_name: props.name,
430
- });
431
-
432
- // Return environment details
433
- return this({
434
- id: `${props.owner}/${props.repository}/${props.name}`,
435
- environmentId: environmentId || env.id,
436
- owner: props.owner,
437
- repository: props.repository,
438
- name: props.name,
439
- waitTimer: props.waitTimer,
440
- preventSelfReview: props.preventSelfReview,
441
- adminBypass: props.adminBypass,
442
- reviewers: props.reviewers,
443
- deploymentBranchPolicy: props.deploymentBranchPolicy,
444
- branchPatterns: props.branchPatterns,
445
- token: props.token,
446
- updatedAt: new Date().toISOString(),
447
- });
448
- } catch (error: any) {
449
- if (
450
- error.status === 403 &&
451
- error.message?.includes("Must have admin rights")
452
- ) {
453
- console.error(
454
- "\n⚠️ Error creating/updating GitHub environment: You must have admin rights to the repository."
455
- );
456
- console.error(
457
- "Make sure your GitHub token has the required permissions (repo scope for private repos).\n"
458
- );
459
- } else {
460
- console.error(
461
- "Error creating/updating GitHub environment:",
462
- error.message
463
- );
410
+ // Add new branch patterns
411
+ for (const pattern of patternsToAdd) {
412
+ await octokit.rest.repos.createDeploymentBranchPolicy({
413
+ owner: props.owner,
414
+ repo: props.repository,
415
+ environment_name: props.name,
416
+ name: pattern,
417
+ });
418
+ }
464
419
  }
465
- throw error;
466
420
  }
421
+
422
+ // Get the updated environment details
423
+ const { data: env } = await octokit.rest.repos.getEnvironment({
424
+ owner: props.owner,
425
+ repo: props.repository,
426
+ environment_name: props.name,
427
+ });
428
+
429
+ // Return environment details
430
+ return this({
431
+ id: `${props.owner}/${props.repository}/${props.name}`,
432
+ environmentId: environmentId || env.id,
433
+ owner: props.owner,
434
+ repository: props.repository,
435
+ name: props.name,
436
+ waitTimer: props.waitTimer,
437
+ preventSelfReview: props.preventSelfReview,
438
+ adminBypass: props.adminBypass,
439
+ reviewers: props.reviewers,
440
+ deploymentBranchPolicy: props.deploymentBranchPolicy,
441
+ branchPatterns: props.branchPatterns,
442
+ token: props.token,
443
+ updatedAt: new Date().toISOString(),
444
+ });
445
+ } catch (error: any) {
446
+ if (
447
+ error.status === 403 &&
448
+ error.message?.includes("Must have admin rights")
449
+ ) {
450
+ console.error(
451
+ "\n⚠️ Error creating/updating GitHub environment: You must have admin rights to the repository.",
452
+ );
453
+ console.error(
454
+ "Make sure your GitHub token has the required permissions (repo scope for private repos).\n",
455
+ );
456
+ } else {
457
+ console.error(
458
+ "Error creating/updating GitHub environment:",
459
+ error.message,
460
+ );
461
+ }
462
+ throw error;
467
463
  }
468
- }
464
+ },
469
465
  );