alchemy-effect 0.5.0 → 0.6.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 (215) hide show
  1. package/README.md +13 -7
  2. package/bin/alchemy-effect.js +16 -17
  3. package/bin/alchemy-effect.js.map +1 -1
  4. package/lib/apply.d.ts.map +1 -1
  5. package/lib/apply.js +19 -17
  6. package/lib/apply.js.map +1 -1
  7. package/lib/aws/client.d.ts.map +1 -1
  8. package/lib/aws/client.js +15 -2
  9. package/lib/aws/client.js.map +1 -1
  10. package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -1
  11. package/lib/aws/dynamodb/table.d.ts.map +1 -1
  12. package/lib/aws/dynamodb/table.js.map +1 -1
  13. package/lib/aws/ec2/egress-only-igw.d.ts +55 -0
  14. package/lib/aws/ec2/egress-only-igw.d.ts.map +1 -0
  15. package/lib/aws/ec2/egress-only-igw.js +4 -0
  16. package/lib/aws/ec2/egress-only-igw.js.map +1 -0
  17. package/lib/aws/ec2/egress-only-igw.provider.d.ts +6 -0
  18. package/lib/aws/ec2/egress-only-igw.provider.d.ts.map +1 -0
  19. package/lib/aws/ec2/egress-only-igw.provider.js +114 -0
  20. package/lib/aws/ec2/egress-only-igw.provider.js.map +1 -0
  21. package/lib/aws/ec2/eip.d.ts +85 -0
  22. package/lib/aws/ec2/eip.d.ts.map +1 -0
  23. package/lib/aws/ec2/eip.js +4 -0
  24. package/lib/aws/ec2/eip.js.map +1 -0
  25. package/lib/aws/ec2/eip.provider.d.ts +6 -0
  26. package/lib/aws/ec2/eip.provider.d.ts.map +1 -0
  27. package/lib/aws/ec2/eip.provider.js +135 -0
  28. package/lib/aws/ec2/eip.provider.js.map +1 -0
  29. package/lib/aws/ec2/index.d.ts +18 -0
  30. package/lib/aws/ec2/index.d.ts.map +1 -1
  31. package/lib/aws/ec2/index.js +18 -0
  32. package/lib/aws/ec2/index.js.map +1 -1
  33. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -1
  34. package/lib/aws/ec2/internet-gateway.provider.d.ts.map +1 -1
  35. package/lib/aws/ec2/internet-gateway.provider.js +9 -5
  36. package/lib/aws/ec2/internet-gateway.provider.js.map +1 -1
  37. package/lib/aws/ec2/nat-gateway.d.ts +127 -0
  38. package/lib/aws/ec2/nat-gateway.d.ts.map +1 -0
  39. package/lib/aws/ec2/nat-gateway.js +4 -0
  40. package/lib/aws/ec2/nat-gateway.js.map +1 -0
  41. package/lib/aws/ec2/nat-gateway.provider.d.ts +6 -0
  42. package/lib/aws/ec2/nat-gateway.provider.d.ts.map +1 -0
  43. package/lib/aws/ec2/nat-gateway.provider.js +222 -0
  44. package/lib/aws/ec2/nat-gateway.provider.js.map +1 -0
  45. package/lib/aws/ec2/network-acl-association.d.ts +44 -0
  46. package/lib/aws/ec2/network-acl-association.d.ts.map +1 -0
  47. package/lib/aws/ec2/network-acl-association.js +4 -0
  48. package/lib/aws/ec2/network-acl-association.js.map +1 -0
  49. package/lib/aws/ec2/network-acl-association.provider.d.ts +4 -0
  50. package/lib/aws/ec2/network-acl-association.provider.d.ts.map +1 -0
  51. package/lib/aws/ec2/network-acl-association.provider.js +115 -0
  52. package/lib/aws/ec2/network-acl-association.provider.js.map +1 -0
  53. package/lib/aws/ec2/network-acl-entry.d.ts +118 -0
  54. package/lib/aws/ec2/network-acl-entry.d.ts.map +1 -0
  55. package/lib/aws/ec2/network-acl-entry.js +3 -0
  56. package/lib/aws/ec2/network-acl-entry.js.map +1 -0
  57. package/lib/aws/ec2/network-acl-entry.provider.d.ts +4 -0
  58. package/lib/aws/ec2/network-acl-entry.provider.d.ts.map +1 -0
  59. package/lib/aws/ec2/network-acl-entry.provider.js +129 -0
  60. package/lib/aws/ec2/network-acl-entry.provider.js.map +1 -0
  61. package/lib/aws/ec2/network-acl.d.ts +82 -0
  62. package/lib/aws/ec2/network-acl.d.ts.map +1 -0
  63. package/lib/aws/ec2/network-acl.js +4 -0
  64. package/lib/aws/ec2/network-acl.js.map +1 -0
  65. package/lib/aws/ec2/network-acl.provider.d.ts +6 -0
  66. package/lib/aws/ec2/network-acl.provider.d.ts.map +1 -0
  67. package/lib/aws/ec2/network-acl.provider.js +136 -0
  68. package/lib/aws/ec2/network-acl.provider.js.map +1 -0
  69. package/lib/aws/ec2/route-table-association.d.ts.map +1 -1
  70. package/lib/aws/ec2/route-table-association.provider.d.ts.map +1 -1
  71. package/lib/aws/ec2/route-table-association.provider.js.map +1 -1
  72. package/lib/aws/ec2/route-table.d.ts.map +1 -1
  73. package/lib/aws/ec2/route-table.provider.d.ts.map +1 -1
  74. package/lib/aws/ec2/route-table.provider.js.map +1 -1
  75. package/lib/aws/ec2/route.d.ts.map +1 -1
  76. package/lib/aws/ec2/route.provider.d.ts.map +1 -1
  77. package/lib/aws/ec2/route.provider.js.map +1 -1
  78. package/lib/aws/ec2/security-group-rule.d.ts +118 -0
  79. package/lib/aws/ec2/security-group-rule.d.ts.map +1 -0
  80. package/lib/aws/ec2/security-group-rule.js +4 -0
  81. package/lib/aws/ec2/security-group-rule.js.map +1 -0
  82. package/lib/aws/ec2/security-group-rule.provider.d.ts +4 -0
  83. package/lib/aws/ec2/security-group-rule.provider.d.ts.map +1 -0
  84. package/lib/aws/ec2/security-group-rule.provider.js +193 -0
  85. package/lib/aws/ec2/security-group-rule.provider.js.map +1 -0
  86. package/lib/aws/ec2/security-group.d.ts +147 -0
  87. package/lib/aws/ec2/security-group.d.ts.map +1 -0
  88. package/lib/aws/ec2/security-group.js +4 -0
  89. package/lib/aws/ec2/security-group.js.map +1 -0
  90. package/lib/aws/ec2/security-group.provider.d.ts +6 -0
  91. package/lib/aws/ec2/security-group.provider.d.ts.map +1 -0
  92. package/lib/aws/ec2/security-group.provider.js +291 -0
  93. package/lib/aws/ec2/security-group.provider.js.map +1 -0
  94. package/lib/aws/ec2/subnet.d.ts.map +1 -1
  95. package/lib/aws/ec2/subnet.provider.d.ts.map +1 -1
  96. package/lib/aws/ec2/subnet.provider.js +33 -30
  97. package/lib/aws/ec2/subnet.provider.js.map +1 -1
  98. package/lib/aws/ec2/vpc-endpoint.d.ts +176 -0
  99. package/lib/aws/ec2/vpc-endpoint.d.ts.map +1 -0
  100. package/lib/aws/ec2/vpc-endpoint.js +4 -0
  101. package/lib/aws/ec2/vpc-endpoint.js.map +1 -0
  102. package/lib/aws/ec2/vpc-endpoint.provider.d.ts +6 -0
  103. package/lib/aws/ec2/vpc-endpoint.provider.d.ts.map +1 -0
  104. package/lib/aws/ec2/vpc-endpoint.provider.js +315 -0
  105. package/lib/aws/ec2/vpc-endpoint.provider.js.map +1 -0
  106. package/lib/aws/ec2/vpc.d.ts.map +1 -1
  107. package/lib/aws/ec2/vpc.provider.d.ts +2 -2
  108. package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
  109. package/lib/aws/ec2/vpc.provider.js +38 -31
  110. package/lib/aws/ec2/vpc.provider.js.map +1 -1
  111. package/lib/aws/index.d.ts +2 -2
  112. package/lib/aws/index.d.ts.map +1 -1
  113. package/lib/aws/index.js +1 -1
  114. package/lib/aws/index.js.map +1 -1
  115. package/lib/aws/lambda/function.d.ts.map +1 -1
  116. package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
  117. package/lib/aws/lambda/function.invoke.js.map +1 -1
  118. package/lib/aws/lambda/function.js.map +1 -1
  119. package/lib/aws/sqs/queue.d.ts +1 -2
  120. package/lib/aws/sqs/queue.d.ts.map +1 -1
  121. package/lib/aws/sqs/queue.event-source.d.ts.map +1 -1
  122. package/lib/aws/sqs/queue.event-source.js +2 -2
  123. package/lib/aws/sqs/queue.event-source.js.map +1 -1
  124. package/lib/aws/sqs/queue.js.map +1 -1
  125. package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
  126. package/lib/aws/sqs/queue.provider.js +22 -14
  127. package/lib/aws/sqs/queue.provider.js.map +1 -1
  128. package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
  129. package/lib/aws/sqs/queue.send-message.js.map +1 -1
  130. package/lib/binding.d.ts.map +1 -1
  131. package/lib/cli/components/PlanProgress.d.ts.map +1 -1
  132. package/lib/cli/components/PlanProgress.js.map +1 -1
  133. package/lib/cli/index.d.ts +1 -1
  134. package/lib/cli/index.d.ts.map +1 -1
  135. package/lib/cli/index.js.map +1 -1
  136. package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -1
  137. package/lib/cloudflare/kv/namespace.binding.js.map +1 -1
  138. package/lib/cloudflare/kv/namespace.d.ts.map +1 -1
  139. package/lib/cloudflare/kv/namespace.provider.d.ts +1 -2
  140. package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
  141. package/lib/cloudflare/kv/namespace.provider.js +0 -2
  142. package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
  143. package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -1
  144. package/lib/cloudflare/r2/bucket.binding.js.map +1 -1
  145. package/lib/cloudflare/r2/bucket.d.ts.map +1 -1
  146. package/lib/output.d.ts.map +1 -1
  147. package/lib/output.js.map +1 -1
  148. package/lib/plan.d.ts +2 -2
  149. package/lib/plan.d.ts.map +1 -1
  150. package/lib/plan.js +14 -13
  151. package/lib/plan.js.map +1 -1
  152. package/lib/provider.d.ts +1 -1
  153. package/lib/provider.d.ts.map +1 -1
  154. package/lib/provider.js.map +1 -1
  155. package/lib/runtime.d.ts.map +1 -1
  156. package/lib/tags.d.ts +12 -0
  157. package/lib/tags.d.ts.map +1 -1
  158. package/lib/tags.js +24 -0
  159. package/lib/tags.js.map +1 -1
  160. package/lib/tsconfig.test.tsbuildinfo +1 -1
  161. package/package.json +51 -51
  162. package/src/apply.ts +21 -12
  163. package/src/aws/client.ts +22 -1
  164. package/src/aws/dynamodb/secondary-index.ts +5 -5
  165. package/src/aws/dynamodb/table.ts +8 -11
  166. package/src/aws/ec2/egress-only-igw.provider.ts +181 -0
  167. package/src/aws/ec2/egress-only-igw.ts +77 -0
  168. package/src/aws/ec2/eip.provider.ts +191 -0
  169. package/src/aws/ec2/eip.ts +106 -0
  170. package/src/aws/ec2/index.ts +18 -0
  171. package/src/aws/ec2/internet-gateway.provider.ts +15 -6
  172. package/src/aws/ec2/internet-gateway.ts +6 -6
  173. package/src/aws/ec2/nat-gateway.provider.ts +341 -0
  174. package/src/aws/ec2/nat-gateway.ts +155 -0
  175. package/src/aws/ec2/network-acl-association.provider.ts +181 -0
  176. package/src/aws/ec2/network-acl-association.ts +60 -0
  177. package/src/aws/ec2/network-acl-entry.provider.ts +218 -0
  178. package/src/aws/ec2/network-acl-entry.ts +140 -0
  179. package/src/aws/ec2/network-acl.provider.ts +195 -0
  180. package/src/aws/ec2/network-acl.ts +102 -0
  181. package/src/aws/ec2/route-table-association.provider.ts +1 -2
  182. package/src/aws/ec2/route-table-association.ts +6 -6
  183. package/src/aws/ec2/route-table.provider.ts +1 -2
  184. package/src/aws/ec2/route-table.ts +6 -6
  185. package/src/aws/ec2/route.provider.ts +1 -2
  186. package/src/aws/ec2/route.ts +6 -6
  187. package/src/aws/ec2/security-group-rule.provider.ts +264 -0
  188. package/src/aws/ec2/security-group-rule.ts +151 -0
  189. package/src/aws/ec2/security-group.provider.ts +392 -0
  190. package/src/aws/ec2/security-group.ts +182 -0
  191. package/src/aws/ec2/subnet.provider.ts +57 -56
  192. package/src/aws/ec2/subnet.ts +6 -6
  193. package/src/aws/ec2/vpc-endpoint.provider.ts +466 -0
  194. package/src/aws/ec2/vpc-endpoint.ts +213 -0
  195. package/src/aws/ec2/vpc.provider.ts +58 -51
  196. package/src/aws/ec2/vpc.ts +6 -6
  197. package/src/aws/index.ts +9 -0
  198. package/src/aws/lambda/function.invoke.ts +4 -2
  199. package/src/aws/lambda/function.ts +4 -2
  200. package/src/aws/sqs/queue.event-source.ts +12 -14
  201. package/src/aws/sqs/queue.provider.ts +25 -15
  202. package/src/aws/sqs/queue.send-message.ts +4 -2
  203. package/src/aws/sqs/queue.ts +1 -8
  204. package/src/binding.ts +7 -7
  205. package/src/cli/components/PlanProgress.tsx +3 -2
  206. package/src/cloudflare/kv/namespace.binding.ts +4 -2
  207. package/src/cloudflare/kv/namespace.provider.ts +0 -2
  208. package/src/cloudflare/kv/namespace.ts +6 -6
  209. package/src/cloudflare/r2/bucket.binding.ts +4 -2
  210. package/src/cloudflare/r2/bucket.ts +6 -6
  211. package/src/output.ts +5 -3
  212. package/src/plan.ts +26 -20
  213. package/src/provider.ts +12 -11
  214. package/src/runtime.ts +2 -2
  215. package/src/tags.ts +29 -0
@@ -23,12 +23,12 @@ export interface Bucket<
23
23
  ID extends string = string,
24
24
  Props extends BucketProps = BucketProps,
25
25
  > extends Resource<
26
- "Cloudflare.R2.Bucket",
27
- ID,
28
- Props,
29
- BucketAttr<Props>,
30
- Bucket
31
- > {}
26
+ "Cloudflare.R2.Bucket",
27
+ ID,
28
+ Props,
29
+ BucketAttr<Props>,
30
+ Bucket
31
+ > {}
32
32
 
33
33
  export const Bucket = Resource<{
34
34
  <const ID extends string, const Props extends BucketProps>(
package/src/output.ts CHANGED
@@ -132,9 +132,11 @@ const proxy = (self: any): any => {
132
132
  return proxy;
133
133
  };
134
134
 
135
- export abstract class BaseExpr<A = any, Src extends Resource = any, Req = any>
136
- implements Output<A, Src, Req>
137
- {
135
+ export abstract class BaseExpr<
136
+ A = any,
137
+ Src extends Resource = any,
138
+ Req = any,
139
+ > implements Output<A, Src, Req> {
138
140
  declare readonly kind: any;
139
141
  declare readonly src: Src;
140
142
  declare readonly req: Req;
package/src/plan.ts CHANGED
@@ -11,25 +11,25 @@ import type {
11
11
  } from "./binding.ts";
12
12
  import type { Capability } from "./capability.ts";
13
13
  import type { Diff, NoopDiff, UpdateDiff } from "./diff.ts";
14
+ import { InstanceId } from "./instance-id.ts";
14
15
  import * as Output from "./output.ts";
15
16
  import type { Instance } from "./policy.ts";
16
17
  import type { Provider } from "./provider.ts";
17
- import { type ProviderService, getProviderByType } from "./provider.ts";
18
+ import { getProviderByType, type ProviderService } from "./provider.ts";
18
19
  import type { AnyResource, Resource, ResourceTags } from "./resource.ts";
19
20
  import { isService, type IService, type Service } from "./service.ts";
20
21
  import {
22
+ State,
23
+ StateStoreError,
21
24
  type CreatedResourceState,
22
25
  type CreatingResourceState,
23
26
  type ReplacedResourceState,
24
27
  type ReplacingResourceState,
28
+ type ResourceState,
25
29
  type UpdatedResourceState,
26
30
  type UpdatingReourceState,
27
- State,
28
- StateStoreError,
29
- type ResourceState,
30
31
  } from "./state.ts";
31
32
  import { asEffect } from "./util.ts";
32
- import { InstanceId } from "./instance-id.ts";
33
33
 
34
34
  export type PlanError = never;
35
35
 
@@ -136,8 +136,9 @@ export interface Delete<R extends Resource = AnyResource> extends BaseNode<R> {
136
136
  state: ResourceState;
137
137
  }
138
138
 
139
- export interface NoopUpdate<R extends Resource = AnyResource>
140
- extends BaseNode<R> {
139
+ export interface NoopUpdate<
140
+ R extends Resource = AnyResource,
141
+ > extends BaseNode<R> {
141
142
  action: "noop";
142
143
  state: CreatedResourceState | UpdatedResourceState;
143
144
  }
@@ -205,7 +206,9 @@ export type TransitiveResources<
205
206
  >
206
207
  ? Src extends Found
207
208
  ? Found
208
- : TransitiveResources<Src, Src | Found>
209
+ : string extends Src["id"]
210
+ ? Found
211
+ : TransitiveResources<Src, Src | Found>
209
212
  : Found;
210
213
  }[keyof Resources["props"][prop]];
211
214
  }[keyof Resources["props"]],
@@ -292,6 +295,7 @@ export const plan = <const Resources extends (Service | Resource)[]>(
292
295
  resourceIds.map((id) =>
293
296
  state.get({ stack: app.name, stage: app.stage, resourceId: id }),
294
297
  ),
298
+ { concurrency: "unbounded" },
295
299
  );
296
300
 
297
301
  type ResolveEffect<T> = Effect.Effect<T, ResolveErr, ResolveReq>;
@@ -414,13 +418,16 @@ export const plan = <const Resources extends (Service | Resource)[]>(
414
418
  } else if (Output.isExpr(input)) {
415
419
  return yield* resolveOutput(input);
416
420
  } else if (Array.isArray(input)) {
417
- return yield* Effect.all(input.map(resolveInput));
421
+ return yield* Effect.all(input.map(resolveInput), {
422
+ concurrency: "unbounded",
423
+ });
418
424
  } else if (typeof input === "object") {
419
425
  return Object.fromEntries(
420
426
  yield* Effect.all(
421
427
  Object.entries(input).map(([key, value]) =>
422
428
  resolveInput(value).pipe(Effect.map((value) => [key, value])),
423
429
  ),
430
+ { concurrency: "unbounded" },
424
431
  ),
425
432
  );
426
433
  }
@@ -441,7 +448,9 @@ export const plan = <const Resources extends (Service | Resource)[]>(
441
448
  const upstream = yield* resolveOutput(expr.expr);
442
449
  return Output.hasOutputs(upstream) ? expr : yield* expr.f(upstream);
443
450
  } else if (Output.isAllExpr(expr)) {
444
- return yield* Effect.all(expr.outs.map(resolveOutput));
451
+ return yield* Effect.all(expr.outs.map(resolveOutput), {
452
+ concurrency: "unbounded",
453
+ });
445
454
  }
446
455
  return yield* Effect.die(new Error("Not implemented yet"));
447
456
  });
@@ -754,6 +763,7 @@ export const plan = <const Resources extends (Service | Resource)[]>(
754
763
  }
755
764
  }),
756
765
  ),
766
+ { concurrency: "unbounded" },
757
767
  )).map((update) => [update.resource.id, update]),
758
768
  ) as IPlan["resources"];
759
769
 
@@ -778,8 +788,8 @@ export const plan = <const Resources extends (Service | Resource)[]>(
778
788
  .read({
779
789
  id,
780
790
  instanceId: oldState.instanceId,
781
- olds: oldState.props as any,
782
- output: oldState.attr as any,
791
+ olds: oldState.props as never,
792
+ output: oldState.attr as never,
783
793
  bindings: oldState.bindings ?? [],
784
794
  })
785
795
  .pipe(
@@ -788,11 +798,6 @@ export const plan = <const Resources extends (Service | Resource)[]>(
788
798
  ),
789
799
  );
790
800
  }
791
- if (attr === undefined) {
792
- // skip deletion if we have no record of any attributes
793
- // TODO(sam): should we open up provider.delete to accept undefined and let it try and generate a physical name and delete?
794
- return undefined;
795
- }
796
801
  }
797
802
  return [
798
803
  id,
@@ -815,6 +820,7 @@ export const plan = <const Resources extends (Service | Resource)[]>(
815
820
  }
816
821
  }),
817
822
  ),
823
+ { concurrency: "unbounded" },
818
824
  )).filter((v) => !!v),
819
825
  );
820
826
 
@@ -948,9 +954,9 @@ const diffBindings = Effect.fn(function* ({
948
954
  },
949
955
  );
950
956
 
951
- return (yield* Effect.all(bindings.map(diffBinding))).filter(
952
- (action): action is BindNode => action !== null,
953
- );
957
+ return (yield* Effect.all(bindings.map(diffBinding), {
958
+ concurrency: "unbounded",
959
+ })).filter((action): action is BindNode => action !== null);
954
960
  });
955
961
 
956
962
  const isBindingDiff = Effect.fn(function* ({
package/src/provider.ts CHANGED
@@ -7,17 +7,18 @@ import type { Resource } from "./resource.ts";
7
7
  import type { Runtime } from "./runtime.ts";
8
8
  import type { Service } from "./service.ts";
9
9
 
10
- export interface Provider<R extends Resource | Service>
11
- extends Context.TagClass<
12
- Provider<R>,
13
- R["type"],
14
- ProviderService<any>
15
- // TODO(sam): we are using any here because the R["type"] is enough and gaining access to the sub type (e.g. SQS.Queue)
16
- // is currently not possible in the current approach
10
+ export interface Provider<
11
+ R extends Resource | Service,
12
+ > extends Context.TagClass<
13
+ Provider<R>,
14
+ R["type"],
15
+ ProviderService<any>
16
+ // TODO(sam): we are using any here because the R["type"] is enough and gaining access to the sub type (e.g. SQS.Queue)
17
+ // is currently not possible in the current approach
17
18
 
18
- // preferred:
19
- // ProviderService<R>
20
- > {}
19
+ // preferred:
20
+ // ProviderService<R>
21
+ > {}
21
22
 
22
23
  type BindingData<Res extends Resource> = [Res] extends [Runtime]
23
24
  ? Res["binding"][]
@@ -48,7 +49,7 @@ export interface ProviderService<
48
49
  read?(input: {
49
50
  id: string;
50
51
  instanceId: string;
51
- olds: Props<Res> | undefined;
52
+ olds: Props<Res>;
52
53
  // what is the ARN?
53
54
  output: Res["attr"] | undefined; // current state -> synced state
54
55
  bindings: BindingData<Res>;
package/src/runtime.ts CHANGED
@@ -58,8 +58,8 @@ export interface Runtime<
58
58
  Type extends string = string,
59
59
  Handler = unknown,
60
60
  Props = unknown,
61
- > extends IRuntime<Type, Handler, Props>,
62
- Resource<Type, string, Props> {
61
+ >
62
+ extends IRuntime<Type, Handler, Props>, Resource<Type, string, Props> {
63
63
  provider: ResourceTags<this>;
64
64
  <
65
65
  const ID extends string,
package/src/tags.ts CHANGED
@@ -37,6 +37,35 @@ export const createTagger = Effect.fn(function* () {
37
37
  });
38
38
  });
39
39
 
40
+ /**
41
+ * Creates AWS-compatible tag filters for finding resources by alchemy tags.
42
+ * Use with AWS describe APIs that accept Filter parameters.
43
+ */
44
+ export const createAlchemyTagFilters = Effect.fn(function* (id: string) {
45
+ const app = yield* App;
46
+ return [
47
+ { Name: "tag:alchemy::app", Values: [app.name] },
48
+ { Name: "tag:alchemy::stage", Values: [app.stage] },
49
+ { Name: "tag:alchemy::id", Values: [id] },
50
+ ];
51
+ });
52
+
53
+ /**
54
+ * Checks if a resource has the expected alchemy tags for this app/stage/id.
55
+ */
56
+ export const hasAlchemyTags = Effect.fn(function* (
57
+ id: string,
58
+ tags: Tags | undefined,
59
+ ) {
60
+ const app = yield* App;
61
+ const expectedTags = {
62
+ "alchemy::app": app.name,
63
+ "alchemy::stage": app.stage,
64
+ "alchemy::id": id,
65
+ };
66
+ return hasTags(expectedTags, tags);
67
+ });
68
+
40
69
  export const diffTags = (
41
70
  oldTags: Record<string, string>,
42
71
  newTags: Record<string, string>,