@alpic-ai/sdk 0.0.0-dev.gcababd8 → 0.0.0-dev.gcb14010
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/auth/index.d.ts +4 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/server/assets/authorize.html +1 -1
- package/dist/client.d.ts +6 -0
- package/dist/client.js +10 -0
- package/dist/client.js.map +1 -1
- 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 +45 -0
- package/dist/deploy/deployments.js +90 -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/index.d.ts +4 -0
- package/dist/lib/emitter.js +2 -6
- package/dist/lib/emitter.js.map +1 -1
- 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.js +3 -19
- package/dist/tunnel/tunnel.js.map +1 -1
- package/dist/vendor/pipenet.js +86 -97
- package/dist/vendor/pipenet.js.map +4 -4
- package/dist/whoami.d.ts +15 -0
- package/dist/whoami.js +12 -0
- package/dist/whoami.js.map +1 -0
- package/package.json +9 -8
package/dist/auth/index.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ export declare class AlpicAuth {
|
|
|
14
14
|
isAuthenticated(): Promise<boolean>;
|
|
15
15
|
getToken(): Promise<string | undefined>;
|
|
16
16
|
getUserAccessToken(): Promise<string | undefined>;
|
|
17
|
+
getUserInfo(): Promise<{
|
|
18
|
+
email: string | undefined;
|
|
19
|
+
name: string | undefined;
|
|
20
|
+
} | null>;
|
|
17
21
|
login(opts?: LoginOptions): Promise<{
|
|
18
22
|
sub: string;
|
|
19
23
|
}>;
|
package/dist/auth/index.js
CHANGED
|
@@ -22,6 +22,17 @@ export class AlpicAuth {
|
|
|
22
22
|
async getUserAccessToken() {
|
|
23
23
|
return (await getOAuthClient().getValidAccessToken())?.access_token;
|
|
24
24
|
}
|
|
25
|
+
async getUserInfo() {
|
|
26
|
+
const credentials = await getOAuthClient().getValidAccessToken();
|
|
27
|
+
if (!credentials) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const userInfo = await getOAuthClient().fetchUserInfo(credentials);
|
|
31
|
+
if (!userInfo) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return { email: userInfo.email, name: userInfo.name };
|
|
35
|
+
}
|
|
25
36
|
async login(opts) {
|
|
26
37
|
const result = await oauthLogin(opts);
|
|
27
38
|
this.events.emit("authenticated", { sub: result.sub });
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAqB,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAoB,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ3D,MAAM,OAAO,SAAS;IACH,MAAM,GAAG,IAAI,iBAAiB,EAAc,CAAC;IAE9D,EAAE,CAA6B,KAAQ,EAAE,QAA0C;QACjF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAA6B,KAAQ,EAAE,QAA0C;QAClF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,OAAO,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,SAAS,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE,YAAY,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,CAAC,MAAM,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE,YAAY,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAmB;QAC7B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,WAAW,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAqB,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAoB,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ3D,MAAM,OAAO,SAAS;IACH,MAAM,GAAG,IAAI,iBAAiB,EAAc,CAAC;IAE9D,EAAE,CAA6B,KAAQ,EAAE,QAA0C;QACjF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAA6B,KAAQ,EAAE,QAA0C;QAClF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,OAAO,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,SAAS,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE,YAAY,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,CAAC,MAAM,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC,EAAE,YAAY,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC,mBAAmB,EAAE,CAAC;QACjE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAmB;QAC7B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,WAAW,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
</div>
|
|
216
216
|
</div>
|
|
217
217
|
<script>
|
|
218
|
-
|
|
218
|
+
const loaderSvg =
|
|
219
219
|
'<svg class="spinner" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v4"/><path d="m16.2 7.8 2.9-2.9"/><path d="M18 12h4"/><path d="m16.2 16.2 2.9 2.9"/><path d="M12 18v4"/><path d="m4.9 19.1 2.9-2.9"/><path d="M2 12h4"/><path d="m4.9 4.9 2.9 2.9"/></svg>';
|
|
220
220
|
// biome-ignore lint/correctness/noUnusedVariables: The function is used within the buttons onclick handlers
|
|
221
221
|
function login(provider, btn) {
|
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { type AlpicApi } from "./api/client.js";
|
|
2
2
|
import { AlpicAuth } from "./auth/index.js";
|
|
3
|
+
import { Deployments } from "./deploy/deployments.js";
|
|
4
|
+
import { Projects } from "./project/projects.js";
|
|
3
5
|
import { Tunnel } from "./tunnel/tunnel.js";
|
|
6
|
+
import { type WhoamiInfo } from "./whoami.js";
|
|
4
7
|
export declare class Alpic {
|
|
5
8
|
readonly auth: AlpicAuth;
|
|
6
9
|
readonly api: AlpicApi;
|
|
7
10
|
readonly tunnel: Tunnel;
|
|
11
|
+
readonly deployments: Deployments;
|
|
12
|
+
readonly projects: Projects;
|
|
8
13
|
constructor();
|
|
14
|
+
whoami(): Promise<WhoamiInfo>;
|
|
9
15
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { createApiClient } from "./api/client.js";
|
|
2
2
|
import { AlpicAuth } from "./auth/index.js";
|
|
3
|
+
import { Deployments } from "./deploy/deployments.js";
|
|
3
4
|
import { env } from "./env.js";
|
|
5
|
+
import { Projects } from "./project/projects.js";
|
|
4
6
|
import { Tunnel } from "./tunnel/tunnel.js";
|
|
7
|
+
import { whoami } from "./whoami.js";
|
|
5
8
|
export class Alpic {
|
|
6
9
|
auth;
|
|
7
10
|
api;
|
|
8
11
|
tunnel;
|
|
12
|
+
deployments;
|
|
13
|
+
projects;
|
|
9
14
|
constructor() {
|
|
10
15
|
this.auth = new AlpicAuth();
|
|
11
16
|
this.api = createApiClient({
|
|
@@ -13,6 +18,11 @@ export class Alpic {
|
|
|
13
18
|
auth: this.auth,
|
|
14
19
|
});
|
|
15
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);
|
|
16
26
|
}
|
|
17
27
|
}
|
|
18
28
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +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,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
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,45 @@
|
|
|
1
|
+
import type { RouterInput, 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 DeploySettings = NonNullable<RouterInput["environments"]["deploy"]["v1"]["settings"]>;
|
|
6
|
+
export type DeployOptions = {
|
|
7
|
+
environmentId: string;
|
|
8
|
+
teamId: string;
|
|
9
|
+
detectSettings?: (files: string[]) => DeploySettings | Promise<DeploySettings>;
|
|
10
|
+
onProgress?: (event: DeployEvent) => void;
|
|
11
|
+
};
|
|
12
|
+
export type DeployResult = {
|
|
13
|
+
deploymentId: string;
|
|
14
|
+
status: DeploymentStatus;
|
|
15
|
+
mcpServerUrl: string;
|
|
16
|
+
domains: string[];
|
|
17
|
+
deploymentPageUrl: string | null;
|
|
18
|
+
elapsedMs: number;
|
|
19
|
+
};
|
|
20
|
+
export type DeployEvent = {
|
|
21
|
+
type: "collecting";
|
|
22
|
+
} | {
|
|
23
|
+
type: "collected";
|
|
24
|
+
fileCount: number;
|
|
25
|
+
} | {
|
|
26
|
+
type: "uploading";
|
|
27
|
+
} | {
|
|
28
|
+
type: "triggering";
|
|
29
|
+
} | {
|
|
30
|
+
type: "deploying";
|
|
31
|
+
status: DeploymentStatus;
|
|
32
|
+
elapsedMs: number;
|
|
33
|
+
deploymentPageUrl: string | null;
|
|
34
|
+
};
|
|
35
|
+
export type DeploymentsDeps = {
|
|
36
|
+
api: AlpicApi;
|
|
37
|
+
};
|
|
38
|
+
export declare class Deployments {
|
|
39
|
+
private readonly api;
|
|
40
|
+
constructor(deps: DeploymentsDeps);
|
|
41
|
+
getLatestForEnvironment(environmentId: string): Promise<Deployment>;
|
|
42
|
+
watch(deploymentId: string): Promise<Deployment>;
|
|
43
|
+
private pollUntilFinal;
|
|
44
|
+
deploy({ environmentId, teamId, detectSettings, onProgress }: DeployOptions): Promise<DeployResult>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
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, detectSettings, 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 settings = detectSettings ? await detectSettings(files) : undefined;
|
|
50
|
+
const archive = await createTarArchive(files);
|
|
51
|
+
tmpDir = archive.tmpDir;
|
|
52
|
+
const { uploadUrl, token } = await this.api.deployments.uploadArtifact.v1({ teamId });
|
|
53
|
+
emit({ type: "uploading" });
|
|
54
|
+
await uploadToPresignedUrl(uploadUrl, readFileSync(archive.archivePath));
|
|
55
|
+
emit({ type: "triggering" });
|
|
56
|
+
const initial = await this.api.environments.deploy.v1({ environmentId, token, settings });
|
|
57
|
+
let deployment = initial;
|
|
58
|
+
const deploymentPageUrl = deployment.deploymentPageUrl ?? null;
|
|
59
|
+
const emitDeploying = () => emit({ type: "deploying", status: deployment.status, elapsedMs: Date.now() - startedAt, deploymentPageUrl });
|
|
60
|
+
emitDeploying();
|
|
61
|
+
while (deployment.status === "ongoing") {
|
|
62
|
+
if (Date.now() - startedAt >= TIMEOUT_MS) {
|
|
63
|
+
throw new Error(deploymentPageUrl
|
|
64
|
+
? `Deployment aborted after 15 minutes. View status: ${deploymentPageUrl}`
|
|
65
|
+
: "Deployment aborted after 15 minutes.");
|
|
66
|
+
}
|
|
67
|
+
deployment = await this.api.deployments.get.v1({ deploymentId: deployment.id });
|
|
68
|
+
emitDeploying();
|
|
69
|
+
if (deployment.status === "ongoing") {
|
|
70
|
+
await sleep(pollIntervalMs(DEPLOY_POLL_MS));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const environment = await this.api.environments.get.v1({ environmentId });
|
|
74
|
+
return {
|
|
75
|
+
deploymentId: deployment.id,
|
|
76
|
+
status: deployment.status,
|
|
77
|
+
mcpServerUrl: environment.mcpServerUrl,
|
|
78
|
+
domains: environment.domains,
|
|
79
|
+
deploymentPageUrl: deployment.deploymentPageUrl ?? null,
|
|
80
|
+
elapsedMs: Date.now() - startedAt,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
if (tmpDir) {
|
|
85
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# 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/index.d.ts
CHANGED
|
@@ -4,4 +4,8 @@ export { AlpicAuth } from "./auth/index.js";
|
|
|
4
4
|
export { getOAuthClient } from "./auth/oauth-client.js";
|
|
5
5
|
export { GlobalStore, globalStore } from "./auth/store.js";
|
|
6
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";
|
|
7
10
|
export type { OpenTunnelOptions, TunnelCloseInfo, TunnelHandle, TunnelRequest } from "./tunnel/tunnel.js";
|
|
11
|
+
export type { Team, WhoamiInfo } from "./whoami.js";
|
package/dist/lib/emitter.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// never throws on an unlistened "error" event, and swallows listener errors so
|
|
3
|
-
// observability can never break the operation that emitted the event.
|
|
1
|
+
// Unlike node's EventEmitter, this never throws on an unlistened "error" event and swallows listener errors so observability can never break the operation that emitted the event.
|
|
4
2
|
export class TypedEventEmitter {
|
|
5
3
|
listeners = new Map();
|
|
6
4
|
on(event, listener) {
|
|
@@ -20,9 +18,7 @@ export class TypedEventEmitter {
|
|
|
20
18
|
try {
|
|
21
19
|
listener(payload);
|
|
22
20
|
}
|
|
23
|
-
catch {
|
|
24
|
-
// Listener errors must never break the emitting operation.
|
|
25
|
-
}
|
|
21
|
+
catch { }
|
|
26
22
|
}
|
|
27
23
|
}
|
|
28
24
|
}
|
package/dist/lib/emitter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/lib/emitter.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/lib/emitter.ts"],"names":[],"mappings":"AAEA,mLAAmL;AACnL,MAAM,OAAO,iBAAiB;IACX,SAAS,GAAG,IAAI,GAAG,EAA0C,CAAC;IAE/E,EAAE,CAA2B,KAAQ,EAAE,QAA+B;QACpE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,EAAqB,CAAC;QACtE,GAAG,CAAC,GAAG,CAAC,QAA6B,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAA2B,KAAQ,EAAE,QAA+B;QACrE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAA6B,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAA2B,KAAQ,EAAE,OAAoB;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QACD,KAAK,MAAM,QAAQ,IAAI,GAAG,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACF,QAAkC,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ProjectConfig = {
|
|
2
|
+
projectId: string;
|
|
3
|
+
teamId: string;
|
|
4
|
+
teamName?: string;
|
|
5
|
+
projectName: string;
|
|
6
|
+
environmentId?: string;
|
|
7
|
+
environmentName?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function loadProjectConfig(): ProjectConfig | null;
|
|
10
|
+
export declare function saveProjectConfig(projectConfig: ProjectConfig): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const getProjectJsonPath = () => join(process.cwd(), ".alpic", "project.json");
|
|
4
|
+
export function loadProjectConfig() {
|
|
5
|
+
const path = getProjectJsonPath();
|
|
6
|
+
if (!existsSync(path)) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
let raw;
|
|
10
|
+
try {
|
|
11
|
+
raw = JSON.parse(readFileSync(path, "utf8"));
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
throw new Error(`Failed to load project config: ${error.message}`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
projectId: raw.projectId,
|
|
18
|
+
teamId: raw.teamId,
|
|
19
|
+
teamName: raw.teamName,
|
|
20
|
+
projectName: raw.projectName ?? raw.projectId,
|
|
21
|
+
environmentId: raw.environmentId,
|
|
22
|
+
environmentName: raw.environmentName,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function saveProjectConfig(projectConfig) {
|
|
26
|
+
mkdirSync(join(process.cwd(), ".alpic"), { recursive: true });
|
|
27
|
+
writeFileSync(getProjectJsonPath(), JSON.stringify(projectConfig, null, 2));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/project/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAWjC,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AAE/E,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAmE,CAAC;IACxE,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAG1C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kCAAmC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,SAAS;QAC7C,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,eAAe,EAAE,GAAG,CAAC,eAAe;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,aAA4B;IAC5D,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,aAAa,CAAC,kBAAkB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
export function detectRuntime() {
|
|
3
|
+
const has = (file) => existsSync(file);
|
|
4
|
+
const read = (file) => {
|
|
5
|
+
try {
|
|
6
|
+
return readFileSync(file, "utf8");
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return "";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
if (has("pyproject.toml") || has("requirements.txt") || has("setup.py") || has(".python-version")) {
|
|
13
|
+
return "python3.13";
|
|
14
|
+
}
|
|
15
|
+
if (has("package.json")) {
|
|
16
|
+
const nvmrc = has(".nvmrc") ? (read(".nvmrc").trim().split(/\s/)[0] ?? "") : "";
|
|
17
|
+
const major = nvmrc.replace(/^v/i, "").match(/^(\d+)/)?.[1];
|
|
18
|
+
if (major === "22") {
|
|
19
|
+
return "node22";
|
|
20
|
+
}
|
|
21
|
+
return "node24";
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=detect-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-runtime.js","sourceRoot":"","sources":["../../src/project/detect-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGnD,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE;QACpC,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,kBAAkB,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClG,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RouterInput, Runtime } from "@alpic-ai/api";
|
|
2
|
+
import type { AlpicApi } from "../api/client.js";
|
|
3
|
+
import { type ProjectConfig } from "./config.js";
|
|
4
|
+
export type CreateLinkedProjectOptions = RouterInput["projects"]["create"]["v1"] & {
|
|
5
|
+
teamName?: string;
|
|
6
|
+
};
|
|
7
|
+
export type LinkedProjectConfig = ProjectConfig & {
|
|
8
|
+
environmentId: string;
|
|
9
|
+
};
|
|
10
|
+
export type ProjectsDeps = {
|
|
11
|
+
api: AlpicApi;
|
|
12
|
+
};
|
|
13
|
+
export declare class Projects {
|
|
14
|
+
private readonly api;
|
|
15
|
+
constructor(deps: ProjectsDeps);
|
|
16
|
+
loadConfig(): ProjectConfig | null;
|
|
17
|
+
saveConfig(projectConfig: ProjectConfig): void;
|
|
18
|
+
detectRuntime(): Runtime | null;
|
|
19
|
+
validateLink(projectConfig: ProjectConfig): Promise<ProjectConfig | null>;
|
|
20
|
+
createLinked({ teamName, ...input }: CreateLinkedProjectOptions): Promise<LinkedProjectConfig>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ORPCError } from "@orpc/client";
|
|
2
|
+
import { loadProjectConfig, saveProjectConfig } from "./config.js";
|
|
3
|
+
import { detectRuntime } from "./detect-runtime.js";
|
|
4
|
+
export class Projects {
|
|
5
|
+
api;
|
|
6
|
+
constructor(deps) {
|
|
7
|
+
this.api = deps.api;
|
|
8
|
+
}
|
|
9
|
+
loadConfig() {
|
|
10
|
+
return loadProjectConfig();
|
|
11
|
+
}
|
|
12
|
+
saveConfig(projectConfig) {
|
|
13
|
+
saveProjectConfig(projectConfig);
|
|
14
|
+
}
|
|
15
|
+
detectRuntime() {
|
|
16
|
+
return detectRuntime();
|
|
17
|
+
}
|
|
18
|
+
async validateLink(projectConfig) {
|
|
19
|
+
let project;
|
|
20
|
+
try {
|
|
21
|
+
project = await this.api.projects.get.v1({ projectId: projectConfig.projectId });
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error instanceof ORPCError && error.code === "NOT_FOUND") {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
if (projectConfig.environmentId && !project.environments?.some((env) => env.id === projectConfig.environmentId)) {
|
|
30
|
+
return { ...projectConfig, environmentId: undefined, environmentName: undefined };
|
|
31
|
+
}
|
|
32
|
+
return projectConfig;
|
|
33
|
+
}
|
|
34
|
+
async createLinked({ teamName, ...input }) {
|
|
35
|
+
const created = await this.api.projects.create.v1(input);
|
|
36
|
+
const productionEnv = created.productionEnvironment;
|
|
37
|
+
if (!productionEnv) {
|
|
38
|
+
throw new Error("Project was created but has no Production environment.");
|
|
39
|
+
}
|
|
40
|
+
const projectConfig = {
|
|
41
|
+
projectId: created.id,
|
|
42
|
+
teamId: created.teamId,
|
|
43
|
+
teamName,
|
|
44
|
+
projectName: created.name,
|
|
45
|
+
environmentId: productionEnv.id,
|
|
46
|
+
environmentName: productionEnv.name,
|
|
47
|
+
};
|
|
48
|
+
saveProjectConfig(projectConfig);
|
|
49
|
+
return projectConfig;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/project/projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAsB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYpD,MAAM,OAAO,QAAQ;IACF,GAAG,CAAW;IAE/B,YAAY,IAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IACtB,CAAC;IAED,UAAU;QACR,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,aAA4B;QACrC,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACnC,CAAC;IAED,aAAa;QACX,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,aAA4B;QAC7C,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC;QACnF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,IAAI,aAAa,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;YAChH,OAAO,EAAE,GAAG,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;QACpF,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAA8B;QACnE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,aAAa,GAAG,OAAO,CAAC,qBAAqB,CAAC;QACpD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,aAAa,GAAwB;YACzC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ;YACR,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,aAAa,EAAE,aAAa,CAAC,EAAE;YAC/B,eAAe,EAAE,aAAa,CAAC,IAAI;SACpC,CAAC;QACF,iBAAiB,CAAC,aAAa,CAAC,CAAC;QACjC,OAAO,aAAa,CAAC;IACvB,CAAC;CACF"}
|
package/dist/tunnel/tunnel.js
CHANGED
|
@@ -11,14 +11,10 @@ export class Tunnel {
|
|
|
11
11
|
this.deps = deps;
|
|
12
12
|
}
|
|
13
13
|
async open(opts) {
|
|
14
|
-
//
|
|
15
|
-
// `alpic` command, the skybridge dev server) don't pay its ~500KB load
|
|
16
|
-
// cost at startup — only when a tunnel is actually opened.
|
|
14
|
+
// Loaded lazily so non-tunnel consumers don't pay the patched pipenet bundle's ~500KB load cost at startup.
|
|
17
15
|
const pipenet = this.deps.pipenet ?? (await import("../vendor/pipenet.js")).pipenet;
|
|
18
16
|
const ticket = await this.deps.api.tunnels.getTicket.v1();
|
|
19
|
-
// ALPIC_TUNNEL_HOST
|
|
20
|
-
// override for a local (plain-HTTP) server, so default to http regardless of the host;
|
|
21
|
-
// pass an explicit https:// to force TLS.
|
|
17
|
+
// ALPIC_TUNNEL_HOST is a dev override pointing a real ticket at a locally-run (plain-HTTP) tunnel server, so default to http regardless of the host; pass an explicit https:// to force TLS.
|
|
22
18
|
const hostOverride = process.env.ALPIC_TUNNEL_HOST;
|
|
23
19
|
let tunnelHost;
|
|
24
20
|
let proto;
|
|
@@ -73,19 +69,7 @@ export class Tunnel {
|
|
|
73
69
|
listener(info);
|
|
74
70
|
}
|
|
75
71
|
});
|
|
76
|
-
//
|
|
77
|
-
// account's subdomain, the server closes our tunnel and rejects our reconnections
|
|
78
|
-
// (they target a session id that no longer exists), so each one connects and is
|
|
79
|
-
// dropped within milliseconds. pipenet's offlineTimeoutMs never fires for this — it
|
|
80
|
-
// only triggers when the server is unreachable entirely (failed connects emit no
|
|
81
|
-
// "dead"). A "dead" with a prior "open" means a socket reached the server and was
|
|
82
|
-
// dropped, so a sustained storm of them is the takeover signature.
|
|
83
|
-
//
|
|
84
|
-
// Normal serving also churns sockets: with the server's small keep-alive pool, most
|
|
85
|
-
// concurrent requests get their socket destroyed right after serving, emitting a
|
|
86
|
-
// "dead" each. A heavy page load can fire 15+ in a few seconds and look identical to
|
|
87
|
-
// a takeover. The discriminator: a real takeover routes all traffic to the new
|
|
88
|
-
// tunnel, so we serve zero requests during the storm. Ignore it while requests flow.
|
|
72
|
+
// Takeover by a newer tunnel shows up as a sustained storm of "dead" events with zero requests served (rejected reconnections reach the server and are dropped in milliseconds, so pipenet's offlineTimeoutMs never fires); normal serving also churns sockets, but only while requests flow, hence the lastRequestAt discriminator.
|
|
89
73
|
let drops = [];
|
|
90
74
|
socket.tunnelCluster?.on("dead", () => {
|
|
91
75
|
if (displaced || closed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/tunnel/tunnel.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,qEAAqE;AACrE,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC/B,MAAM,cAAc,GAAG,EAAE,CAAC;AAsC1B,MAAM,OAAO,MAAM;IACY;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,KAAK,CAAC,IAAI,CAAC,IAAuB;QAChC,
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/tunnel/tunnel.ts"],"names":[],"mappings":"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"}
|