@jini-ai/platform 0.1.1 → 0.3.0
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 +88 -0
- package/dist/fetch-with-timeout.d.ts +105 -0
- package/dist/fetch-with-timeout.d.ts.map +1 -0
- package/dist/fetch-with-timeout.js +121 -0
- package/dist/fetch-with-timeout.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +10 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +11 -3
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# `@jini-ai/platform`
|
|
2
|
+
|
|
3
|
+
Generic OS/platform primitives: process exec and lifecycle, filesystem containment, HTTP
|
|
4
|
+
readiness polling, toolchain discovery, blob storage, AWS signing, and an SSRF-safe asset cache.
|
|
5
|
+
This is the Node-only substrate a daemon host needs to spawn and supervise child processes, wait
|
|
6
|
+
for a port to come up, resolve a user's installed toolchains, manage terminal (PTY) sessions, and
|
|
7
|
+
store blobs — all without depending on `@jini-ai/daemon` or any product code. Ported mostly
|
|
8
|
+
verbatim from Open Design's own `packages/platform` plus several generic daemon-support files
|
|
9
|
+
that were split out of OD's monolithic daemon (see `source-map.md` for the full per-file trail).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @jini-ai/platform
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
No peer dependencies. `undici` is a regular dependency (used by the SSRF-safe asset cache's
|
|
18
|
+
connection-time DNS-rebinding guard). Interactive terminal sessions (`createTerminalService`)
|
|
19
|
+
need a `PtySpawn` implementation supplied by the caller — this package defines the `PtyProcess`/
|
|
20
|
+
`PtySpawn` port only, it does not depend on `node-pty` itself, so bring your own adapter (or use
|
|
21
|
+
`@jini-ai/daemon`'s, which wires a real `node-pty` behind the same port).
|
|
22
|
+
|
|
23
|
+
## What you get
|
|
24
|
+
|
|
25
|
+
- **Process lifecycle** — `spawnBackgroundProcess`, `spawnLoggedProcess`, `stopProcesses`,
|
|
26
|
+
`waitForProcessExit`, `isProcessAlive`, `listProcessSnapshots`, process-stamp encode/match
|
|
27
|
+
helpers (`createProcessStampArgs`, `readProcessStamp`, `matchesProcessStamp`).
|
|
28
|
+
- **Command construction** — `createCommandInvocation`, `createPackageManagerInvocation`
|
|
29
|
+
(cross-platform `.bat`/`.cmd` shim quoting).
|
|
30
|
+
- **Shell execution** — `execFileBuffered`, `execCommandViaLoginShell` (re-enters the login shell
|
|
31
|
+
so profile-only `PATH` entries are visible).
|
|
32
|
+
- **Filesystem** — `pathContains`, `atomicCopyFile`, `removePathBestEffort`, `readLogTail`.
|
|
33
|
+
- **HTTP readiness** — `waitForHttpOk`.
|
|
34
|
+
- **Toolchain discovery** — `wellKnownUserToolchainBins` (npm/pnpm/bun/cargo/deno/go/pyenv,
|
|
35
|
+
asdf/volta/mise/nvm/fnm shims).
|
|
36
|
+
- **Proxy-aware env** — `resolveSystemProxyEnv`, `mergeProxyAwareEnv` (macOS `scutil` / Windows
|
|
37
|
+
registry discovery).
|
|
38
|
+
- **Sandboxed execution env** — `resolveSandboxRuntimeConfig(FromEnv)`, `ensureSandboxRuntimeDirs`,
|
|
39
|
+
`applySandboxRuntimeEnv`, `isSandboxModeEnabled`.
|
|
40
|
+
- **Resource paths** — `resolveDaemonCliPath`, `resolveDaemonResourceRoot`, `resolveDataDir`,
|
|
41
|
+
`resolveProcessResourcesPath` — daemon CLI/resource-root/data-dir resolution for a packaged app.
|
|
42
|
+
- **Terminal sessions** — `createTerminalService` (in-memory PTY session manager: spawn, write,
|
|
43
|
+
resize, kill, `attach`/`detach` transport-neutral streaming via `TerminalSseSink`).
|
|
44
|
+
- **Managed downloads** — `managedDownload`, `inspectManagedDownload`, `pruneManagedDownloads`,
|
|
45
|
+
`downloadCopyAndClear` (atomic, resumable, checksum-verified, with cross-process locking and
|
|
46
|
+
retention pruning).
|
|
47
|
+
- **AWS SigV4 signing** — `signSigV4`, `encodeS3PathSegment` (no `@aws-sdk/*` dependency).
|
|
48
|
+
- **Blob storage** — `LocalBlobStorage` and `S3BlobStorage`, both implementing the `BlobStorage`
|
|
49
|
+
port, plus `StorageError`.
|
|
50
|
+
- **SSRF-safe asset cache** — `createAssetCache`, `isCacheableExternalUrl`, `isPrivateAddress`,
|
|
51
|
+
`assertSafePublicUrl` — a same-origin disk cache/proxy for external media any sandboxed-content
|
|
52
|
+
renderer (an iframe preview, an embedded document) needs.
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { waitForHttpOk, pathContains, spawnBackgroundProcess, LocalBlobStorage } from '@jini-ai/platform';
|
|
58
|
+
|
|
59
|
+
await waitForHttpOk('http://127.0.0.1:4317/api/daemon/status', { timeoutMs: 15000 });
|
|
60
|
+
|
|
61
|
+
if (!pathContains('/workspace/project', requestedPath)) {
|
|
62
|
+
throw new Error('path escapes project root');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const proc = spawnBackgroundProcess({ command: 'node', args: ['server.js'] });
|
|
66
|
+
|
|
67
|
+
const blobs = new LocalBlobStorage('/var/lib/app/blobs');
|
|
68
|
+
await blobs.writeFile('tenant-42', 'avatar.png', Buffer.from([]));
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## What's swappable
|
|
72
|
+
|
|
73
|
+
`BlobStorage` is a port with two concrete implementations shipped (`LocalBlobStorage`,
|
|
74
|
+
`S3BlobStorage`) — swap in your own by implementing the same interface. `PtySpawn`/`PtyProcess`
|
|
75
|
+
are ports too: `createTerminalService` takes a `loadSpawnPty: () => Promise<PtySpawn>` factory
|
|
76
|
+
rather than importing `node-pty` directly, so a caller supplies a real adapter or a fake for
|
|
77
|
+
tests. `TerminalSseSink` (`{ send, end }`) decouples terminal streaming from any specific
|
|
78
|
+
transport (Express, SSE, WebSocket) — everything else (process spawning, command construction,
|
|
79
|
+
the asset cache's SSRF guard chain, download resume logic) is fixed, concrete implementation.
|
|
80
|
+
|
|
81
|
+
## Runtime
|
|
82
|
+
|
|
83
|
+
Node-only.
|
|
84
|
+
ESM only — ships `"type": "module"` with no CommonJS `require` build.
|
|
85
|
+
|
|
86
|
+
## Provenance
|
|
87
|
+
|
|
88
|
+
See [source-map.md](./source-map.md) for per-file provenance and scope decisions. Apache-2.0.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module fetch-with-timeout
|
|
3
|
+
*
|
|
4
|
+
* The shared timeout wrapper for every outbound `fetch()` call this monorepo makes to a remote
|
|
5
|
+
* service — see the 2026-08-16 Jini failure-mode audit, Finding 2: 101 raw `fetch()` call sites
|
|
6
|
+
* repo-wide (corrected from the audit's own initial "67" — re-count before trusting any figure in
|
|
7
|
+
* a handoff), across devops deploy providers, agent-runtime providers, media-provider dispatch,
|
|
8
|
+
* github-client, and llm-provider, most already protected in some ad hoc way. A remote that accepts
|
|
9
|
+
* the TCP connection but
|
|
10
|
+
* never responds — a stalled load balancer, a provider having a bad day, a firewall black-holing the
|
|
11
|
+
* request — leaves `await fetch(...)` unresolved forever; whatever awaits it hangs indefinitely, with
|
|
12
|
+
* nothing to alert on. A hang like that is worse than a crash: a crash is loud.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately ONE helper, not 67 call sites each hand-rolling a slightly different
|
|
15
|
+
* `AbortController`/`setTimeout` idiom — a caller who already has their own `AbortSignal` (a
|
|
16
|
+
* user-initiated cancel, a parent request's own deadline) can still supply it via `init.signal`;
|
|
17
|
+
* `AbortSignal.any` composes it with the timeout so either one aborts the call, and the thrown
|
|
18
|
+
* `FetchTimeoutError` vs. the caller's own abort reason stay distinguishable (see `fetchWithTimeout`'s
|
|
19
|
+
* own doc).
|
|
20
|
+
*
|
|
21
|
+
* `FETCH_TIMEOUT_MS` gives call sites a small, documented, shared vocabulary instead of inventing a
|
|
22
|
+
* number each time — a deploy-provider API call, an image byte-fetch, and a large asset upload
|
|
23
|
+
* genuinely have different reasonable ceilings. `timeoutMs` is never hidden inside the helper as an
|
|
24
|
+
* undocumented default with no parameter, though: every call site names one explicitly (usually one
|
|
25
|
+
* of these constants), because a caller reading its own code should see the number, not have to go
|
|
26
|
+
* find it.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately excludes anything meant to stay open for a long time independent of transfer size —
|
|
29
|
+
* Server-Sent Events, WebSockets, long-poll. None of the 67 flagged call sites are that shape (the
|
|
30
|
+
* audit traced this: the repo's real streaming transports are `EventSource` on the browser side and
|
|
31
|
+
* a hand-rolled SSE channel server-side, both entirely separate from `fetch()`), but a future caller
|
|
32
|
+
* reaching for this helper for one of those would be reaching for the wrong tool — `AbortSignal.timeout`
|
|
33
|
+
* bounds the WHOLE call, body included, so it would sever a deliberately long-lived stream partway
|
|
34
|
+
* through exactly like the bug this fixes, just self-inflicted instead of accidental.
|
|
35
|
+
*
|
|
36
|
+
* **Also exported as its own subpath, `@jini-ai/platform/fetch-with-timeout`, deliberately.** This
|
|
37
|
+
* module has zero imports of its own — no `node:*` builtin, no `undici` — unlike the package's root
|
|
38
|
+
* barrel (`index.ts`), which re-exports sibling modules (`process.ts`, `fs.ts`, `terminal.ts`,
|
|
39
|
+
* `asset-cache.ts`, …) that import `node:child_process`, `node:fs`, `undici`'s `Agent`, etc.
|
|
40
|
+
* Importing from the root barrel in browser-bundled code is silently fine in a *production* build
|
|
41
|
+
* through Vite/Rollup — tree-shaking (this package sets `sideEffects: false`) proves the Node-only
|
|
42
|
+
* re-exports are unused and drops them before the `node:*` imports are ever resolved — but it is
|
|
43
|
+
* NOT fine in `vite dev` or any other unbundled-native-ESM serving mode: there is no tree-shaking on
|
|
44
|
+
* that path, so the browser eagerly loads and evaluates every sibling the barrel re-exports, and
|
|
45
|
+
* `process.ts`'s very first statement destructures `execFile`/`spawn` off `node:child_process` —
|
|
46
|
+
* which Vite's dev server serves as a `Proxy` that throws on first property access. The whole module
|
|
47
|
+
* graph fails to evaluate the instant anything imports the barrel, regardless of which export is
|
|
48
|
+
* actually used. Verified empirically (`esbuild --bundle --platform=browser` on the barrel: 154
|
|
49
|
+
* resolution errors; `vite build`: clean, 5.92kB, zero Node-only code in the output; `vite dev`
|
|
50
|
+
* serving `index.js`: throws at import time) — see the 2026-08-17 Jini hardening report. Browser
|
|
51
|
+
* call sites should import from this subpath, never the root barrel.
|
|
52
|
+
*/
|
|
53
|
+
/** Thrown in place of the platform's generic abort error specifically when the timeout — not a
|
|
54
|
+
* caller-supplied `init.signal` — is what ended the call, so a caller can tell "this took too long"
|
|
55
|
+
* apart from "I cancelled it myself" without string-matching an error message. */
|
|
56
|
+
export declare class FetchTimeoutError extends Error {
|
|
57
|
+
readonly url: string;
|
|
58
|
+
readonly timeoutMs: number;
|
|
59
|
+
constructor(url: string, timeoutMs: number);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Shared, documented timeout classes for outbound `fetch()` calls. Every call site names one
|
|
63
|
+
* explicitly (or its own justified number) rather than relying on an unstated default.
|
|
64
|
+
*/
|
|
65
|
+
export declare const FETCH_TIMEOUT_MS: {
|
|
66
|
+
/** A single metadata/status/API-read call expected to return quickly: a model catalog listing, a
|
|
67
|
+
* connection test, a GitHub API read, an LLM provider's non-streaming completion call. */
|
|
68
|
+
readonly QUICK: 15000;
|
|
69
|
+
/** A deploy-provider API call that may involve real backend work on the provider's side — site
|
|
70
|
+
* creation, DNS record lookups, deployment status polling. */
|
|
71
|
+
readonly DEPLOY: 30000;
|
|
72
|
+
/** A large-payload transfer: an asset/blob upload, a generated-media byte fetch. */
|
|
73
|
+
readonly UPLOAD: 120000;
|
|
74
|
+
/** A media-generation API call whose response only arrives once the vendor has actually finished
|
|
75
|
+
* generating the image/video/audio server-side — routinely minutes, not seconds. Matches the
|
|
76
|
+
* value OpenAI's and OpenRouter's own image providers already hardcode locally
|
|
77
|
+
* (`OPENAI_IMAGE_*_TIMEOUT_MS`/`OPENROUTER_IMAGE_TIMEOUT_MS`); used as the shared dispatch-level
|
|
78
|
+
* backstop in `@jini-ai/integrations`' `dispatchVendorRequest` for every OTHER vendor that (as of
|
|
79
|
+
* 2026-08-16) sets no timeout of its own at all. Deliberately NOT the same as `UPLOAD`: a backstop
|
|
80
|
+
* shorter than a vendor's own already-correct 10-minute generation timeout would abort a
|
|
81
|
+
* legitimately still-generating request early. */
|
|
82
|
+
readonly GENERATE: number;
|
|
83
|
+
};
|
|
84
|
+
export interface FetchWithTimeoutOptions {
|
|
85
|
+
/** Milliseconds before the call is aborted. Pick one of {@link FETCH_TIMEOUT_MS}, or a specific
|
|
86
|
+
* justified number for a call site that doesn't fit those classes. */
|
|
87
|
+
timeoutMs: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* `fetch`, but aborted after `options.timeoutMs` if it hasn't settled by then. If `init.signal` is
|
|
91
|
+
* already set, the call aborts on EITHER that signal or the timeout, via `AbortSignal.any` — a
|
|
92
|
+
* caller's own cancellation (e.g. a user-initiated cancel button) keeps working exactly as it did
|
|
93
|
+
* without this wrapper.
|
|
94
|
+
*
|
|
95
|
+
* @param url - Same as `fetch`'s first argument.
|
|
96
|
+
* @param init - Same as `fetch`'s second argument. `init.signal`, if present, is combined with the
|
|
97
|
+
* timeout rather than replaced.
|
|
98
|
+
* @param options - See {@link FetchWithTimeoutOptions}.
|
|
99
|
+
* @returns The same `Promise<Response>` `fetch` itself would return.
|
|
100
|
+
* @throws {@link FetchTimeoutError} if the timeout fires before the call settles and the caller's own
|
|
101
|
+
* `init.signal` (if any) did not itself already abort. Any other rejection (a caller's own abort, a
|
|
102
|
+
* genuine network error) propagates unchanged.
|
|
103
|
+
*/
|
|
104
|
+
export declare function fetchWithTimeout(url: string | URL, init: RequestInit | undefined, options: FetchWithTimeoutOptions): Promise<Response>;
|
|
105
|
+
//# sourceMappingURL=fetch-with-timeout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-with-timeout.d.ts","sourceRoot":"","sources":["../src/fetch-with-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH;;kFAEkF;AAClF,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM3C;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;8FAC0F;;IAE1F;kEAC8D;;IAE9D,oFAAoF;;IAEpF;;;;;;;sDAOkD;;CAET,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC;0EACsE;IACtE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,EAAE,WAAW,YAAK,EACtB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,QAAQ,CAAC,CAgBnB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module fetch-with-timeout
|
|
3
|
+
*
|
|
4
|
+
* The shared timeout wrapper for every outbound `fetch()` call this monorepo makes to a remote
|
|
5
|
+
* service — see the 2026-08-16 Jini failure-mode audit, Finding 2: 101 raw `fetch()` call sites
|
|
6
|
+
* repo-wide (corrected from the audit's own initial "67" — re-count before trusting any figure in
|
|
7
|
+
* a handoff), across devops deploy providers, agent-runtime providers, media-provider dispatch,
|
|
8
|
+
* github-client, and llm-provider, most already protected in some ad hoc way. A remote that accepts
|
|
9
|
+
* the TCP connection but
|
|
10
|
+
* never responds — a stalled load balancer, a provider having a bad day, a firewall black-holing the
|
|
11
|
+
* request — leaves `await fetch(...)` unresolved forever; whatever awaits it hangs indefinitely, with
|
|
12
|
+
* nothing to alert on. A hang like that is worse than a crash: a crash is loud.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately ONE helper, not 67 call sites each hand-rolling a slightly different
|
|
15
|
+
* `AbortController`/`setTimeout` idiom — a caller who already has their own `AbortSignal` (a
|
|
16
|
+
* user-initiated cancel, a parent request's own deadline) can still supply it via `init.signal`;
|
|
17
|
+
* `AbortSignal.any` composes it with the timeout so either one aborts the call, and the thrown
|
|
18
|
+
* `FetchTimeoutError` vs. the caller's own abort reason stay distinguishable (see `fetchWithTimeout`'s
|
|
19
|
+
* own doc).
|
|
20
|
+
*
|
|
21
|
+
* `FETCH_TIMEOUT_MS` gives call sites a small, documented, shared vocabulary instead of inventing a
|
|
22
|
+
* number each time — a deploy-provider API call, an image byte-fetch, and a large asset upload
|
|
23
|
+
* genuinely have different reasonable ceilings. `timeoutMs` is never hidden inside the helper as an
|
|
24
|
+
* undocumented default with no parameter, though: every call site names one explicitly (usually one
|
|
25
|
+
* of these constants), because a caller reading its own code should see the number, not have to go
|
|
26
|
+
* find it.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately excludes anything meant to stay open for a long time independent of transfer size —
|
|
29
|
+
* Server-Sent Events, WebSockets, long-poll. None of the 67 flagged call sites are that shape (the
|
|
30
|
+
* audit traced this: the repo's real streaming transports are `EventSource` on the browser side and
|
|
31
|
+
* a hand-rolled SSE channel server-side, both entirely separate from `fetch()`), but a future caller
|
|
32
|
+
* reaching for this helper for one of those would be reaching for the wrong tool — `AbortSignal.timeout`
|
|
33
|
+
* bounds the WHOLE call, body included, so it would sever a deliberately long-lived stream partway
|
|
34
|
+
* through exactly like the bug this fixes, just self-inflicted instead of accidental.
|
|
35
|
+
*
|
|
36
|
+
* **Also exported as its own subpath, `@jini-ai/platform/fetch-with-timeout`, deliberately.** This
|
|
37
|
+
* module has zero imports of its own — no `node:*` builtin, no `undici` — unlike the package's root
|
|
38
|
+
* barrel (`index.ts`), which re-exports sibling modules (`process.ts`, `fs.ts`, `terminal.ts`,
|
|
39
|
+
* `asset-cache.ts`, …) that import `node:child_process`, `node:fs`, `undici`'s `Agent`, etc.
|
|
40
|
+
* Importing from the root barrel in browser-bundled code is silently fine in a *production* build
|
|
41
|
+
* through Vite/Rollup — tree-shaking (this package sets `sideEffects: false`) proves the Node-only
|
|
42
|
+
* re-exports are unused and drops them before the `node:*` imports are ever resolved — but it is
|
|
43
|
+
* NOT fine in `vite dev` or any other unbundled-native-ESM serving mode: there is no tree-shaking on
|
|
44
|
+
* that path, so the browser eagerly loads and evaluates every sibling the barrel re-exports, and
|
|
45
|
+
* `process.ts`'s very first statement destructures `execFile`/`spawn` off `node:child_process` —
|
|
46
|
+
* which Vite's dev server serves as a `Proxy` that throws on first property access. The whole module
|
|
47
|
+
* graph fails to evaluate the instant anything imports the barrel, regardless of which export is
|
|
48
|
+
* actually used. Verified empirically (`esbuild --bundle --platform=browser` on the barrel: 154
|
|
49
|
+
* resolution errors; `vite build`: clean, 5.92kB, zero Node-only code in the output; `vite dev`
|
|
50
|
+
* serving `index.js`: throws at import time) — see the 2026-08-17 Jini hardening report. Browser
|
|
51
|
+
* call sites should import from this subpath, never the root barrel.
|
|
52
|
+
*/
|
|
53
|
+
/** Thrown in place of the platform's generic abort error specifically when the timeout — not a
|
|
54
|
+
* caller-supplied `init.signal` — is what ended the call, so a caller can tell "this took too long"
|
|
55
|
+
* apart from "I cancelled it myself" without string-matching an error message. */
|
|
56
|
+
export class FetchTimeoutError extends Error {
|
|
57
|
+
url;
|
|
58
|
+
timeoutMs;
|
|
59
|
+
constructor(url, timeoutMs) {
|
|
60
|
+
super(`fetch timed out after ${timeoutMs}ms: ${url}`);
|
|
61
|
+
this.name = "FetchTimeoutError";
|
|
62
|
+
this.url = url;
|
|
63
|
+
this.timeoutMs = timeoutMs;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Shared, documented timeout classes for outbound `fetch()` calls. Every call site names one
|
|
68
|
+
* explicitly (or its own justified number) rather than relying on an unstated default.
|
|
69
|
+
*/
|
|
70
|
+
export const FETCH_TIMEOUT_MS = {
|
|
71
|
+
/** A single metadata/status/API-read call expected to return quickly: a model catalog listing, a
|
|
72
|
+
* connection test, a GitHub API read, an LLM provider's non-streaming completion call. */
|
|
73
|
+
QUICK: 15_000,
|
|
74
|
+
/** A deploy-provider API call that may involve real backend work on the provider's side — site
|
|
75
|
+
* creation, DNS record lookups, deployment status polling. */
|
|
76
|
+
DEPLOY: 30_000,
|
|
77
|
+
/** A large-payload transfer: an asset/blob upload, a generated-media byte fetch. */
|
|
78
|
+
UPLOAD: 120_000,
|
|
79
|
+
/** A media-generation API call whose response only arrives once the vendor has actually finished
|
|
80
|
+
* generating the image/video/audio server-side — routinely minutes, not seconds. Matches the
|
|
81
|
+
* value OpenAI's and OpenRouter's own image providers already hardcode locally
|
|
82
|
+
* (`OPENAI_IMAGE_*_TIMEOUT_MS`/`OPENROUTER_IMAGE_TIMEOUT_MS`); used as the shared dispatch-level
|
|
83
|
+
* backstop in `@jini-ai/integrations`' `dispatchVendorRequest` for every OTHER vendor that (as of
|
|
84
|
+
* 2026-08-16) sets no timeout of its own at all. Deliberately NOT the same as `UPLOAD`: a backstop
|
|
85
|
+
* shorter than a vendor's own already-correct 10-minute generation timeout would abort a
|
|
86
|
+
* legitimately still-generating request early. */
|
|
87
|
+
GENERATE: 10 * 60_000,
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* `fetch`, but aborted after `options.timeoutMs` if it hasn't settled by then. If `init.signal` is
|
|
91
|
+
* already set, the call aborts on EITHER that signal or the timeout, via `AbortSignal.any` — a
|
|
92
|
+
* caller's own cancellation (e.g. a user-initiated cancel button) keeps working exactly as it did
|
|
93
|
+
* without this wrapper.
|
|
94
|
+
*
|
|
95
|
+
* @param url - Same as `fetch`'s first argument.
|
|
96
|
+
* @param init - Same as `fetch`'s second argument. `init.signal`, if present, is combined with the
|
|
97
|
+
* timeout rather than replaced.
|
|
98
|
+
* @param options - See {@link FetchWithTimeoutOptions}.
|
|
99
|
+
* @returns The same `Promise<Response>` `fetch` itself would return.
|
|
100
|
+
* @throws {@link FetchTimeoutError} if the timeout fires before the call settles and the caller's own
|
|
101
|
+
* `init.signal` (if any) did not itself already abort. Any other rejection (a caller's own abort, a
|
|
102
|
+
* genuine network error) propagates unchanged.
|
|
103
|
+
*/
|
|
104
|
+
export async function fetchWithTimeout(url, init = {}, options) {
|
|
105
|
+
const { timeoutMs } = options;
|
|
106
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
107
|
+
const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
|
|
108
|
+
try {
|
|
109
|
+
return await fetch(url, { ...init, signal });
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// `timeoutSignal` is the original object this function created, not the (possibly composed)
|
|
113
|
+
// signal handed to `fetch` — checking its own `.aborted` tells us specifically whether OUR
|
|
114
|
+
// timeout fired, independent of whether a caller-supplied signal also exists or also aborted.
|
|
115
|
+
if (timeoutSignal.aborted && !init.signal?.aborted) {
|
|
116
|
+
throw new FetchTimeoutError(String(url), timeoutMs);
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=fetch-with-timeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-with-timeout.js","sourceRoot":"","sources":["../src/fetch-with-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH;;kFAEkF;AAClF,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,GAAG,CAAS;IACZ,SAAS,CAAS;IAE3B,YAAY,GAAW,EAAE,SAAiB;QACxC,KAAK,CAAC,yBAAyB,SAAS,OAAO,GAAG,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B;8FAC0F;IAC1F,KAAK,EAAE,MAAM;IACb;kEAC8D;IAC9D,MAAM,EAAE,MAAM;IACd,oFAAoF;IACpF,MAAM,EAAE,OAAO;IACf;;;;;;;sDAOkD;IAClD,QAAQ,EAAE,EAAE,GAAG,MAAM;CACoB,CAAC;AAQ5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAiB,EACjB,OAAoB,EAAE,EACtB,OAAgC;IAEhC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAE3F,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4FAA4F;QAC5F,2FAA2F;QAC3F,8FAA8F;QAC9F,IAAI,aAAa,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACnD,MAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAOF;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,SAAiB,EAAE,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB3G"}
|
package/dist/http.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* copy so it owns no cross-module runtime surface.
|
|
7
7
|
*/
|
|
8
8
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
9
|
+
import { fetchWithTimeout } from "./fetch-with-timeout.js";
|
|
9
10
|
/** @internal Extract a human-readable message from an unknown thrown value. */
|
|
10
11
|
function errorMessage(error) {
|
|
11
12
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -24,7 +25,15 @@ export async function waitForHttpOk(url, { timeoutMs = 20000 } = {}) {
|
|
|
24
25
|
let lastError = null;
|
|
25
26
|
while (Date.now() - startedAt < timeoutMs) {
|
|
26
27
|
try {
|
|
27
|
-
|
|
28
|
+
// Each attempt gets its own bounded timeout — capped at what's left of the OVERALL
|
|
29
|
+
// `timeoutMs`, floored at 1ms so a caller who deliberately passes `timeoutMs: 0` still gets a
|
|
30
|
+
// schedulable (if immediately-expiring) signal rather than `AbortSignal.timeout(0)`'s
|
|
31
|
+
// undefined-ish edge behavior. Without this, a single stalled attempt could hang past the
|
|
32
|
+
// `timeoutMs` this function promises to the caller: the outer `while` can only re-check the
|
|
33
|
+
// clock once `await fetch(...)` itself returns, so an unbounded fetch call defeats the loop's
|
|
34
|
+
// own deadline exactly like Finding 2 of the 2026-08-16 audit describes.
|
|
35
|
+
const remaining = timeoutMs - (Date.now() - startedAt);
|
|
36
|
+
const response = await fetchWithTimeout(url, { cache: "no-store" }, { timeoutMs: Math.max(1, remaining) });
|
|
28
37
|
if (response.ok)
|
|
29
38
|
return true;
|
|
30
39
|
lastError = new Error(`HTTP ${response.status} from ${url}`);
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAM3D,+EAA+E;AAC/E,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,EAAE,SAAS,GAAG,KAAK,KAAsB,EAAE;IAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAM3D,+EAA+E;AAC/E,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,EAAE,SAAS,GAAG,KAAK,KAAsB,EAAE;IAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,mFAAmF;YACnF,8FAA8F;YAC9F,sFAAsF;YACtF,0FAA0F;YAC1F,4FAA4F;YAC5F,8FAA8F;YAC9F,yEAAyE;YACzE,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;YAC3G,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC7B,SAAS,GAAG,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/F,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - `proxy-env` — system proxy discovery and proxy-aware env merging.
|
|
10
10
|
* - `fs` — filesystem containment, atomic copy, removal, log tails.
|
|
11
11
|
* - `http` — HTTP readiness polling.
|
|
12
|
+
* - `fetch-with-timeout` — the shared `AbortSignal`-timeout wrapper every outbound `fetch()` call
|
|
13
|
+
* in this monorepo is meant to go through (2026-08-16 failure-mode audit, Finding 2).
|
|
12
14
|
* - `toolchain` — user-level toolchain bin discovery.
|
|
13
15
|
* - `asset-cache` — SSRF-safe same-origin cache/proxy for sandboxed content's
|
|
14
16
|
* external media references.
|
|
@@ -37,6 +39,8 @@ export type { AtomicCopyFileOptions, AtomicCopyFileResult, RemovePathBestEffortO
|
|
|
37
39
|
export { atomicCopyFile, pathContains, readLogTail, removePathBestEffort } from "./fs.js";
|
|
38
40
|
export type { HttpWaitOptions } from "./http.js";
|
|
39
41
|
export { waitForHttpOk } from "./http.js";
|
|
42
|
+
export type { FetchWithTimeoutOptions } from "./fetch-with-timeout.js";
|
|
43
|
+
export { FETCH_TIMEOUT_MS, FetchTimeoutError, fetchWithTimeout } from "./fetch-with-timeout.js";
|
|
40
44
|
export type { WellKnownUserToolchainOptions } from "./toolchain.js";
|
|
41
45
|
export { wellKnownUserToolchainBins } from "./toolchain.js";
|
|
42
46
|
export type { BufferedCommandResult } from "./shell.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAEvF,YAAY,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,uCAAuC,EACvC,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE1F,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhG,YAAY,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEnF,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,kCAAkC,EAClC,8BAA8B,EAC9B,yBAAyB,EACzB,2CAA2C,GAC5C,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EACV,qCAAqC,EACrC,gCAAgC,EAChC,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EACzB,cAAc,EACd,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,UAAU,EACV,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE5H,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - `proxy-env` — system proxy discovery and proxy-aware env merging.
|
|
10
10
|
* - `fs` — filesystem containment, atomic copy, removal, log tails.
|
|
11
11
|
* - `http` — HTTP readiness polling.
|
|
12
|
+
* - `fetch-with-timeout` — the shared `AbortSignal`-timeout wrapper every outbound `fetch()` call
|
|
13
|
+
* in this monorepo is meant to go through (2026-08-16 failure-mode audit, Finding 2).
|
|
12
14
|
* - `toolchain` — user-level toolchain bin discovery.
|
|
13
15
|
* - `asset-cache` — SSRF-safe same-origin cache/proxy for sandboxed content's
|
|
14
16
|
* external media references.
|
|
@@ -32,6 +34,7 @@ export { mergeProxyAwareEnv, parseMacosScutilProxyOutput, parseWindowsInternetSe
|
|
|
32
34
|
export { collectProcessTreePids, createProcessStampArgs, isProcessAlive, listProcessSnapshots, matchesProcessStamp, matchesStampedProcess, readFlagValue, readProcessStamp, readProcessStampFromCommand, spawnBackgroundProcess, spawnLoggedProcess, stopProcesses, waitForProcessExit, } from "./process.js";
|
|
33
35
|
export { atomicCopyFile, pathContains, readLogTail, removePathBestEffort } from "./fs.js";
|
|
34
36
|
export { waitForHttpOk } from "./http.js";
|
|
37
|
+
export { FETCH_TIMEOUT_MS, FetchTimeoutError, fetchWithTimeout } from "./fetch-with-timeout.js";
|
|
35
38
|
export { wellKnownUserToolchainBins } from "./toolchain.js";
|
|
36
39
|
export { execCommandViaLoginShell, execFileBuffered } from "./shell.js";
|
|
37
40
|
export { AssetCacheError, assertSafePublicUrl, assetCacheKey, assetCacheRewriteUrl, createAssetCache, createValidatingLookup, isCacheableExternalUrl, isPrivateAddress, } from "./asset-cache.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAGvF,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,uCAAuC,EACvC,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAWxB,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAQtB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAG1F,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhG,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAG5D,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGxE,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAGnF,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,kCAAkC,EAClC,8BAA8B,EAC9B,yBAAyB,EACzB,2CAA2C,GAC5C,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAC9B,wBAAwB,EACxB,yBAAyB,EACzB,cAAc,EACd,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAc7B,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAiB5H,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/platform",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Generic OS/platform primitives: process exec and lifecycle, filesystem containment, HTTP readiness polling, toolchain discovery, blob storage, AWS signing, and an SSRF-safe asset cache.",
|
|
4
5
|
"license": "Apache-2.0",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
@@ -10,15 +11,22 @@
|
|
|
10
11
|
"jini": {
|
|
11
12
|
"domain": "platform",
|
|
12
13
|
"kind": "abstraction",
|
|
13
|
-
"runtime": "node"
|
|
14
|
-
"admission": "locked"
|
|
14
|
+
"runtime": "node"
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
17
20
|
"exports": {
|
|
18
21
|
".": {
|
|
19
22
|
"types": "./dist/index.d.ts",
|
|
20
23
|
"import": "./dist/index.js",
|
|
21
24
|
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./fetch-with-timeout": {
|
|
27
|
+
"types": "./dist/fetch-with-timeout.d.ts",
|
|
28
|
+
"import": "./dist/fetch-with-timeout.js",
|
|
29
|
+
"default": "./dist/fetch-with-timeout.js"
|
|
22
30
|
}
|
|
23
31
|
},
|
|
24
32
|
"files": [
|