@promigence/sdk 0.1.0-beta.7 → 0.1.0-beta.8
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 +38 -0
- package/dist/cjs/client.js +28 -12
- package/dist/cjs/core.d.ts +10 -1
- package/dist/cjs/core.js +11 -3
- package/dist/cjs/credstore.d.ts +3 -2
- package/dist/cjs/credstore.js +17 -4
- package/dist/cjs/models.gen.d.ts +148 -6
- 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 +32 -0
- package/dist/cjs/sandbox.js +3 -0
- package/dist/cjs/ssh.js +1 -0
- package/dist/client.d.ts +38 -0
- package/dist/client.js +29 -13
- package/dist/core.d.ts +10 -1
- package/dist/core.js +9 -2
- package/dist/credstore.d.ts +3 -2
- package/dist/credstore.js +17 -4
- package/dist/models.gen.d.ts +148 -6
- package/dist/proxy.js +2 -1
- package/dist/pty.d.ts +65 -3
- package/dist/pty.js +269 -33
- package/dist/sandbox.d.ts +32 -0
- package/dist/sandbox.js +3 -0
- 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
|
@@ -748,6 +748,8 @@ export interface CreditOffer {
|
|
|
748
748
|
state: string;
|
|
749
749
|
credit_usd: number;
|
|
750
750
|
card_bonus_usd: number;
|
|
751
|
+
/** USD charged to confirm Apple Pay, Google Pay or Amazon Pay when one is added (added to the credit). */
|
|
752
|
+
method_check_usd?: number;
|
|
751
753
|
expires_at?: string | null;
|
|
752
754
|
campaign?: string | null;
|
|
753
755
|
message: string;
|
|
@@ -906,6 +908,16 @@ export interface BillingUsage {
|
|
|
906
908
|
brand?: string;
|
|
907
909
|
last4?: string;
|
|
908
910
|
} | null;
|
|
911
|
+
/** Set when the card on file does not unlock paid limits for this organization (it already pays for another one,
|
|
912
|
+
* it is being confirmed with a $1 charge, or that charge did not go through). */
|
|
913
|
+
card_note?: string | null;
|
|
914
|
+
/** The $1 that confirms Apple Pay, Google Pay or Amazon Pay on file: `confirming`, `paid` or `failed`. */
|
|
915
|
+
method_check?: {
|
|
916
|
+
method: string;
|
|
917
|
+
status: string;
|
|
918
|
+
amount_usd: number;
|
|
919
|
+
bonus_usd?: number | null;
|
|
920
|
+
} | null;
|
|
909
921
|
suspended?: boolean;
|
|
910
922
|
suspend_reason?: string | null;
|
|
911
923
|
period?: {
|
|
@@ -929,6 +941,10 @@ export interface BillingUsage {
|
|
|
929
941
|
upcoming_invoice_error?: string | null;
|
|
930
942
|
[extra: string]: unknown;
|
|
931
943
|
}
|
|
944
|
+
/** One row of `GET /billing/history`: a credit the organization received, or a payment. */
|
|
945
|
+
export type BillingHistoryEntry = M.BillingHistoryEntry;
|
|
946
|
+
/** What `billing.historyPage()` lists: everything, only credits, or only payments. */
|
|
947
|
+
export type BillingHistoryKind = "all" | "credits" | "payments";
|
|
932
948
|
/** One metered row of `GET /me/ledger`. */
|
|
933
949
|
export interface LedgerEntry {
|
|
934
950
|
entry_id: string;
|
|
@@ -2033,6 +2049,16 @@ export declare class PromigenceClient {
|
|
|
2033
2049
|
limit?: number;
|
|
2034
2050
|
cursor?: string;
|
|
2035
2051
|
}) => Promise<Page<LedgerEntry>>;
|
|
2052
|
+
/**
|
|
2053
|
+
* `GET /billing/history` — the credits the organization received and its payments, newest
|
|
2054
|
+
* first (one page). `kind` narrows it to `credits` or `payments`; feed `nextCursor` back as
|
|
2055
|
+
* `cursor` until it is `null`. An owner's key.
|
|
2056
|
+
*/
|
|
2057
|
+
historyPage: (opts?: {
|
|
2058
|
+
kind?: BillingHistoryKind;
|
|
2059
|
+
limit?: number;
|
|
2060
|
+
cursor?: string;
|
|
2061
|
+
}) => Promise<Page<BillingHistoryEntry>>;
|
|
2036
2062
|
/** `POST /billing/checkout` — the hosted page that puts a card on file. */
|
|
2037
2063
|
checkout: () => Promise<{
|
|
2038
2064
|
url: string;
|
|
@@ -2433,6 +2459,18 @@ export declare class PromigenceClient {
|
|
|
2433
2459
|
onData?: (data: Uint8Array) => void;
|
|
2434
2460
|
onExit?: (exit: PtyExit) => void;
|
|
2435
2461
|
timeoutMs?: number;
|
|
2462
|
+
/** Pick the same terminal up again when its connection drops or the service is updated;
|
|
2463
|
+
* see `PtyConnectOpts.resume`. Default: on. */
|
|
2464
|
+
resume?: boolean;
|
|
2465
|
+
/** Reconnect in a new shell when the service is updated (a WebSocket `Close` 1012) and the
|
|
2466
|
+
* terminal cannot be picked up again; see `PtyConnectOpts.reconnect`. Default: on without
|
|
2467
|
+
* `cmd`, off with one. */
|
|
2468
|
+
reconnect?: boolean;
|
|
2469
|
+
/** Called after each reconnect: `resumed` says whether it is the same terminal or a new
|
|
2470
|
+
* shell. */
|
|
2471
|
+
onReconnected?: (how: {
|
|
2472
|
+
resumed: boolean;
|
|
2473
|
+
}) => void;
|
|
2436
2474
|
}) => Promise<PtySession>;
|
|
2437
2475
|
/** `GET /sandboxes/:id`. */
|
|
2438
2476
|
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));
|
|
@@ -1291,6 +1292,14 @@ class PromigenceClient {
|
|
|
1291
1292
|
const r = await this.request({ method: "GET", path: `/me/ledger?${pageQuery(limit, 1000, opts.cursor)}` });
|
|
1292
1293
|
return pageOf(r, "entries", limit);
|
|
1293
1294
|
},
|
|
1295
|
+
historyPage: async (opts = {}) => {
|
|
1296
|
+
const limit = opts.limit ?? 50;
|
|
1297
|
+
const q = new URLSearchParams(pageQuery(limit, 100, opts.cursor));
|
|
1298
|
+
if (opts.kind !== undefined && opts.kind !== "all")
|
|
1299
|
+
q.set("kind", opts.kind);
|
|
1300
|
+
const r = await this.request({ method: "GET", path: `/billing/history?${q.toString()}` });
|
|
1301
|
+
return pageOf(r, "entries", limit);
|
|
1302
|
+
},
|
|
1294
1303
|
checkout: () => this.request({ method: "POST", path: "/billing/checkout", body: {} }),
|
|
1295
1304
|
portal: () => this.request({ method: "POST", path: "/billing/portal", body: {} }),
|
|
1296
1305
|
referrals: () => this.request({ method: "GET", path: "/referrals" }),
|
|
@@ -1785,6 +1794,10 @@ class PromigenceClient {
|
|
|
1785
1794
|
on.heartbeat?.();
|
|
1786
1795
|
continue;
|
|
1787
1796
|
}
|
|
1797
|
+
if (event === "reconnect") {
|
|
1798
|
+
reader.cancel().catch(() => { });
|
|
1799
|
+
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.");
|
|
1800
|
+
}
|
|
1788
1801
|
let parsed = {};
|
|
1789
1802
|
try {
|
|
1790
1803
|
parsed = JSON.parse(data);
|
|
@@ -2020,6 +2033,9 @@ class PromigenceClient {
|
|
|
2020
2033
|
...(opts.onData ? { onData: opts.onData } : {}),
|
|
2021
2034
|
...(opts.onExit ? { onExit: opts.onExit } : {}),
|
|
2022
2035
|
...(opts.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }),
|
|
2036
|
+
...(opts.resume === undefined ? {} : { resume: opts.resume }),
|
|
2037
|
+
...(opts.reconnect === undefined ? {} : { reconnect: opts.reconnect }),
|
|
2038
|
+
...(opts.onReconnected ? { onReconnected: opts.onReconnected } : {}),
|
|
2023
2039
|
refuse: (status, text, retryAfter) => {
|
|
2024
2040
|
let payload = {};
|
|
2025
2041
|
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.8";
|
|
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";
|
|
@@ -190,6 +190,15 @@ export declare class TimeoutError extends PromigenceError {
|
|
|
190
190
|
runId?: string;
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* A service update may stop a command that was running while its output was streaming to you
|
|
195
|
+
* (`execStream`, `commands.run` with output callbacks); the time it ran is credited back, and the
|
|
196
|
+
* sandbox keeps running. `retryable` is `false`: the command may have done part of its work before
|
|
197
|
+
* it stopped, so run it again only if that is safe. exit 3
|
|
198
|
+
*/
|
|
199
|
+
export declare class ServiceRestartError extends PromigenceError {
|
|
200
|
+
constructor(message: string, fix: string);
|
|
201
|
+
}
|
|
193
202
|
/** An API error with no more specific class (5xx, unknown code). exit from the table. */
|
|
194
203
|
export declare class ApiError extends PromigenceError {
|
|
195
204
|
}
|
package/dist/cjs/core.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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.8";
|
|
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";
|
|
@@ -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/models.gen.d.ts
CHANGED
|
@@ -243,6 +243,36 @@ export interface BackgroundExecList {
|
|
|
243
243
|
execs: Array<BackgroundExec>;
|
|
244
244
|
sandbox_id: string;
|
|
245
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* `GET /v1/billing/history` — your billing history, newest first: every credit you received and
|
|
248
|
+
* every payment, one page at a time.
|
|
249
|
+
*/
|
|
250
|
+
export interface BillingHistory {
|
|
251
|
+
entries: Array<BillingHistoryEntry>;
|
|
252
|
+
/**
|
|
253
|
+
* Pass as `cursor` for the next, older page; `null` on the last page.
|
|
254
|
+
*/
|
|
255
|
+
next_cursor?: string | null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* One entry of your billing history: a credit you received or a payment. Exactly one of
|
|
259
|
+
* `credit` and `payment` is set.
|
|
260
|
+
*/
|
|
261
|
+
export interface BillingHistoryEntry {
|
|
262
|
+
/**
|
|
263
|
+
* When it happened, RFC 3339: when a credit was added, when a payment was made, failed or
|
|
264
|
+
* was refunded.
|
|
265
|
+
*/
|
|
266
|
+
at: string;
|
|
267
|
+
/**
|
|
268
|
+
* A credit you received; `null` for a payment.
|
|
269
|
+
*/
|
|
270
|
+
credit?: CreditGrant | null;
|
|
271
|
+
/**
|
|
272
|
+
* A payment; `null` for a credit.
|
|
273
|
+
*/
|
|
274
|
+
payment?: Payment | null;
|
|
275
|
+
}
|
|
246
276
|
/**
|
|
247
277
|
* The billing period `usage` covers.
|
|
248
278
|
*/
|
|
@@ -261,9 +291,9 @@ export interface BillingPeriod {
|
|
|
261
291
|
start: string;
|
|
262
292
|
}
|
|
263
293
|
/**
|
|
264
|
-
* `GET /v1/billing` — plan, card on file, this month's usage, and the upcoming invoice
|
|
265
|
-
*
|
|
266
|
-
*
|
|
294
|
+
* `GET /v1/billing` — plan, card on file, this month's usage, and the upcoming invoice preview.
|
|
295
|
+
* Never fails because the payment provider is slow: the estimate is the only part that asks it,
|
|
296
|
+
* and its failure is a field, not a status.
|
|
267
297
|
*/
|
|
268
298
|
export interface BillingStatus {
|
|
269
299
|
/**
|
|
@@ -274,11 +304,22 @@ export interface BillingStatus {
|
|
|
274
304
|
* `null` while no card is on file.
|
|
275
305
|
*/
|
|
276
306
|
card?: CardOnFile | null;
|
|
307
|
+
/**
|
|
308
|
+
* A sentence to show beside the card when it does not unlock paid limits for this
|
|
309
|
+
* organization (it already pays for another one, or it is being confirmed with a $1 charge, or
|
|
310
|
+
* that charge did not go through); `null` otherwise.
|
|
311
|
+
*/
|
|
312
|
+
card_note?: string | null;
|
|
277
313
|
card_on_file: boolean;
|
|
278
314
|
/**
|
|
279
315
|
* True once a billing customer exists for the organisation.
|
|
280
316
|
*/
|
|
281
317
|
customer: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* The $1 that confirms the payment method on file when it has no stable payer (Apple Pay,
|
|
320
|
+
* Google Pay, Amazon Pay); `null` when it needed none.
|
|
321
|
+
*/
|
|
322
|
+
method_check?: MethodCheckView | null;
|
|
282
323
|
notice?: TrialNotice | null;
|
|
283
324
|
org_id: string;
|
|
284
325
|
period: BillingPeriod;
|
|
@@ -830,7 +871,7 @@ export interface CliTokenCreate {
|
|
|
830
871
|
/**
|
|
831
872
|
* Every error and failure code the API returns.
|
|
832
873
|
*/
|
|
833
|
-
export type Code = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "capacity_busy" | "verify_did_not_cover" | "nonzero_exit" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "cap_killed" | "cap_exceeded" | "aborted_by_client" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "enoent" | "trial_credits_exhausted" | "card_required" | "concurrency_limit" | "egress_cap_reached" | "network_policy_unsupported" | "network_host_refused" | "toolchain_mismatch" | "resume_unavailable" | "sandbox_unreachable" | "region_at_capacity" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "builder_unavailable" | "builder_busy" | "overloaded" | "preempted" | "grader_failed" | "grade_not_passed" | "shutdown_by_task" | "modified_by_task" | "cap_paused" | "credits_paused" | "stopped_by_support" | "forbidden" | "snapshot_incompatible" | "storage_limit_reached" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "credit_unclaimed" | "billing_unavailable" | "project_cap_reached" | "spend_limit_reached" | "tier_over_plan" | "secrets_in_snapshot" | "secrets_unavailable" | "secret_binding_unsupported" | "idempotency_key_reused" | "idempotency_key_in_use" | "repo_credentials_not_supported" | "account_exists" | "invite_invalid" | "invite_required" | "key_expired" | "account_blocked" | "setup_required";
|
|
874
|
+
export type Code = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "capacity_busy" | "verify_did_not_cover" | "nonzero_exit" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "cap_killed" | "cap_exceeded" | "aborted_by_client" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "enoent" | "trial_credits_exhausted" | "card_required" | "concurrency_limit" | "egress_cap_reached" | "network_policy_unsupported" | "network_host_refused" | "toolchain_mismatch" | "resume_unavailable" | "sandbox_unreachable" | "region_at_capacity" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "builder_unavailable" | "builder_busy" | "overloaded" | "preempted" | "grader_failed" | "grade_not_passed" | "shutdown_by_task" | "modified_by_task" | "cap_paused" | "credits_paused" | "stopped_by_support" | "forbidden" | "snapshot_incompatible" | "storage_limit_reached" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "credit_unclaimed" | "billing_unavailable" | "project_cap_reached" | "spend_limit_reached" | "billing_hold" | "tier_over_plan" | "secrets_in_snapshot" | "secrets_unavailable" | "secret_binding_unsupported" | "idempotency_key_reused" | "idempotency_key_in_use" | "repo_credentials_not_supported" | "account_exists" | "invite_invalid" | "invite_required" | "key_expired" | "account_blocked" | "setup_required";
|
|
834
875
|
export interface Concurrency {
|
|
835
876
|
}
|
|
836
877
|
/**
|
|
@@ -916,6 +957,41 @@ export interface CreditClaim {
|
|
|
916
957
|
terms_version?: string | null;
|
|
917
958
|
token?: string | null;
|
|
918
959
|
}
|
|
960
|
+
/**
|
|
961
|
+
* A credit your organization received, and what is left of it.
|
|
962
|
+
*/
|
|
963
|
+
export interface CreditGrant {
|
|
964
|
+
/**
|
|
965
|
+
* When it expires, RFC 3339; `null` when it never expires.
|
|
966
|
+
*/
|
|
967
|
+
expires_at?: string | null;
|
|
968
|
+
/**
|
|
969
|
+
* When it was added, RFC 3339.
|
|
970
|
+
*/
|
|
971
|
+
granted_at: string;
|
|
972
|
+
/**
|
|
973
|
+
* USD.
|
|
974
|
+
*/
|
|
975
|
+
granted_usd: number;
|
|
976
|
+
/**
|
|
977
|
+
* What it is: `free_credit` (the free credit), `card_bonus` (credit for adding a card),
|
|
978
|
+
* `referral` (a referral reward), `plan` (usage included with a paid plan),
|
|
979
|
+
* `from_promigence` (credit Promigence added to your account), `service_restart` (credit
|
|
980
|
+
* for a command a service restart stopped), `confirmation_credit` (a $1 charge that
|
|
981
|
+
* confirmed a payment method, added back as credit), or `other`.
|
|
982
|
+
*/
|
|
983
|
+
kind: string;
|
|
984
|
+
/**
|
|
985
|
+
* What is left of it, USD: 0 once it is used, expired or taken back. Credit that expires
|
|
986
|
+
* soonest is used first, and credit that never expires last.
|
|
987
|
+
*/
|
|
988
|
+
remaining_usd: number;
|
|
989
|
+
/**
|
|
990
|
+
* `active` (some of it is left), `used` (all of it was used), `expired` (it expired before
|
|
991
|
+
* all of it was used), or `taken_back`.
|
|
992
|
+
*/
|
|
993
|
+
status: string;
|
|
994
|
+
}
|
|
919
995
|
/**
|
|
920
996
|
* The account's free credit (`GET /v1/credits/offer`, and the answer to a claim). The credit is
|
|
921
997
|
* claimed in the browser, where the terms are accepted: `POST /v1/credits/claim-link` makes the
|
|
@@ -942,6 +1018,11 @@ export interface CreditOffer {
|
|
|
942
1018
|
* One sentence for a person.
|
|
943
1019
|
*/
|
|
944
1020
|
message: string;
|
|
1021
|
+
/**
|
|
1022
|
+
* USD charged to confirm a payment method with no stable payer when it is added (Apple Pay,
|
|
1023
|
+
* Google Pay, Amazon Pay): it is added to your credit, and the card bonus comes with it.
|
|
1024
|
+
*/
|
|
1025
|
+
method_check_usd?: number;
|
|
945
1026
|
/**
|
|
946
1027
|
* `claimable`, `claimed`, `pending_review`, `needs_card`, `not_eligible`, `offer_ended`,
|
|
947
1028
|
* `denied` or `none`.
|
|
@@ -1075,7 +1156,7 @@ export interface ErrorBody {
|
|
|
1075
1156
|
/**
|
|
1076
1157
|
* Every error code the API returns. `category` decides whether the failure is billed: `env` is ours (not billed before hand-over; after it, the time since the sandbox's last snapshot is credited back, up to 24 hours, when our side shows the cause), `task` is your command and is billed. The full table is `x-promigence-error-codes` at the document root.
|
|
1077
1158
|
*/
|
|
1078
|
-
export type ErrorCode = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "toolchain_mismatch" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "preempted" | "verify_did_not_cover" | "grader_failed" | "nonzero_exit" | "grade_not_passed" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "shutdown_by_task" | "modified_by_task" | "cap_killed" | "cap_exceeded" | "cap_paused" | "credits_paused" | "aborted_by_client" | "stopped_by_support" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "forbidden" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "snapshot_incompatible" | "storage_limit_reached" | "resume_unavailable" | "sandbox_unreachable" | "capacity_busy" | "region_at_capacity" | "builder_unavailable" | "builder_busy" | "overloaded" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "enoent" | "trial_credits_exhausted" | "credit_unclaimed" | "setup_required" | "card_required" | "billing_unavailable" | "concurrency_limit" | "egress_cap_reached" | "project_cap_reached" | "spend_limit_reached" | "tier_over_plan" | "network_host_refused" | "network_policy_unsupported" | "secrets_in_snapshot" | "secrets_unavailable" | "secret_binding_unsupported" | "idempotency_key_reused" | "idempotency_key_in_use" | "repo_credentials_not_supported" | "account_exists" | "invite_invalid" | "invite_required" | "key_expired" | "account_blocked";
|
|
1159
|
+
export type ErrorCode = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "toolchain_mismatch" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "preempted" | "verify_did_not_cover" | "grader_failed" | "nonzero_exit" | "grade_not_passed" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "shutdown_by_task" | "modified_by_task" | "cap_killed" | "cap_exceeded" | "cap_paused" | "credits_paused" | "aborted_by_client" | "stopped_by_support" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "forbidden" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "snapshot_incompatible" | "storage_limit_reached" | "resume_unavailable" | "sandbox_unreachable" | "capacity_busy" | "region_at_capacity" | "builder_unavailable" | "builder_busy" | "overloaded" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "enoent" | "trial_credits_exhausted" | "credit_unclaimed" | "setup_required" | "card_required" | "billing_unavailable" | "concurrency_limit" | "egress_cap_reached" | "project_cap_reached" | "spend_limit_reached" | "billing_hold" | "tier_over_plan" | "network_host_refused" | "network_policy_unsupported" | "secrets_in_snapshot" | "secrets_unavailable" | "secret_binding_unsupported" | "idempotency_key_reused" | "idempotency_key_in_use" | "repo_credentials_not_supported" | "account_exists" | "invite_invalid" | "invite_required" | "key_expired" | "account_blocked";
|
|
1079
1160
|
/**
|
|
1080
1161
|
* `POST /v1/sandboxes/{id}/execs`, and the `exec` of `POST /v1/runs`: one command. `argv` (a
|
|
1081
1162
|
* non-empty list) or `sh` (a shell line) is required.
|
|
@@ -2547,6 +2628,29 @@ export interface MemberView {
|
|
|
2547
2628
|
*/
|
|
2548
2629
|
you: boolean;
|
|
2549
2630
|
}
|
|
2631
|
+
/**
|
|
2632
|
+
* The $1 charged to confirm a payment method with no stable payer (`GET /v1/billing`
|
|
2633
|
+
* `method_check`).
|
|
2634
|
+
*/
|
|
2635
|
+
export interface MethodCheckView {
|
|
2636
|
+
/**
|
|
2637
|
+
* USD charged; added to your credit once paid.
|
|
2638
|
+
*/
|
|
2639
|
+
amount_usd: number;
|
|
2640
|
+
/**
|
|
2641
|
+
* USD of credit that came with it (the card bonus), once paid; `null` otherwise.
|
|
2642
|
+
*/
|
|
2643
|
+
bonus_usd?: number | null;
|
|
2644
|
+
/**
|
|
2645
|
+
* The method as a person reads it: `Apple Pay`, `Google Pay`, `Amazon Pay`, ...
|
|
2646
|
+
*/
|
|
2647
|
+
method: string;
|
|
2648
|
+
/**
|
|
2649
|
+
* `confirming` (charged, its answer not in yet), `paid` (it counts as your payment method) or
|
|
2650
|
+
* `failed` (declined, or it needed you there to approve it: it does not count; add a card).
|
|
2651
|
+
*/
|
|
2652
|
+
status: string;
|
|
2653
|
+
}
|
|
2550
2654
|
/**
|
|
2551
2655
|
* `POST /v1/orgs` and `POST /v1/orgs/{org}/projects`.
|
|
2552
2656
|
*/
|
|
@@ -2814,6 +2918,44 @@ export interface ParkedBytes {
|
|
|
2814
2918
|
*/
|
|
2815
2919
|
allocated: number;
|
|
2816
2920
|
}
|
|
2921
|
+
/**
|
|
2922
|
+
* A payment: an invoice paid, a payment that failed, a refund, or the charge that confirmed a
|
|
2923
|
+
* payment method.
|
|
2924
|
+
*/
|
|
2925
|
+
export interface Payment {
|
|
2926
|
+
/**
|
|
2927
|
+
* USD: what was paid, what was due, what was refunded, or what confirmed the method.
|
|
2928
|
+
*/
|
|
2929
|
+
amount_usd: number;
|
|
2930
|
+
/**
|
|
2931
|
+
* The invoice's number, as the invoice shows it; `null` when not known.
|
|
2932
|
+
*/
|
|
2933
|
+
invoice_number?: string | null;
|
|
2934
|
+
/**
|
|
2935
|
+
* The invoice's page: its receipt once it is paid, where to pay it while a payment has
|
|
2936
|
+
* failed; `null` when not known.
|
|
2937
|
+
*/
|
|
2938
|
+
invoice_url?: string | null;
|
|
2939
|
+
/**
|
|
2940
|
+
* `invoice_paid`, `payment_failed`, `refund`, or `method_check` (a charge, usually $1, that
|
|
2941
|
+
* confirmed a payment method; it comes back as credit).
|
|
2942
|
+
*/
|
|
2943
|
+
kind: string;
|
|
2944
|
+
/**
|
|
2945
|
+
* `method_check`: the payment method it confirmed, by name (`Apple Pay`); `null` otherwise.
|
|
2946
|
+
*/
|
|
2947
|
+
method?: string | null;
|
|
2948
|
+
/**
|
|
2949
|
+
* The plan whose fee the invoice billed; `null` when it billed usage alone.
|
|
2950
|
+
*/
|
|
2951
|
+
plan?: string | null;
|
|
2952
|
+
/**
|
|
2953
|
+
* `paid` (for a payment that failed: paid since), `retrying` (it failed and will be tried
|
|
2954
|
+
* again), `failed` (it failed and will not be tried again; for `method_check`, the method
|
|
2955
|
+
* was not confirmed), `refunded`, or `confirmed` (`method_check`: the method is confirmed).
|
|
2956
|
+
*/
|
|
2957
|
+
status: string;
|
|
2958
|
+
}
|
|
2817
2959
|
export interface Percentiles {
|
|
2818
2960
|
p50: number;
|
|
2819
2961
|
p95: number;
|
|
@@ -4502,7 +4644,7 @@ export interface SandboxView {
|
|
|
4502
4644
|
*/
|
|
4503
4645
|
outcome?: string | null;
|
|
4504
4646
|
/**
|
|
4505
|
-
* While it is paused: when it will be deleted, with its
|
|
4647
|
+
* While it is paused: when it will be deleted, with its files and state, unless it is
|
|
4506
4648
|
* resumed before then (RFC 3339). A paused sandbox is kept for 30 days, and resuming it
|
|
4507
4649
|
* starts the 30 days again. Absent while it is not paused, and for a paused sandbox that is
|
|
4508
4650
|
* not due to be deleted.
|
package/dist/cjs/proxy.js
CHANGED
|
@@ -205,8 +205,9 @@ function requestVia(url, options, env = process.env) {
|
|
|
205
205
|
connect.end();
|
|
206
206
|
return undefined;
|
|
207
207
|
};
|
|
208
|
+
const { agent: _agent, ...direct } = options;
|
|
208
209
|
return (0, node_https_1.request)(url, {
|
|
209
|
-
...
|
|
210
|
+
...direct,
|
|
210
211
|
createConnection: createConnection,
|
|
211
212
|
});
|
|
212
213
|
}
|