@itssergio91/sandman 0.1.2 → 0.2.1

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 (81) hide show
  1. package/README.md +9 -7
  2. package/dist/cli/commands/connect.d.ts +5 -1
  3. package/dist/cli/commands/connect.d.ts.map +1 -1
  4. package/dist/cli/commands/connect.js +22 -20
  5. package/dist/cli/commands/connect.js.map +1 -1
  6. package/dist/cli/commands/create.d.ts +3 -2
  7. package/dist/cli/commands/create.d.ts.map +1 -1
  8. package/dist/cli/commands/create.js +53 -16
  9. package/dist/cli/commands/create.js.map +1 -1
  10. package/dist/cli/commands/destroy.d.ts +1 -0
  11. package/dist/cli/commands/destroy.d.ts.map +1 -1
  12. package/dist/cli/commands/destroy.js +15 -6
  13. package/dist/cli/commands/destroy.js.map +1 -1
  14. package/dist/cli/commands/enable.d.ts +5 -1
  15. package/dist/cli/commands/enable.d.ts.map +1 -1
  16. package/dist/cli/commands/enable.js +29 -14
  17. package/dist/cli/commands/enable.js.map +1 -1
  18. package/dist/cli/commands/init.d.ts +6 -1
  19. package/dist/cli/commands/init.d.ts.map +1 -1
  20. package/dist/cli/commands/init.js +13 -6
  21. package/dist/cli/commands/init.js.map +1 -1
  22. package/dist/cli/commands/status.d.ts +1 -1
  23. package/dist/cli/commands/status.d.ts.map +1 -1
  24. package/dist/cli/commands/status.js +34 -23
  25. package/dist/cli/commands/status.js.map +1 -1
  26. package/dist/cli/index.d.ts.map +1 -1
  27. package/dist/cli/index.js +14 -9
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/core/state-store.d.ts +3 -3
  30. package/dist/core/state-store.d.ts.map +1 -1
  31. package/dist/core/state-store.js +1 -1
  32. package/dist/core/state-store.js.map +1 -1
  33. package/dist/providers/aws/adapter.d.ts +3 -0
  34. package/dist/providers/aws/adapter.d.ts.map +1 -1
  35. package/dist/providers/aws/adapter.js +331 -9
  36. package/dist/providers/aws/adapter.js.map +1 -1
  37. package/dist/providers/aws/adapter.test.js +107 -0
  38. package/dist/providers/aws/adapter.test.js.map +1 -1
  39. package/dist/providers/base.d.ts +2 -0
  40. package/dist/providers/base.d.ts.map +1 -1
  41. package/dist/providers/base.js +14 -0
  42. package/dist/providers/base.js.map +1 -1
  43. package/dist/providers/cloudflare/adapter.d.ts +12 -0
  44. package/dist/providers/cloudflare/adapter.d.ts.map +1 -0
  45. package/dist/providers/cloudflare/adapter.js +85 -0
  46. package/dist/providers/cloudflare/adapter.js.map +1 -0
  47. package/dist/providers/cloudflare/adapter.test.d.ts +2 -0
  48. package/dist/providers/cloudflare/adapter.test.d.ts.map +1 -0
  49. package/dist/providers/cloudflare/adapter.test.js +178 -0
  50. package/dist/providers/cloudflare/adapter.test.js.map +1 -0
  51. package/dist/providers/gcp/adapter.d.ts +3 -0
  52. package/dist/providers/gcp/adapter.d.ts.map +1 -1
  53. package/dist/providers/gcp/adapter.js +150 -18
  54. package/dist/providers/gcp/adapter.js.map +1 -1
  55. package/dist/providers/gcp/adapter.test.js +122 -15
  56. package/dist/providers/gcp/adapter.test.js.map +1 -1
  57. package/dist/providers/index.d.ts +4 -0
  58. package/dist/providers/index.d.ts.map +1 -0
  59. package/dist/providers/index.js +13 -0
  60. package/dist/providers/index.js.map +1 -0
  61. package/dist/providers/vercel/adapter.d.ts +12 -0
  62. package/dist/providers/vercel/adapter.d.ts.map +1 -0
  63. package/dist/providers/vercel/adapter.js +74 -0
  64. package/dist/providers/vercel/adapter.js.map +1 -0
  65. package/dist/providers/vercel/adapter.test.d.ts +2 -0
  66. package/dist/providers/vercel/adapter.test.d.ts.map +1 -0
  67. package/dist/providers/vercel/adapter.test.js +166 -0
  68. package/dist/providers/vercel/adapter.test.js.map +1 -0
  69. package/dist/types/index.d.ts +21 -21
  70. package/dist/types/index.d.ts.map +1 -1
  71. package/dist/types/index.js +18 -4
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/cost-estimator.d.ts +36 -0
  74. package/dist/utils/cost-estimator.d.ts.map +1 -0
  75. package/dist/utils/cost-estimator.js +87 -0
  76. package/dist/utils/cost-estimator.js.map +1 -0
  77. package/dist/utils/cost-estimator.test.d.ts +2 -0
  78. package/dist/utils/cost-estimator.test.d.ts.map +1 -0
  79. package/dist/utils/cost-estimator.test.js +77 -0
  80. package/dist/utils/cost-estimator.test.js.map +1 -0
  81. package/package.json +1 -1
@@ -0,0 +1,85 @@
1
+ import { CLOUDFLARE_SERVICES } from "../base.js";
2
+ export class CloudflareAdapter {
3
+ accountId = null;
4
+ async init() {
5
+ const apiToken = process.env.CLOUDFLARE_API_TOKEN;
6
+ const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
7
+ if (!apiToken) {
8
+ throw new Error("CLOUDFLARE_API_TOKEN environment variable is required. " +
9
+ "Create a token at https://dash.cloudflare.com/profile/api-tokens");
10
+ }
11
+ // Verify token by fetching account info
12
+ const response = await fetch("https://api.cloudflare.com/client/v4/user", {
13
+ headers: {
14
+ Authorization: `Bearer ${apiToken}`,
15
+ "Content-Type": "application/json",
16
+ },
17
+ });
18
+ if (!response.ok) {
19
+ const body = (await response.json());
20
+ const msg = body.errors?.[0]?.message || response.statusText;
21
+ throw new Error(`Cloudflare authentication failed: ${msg}`);
22
+ }
23
+ if (accountId) {
24
+ this.accountId = accountId;
25
+ }
26
+ else {
27
+ // Fetch first account associated with the token
28
+ const accountsRes = await fetch("https://api.cloudflare.com/client/v4/accounts", {
29
+ headers: {
30
+ Authorization: `Bearer ${apiToken}`,
31
+ "Content-Type": "application/json",
32
+ },
33
+ });
34
+ if (accountsRes.ok) {
35
+ const data = (await accountsRes.json());
36
+ this.accountId = data.result?.[0]?.id || null;
37
+ }
38
+ }
39
+ }
40
+ async createEnvironment(name) {
41
+ const now = new Date().toISOString();
42
+ const namespaceId = `sandman-${name}-${Date.now()}`;
43
+ return {
44
+ name,
45
+ provider: "cloudflare",
46
+ accountId: process.env.CLOUDFLARE_ACCOUNT_ID || undefined,
47
+ status: "active",
48
+ services: [],
49
+ resources: {
50
+ namespaceId,
51
+ },
52
+ createdAt: now,
53
+ updatedAt: now,
54
+ };
55
+ }
56
+ async enableServices(env, services) {
57
+ const enabledServices = services
58
+ .map((s) => CLOUDFLARE_SERVICES[s])
59
+ .filter(Boolean);
60
+ console.log(`Enabling Cloudflare services: ${enabledServices.join(", ")}`);
61
+ }
62
+ async connect(env) {
63
+ const result = {
64
+ provider: "cloudflare",
65
+ };
66
+ if (env.accountId) {
67
+ result.CLOUDFLARE_ACCOUNT_ID = env.accountId;
68
+ }
69
+ if (process.env.CLOUDFLARE_API_TOKEN) {
70
+ result.CLOUDFLARE_API_TOKEN = process.env.CLOUDFLARE_API_TOKEN;
71
+ }
72
+ if (env.resources.namespaceId) {
73
+ result.CLOUDFLARE_NAMESPACE_ID = env.resources.namespaceId;
74
+ }
75
+ return result;
76
+ }
77
+ async destroyEnvironment(env) {
78
+ console.log(`Cleaning up Cloudflare resources for environment: ${env.name}`);
79
+ // Future: delete KV namespaces, R2 buckets, D1 databases via API
80
+ }
81
+ async getStatus(env) {
82
+ return env;
83
+ }
84
+ }
85
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/cloudflare/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../../src/providers/cloudflare/adapter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,178 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { CloudflareAdapter } from "./adapter.js";
3
+ global.fetch = vi.fn();
4
+ describe("CloudflareAdapter", () => {
5
+ let adapter;
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ vi.resetAllMocks();
9
+ adapter = new CloudflareAdapter();
10
+ delete process.env.CLOUDFLARE_ACCOUNT_ID;
11
+ });
12
+ describe("init", () => {
13
+ it("should throw if CLOUDFLARE_API_TOKEN is missing", async () => {
14
+ delete process.env.CLOUDFLARE_API_TOKEN;
15
+ await expect(adapter.init()).rejects.toThrow("CLOUDFLARE_API_TOKEN environment variable is required");
16
+ });
17
+ it("should authenticate and fetch account ID", async () => {
18
+ process.env.CLOUDFLARE_API_TOKEN = "test-token";
19
+ process.env.CLOUDFLARE_ACCOUNT_ID = "abc123";
20
+ global.fetch.mockResolvedValueOnce({
21
+ ok: true,
22
+ json: async () => ({ result: { id: "user123" } }),
23
+ });
24
+ await adapter.init();
25
+ // Would throw if auth failed
26
+ expect(global.fetch).toHaveBeenCalledWith("https://api.cloudflare.com/client/v4/user", expect.any(Object));
27
+ });
28
+ it("should throw on authentication failure", async () => {
29
+ process.env.CLOUDFLARE_API_TOKEN = "bad-token";
30
+ global.fetch.mockResolvedValueOnce({
31
+ ok: false,
32
+ json: async () => ({ errors: [{ message: "Invalid token" }] }),
33
+ });
34
+ await expect(adapter.init()).rejects.toThrow("Cloudflare authentication failed: Invalid token");
35
+ });
36
+ it("should fetch first account when ACCOUNT_ID not set", async () => {
37
+ process.env.CLOUDFLARE_API_TOKEN = "test-token";
38
+ delete process.env.CLOUDFLARE_ACCOUNT_ID;
39
+ global.fetch
40
+ .mockResolvedValueOnce({
41
+ ok: true,
42
+ json: async () => ({ result: { id: "user123" } }),
43
+ })
44
+ .mockResolvedValueOnce({
45
+ ok: true,
46
+ json: async () => ({
47
+ result: [{ id: "account123", name: "My Account" }],
48
+ }),
49
+ });
50
+ await adapter.init();
51
+ expect(global.fetch).toHaveBeenCalledWith("https://api.cloudflare.com/client/v4/accounts", expect.any(Object));
52
+ });
53
+ });
54
+ describe("createEnvironment", () => {
55
+ it("should create an environment record with namespaceId", async () => {
56
+ const env = await adapter.createEnvironment("test-env");
57
+ expect(env.name).toBe("test-env");
58
+ expect(env.provider).toBe("cloudflare");
59
+ expect(env.status).toBe("active");
60
+ expect(env.resources.namespaceId).toMatch(/^sandman-test-env-/);
61
+ });
62
+ it("should include accountId from env", async () => {
63
+ process.env.CLOUDFLARE_ACCOUNT_ID = "my-account";
64
+ const env = await adapter.createEnvironment("prod");
65
+ expect(env.accountId).toBe("my-account");
66
+ });
67
+ });
68
+ describe("enableServices", () => {
69
+ it("should log services to enable", async () => {
70
+ const env = {
71
+ name: "test",
72
+ provider: "cloudflare",
73
+ status: "active",
74
+ services: [],
75
+ resources: {},
76
+ createdAt: new Date().toISOString(),
77
+ updatedAt: new Date().toISOString(),
78
+ };
79
+ const consoleSpy = vi.spyOn(console, "log");
80
+ await adapter.enableServices(env, ["workers", "kv", "d1"]);
81
+ expect(consoleSpy).toHaveBeenCalledWith("Enabling Cloudflare services: workers, kv, d1");
82
+ consoleSpy.mockRestore();
83
+ });
84
+ it("should filter invalid services", async () => {
85
+ const env = {
86
+ name: "test",
87
+ provider: "cloudflare",
88
+ status: "active",
89
+ services: [],
90
+ resources: {},
91
+ createdAt: new Date().toISOString(),
92
+ updatedAt: new Date().toISOString(),
93
+ };
94
+ const consoleSpy = vi.spyOn(console, "log");
95
+ await adapter.enableServices(env, ["invalid-service"]);
96
+ expect(consoleSpy).toHaveBeenCalledWith("Enabling Cloudflare services: ");
97
+ consoleSpy.mockRestore();
98
+ });
99
+ });
100
+ describe("connect", () => {
101
+ it("should return environment variables", async () => {
102
+ process.env.CLOUDFLARE_API_TOKEN = "my-token";
103
+ process.env.CLOUDFLARE_ACCOUNT_ID = "my-account";
104
+ const env = {
105
+ name: "test",
106
+ provider: "cloudflare",
107
+ status: "active",
108
+ services: [],
109
+ resources: { namespaceId: "ns-123" },
110
+ createdAt: new Date().toISOString(),
111
+ updatedAt: new Date().toISOString(),
112
+ accountId: "my-account",
113
+ };
114
+ const creds = await adapter.connect(env);
115
+ expect(creds.provider).toBe("cloudflare");
116
+ expect(creds.CLOUDFLARE_ACCOUNT_ID).toBe("my-account");
117
+ expect(creds.CLOUDFLARE_API_TOKEN).toBe("my-token");
118
+ expect(creds.CLOUDFLARE_NAMESPACE_ID).toBe("ns-123");
119
+ });
120
+ it("should work without optional fields", async () => {
121
+ const env = {
122
+ name: "test",
123
+ provider: "cloudflare",
124
+ status: "active",
125
+ services: [],
126
+ resources: {},
127
+ createdAt: new Date().toISOString(),
128
+ updatedAt: new Date().toISOString(),
129
+ };
130
+ const creds = await adapter.connect(env);
131
+ expect(creds.provider).toBe("cloudflare");
132
+ expect(creds.CLOUDFLARE_ACCOUNT_ID).toBeUndefined();
133
+ });
134
+ });
135
+ describe("destroyEnvironment", () => {
136
+ it("should log cleanup message", async () => {
137
+ const env = {
138
+ name: "test",
139
+ provider: "cloudflare",
140
+ status: "active",
141
+ services: [],
142
+ resources: { namespaceId: "ns-123" },
143
+ createdAt: new Date().toISOString(),
144
+ updatedAt: new Date().toISOString(),
145
+ };
146
+ const consoleSpy = vi.spyOn(console, "log");
147
+ await adapter.destroyEnvironment(env);
148
+ expect(consoleSpy).toHaveBeenCalledWith("Cleaning up Cloudflare resources for environment: test");
149
+ consoleSpy.mockRestore();
150
+ });
151
+ });
152
+ describe("getStatus", () => {
153
+ it("should return environment as-is", async () => {
154
+ const env = {
155
+ name: "test",
156
+ provider: "cloudflare",
157
+ status: "active",
158
+ services: ["workers", "kv"],
159
+ resources: { namespaceId: "ns-123" },
160
+ createdAt: "2026-01-01T00:00:00.000Z",
161
+ updatedAt: "2026-01-01T00:00:00.000Z",
162
+ };
163
+ const result = await adapter.getStatus(env);
164
+ expect(result).toEqual(env);
165
+ });
166
+ });
167
+ describe("interface compliance", () => {
168
+ it("should have all required methods", () => {
169
+ expect(typeof adapter.init).toBe("function");
170
+ expect(typeof adapter.createEnvironment).toBe("function");
171
+ expect(typeof adapter.enableServices).toBe("function");
172
+ expect(typeof adapter.connect).toBe("function");
173
+ expect(typeof adapter.destroyEnvironment).toBe("function");
174
+ expect(typeof adapter.getStatus).toBe("function");
175
+ });
176
+ });
177
+ });
178
+ //# sourceMappingURL=adapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["../../../src/providers/cloudflare/adapter.test.ts"],"names":[],"mappings":"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"}
@@ -2,14 +2,17 @@ import { ProviderAdapter } from "../base.js";
2
2
  import { EnvironmentRecord, ServiceName } from "../../types/index.js";
3
3
  export declare class GcpAdapter implements ProviderAdapter {
4
4
  private projectId;
5
+ private projectNumber;
5
6
  private billingAccountId;
6
7
  init(): Promise<void>;
7
8
  createEnvironment(name: string): Promise<EnvironmentRecord>;
9
+ private linkBillingAccount;
8
10
  enableServices(env: EnvironmentRecord, services: ServiceName[]): Promise<void>;
9
11
  connect(env: EnvironmentRecord): Promise<Record<string, string>>;
10
12
  destroyEnvironment(env: EnvironmentRecord): Promise<void>;
11
13
  getStatus(env: EnvironmentRecord): Promise<EnvironmentRecord>;
12
14
  setBillingAccount(accountId: string): void;
13
15
  getProjectId(): string | null;
16
+ getProjectNumber(): string | null;
14
17
  }
15
18
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/gcp/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEtE,qBAAa,UAAW,YAAW,eAAe;IAChD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,gBAAgB,CAAuB;IAEzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA8CrB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiB3D,cAAc,CAClB,GAAG,EAAE,iBAAiB,EACtB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC;IAOV,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAYhE,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAInE,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI1C,YAAY,IAAI,MAAM,GAAG,IAAI;CAG9B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/gcp/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEtE,qBAAa,UAAW,YAAW,eAAe;IAChD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAuB;IAEzC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA8CrB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;YA0DnD,kBAAkB;IAuB1B,cAAc,CAClB,GAAG,EAAE,iBAAiB,EACtB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC;IAiCV,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAYhE,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBzD,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmDnE,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI1C,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,gBAAgB,IAAI,MAAM,GAAG,IAAI;CAGlC"}
@@ -1,6 +1,7 @@
1
1
  import { GCP_SERVICES } from "../base.js";
2
2
  export class GcpAdapter {
3
3
  projectId = null;
4
+ projectNumber = null;
4
5
  billingAccountId = null;
5
6
  async init() {
6
7
  try {
@@ -42,25 +43,93 @@ export class GcpAdapter {
42
43
  }
43
44
  }
44
45
  async createEnvironment(name) {
46
+ if (!this.projectId) {
47
+ throw new Error("No GCP project configured. Set GCP_PROJECT environment variable or run 'gcloud config set project PROJECT_ID'");
48
+ }
49
+ // Generate a unique project ID for the sandman environment
45
50
  const timestamp = Date.now();
46
- const projectId = `sandman-${name}-${timestamp}`;
47
- const now = new Date().toISOString();
48
- return {
49
- name,
50
- provider: "gcp",
51
- projectId,
52
- status: "active",
53
- services: [],
54
- resources: {},
55
- createdAt: now,
56
- updatedAt: now,
57
- };
51
+ const sandmanProjectId = `sandman-${name}-${timestamp}`;
52
+ try {
53
+ const { ProjectsClient } = await import("@google-cloud/resource-manager");
54
+ const resourceManagerClient = new ProjectsClient();
55
+ // Create the project
56
+ const [operation] = await resourceManagerClient.createProject({
57
+ project: {
58
+ projectId: sandmanProjectId,
59
+ name: `Sandman Environment: ${name}`,
60
+ },
61
+ });
62
+ // Wait for the operation to complete
63
+ const [projectOperation] = await operation.promise();
64
+ // Get the project details to get the project number
65
+ const [project] = await resourceManagerClient.getProject({
66
+ name: `projects/${sandmanProjectId}`,
67
+ });
68
+ // Store the project ID and number
69
+ this.projectId = sandmanProjectId;
70
+ this.projectNumber = project.projectNumber?.toString() || null;
71
+ // Link billing account if provided
72
+ if (this.billingAccountId) {
73
+ await this.linkBillingAccount(sandmanProjectId);
74
+ }
75
+ const now = new Date().toISOString();
76
+ return {
77
+ name,
78
+ provider: "gcp",
79
+ projectId: sandmanProjectId,
80
+ status: "active",
81
+ services: [],
82
+ resources: {},
83
+ createdAt: now,
84
+ updatedAt: now,
85
+ };
86
+ }
87
+ catch (error) {
88
+ throw new Error(`Failed to create GCP project: ${error.message ?? "Unknown error"}`);
89
+ }
90
+ }
91
+ async linkBillingAccount(projectId) {
92
+ if (!this.billingAccountId) {
93
+ return;
94
+ }
95
+ try {
96
+ const { CloudBillingClient } = await import("@google-cloud/billing");
97
+ const billingClient = new CloudBillingClient();
98
+ // Update project billing info to link the billing account
99
+ await billingClient.updateProjectBillingInfo({
100
+ name: `projects/${projectId}`,
101
+ projectBillingInfo: {
102
+ billingAccountName: `billingAccounts/${this.billingAccountId}`,
103
+ },
104
+ });
105
+ }
106
+ catch (error) {
107
+ throw new Error(`Failed to link billing account: ${error.message ?? "Unknown error"}`);
108
+ }
58
109
  }
59
110
  async enableServices(env, services) {
60
- const enabledServices = services
61
- .map((s) => GCP_SERVICES[s])
62
- .filter(Boolean);
63
- console.log(`Enabling GCP services: ${enabledServices.join(", ")}`);
111
+ if (!env.projectId) {
112
+ throw new Error("Project ID is required to enable services");
113
+ }
114
+ try {
115
+ const { ServiceUsageClient } = await import("@google-cloud/service-usage");
116
+ const serviceUsageClient = new ServiceUsageClient();
117
+ const serviceNames = services.map((s) => GCP_SERVICES[s]).filter(Boolean);
118
+ if (serviceNames.length === 0) {
119
+ return;
120
+ }
121
+ console.log(`Enabling GCP services: ${serviceNames.join(", ")}`);
122
+ // Enable each service
123
+ for (const serviceName of serviceNames) {
124
+ const request = {
125
+ name: `projects/${env.projectId}/services/${serviceName}`,
126
+ };
127
+ await serviceUsageClient.enableService(request);
128
+ }
129
+ }
130
+ catch (error) {
131
+ throw new Error(`Failed to enable GCP services: ${error.message ?? "Unknown error"}`);
132
+ }
64
133
  }
65
134
  async connect(env) {
66
135
  const result = {
@@ -72,10 +141,70 @@ export class GcpAdapter {
72
141
  return result;
73
142
  }
74
143
  async destroyEnvironment(env) {
75
- console.log(`Would delete GCP project: ${env.projectId}`);
144
+ if (!env.projectId) {
145
+ throw new Error("Project ID is required to destroy environment");
146
+ }
147
+ try {
148
+ const { ProjectsClient } = await import("@google-cloud/resource-manager");
149
+ const resourceManagerClient = new ProjectsClient();
150
+ // Delete the project
151
+ const [operation] = await resourceManagerClient.deleteProject({
152
+ name: `projects/${env.projectId}`,
153
+ });
154
+ // Wait for the operation to complete
155
+ await operation.promise();
156
+ console.log(`Deleted GCP project: ${env.projectId}`);
157
+ }
158
+ catch (error) {
159
+ throw new Error(`Failed to delete GCP project: ${error.message ?? "Unknown error"}`);
160
+ }
76
161
  }
77
162
  async getStatus(env) {
78
- return env;
163
+ if (!env.projectId) {
164
+ return {
165
+ ...env,
166
+ status: "failed",
167
+ error: "Project ID not available",
168
+ };
169
+ }
170
+ try {
171
+ const { ProjectsClient } = await import("@google-cloud/resource-manager");
172
+ const resourceManagerClient = new ProjectsClient();
173
+ // Get the project to check its status
174
+ const [project] = await resourceManagerClient.getProject({
175
+ name: `projects/${env.projectId}`,
176
+ });
177
+ // Map GCP project lifecycle state to our status
178
+ let status = env.status;
179
+ const lifecycleState = project.lifecycleState;
180
+ switch (lifecycleState) {
181
+ case "ACTIVE":
182
+ status = "active";
183
+ break;
184
+ case "DELETE_REQUESTED":
185
+ case "DELETE_IN_PROGRESS":
186
+ status = "destroyed";
187
+ break;
188
+ case "FAILED":
189
+ status = "failed";
190
+ break;
191
+ default:
192
+ status = "pending";
193
+ }
194
+ return {
195
+ ...env,
196
+ status,
197
+ updatedAt: new Date().toISOString(),
198
+ };
199
+ }
200
+ catch (error) {
201
+ // If we can't get the project, it might have been deleted
202
+ return {
203
+ ...env,
204
+ status: "destroyed",
205
+ updatedAt: new Date().toISOString(),
206
+ };
207
+ }
79
208
  }
80
209
  setBillingAccount(accountId) {
81
210
  this.billingAccountId = accountId;
@@ -83,5 +212,8 @@ export class GcpAdapter {
83
212
  getProjectId() {
84
213
  return this.projectId;
85
214
  }
215
+ getProjectNumber() {
216
+ return this.projectNumber;
217
+ }
86
218
  }
87
219
  //# sourceMappingURL=adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/gcp/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/gcp/adapter.ts"],"names":[],"mappings":"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"}