@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/README.md
CHANGED
|
@@ -13,8 +13,9 @@ npm i @promigence/sdk
|
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
You need a Promigence account (private beta, by invite). The quickest way to create one is the CLI:
|
|
16
|
-
`npm i -g promigence`, then `promigence signup`. The SDK
|
|
17
|
-
|
|
16
|
+
`npm i -g promigence`, then `promigence signup`. The SDK uses the key you pass (`apiKey`) or
|
|
17
|
+
`PROMIGENCE_API_KEY`; with neither, the key the CLI stored: the system keychain, or
|
|
18
|
+
`~/.config/promigence/credentials`. A key you pass or set is used as is; the stored one is not read.
|
|
18
19
|
|
|
19
20
|
## Use it
|
|
20
21
|
|
package/dist/cjs/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/cjs/client.js
CHANGED
|
@@ -168,7 +168,7 @@ function decodeCredentials(buf) {
|
|
|
168
168
|
return buf.subarray(3).toString("utf8");
|
|
169
169
|
return buf.toString("utf8");
|
|
170
170
|
}
|
|
171
|
-
function storedCredentials(env = process.env) {
|
|
171
|
+
function storedCredentials(env = process.env, platform = process.platform) {
|
|
172
172
|
const path = credentialsPath(env);
|
|
173
173
|
let present = true;
|
|
174
174
|
try {
|
|
@@ -178,7 +178,7 @@ function storedCredentials(env = process.env) {
|
|
|
178
178
|
present = e.code !== "ENOENT";
|
|
179
179
|
}
|
|
180
180
|
if (!present) {
|
|
181
|
-
const store = (0, credstore_js_1.keychainStore)(env);
|
|
181
|
+
const store = (0, credstore_js_1.keychainStore)(env, platform);
|
|
182
182
|
if (store === undefined)
|
|
183
183
|
return undefined;
|
|
184
184
|
const r = (0, credstore_js_1.keychainReadCached)(store, path, env);
|
|
@@ -292,8 +292,6 @@ function keyOrigin(env = process.env) {
|
|
|
292
292
|
const stored = readCredentialsWithStore(env);
|
|
293
293
|
if (stored.creds.api_key)
|
|
294
294
|
return stored.store === "macos-keychain" ? "macOS Keychain" : stored.store === "secret-service" ? "Secret Service keyring" : "credentials file";
|
|
295
|
-
if (compatApiKey(env["E2B_API_KEY"]))
|
|
296
|
-
return "E2B_API_KEY (compat)";
|
|
297
295
|
return undefined;
|
|
298
296
|
}
|
|
299
297
|
function resolveCredentials(opts, env = process.env) {
|
|
@@ -302,17 +300,19 @@ function resolveCredentials(opts, env = process.env) {
|
|
|
302
300
|
const t = u.replace(/\/+$/, "");
|
|
303
301
|
return /^https?:\/\/[^/?#]+$/i.test(t) ? `${t}/v1` : t;
|
|
304
302
|
};
|
|
305
|
-
const { creds, store } = readCredentialsWithStore(env);
|
|
306
303
|
const envKey = set(env["PROMIGENCE_API_KEY"]?.trim());
|
|
307
304
|
const envUrl = set(env["PROMIGENCE_API_URL"]);
|
|
308
305
|
const optKey = opts.apiKey?.trim();
|
|
306
|
+
const given = optKey !== undefined || envKey !== undefined;
|
|
307
|
+
const { creds, store } = given
|
|
308
|
+
? { creds: {}, store: undefined }
|
|
309
|
+
: readCredentialsWithStore(env);
|
|
309
310
|
const source = optKey !== undefined ? "opts" : envKey !== undefined ? "env" : creds.api_key !== undefined ? "file" : undefined;
|
|
310
311
|
const ours = optKey ?? envKey ?? creds.api_key;
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const fromFile = trim(creds.api_url ?? compatUrl ?? core_js_1.DEFAULT_API_URL);
|
|
312
|
+
const fallback = ours === undefined ? opts.fallbackKey : undefined;
|
|
313
|
+
const fallbackKey = set(fallback?.apiKey.trim());
|
|
314
|
+
const fallbackUrl = fallbackKey === undefined ? undefined : set(fallback?.apiUrl);
|
|
315
|
+
const fromFile = trim(creds.api_url ?? fallbackUrl ?? core_js_1.DEFAULT_API_URL);
|
|
316
316
|
const fromEnv = envUrl !== undefined ? trim(envUrl) : fromFile;
|
|
317
317
|
const apiUrl = opts.apiUrl !== undefined ? trim(opts.apiUrl) : fromEnv;
|
|
318
318
|
const paired = source === "file" ? fromFile : source === "env" ? fromEnv : apiUrl;
|
|
@@ -324,10 +324,10 @@ function resolveCredentials(opts, env = process.env) {
|
|
|
324
324
|
: "Pass apiKey together with apiUrl, or set PROMIGENCE_API_URL to that URL instead of passing apiUrl.");
|
|
325
325
|
return { apiKey: undefined, apiUrl, refusal };
|
|
326
326
|
}
|
|
327
|
-
const key = ours ??
|
|
327
|
+
const key = ours ?? fallbackKey;
|
|
328
328
|
if (key) {
|
|
329
329
|
const from = source === "opts" ? "the apiKey option" : source === "env" ? "PROMIGENCE_API_KEY"
|
|
330
|
-
: source === "file" ? storedName(store, env) :
|
|
330
|
+
: source === "file" ? storedName(store, env) : fallback.from;
|
|
331
331
|
const refusal = keyRefusal(key, from);
|
|
332
332
|
if (refusal)
|
|
333
333
|
return { apiKey: undefined, apiUrl, refusal };
|
|
@@ -685,6 +685,7 @@ function errorFor(code, message, fix, extra = {}) {
|
|
|
685
685
|
case "invalid_argument":
|
|
686
686
|
return attach(new core_js_1.InvalidArgumentError(message, extra.cli ? fix : withoutCliHelp(fix), code));
|
|
687
687
|
case "not_released": return attach(new core_js_1.NotReleasedError(message));
|
|
688
|
+
case "service_restart": return attach(new core_js_1.ServiceRestartError(message, fix));
|
|
688
689
|
default:
|
|
689
690
|
if (ENV_CODES.has(code) || extra.category === "env")
|
|
690
691
|
return attach(new core_js_1.EnvFailedError(code, message, fix));
|
|
@@ -869,7 +870,8 @@ class PromigenceClient {
|
|
|
869
870
|
refusalBackoff(status, retryAfterMs, code, attempt, replayable, signal) {
|
|
870
871
|
if (attempt >= this.maxRetries || signal?.aborted)
|
|
871
872
|
return undefined;
|
|
872
|
-
|
|
873
|
+
const gateway = (status === 502 || status === 504) && replayable && code === undefined;
|
|
874
|
+
if (status !== 429 && status !== 503 && !gateway)
|
|
873
875
|
return undefined;
|
|
874
876
|
if ((retryAfterMs ?? 0) > MAX_RETRY_SLEEP_MS)
|
|
875
877
|
return undefined;
|
|
@@ -992,12 +994,17 @@ class PromigenceClient {
|
|
|
992
994
|
throw new core_js_1.UnreachableError(`cannot reach ${url}: ${transportDetail(e)}`);
|
|
993
995
|
}
|
|
994
996
|
const retryAfterMs = parseRetryAfter(headerOf(res, "retry-after"));
|
|
995
|
-
|
|
997
|
+
const gateway = (res.status === 502 || res.status === 504) && replayable;
|
|
998
|
+
let retryable = (res.status === 429 || res.status === 503 || gateway) && (retryAfterMs ?? 0) <= MAX_RETRY_SLEEP_MS;
|
|
996
999
|
let body;
|
|
997
1000
|
if (retryable && res.status === 503 && !replayable && retryAfterMs === undefined) {
|
|
998
1001
|
body = await res.text().catch(() => "");
|
|
999
1002
|
retryable = REFUSED_503_CODES.has(errorCodeOf(body) ?? "");
|
|
1000
1003
|
}
|
|
1004
|
+
if (retryable && gateway) {
|
|
1005
|
+
body = await res.text().catch(() => "");
|
|
1006
|
+
retryable = errorCodeOf(body) === undefined;
|
|
1007
|
+
}
|
|
1001
1008
|
if (retryable && attempt < this.maxRetries) {
|
|
1002
1009
|
const backoff = Math.min(MAX_RETRY_SLEEP_MS, this.retryBaseMs * 2 ** attempt);
|
|
1003
1010
|
const jitter = Math.random();
|
|
@@ -1005,6 +1012,8 @@ class PromigenceClient {
|
|
|
1005
1012
|
? retryAfterMs + jitter * Math.min(250, this.retryBaseMs)
|
|
1006
1013
|
: backoff * (0.5 + jitter * 0.5);
|
|
1007
1014
|
this.stats.retries++;
|
|
1015
|
+
if (gateway && opts.method === "DELETE")
|
|
1016
|
+
resentDelete = true;
|
|
1008
1017
|
if (body === undefined)
|
|
1009
1018
|
try {
|
|
1010
1019
|
await res.text();
|
|
@@ -1291,6 +1300,14 @@ class PromigenceClient {
|
|
|
1291
1300
|
const r = await this.request({ method: "GET", path: `/me/ledger?${pageQuery(limit, 1000, opts.cursor)}` });
|
|
1292
1301
|
return pageOf(r, "entries", limit);
|
|
1293
1302
|
},
|
|
1303
|
+
historyPage: async (opts = {}) => {
|
|
1304
|
+
const limit = opts.limit ?? 50;
|
|
1305
|
+
const q = new URLSearchParams(pageQuery(limit, 100, opts.cursor));
|
|
1306
|
+
if (opts.kind !== undefined && opts.kind !== "all")
|
|
1307
|
+
q.set("kind", opts.kind);
|
|
1308
|
+
const r = await this.request({ method: "GET", path: `/billing/history?${q.toString()}` });
|
|
1309
|
+
return pageOf(r, "entries", limit);
|
|
1310
|
+
},
|
|
1294
1311
|
checkout: () => this.request({ method: "POST", path: "/billing/checkout", body: {} }),
|
|
1295
1312
|
portal: () => this.request({ method: "POST", path: "/billing/portal", body: {} }),
|
|
1296
1313
|
referrals: () => this.request({ method: "GET", path: "/referrals" }),
|
|
@@ -1785,6 +1802,10 @@ class PromigenceClient {
|
|
|
1785
1802
|
on.heartbeat?.();
|
|
1786
1803
|
continue;
|
|
1787
1804
|
}
|
|
1805
|
+
if (event === "reconnect") {
|
|
1806
|
+
reader.cancel().catch(() => { });
|
|
1807
|
+
throw new core_js_1.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.");
|
|
1808
|
+
}
|
|
1788
1809
|
let parsed = {};
|
|
1789
1810
|
try {
|
|
1790
1811
|
parsed = JSON.parse(data);
|
|
@@ -2020,6 +2041,9 @@ class PromigenceClient {
|
|
|
2020
2041
|
...(opts.onData ? { onData: opts.onData } : {}),
|
|
2021
2042
|
...(opts.onExit ? { onExit: opts.onExit } : {}),
|
|
2022
2043
|
...(opts.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }),
|
|
2044
|
+
...(opts.resume === undefined ? {} : { resume: opts.resume }),
|
|
2045
|
+
...(opts.reconnect === undefined ? {} : { reconnect: opts.reconnect }),
|
|
2046
|
+
...(opts.onReconnected ? { onReconnected: opts.onReconnected } : {}),
|
|
2023
2047
|
refuse: (status, text, retryAfter) => {
|
|
2024
2048
|
let payload = {};
|
|
2025
2049
|
try {
|
package/dist/cjs/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/cjs/core.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EXIT_BY_CODE = exports.NotReleasedError = exports.ApiError = exports.TimeoutError = exports.RateLimitError = exports.UnreachableError = exports.NotFoundError = exports.AuthError = exports.NotVerifiedError = exports.SpendCapError = exports.CommandExitError = exports.EnvFailedError = exports.PreviewsUnavailableError = exports.UnsupportedError = exports.InvalidArgumentError = exports.PromigenceError = exports.PREVIEWS_UNAVAILABLE = exports.FILE_PUT_CHUNK_BYTES = exports.MAX_OUTPUT_BYTES_DEFAULT = exports.IMAGE_BUILD_LIST_PRICE = exports.IMAGE_BUILD_TIMEOUT_MS = exports.WAIT_TIMEOUT_MS = exports.KEY_CONTACT = exports.DEFAULT_API_URL = exports.ERRORS_DOCS_URL = exports.DOCS_URL = exports.VERSION = void 0;
|
|
3
|
+
exports.EXIT_BY_CODE = exports.NotReleasedError = exports.ApiError = exports.ServiceRestartError = exports.TimeoutError = exports.RateLimitError = exports.UnreachableError = exports.NotFoundError = exports.AuthError = exports.NotVerifiedError = exports.SpendCapError = exports.CommandExitError = exports.EnvFailedError = exports.PreviewsUnavailableError = exports.UnsupportedError = exports.InvalidArgumentError = exports.PromigenceError = exports.PREVIEWS_UNAVAILABLE = exports.FILE_PUT_CHUNK_BYTES = exports.MAX_OUTPUT_BYTES_DEFAULT = exports.IMAGE_BUILD_LIST_PRICE = exports.IMAGE_BUILD_TIMEOUT_MS = exports.WAIT_TIMEOUT_MS = exports.KEY_CONTACT = exports.DEFAULT_API_URL = exports.ERRORS_DOCS_URL = exports.DOCS_URL = exports.VERSION = void 0;
|
|
4
4
|
exports.previewsFix = previewsFix;
|
|
5
5
|
exports.withPreviewsFix = withPreviewsFix;
|
|
6
6
|
exports.fixBeyondMessage = fixBeyondMessage;
|
|
7
7
|
exports.previewsOff = previewsOff;
|
|
8
8
|
exports.exitForCode = exitForCode;
|
|
9
9
|
const hint_js_1 = require("./hint.js");
|
|
10
|
-
exports.VERSION = "0.1.0-beta.
|
|
10
|
+
exports.VERSION = "0.1.0-beta.9";
|
|
11
11
|
exports.DOCS_URL = "https://promigence.ai";
|
|
12
12
|
exports.ERRORS_DOCS_URL = "https://www.promigence.ai/docs/errors";
|
|
13
13
|
exports.DEFAULT_API_URL = "https://api.promigence.ai/v1";
|
|
14
14
|
exports.KEY_CONTACT = "support@promigence.ai";
|
|
15
15
|
exports.WAIT_TIMEOUT_MS = 100_000;
|
|
16
16
|
exports.IMAGE_BUILD_TIMEOUT_MS = 15 * 60_000;
|
|
17
|
-
exports.IMAGE_BUILD_LIST_PRICE =
|
|
17
|
+
exports.IMAGE_BUILD_LIST_PRICE = 0.1656;
|
|
18
18
|
exports.MAX_OUTPUT_BYTES_DEFAULT = 64 * 1024;
|
|
19
19
|
exports.FILE_PUT_CHUNK_BYTES = 16 * 1024 * 1024;
|
|
20
20
|
const PREVIEWS_OFF = /^previews are not enabled on this deployment\.?$/i;
|
|
@@ -215,6 +215,12 @@ class TimeoutError extends PromigenceError {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
exports.TimeoutError = TimeoutError;
|
|
218
|
+
class ServiceRestartError extends PromigenceError {
|
|
219
|
+
constructor(message, fix) {
|
|
220
|
+
super({ code: "service_restart", message, fix, exitCode: 3, category: "env", retryable: false });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports.ServiceRestartError = ServiceRestartError;
|
|
218
224
|
class ApiError extends PromigenceError {
|
|
219
225
|
}
|
|
220
226
|
exports.ApiError = ApiError;
|
|
@@ -233,6 +239,7 @@ exports.EXIT_BY_CODE = {
|
|
|
233
239
|
invalid_argument: 2, unsupported: 2, not_released: 1, task_failed: 4,
|
|
234
240
|
env_failed: 3, snapshot_rejected: 6, build_failed: 3, snapshot_failed: 4,
|
|
235
241
|
not_connected: 7,
|
|
242
|
+
service_restart: 3,
|
|
236
243
|
fork_failed: 3, start_timeout: 3, readiness_failed: 3, verify_too_slow: 3,
|
|
237
244
|
verify_each_failed: 3, toolchain_mismatch: 3, sandbox_unresponsive: 3, oom_within_tier: 3,
|
|
238
245
|
disk_full_within_tier: 3, sandbox_interrupted: 3, integrity_mismatch: 3, egress_unavailable: 3,
|
|
@@ -259,10 +266,11 @@ exports.EXIT_BY_CODE = {
|
|
|
259
266
|
build_timeout: 4,
|
|
260
267
|
image_unresolvable: 2,
|
|
261
268
|
registry_unavailable: 3,
|
|
262
|
-
trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached:
|
|
269
|
+
trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached: 5,
|
|
263
270
|
billing_unavailable: 5,
|
|
264
271
|
project_cap_reached: 5,
|
|
265
272
|
spend_limit_reached: 5,
|
|
273
|
+
billing_hold: 5,
|
|
266
274
|
tier_over_plan: 2,
|
|
267
275
|
network_host_refused: 9, network_policy_unsupported: 3,
|
|
268
276
|
secrets_in_snapshot: 2, secrets_unavailable: 3,
|
package/dist/cjs/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/cjs/credstore.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.keychainCacheSet = keychainCacheSet;
|
|
|
13
13
|
exports.forgetKeychainReads = forgetKeychainReads;
|
|
14
14
|
const node_child_process_1 = require("node:child_process");
|
|
15
15
|
const node_fs_1 = require("node:fs");
|
|
16
|
+
const node_os_1 = require("node:os");
|
|
16
17
|
const node_path_1 = require("node:path");
|
|
17
18
|
exports.KEYCHAIN_SERVICE = "promigence-cli";
|
|
18
19
|
const KEYCHAIN_LABEL = "Promigence CLI credentials";
|
|
@@ -43,8 +44,19 @@ function sessionBus(env) {
|
|
|
43
44
|
const run = env["XDG_RUNTIME_DIR"];
|
|
44
45
|
return Boolean(run) && (0, node_fs_1.existsSync)((0, node_path_1.join)(run, "bus"));
|
|
45
46
|
}
|
|
47
|
+
function userHome(env, home = node_os_1.homedir) {
|
|
48
|
+
const h = env["HOME"];
|
|
49
|
+
if (h)
|
|
50
|
+
return h;
|
|
51
|
+
try {
|
|
52
|
+
return home() || undefined;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
46
58
|
const warnedSetting = new Set();
|
|
47
|
-
function keychainStore(env = process.env, platform = process.platform) {
|
|
59
|
+
function keychainStore(env = process.env, platform = process.platform, home = node_os_1.homedir) {
|
|
48
60
|
const raw = (env["PROMIGENCE_CREDENTIAL_STORE"] ?? "").trim().toLowerCase();
|
|
49
61
|
switch (raw) {
|
|
50
62
|
case "file": return undefined;
|
|
@@ -59,8 +71,8 @@ function keychainStore(env = process.env, platform = process.platform) {
|
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
73
|
if (platform === "darwin") {
|
|
62
|
-
const
|
|
63
|
-
return
|
|
74
|
+
const h = userHome(env, home);
|
|
75
|
+
return h && (0, node_fs_1.existsSync)((0, node_path_1.join)(h, "Library", "Keychains")) && onPath("security", env) ? "macos-keychain" : undefined;
|
|
64
76
|
}
|
|
65
77
|
if (platform === "win32")
|
|
66
78
|
return undefined;
|
|
@@ -107,8 +119,9 @@ function runTool(store, args, env, input, timeout) {
|
|
|
107
119
|
const bin = onPath(toolName(store), env);
|
|
108
120
|
if (bin === undefined)
|
|
109
121
|
throw Object.assign(new Error(`${toolName(store)} not found`), { code: "ENOENT" });
|
|
122
|
+
const h = store === "macos-keychain" && !env["HOME"] ? userHome(env) : undefined;
|
|
110
123
|
return (0, node_child_process_1.execFileSync)(bin, args, {
|
|
111
|
-
encoding: "utf8", timeout, env,
|
|
124
|
+
encoding: "utf8", timeout, env: h ? { ...env, HOME: h } : env,
|
|
112
125
|
...(input === undefined ? { stdio: ["ignore", "pipe", "pipe"] } : { input, stdio: ["pipe", "pipe", "pipe"] }),
|
|
113
126
|
});
|
|
114
127
|
}
|
package/dist/cjs/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/cjs/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;
|