@alpic-ai/sdk 0.0.0-dev.g00aa430
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.
- package/dist/api/auth-scope.d.ts +2 -0
- package/dist/api/auth-scope.js +7 -0
- package/dist/api/auth-scope.js.map +1 -0
- package/dist/api/client.d.ts +11 -0
- package/dist/api/client.js +25 -0
- package/dist/api/client.js.map +1 -0
- package/dist/auth/constants.d.ts +2 -0
- package/dist/auth/constants.js +3 -0
- package/dist/auth/constants.js.map +1 -0
- package/dist/auth/index.d.ts +25 -0
- package/dist/auth/index.js +45 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/login.d.ts +7 -0
- package/dist/auth/login.js +21 -0
- package/dist/auth/login.js.map +1 -0
- package/dist/auth/oauth-client.d.ts +28 -0
- package/dist/auth/oauth-client.js +116 -0
- package/dist/auth/oauth-client.js.map +1 -0
- package/dist/auth/server/assets/alpic-mountain.png +0 -0
- package/dist/auth/server/assets/authorize.html +234 -0
- package/dist/auth/server/assets/callback.html +88 -0
- package/dist/auth/server/index.d.ts +14 -0
- package/dist/auth/server/index.js +128 -0
- package/dist/auth/server/index.js.map +1 -0
- package/dist/auth/store.d.ts +30 -0
- package/dist/auth/store.js +76 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.js +28 -0
- package/dist/client.js.map +1 -0
- package/dist/deploy/archive.d.ts +8 -0
- package/dist/deploy/archive.js +61 -0
- package/dist/deploy/archive.js.map +1 -0
- package/dist/deploy/deployments.d.ts +43 -0
- package/dist/deploy/deployments.js +89 -0
- package/dist/deploy/deployments.js.map +1 -0
- package/dist/deploy/poll.d.ts +2 -0
- package/dist/deploy/poll.js +10 -0
- package/dist/deploy/poll.js.map +1 -0
- package/dist/deploy/upload.d.ts +1 -0
- package/dist/deploy/upload.js +13 -0
- package/dist/deploy/upload.js.map +1 -0
- package/dist/env.d.ts +4 -0
- package/dist/env.js +10 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/emitter.d.ts +7 -0
- package/dist/lib/emitter.js +29 -0
- package/dist/lib/emitter.js.map +1 -0
- package/dist/project/config.d.ts +10 -0
- package/dist/project/config.js +29 -0
- package/dist/project/config.js.map +1 -0
- package/dist/project/detect-runtime.d.ts +2 -0
- package/dist/project/detect-runtime.js +25 -0
- package/dist/project/detect-runtime.js.map +1 -0
- package/dist/project/projects.d.ts +21 -0
- package/dist/project/projects.js +52 -0
- package/dist/project/projects.js.map +1 -0
- package/dist/tunnel/tunnel.d.ts +43 -0
- package/dist/tunnel/tunnel.js +127 -0
- package/dist/tunnel/tunnel.js.map +1 -0
- package/dist/vendor/pipenet.d.ts +1 -0
- package/dist/vendor/pipenet.js +16883 -0
- package/dist/vendor/pipenet.js.LEGAL.txt +17 -0
- package/dist/vendor/pipenet.js.map +7 -0
- package/dist/whoami.d.ts +15 -0
- package/dist/whoami.js +12 -0
- package/dist/whoami.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Credentials } from "../store.js";
|
|
2
|
+
type Logger = {
|
|
3
|
+
log: (msg: string) => void;
|
|
4
|
+
error: (msg: string) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare const getLoginPageUrl: () => string;
|
|
7
|
+
export declare const listenToOAuthCallback: ({ state, nonce, codeVerifier, authorizeUrl, logger, }: {
|
|
8
|
+
state: string;
|
|
9
|
+
nonce: string;
|
|
10
|
+
codeVerifier: string;
|
|
11
|
+
authorizeUrl?: string;
|
|
12
|
+
logger?: Logger;
|
|
13
|
+
}) => Promise<Credentials>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { LOOPBACK_HOST, LOOPBACK_PORT } from "../constants.js";
|
|
6
|
+
import { getOAuthClient } from "../oauth-client.js";
|
|
7
|
+
const noopLogger = { log: () => { }, error: () => { } };
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const ASSETS_DIR = path.join(__dirname, "assets");
|
|
10
|
+
const createCallbackServer = ({ state, nonce, codeVerifier, authorizeUrl, onSuccess, onError, logger = noopLogger, }) => createServer(async (req, res) => {
|
|
11
|
+
const url = req.url ?? "/";
|
|
12
|
+
const pathname = url.split("?")[0] ?? "/";
|
|
13
|
+
if (pathname === "/login") {
|
|
14
|
+
try {
|
|
15
|
+
const htmlPath = path.join(ASSETS_DIR, "authorize.html");
|
|
16
|
+
let html = await readFile(htmlPath, "utf-8");
|
|
17
|
+
if (authorizeUrl) {
|
|
18
|
+
html = html.replace(/%AUTH_BASE_URL%/g, authorizeUrl);
|
|
19
|
+
}
|
|
20
|
+
res.writeHead(200, {
|
|
21
|
+
"Content-Type": "text/html",
|
|
22
|
+
Connection: "close",
|
|
23
|
+
});
|
|
24
|
+
res.end(html);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
29
|
+
logger.error(msg);
|
|
30
|
+
res.writeHead(500).end();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (pathname === "/assets/alpic-mountain.png") {
|
|
35
|
+
const filePath = path.join(ASSETS_DIR, "alpic-mountain.png");
|
|
36
|
+
const content = await readFile(filePath);
|
|
37
|
+
res.writeHead(200, { "Content-Type": "image/png", Connection: "close" });
|
|
38
|
+
res.end(content);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!url.startsWith("/callback")) {
|
|
42
|
+
res.writeHead(404).end();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const tokens = await getOAuthClient().exchangeAuthorizationCode({
|
|
47
|
+
url: new URL(url, `http://${req.headers.host}`),
|
|
48
|
+
codeVerifier,
|
|
49
|
+
state,
|
|
50
|
+
nonce,
|
|
51
|
+
});
|
|
52
|
+
const sub = tokens.claims()?.sub;
|
|
53
|
+
if (!sub || !tokens.refresh_token) {
|
|
54
|
+
throw new Error("ID token did not contain sub");
|
|
55
|
+
}
|
|
56
|
+
const stored = {
|
|
57
|
+
access_token: tokens.access_token,
|
|
58
|
+
refresh_token: tokens.refresh_token,
|
|
59
|
+
expires_at: getOAuthClient().getExpiresAt(tokens.expires_in),
|
|
60
|
+
sub,
|
|
61
|
+
};
|
|
62
|
+
const msg = "Authentication successful";
|
|
63
|
+
logger.log(msg);
|
|
64
|
+
const successHtmlPath = path.join(ASSETS_DIR, "callback.html");
|
|
65
|
+
let html = await readFile(successHtmlPath, "utf-8");
|
|
66
|
+
html = html
|
|
67
|
+
.replace(/__CALLBACK_STATUS__/g, "success")
|
|
68
|
+
.replace(/__CALLBACK_TITLE__/g, "You are logged in")
|
|
69
|
+
.replace(/__CALLBACK_SUB__/g, "You can close this page.");
|
|
70
|
+
res.writeHead(200, { "Content-Type": "text/html", Connection: "close" });
|
|
71
|
+
res.end(html);
|
|
72
|
+
onSuccess(stored);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
76
|
+
logger.error(msg);
|
|
77
|
+
const callbackHtmlPath = path.join(ASSETS_DIR, "callback.html");
|
|
78
|
+
let html = await readFile(callbackHtmlPath, "utf-8");
|
|
79
|
+
html = html
|
|
80
|
+
.replace(/__CALLBACK_STATUS__/g, "error")
|
|
81
|
+
.replace(/__CALLBACK_TITLE__/g, "An error occurred. You can close this page.")
|
|
82
|
+
.replace(/__CALLBACK_SUB__/g, "");
|
|
83
|
+
res.writeHead(500, { "Content-Type": "text/html", Connection: "close" });
|
|
84
|
+
res.end(html);
|
|
85
|
+
onError(e instanceof Error ? e : new Error(String(e)));
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
export const getLoginPageUrl = () => `http://${LOOPBACK_HOST}:${LOOPBACK_PORT}/login`;
|
|
89
|
+
const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
90
|
+
export const listenToOAuthCallback = ({ state, nonce, codeVerifier, authorizeUrl, logger = noopLogger, }) => {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
let timeoutHandle;
|
|
93
|
+
const callbackServer = createCallbackServer({
|
|
94
|
+
state,
|
|
95
|
+
nonce,
|
|
96
|
+
codeVerifier,
|
|
97
|
+
authorizeUrl,
|
|
98
|
+
logger,
|
|
99
|
+
onSuccess: (storedToken) => {
|
|
100
|
+
clearTimeout(timeoutHandle);
|
|
101
|
+
callbackServer.close();
|
|
102
|
+
resolve(storedToken);
|
|
103
|
+
},
|
|
104
|
+
onError: (err) => {
|
|
105
|
+
clearTimeout(timeoutHandle);
|
|
106
|
+
callbackServer.close();
|
|
107
|
+
reject(err);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
callbackServer.on("error", (err) => {
|
|
111
|
+
clearTimeout(timeoutHandle);
|
|
112
|
+
callbackServer.close();
|
|
113
|
+
if (err.code === "EADDRINUSE") {
|
|
114
|
+
reject(new Error(`Port ${LOOPBACK_PORT} is already in use. Another login may be in progress. Please try again.`));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
reject(err);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
timeoutHandle = setTimeout(() => {
|
|
121
|
+
callbackServer.close();
|
|
122
|
+
reject(new Error("Login timed out after 5 minutes. Please try again."));
|
|
123
|
+
}, LOGIN_TIMEOUT_MS);
|
|
124
|
+
timeoutHandle.unref();
|
|
125
|
+
callbackServer.listen(LOOPBACK_PORT, LOOPBACK_HOST);
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/server/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
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(opts?: {
|
|
16
|
+
configDir?: string;
|
|
17
|
+
});
|
|
18
|
+
getCredentials(): Credentials | null;
|
|
19
|
+
saveCredentials(credentials: Credentials): void;
|
|
20
|
+
clearCredentials(): void;
|
|
21
|
+
getConfig(): Config;
|
|
22
|
+
saveConfig(config: Config): void;
|
|
23
|
+
clearConfig(): void;
|
|
24
|
+
private getCredentialsFilePath;
|
|
25
|
+
private getConfigFilePath;
|
|
26
|
+
private parseJsonFile;
|
|
27
|
+
private saveJsonFile;
|
|
28
|
+
private clear;
|
|
29
|
+
}
|
|
30
|
+
export declare const globalStore: GlobalStore;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import envPaths from "env-paths";
|
|
5
|
+
export class GlobalStore {
|
|
6
|
+
configDir;
|
|
7
|
+
constructor(opts) {
|
|
8
|
+
const configDirOverride = opts?.configDir ?? process.env.ALPIC_GLOBAL_CONFIG_DIR;
|
|
9
|
+
this.configDir = configDirOverride ?? envPaths("alpic", { suffix: "" }).config;
|
|
10
|
+
}
|
|
11
|
+
getCredentials() {
|
|
12
|
+
const token = this.parseJsonFile(this.getCredentialsFilePath());
|
|
13
|
+
if (!token) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return token;
|
|
17
|
+
}
|
|
18
|
+
saveCredentials(credentials) {
|
|
19
|
+
this.saveJsonFile(this.getCredentialsFilePath(), credentials);
|
|
20
|
+
}
|
|
21
|
+
clearCredentials() {
|
|
22
|
+
this.clear(this.getCredentialsFilePath());
|
|
23
|
+
}
|
|
24
|
+
getConfig() {
|
|
25
|
+
const existing = this.parseJsonFile(this.getConfigFilePath());
|
|
26
|
+
if (existing?.machineId && existing?.telemetry !== undefined) {
|
|
27
|
+
return existing;
|
|
28
|
+
}
|
|
29
|
+
const config = {
|
|
30
|
+
machineId: existing?.machineId ?? crypto.randomUUID(),
|
|
31
|
+
telemetry: {
|
|
32
|
+
enabled: existing?.telemetry?.enabled ?? true,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
this.saveConfig(config);
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
38
|
+
saveConfig(config) {
|
|
39
|
+
this.saveJsonFile(this.getConfigFilePath(), config);
|
|
40
|
+
}
|
|
41
|
+
clearConfig() {
|
|
42
|
+
this.clear(this.getConfigFilePath());
|
|
43
|
+
}
|
|
44
|
+
getCredentialsFilePath() {
|
|
45
|
+
return join(this.configDir, "credentials.json");
|
|
46
|
+
}
|
|
47
|
+
getConfigFilePath() {
|
|
48
|
+
return join(this.configDir, "config.json");
|
|
49
|
+
}
|
|
50
|
+
parseJsonFile(filePath) {
|
|
51
|
+
if (!existsSync(filePath)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
this.clear(filePath);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
saveJsonFile(filePath, data) {
|
|
63
|
+
mkdirSync(this.configDir, { recursive: true });
|
|
64
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2), {
|
|
65
|
+
encoding: "utf-8",
|
|
66
|
+
mode: 0o600,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
clear(filePath) {
|
|
70
|
+
if (existsSync(filePath)) {
|
|
71
|
+
unlinkSync(filePath);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export const globalStore = new GlobalStore();
|
|
76
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type AlpicApi } from "./api/client.js";
|
|
2
|
+
import { AlpicAuth } from "./auth/index.js";
|
|
3
|
+
import { Deployments } from "./deploy/deployments.js";
|
|
4
|
+
import { Projects } from "./project/projects.js";
|
|
5
|
+
import { Tunnel } from "./tunnel/tunnel.js";
|
|
6
|
+
import { type WhoamiInfo } from "./whoami.js";
|
|
7
|
+
export declare class Alpic {
|
|
8
|
+
readonly auth: AlpicAuth;
|
|
9
|
+
readonly api: AlpicApi;
|
|
10
|
+
readonly tunnel: Tunnel;
|
|
11
|
+
readonly deployments: Deployments;
|
|
12
|
+
readonly projects: Projects;
|
|
13
|
+
constructor();
|
|
14
|
+
whoami(): Promise<WhoamiInfo>;
|
|
15
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createApiClient } from "./api/client.js";
|
|
2
|
+
import { AlpicAuth } from "./auth/index.js";
|
|
3
|
+
import { Deployments } from "./deploy/deployments.js";
|
|
4
|
+
import { env } from "./env.js";
|
|
5
|
+
import { Projects } from "./project/projects.js";
|
|
6
|
+
import { Tunnel } from "./tunnel/tunnel.js";
|
|
7
|
+
import { whoami } from "./whoami.js";
|
|
8
|
+
export class Alpic {
|
|
9
|
+
auth;
|
|
10
|
+
api;
|
|
11
|
+
tunnel;
|
|
12
|
+
deployments;
|
|
13
|
+
projects;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.auth = new AlpicAuth();
|
|
16
|
+
this.api = createApiClient({
|
|
17
|
+
apiBaseUrl: env.ALPIC_API_BASE_URL,
|
|
18
|
+
auth: this.auth,
|
|
19
|
+
});
|
|
20
|
+
this.tunnel = new Tunnel({ api: this.api });
|
|
21
|
+
this.deployments = new Deployments({ api: this.api });
|
|
22
|
+
this.projects = new Projects({ api: this.api });
|
|
23
|
+
}
|
|
24
|
+
whoami() {
|
|
25
|
+
return whoami(this.auth, this.api);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAmB,MAAM,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,OAAO,KAAK;IACP,IAAI,CAAY;IAChB,GAAG,CAAW;IACd,MAAM,CAAS;IACf,WAAW,CAAc;IACzB,QAAQ,CAAW;IAE5B;QACE,IAAI,CAAC,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC;YACzB,UAAU,EAAE,GAAG,CAAC,kBAAkB;YAClC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,MAAM;QACJ,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function isExcluded(file: string): boolean;
|
|
2
|
+
export declare function ensureGitAvailable(): void;
|
|
3
|
+
export declare function getGitFiles(): string[];
|
|
4
|
+
export declare function getFilesToPack(): string[];
|
|
5
|
+
export declare function createTarArchive(files: string[]): Promise<{
|
|
6
|
+
tmpDir: string;
|
|
7
|
+
archivePath: string;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { create as tarCreate } from "tar";
|
|
6
|
+
const GIT_FILES_MAX_BUFFER = 10 * 1024 * 1024;
|
|
7
|
+
const EXCLUDED_DIRS = new Set(["node_modules", ".venv", "venv", "__pycache__", ".git", "dist"]);
|
|
8
|
+
export function isExcluded(file) {
|
|
9
|
+
return file.split("/").some((segment) => EXCLUDED_DIRS.has(segment));
|
|
10
|
+
}
|
|
11
|
+
function isGitRepository() {
|
|
12
|
+
return existsSync(join(process.cwd(), ".git"));
|
|
13
|
+
}
|
|
14
|
+
export function ensureGitAvailable() {
|
|
15
|
+
try {
|
|
16
|
+
execSync("git --version", { stdio: "ignore" });
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error("Git is required to deploy. Please install git and ensure it is available in your PATH.");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function getGitFiles() {
|
|
23
|
+
const output = execSync("git ls-files -z --cached --others --exclude-standard -- .", {
|
|
24
|
+
encoding: "utf8",
|
|
25
|
+
maxBuffer: GIT_FILES_MAX_BUFFER,
|
|
26
|
+
});
|
|
27
|
+
const files = output
|
|
28
|
+
.split("\0")
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.filter((file) => !isExcluded(file));
|
|
31
|
+
if (files.length === 0) {
|
|
32
|
+
throw new Error("No tracked or untracked files found. Ensure you are in a git repository with files to deploy.");
|
|
33
|
+
}
|
|
34
|
+
return files;
|
|
35
|
+
}
|
|
36
|
+
export function getFilesToPack() {
|
|
37
|
+
if (isGitRepository()) {
|
|
38
|
+
return getGitFiles();
|
|
39
|
+
}
|
|
40
|
+
ensureGitAvailable();
|
|
41
|
+
execSync("git init", { stdio: "ignore" });
|
|
42
|
+
try {
|
|
43
|
+
return getGitFiles();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
rmSync(join(process.cwd(), ".git"), { recursive: true, force: true });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function createTarArchive(files) {
|
|
50
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "alpic-deploy-"));
|
|
51
|
+
const archivePath = join(tmpDir, "source.tar.gz");
|
|
52
|
+
try {
|
|
53
|
+
await tarCreate({ gzip: true, file: archivePath }, files);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
return { tmpDir, archivePath };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/deploy/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RouterOutput } from "@alpic-ai/api";
|
|
2
|
+
import type { AlpicApi } from "../api/client.js";
|
|
3
|
+
export type Deployment = RouterOutput["deployments"]["get"]["v1"];
|
|
4
|
+
export type DeploymentStatus = Deployment["status"];
|
|
5
|
+
export type DeployOptions = {
|
|
6
|
+
environmentId: string;
|
|
7
|
+
teamId: string;
|
|
8
|
+
onProgress?: (event: DeployEvent) => void;
|
|
9
|
+
};
|
|
10
|
+
export type DeployResult = {
|
|
11
|
+
deploymentId: string;
|
|
12
|
+
status: DeploymentStatus;
|
|
13
|
+
mcpServerUrl: string;
|
|
14
|
+
domains: string[];
|
|
15
|
+
deploymentPageUrl: string | null;
|
|
16
|
+
elapsedMs: number;
|
|
17
|
+
};
|
|
18
|
+
export type DeployEvent = {
|
|
19
|
+
type: "collecting";
|
|
20
|
+
} | {
|
|
21
|
+
type: "collected";
|
|
22
|
+
fileCount: number;
|
|
23
|
+
} | {
|
|
24
|
+
type: "uploading";
|
|
25
|
+
} | {
|
|
26
|
+
type: "triggering";
|
|
27
|
+
} | {
|
|
28
|
+
type: "deploying";
|
|
29
|
+
status: DeploymentStatus;
|
|
30
|
+
elapsedMs: number;
|
|
31
|
+
deploymentPageUrl: string | null;
|
|
32
|
+
};
|
|
33
|
+
export type DeploymentsDeps = {
|
|
34
|
+
api: AlpicApi;
|
|
35
|
+
};
|
|
36
|
+
export declare class Deployments {
|
|
37
|
+
private readonly api;
|
|
38
|
+
constructor(deps: DeploymentsDeps);
|
|
39
|
+
getLatestForEnvironment(environmentId: string): Promise<Deployment>;
|
|
40
|
+
watch(deploymentId: string): Promise<Deployment>;
|
|
41
|
+
private pollUntilFinal;
|
|
42
|
+
deploy({ environmentId, teamId, onProgress }: DeployOptions): Promise<DeployResult>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { createTarArchive, getFilesToPack } from "./archive.js";
|
|
3
|
+
import { pollIntervalMs, sleep } from "./poll.js";
|
|
4
|
+
import { uploadToPresignedUrl } from "./upload.js";
|
|
5
|
+
const FINAL_STATUSES = new Set(["deployed", "failed", "canceled"]);
|
|
6
|
+
const TIMEOUT_MS = 15 * 60 * 1000;
|
|
7
|
+
const DEPLOY_POLL_MS = 10_000;
|
|
8
|
+
const WATCH_POLL_MS = 3_000;
|
|
9
|
+
export class Deployments {
|
|
10
|
+
api;
|
|
11
|
+
constructor(deps) {
|
|
12
|
+
this.api = deps.api;
|
|
13
|
+
}
|
|
14
|
+
async getLatestForEnvironment(environmentId) {
|
|
15
|
+
const environment = await this.api.environments.get.v1({ environmentId });
|
|
16
|
+
const deployments = await this.api.deployments.list.v1({
|
|
17
|
+
projectId: environment.projectId,
|
|
18
|
+
environmentId,
|
|
19
|
+
});
|
|
20
|
+
const latest = deployments[0];
|
|
21
|
+
if (!latest) {
|
|
22
|
+
throw new Error(`No deployments found for environment ${environmentId}.`);
|
|
23
|
+
}
|
|
24
|
+
return latest;
|
|
25
|
+
}
|
|
26
|
+
watch(deploymentId) {
|
|
27
|
+
return this.pollUntilFinal(deploymentId, WATCH_POLL_MS);
|
|
28
|
+
}
|
|
29
|
+
async pollUntilFinal(deploymentId, intervalMs) {
|
|
30
|
+
const startedAt = Date.now();
|
|
31
|
+
let current = await this.api.deployments.get.v1({ deploymentId });
|
|
32
|
+
while (!FINAL_STATUSES.has(current.status)) {
|
|
33
|
+
if (Date.now() - startedAt >= TIMEOUT_MS) {
|
|
34
|
+
throw new Error("Deployment did not reach a final state within 15 minutes.");
|
|
35
|
+
}
|
|
36
|
+
await sleep(pollIntervalMs(intervalMs));
|
|
37
|
+
current = await this.api.deployments.get.v1({ deploymentId });
|
|
38
|
+
}
|
|
39
|
+
return current;
|
|
40
|
+
}
|
|
41
|
+
async deploy({ environmentId, teamId, onProgress }) {
|
|
42
|
+
const emit = onProgress ?? (() => { });
|
|
43
|
+
let tmpDir;
|
|
44
|
+
const startedAt = Date.now();
|
|
45
|
+
try {
|
|
46
|
+
emit({ type: "collecting" });
|
|
47
|
+
const files = getFilesToPack();
|
|
48
|
+
emit({ type: "collected", fileCount: files.length });
|
|
49
|
+
const archive = await createTarArchive(files);
|
|
50
|
+
tmpDir = archive.tmpDir;
|
|
51
|
+
const { uploadUrl, token } = await this.api.deployments.uploadArtifact.v1({ teamId });
|
|
52
|
+
emit({ type: "uploading" });
|
|
53
|
+
await uploadToPresignedUrl(uploadUrl, readFileSync(archive.archivePath));
|
|
54
|
+
emit({ type: "triggering" });
|
|
55
|
+
const initial = await this.api.environments.deploy.v1({ environmentId, token });
|
|
56
|
+
let deployment = initial;
|
|
57
|
+
const deploymentPageUrl = deployment.deploymentPageUrl ?? null;
|
|
58
|
+
const emitDeploying = () => emit({ type: "deploying", status: deployment.status, elapsedMs: Date.now() - startedAt, deploymentPageUrl });
|
|
59
|
+
emitDeploying();
|
|
60
|
+
while (deployment.status === "ongoing") {
|
|
61
|
+
if (Date.now() - startedAt >= TIMEOUT_MS) {
|
|
62
|
+
throw new Error(deploymentPageUrl
|
|
63
|
+
? `Deployment aborted after 15 minutes. View status: ${deploymentPageUrl}`
|
|
64
|
+
: "Deployment aborted after 15 minutes.");
|
|
65
|
+
}
|
|
66
|
+
deployment = await this.api.deployments.get.v1({ deploymentId: deployment.id });
|
|
67
|
+
emitDeploying();
|
|
68
|
+
if (deployment.status === "ongoing") {
|
|
69
|
+
await sleep(pollIntervalMs(DEPLOY_POLL_MS));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const environment = await this.api.environments.get.v1({ environmentId });
|
|
73
|
+
return {
|
|
74
|
+
deploymentId: deployment.id,
|
|
75
|
+
status: deployment.status,
|
|
76
|
+
mcpServerUrl: environment.mcpServerUrl,
|
|
77
|
+
domains: environment.domains,
|
|
78
|
+
deploymentPageUrl: deployment.deploymentPageUrl ?? null,
|
|
79
|
+
elapsedMs: Date.now() - startedAt,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
if (tmpDir) {
|
|
84
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=deployments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployments.js","sourceRoot":"","sources":["../../src/deploy/deployments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function pollIntervalMs(defaultMs) {
|
|
2
|
+
const override = process.env.ALPIC_POLL_INTERVAL_MS;
|
|
3
|
+
if (override !== undefined) {
|
|
4
|
+
const parsed = Number.parseInt(override, 10);
|
|
5
|
+
return Number.isNaN(parsed) ? defaultMs : parsed;
|
|
6
|
+
}
|
|
7
|
+
return defaultMs;
|
|
8
|
+
}
|
|
9
|
+
export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
//# sourceMappingURL=poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/deploy/poll.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uploadToPresignedUrl(uploadUrl: string, buffer: Buffer): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export async function uploadToPresignedUrl(uploadUrl, buffer) {
|
|
2
|
+
const res = await fetch(uploadUrl, {
|
|
3
|
+
method: "PUT",
|
|
4
|
+
headers: {
|
|
5
|
+
"Content-Type": "application/gzip",
|
|
6
|
+
},
|
|
7
|
+
body: new Uint8Array(buffer),
|
|
8
|
+
});
|
|
9
|
+
if (!res.ok) {
|
|
10
|
+
throw new Error(`Upload failed: ${res.status} ${res.statusText}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/deploy/upload.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAiB,EAAE,MAAc;IAC1E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACjC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
|
package/dist/env.d.ts
ADDED
package/dist/env.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createEnv } from "@t3-oss/env-core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export const env = createEnv({
|
|
4
|
+
server: {
|
|
5
|
+
ALPIC_API_BASE_URL: z.string().default("https://api.alpic.ai"),
|
|
6
|
+
ALPIC_COGNITO_CLIENT_ID: z.string().default("h9nqsttp8ddb40ddi1aoni91h"),
|
|
7
|
+
},
|
|
8
|
+
runtimeEnv: process.env,
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE;QACN,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC;QAC9D,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC;KACzE;IACD,UAAU,EAAE,OAAO,CAAC,GAAG;CACxB,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { AlpicApi } from "./api/client.js";
|
|
2
|
+
export type { AuthEvents, Credentials, LoginOptions } from "./auth/index.js";
|
|
3
|
+
export { AlpicAuth } from "./auth/index.js";
|
|
4
|
+
export { getOAuthClient } from "./auth/oauth-client.js";
|
|
5
|
+
export { GlobalStore, globalStore } from "./auth/store.js";
|
|
6
|
+
export { Alpic } from "./client.js";
|
|
7
|
+
export type { DeployEvent, Deployment, DeploymentStatus, DeployOptions, DeployResult } from "./deploy/deployments.js";
|
|
8
|
+
export type { ProjectConfig } from "./project/config.js";
|
|
9
|
+
export type { CreateLinkedProjectOptions, LinkedProjectConfig } from "./project/projects.js";
|
|
10
|
+
export type { OpenTunnelOptions, TunnelCloseInfo, TunnelHandle, TunnelRequest } from "./tunnel/tunnel.js";
|
|
11
|
+
export type { Team, WhoamiInfo } from "./whoami.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type Listener<T> = (payload: T) => void;
|
|
2
|
+
export declare class TypedEventEmitter<EventMap extends Record<string, unknown>> {
|
|
3
|
+
private readonly listeners;
|
|
4
|
+
on<K extends keyof EventMap>(event: K, listener: Listener<EventMap[K]>): void;
|
|
5
|
+
off<K extends keyof EventMap>(event: K, listener: Listener<EventMap[K]>): void;
|
|
6
|
+
emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
|
|
7
|
+
}
|