@microagi/alchemy-gcp 0.1.2

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 (123) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +88 -0
  3. package/lib/Auth/AuthProvider.d.ts +48 -0
  4. package/lib/Auth/AuthProvider.d.ts.map +1 -0
  5. package/lib/Auth/AuthProvider.js +84 -0
  6. package/lib/Auth/AuthProvider.js.map +1 -0
  7. package/lib/Auth/Credentials.d.ts +28 -0
  8. package/lib/Auth/Credentials.d.ts.map +1 -0
  9. package/lib/Auth/Credentials.js +41 -0
  10. package/lib/Auth/Credentials.js.map +1 -0
  11. package/lib/CloudResourceManager/Project.d.ts +143 -0
  12. package/lib/CloudResourceManager/Project.d.ts.map +1 -0
  13. package/lib/CloudResourceManager/Project.js +272 -0
  14. package/lib/CloudResourceManager/Project.js.map +1 -0
  15. package/lib/CloudResourceManager/index.d.ts +3 -0
  16. package/lib/CloudResourceManager/index.d.ts.map +1 -0
  17. package/lib/CloudResourceManager/index.js +2 -0
  18. package/lib/CloudResourceManager/index.js.map +1 -0
  19. package/lib/Compute/GlobalAddress.d.ts +101 -0
  20. package/lib/Compute/GlobalAddress.d.ts.map +1 -0
  21. package/lib/Compute/GlobalAddress.js +134 -0
  22. package/lib/Compute/GlobalAddress.js.map +1 -0
  23. package/lib/Compute/Network.d.ts +114 -0
  24. package/lib/Compute/Network.d.ts.map +1 -0
  25. package/lib/Compute/Network.js +145 -0
  26. package/lib/Compute/Network.js.map +1 -0
  27. package/lib/Compute/Operations.d.ts +34 -0
  28. package/lib/Compute/Operations.d.ts.map +1 -0
  29. package/lib/Compute/Operations.js +62 -0
  30. package/lib/Compute/Operations.js.map +1 -0
  31. package/lib/Compute/SharedVpcHost.d.ts +44 -0
  32. package/lib/Compute/SharedVpcHost.d.ts.map +1 -0
  33. package/lib/Compute/SharedVpcHost.js +71 -0
  34. package/lib/Compute/SharedVpcHost.js.map +1 -0
  35. package/lib/Compute/SharedVpcServiceProject.d.ts +46 -0
  36. package/lib/Compute/SharedVpcServiceProject.d.ts.map +1 -0
  37. package/lib/Compute/SharedVpcServiceProject.js +96 -0
  38. package/lib/Compute/SharedVpcServiceProject.js.map +1 -0
  39. package/lib/Compute/Subnetwork.d.ts +108 -0
  40. package/lib/Compute/Subnetwork.d.ts.map +1 -0
  41. package/lib/Compute/Subnetwork.js +201 -0
  42. package/lib/Compute/Subnetwork.js.map +1 -0
  43. package/lib/Compute/index.d.ts +6 -0
  44. package/lib/Compute/index.d.ts.map +1 -0
  45. package/lib/Compute/index.js +6 -0
  46. package/lib/Compute/index.js.map +1 -0
  47. package/lib/Container/Cluster.d.ts +216 -0
  48. package/lib/Container/Cluster.d.ts.map +1 -0
  49. package/lib/Container/Cluster.js +326 -0
  50. package/lib/Container/Cluster.js.map +1 -0
  51. package/lib/Container/NodePool.d.ts +214 -0
  52. package/lib/Container/NodePool.d.ts.map +1 -0
  53. package/lib/Container/NodePool.js +344 -0
  54. package/lib/Container/NodePool.js.map +1 -0
  55. package/lib/Container/Operations.d.ts +50 -0
  56. package/lib/Container/Operations.d.ts.map +1 -0
  57. package/lib/Container/Operations.js +51 -0
  58. package/lib/Container/Operations.js.map +1 -0
  59. package/lib/Container/index.d.ts +5 -0
  60. package/lib/Container/index.d.ts.map +1 -0
  61. package/lib/Container/index.js +3 -0
  62. package/lib/Container/index.js.map +1 -0
  63. package/lib/Parallelstore/Instance.d.ts +119 -0
  64. package/lib/Parallelstore/Instance.d.ts.map +1 -0
  65. package/lib/Parallelstore/Instance.js +180 -0
  66. package/lib/Parallelstore/Instance.js.map +1 -0
  67. package/lib/Parallelstore/index.d.ts +2 -0
  68. package/lib/Parallelstore/index.d.ts.map +1 -0
  69. package/lib/Parallelstore/index.js +2 -0
  70. package/lib/Parallelstore/index.js.map +1 -0
  71. package/lib/Providers.d.ts +24 -0
  72. package/lib/Providers.d.ts.map +1 -0
  73. package/lib/Providers.js +51 -0
  74. package/lib/Providers.js.map +1 -0
  75. package/lib/ServiceNetworking/PsaConnection.d.ts +84 -0
  76. package/lib/ServiceNetworking/PsaConnection.d.ts.map +1 -0
  77. package/lib/ServiceNetworking/PsaConnection.js +130 -0
  78. package/lib/ServiceNetworking/PsaConnection.js.map +1 -0
  79. package/lib/ServiceNetworking/index.d.ts +2 -0
  80. package/lib/ServiceNetworking/index.d.ts.map +1 -0
  81. package/lib/ServiceNetworking/index.js +2 -0
  82. package/lib/ServiceNetworking/index.js.map +1 -0
  83. package/lib/ServiceUsage/ApiEnable.d.ts +78 -0
  84. package/lib/ServiceUsage/ApiEnable.d.ts.map +1 -0
  85. package/lib/ServiceUsage/ApiEnable.js +132 -0
  86. package/lib/ServiceUsage/ApiEnable.js.map +1 -0
  87. package/lib/ServiceUsage/index.d.ts +3 -0
  88. package/lib/ServiceUsage/index.d.ts.map +1 -0
  89. package/lib/ServiceUsage/index.js +2 -0
  90. package/lib/ServiceUsage/index.js.map +1 -0
  91. package/lib/Tags.d.ts +57 -0
  92. package/lib/Tags.d.ts.map +1 -0
  93. package/lib/Tags.js +106 -0
  94. package/lib/Tags.js.map +1 -0
  95. package/lib/index.d.ts +11 -0
  96. package/lib/index.d.ts.map +1 -0
  97. package/lib/index.js +10 -0
  98. package/lib/index.js.map +1 -0
  99. package/package.json +70 -0
  100. package/src/Auth/AuthProvider.ts +180 -0
  101. package/src/Auth/Credentials.ts +69 -0
  102. package/src/CloudResourceManager/Project.ts +517 -0
  103. package/src/CloudResourceManager/index.ts +2 -0
  104. package/src/Compute/GlobalAddress.ts +283 -0
  105. package/src/Compute/Network.ts +306 -0
  106. package/src/Compute/Operations.ts +108 -0
  107. package/src/Compute/SharedVpcHost.ts +141 -0
  108. package/src/Compute/SharedVpcServiceProject.ts +185 -0
  109. package/src/Compute/Subnetwork.ts +375 -0
  110. package/src/Compute/index.ts +5 -0
  111. package/src/Container/Cluster.ts +599 -0
  112. package/src/Container/NodePool.ts +620 -0
  113. package/src/Container/Operations.ts +88 -0
  114. package/src/Container/index.ts +8 -0
  115. package/src/Parallelstore/Instance.ts +371 -0
  116. package/src/Parallelstore/index.ts +1 -0
  117. package/src/Providers.ts +84 -0
  118. package/src/ServiceNetworking/PsaConnection.ts +269 -0
  119. package/src/ServiceNetworking/index.ts +1 -0
  120. package/src/ServiceUsage/ApiEnable.ts +267 -0
  121. package/src/ServiceUsage/index.ts +2 -0
  122. package/src/Tags.ts +130 -0
  123. package/src/index.ts +16 -0
@@ -0,0 +1,130 @@
1
+ import { ConfigError } from "@distilled.cloud/gcp";
2
+ import * as sn from "@distilled.cloud/gcp/servicenetworking-v1";
3
+ import { Resource } from "alchemy";
4
+ import { deepEqual, isResolved } from "alchemy/Diff";
5
+ import * as Provider from "alchemy/Provider";
6
+ import * as Duration from "effect/Duration";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Schedule from "effect/Schedule";
9
+ export const PsaConnection = Resource("GCP.PsaConnection");
10
+ const DEFAULT_SERVICE = "servicenetworking.googleapis.com";
11
+ const serviceParent = (service) => service.startsWith("services/") ? service : `services/${service}`;
12
+ export const PsaConnectionProvider = () => Provider.effect(PsaConnection, Effect.gen(function* () {
13
+ const listConnections = yield* sn.listServicesConnections;
14
+ const createConnection = yield* sn.createServicesConnections;
15
+ const patchConnection = yield* sn.patchServicesConnections;
16
+ const deleteConnection = yield* sn.deleteConnectionServicesConnections;
17
+ const getOperations = yield* sn.getOperations;
18
+ const awaitOperation = Effect.fn(function* (operationName, session) {
19
+ const op = yield* getOperations({ name: operationName }).pipe(Effect.flatMap((current) => current.done === true
20
+ ? Effect.succeed(current)
21
+ : Effect.fail({ _tag: "OperationPending" })), Effect.retry({
22
+ while: (e) => e?._tag === "OperationPending",
23
+ schedule: Schedule.exponential(Duration.seconds(2), 1.5).pipe(Schedule.either(Schedule.spaced(Duration.seconds(15))),
24
+ // PSA peering creates can take 5–10 min while the
25
+ // service producer provisions its side. 80 × 15s ≈ 20 min.
26
+ Schedule.both(Schedule.recurs(80)), Schedule.tapOutput(() => session.note(`Waiting for ServiceNetworking operation ${operationName}…`))),
27
+ }));
28
+ if (op.error) {
29
+ return yield* new ConfigError({
30
+ message: `ServiceNetworking operation ${operationName} failed: ${op.error.message ?? JSON.stringify(op.error)}`,
31
+ });
32
+ }
33
+ return op;
34
+ });
35
+ // List connections in the consumer VPC and return the matching
36
+ // one (there can be at most one connection per `(network, service)`
37
+ // pair). 404/403 collapse to "not present".
38
+ const observe = (parent, network) => listConnections({ parent, network }).pipe(Effect.map((res) => (res.connections ?? []).find((c) => c.network === network)), Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)));
39
+ return {
40
+ stables: ["network", "serviceName", "peering"],
41
+ diff: Effect.fn(function* ({ news, olds = {} }) {
42
+ if (!isResolved(news))
43
+ return undefined;
44
+ const oldsService = olds.service ?? DEFAULT_SERVICE;
45
+ const newsService = news.service ?? DEFAULT_SERVICE;
46
+ if ((olds.network !== undefined && olds.network !== news.network) ||
47
+ (olds.service !== undefined && oldsService !== newsService)) {
48
+ return { action: "replace" };
49
+ }
50
+ return undefined;
51
+ }),
52
+ reconcile: Effect.fn(function* ({ news, session }) {
53
+ const service = news.service ?? DEFAULT_SERVICE;
54
+ const parent = serviceParent(service);
55
+ const desired = [...news.reservedPeeringRanges].sort();
56
+ let observed = yield* observe(parent, news.network);
57
+ if (!observed) {
58
+ const op = yield* createConnection({
59
+ parent,
60
+ body: {
61
+ network: news.network,
62
+ reservedPeeringRanges: desired,
63
+ },
64
+ }).pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
65
+ if (op?.name)
66
+ yield* awaitOperation(op.name, session);
67
+ observed = yield* observe(parent, news.network);
68
+ }
69
+ if (!observed) {
70
+ return yield* new ConfigError({
71
+ message: `PSA connection on ${news.network} did not appear after create.`,
72
+ });
73
+ }
74
+ // Sync reserved ranges. `force=true` is required when removing
75
+ // a previously-assigned range; we pass it unconditionally to
76
+ // keep the patch idempotent regardless of which direction the
77
+ // diff went.
78
+ const observedRanges = [...(observed.reservedPeeringRanges ?? [])].sort();
79
+ if (!deepEqual(observedRanges, desired) && observed.peering) {
80
+ const op = yield* patchConnection({
81
+ name: `${parent}/connections/${observed.peering}`,
82
+ force: true,
83
+ updateMask: "reservedPeeringRanges",
84
+ body: {
85
+ network: news.network,
86
+ reservedPeeringRanges: desired,
87
+ },
88
+ });
89
+ if (op.name)
90
+ yield* awaitOperation(op.name, session);
91
+ observed = yield* observe(parent, news.network);
92
+ }
93
+ return {
94
+ network: news.network,
95
+ serviceName: parent,
96
+ peering: observed?.peering ?? "",
97
+ reservedPeeringRanges: observed?.reservedPeeringRanges ?? desired,
98
+ };
99
+ }),
100
+ delete: Effect.fn(function* ({ output, session }) {
101
+ if (!output.peering)
102
+ return; // Never fully created.
103
+ yield* deleteConnection({
104
+ name: `${output.serviceName}/connections/${output.peering}`,
105
+ body: { consumerNetwork: output.network },
106
+ }).pipe(Effect.flatMap((op) => op.name ? awaitOperation(op.name, session) : Effect.succeed(op)), Effect.catchTag("NotFound", () => Effect.void));
107
+ }),
108
+ read: Effect.fn(function* ({ output, olds }) {
109
+ const network = output?.network ?? olds?.network;
110
+ const service = olds?.service ?? DEFAULT_SERVICE;
111
+ const parent = output?.serviceName ?? serviceParent(service);
112
+ if (!network)
113
+ return undefined;
114
+ const observed = yield* observe(parent, network);
115
+ if (!observed)
116
+ return undefined;
117
+ // No ownership concept: PSA connections are unique per
118
+ // `(network, service)`, and the operation can only be
119
+ // performed by the consumer-VPC project owner. Adoption is
120
+ // permissive — same stance as `ApiEnable`.
121
+ return {
122
+ network,
123
+ serviceName: parent,
124
+ peering: observed.peering ?? "",
125
+ reservedPeeringRanges: observed.reservedPeeringRanges ?? [],
126
+ };
127
+ }),
128
+ };
129
+ }));
130
+ //# sourceMappingURL=PsaConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PsaConnection.js","sourceRoot":"","sources":["../../src/ServiceNetworking/PsaConnection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./PsaConnection.ts";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ServiceNetworking/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./PsaConnection.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ServiceNetworking/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { Resource } from "alchemy";
2
+ import * as Provider from "alchemy/Provider";
3
+ import type * as GCP from "../Providers.ts";
4
+ /**
5
+ * Enable a Google Cloud API on a project (`serviceusage.googleapis.com`
6
+ * `services.enable`). Required before any operation against the
7
+ * underlying API will succeed — e.g. a fresh `GCP.Project` cannot host
8
+ * a `GCP.Cluster` until `container.googleapis.com` is enabled.
9
+ *
10
+ * The resource is keyed by `(project, service)`; both are immutable —
11
+ * changing either replaces.
12
+ *
13
+ * `delete` calls `services.disable`, which GCP rejects with HTTP 400
14
+ * (`FAILED_PRECONDITION`) if the service is already disabled or has
15
+ * dependent services in use. We treat "already disabled" as success
16
+ * (idempotent teardown). Other 400s propagate so the user sees the
17
+ * real reason (typically: another service depends on this one).
18
+ */
19
+ export type ApiEnableProps = {
20
+ /** GCP project ID hosting the API enablement. Immutable — replace. */
21
+ project: string;
22
+ /**
23
+ * Fully-qualified service name, e.g. `container.googleapis.com`,
24
+ * `compute.googleapis.com`, `iam.googleapis.com`. Immutable — replace.
25
+ */
26
+ service: string;
27
+ };
28
+ export type ApiEnableAttributes = {
29
+ /** GCP project ID, threaded through from props. */
30
+ project: string;
31
+ /** Service name, threaded through from props. */
32
+ service: string;
33
+ /** Resource name in the form `projects/{project}/services/{service}`. */
34
+ name: string;
35
+ /** Lifecycle state — `"ENABLED"` once the LRO completes. */
36
+ state: string;
37
+ };
38
+ /**
39
+ * @section Enabling APIs
40
+ *
41
+ * **Dependency edges are explicit.** Alchemy sequences resources by the
42
+ * Output references they consume. To make a downstream resource (e.g.
43
+ * `GCP.Cluster`) wait for the API enable, route its `project` prop
44
+ * through `apiEnable.project` rather than `project.projectId`:
45
+ *
46
+ * @example Container API for GKE
47
+ * ```typescript
48
+ * const project = yield* GCP.Project("Research", { ... });
49
+ * const containerApi = yield* GCP.ApiEnable("ContainerApi", {
50
+ * project: project.projectId,
51
+ * service: "container.googleapis.com",
52
+ * });
53
+ * const cluster = yield* GCP.Cluster("Main", {
54
+ * project: containerApi.project, // ← edge through ApiEnable, not Project
55
+ * location: "us-central1-a",
56
+ * // ...
57
+ * });
58
+ * ```
59
+ *
60
+ * If the cluster instead read `project.projectId`, alchemy would
61
+ * schedule the cluster create in parallel with the API enable and the
62
+ * GKE call would fail with `Forbidden: <X> API has not been used in
63
+ * project ... before or it is disabled.`
64
+ *
65
+ * @example Multiple APIs on a project
66
+ * ```typescript
67
+ * const containerApi = yield* GCP.ApiEnable("ContainerApi",
68
+ * { project: project.projectId, service: "container.googleapis.com" });
69
+ * const computeApi = yield* GCP.ApiEnable("ComputeApi",
70
+ * { project: project.projectId, service: "compute.googleapis.com" });
71
+ * // Then route downstream resources through the API enables that gate them:
72
+ * const cluster = yield* GCP.Cluster("Main", { project: containerApi.project, ... });
73
+ * ```
74
+ */
75
+ export type ApiEnable = Resource<"GCP.ApiEnable", ApiEnableProps, ApiEnableAttributes, never, GCP.Providers>;
76
+ export declare const ApiEnable: import("alchemy").ResourceClass<ApiEnable>;
77
+ export declare const ApiEnableProvider: () => import("effect/Layer").Layer<Provider.Provider<ApiEnable>, never, import("effect/unstable/http/HttpClient").HttpClient | import("@distilled.cloud/gcp").Credentials>;
78
+ //# sourceMappingURL=ApiEnable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiEnable.d.ts","sourceRoot":"","sources":["../../src/ServiceUsage/ApiEnable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAC9B,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AAEF,eAAO,MAAM,SAAS,4CAAuC,CAAC;AAK9D,eAAO,MAAM,iBAAiB,4KAyK3B,CAAC"}
@@ -0,0 +1,132 @@
1
+ import { ConfigError } from "@distilled.cloud/gcp";
2
+ import * as su from "@distilled.cloud/gcp/serviceusage-v1";
3
+ import { Resource } from "alchemy";
4
+ import { isResolved } from "alchemy/Diff";
5
+ import * as Provider from "alchemy/Provider";
6
+ import * as Duration from "effect/Duration";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Schedule from "effect/Schedule";
9
+ export const ApiEnable = Resource("GCP.ApiEnable");
10
+ const fqServiceName = (project, service) => `projects/${project}/services/${service}`;
11
+ export const ApiEnableProvider = () => Provider.effect(ApiEnable, Effect.gen(function* () {
12
+ const getServices = yield* su.getServices;
13
+ const enableServices = yield* su.enableServices;
14
+ const disableServices = yield* su.disableServices;
15
+ const getOperations = yield* su.getOperations;
16
+ // Service Usage `Operation` carries `.done: boolean` (matching CRM,
17
+ // NOT Container's `.status: "DONE"`), so we can't reuse the
18
+ // Container `makeAwaitOperation`. Mirror Project.ts's polling
19
+ // schedule (cheap polls for fast LROs; service enable usually
20
+ // resolves in <30s).
21
+ const awaitOperation = Effect.fn(function* (operationName, session) {
22
+ const op = yield* getOperations({ name: operationName }).pipe(Effect.flatMap((current) => current.done === true
23
+ ? Effect.succeed(current)
24
+ : Effect.fail({ _tag: "OperationPending" })), Effect.retry({
25
+ while: (e) => e?._tag === "OperationPending",
26
+ schedule: Schedule.exponential(Duration.seconds(1), 1.5).pipe(Schedule.either(Schedule.spaced(Duration.seconds(15))), Schedule.both(Schedule.recurs(60)), Schedule.tapOutput(() => session.note(`Waiting for ServiceUsage operation ${operationName}…`))),
27
+ }));
28
+ if (op.error) {
29
+ return yield* new ConfigError({
30
+ message: `ServiceUsage operation ${operationName} failed: ${op.error.message ?? JSON.stringify(op.error)}`,
31
+ });
32
+ }
33
+ return op;
34
+ });
35
+ return {
36
+ // No physical-name generation: identity is `(project, service)`.
37
+ // Both are static strings on `news`/`olds`/`output`.
38
+ stables: ["project", "service", "name"],
39
+ diff: Effect.fn(function* ({ news, olds = {} }) {
40
+ if (!isResolved(news))
41
+ return undefined;
42
+ if ((olds.project !== undefined && olds.project !== news.project) ||
43
+ (olds.service !== undefined && olds.service !== news.service)) {
44
+ return { action: "replace" };
45
+ }
46
+ return undefined;
47
+ }),
48
+ reconcile: Effect.fn(function* ({ news, session }) {
49
+ const name = fqServiceName(news.project, news.service);
50
+ // `getServices` returns the service entity even when disabled
51
+ // (state="DISABLED"), so 404 here means an invalid service
52
+ // name, not "not enabled". Treat NotFound and Forbidden as
53
+ // "needs enable attempt" — the enable call will surface the
54
+ // real error.
55
+ let observed = yield* getServices({ name }).pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)));
56
+ if (!observed || observed.state !== "ENABLED") {
57
+ // `Conflict` here covers concurrent enable / state-persistence
58
+ // race; fall through and re-observe.
59
+ const op = yield* enableServices({ name, body: {} }).pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
60
+ if (op?.name)
61
+ yield* awaitOperation(op.name, session);
62
+ observed = yield* getServices({ name });
63
+ }
64
+ return {
65
+ project: news.project,
66
+ service: news.service,
67
+ name: observed.name ?? name,
68
+ state: observed.state ?? "ENABLED",
69
+ };
70
+ }),
71
+ delete: Effect.fn(function* ({ output, session }) {
72
+ const name = fqServiceName(output.project, output.service);
73
+ yield* disableServices({
74
+ name,
75
+ body: { disableDependentServices: false },
76
+ }).pipe(Effect.flatMap((op) => op.name ? awaitOperation(op.name, session) : Effect.succeed(op)), Effect.catchTag("NotFound", () => Effect.void),
77
+ // GCP returns HTTP 400 in two important cases on disable
78
+ // that we treat as idempotent success:
79
+ //
80
+ // 1. Service already disabled. The resource is gone from
81
+ // the user's perspective; alchemy is removing it from
82
+ // state.
83
+ //
84
+ // 2. "Resources are found when disabling service(s) X.
85
+ // Before you can disable, please delete the following
86
+ // resources first: …" — this is GCP's eventual-
87
+ // consistency lag: a sibling resource (cluster, node
88
+ // pool) was deleted via its own API but ServiceUsage's
89
+ // "what's still using this service" view hasn't
90
+ // propagated yet. The cluster is gone; alchemy state is
91
+ // being torn down; if the project itself is also being
92
+ // destroyed (the typical case in `stack.destroy`), all
93
+ // API state goes with it. Failing here would leave a
94
+ // half-torn-down stack the user has to clean up by
95
+ // hand.
96
+ //
97
+ // Other 400s (e.g. dependent *services* still enabled, or
98
+ // a true API-level rejection) propagate so the user sees
99
+ // the real failure.
100
+ Effect.catchTag("BadRequest", (e) => /already.*disabled|not.*currently enabled|FAILED_PRECONDITION|Resources are found/i.test(e.message ?? "")
101
+ ? Effect.void
102
+ : Effect.fail(e)));
103
+ }),
104
+ read: Effect.fn(function* ({ output, olds }) {
105
+ const project = output?.project ?? olds?.project;
106
+ const service = output?.service ?? olds?.service;
107
+ if (!project || !service)
108
+ return undefined;
109
+ const name = fqServiceName(project, service);
110
+ const observed = yield* getServices({ name }).pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)));
111
+ if (!observed)
112
+ return undefined;
113
+ // A DISABLED service is functionally absent from this
114
+ // resource's perspective — the engine treats `undefined` as
115
+ // "needs reconcile" and the next plan will re-enable.
116
+ if (observed.state !== "ENABLED")
117
+ return undefined;
118
+ // No `alchemy_*` ownership labels available on services
119
+ // (no labels field), so we can't gate via `Unowned`.
120
+ // API enablement is project-scoped state, not a labeled
121
+ // resource — adoption is fine: any project we can read from
122
+ // has the API enabled regardless of who turned it on.
123
+ return {
124
+ project,
125
+ service,
126
+ name: observed.name ?? name,
127
+ state: observed.state,
128
+ };
129
+ }),
130
+ };
131
+ }));
132
+ //# sourceMappingURL=ApiEnable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiEnable.js","sourceRoot":"","sources":["../../src/ServiceUsage/ApiEnable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { ApiEnable, ApiEnableProvider } from "./ApiEnable.ts";
2
+ export type { ApiEnableAttributes, ApiEnableProps } from "./ApiEnable.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ServiceUsage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ApiEnable, ApiEnableProvider } from "./ApiEnable.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ServiceUsage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
package/lib/Tags.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { Stack } from "alchemy/Stack";
3
+ import { Stage } from "alchemy/Stage";
4
+ /**
5
+ * GCP labels are stricter than AWS tags:
6
+ *
7
+ * - **Keys** must match `[a-z][a-z0-9_-]{0,62}`. Alchemy's default
8
+ * `createInternalTags` returns keys like `alchemy::stack` — `:` is
9
+ * illegal in a GCP label key, so we use `_` separators here.
10
+ * - **Values** must match `[a-z0-9_-]{0,63}`. We lowercase and replace
11
+ * any out-of-range character with `-`.
12
+ *
13
+ * The label values together with the keys are what `read` uses to
14
+ * decide whether a project is owned by this stack/stage/id (returning
15
+ * plain attrs) or foreign (returning `Unowned(attrs)`).
16
+ *
17
+ * @see {@link https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements}
18
+ */
19
+ declare const LABEL_KEY_APP = "alchemy_app";
20
+ declare const LABEL_KEY_STAGE = "alchemy_stage";
21
+ declare const LABEL_KEY_ID = "alchemy_id";
22
+ /**
23
+ * Compute the alchemy-internal label set for a Resource. Merge the
24
+ * result with user-provided labels (user wins on key collision is
25
+ * deliberately disallowed — alchemy keys are reserved).
26
+ */
27
+ export declare const gcpInternalLabels: (id: string) => Effect.Effect<{
28
+ alchemy_app: string;
29
+ alchemy_stage: string;
30
+ alchemy_id: string;
31
+ }, never, Stage | Stack>;
32
+ /**
33
+ * True when `labels` contains all three alchemy-internal keys with
34
+ * values matching this stack/stage/id. Used in `read` to decide
35
+ * adoption ownership.
36
+ */
37
+ export declare const hasAlchemyLabels: (id: string, labels: Record<string, string> | undefined) => Effect.Effect<boolean, never, Stage | Stack>;
38
+ export { LABEL_KEY_APP as ALCHEMY_LABEL_APP, LABEL_KEY_STAGE as ALCHEMY_LABEL_STAGE, LABEL_KEY_ID as ALCHEMY_LABEL_ID, };
39
+ /**
40
+ * Compose `[alchemy:...] <userDescription?>`. Pass through to the
41
+ * resource's `description` body field at create time.
42
+ */
43
+ export declare const gcpAlchemyDescription: (id: string, userDescription?: string | undefined) => Effect.Effect<string, never, Stage | Stack>;
44
+ /**
45
+ * True when `description` begins with an alchemy marker matching this
46
+ * stack/stage/id. Used in `read` for resources that lack a labels
47
+ * field.
48
+ */
49
+ export declare const descriptionHasAlchemyMarker: (id: string, description: string | undefined) => Effect.Effect<boolean, never, Stage | Stack>;
50
+ /**
51
+ * Strip the leading alchemy marker (if any) and return what remains —
52
+ * used when surfacing the user-visible description back through
53
+ * Attributes. Matches whether the marker was generated by us or not;
54
+ * if there's no marker, returns the description unchanged.
55
+ */
56
+ export declare const stripAlchemyMarker: (description: string | undefined) => string | undefined;
57
+ //# sourceMappingURL=Tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tags.d.ts","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,QAAA,MAAM,aAAa,gBAAgB,CAAC;AACpC,QAAA,MAAM,eAAe,kBAAkB,CAAC;AACxC,QAAA,MAAM,YAAY,eAAe,CAAC;AAQlC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;wBAQ5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,0GAW3B,CAAC;AAEH,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,eAAe,IAAI,mBAAmB,EACtC,YAAY,IAAI,gBAAgB,GACjC,CAAC;AAsBF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,mGAQhC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,+FAStC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,SAI7E,CAAC"}
package/lib/Tags.js ADDED
@@ -0,0 +1,106 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { Stack } from "alchemy/Stack";
3
+ import { Stage } from "alchemy/Stage";
4
+ /**
5
+ * GCP labels are stricter than AWS tags:
6
+ *
7
+ * - **Keys** must match `[a-z][a-z0-9_-]{0,62}`. Alchemy's default
8
+ * `createInternalTags` returns keys like `alchemy::stack` — `:` is
9
+ * illegal in a GCP label key, so we use `_` separators here.
10
+ * - **Values** must match `[a-z0-9_-]{0,63}`. We lowercase and replace
11
+ * any out-of-range character with `-`.
12
+ *
13
+ * The label values together with the keys are what `read` uses to
14
+ * decide whether a project is owned by this stack/stage/id (returning
15
+ * plain attrs) or foreign (returning `Unowned(attrs)`).
16
+ *
17
+ * @see {@link https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements}
18
+ */
19
+ const LABEL_KEY_APP = "alchemy_app";
20
+ const LABEL_KEY_STAGE = "alchemy_stage";
21
+ const LABEL_KEY_ID = "alchemy_id";
22
+ const sanitizeLabelValue = (raw) => {
23
+ const lowered = raw.toLowerCase();
24
+ const replaced = lowered.replace(/[^a-z0-9_-]/g, "-");
25
+ return replaced.slice(0, 63);
26
+ };
27
+ /**
28
+ * Compute the alchemy-internal label set for a Resource. Merge the
29
+ * result with user-provided labels (user wins on key collision is
30
+ * deliberately disallowed — alchemy keys are reserved).
31
+ */
32
+ export const gcpInternalLabels = Effect.fnUntraced(function* (id) {
33
+ const stack = yield* Stack;
34
+ const stage = yield* Stage;
35
+ return {
36
+ [LABEL_KEY_APP]: sanitizeLabelValue(stack.name),
37
+ [LABEL_KEY_STAGE]: sanitizeLabelValue(stage),
38
+ [LABEL_KEY_ID]: sanitizeLabelValue(id),
39
+ };
40
+ });
41
+ /**
42
+ * True when `labels` contains all three alchemy-internal keys with
43
+ * values matching this stack/stage/id. Used in `read` to decide
44
+ * adoption ownership.
45
+ */
46
+ export const hasAlchemyLabels = Effect.fnUntraced(function* (id, labels) {
47
+ if (!labels)
48
+ return false;
49
+ const expected = yield* gcpInternalLabels(id);
50
+ return (labels[LABEL_KEY_APP] === expected[LABEL_KEY_APP] &&
51
+ labels[LABEL_KEY_STAGE] === expected[LABEL_KEY_STAGE] &&
52
+ labels[LABEL_KEY_ID] === expected[LABEL_KEY_ID]);
53
+ });
54
+ export { LABEL_KEY_APP as ALCHEMY_LABEL_APP, LABEL_KEY_STAGE as ALCHEMY_LABEL_STAGE, LABEL_KEY_ID as ALCHEMY_LABEL_ID, };
55
+ /**
56
+ * Some GCP resources (compute Networks, Subnetworks) carry no labels
57
+ * field, so the label-based adoption gate cannot apply. For these we
58
+ * encode the same `(app, stage, id)` triple as a sentinel inside the
59
+ * resource's `description` field — created on insert and read back on
60
+ * adoption.
61
+ *
62
+ * Format: `[alchemy:app=<app>,stage=<stage>,id=<id>] <user description>`.
63
+ * The leading bracketed segment is what `descriptionHasAlchemyMarker`
64
+ * matches; everything after the closing `]` is the user-supplied
65
+ * description and is preserved as-is. We never *update* this marker
66
+ * because both Network and Subnetwork treat `description` as immutable
67
+ * after create — the marker is only ever written on insert.
68
+ */
69
+ const sanitizeMarkerValue = (raw) => raw.toLowerCase().replace(/[^a-z0-9_-]/g, "-").slice(0, 63);
70
+ const buildMarkerPrefix = (app, stage, id) => `[alchemy:app=${sanitizeMarkerValue(app)},stage=${sanitizeMarkerValue(stage)},id=${sanitizeMarkerValue(id)}]`;
71
+ /**
72
+ * Compose `[alchemy:...] <userDescription?>`. Pass through to the
73
+ * resource's `description` body field at create time.
74
+ */
75
+ export const gcpAlchemyDescription = Effect.fnUntraced(function* (id, userDescription) {
76
+ const stack = yield* Stack;
77
+ const stage = yield* Stage;
78
+ const prefix = buildMarkerPrefix(stack.name, stage, id);
79
+ return userDescription ? `${prefix} ${userDescription}` : prefix;
80
+ });
81
+ /**
82
+ * True when `description` begins with an alchemy marker matching this
83
+ * stack/stage/id. Used in `read` for resources that lack a labels
84
+ * field.
85
+ */
86
+ export const descriptionHasAlchemyMarker = Effect.fnUntraced(function* (id, description) {
87
+ if (!description)
88
+ return false;
89
+ const stack = yield* Stack;
90
+ const stage = yield* Stage;
91
+ const expected = buildMarkerPrefix(stack.name, stage, id);
92
+ return description.startsWith(expected);
93
+ });
94
+ /**
95
+ * Strip the leading alchemy marker (if any) and return what remains —
96
+ * used when surfacing the user-visible description back through
97
+ * Attributes. Matches whether the marker was generated by us or not;
98
+ * if there's no marker, returns the description unchanged.
99
+ */
100
+ export const stripAlchemyMarker = (description) => {
101
+ if (!description)
102
+ return description;
103
+ const m = description.match(/^\[alchemy:[^\]]+\]\s?/);
104
+ return m ? description.slice(m[0].length) || undefined : description;
105
+ };
106
+ //# sourceMappingURL=Tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tags.js","sourceRoot":"","sources":["../src/Tags.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export { Credentials, fromADC, fromAuthProvider } from "./Auth/Credentials.ts";
2
+ export { GCP_AUTH_PROVIDER_NAME, GCPAuth, } from "./Auth/AuthProvider.ts";
3
+ export type { GCPAuthConfig, GCPResolvedCredentials, } from "./Auth/AuthProvider.ts";
4
+ export * from "./CloudResourceManager/index.ts";
5
+ export * from "./Compute/index.ts";
6
+ export * from "./Container/index.ts";
7
+ export * from "./Parallelstore/index.ts";
8
+ export * from "./ServiceNetworking/index.ts";
9
+ export * from "./ServiceUsage/index.ts";
10
+ export * from "./Providers.ts";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,aAAa,EACb,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { Credentials, fromADC, fromAuthProvider } from "./Auth/Credentials.js";
2
+ export { GCP_AUTH_PROVIDER_NAME, GCPAuth, } from "./Auth/AuthProvider.js";
3
+ export * from "./CloudResourceManager/index.js";
4
+ export * from "./Compute/index.js";
5
+ export * from "./Container/index.js";
6
+ export * from "./Parallelstore/index.js";
7
+ export * from "./ServiceNetworking/index.js";
8
+ export * from "./ServiceUsage/index.js";
9
+ export * from "./Providers.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAKhC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}