alpic 0.0.0-dev.f55bd3e → 0.0.0-dev.f5cc295

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 (69) hide show
  1. package/dist/__tests__/auth.e2e.test.d.ts +1 -0
  2. package/dist/__tests__/auth.e2e.test.js +142 -0
  3. package/dist/__tests__/auth.e2e.test.js.map +1 -0
  4. package/dist/__tests__/deploy.e2e.test.js +36 -4
  5. package/dist/__tests__/deploy.e2e.test.js.map +1 -1
  6. package/dist/__tests__/git.e2e.test.js +53 -17
  7. package/dist/__tests__/git.e2e.test.js.map +1 -1
  8. package/dist/__tests__/mock-server.js +60 -3
  9. package/dist/__tests__/mock-server.js.map +1 -1
  10. package/dist/__tests__/utils.d.ts +7 -1
  11. package/dist/__tests__/utils.js +24 -1
  12. package/dist/__tests__/utils.js.map +1 -1
  13. package/dist/api.d.ts +0 -1
  14. package/dist/api.js +5 -9
  15. package/dist/api.js.map +1 -1
  16. package/dist/commands/deploy.js +4 -8
  17. package/dist/commands/deploy.js.map +1 -1
  18. package/dist/commands/git/connect.js +4 -10
  19. package/dist/commands/git/connect.js.map +1 -1
  20. package/dist/commands/git/disconnect.js +4 -8
  21. package/dist/commands/git/disconnect.js.map +1 -1
  22. package/dist/commands/git.js +1 -1
  23. package/dist/commands/git.js.map +1 -1
  24. package/dist/commands/login.d.ts +6 -0
  25. package/dist/commands/login.js +38 -0
  26. package/dist/commands/login.js.map +1 -0
  27. package/dist/commands/logout.d.ts +6 -0
  28. package/dist/commands/logout.js +20 -0
  29. package/dist/commands/logout.js.map +1 -0
  30. package/dist/commands/whoami.d.ts +6 -0
  31. package/dist/commands/whoami.js +25 -0
  32. package/dist/commands/whoami.js.map +1 -0
  33. package/dist/env.d.ts +4 -0
  34. package/dist/env.js +10 -0
  35. package/dist/env.js.map +1 -0
  36. package/dist/lib/alpic-command.js +0 -3
  37. package/dist/lib/alpic-command.js.map +1 -1
  38. package/dist/lib/auth/auth.d.ts +2 -0
  39. package/dist/lib/auth/auth.js +21 -0
  40. package/dist/lib/auth/auth.js.map +1 -0
  41. package/dist/lib/auth/oauth/client.d.ts +29 -0
  42. package/dist/lib/auth/oauth/client.js +112 -0
  43. package/dist/lib/auth/oauth/client.js.map +1 -0
  44. package/dist/lib/auth/oauth/constants.d.ts +2 -0
  45. package/dist/lib/auth/oauth/constants.js +3 -0
  46. package/dist/lib/auth/oauth/constants.js.map +1 -0
  47. package/dist/lib/auth/oauth/server.d.ts +6 -0
  48. package/dist/lib/auth/oauth/server.js +88 -0
  49. package/dist/lib/auth/oauth/server.js.map +1 -0
  50. package/dist/lib/auth/whoami.d.ts +28 -0
  51. package/dist/lib/auth/whoami.js +35 -0
  52. package/dist/lib/auth/whoami.js.map +1 -0
  53. package/dist/lib/deployment.d.ts +2 -3
  54. package/dist/lib/deployment.js +13 -8
  55. package/dist/lib/deployment.js.map +1 -1
  56. package/dist/lib/git.js +2 -3
  57. package/dist/lib/git.js.map +1 -1
  58. package/dist/lib/global-store.d.ts +28 -0
  59. package/dist/lib/global-store.js +75 -0
  60. package/dist/lib/global-store.js.map +1 -0
  61. package/dist/lib/telemetry.js +6 -6
  62. package/dist/lib/telemetry.js.map +1 -1
  63. package/package.json +12 -5
  64. package/dist/lib/auth.d.ts +0 -1
  65. package/dist/lib/auth.js +0 -10
  66. package/dist/lib/auth.js.map +0 -1
  67. package/dist/lib/global-config.d.ts +0 -9
  68. package/dist/lib/global-config.js +0 -48
  69. package/dist/lib/global-config.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ import { oAuthClient } from "./oauth/client.js";
2
+ export async function getApiToken() {
3
+ const token = process.env.ALPIC_API_KEY ?? (await oAuthClient.getValidAccessToken())?.access_token;
4
+ return token;
5
+ }
6
+ export async function isAuthenticated() {
7
+ const isAuthenticatedViaApiKey = hasApiKey();
8
+ if (isAuthenticatedViaApiKey)
9
+ return true;
10
+ const isAuthenticatedViaOAuth = await hasValidAccessToken();
11
+ if (isAuthenticatedViaOAuth)
12
+ return true;
13
+ return false;
14
+ }
15
+ function hasApiKey() {
16
+ return process.env.ALPIC_API_KEY !== undefined;
17
+ }
18
+ async function hasValidAccessToken() {
19
+ return (await oAuthClient.getValidAccessToken()) !== null;
20
+ }
21
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/lib/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,WAAW,CAAC,mBAAmB,EAAE,CAAC,EAAE,YAAY,CAAC;IAEnG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,wBAAwB,GAAG,SAAS,EAAE,CAAC;IAC7C,IAAI,wBAAwB;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,uBAAuB,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5D,IAAI,uBAAuB;QAAE,OAAO,IAAI,CAAC;IAEzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,mBAAmB;IAChC,OAAO,CAAC,MAAM,WAAW,CAAC,mBAAmB,EAAE,CAAC,KAAK,IAAI,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,29 @@
1
+ import * as openid from "openid-client";
2
+ import { type Credentials } from "../../global-store.js";
3
+ export declare class OAuthClient {
4
+ private config;
5
+ initialize: Promise<void>;
6
+ constructor();
7
+ getValidAccessToken(): Promise<Credentials | null>;
8
+ fetchUserInfo(credentials: Credentials): Promise<openid.UserInfoResponse>;
9
+ refreshAccessToken(credentials: Credentials): Promise<Credentials>;
10
+ prepareOAuthConfig(): Promise<{
11
+ authorizeUrl: URL;
12
+ state: string;
13
+ nonce: string;
14
+ codeVerifier: string;
15
+ }>;
16
+ exchangeAuthorizationCode({ url, codeVerifier, state, nonce, }: {
17
+ url: URL;
18
+ codeVerifier: string;
19
+ state: string;
20
+ nonce: string;
21
+ }): Promise<openid.TokenEndpointResponse & openid.TokenEndpointResponseHelpers>;
22
+ getExpiresAt(expires_in: number): number;
23
+ private getCallbackUrl;
24
+ private loadConfig;
25
+ private fetchOAuthProtectedResourceConfig;
26
+ private getConfig;
27
+ private isAccessTokenExpired;
28
+ }
29
+ export declare const oAuthClient: OAuthClient;
@@ -0,0 +1,112 @@
1
+ import * as openid from "openid-client";
2
+ import { env } from "../../../env.js";
3
+ import { globalStore } from "../../global-store.js";
4
+ import { LOOPBACK_HOST, LOOPBACK_PORT } from "./constants.js";
5
+ const SCOPES = ["openid", "email", "profile"];
6
+ export class OAuthClient {
7
+ config = null;
8
+ initialize;
9
+ constructor() {
10
+ this.initialize = this.loadConfig();
11
+ }
12
+ async getValidAccessToken() {
13
+ await this.initialize;
14
+ const stored = globalStore.getCredentials();
15
+ if (!stored) {
16
+ return null;
17
+ }
18
+ if (this.isAccessTokenExpired(stored)) {
19
+ try {
20
+ return await this.refreshAccessToken(stored);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ return stored;
27
+ }
28
+ async fetchUserInfo(credentials) {
29
+ return openid.fetchUserInfo(await this.getConfig(), credentials.access_token, credentials.sub);
30
+ }
31
+ async refreshAccessToken(credentials) {
32
+ if (!credentials.refresh_token) {
33
+ throw new Error("No refresh token available");
34
+ }
35
+ const response = await openid.refreshTokenGrant(await this.getConfig(), credentials.refresh_token);
36
+ const refreshed = {
37
+ access_token: response.access_token,
38
+ refresh_token: response.refresh_token ?? credentials.refresh_token,
39
+ expires_at: this.getExpiresAt(response.expires_in ?? 0),
40
+ sub: credentials.sub,
41
+ };
42
+ globalStore.saveCredentials(refreshed);
43
+ return refreshed;
44
+ }
45
+ async prepareOAuthConfig() {
46
+ await this.initialize;
47
+ if (!this.config) {
48
+ throw new Error("Config not loaded");
49
+ }
50
+ const codeVerifier = openid.randomPKCECodeVerifier();
51
+ const codeChallenge = await openid.calculatePKCECodeChallenge(codeVerifier);
52
+ const state = openid.randomState();
53
+ const nonce = openid.randomNonce();
54
+ const authorizeUrl = openid.buildAuthorizationUrl(this.config, {
55
+ redirect_uri: this.getCallbackUrl().toString(),
56
+ scope: SCOPES.join(" "),
57
+ code_challenge: codeChallenge,
58
+ code_challenge_method: "S256",
59
+ state,
60
+ nonce,
61
+ });
62
+ return { authorizeUrl, state, nonce, codeVerifier };
63
+ }
64
+ async exchangeAuthorizationCode({ url, codeVerifier, state, nonce, }) {
65
+ return await openid.authorizationCodeGrant(await this.getConfig(), url, {
66
+ pkceCodeVerifier: codeVerifier,
67
+ expectedState: state,
68
+ expectedNonce: nonce,
69
+ });
70
+ }
71
+ getExpiresAt(expires_in) {
72
+ return expires_in !== undefined ? Math.floor(Date.now() / 1000) + expires_in : Date.now() / 1000 + 3600;
73
+ }
74
+ getCallbackUrl() {
75
+ return new URL(`http://${LOOPBACK_HOST}:${LOOPBACK_PORT}/callback`);
76
+ }
77
+ async loadConfig() {
78
+ const protectedResourceConfig = await this.fetchOAuthProtectedResourceConfig();
79
+ const issuer = protectedResourceConfig.authorization_servers[0];
80
+ if (!issuer) {
81
+ throw new Error("No authorization server in OAuth protected resource config");
82
+ }
83
+ const issuerUrl = new URL(issuer);
84
+ try {
85
+ this.config = await openid.discovery(issuerUrl, env.ALPIC_COGNITO_CLIENT_ID);
86
+ }
87
+ catch {
88
+ throw new Error("Failed to discover OAuth config");
89
+ }
90
+ }
91
+ async fetchOAuthProtectedResourceConfig() {
92
+ const baseUrl = env.ALPIC_API_BASE_URL;
93
+ const response = await fetch(`${baseUrl}/.well-known/oauth-protected-resource`);
94
+ if (!response.ok) {
95
+ throw new Error(`Failed to load service config from ${baseUrl} (${response.status} ${response.statusText})`);
96
+ }
97
+ return (await response.json());
98
+ }
99
+ async getConfig() {
100
+ await this.initialize;
101
+ if (!this.config) {
102
+ throw new Error("Config not loaded");
103
+ }
104
+ return this.config;
105
+ }
106
+ isAccessTokenExpired(credentials) {
107
+ const EXPIRATION_WINDOW_IN_SECONDS = 300;
108
+ return Date.now() / 1000 + EXPIRATION_WINDOW_IN_SECONDS >= credentials.expires_at;
109
+ }
110
+ }
111
+ export const oAuthClient = new OAuthClient();
112
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const LOOPBACK_HOST = "127.0.0.1";
2
+ export declare const LOOPBACK_PORT = 38472;
@@ -0,0 +1,3 @@
1
+ export const LOOPBACK_HOST = "127.0.0.1";
2
+ export const LOOPBACK_PORT = 38472;
3
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Credentials } from "../../global-store.js";
2
+ export declare const listenToOAuthCallback: ({ state, nonce, codeVerifier, }: {
3
+ state: string;
4
+ nonce: string;
5
+ codeVerifier: string;
6
+ }) => Promise<Credentials>;
@@ -0,0 +1,88 @@
1
+ import * as p from "@clack/prompts";
2
+ import { createServer } from "node:http";
3
+ import { oAuthClient } from "./client.js";
4
+ import { LOOPBACK_HOST, LOOPBACK_PORT } from "./constants.js";
5
+ const createCallbackServer = ({ state, nonce, codeVerifier, onSuccess, onError, }) => createServer(async (req, res) => {
6
+ const url = req.url ?? "/";
7
+ if (!url.startsWith("/callback")) {
8
+ p.log.message(`Ignoring request to ${url}`);
9
+ res.writeHead(404).end();
10
+ return;
11
+ }
12
+ try {
13
+ const tokens = await oAuthClient.exchangeAuthorizationCode({
14
+ url: new URL(url, `http://${req.headers.host}`),
15
+ codeVerifier,
16
+ state,
17
+ nonce,
18
+ });
19
+ const sub = tokens.claims()?.sub;
20
+ if (!sub || !tokens.refresh_token) {
21
+ throw new Error("ID token did not contain sub");
22
+ }
23
+ const stored = {
24
+ access_token: tokens.access_token,
25
+ refresh_token: tokens.refresh_token,
26
+ expires_at: oAuthClient.getExpiresAt(tokens.expires_in ?? 0),
27
+ sub,
28
+ };
29
+ p.log.success("✅ Authentication successful");
30
+ res.writeHead(200, { "Content-Type": "text/html" });
31
+ res.end(html("Logged in", "You can close this window.", true));
32
+ onSuccess(stored);
33
+ }
34
+ catch (e) {
35
+ p.log.error(e instanceof Error ? e.message : String(e));
36
+ res.writeHead(500, { "Content-Type": "text/html" });
37
+ res.end(html("Login failed", "Token exchange error. Try again.", false));
38
+ onError(e instanceof Error ? e : new Error(String(e)));
39
+ }
40
+ });
41
+ export const listenToOAuthCallback = ({ state, nonce, codeVerifier, }) => {
42
+ return new Promise((resolve, reject) => {
43
+ const callbackServer = createCallbackServer({
44
+ state,
45
+ nonce,
46
+ codeVerifier,
47
+ onSuccess: (storedToken) => {
48
+ callbackServer.close();
49
+ resolve(storedToken);
50
+ },
51
+ onError: (err) => {
52
+ callbackServer.close();
53
+ reject(err);
54
+ },
55
+ });
56
+ callbackServer.listen(LOOPBACK_PORT, LOOPBACK_HOST);
57
+ });
58
+ };
59
+ function html(title, body, success) {
60
+ const bg = success ? "#ecfdf5" : "#fef2f2";
61
+ const border = success ? "#10b981" : "#ef4444";
62
+ const color = success ? "#065f46" : "#991b1b";
63
+ const logoSvg = `<svg width="120" height="24" viewBox="0 0 213 42" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18.139 41.4181H1.58758C0.877981 41.4181 0.302734 40.8443 0.302734 40.1347V16.4957C0.302734 15.3182 1.73285 14.7794 2.48612 15.6845C7.8891 22.1765 15.4029 32.6359 19.2489 39.5848C19.7114 40.4205 19.0941 41.4181 18.139 41.4181Z" fill="#0A0E1C"/><path d="M34.9934 41.4181H23.8233C23.3366 41.4181 22.8936 41.144 22.6686 40.7125C18.5795 32.8689 8.1012 17.5927 0.638233 9.39174C0.420845 9.15285 0.302734 8.84629 0.302734 8.5233V1.58783C0.302734 0.878225 0.876486 0.302979 1.58609 0.302979H6.87182C7.19145 0.302979 7.48677 0.406983 7.71702 0.628672C14.4657 7.1264 32.6261 34.0831 35.8013 40.2463C36.1263 40.8771 35.703 41.4181 34.9934 41.4181Z" fill="#0A0E1C"/><path d="M41.4179 22.479C41.4177 26.1486 41.4178 34.7435 41.4178 40.0835C41.4178 41.3801 39.7105 41.8673 39.0235 40.7677C32.9779 31.091 20.3757 11.3903 13.1298 2.51663C12.4214 1.64905 13.0384 0.302979 14.1585 0.302979H25.3523C25.7594 0.302979 26.1363 0.487723 26.3781 0.815243C28.4729 3.65265 38.6422 17.4716 41.2512 21.8598C41.3654 22.052 41.4179 22.2554 41.4179 22.479Z" fill="#0A0E1C"/><path d="M40.133 0.302979H31.6871C30.6461 0.302979 30.0373 1.47597 30.6363 2.32725L39.0823 14.3294C39.8043 15.3554 41.4179 14.8446 41.4179 13.59V1.58783C41.4179 0.878225 40.8426 0.302979 40.133 0.302979Z" fill="#0A0E1C"/><path d="M69.4252 40.871H61.9757L75.539 0.850139H84.1548L97.737 40.871H90.2875L87.0895 31.0026H72.6044L69.4252 40.871ZM74.4856 25.1792H85.2083L79.9974 9.05754H79.6964L74.4856 25.1792Z" fill="#0A0E1C"/><path d="M102.282 40.871V0.850139H109.261V34.7936H126.229V40.871H102.282Z" fill="#0A0E1C"/><path d="M131.757 40.871V0.850139H146.204C155.065 0.850139 159.786 6.45853 159.786 14.0992C159.786 21.7985 155.008 27.3483 146.11 27.3483H138.736V40.871H131.757ZM138.736 21.3882H145.17C150.362 21.3882 152.676 18.3593 152.676 14.0992C152.676 9.83919 150.362 6.90798 145.132 6.90798H138.736V21.3882Z" fill="#0A0E1C"/><path d="M172.298 0.850139V40.871H165.319V0.850139H172.298Z" fill="#0A0E1C"/><path d="M212.303 14.3533H205.267C204.458 9.56561 200.79 6.81027 196.106 6.81027C189.804 6.81027 185.364 11.8324 185.364 20.8606C185.364 30.045 189.842 34.9108 196.087 34.9108C200.696 34.9108 204.383 32.2727 205.267 27.5828L212.303 27.6219C211.231 35.2626 205.154 41.4181 195.993 41.4181C185.835 41.4181 178.348 33.7774 178.348 20.8606C178.348 7.92413 185.929 0.302979 195.993 0.302979C204.534 0.302979 211.118 5.46191 212.303 14.3533Z" fill="#0A0E1C"/></svg>`;
64
+ return `<!DOCTYPE html>
65
+ <html>
66
+ <head>
67
+ <meta charset="utf-8">
68
+ <meta name="viewport" content="width=device-width, initial-scale=1">
69
+ <title>${title}</title>
70
+ <style>
71
+ * { box-sizing: border-box; }
72
+ body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2rem; font-family: system-ui, -apple-system, sans-serif; background: #f8fafc; }
73
+ .logo { flex-shrink: 0; }
74
+ .alert { max-width: 360px; padding: 1.25rem 1.5rem; border-radius: 8px; border-left: 4px solid ${border}; background: ${bg}; color: ${color}; }
75
+ .alert h1 { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 600; }
76
+ .alert p { margin: 0; font-size: 0.9375rem; line-height: 1.5; opacity: 0.95; }
77
+ </style>
78
+ </head>
79
+ <body>
80
+ <div class="logo" aria-hidden="true">${logoSvg}</div>
81
+ <div class="alert">
82
+ <h1>${title}</h1>
83
+ <p>${body}</p>
84
+ </div>
85
+ </body>
86
+ </html>`;
87
+ }
88
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export type WhoamiInfo = {
2
+ method: "api_key";
3
+ team: {
4
+ id: string;
5
+ name: string;
6
+ };
7
+ } | {
8
+ method: "oauth";
9
+ email: string;
10
+ name: string;
11
+ } | null;
12
+ export declare function getWhoamiInfo(): Promise<{
13
+ method: string;
14
+ team: {
15
+ id: string;
16
+ name: string;
17
+ createdAt: Date;
18
+ hasStripeAccount: boolean;
19
+ hasActiveSubscription: boolean;
20
+ } | undefined;
21
+ email?: undefined;
22
+ name?: undefined;
23
+ } | {
24
+ method: string;
25
+ email: string | undefined;
26
+ name: string | undefined;
27
+ team?: undefined;
28
+ } | null>;
@@ -0,0 +1,35 @@
1
+ import { api } from "../../api.js";
2
+ import { oAuthClient } from "./oauth/client.js";
3
+ export async function getWhoamiInfo() {
4
+ if (process.env.ALPIC_API_KEY !== undefined) {
5
+ const team = await getApiKeyTeam();
6
+ return {
7
+ method: "api_key",
8
+ team,
9
+ };
10
+ }
11
+ const token = await oAuthClient.getValidAccessToken();
12
+ if (!token)
13
+ return null;
14
+ const userInfo = await fetchOAuthUserInfo(token);
15
+ if (!userInfo)
16
+ return null;
17
+ return {
18
+ method: "oauth",
19
+ email: userInfo.email,
20
+ name: userInfo.name,
21
+ };
22
+ }
23
+ async function fetchOAuthUserInfo(credentials) {
24
+ try {
25
+ return await oAuthClient.fetchUserInfo(credentials);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ async function getApiKeyTeam() {
32
+ const teams = await api.teams.list.v1();
33
+ return teams[0];
34
+ }
35
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../../src/lib/auth/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOhD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,IAAI;SACL,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,mBAAmB,EAAE,CAAC;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,OAAO;QACL,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,WAAwB;IACxD,IAAI,CAAC;QACH,OAAO,MAAM,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -1,10 +1,8 @@
1
1
  import type { RouterOutput } from "@alpic-ai/api";
2
2
  export declare function formatElapsed(ms: number): string;
3
- export declare function deployAndWait({ initial, startedAt, teamId, projectId, }: {
3
+ export declare function deployAndWait({ initial, startedAt, }: {
4
4
  initial: RouterOutput["deployments"]["get"]["v1"];
5
5
  startedAt: number;
6
- teamId: string;
7
- projectId: string;
8
6
  }): Promise<{
9
7
  deployment: {
10
8
  id: string;
@@ -16,6 +14,7 @@ export declare function deployAndWait({ initial, startedAt, teamId, projectId, }
16
14
  authorAvatarUrl: string | null;
17
15
  startedAt: Date | null;
18
16
  completedAt: Date | null;
17
+ deploymentPageUrl: string | null;
19
18
  };
20
19
  elapsedMs: number;
21
20
  }>;
@@ -1,31 +1,36 @@
1
1
  import * as p from "@clack/prompts";
2
2
  import chalk from "chalk";
3
- import { api, getFrontendBaseUrl } from "../api.js";
3
+ import { api } from "../api.js";
4
+ import { env } from "../env.js";
4
5
  export function formatElapsed(ms) {
5
6
  const totalSeconds = Math.floor(ms / 1000);
6
7
  const minutes = Math.floor(totalSeconds / 60);
7
8
  const seconds = totalSeconds % 60;
8
9
  return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
9
10
  }
10
- export async function deployAndWait({ initial, startedAt, teamId, projectId, }) {
11
+ export async function deployAndWait({ initial, startedAt, }) {
11
12
  const spinner = p.spinner();
13
+ let deployment = initial;
14
+ const deploymentPageUrl = deployment.deploymentPageUrl;
15
+ if (deploymentPageUrl) {
16
+ p.note(`🔗 ${deploymentPageUrl}`, "View deployment details:", { format: (line) => line });
17
+ }
12
18
  spinner.start("Deployment in progress");
13
- const deploymentPageUrl = `${getFrontendBaseUrl()}/team/${teamId}/project/${projectId}/deployments/${initial.id}`;
14
- p.note(deploymentPageUrl, "View deployment details:", { format: (line) => line });
19
+ const FIFTEEN_MINUTES_IN_MS = 15 * 60 * 1000; // 15 minutes
15
20
  const elapsedInterval = setInterval(() => {
16
21
  const elapsed = formatElapsed(Date.now() - startedAt);
17
22
  spinner.message(`Deployment in progress — ${elapsed}`);
18
23
  }, 1000);
19
- const timeoutMs = 15 * 60 * 1000; // 15 minutes
20
- let deployment = await api.deployments.get.v1({ deploymentId: initial.id });
21
24
  try {
22
25
  while (deployment.status === "ongoing") {
23
26
  const elapsedMs = Date.now() - startedAt;
24
- if (elapsedMs >= timeoutMs) {
27
+ if (elapsedMs >= FIFTEEN_MINUTES_IN_MS) {
25
28
  throw new Error(`Deployment aborted after 15 minutes. View status: ${deploymentPageUrl}`);
26
29
  }
27
30
  deployment = await api.deployments.get.v1({ deploymentId: deployment.id });
28
- await new Promise((resolve) => setTimeout(resolve, 10_000));
31
+ if (deployment.status === "ongoing") {
32
+ await new Promise((resolve) => setTimeout(resolve, 10_000));
33
+ }
29
34
  }
30
35
  return { deployment, elapsedMs: Date.now() - startedAt };
31
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../src/lib/deployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAClC,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,OAAO,EACP,SAAS,EACT,MAAM,EACN,SAAS,GAMV;IACC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAE5B,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAExC,MAAM,iBAAiB,GAAG,GAAG,kBAAkB,EAAE,SAAS,MAAM,YAAY,SAAS,gBAAgB,OAAO,CAAC,EAAE,EAAE,CAAC;IAClH,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,0BAA0B,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IAElF,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;QACvC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACtD,OAAO,CAAC,OAAO,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,EAAE,IAAI,CAAC,CAAC;IAET,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IAC/C,IAAI,UAAU,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACzC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,qDAAqD,iBAAiB,EAAE,CAAC,CAAC;YAC5F,CAAC;YACD,UAAU,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3E,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;IAC3D,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,GACX,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,aAAa,CAAC,eAAe,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../src/lib/deployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAClC,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,OAAO,EACP,SAAS,GAIV;IACC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAE5B,IAAI,UAAU,GAAG,OAAO,CAAC;IACzB,MAAM,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC;IACvD,IAAI,iBAAiB,EAAE,CAAC;QACtB,CAAC,CAAC,IAAI,CAAC,MAAM,iBAAiB,EAAE,EAAE,0BAA0B,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IAC3D,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;QACvC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QACtD,OAAO,CAAC,OAAO,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC,EAAE,IAAI,CAAC,CAAC;IACT,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACzC,IAAI,SAAS,IAAI,qBAAqB,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,qDAAqD,iBAAiB,EAAE,CAAC,CAAC;YAC5F,CAAC;YACD,UAAU,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3E,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACpC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;IAC3D,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,GACX,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,aAAa,CAAC,eAAe,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
package/dist/lib/git.js CHANGED
@@ -64,9 +64,8 @@ export async function confirmLinkAnotherIfAlreadyConnected(project) {
64
64
  return true;
65
65
  }
66
66
  export async function selectRemoteSourceRepository(remotes) {
67
- if (remotes.length === 1) {
68
- p.log.info(`Using remote source repository "${remotes[0].sourceRepository}" (${remotes[0].name}).`);
69
- return remotes[0].sourceRepository;
67
+ if (remotes.length === 0) {
68
+ return null;
70
69
  }
71
70
  const selected = await p.select({
72
71
  message: chalk.bold("Choose the remote source to connect"),
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export interface Credentials {
2
+ access_token: string;
3
+ refresh_token: string;
4
+ expires_at: number;
5
+ sub: string;
6
+ }
7
+ export interface Config {
8
+ machineId: string;
9
+ telemetry: {
10
+ enabled: boolean;
11
+ };
12
+ }
13
+ export declare class GlobalStore {
14
+ private readonly configDir;
15
+ constructor(configDir?: string);
16
+ getCredentials(): Credentials | null;
17
+ saveCredentials(credentials: Credentials): void;
18
+ clearCredentials(): void;
19
+ getConfig(): Config;
20
+ saveConfig(config: Config): void;
21
+ clearConfig(): void;
22
+ private getCredentialsFilePath;
23
+ private getConfigFilePath;
24
+ private parseJsonFile;
25
+ private saveJsonFile;
26
+ private clear;
27
+ }
28
+ export declare const globalStore: GlobalStore;
@@ -0,0 +1,75 @@
1
+ import crypto from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import XDGAppPaths from "xdg-app-paths";
5
+ export class GlobalStore {
6
+ configDir;
7
+ constructor(configDir) {
8
+ this.configDir = configDir ?? XDGAppPaths({ name: "alpic" }).config();
9
+ }
10
+ getCredentials() {
11
+ const token = this.parseJsonFile(this.getCredentialsFilePath());
12
+ if (!token) {
13
+ return null;
14
+ }
15
+ return token;
16
+ }
17
+ saveCredentials(credentials) {
18
+ this.saveJsonFile(this.getCredentialsFilePath(), credentials);
19
+ }
20
+ clearCredentials() {
21
+ this.clear(this.getCredentialsFilePath());
22
+ }
23
+ getConfig() {
24
+ const existing = this.parseJsonFile(this.getConfigFilePath());
25
+ if (existing?.machineId && existing?.telemetry !== undefined) {
26
+ return existing;
27
+ }
28
+ const config = {
29
+ machineId: existing?.machineId ?? crypto.randomUUID(),
30
+ telemetry: {
31
+ enabled: existing?.telemetry?.enabled ?? true,
32
+ },
33
+ };
34
+ this.saveConfig(config);
35
+ return config;
36
+ }
37
+ saveConfig(config) {
38
+ this.saveJsonFile(this.getConfigFilePath(), config);
39
+ }
40
+ clearConfig() {
41
+ this.clear(this.getConfigFilePath());
42
+ }
43
+ getCredentialsFilePath() {
44
+ return join(this.configDir, "credentials.json");
45
+ }
46
+ getConfigFilePath() {
47
+ return join(this.configDir, "config.json");
48
+ }
49
+ parseJsonFile(filePath) {
50
+ if (!existsSync(filePath)) {
51
+ return null;
52
+ }
53
+ try {
54
+ return JSON.parse(readFileSync(filePath, "utf-8"));
55
+ }
56
+ catch {
57
+ this.clear(filePath);
58
+ return null;
59
+ }
60
+ }
61
+ saveJsonFile(filePath, data) {
62
+ mkdirSync(this.configDir, { recursive: true });
63
+ writeFileSync(filePath, JSON.stringify(data, null, 2), {
64
+ encoding: "utf-8",
65
+ mode: 0o600,
66
+ });
67
+ }
68
+ clear(filePath) {
69
+ if (existsSync(filePath)) {
70
+ unlinkSync(filePath);
71
+ }
72
+ }
73
+ }
74
+ export const globalStore = new GlobalStore();
75
+ //# sourceMappingURL=global-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-store.js","sourceRoot":"","sources":["../../src/lib/global-store.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import ci from "ci-info";
2
2
  import crypto from "node:crypto";
3
3
  import posthog from "../posthog.js";
4
- import { getGlobalConfig, saveGlobalConfig } from "./global-config.js";
4
+ import { globalStore } from "./global-store.js";
5
5
  const ENV_TELEMETRY_DISABLED = "ALPIC_TELEMETRY_DISABLED";
6
6
  const ENV_TELEMETRY_DEBUG = "ALPIC_TELEMETRY_DEBUG";
7
7
  const ENV_DO_NOT_TRACK = "DO_NOT_TRACK";
@@ -15,22 +15,22 @@ export function isEnabled() {
15
15
  if (ci.isCI) {
16
16
  return true;
17
17
  }
18
- const config = getGlobalConfig();
18
+ const config = globalStore.getConfig();
19
19
  return config.telemetry.enabled;
20
20
  }
21
21
  export function isDebugMode() {
22
22
  return process.env[ENV_TELEMETRY_DEBUG] === "1" || process.env[ENV_TELEMETRY_DEBUG]?.toLowerCase() === "true";
23
23
  }
24
24
  export function setEnabled(enabled) {
25
- const config = getGlobalConfig();
25
+ const config = globalStore.getConfig();
26
26
  config.telemetry.enabled = enabled;
27
- saveGlobalConfig(config);
27
+ globalStore.saveConfig(config);
28
28
  }
29
29
  export function getMachineId() {
30
30
  if (ci.isCI) {
31
31
  return ci.name ?? "unknown-ci";
32
32
  }
33
- return getGlobalConfig().machineId;
33
+ return globalStore.getConfig().machineId;
34
34
  }
35
35
  const hook = async ({ id: command, config: { version }, error, }) => {
36
36
  if (!isEnabled()) {
@@ -58,7 +58,7 @@ const hook = async ({ id: command, config: { version }, error, }) => {
58
58
  properties: event,
59
59
  });
60
60
  }
61
- catch (e) {
61
+ catch {
62
62
  // Silently ignore telemetry errors - never block CLI operation
63
63
  }
64
64
  };