@microagi/alchemy-gcp 0.2.1 → 0.5.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 (107) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +54 -2
  3. package/lib/ArtifactRegistry/Operations.d.ts +47 -0
  4. package/lib/ArtifactRegistry/Operations.d.ts.map +1 -0
  5. package/lib/ArtifactRegistry/Operations.js +47 -0
  6. package/lib/ArtifactRegistry/Operations.js.map +1 -0
  7. package/lib/ArtifactRegistry/Repository.d.ts +263 -0
  8. package/lib/ArtifactRegistry/Repository.d.ts.map +1 -0
  9. package/lib/ArtifactRegistry/Repository.js +257 -0
  10. package/lib/ArtifactRegistry/Repository.js.map +1 -0
  11. package/lib/ArtifactRegistry/Types.d.ts +32 -0
  12. package/lib/ArtifactRegistry/Types.d.ts.map +1 -0
  13. package/lib/ArtifactRegistry/Types.js +12 -0
  14. package/lib/ArtifactRegistry/Types.js.map +1 -0
  15. package/lib/ArtifactRegistry/Validation.d.ts +43 -0
  16. package/lib/ArtifactRegistry/Validation.d.ts.map +1 -0
  17. package/lib/ArtifactRegistry/Validation.js +95 -0
  18. package/lib/ArtifactRegistry/Validation.js.map +1 -0
  19. package/lib/ArtifactRegistry/index.d.ts +4 -0
  20. package/lib/ArtifactRegistry/index.d.ts.map +1 -0
  21. package/lib/ArtifactRegistry/index.js +2 -0
  22. package/lib/ArtifactRegistry/index.js.map +1 -0
  23. package/lib/Providers.d.ts.map +1 -1
  24. package/lib/Providers.js +13 -1
  25. package/lib/Providers.js.map +1 -1
  26. package/lib/Run/IamMember.d.ts +70 -0
  27. package/lib/Run/IamMember.d.ts.map +1 -0
  28. package/lib/Run/IamMember.js +65 -0
  29. package/lib/Run/IamMember.js.map +1 -0
  30. package/lib/Run/IamSync.d.ts +80 -0
  31. package/lib/Run/IamSync.d.ts.map +1 -0
  32. package/lib/Run/IamSync.js +73 -0
  33. package/lib/Run/IamSync.js.map +1 -0
  34. package/lib/Run/Job.d.ts +167 -0
  35. package/lib/Run/Job.d.ts.map +1 -0
  36. package/lib/Run/Job.js +199 -0
  37. package/lib/Run/Job.js.map +1 -0
  38. package/lib/Run/Operations.d.ts +47 -0
  39. package/lib/Run/Operations.d.ts.map +1 -0
  40. package/lib/Run/Operations.js +46 -0
  41. package/lib/Run/Operations.js.map +1 -0
  42. package/lib/Run/Service.d.ts +193 -0
  43. package/lib/Run/Service.d.ts.map +1 -0
  44. package/lib/Run/Service.js +247 -0
  45. package/lib/Run/Service.js.map +1 -0
  46. package/lib/Run/Validation.d.ts +54 -0
  47. package/lib/Run/Validation.d.ts.map +1 -0
  48. package/lib/Run/Validation.js +129 -0
  49. package/lib/Run/Validation.js.map +1 -0
  50. package/lib/Run/index.d.ts +51 -0
  51. package/lib/Run/index.d.ts.map +1 -0
  52. package/lib/Run/index.js +4 -0
  53. package/lib/Run/index.js.map +1 -0
  54. package/lib/Sqladmin/Database.d.ts +82 -0
  55. package/lib/Sqladmin/Database.d.ts.map +1 -0
  56. package/lib/Sqladmin/Database.js +87 -0
  57. package/lib/Sqladmin/Database.js.map +1 -0
  58. package/lib/Sqladmin/Instance.d.ts +234 -0
  59. package/lib/Sqladmin/Instance.d.ts.map +1 -0
  60. package/lib/Sqladmin/Instance.js +251 -0
  61. package/lib/Sqladmin/Instance.js.map +1 -0
  62. package/lib/Sqladmin/Operations.d.ts +41 -0
  63. package/lib/Sqladmin/Operations.d.ts.map +1 -0
  64. package/lib/Sqladmin/Operations.js +42 -0
  65. package/lib/Sqladmin/Operations.js.map +1 -0
  66. package/lib/Sqladmin/Types.d.ts +82 -0
  67. package/lib/Sqladmin/Types.d.ts.map +1 -0
  68. package/lib/Sqladmin/Types.js +28 -0
  69. package/lib/Sqladmin/Types.js.map +1 -0
  70. package/lib/Sqladmin/User.d.ts +110 -0
  71. package/lib/Sqladmin/User.d.ts.map +1 -0
  72. package/lib/Sqladmin/User.js +156 -0
  73. package/lib/Sqladmin/User.js.map +1 -0
  74. package/lib/Sqladmin/Validation.d.ts +60 -0
  75. package/lib/Sqladmin/Validation.d.ts.map +1 -0
  76. package/lib/Sqladmin/Validation.js +125 -0
  77. package/lib/Sqladmin/Validation.js.map +1 -0
  78. package/lib/Sqladmin/index.d.ts +9 -0
  79. package/lib/Sqladmin/index.d.ts.map +1 -0
  80. package/lib/Sqladmin/index.js +5 -0
  81. package/lib/Sqladmin/index.js.map +1 -0
  82. package/lib/index.d.ts +3 -0
  83. package/lib/index.d.ts.map +1 -1
  84. package/lib/index.js +3 -0
  85. package/lib/index.js.map +1 -1
  86. package/package.json +5 -4
  87. package/src/ArtifactRegistry/Operations.ts +79 -0
  88. package/src/ArtifactRegistry/Repository.ts +624 -0
  89. package/src/ArtifactRegistry/Types.ts +49 -0
  90. package/src/ArtifactRegistry/Validation.ts +112 -0
  91. package/src/ArtifactRegistry/index.ts +10 -0
  92. package/src/Providers.ts +21 -0
  93. package/src/Run/IamMember.ts +79 -0
  94. package/src/Run/IamSync.ts +134 -0
  95. package/src/Run/Job.ts +453 -0
  96. package/src/Run/Operations.ts +77 -0
  97. package/src/Run/Service.ts +541 -0
  98. package/src/Run/Validation.ts +153 -0
  99. package/src/Run/index.ts +52 -0
  100. package/src/Sqladmin/Database.ts +209 -0
  101. package/src/Sqladmin/Instance.ts +620 -0
  102. package/src/Sqladmin/Operations.ts +73 -0
  103. package/src/Sqladmin/Types.ts +101 -0
  104. package/src/Sqladmin/User.ts +333 -0
  105. package/src/Sqladmin/Validation.ts +148 -0
  106. package/src/Sqladmin/index.ts +19 -0
  107. package/src/index.ts +3 -0
@@ -0,0 +1,52 @@
1
+ import type * as run from "@distilled.cloud/gcp/run-v2";
2
+
3
+ export { Job, JobProvider } from "./Job.ts";
4
+ export type { JobAttributes, JobProps } from "./Job.ts";
5
+ export { jobIamMember, serviceIamMember } from "./IamMember.ts";
6
+ export type { RunIamBinding, RunIamBindingContract } from "./IamSync.ts";
7
+ export { Service, ServiceProvider } from "./Service.ts";
8
+ export type { ServiceAttributes, ServiceProps } from "./Service.ts";
9
+
10
+ /**
11
+ * Clean aliases for the most commonly-used Cloud Run v2 SDK types,
12
+ * re-exported from `@distilled.cloud/gcp/run-v2` so consumers don't
13
+ * need to import from the underlying SDK directly. The aliases are
14
+ * type-only — they share identity with the distilled types, so values
15
+ * are interchangeable.
16
+ *
17
+ * The `GoogleCloudRunV2*` prefix on the SDK types is generated from
18
+ * the GCP Discovery Document and is awkward to consume; these aliases
19
+ * mirror the casing the GCP REST docs use ("RevisionTemplate",
20
+ * "Container", "TrafficTarget"), which is what most users will
21
+ * already have in their heads.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import * as GCP from "@microagi/alchemy-gcp";
26
+ *
27
+ * const template: GCP.RevisionTemplate = {
28
+ * containers: [{ image: "..." }],
29
+ * };
30
+ * ```
31
+ */
32
+ export type RevisionTemplate = run.GoogleCloudRunV2RevisionTemplate;
33
+ export type ExecutionTemplate = run.GoogleCloudRunV2ExecutionTemplate;
34
+ export type TaskTemplate = run.GoogleCloudRunV2TaskTemplate;
35
+ export type Container = run.GoogleCloudRunV2Container;
36
+ export type ContainerPort = run.GoogleCloudRunV2ContainerPort;
37
+ export type EnvVar = run.GoogleCloudRunV2EnvVar;
38
+ export type EnvVarSource = run.GoogleCloudRunV2EnvVarSource;
39
+ export type ResourceRequirements = run.GoogleCloudRunV2ResourceRequirements;
40
+ export type Probe = run.GoogleCloudRunV2Probe;
41
+ export type VpcAccess = run.GoogleCloudRunV2VpcAccess;
42
+ export type NetworkInterface = run.GoogleCloudRunV2NetworkInterface;
43
+ export type NodeSelector = run.GoogleCloudRunV2NodeSelector;
44
+ export type TrafficTarget = run.GoogleCloudRunV2TrafficTarget;
45
+ export type TrafficTargetStatus = run.GoogleCloudRunV2TrafficTargetStatus;
46
+ export type ServiceScaling = run.GoogleCloudRunV2ServiceScaling;
47
+ export type BinaryAuthorization = run.GoogleCloudRunV2BinaryAuthorization;
48
+ export type Volume = run.GoogleCloudRunV2Volume;
49
+ export type VolumeMount = run.GoogleCloudRunV2VolumeMount;
50
+ export type Condition = run.GoogleCloudRunV2Condition;
51
+ export type ExecutionReference = run.GoogleCloudRunV2ExecutionReference;
52
+ export type SecretKeySelector = run.GoogleCloudRunV2SecretKeySelector;
@@ -0,0 +1,209 @@
1
+ import * as sql from "@distilled.cloud/gcp/sqladmin-v1";
2
+ import { Resource } from "alchemy";
3
+ import { isResolved, somePropsAreDifferent } from "alchemy/Diff";
4
+ import * as Provider from "alchemy/Provider";
5
+ import * as Effect from "effect/Effect";
6
+ import type * as GCP from "../Providers.ts";
7
+ import { makeAwaitOperation } from "./Operations.ts";
8
+ import { reshapeBadRequest, validateDatabaseName } from "./Validation.ts";
9
+
10
+ /**
11
+ * A logical Postgres database inside a Cloud SQL instance.
12
+ *
13
+ * Cloud SQL `databases` resources are extremely thin — name, charset,
14
+ * collation, parent instance. Use this resource to declaratively
15
+ * create a tenant database (one per app, one per team, etc.) and let
16
+ * alchemy track its lifecycle.
17
+ *
18
+ * **Adoption.** Cloud SQL databases carry NO labels. There is no
19
+ * server-side adoption marker we can stamp without polluting the
20
+ * collation field, so `read` is best-effort: it returns the observed
21
+ * shape if the database exists at the same logical address, and
22
+ * `undefined` otherwise. The caller is responsible for `--adopt` if
23
+ * they want to take over an existing physical database; we do not
24
+ * gate on labels here.
25
+ *
26
+ * **Replace triggers.** `project`, `instance`, `name`. Charset and
27
+ * collation are immutable post-create in practice — the API accepts
28
+ * a `patch` but ignores collation/charset drift, so we treat them as
29
+ * "set once, then forgotten" and only diff name/parent.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const db = yield* GCP.SqlDatabase("AppDb", {
34
+ * project: instance.project,
35
+ * instance: instance.name,
36
+ * name: "app",
37
+ * });
38
+ * ```
39
+ *
40
+ * @see https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1/databases
41
+ */
42
+ export type SqlDatabaseProps = {
43
+ /**
44
+ * GCP project ID hosting the parent instance. Immutable — replace.
45
+ * @see https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1/databases#Database
46
+ */
47
+ project: string;
48
+ /**
49
+ * Parent Cloud SQL instance name (NOT the fully-qualified resource
50
+ * name; just the bare `name`). Immutable — replace.
51
+ */
52
+ instance: string;
53
+ /**
54
+ * Database name. 1–64 chars; Postgres-specific naming applies (no
55
+ * reserved words, etc.). Immutable — replace if changed.
56
+ */
57
+ name: string;
58
+ /**
59
+ * Server-side character set. Postgres-default is `UTF8`. Set at
60
+ * create; not honoured on patch.
61
+ * @see https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1/databases#Database.FIELDS.charset
62
+ */
63
+ charset?: string;
64
+ /**
65
+ * Collation. Postgres-default is `en_US.UTF8`. Set at create; not
66
+ * honoured on patch.
67
+ * @see https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1/databases#Database.FIELDS.collation
68
+ */
69
+ collation?: string;
70
+ };
71
+
72
+ export type SqlDatabaseAttributes = {
73
+ /** Database name. */
74
+ name: string;
75
+ /** Parent instance name. */
76
+ instance: string;
77
+ /** Project ID. */
78
+ project: string;
79
+ /** Server-defined URL. */
80
+ selfLink: string;
81
+ /** Effective charset (server may default to `UTF8`). */
82
+ charset: string | undefined;
83
+ /** Effective collation. */
84
+ collation: string | undefined;
85
+ };
86
+
87
+ export type SqlDatabase = Resource<
88
+ "GCP.SqlDatabase",
89
+ SqlDatabaseProps,
90
+ SqlDatabaseAttributes,
91
+ never,
92
+ GCP.Providers
93
+ >;
94
+ export const SqlDatabase = Resource<SqlDatabase>("GCP.SqlDatabase");
95
+
96
+ const toAttributes = (
97
+ d: sql.Database,
98
+ parent: { project: string; instance: string; name: string },
99
+ ): SqlDatabaseAttributes => ({
100
+ name: parent.name,
101
+ instance: parent.instance,
102
+ project: parent.project,
103
+ selfLink: d.selfLink ?? "",
104
+ charset: d.charset,
105
+ collation: d.collation,
106
+ });
107
+
108
+ export const SqlDatabaseProvider = () =>
109
+ Provider.effect(
110
+ SqlDatabase,
111
+ Effect.gen(function* () {
112
+ const getDatabases = yield* sql.getDatabases;
113
+ const insertDatabases = yield* sql.insertDatabases;
114
+ const deleteDatabases = yield* sql.deleteDatabases;
115
+ const getOperations = yield* sql.getOperations;
116
+ const awaitOperation = makeAwaitOperation(getOperations);
117
+
118
+ const observe = (project: string, instance: string, database: string) =>
119
+ getDatabases({ project, instance, database }).pipe(
120
+ Effect.catchTag("NotFound", () =>
121
+ Effect.succeed(undefined as sql.Database | undefined),
122
+ ),
123
+ Effect.catchTag("Forbidden", () =>
124
+ Effect.succeed(undefined as sql.Database | undefined),
125
+ ),
126
+ );
127
+
128
+ return {
129
+ stables: ["name", "instance", "project", "selfLink"],
130
+ diff: Effect.fn(function* ({ news, olds = {} }) {
131
+ if (!isResolved(news)) return undefined;
132
+ if (
133
+ somePropsAreDifferent(olds as SqlDatabaseProps, news, [
134
+ "project",
135
+ "instance",
136
+ "name",
137
+ ])
138
+ ) {
139
+ return { action: "replace" } as const;
140
+ }
141
+ return undefined;
142
+ }),
143
+ reconcile: Effect.fn(function* ({ news, session }) {
144
+ yield* validateDatabaseName(news.name);
145
+
146
+ let observed = yield* observe(news.project, news.instance, news.name);
147
+
148
+ if (!observed) {
149
+ const op = yield* insertDatabases({
150
+ project: news.project,
151
+ instance: news.instance,
152
+ body: {
153
+ name: news.name,
154
+ ...(news.charset ? { charset: news.charset } : {}),
155
+ ...(news.collation ? { collation: news.collation } : {}),
156
+ },
157
+ }).pipe(
158
+ Effect.catchTag("Conflict", () =>
159
+ Effect.succeed(undefined as sql.Operation | undefined),
160
+ ),
161
+ Effect.catchTag(
162
+ "BadRequest",
163
+ reshapeBadRequest("Database", "insert"),
164
+ ),
165
+ );
166
+ if (op?.name) yield* awaitOperation(news.project, op.name, session);
167
+ observed = yield* getDatabases({
168
+ project: news.project,
169
+ instance: news.instance,
170
+ database: news.name,
171
+ });
172
+ }
173
+
174
+ return toAttributes(observed, {
175
+ project: news.project,
176
+ instance: news.instance,
177
+ name: news.name,
178
+ });
179
+ }),
180
+ delete: Effect.fn(function* ({ output, session }) {
181
+ yield* deleteDatabases({
182
+ project: output.project,
183
+ instance: output.instance,
184
+ database: output.name,
185
+ }).pipe(
186
+ Effect.flatMap((op) =>
187
+ op.name
188
+ ? awaitOperation(output.project, op.name, session)
189
+ : Effect.succeed(op),
190
+ ),
191
+ Effect.catchTag("NotFound", () => Effect.void),
192
+ Effect.catchTag(
193
+ "BadRequest",
194
+ reshapeBadRequest("Database", "delete"),
195
+ ),
196
+ );
197
+ }),
198
+ read: Effect.fn(function* ({ output, olds }) {
199
+ const project = output?.project ?? olds?.project;
200
+ const instance = output?.instance ?? olds?.instance;
201
+ const name = output?.name ?? olds?.name;
202
+ if (!project || !instance || !name) return undefined;
203
+ const observed = yield* observe(project, instance, name);
204
+ if (!observed) return undefined;
205
+ return toAttributes(observed, { project, instance, name });
206
+ }),
207
+ };
208
+ }),
209
+ );