alpic 0.0.0-dev.ff6c5b5 → 0.0.0-dev.ff9c7e6

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 (148) hide show
  1. package/dist/__tests__/auth.e2e.test.js +18 -3
  2. package/dist/__tests__/auth.e2e.test.js.map +1 -1
  3. package/dist/__tests__/deploy-flags.e2e.test.js +107 -6
  4. package/dist/__tests__/deploy-flags.e2e.test.js.map +1 -1
  5. package/dist/__tests__/deploy.e2e.test.js +22 -10
  6. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  7. package/dist/__tests__/deployment-inspect.e2e.test.d.ts +1 -0
  8. package/dist/__tests__/deployment-inspect.e2e.test.js +114 -0
  9. package/dist/__tests__/deployment-inspect.e2e.test.js.map +1 -0
  10. package/dist/__tests__/deployment-list.e2e.test.d.ts +1 -0
  11. package/dist/__tests__/deployment-list.e2e.test.js +116 -0
  12. package/dist/__tests__/deployment-list.e2e.test.js.map +1 -0
  13. package/dist/__tests__/deployment-logs.e2e.test.d.ts +1 -0
  14. package/dist/__tests__/deployment-logs.e2e.test.js +255 -0
  15. package/dist/__tests__/deployment-logs.e2e.test.js.map +1 -0
  16. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.d.ts +1 -0
  17. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js +259 -0
  18. package/dist/__tests__/environment-variable/environment-variable-add.e2e.test.js.map +1 -0
  19. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.d.ts +1 -0
  20. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js +139 -0
  21. package/dist/__tests__/environment-variable/environment-variable-list.e2e.test.js.map +1 -0
  22. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.d.ts +1 -0
  23. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js +150 -0
  24. package/dist/__tests__/environment-variable/environment-variable-remove.e2e.test.js.map +1 -0
  25. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.d.ts +1 -0
  26. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js +342 -0
  27. package/dist/__tests__/environment-variable/environment-variable-update.e2e.test.js.map +1 -0
  28. package/dist/__tests__/environment-variable/environment-variable-validation.test.d.ts +1 -0
  29. package/dist/__tests__/environment-variable/environment-variable-validation.test.js +20 -0
  30. package/dist/__tests__/environment-variable/environment-variable-validation.test.js.map +1 -0
  31. package/dist/__tests__/git-flags.e2e.test.js +6 -6
  32. package/dist/__tests__/git-flags.e2e.test.js.map +1 -1
  33. package/dist/__tests__/git.e2e.test.js +2 -2
  34. package/dist/__tests__/link.e2e.test.d.ts +1 -0
  35. package/dist/__tests__/link.e2e.test.js +279 -0
  36. package/dist/__tests__/link.e2e.test.js.map +1 -0
  37. package/dist/__tests__/logs.e2e.test.d.ts +1 -0
  38. package/dist/__tests__/logs.e2e.test.js +227 -0
  39. package/dist/__tests__/logs.e2e.test.js.map +1 -0
  40. package/dist/__tests__/mock-server.d.ts +20 -0
  41. package/dist/__tests__/mock-server.js +266 -20
  42. package/dist/__tests__/mock-server.js.map +1 -1
  43. package/dist/__tests__/publish.e2e.test.d.ts +1 -0
  44. package/dist/__tests__/publish.e2e.test.js +505 -0
  45. package/dist/__tests__/publish.e2e.test.js.map +1 -0
  46. package/dist/__tests__/tunnel.e2e.test.d.ts +1 -0
  47. package/dist/__tests__/tunnel.e2e.test.js +64 -0
  48. package/dist/__tests__/tunnel.e2e.test.js.map +1 -0
  49. package/dist/__tests__/utils.d.ts +8 -2
  50. package/dist/__tests__/utils.js +55 -20
  51. package/dist/__tests__/utils.js.map +1 -1
  52. package/dist/api.d.ts +1 -1
  53. package/dist/api.js +1 -1
  54. package/dist/api.js.map +1 -1
  55. package/dist/commands/deploy.d.ts +4 -4
  56. package/dist/commands/deploy.js +44 -33
  57. package/dist/commands/deploy.js.map +1 -1
  58. package/dist/commands/deployment/inspect.d.ts +11 -0
  59. package/dist/commands/deployment/inspect.js +91 -0
  60. package/dist/commands/deployment/inspect.js.map +1 -0
  61. package/dist/commands/deployment/list.d.ts +11 -0
  62. package/dist/commands/deployment/list.js +97 -0
  63. package/dist/commands/deployment/list.js.map +1 -0
  64. package/dist/commands/deployment/logs.d.ts +12 -0
  65. package/dist/commands/deployment/logs.js +50 -0
  66. package/dist/commands/deployment/logs.js.map +1 -0
  67. package/dist/commands/environment-variable/add.d.ts +14 -0
  68. package/dist/commands/environment-variable/add.js +47 -0
  69. package/dist/commands/environment-variable/add.js.map +1 -0
  70. package/dist/commands/environment-variable/list.d.ts +9 -0
  71. package/dist/commands/environment-variable/list.js +45 -0
  72. package/dist/commands/environment-variable/list.js.map +1 -0
  73. package/dist/commands/environment-variable/remove.d.ts +11 -0
  74. package/dist/commands/environment-variable/remove.js +33 -0
  75. package/dist/commands/environment-variable/remove.js.map +1 -0
  76. package/dist/commands/environment-variable/update.d.ts +13 -0
  77. package/dist/commands/environment-variable/update.js +41 -0
  78. package/dist/commands/environment-variable/update.js.map +1 -0
  79. package/dist/commands/git/connect.d.ts +1 -4
  80. package/dist/commands/git/connect.js +16 -26
  81. package/dist/commands/git/connect.js.map +1 -1
  82. package/dist/commands/git/disconnect.d.ts +1 -4
  83. package/dist/commands/git/disconnect.js +14 -26
  84. package/dist/commands/git/disconnect.js.map +1 -1
  85. package/dist/commands/git.js +2 -2
  86. package/dist/commands/git.js.map +1 -1
  87. package/dist/commands/link.d.ts +17 -0
  88. package/dist/commands/link.js +101 -0
  89. package/dist/commands/link.js.map +1 -0
  90. package/dist/commands/login.js +4 -2
  91. package/dist/commands/login.js.map +1 -1
  92. package/dist/commands/logs.d.ts +16 -0
  93. package/dist/commands/logs.js +96 -0
  94. package/dist/commands/logs.js.map +1 -0
  95. package/dist/commands/publish.d.ts +15 -0
  96. package/dist/commands/publish.js +51 -0
  97. package/dist/commands/publish.js.map +1 -0
  98. package/dist/commands/tunnel.d.ts +9 -0
  99. package/dist/commands/tunnel.js +53 -0
  100. package/dist/commands/tunnel.js.map +1 -0
  101. package/dist/lib/archive.d.ts +3 -3
  102. package/dist/lib/archive.js +11 -15
  103. package/dist/lib/archive.js.map +1 -1
  104. package/dist/lib/auth/oauth/server/index.js +5 -2
  105. package/dist/lib/auth/oauth/server/index.js.map +1 -1
  106. package/dist/lib/base-workflow.d.ts +1 -1
  107. package/dist/lib/base-workflow.js +1 -1
  108. package/dist/lib/base-workflow.js.map +1 -1
  109. package/dist/lib/config.d.ts +3 -2
  110. package/dist/lib/config.js +8 -7
  111. package/dist/lib/config.js.map +1 -1
  112. package/dist/lib/deployment.d.ts +68 -1
  113. package/dist/lib/deployment.js +111 -15
  114. package/dist/lib/deployment.js.map +1 -1
  115. package/dist/lib/environment-variable.d.ts +37 -0
  116. package/dist/lib/environment-variable.js +299 -0
  117. package/dist/lib/environment-variable.js.map +1 -0
  118. package/dist/lib/git.d.ts +5 -5
  119. package/dist/lib/git.js +10 -13
  120. package/dist/lib/git.js.map +1 -1
  121. package/dist/lib/global-store.js +2 -2
  122. package/dist/lib/global-store.js.map +1 -1
  123. package/dist/lib/{project.d.ts → link.d.ts} +24 -12
  124. package/dist/lib/{project.js → link.js} +184 -96
  125. package/dist/lib/link.js.map +1 -0
  126. package/dist/lib/logs.d.ts +20 -0
  127. package/dist/lib/logs.js +86 -0
  128. package/dist/lib/logs.js.map +1 -0
  129. package/dist/lib/publish.d.ts +22 -0
  130. package/dist/lib/publish.js +185 -0
  131. package/dist/lib/publish.js.map +1 -0
  132. package/dist/lib/resolve.d.ts +6 -0
  133. package/dist/lib/resolve.js +26 -0
  134. package/dist/lib/resolve.js.map +1 -0
  135. package/dist/lib/table.d.ts +8 -0
  136. package/dist/lib/table.js +27 -0
  137. package/dist/lib/table.js.map +1 -0
  138. package/dist/lib/telemetry.js +1 -1
  139. package/dist/lib/telemetry.js.map +1 -1
  140. package/dist/lib/utils.d.ts +4 -0
  141. package/dist/lib/utils.js +45 -0
  142. package/dist/lib/utils.js.map +1 -0
  143. package/dist/lib/utils.test.d.ts +1 -0
  144. package/dist/lib/utils.test.js +27 -0
  145. package/dist/lib/utils.test.js.map +1 -0
  146. package/dist/types.d.ts +1 -0
  147. package/package.json +24 -19
  148. package/dist/lib/project.js.map +0 -1
@@ -0,0 +1,139 @@
1
+ import { rmSync } from "node:fs";
2
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
3
+ import { MockApiServer } from "../mock-server.js";
4
+ import { buildMockProject, cliSession, createConfigFile, expectSuccessfulApiCall, setupTestDirectory, } from "../utils.js";
5
+ describe("alpic environment-variable list (E2E)", () => {
6
+ let mockServer;
7
+ let serverUrl;
8
+ let cwd;
9
+ let binPath;
10
+ const projectId = "test-project-id";
11
+ const teamId = "mock-team-id";
12
+ const environmentId = "test-env-id";
13
+ const environmentName = "production";
14
+ beforeEach(async () => {
15
+ mockServer = new MockApiServer();
16
+ serverUrl = await mockServer.start();
17
+ const setup = await setupTestDirectory();
18
+ cwd = setup.cwd;
19
+ binPath = setup.binPath;
20
+ mockServer.addProject(buildMockProject({
21
+ projectId,
22
+ teamId,
23
+ projectName: "test-project",
24
+ environmentId,
25
+ environmentName,
26
+ }));
27
+ });
28
+ afterEach(async () => {
29
+ await mockServer.stop();
30
+ if (cwd) {
31
+ rmSync(cwd, { recursive: true, force: true });
32
+ }
33
+ });
34
+ it("shows 'no environment variables' message when list is empty", async () => {
35
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "list", "--environment-id", environmentId], {
36
+ cwd,
37
+ env: {
38
+ ALPIC_API_BASE_URL: serverUrl,
39
+ ALPIC_API_KEY: "test-api-key",
40
+ },
41
+ }, async (cli) => {
42
+ await cli.expect("No environment variables defined.");
43
+ });
44
+ expect(exitCode).toBe(0);
45
+ expect(output).toContain("Found 0 environment variables");
46
+ expect(output).toContain("No environment variables defined.");
47
+ const listCall = mockServer.getLastCall("GET", `/v1/environments/${environmentId}/environment-variables`);
48
+ expectSuccessfulApiCall(listCall);
49
+ });
50
+ it("shows a nicely formatted table with environment variables", async () => {
51
+ const oneHourAgo = new Date(Date.now() - 1 * 60 * 60 * 1000);
52
+ mockServer.addEnvironmentVariables(environmentId, [
53
+ {
54
+ id: "var-1",
55
+ key: "DATABASE_URL",
56
+ value: "postgres://localhost/db",
57
+ isSecret: false,
58
+ createdAt: oneHourAgo,
59
+ },
60
+ {
61
+ id: "var-2",
62
+ key: "API_KEY",
63
+ value: "supersecret",
64
+ isSecret: true,
65
+ createdAt: oneHourAgo,
66
+ },
67
+ {
68
+ id: "var-3",
69
+ key: "PORT",
70
+ value: "3000",
71
+ isSecret: false,
72
+ createdAt: oneHourAgo,
73
+ },
74
+ ]);
75
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "list", "--environment-id", environmentId], {
76
+ cwd,
77
+ env: {
78
+ ALPIC_API_BASE_URL: serverUrl,
79
+ ALPIC_API_KEY: "test-api-key",
80
+ },
81
+ }, async (cli) => {
82
+ await cli.expect("Found 3 environment variables");
83
+ });
84
+ expect(exitCode).toBe(0);
85
+ const normalizedOutput = output.replace(/^.*Fetching environment variables\.\.\.\r?\n?/gm, "");
86
+ expect(normalizedOutput).toMatchSnapshot();
87
+ expect(output).not.toContain("supersecret");
88
+ });
89
+ it("shows info message when environment-id is taken from config file", async () => {
90
+ createConfigFile(cwd, projectId, teamId, "test-project", environmentId, environmentName);
91
+ const { exitCode } = await cliSession(process.execPath, [binPath, "environment-variable", "list"], {
92
+ cwd,
93
+ env: {
94
+ ALPIC_API_BASE_URL: serverUrl,
95
+ ALPIC_API_KEY: "test-api-key",
96
+ },
97
+ }, async (cli) => {
98
+ await cli.expect(`Using environment id from .alpic config: ${environmentId}`);
99
+ await cli.expect("Found 0 environment variables");
100
+ });
101
+ expect(exitCode).toBe(0);
102
+ });
103
+ it("does not show info message when environment-id is provided via flag", async () => {
104
+ createConfigFile(cwd, projectId, teamId, "test-project", environmentId, environmentName);
105
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "list", "--environment-id", environmentId], {
106
+ cwd,
107
+ env: {
108
+ ALPIC_API_BASE_URL: serverUrl,
109
+ ALPIC_API_KEY: "test-api-key",
110
+ },
111
+ }, async (cli) => {
112
+ await cli.expect("Found 0 environment variables");
113
+ });
114
+ expect(exitCode).toBe(0);
115
+ expect(output).not.toContain("Using environment id from .alpic config");
116
+ });
117
+ it("exits with error when not authenticated", async () => {
118
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "list", "--environment-id", environmentId], {
119
+ cwd,
120
+ env: {
121
+ ALPIC_API_BASE_URL: serverUrl,
122
+ },
123
+ });
124
+ expect(exitCode).toBe(1);
125
+ expect(output).toContain("Not authenticated. Run `alpic login` or set ALPIC_API_KEY. Get an API key from Team settings in the Alpic dashboard.");
126
+ });
127
+ it("exits with error when no environment-id is provided and no config file exists", async () => {
128
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "list"], {
129
+ cwd,
130
+ env: {
131
+ ALPIC_API_BASE_URL: serverUrl,
132
+ ALPIC_API_KEY: "test-api-key",
133
+ },
134
+ });
135
+ expect(exitCode).toBe(1);
136
+ expect(output).toContain("No environment specified");
137
+ });
138
+ }, 15_000);
139
+ //# sourceMappingURL=environment-variable-list.e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-variable-list.e2e.test.js","sourceRoot":"","sources":["../../../src/__tests__/environment-variable/environment-variable-list.e2e.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { rmSync } from "node:fs";
2
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
3
+ import { MockApiServer } from "../mock-server.js";
4
+ import { buildMockProject, cliSession, createConfigFile, expectSuccessfulApiCall, setupTestDirectory, } from "../utils.js";
5
+ describe("alpic environment-variable remove (E2E)", () => {
6
+ let mockServer;
7
+ let serverUrl;
8
+ let cwd;
9
+ let binPath;
10
+ const projectId = "test-project-id";
11
+ const teamId = "mock-team-id";
12
+ const environmentId = "test-env-id";
13
+ const environmentName = "production";
14
+ beforeEach(async () => {
15
+ mockServer = new MockApiServer();
16
+ serverUrl = await mockServer.start();
17
+ const setup = await setupTestDirectory();
18
+ cwd = setup.cwd;
19
+ binPath = setup.binPath;
20
+ mockServer.addProject(buildMockProject({
21
+ projectId,
22
+ teamId,
23
+ projectName: "test-project",
24
+ environmentId,
25
+ environmentName,
26
+ }));
27
+ mockServer.addEnvironmentVariables(environmentId, [
28
+ {
29
+ id: "var-1",
30
+ key: "DATABASE_URL",
31
+ value: "postgres://localhost/db",
32
+ isSecret: false,
33
+ createdAt: new Date(),
34
+ },
35
+ {
36
+ id: "var-2",
37
+ key: "API_KEY",
38
+ value: "supersecret",
39
+ isSecret: true,
40
+ createdAt: new Date(),
41
+ },
42
+ ]);
43
+ });
44
+ afterEach(async () => {
45
+ await mockServer.stop();
46
+ if (cwd) {
47
+ rmSync(cwd, { recursive: true, force: true });
48
+ }
49
+ });
50
+ it("removes a variable in non-interactive mode", async () => {
51
+ const { exitCode, output } = await cliSession(process.execPath, [
52
+ binPath,
53
+ "environment-variable",
54
+ "remove",
55
+ "--environment-id",
56
+ environmentId,
57
+ "--key",
58
+ "DATABASE_URL",
59
+ "--non-interactive",
60
+ ], {
61
+ cwd,
62
+ env: {
63
+ ALPIC_API_BASE_URL: serverUrl,
64
+ ALPIC_API_KEY: "test-api-key",
65
+ },
66
+ }, async (cli) => {
67
+ await cli.expect("Successfully removed DATABASE_URL.");
68
+ });
69
+ expect(exitCode).toBe(0);
70
+ expect(output).toContain("Successfully removed DATABASE_URL.");
71
+ const call = mockServer.getLastCall("DELETE", "/v1/environment-variables/var-1");
72
+ expectSuccessfulApiCall(call);
73
+ });
74
+ it("uses environment-id from config file", async () => {
75
+ createConfigFile(cwd, projectId, teamId, "test-project", environmentId, environmentName);
76
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "remove", "--key", "DATABASE_URL", "--non-interactive"], {
77
+ cwd,
78
+ env: {
79
+ ALPIC_API_BASE_URL: serverUrl,
80
+ ALPIC_API_KEY: "test-api-key",
81
+ },
82
+ }, async (cli) => {
83
+ await cli.expect("Successfully removed DATABASE_URL.");
84
+ });
85
+ expect(exitCode).toBe(0);
86
+ expect(output).toContain(`Using environment id from .alpic config: ${environmentId}`);
87
+ });
88
+ it("errors when key does not exist", async () => {
89
+ const { exitCode, output } = await cliSession(process.execPath, [
90
+ binPath,
91
+ "environment-variable",
92
+ "remove",
93
+ "--environment-id",
94
+ environmentId,
95
+ "--key",
96
+ "NONEXISTENT",
97
+ "--non-interactive",
98
+ ], {
99
+ cwd,
100
+ env: {
101
+ ALPIC_API_BASE_URL: serverUrl,
102
+ ALPIC_API_KEY: "test-api-key",
103
+ },
104
+ });
105
+ expect(exitCode).toBe(1);
106
+ expect(output).toContain('Environment variable "NONEXISTENT" not found.');
107
+ });
108
+ it("errors when --key is missing in non-interactive mode", async () => {
109
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "remove", "--environment-id", environmentId, "--non-interactive"], {
110
+ cwd,
111
+ env: {
112
+ ALPIC_API_BASE_URL: serverUrl,
113
+ ALPIC_API_KEY: "test-api-key",
114
+ },
115
+ });
116
+ expect(exitCode).toBe(1);
117
+ expect(output).toContain("--key is required in non-interactive mode.");
118
+ });
119
+ it("exits with error when not authenticated", async () => {
120
+ const { exitCode, output } = await cliSession(process.execPath, [
121
+ binPath,
122
+ "environment-variable",
123
+ "remove",
124
+ "--environment-id",
125
+ environmentId,
126
+ "--key",
127
+ "DATABASE_URL",
128
+ "--non-interactive",
129
+ ], {
130
+ cwd,
131
+ env: {
132
+ ALPIC_API_BASE_URL: serverUrl,
133
+ },
134
+ });
135
+ expect(exitCode).toBe(1);
136
+ expect(output).toContain("Not authenticated. Run `alpic login` or set ALPIC_API_KEY. Get an API key from Team settings in the Alpic dashboard.");
137
+ });
138
+ it("exits with error when no environment-id is provided and no config file exists", async () => {
139
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "remove", "--key", "DATABASE_URL", "--non-interactive"], {
140
+ cwd,
141
+ env: {
142
+ ALPIC_API_BASE_URL: serverUrl,
143
+ ALPIC_API_KEY: "test-api-key",
144
+ },
145
+ });
146
+ expect(exitCode).toBe(1);
147
+ expect(output).toContain("No environment specified");
148
+ });
149
+ }, 15_000);
150
+ //# sourceMappingURL=environment-variable-remove.e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-variable-remove.e2e.test.js","sourceRoot":"","sources":["../../../src/__tests__/environment-variable/environment-variable-remove.e2e.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,342 @@
1
+ import { rmSync } from "node:fs";
2
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
3
+ import { MockApiServer } from "../mock-server.js";
4
+ import { buildMockProject, cliSession, createConfigFile, expectSuccessfulApiCall, setupTestDirectory, } from "../utils.js";
5
+ describe("alpic environment-variable update (E2E)", () => {
6
+ let mockServer;
7
+ let serverUrl;
8
+ let cwd;
9
+ let binPath;
10
+ const projectId = "test-project-id";
11
+ const teamId = "mock-team-id";
12
+ const environmentId = "test-env-id";
13
+ const environmentName = "production";
14
+ beforeEach(async () => {
15
+ mockServer = new MockApiServer();
16
+ serverUrl = await mockServer.start();
17
+ const setup = await setupTestDirectory();
18
+ cwd = setup.cwd;
19
+ binPath = setup.binPath;
20
+ mockServer.addProject(buildMockProject({
21
+ projectId,
22
+ teamId,
23
+ projectName: "test-project",
24
+ environmentId,
25
+ environmentName,
26
+ }));
27
+ mockServer.addEnvironmentVariables(environmentId, [
28
+ {
29
+ id: "var-1",
30
+ key: "DATABASE_URL",
31
+ value: "postgres://localhost/db",
32
+ isSecret: false,
33
+ createdAt: new Date(),
34
+ },
35
+ {
36
+ id: "var-2",
37
+ key: "API_KEY",
38
+ value: "supersecret",
39
+ isSecret: true,
40
+ createdAt: new Date(),
41
+ },
42
+ ]);
43
+ });
44
+ afterEach(async () => {
45
+ await mockServer.stop();
46
+ if (cwd) {
47
+ rmSync(cwd, { recursive: true, force: true });
48
+ }
49
+ });
50
+ it("updates a variable in non-interactive mode", async () => {
51
+ const { exitCode, output } = await cliSession(process.execPath, [
52
+ binPath,
53
+ "environment-variable",
54
+ "update",
55
+ "--environment-id",
56
+ environmentId,
57
+ "--key",
58
+ "DATABASE_URL",
59
+ "--value",
60
+ "postgres://prod/db",
61
+ "--non-interactive",
62
+ ], {
63
+ cwd,
64
+ env: {
65
+ ALPIC_API_BASE_URL: serverUrl,
66
+ ALPIC_API_KEY: "test-api-key",
67
+ },
68
+ }, async (cli) => {
69
+ await cli.expect("Successfully updated DATABASE_URL.");
70
+ });
71
+ expect(exitCode).toBe(0);
72
+ expect(output).toContain("Successfully updated DATABASE_URL.");
73
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-1");
74
+ expectSuccessfulApiCall(call);
75
+ expect(call?.input).toMatchObject({
76
+ key: "DATABASE_URL",
77
+ value: "postgres://prod/db",
78
+ isSecret: false,
79
+ });
80
+ });
81
+ it("preserves isSecret when updating", async () => {
82
+ const { exitCode } = await cliSession(process.execPath, [
83
+ binPath,
84
+ "environment-variable",
85
+ "update",
86
+ "--environment-id",
87
+ environmentId,
88
+ "--key",
89
+ "API_KEY",
90
+ "--value",
91
+ "new-secret-value",
92
+ "--non-interactive",
93
+ ], {
94
+ cwd,
95
+ env: {
96
+ ALPIC_API_BASE_URL: serverUrl,
97
+ ALPIC_API_KEY: "test-api-key",
98
+ },
99
+ }, async (cli) => {
100
+ await cli.expect("Successfully updated API_KEY.");
101
+ });
102
+ expect(exitCode).toBe(0);
103
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-2");
104
+ expectSuccessfulApiCall(call);
105
+ expect(call?.input).toMatchObject({
106
+ key: "API_KEY",
107
+ value: "new-secret-value",
108
+ isSecret: true,
109
+ });
110
+ });
111
+ it("updates secret visibility with --no-secret", async () => {
112
+ const { exitCode, output } = await cliSession(process.execPath, [
113
+ binPath,
114
+ "environment-variable",
115
+ "update",
116
+ "--environment-id",
117
+ environmentId,
118
+ "--key",
119
+ "API_KEY",
120
+ "--value",
121
+ "still-secret-value",
122
+ "--no-secret",
123
+ "--non-interactive",
124
+ ], {
125
+ cwd,
126
+ env: {
127
+ ALPIC_API_BASE_URL: serverUrl,
128
+ ALPIC_API_KEY: "test-api-key",
129
+ },
130
+ }, async (cli) => {
131
+ await cli.expect("Successfully updated API_KEY.");
132
+ });
133
+ expect(exitCode).toBe(0);
134
+ expect(output).toContain("Successfully updated API_KEY.");
135
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-2");
136
+ expectSuccessfulApiCall(call);
137
+ expect(call?.input).toMatchObject({
138
+ key: "API_KEY",
139
+ value: "still-secret-value",
140
+ isSecret: false,
141
+ });
142
+ });
143
+ it("updates only secret visibility in non-interactive mode", async () => {
144
+ const { exitCode, output } = await cliSession(process.execPath, [
145
+ binPath,
146
+ "environment-variable",
147
+ "update",
148
+ "--environment-id",
149
+ environmentId,
150
+ "--key",
151
+ "DATABASE_URL",
152
+ "--secret",
153
+ "--non-interactive",
154
+ ], {
155
+ cwd,
156
+ env: {
157
+ ALPIC_API_BASE_URL: serverUrl,
158
+ ALPIC_API_KEY: "test-api-key",
159
+ },
160
+ }, async (cli) => {
161
+ await cli.expect("Successfully updated DATABASE_URL.");
162
+ });
163
+ expect(exitCode).toBe(0);
164
+ expect(output).toContain("Successfully updated DATABASE_URL.");
165
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-1");
166
+ expectSuccessfulApiCall(call);
167
+ expect(call?.input).toMatchObject({
168
+ key: "DATABASE_URL",
169
+ isSecret: true,
170
+ });
171
+ });
172
+ it("prompts for secret status in interactive mode and defaults to current value", async () => {
173
+ const { exitCode, output } = await cliSession(process.execPath, [
174
+ binPath,
175
+ "environment-variable",
176
+ "update",
177
+ "--environment-id",
178
+ environmentId,
179
+ "--key",
180
+ "API_KEY",
181
+ "--value",
182
+ "updated-value",
183
+ ], {
184
+ cwd,
185
+ env: {
186
+ ALPIC_API_BASE_URL: serverUrl,
187
+ ALPIC_API_KEY: "test-api-key",
188
+ },
189
+ }, async (cli) => {
190
+ await cli.expect("Mark as secret?");
191
+ cli.write("\u001B[B");
192
+ await cli.send("");
193
+ await cli.expect("Successfully updated API_KEY.");
194
+ });
195
+ expect(exitCode).toBe(0);
196
+ expect(output).toContain("Successfully updated API_KEY.");
197
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-2");
198
+ expectSuccessfulApiCall(call);
199
+ expect(call?.input).toMatchObject({
200
+ key: "API_KEY",
201
+ value: "updated-value",
202
+ isSecret: false,
203
+ });
204
+ });
205
+ it("keeps current value when interactive value prompt is skipped", async () => {
206
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "update", "--environment-id", environmentId, "--key", "DATABASE_URL"], {
207
+ cwd,
208
+ env: {
209
+ ALPIC_API_BASE_URL: serverUrl,
210
+ ALPIC_API_KEY: "test-api-key",
211
+ },
212
+ }, async (cli) => {
213
+ await cli.expect("New value for DATABASE_URL");
214
+ await cli.send("");
215
+ await cli.expect("Mark as secret?");
216
+ await cli.send("");
217
+ await cli.expect("Successfully updated DATABASE_URL.");
218
+ });
219
+ expect(exitCode).toBe(0);
220
+ expect(output).toContain("No value provided, keeping the current value.");
221
+ expect(output).toContain("Successfully updated DATABASE_URL.");
222
+ const call = mockServer.getLastCall("PATCH", "/v1/environment-variables/var-1");
223
+ expectSuccessfulApiCall(call);
224
+ const input = call.input;
225
+ expect(input).toMatchObject({
226
+ key: "DATABASE_URL",
227
+ isSecret: false,
228
+ });
229
+ expect(input.value).toBeUndefined();
230
+ });
231
+ it("uses environment-id from config file", async () => {
232
+ createConfigFile(cwd, projectId, teamId, "test-project", environmentId, environmentName);
233
+ const { exitCode, output } = await cliSession(process.execPath, [
234
+ binPath,
235
+ "environment-variable",
236
+ "update",
237
+ "--key",
238
+ "DATABASE_URL",
239
+ "--value",
240
+ "postgres://prod/db",
241
+ "--non-interactive",
242
+ ], {
243
+ cwd,
244
+ env: {
245
+ ALPIC_API_BASE_URL: serverUrl,
246
+ ALPIC_API_KEY: "test-api-key",
247
+ },
248
+ }, async (cli) => {
249
+ await cli.expect("Successfully updated DATABASE_URL.");
250
+ });
251
+ expect(exitCode).toBe(0);
252
+ expect(output).toContain(`Using environment id from .alpic config: ${environmentId}`);
253
+ });
254
+ it("errors when key does not exist", async () => {
255
+ const { exitCode, output } = await cliSession(process.execPath, [
256
+ binPath,
257
+ "environment-variable",
258
+ "update",
259
+ "--environment-id",
260
+ environmentId,
261
+ "--key",
262
+ "NONEXISTENT",
263
+ "--value",
264
+ "value",
265
+ "--non-interactive",
266
+ ], {
267
+ cwd,
268
+ env: {
269
+ ALPIC_API_BASE_URL: serverUrl,
270
+ ALPIC_API_KEY: "test-api-key",
271
+ },
272
+ });
273
+ expect(exitCode).toBe(1);
274
+ expect(output).toContain('Environment variable "NONEXISTENT" not found.');
275
+ });
276
+ it("errors when --value is empty in non-interactive mode", async () => {
277
+ const { exitCode, output } = await cliSession(process.execPath, [
278
+ binPath,
279
+ "environment-variable",
280
+ "update",
281
+ "--environment-id",
282
+ environmentId,
283
+ "--key",
284
+ "DATABASE_URL",
285
+ "--value",
286
+ "",
287
+ "--non-interactive",
288
+ ], {
289
+ cwd,
290
+ env: {
291
+ ALPIC_API_BASE_URL: serverUrl,
292
+ ALPIC_API_KEY: "test-api-key",
293
+ },
294
+ });
295
+ expect(exitCode).toBe(1);
296
+ expect(output).toContain("Value cannot be empty.");
297
+ });
298
+ it("errors when --key or both --value and --secret/--no-secret are missing in non-interactive mode", async () => {
299
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "update", "--environment-id", environmentId, "--non-interactive"], {
300
+ cwd,
301
+ env: {
302
+ ALPIC_API_BASE_URL: serverUrl,
303
+ ALPIC_API_KEY: "test-api-key",
304
+ },
305
+ });
306
+ expect(exitCode).toBe(1);
307
+ expect(output).toContain("--key and one of --value or --secret/--no-secret are required in non-interactive mode.");
308
+ });
309
+ it("exits with error when not authenticated", async () => {
310
+ const { exitCode, output } = await cliSession(process.execPath, [
311
+ binPath,
312
+ "environment-variable",
313
+ "update",
314
+ "--environment-id",
315
+ environmentId,
316
+ "--key",
317
+ "DATABASE_URL",
318
+ "--value",
319
+ "new-value",
320
+ "--non-interactive",
321
+ ], {
322
+ cwd,
323
+ env: {
324
+ ALPIC_API_BASE_URL: serverUrl,
325
+ },
326
+ });
327
+ expect(exitCode).toBe(1);
328
+ expect(output).toContain("Not authenticated. Run `alpic login` or set ALPIC_API_KEY. Get an API key from Team settings in the Alpic dashboard.");
329
+ });
330
+ it("exits with error when no environment-id is provided and no config file exists", async () => {
331
+ const { exitCode, output } = await cliSession(process.execPath, [binPath, "environment-variable", "update", "--key", "DATABASE_URL", "--value", "new-value", "--non-interactive"], {
332
+ cwd,
333
+ env: {
334
+ ALPIC_API_BASE_URL: serverUrl,
335
+ ALPIC_API_KEY: "test-api-key",
336
+ },
337
+ });
338
+ expect(exitCode).toBe(1);
339
+ expect(output).toContain("No environment specified");
340
+ });
341
+ }, 15_000);
342
+ //# sourceMappingURL=environment-variable-update.e2e.test.js.map