@promigence/sdk 0.1.0-beta.7 → 0.1.0-beta.9
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/README.md +3 -2
- package/dist/cjs/client.d.ts +67 -6
- package/dist/cjs/client.js +38 -14
- package/dist/cjs/core.d.ts +17 -6
- package/dist/cjs/core.js +12 -4
- package/dist/cjs/credstore.d.ts +3 -2
- package/dist/cjs/credstore.js +17 -4
- package/dist/cjs/github.d.ts +1 -1
- package/dist/cjs/gitlab.d.ts +1 -1
- package/dist/cjs/models.gen.d.ts +227 -22
- package/dist/cjs/proxy.js +2 -1
- package/dist/cjs/pty.d.ts +65 -3
- package/dist/cjs/pty.js +270 -34
- package/dist/cjs/sandbox.d.ts +41 -10
- package/dist/cjs/sandbox.js +10 -3
- package/dist/cjs/ssh.js +1 -0
- package/dist/client.d.ts +67 -6
- package/dist/client.js +39 -15
- package/dist/core.d.ts +17 -6
- package/dist/core.js +10 -3
- package/dist/credstore.d.ts +3 -2
- package/dist/credstore.js +17 -4
- package/dist/github.d.ts +1 -1
- package/dist/gitlab.d.ts +1 -1
- package/dist/models.gen.d.ts +227 -22
- package/dist/proxy.js +2 -1
- package/dist/pty.d.ts +65 -3
- package/dist/pty.js +269 -33
- package/dist/sandbox.d.ts +41 -10
- package/dist/sandbox.js +10 -3
- package/dist/ssh.js +1 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -420,7 +420,19 @@ export interface SnapshotBuild {
|
|
|
420
420
|
/** `true` when the snapshot this build made has since been deleted. */
|
|
421
421
|
snapshot_deleted?: boolean;
|
|
422
422
|
tier_assigned?: string;
|
|
423
|
+
/**
|
|
424
|
+
* The most the build can cost, USD, said before it runs: `max_seconds` at `per_second_usd`. A build
|
|
425
|
+
* is billed per second for the time it runs; what it cost is `cost_usd` once it has ended.
|
|
426
|
+
*/
|
|
423
427
|
build_price?: number;
|
|
428
|
+
/** What one second of the build costs, USD: its tier's per-second rate. */
|
|
429
|
+
per_second_usd?: number;
|
|
430
|
+
/** The longest the build may run, in seconds: it is billed for at most this long. */
|
|
431
|
+
max_seconds?: number;
|
|
432
|
+
/** Once it has ended, the seconds it is billed for; 0 when it failed on our side. */
|
|
433
|
+
billable_seconds?: number;
|
|
434
|
+
/** Once it has ended, what it cost, USD; 0 when nothing was charged. */
|
|
435
|
+
cost_usd?: number;
|
|
424
436
|
repo?: string;
|
|
425
437
|
commit?: string;
|
|
426
438
|
verification?: Record<string, unknown>;
|
|
@@ -748,6 +760,8 @@ export interface CreditOffer {
|
|
|
748
760
|
state: string;
|
|
749
761
|
credit_usd: number;
|
|
750
762
|
card_bonus_usd: number;
|
|
763
|
+
/** USD charged to confirm Apple Pay, Google Pay or Amazon Pay when one is added (added to the credit). */
|
|
764
|
+
method_check_usd?: number;
|
|
751
765
|
expires_at?: string | null;
|
|
752
766
|
campaign?: string | null;
|
|
753
767
|
message: string;
|
|
@@ -845,7 +859,10 @@ export interface PricingView {
|
|
|
845
859
|
gib_second_usd: number;
|
|
846
860
|
preemptible_vcpu_second_usd: number;
|
|
847
861
|
preemptible_gib_second_usd: number;
|
|
848
|
-
/**
|
|
862
|
+
/**
|
|
863
|
+
* The most one snapshot build of the default tier can cost (`limits.build_max_s` seconds at that
|
|
864
|
+
* tier's rate). A build is billed per second at its own tier's rate for the time it runs.
|
|
865
|
+
*/
|
|
849
866
|
build_usd: number;
|
|
850
867
|
/** Per GiB of data out above the month's allowance; `null` when not priced. */
|
|
851
868
|
egress_gb_usd: number | null;
|
|
@@ -870,6 +887,8 @@ export interface PricingView {
|
|
|
870
887
|
max_egress_gb_month: number | null;
|
|
871
888
|
/** Outbound mail ports open. */
|
|
872
889
|
smtp: boolean;
|
|
890
|
+
/** The longest a snapshot build may run, in seconds: the most one build is billed for. */
|
|
891
|
+
build_max_s?: number;
|
|
873
892
|
};
|
|
874
893
|
/** The free credit a new account gets (an account's own: `GET /credits/offer`). */
|
|
875
894
|
free_credit: {
|
|
@@ -906,6 +925,16 @@ export interface BillingUsage {
|
|
|
906
925
|
brand?: string;
|
|
907
926
|
last4?: string;
|
|
908
927
|
} | null;
|
|
928
|
+
/** Set when the card on file does not unlock paid limits for this organization (it already pays for another one,
|
|
929
|
+
* it is being confirmed with a $1 charge, or that charge did not go through). */
|
|
930
|
+
card_note?: string | null;
|
|
931
|
+
/** The $1 that confirms Apple Pay, Google Pay or Amazon Pay on file: `confirming`, `paid` or `failed`. */
|
|
932
|
+
method_check?: {
|
|
933
|
+
method: string;
|
|
934
|
+
status: string;
|
|
935
|
+
amount_usd: number;
|
|
936
|
+
bonus_usd?: number | null;
|
|
937
|
+
} | null;
|
|
909
938
|
suspended?: boolean;
|
|
910
939
|
suspend_reason?: string | null;
|
|
911
940
|
period?: {
|
|
@@ -929,6 +958,10 @@ export interface BillingUsage {
|
|
|
929
958
|
upcoming_invoice_error?: string | null;
|
|
930
959
|
[extra: string]: unknown;
|
|
931
960
|
}
|
|
961
|
+
/** One row of `GET /billing/history`: a credit the organization received, or a payment. */
|
|
962
|
+
export type BillingHistoryEntry = M.BillingHistoryEntry;
|
|
963
|
+
/** What `billing.historyPage()` lists: everything, only credits, or only payments. */
|
|
964
|
+
export type BillingHistoryKind = "all" | "credits" | "payments";
|
|
932
965
|
/** One metered row of `GET /me/ledger`. */
|
|
933
966
|
export interface LedgerEntry {
|
|
934
967
|
entry_id: string;
|
|
@@ -1431,7 +1464,11 @@ export interface PromigenceClientOpts {
|
|
|
1431
1464
|
* From the CLI: `promigence --request-timeout DUR` or `PROMIGENCE_REQUEST_TIMEOUT`.
|
|
1432
1465
|
*/
|
|
1433
1466
|
requestTimeoutMs?: number;
|
|
1434
|
-
/**
|
|
1467
|
+
/**
|
|
1468
|
+
* How many times a request is sent again (default 3): after a 429 or a 503, and after a 502 or
|
|
1469
|
+
* 504 that is not the API's own answer when sending twice is harmless (a read, a delete, or a
|
|
1470
|
+
* create with its idempotency key).
|
|
1471
|
+
*/
|
|
1435
1472
|
maxRetries?: number;
|
|
1436
1473
|
/** Backoff base when the server sends no `Retry-After` (default 250 ms). */
|
|
1437
1474
|
retryBaseMs?: number;
|
|
@@ -1869,7 +1906,7 @@ interface RequestOpts {
|
|
|
1869
1906
|
signal?: AbortSignal;
|
|
1870
1907
|
/** Skip the Authorization header (unauthenticated routes). */
|
|
1871
1908
|
anonymous?: boolean;
|
|
1872
|
-
/** Called with the response headers of the attempt that answered (not of
|
|
1909
|
+
/** Called with the response headers of the attempt that answered (not of one that was retried). */
|
|
1873
1910
|
onHeaders?: (headers: Headers) => void;
|
|
1874
1911
|
/** Extra request headers (e.g. `promigence-replaced-by`). Never the authorization. */
|
|
1875
1912
|
headers?: Record<string, string>;
|
|
@@ -1944,8 +1981,10 @@ export declare class PromigenceClient {
|
|
|
1944
1981
|
* rule `request()` applies, for the calls that cannot go through it (byte transfers, the
|
|
1945
1982
|
* opening of an exec stream, the terminal handshake). Retried: a 429, and a 503 that says
|
|
1946
1983
|
* nothing started — any 503 for a request safe to send twice, else only one carrying a
|
|
1947
|
-
* `Retry-After` (every refusal at the door sets one) or a refusal code
|
|
1948
|
-
*
|
|
1984
|
+
* `Retry-After` (every refusal at the door sets one) or a refusal code — and, for a request
|
|
1985
|
+
* safe to send twice, a 502 or 504 that is not the API's own answer (it carries no error
|
|
1986
|
+
* code). At most `maxRetries` times, and never a `Retry-After` longer than
|
|
1987
|
+
* MAX_RETRY_SLEEP_MS: that one is the caller's.
|
|
1949
1988
|
*/
|
|
1950
1989
|
private refusalBackoff;
|
|
1951
1990
|
/** A long-poll request must outlive its own `wait_ms`; everything else keeps the default. */
|
|
@@ -1982,7 +2021,7 @@ export declare class PromigenceClient {
|
|
|
1982
2021
|
}): Promise<StatusResponse>;
|
|
1983
2022
|
/**
|
|
1984
2023
|
* `GET /pricing` — your organization's price list, live: the per-second rates, every sandbox
|
|
1985
|
-
* shape on sale and its price
|
|
2024
|
+
* shape on sale and its price (a snapshot build bills at its tier's), the limits, the free credit and the plan they
|
|
1986
2025
|
* come from, read on every call from what billing charges. Needs a key: without one this throws
|
|
1987
2026
|
* `AuthError` and sends nothing. The published list prices are on the pricing page.
|
|
1988
2027
|
*
|
|
@@ -2033,6 +2072,16 @@ export declare class PromigenceClient {
|
|
|
2033
2072
|
limit?: number;
|
|
2034
2073
|
cursor?: string;
|
|
2035
2074
|
}) => Promise<Page<LedgerEntry>>;
|
|
2075
|
+
/**
|
|
2076
|
+
* `GET /billing/history` — the credits the organization received and its payments, newest
|
|
2077
|
+
* first (one page). `kind` narrows it to `credits` or `payments`; feed `nextCursor` back as
|
|
2078
|
+
* `cursor` until it is `null`. An owner's key.
|
|
2079
|
+
*/
|
|
2080
|
+
historyPage: (opts?: {
|
|
2081
|
+
kind?: BillingHistoryKind;
|
|
2082
|
+
limit?: number;
|
|
2083
|
+
cursor?: string;
|
|
2084
|
+
}) => Promise<Page<BillingHistoryEntry>>;
|
|
2036
2085
|
/** `POST /billing/checkout` — the hosted page that puts a card on file. */
|
|
2037
2086
|
checkout: () => Promise<{
|
|
2038
2087
|
url: string;
|
|
@@ -2433,6 +2482,18 @@ export declare class PromigenceClient {
|
|
|
2433
2482
|
onData?: (data: Uint8Array) => void;
|
|
2434
2483
|
onExit?: (exit: PtyExit) => void;
|
|
2435
2484
|
timeoutMs?: number;
|
|
2485
|
+
/** Pick the same terminal up again when its connection drops or the service is updated;
|
|
2486
|
+
* see `PtyConnectOpts.resume`. Default: on. */
|
|
2487
|
+
resume?: boolean;
|
|
2488
|
+
/** Reconnect in a new shell when the service is updated (a WebSocket `Close` 1012) and the
|
|
2489
|
+
* terminal cannot be picked up again; see `PtyConnectOpts.reconnect`. Default: on without
|
|
2490
|
+
* `cmd`, off with one. */
|
|
2491
|
+
reconnect?: boolean;
|
|
2492
|
+
/** Called after each reconnect: `resumed` says whether it is the same terminal or a new
|
|
2493
|
+
* shell. */
|
|
2494
|
+
onReconnected?: (how: {
|
|
2495
|
+
resumed: boolean;
|
|
2496
|
+
}) => void;
|
|
2436
2497
|
}) => Promise<PtySession>;
|
|
2437
2498
|
/** `GET /sandboxes/:id`. */
|
|
2438
2499
|
get: (sandboxId: string) => Promise<SandboxRecord>;
|
package/dist/client.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync, statSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { inspect } from "node:util";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
|
-
import { ApiError, AuthError, EnvFailedError, PromigenceError, InvalidArgumentError, NotFoundError, NotReleasedError, NotVerifiedError, RateLimitError, SpendCapError, TimeoutError, UnreachableError, DEFAULT_API_URL, ERRORS_DOCS_URL, FILE_PUT_CHUNK_BYTES, MAX_OUTPUT_BYTES_DEFAULT, VERSION, WAIT_TIMEOUT_MS, PreviewsUnavailableError, exitForCode, previewsOff, withPreviewsFix, } from "./core.js";
|
|
5
|
+
import { ApiError, AuthError, EnvFailedError, PromigenceError, InvalidArgumentError, NotFoundError, NotReleasedError, NotVerifiedError, RateLimitError, ServiceRestartError, SpendCapError, TimeoutError, UnreachableError, DEFAULT_API_URL, ERRORS_DOCS_URL, FILE_PUT_CHUNK_BYTES, MAX_OUTPUT_BYTES_DEFAULT, VERSION, WAIT_TIMEOUT_MS, PreviewsUnavailableError, exitForCode, previewsOff, withPreviewsFix, } from "./core.js";
|
|
6
6
|
import { buildBundle } from "./bundle.js";
|
|
7
7
|
import { keychainReadCached, keychainStore, storeLabel } from "./credstore.js";
|
|
8
8
|
import { CALLER_HEADER, resolveCaller, userAgentWithCaller } from "./caller.js";
|
|
@@ -135,7 +135,7 @@ function decodeCredentials(buf) {
|
|
|
135
135
|
return buf.subarray(3).toString("utf8");
|
|
136
136
|
return buf.toString("utf8");
|
|
137
137
|
}
|
|
138
|
-
export function storedCredentials(env = process.env) {
|
|
138
|
+
export function storedCredentials(env = process.env, platform = process.platform) {
|
|
139
139
|
const path = credentialsPath(env);
|
|
140
140
|
let present = true;
|
|
141
141
|
try {
|
|
@@ -145,7 +145,7 @@ export function storedCredentials(env = process.env) {
|
|
|
145
145
|
present = e.code !== "ENOENT";
|
|
146
146
|
}
|
|
147
147
|
if (!present) {
|
|
148
|
-
const store = keychainStore(env);
|
|
148
|
+
const store = keychainStore(env, platform);
|
|
149
149
|
if (store === undefined)
|
|
150
150
|
return undefined;
|
|
151
151
|
const r = keychainReadCached(store, path, env);
|
|
@@ -259,8 +259,6 @@ export function keyOrigin(env = process.env) {
|
|
|
259
259
|
const stored = readCredentialsWithStore(env);
|
|
260
260
|
if (stored.creds.api_key)
|
|
261
261
|
return stored.store === "macos-keychain" ? "macOS Keychain" : stored.store === "secret-service" ? "Secret Service keyring" : "credentials file";
|
|
262
|
-
if (compatApiKey(env["E2B_API_KEY"]))
|
|
263
|
-
return "E2B_API_KEY (compat)";
|
|
264
262
|
return undefined;
|
|
265
263
|
}
|
|
266
264
|
function resolveCredentials(opts, env = process.env) {
|
|
@@ -269,17 +267,19 @@ function resolveCredentials(opts, env = process.env) {
|
|
|
269
267
|
const t = u.replace(/\/+$/, "");
|
|
270
268
|
return /^https?:\/\/[^/?#]+$/i.test(t) ? `${t}/v1` : t;
|
|
271
269
|
};
|
|
272
|
-
const { creds, store } = readCredentialsWithStore(env);
|
|
273
270
|
const envKey = set(env["PROMIGENCE_API_KEY"]?.trim());
|
|
274
271
|
const envUrl = set(env["PROMIGENCE_API_URL"]);
|
|
275
272
|
const optKey = opts.apiKey?.trim();
|
|
273
|
+
const given = optKey !== undefined || envKey !== undefined;
|
|
274
|
+
const { creds, store } = given
|
|
275
|
+
? { creds: {}, store: undefined }
|
|
276
|
+
: readCredentialsWithStore(env);
|
|
276
277
|
const source = optKey !== undefined ? "opts" : envKey !== undefined ? "env" : creds.api_key !== undefined ? "file" : undefined;
|
|
277
278
|
const ours = optKey ?? envKey ?? creds.api_key;
|
|
278
|
-
const
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const fromFile = trim(creds.api_url ?? compatUrl ?? DEFAULT_API_URL);
|
|
279
|
+
const fallback = ours === undefined ? opts.fallbackKey : undefined;
|
|
280
|
+
const fallbackKey = set(fallback?.apiKey.trim());
|
|
281
|
+
const fallbackUrl = fallbackKey === undefined ? undefined : set(fallback?.apiUrl);
|
|
282
|
+
const fromFile = trim(creds.api_url ?? fallbackUrl ?? DEFAULT_API_URL);
|
|
283
283
|
const fromEnv = envUrl !== undefined ? trim(envUrl) : fromFile;
|
|
284
284
|
const apiUrl = opts.apiUrl !== undefined ? trim(opts.apiUrl) : fromEnv;
|
|
285
285
|
const paired = source === "file" ? fromFile : source === "env" ? fromEnv : apiUrl;
|
|
@@ -291,10 +291,10 @@ function resolveCredentials(opts, env = process.env) {
|
|
|
291
291
|
: "Pass apiKey together with apiUrl, or set PROMIGENCE_API_URL to that URL instead of passing apiUrl.");
|
|
292
292
|
return { apiKey: undefined, apiUrl, refusal };
|
|
293
293
|
}
|
|
294
|
-
const key = ours ??
|
|
294
|
+
const key = ours ?? fallbackKey;
|
|
295
295
|
if (key) {
|
|
296
296
|
const from = source === "opts" ? "the apiKey option" : source === "env" ? "PROMIGENCE_API_KEY"
|
|
297
|
-
: source === "file" ? storedName(store, env) :
|
|
297
|
+
: source === "file" ? storedName(store, env) : fallback.from;
|
|
298
298
|
const refusal = keyRefusal(key, from);
|
|
299
299
|
if (refusal)
|
|
300
300
|
return { apiKey: undefined, apiUrl, refusal };
|
|
@@ -652,6 +652,7 @@ export function errorFor(code, message, fix, extra = {}) {
|
|
|
652
652
|
case "invalid_argument":
|
|
653
653
|
return attach(new InvalidArgumentError(message, extra.cli ? fix : withoutCliHelp(fix), code));
|
|
654
654
|
case "not_released": return attach(new NotReleasedError(message));
|
|
655
|
+
case "service_restart": return attach(new ServiceRestartError(message, fix));
|
|
655
656
|
default:
|
|
656
657
|
if (ENV_CODES.has(code) || extra.category === "env")
|
|
657
658
|
return attach(new EnvFailedError(code, message, fix));
|
|
@@ -836,7 +837,8 @@ export class PromigenceClient {
|
|
|
836
837
|
refusalBackoff(status, retryAfterMs, code, attempt, replayable, signal) {
|
|
837
838
|
if (attempt >= this.maxRetries || signal?.aborted)
|
|
838
839
|
return undefined;
|
|
839
|
-
|
|
840
|
+
const gateway = (status === 502 || status === 504) && replayable && code === undefined;
|
|
841
|
+
if (status !== 429 && status !== 503 && !gateway)
|
|
840
842
|
return undefined;
|
|
841
843
|
if ((retryAfterMs ?? 0) > MAX_RETRY_SLEEP_MS)
|
|
842
844
|
return undefined;
|
|
@@ -959,12 +961,17 @@ export class PromigenceClient {
|
|
|
959
961
|
throw new UnreachableError(`cannot reach ${url}: ${transportDetail(e)}`);
|
|
960
962
|
}
|
|
961
963
|
const retryAfterMs = parseRetryAfter(headerOf(res, "retry-after"));
|
|
962
|
-
|
|
964
|
+
const gateway = (res.status === 502 || res.status === 504) && replayable;
|
|
965
|
+
let retryable = (res.status === 429 || res.status === 503 || gateway) && (retryAfterMs ?? 0) <= MAX_RETRY_SLEEP_MS;
|
|
963
966
|
let body;
|
|
964
967
|
if (retryable && res.status === 503 && !replayable && retryAfterMs === undefined) {
|
|
965
968
|
body = await res.text().catch(() => "");
|
|
966
969
|
retryable = REFUSED_503_CODES.has(errorCodeOf(body) ?? "");
|
|
967
970
|
}
|
|
971
|
+
if (retryable && gateway) {
|
|
972
|
+
body = await res.text().catch(() => "");
|
|
973
|
+
retryable = errorCodeOf(body) === undefined;
|
|
974
|
+
}
|
|
968
975
|
if (retryable && attempt < this.maxRetries) {
|
|
969
976
|
const backoff = Math.min(MAX_RETRY_SLEEP_MS, this.retryBaseMs * 2 ** attempt);
|
|
970
977
|
const jitter = Math.random();
|
|
@@ -972,6 +979,8 @@ export class PromigenceClient {
|
|
|
972
979
|
? retryAfterMs + jitter * Math.min(250, this.retryBaseMs)
|
|
973
980
|
: backoff * (0.5 + jitter * 0.5);
|
|
974
981
|
this.stats.retries++;
|
|
982
|
+
if (gateway && opts.method === "DELETE")
|
|
983
|
+
resentDelete = true;
|
|
975
984
|
if (body === undefined)
|
|
976
985
|
try {
|
|
977
986
|
await res.text();
|
|
@@ -1258,6 +1267,14 @@ export class PromigenceClient {
|
|
|
1258
1267
|
const r = await this.request({ method: "GET", path: `/me/ledger?${pageQuery(limit, 1000, opts.cursor)}` });
|
|
1259
1268
|
return pageOf(r, "entries", limit);
|
|
1260
1269
|
},
|
|
1270
|
+
historyPage: async (opts = {}) => {
|
|
1271
|
+
const limit = opts.limit ?? 50;
|
|
1272
|
+
const q = new URLSearchParams(pageQuery(limit, 100, opts.cursor));
|
|
1273
|
+
if (opts.kind !== undefined && opts.kind !== "all")
|
|
1274
|
+
q.set("kind", opts.kind);
|
|
1275
|
+
const r = await this.request({ method: "GET", path: `/billing/history?${q.toString()}` });
|
|
1276
|
+
return pageOf(r, "entries", limit);
|
|
1277
|
+
},
|
|
1261
1278
|
checkout: () => this.request({ method: "POST", path: "/billing/checkout", body: {} }),
|
|
1262
1279
|
portal: () => this.request({ method: "POST", path: "/billing/portal", body: {} }),
|
|
1263
1280
|
referrals: () => this.request({ method: "GET", path: "/referrals" }),
|
|
@@ -1752,6 +1769,10 @@ export class PromigenceClient {
|
|
|
1752
1769
|
on.heartbeat?.();
|
|
1753
1770
|
continue;
|
|
1754
1771
|
}
|
|
1772
|
+
if (event === "reconnect") {
|
|
1773
|
+
reader.cancel().catch(() => { });
|
|
1774
|
+
throw new ServiceRestartError(`a service restart stopped the command on sandbox ${sandboxId} while its output was streaming`, "Not billed: the time the command ran is credited back. The sandbox kept running; the command may have done part of its work before it stopped: run it again if that is safe.");
|
|
1775
|
+
}
|
|
1755
1776
|
let parsed = {};
|
|
1756
1777
|
try {
|
|
1757
1778
|
parsed = JSON.parse(data);
|
|
@@ -1987,6 +2008,9 @@ export class PromigenceClient {
|
|
|
1987
2008
|
...(opts.onData ? { onData: opts.onData } : {}),
|
|
1988
2009
|
...(opts.onExit ? { onExit: opts.onExit } : {}),
|
|
1989
2010
|
...(opts.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }),
|
|
2011
|
+
...(opts.resume === undefined ? {} : { resume: opts.resume }),
|
|
2012
|
+
...(opts.reconnect === undefined ? {} : { reconnect: opts.reconnect }),
|
|
2013
|
+
...(opts.onReconnected ? { onReconnected: opts.onReconnected } : {}),
|
|
1990
2014
|
refuse: (status, text, retryAfter) => {
|
|
1991
2015
|
let payload = {};
|
|
1992
2016
|
try {
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Promigence SDK — constants, error hierarchy and shared types. */
|
|
2
|
-
export declare const VERSION = "0.1.0-beta.
|
|
2
|
+
export declare const VERSION = "0.1.0-beta.9";
|
|
3
3
|
export declare const DOCS_URL = "https://promigence.ai";
|
|
4
4
|
/** The error reference; each code is an anchor on it (the API's `docs` link has the same form). */
|
|
5
5
|
export declare const ERRORS_DOCS_URL = "https://www.promigence.ai/docs/errors";
|
|
@@ -14,12 +14,14 @@ export declare const WAIT_TIMEOUT_MS = 100000;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare const IMAGE_BUILD_TIMEOUT_MS: number;
|
|
16
16
|
/**
|
|
17
|
-
* The
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* The most one new snapshot build of the default tier can cost at the list prices this SDK was
|
|
18
|
+
* built with, in USD: its time limit (an hour) at that tier's per-second rate. A build is billed per
|
|
19
|
+
* second for the time it runs; reusing or joining an identical build is free. Prices change: the
|
|
20
|
+
* live figure is `client.pricing()`'s `rates.build_usd` (this key's organization's), and a build's
|
|
21
|
+
* own arrives as `build_price` in the `POST /snapshots` answer. This is only the fallback when the
|
|
22
|
+
* API cannot be asked.
|
|
21
23
|
*/
|
|
22
|
-
export declare const IMAGE_BUILD_LIST_PRICE =
|
|
24
|
+
export declare const IMAGE_BUILD_LIST_PRICE = 0.1656;
|
|
23
25
|
/** Inline output budget for an exec before `truncated` + `_ref`. */
|
|
24
26
|
export declare const MAX_OUTPUT_BYTES_DEFAULT: number;
|
|
25
27
|
/** One request of a `files.put`. **Not a file-size limit** — `put` loops. */
|
|
@@ -190,6 +192,15 @@ export declare class TimeoutError extends PromigenceError {
|
|
|
190
192
|
runId?: string;
|
|
191
193
|
});
|
|
192
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* A service update may stop a command that was running while its output was streaming to you
|
|
197
|
+
* (`execStream`, `commands.run` with output callbacks); the time it ran is credited back, and the
|
|
198
|
+
* sandbox keeps running. `retryable` is `false`: the command may have done part of its work before
|
|
199
|
+
* it stopped, so run it again only if that is safe. exit 3
|
|
200
|
+
*/
|
|
201
|
+
export declare class ServiceRestartError extends PromigenceError {
|
|
202
|
+
constructor(message: string, fix: string);
|
|
203
|
+
}
|
|
193
204
|
/** An API error with no more specific class (5xx, unknown code). exit from the table. */
|
|
194
205
|
export declare class ApiError extends PromigenceError {
|
|
195
206
|
}
|
package/dist/core.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { hintArg } from "./hint.js";
|
|
2
|
-
export const VERSION = "0.1.0-beta.
|
|
2
|
+
export const VERSION = "0.1.0-beta.9";
|
|
3
3
|
export const DOCS_URL = "https://promigence.ai";
|
|
4
4
|
export const ERRORS_DOCS_URL = "https://www.promigence.ai/docs/errors";
|
|
5
5
|
export const DEFAULT_API_URL = "https://api.promigence.ai/v1";
|
|
6
6
|
export const KEY_CONTACT = "support@promigence.ai";
|
|
7
7
|
export const WAIT_TIMEOUT_MS = 100_000;
|
|
8
8
|
export const IMAGE_BUILD_TIMEOUT_MS = 15 * 60_000;
|
|
9
|
-
export const IMAGE_BUILD_LIST_PRICE =
|
|
9
|
+
export const IMAGE_BUILD_LIST_PRICE = 0.1656;
|
|
10
10
|
export const MAX_OUTPUT_BYTES_DEFAULT = 64 * 1024;
|
|
11
11
|
export const FILE_PUT_CHUNK_BYTES = 16 * 1024 * 1024;
|
|
12
12
|
const PREVIEWS_OFF = /^previews are not enabled on this deployment\.?$/i;
|
|
@@ -194,6 +194,11 @@ export class TimeoutError extends PromigenceError {
|
|
|
194
194
|
this.runId = ids.runId;
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
+
export class ServiceRestartError extends PromigenceError {
|
|
198
|
+
constructor(message, fix) {
|
|
199
|
+
super({ code: "service_restart", message, fix, exitCode: 3, category: "env", retryable: false });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
197
202
|
export class ApiError extends PromigenceError {
|
|
198
203
|
}
|
|
199
204
|
export class NotReleasedError extends PromigenceError {
|
|
@@ -210,6 +215,7 @@ export const EXIT_BY_CODE = {
|
|
|
210
215
|
invalid_argument: 2, unsupported: 2, not_released: 1, task_failed: 4,
|
|
211
216
|
env_failed: 3, snapshot_rejected: 6, build_failed: 3, snapshot_failed: 4,
|
|
212
217
|
not_connected: 7,
|
|
218
|
+
service_restart: 3,
|
|
213
219
|
fork_failed: 3, start_timeout: 3, readiness_failed: 3, verify_too_slow: 3,
|
|
214
220
|
verify_each_failed: 3, toolchain_mismatch: 3, sandbox_unresponsive: 3, oom_within_tier: 3,
|
|
215
221
|
disk_full_within_tier: 3, sandbox_interrupted: 3, integrity_mismatch: 3, egress_unavailable: 3,
|
|
@@ -236,10 +242,11 @@ export const EXIT_BY_CODE = {
|
|
|
236
242
|
build_timeout: 4,
|
|
237
243
|
image_unresolvable: 2,
|
|
238
244
|
registry_unavailable: 3,
|
|
239
|
-
trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached:
|
|
245
|
+
trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached: 5,
|
|
240
246
|
billing_unavailable: 5,
|
|
241
247
|
project_cap_reached: 5,
|
|
242
248
|
spend_limit_reached: 5,
|
|
249
|
+
billing_hold: 5,
|
|
243
250
|
tier_over_plan: 2,
|
|
244
251
|
network_host_refused: 9, network_policy_unsupported: 3,
|
|
245
252
|
secrets_in_snapshot: 2, secrets_unavailable: 3,
|
package/dist/credstore.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* the credentials file (`~/.config/promigence/credentials`, 0600). The CLI writes it
|
|
4
4
|
* (`promigence login`, `promigence auth login`, `promigence logout`); the CLI and both SDKs read it.
|
|
5
5
|
*
|
|
6
|
-
* macOS the login Keychain, through `security` (when
|
|
6
|
+
* macOS the login Keychain, through `security` (when the user's home holds one: HOME,
|
|
7
|
+
* or the account's own home when the environment has no HOME)
|
|
7
8
|
* Linux and BSD the Secret Service (GNOME Keyring, KWallet), through `secret-tool`, when a
|
|
8
9
|
* desktop session bus is there (a CI job or an SSH shell has none: the file)
|
|
9
10
|
* Windows the file: no tool that ships with Windows can read a stored secret back
|
|
@@ -34,7 +35,7 @@ export declare function storeLabel(store: CredentialStore, path?: string): strin
|
|
|
34
35
|
* The keychain this process stores a sign-in in, or undefined for the file. `auto` is decided by
|
|
35
36
|
* the platform and by whether its tool (and, for the Secret Service, a session bus) is there.
|
|
36
37
|
*/
|
|
37
|
-
export declare function keychainStore(env?: NodeJS.ProcessEnv, platform?: string): KeychainStore | undefined;
|
|
38
|
+
export declare function keychainStore(env?: NodeJS.ProcessEnv, platform?: string, home?: () => string): KeychainStore | undefined;
|
|
38
39
|
/**
|
|
39
40
|
* The keychains a sign-out (or a sign-in that lands in the file) must clear for this path: the one
|
|
40
41
|
* in use, and the platform's own even when `PROMIGENCE_CREDENTIAL_STORE=file` (an item a previous
|
package/dist/credstore.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { accessSync, constants, existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { delimiter, join } from "node:path";
|
|
4
5
|
export const KEYCHAIN_SERVICE = "promigence-cli";
|
|
5
6
|
const KEYCHAIN_LABEL = "Promigence CLI credentials";
|
|
@@ -30,8 +31,19 @@ function sessionBus(env) {
|
|
|
30
31
|
const run = env["XDG_RUNTIME_DIR"];
|
|
31
32
|
return Boolean(run) && existsSync(join(run, "bus"));
|
|
32
33
|
}
|
|
34
|
+
function userHome(env, home = homedir) {
|
|
35
|
+
const h = env["HOME"];
|
|
36
|
+
if (h)
|
|
37
|
+
return h;
|
|
38
|
+
try {
|
|
39
|
+
return home() || undefined;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
33
45
|
const warnedSetting = new Set();
|
|
34
|
-
export function keychainStore(env = process.env, platform = process.platform) {
|
|
46
|
+
export function keychainStore(env = process.env, platform = process.platform, home = homedir) {
|
|
35
47
|
const raw = (env["PROMIGENCE_CREDENTIAL_STORE"] ?? "").trim().toLowerCase();
|
|
36
48
|
switch (raw) {
|
|
37
49
|
case "file": return undefined;
|
|
@@ -46,8 +58,8 @@ export function keychainStore(env = process.env, platform = process.platform) {
|
|
|
46
58
|
}
|
|
47
59
|
}
|
|
48
60
|
if (platform === "darwin") {
|
|
49
|
-
const
|
|
50
|
-
return
|
|
61
|
+
const h = userHome(env, home);
|
|
62
|
+
return h && existsSync(join(h, "Library", "Keychains")) && onPath("security", env) ? "macos-keychain" : undefined;
|
|
51
63
|
}
|
|
52
64
|
if (platform === "win32")
|
|
53
65
|
return undefined;
|
|
@@ -94,8 +106,9 @@ function runTool(store, args, env, input, timeout) {
|
|
|
94
106
|
const bin = onPath(toolName(store), env);
|
|
95
107
|
if (bin === undefined)
|
|
96
108
|
throw Object.assign(new Error(`${toolName(store)} not found`), { code: "ENOENT" });
|
|
109
|
+
const h = store === "macos-keychain" && !env["HOME"] ? userHome(env) : undefined;
|
|
97
110
|
return execFileSync(bin, args, {
|
|
98
|
-
encoding: "utf8", timeout, env,
|
|
111
|
+
encoding: "utf8", timeout, env: h ? { ...env, HOME: h } : env,
|
|
99
112
|
...(input === undefined ? { stdio: ["ignore", "pipe", "pipe"] } : { input, stdio: ["pipe", "pipe", "pipe"] }),
|
|
100
113
|
});
|
|
101
114
|
}
|
package/dist/github.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export interface GithubPending {
|
|
|
34
34
|
state: string;
|
|
35
35
|
message: string;
|
|
36
36
|
}
|
|
37
|
-
/** A snapshot that follows a branch: every push builds it again (
|
|
37
|
+
/** A snapshot that follows a branch: every push builds it again (each build billed per second). */
|
|
38
38
|
export interface GithubTrack {
|
|
39
39
|
track_id: string;
|
|
40
40
|
repo: string;
|
package/dist/gitlab.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface GitlabPending {
|
|
|
37
37
|
expires_at: string;
|
|
38
38
|
message: string;
|
|
39
39
|
}
|
|
40
|
-
/** A snapshot that follows a GitLab branch: each new commit builds it again (
|
|
40
|
+
/** A snapshot that follows a GitLab branch: each new commit builds it again (each build billed per second). */
|
|
41
41
|
export interface GitlabTrack {
|
|
42
42
|
track_id: string;
|
|
43
43
|
repo: string;
|