@jini-ai/platform 0.5.5 → 0.5.7
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/CHANGELOG.md +10 -0
- package/README.md +22 -2
- package/dist/asset-cache.adapter.d.ts +9 -0
- package/dist/asset-cache.adapter.js +10 -0
- package/dist/asset-cache.d.ts +4 -2
- package/dist/asset-cache.js +15 -3
- package/dist/fetch-with-timeout.d.ts +2 -1
- package/dist/fetch-with-timeout.js +2 -1
- package/dist/secrets/credential-sets/contracts.d.ts +6 -0
- package/dist/secrets/credential-sets/contracts.js +6 -0
- package/dist/web/index.d.ts +2 -1
- package/dist/web/index.js +2 -1
- package/package.json +56 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @jini-ai/platform
|
|
2
2
|
|
|
3
|
+
## 0.5.7 — 2026-10-14
|
|
4
|
+
|
|
5
|
+
- The asset cache's optional `undici` load moves behind `asset-cache.adapter.ts` (64eafe35); injected dispatchers, DNS validation and the MODULE_NOT_FOUND message are unchanged. No API change.
|
|
6
|
+
|
|
7
|
+
## 0.5.6 — 2026-10-13
|
|
8
|
+
|
|
9
|
+
- `undici` and `hast-util-from-parse5`, `hast-util-to-mdast`, `mdast-util-to-markdown`, `mdast-util-gfm-table` (with `parse5`) are now optional peers instead of dependencies. Only `./web` needs the HTML/Markdown set; only the default `createAssetCacheDispatcher` needs undici, loaded lazily (a missing peer throws `AssetCacheError` 500; a host-supplied dispatcher needs none). Hosts using those must list the packages themselves.
|
|
10
|
+
- New `./asset-cache` subpath (node) exporting the asset cache without the root barrel.
|
|
11
|
+
- New universal `./secrets/credential-sets/contracts` leaf (vault contracts without the vault runtime); `@jini-ai/db` 0.3.4's SQL vault repo imports it.
|
|
12
|
+
|
|
3
13
|
## 0.5.5 — 2026-10-13
|
|
4
14
|
|
|
5
15
|
- New narrow subpaths for the existing OS helpers: `./command`, `./process`, `./toolchain`, `./proxy-env`, `./shell`, `./child-environment`. Importing one loads 1-2 modules instead of the root barrel's 181 (incl. undici). The root still exports everything; no signature change.
|
package/README.md
CHANGED
|
@@ -14,8 +14,14 @@ that were split out of OD's monolithic daemon (see the archived provenance ledge
|
|
|
14
14
|
npm install @jini-ai/platform
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
`undici@^7.25.0` is an optional peer for the SSRF-safe asset cache's default dispatcher.
|
|
18
|
+
Install it when calling `createAssetCacheDispatcher` or creating a cache without a host-supplied
|
|
19
|
+
guarded dispatcher. Root imports and `@jini-ai/platform/asset-cache` imports do not load undici;
|
|
20
|
+
the synchronous factory loads it on demand and reports a missing-peer error if it is absent.
|
|
21
|
+
The root declarations retain undici types, so TypeScript consumers of those declarations also
|
|
22
|
+
need the peer available. The dispatcher validates DNS at connection time, and cache `close()`
|
|
23
|
+
closes only its default dispatcher; a host-supplied dispatcher remains owned by the host.
|
|
24
|
+
Interactive terminal sessions (`createTerminalService`)
|
|
19
25
|
need a `PtySpawn` implementation supplied by the caller — this package defines the `PtyProcess`/
|
|
20
26
|
`PtySpawn` port only, it does not depend on `node-pty` itself, so bring your own adapter (or use
|
|
21
27
|
`@jini-ai/daemon`'s, which wires a real `node-pty` behind the same port).
|
|
@@ -92,6 +98,20 @@ The package also exposes `./http/guarded`, `./mail`, `./mail/smtp`,
|
|
|
92
98
|
`./fs/guarded-reader`, `./fs/durable-json`, and `./secrets`. New APIs take a required
|
|
93
99
|
object followed by an optional object. Application identity and policy values belong to the caller.
|
|
94
100
|
|
|
101
|
+
`@jini-ai/platform/web` loads these optional peers at import time: `parse5@7.3.0`,
|
|
102
|
+
`hast-util-from-parse5@8.0.3`, `hast-util-to-mdast@10.1.2`,
|
|
103
|
+
`mdast-util-to-markdown@2.1.2`, and `mdast-util-gfm-table@2.0.0`. Install all five
|
|
104
|
+
when using that subpath; the other entries do not load them. Existing web consumers that
|
|
105
|
+
relied on transitive installation must add them before upgrading.
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
npm install parse5@7.3.0 hast-util-from-parse5@8.0.3 hast-util-to-mdast@10.1.2 mdast-util-to-markdown@2.1.2 mdast-util-gfm-table@2.0.0
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The isolation metadata shares only the address classifiers (including their literal
|
|
112
|
+
endpoint policy), timeout wrapper and egress refusal class across domains. These
|
|
113
|
+
leaves retain one owner so HTTP and web adapters use the same security decisions.
|
|
114
|
+
|
|
95
115
|
```ts
|
|
96
116
|
import { createHttpClient, createNodeGuardedHttpPorts, guardedFetch } from "@jini-ai/platform/http/guarded";
|
|
97
117
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LookupFunction } from 'node:net';
|
|
2
|
+
import type { Agent } from 'undici';
|
|
3
|
+
/** Load the optional vendor only for a default dispatcher; the cache owns lookup validation.
|
|
4
|
+
* @throws When the optional peer cannot be loaded or its Agent cannot be constructed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createUndiciAssetCacheDispatcher({ lookup }: {
|
|
7
|
+
lookup: LookupFunction;
|
|
8
|
+
}, _options?: Record<string, never>): Agent;
|
|
9
|
+
//# sourceMappingURL=asset-cache.adapter.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
/** Load the optional vendor only for a default dispatcher; the cache owns lookup validation.
|
|
4
|
+
* @throws When the optional peer cannot be loaded or its Agent cannot be constructed.
|
|
5
|
+
*/
|
|
6
|
+
export function createUndiciAssetCacheDispatcher({ lookup }, _options = {}) {
|
|
7
|
+
const { Agent } = require('undici');
|
|
8
|
+
return new Agent({ connect: { lookup } });
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=asset-cache.adapter.js.map
|
package/dist/asset-cache.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { lookup as dnsLookupCb } from 'node:dns';
|
|
2
|
-
import { Agent,
|
|
2
|
+
import type { Agent, Dispatcher } from 'undici';
|
|
3
3
|
/** Media extensions we are willing to cache + proxy. Anything else (HTML,
|
|
4
4
|
* CSS, JS, fonts) is intentionally left alone so this surface never becomes a
|
|
5
5
|
* general-purpose open proxy. */
|
|
@@ -52,7 +52,9 @@ export interface AssetCache {
|
|
|
52
52
|
/** Closes only the default adapter; an injected dispatcher remains owned by its host. */
|
|
53
53
|
close?(): Promise<void>;
|
|
54
54
|
}
|
|
55
|
-
/** Default adapter: validate DNS at connection time, so the checked address is the connected one.
|
|
55
|
+
/** Default adapter: validate DNS at connection time, so the checked address is the connected one.
|
|
56
|
+
* @throws {AssetCacheError} When the host has not installed the optional undici peer.
|
|
57
|
+
*/
|
|
56
58
|
export declare function createAssetCacheDispatcher(_required: Record<string, never>, { lookupImpl }?: {
|
|
57
59
|
lookupImpl?: DnsLookupCb;
|
|
58
60
|
}): Agent;
|
package/dist/asset-cache.js
CHANGED
|
@@ -24,7 +24,7 @@ import { lookup as dnsLookupCb } from 'node:dns';
|
|
|
24
24
|
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
25
25
|
import { isIP } from 'node:net';
|
|
26
26
|
import path from 'node:path';
|
|
27
|
-
import {
|
|
27
|
+
import { createUndiciAssetCacheDispatcher } from './asset-cache.adapter.js';
|
|
28
28
|
import { isPrivateAddress } from './net/address.js';
|
|
29
29
|
/** Media extensions we are willing to cache + proxy. Anything else (HTML,
|
|
30
30
|
* CSS, JS, fonts) is intentionally left alone so this surface never becomes a
|
|
@@ -127,9 +127,21 @@ export function createValidatingLookup(lookupImpl = dnsLookupCb) {
|
|
|
127
127
|
});
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
|
-
/** Default adapter: validate DNS at connection time, so the checked address is the connected one.
|
|
130
|
+
/** Default adapter: validate DNS at connection time, so the checked address is the connected one.
|
|
131
|
+
* @throws {AssetCacheError} When the host has not installed the optional undici peer.
|
|
132
|
+
*/
|
|
131
133
|
export function createAssetCacheDispatcher(_required, { lookupImpl } = {}) {
|
|
132
|
-
|
|
134
|
+
// Keep the factory synchronous while root imports and host-supplied dispatchers need no undici.
|
|
135
|
+
try {
|
|
136
|
+
return createUndiciAssetCacheDispatcher({ lookup: createValidatingLookup(lookupImpl) });
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error instanceof Error && error.code === 'MODULE_NOT_FOUND'
|
|
140
|
+
&& error.message.split('\n')[0] === "Cannot find module 'undici'") {
|
|
141
|
+
throw new AssetCacheError(500, 'Asset cache dispatcher requires the optional peer "undici"; install undici@^7.25.0 or supply a guarded dispatcher.');
|
|
142
|
+
}
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
133
145
|
}
|
|
134
146
|
/** Build a disk-backed cache for external sandboxed-content media. Concurrent
|
|
135
147
|
* requests for the same URL share one in-flight fetch; completed fetches
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
* **Also exported as its own subpath, `@jini-ai/platform/fetch-with-timeout`, deliberately.** This
|
|
37
37
|
* module has zero imports of its own — no `node:*` builtin, no `undici` — unlike the package's root
|
|
38
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`,
|
|
39
|
+
* `asset-cache.ts`, …) that import `node:child_process`, `node:fs`, etc.; the asset-cache
|
|
40
|
+
* dispatcher loads the optional `undici` peer only when its synchronous factory is called.
|
|
40
41
|
* Importing from the root barrel in browser-bundled code is silently fine in a *production* build
|
|
41
42
|
* through Vite/Rollup — tree-shaking (this package sets `sideEffects: false`) proves the Node-only
|
|
42
43
|
* re-exports are unused and drops them before the `node:*` imports are ever resolved — but it is
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
* **Also exported as its own subpath, `@jini-ai/platform/fetch-with-timeout`, deliberately.** This
|
|
37
37
|
* module has zero imports of its own — no `node:*` builtin, no `undici` — unlike the package's root
|
|
38
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`,
|
|
39
|
+
* `asset-cache.ts`, …) that import `node:child_process`, `node:fs`, etc.; the asset-cache
|
|
40
|
+
* dispatcher loads the optional `undici` peer only when its synchronous factory is called.
|
|
40
41
|
* Importing from the root barrel in browser-bundled code is silently fine in a *production* build
|
|
41
42
|
* through Vite/Rollup — tree-shaking (this package sets `sideEffects: false`) proves the Node-only
|
|
42
43
|
* re-exports are unused and drops them before the `node:*` imports are ever resolved — but it is
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Universal vault contracts and invariants, without service, keyring or storage adapters.
|
|
2
|
+
* Re-export the owner so aggregate callers and persistence adapters share VaultError identity.
|
|
3
|
+
* @example import { VaultError, type VaultRepoPort } from "@jini-ai/platform/secrets/credential-sets/contracts";
|
|
4
|
+
*/
|
|
5
|
+
export * from "./vault.types.js";
|
|
6
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Universal vault contracts and invariants, without service, keyring or storage adapters.
|
|
2
|
+
* Re-export the owner so aggregate callers and persistence adapters share VaultError identity.
|
|
3
|
+
* @example import { VaultError, type VaultRepoPort } from "@jini-ai/platform/secrets/credential-sets/contracts";
|
|
4
|
+
*/
|
|
5
|
+
export * from "./vault.types.js";
|
|
6
|
+
//# sourceMappingURL=contracts.js.map
|
package/dist/web/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** Public-page projections and an anonymous reader over injected guarded HTTP ports.
|
|
1
|
+
/** Public-page projections and an anonymous reader over injected guarded HTTP ports.
|
|
2
|
+
* Importing this entry requires the optional `parse5` peer listed in README.md. */
|
|
2
3
|
export * from "./web-page.js";
|
|
3
4
|
export * from "./html-document.js";
|
|
4
5
|
export { htmlToMarkdown } from "./html-to-markdown.js";
|
package/dist/web/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/** Public-page projections and an anonymous reader over injected guarded HTTP ports.
|
|
1
|
+
/** Public-page projections and an anonymous reader over injected guarded HTTP ports.
|
|
2
|
+
* Importing this entry requires the optional `parse5` peer listed in README.md. */
|
|
2
3
|
export * from "./web-page.js";
|
|
3
4
|
export * from "./html-document.js";
|
|
4
5
|
export { htmlToMarkdown } from "./html-to-markdown.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/platform",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
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.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
"entries": {
|
|
16
16
|
".": "node",
|
|
17
17
|
"./fetch-with-timeout": "node",
|
|
18
|
+
"./asset-cache": "node",
|
|
18
19
|
"./secrets": "node",
|
|
19
20
|
"./secrets/credential-sets": "node",
|
|
21
|
+
"./secrets/credential-sets/contracts": "universal",
|
|
20
22
|
"./secrets/testing": "node",
|
|
21
23
|
"./http/guarded": "node",
|
|
22
24
|
"./mail": "node",
|
|
@@ -44,7 +46,13 @@
|
|
|
44
46
|
"./proxy-env": "os",
|
|
45
47
|
"./shell": "os",
|
|
46
48
|
"./child-environment": "os"
|
|
47
|
-
}
|
|
49
|
+
},
|
|
50
|
+
"shared": [
|
|
51
|
+
"src/net/address.ts",
|
|
52
|
+
"src/net/endpoint-policy.ts",
|
|
53
|
+
"src/fetch-with-timeout.ts",
|
|
54
|
+
"src/http/guarded/errors.ts"
|
|
55
|
+
]
|
|
48
56
|
}
|
|
49
57
|
},
|
|
50
58
|
"type": "module",
|
|
@@ -62,6 +70,11 @@
|
|
|
62
70
|
"import": "./dist/fetch-with-timeout.js",
|
|
63
71
|
"default": "./dist/fetch-with-timeout.js"
|
|
64
72
|
},
|
|
73
|
+
"./asset-cache": {
|
|
74
|
+
"types": "./dist/asset-cache.d.ts",
|
|
75
|
+
"import": "./dist/asset-cache.js",
|
|
76
|
+
"default": "./dist/asset-cache.js"
|
|
77
|
+
},
|
|
65
78
|
"./secrets": {
|
|
66
79
|
"types": "./dist/secrets/index.d.ts",
|
|
67
80
|
"import": "./dist/secrets/index.js",
|
|
@@ -72,6 +85,11 @@
|
|
|
72
85
|
"import": "./dist/secrets/credential-sets/index.js",
|
|
73
86
|
"default": "./dist/secrets/credential-sets/index.js"
|
|
74
87
|
},
|
|
88
|
+
"./secrets/credential-sets/contracts": {
|
|
89
|
+
"types": "./dist/secrets/credential-sets/contracts.d.ts",
|
|
90
|
+
"import": "./dist/secrets/credential-sets/contracts.js",
|
|
91
|
+
"default": "./dist/secrets/credential-sets/contracts.js"
|
|
92
|
+
},
|
|
75
93
|
"./secrets/testing": {
|
|
76
94
|
"types": "./dist/secrets/testing.d.ts",
|
|
77
95
|
"import": "./dist/secrets/testing.js",
|
|
@@ -176,20 +194,48 @@
|
|
|
176
194
|
"!dist/**/*.map"
|
|
177
195
|
],
|
|
178
196
|
"dependencies": {
|
|
179
|
-
"
|
|
180
|
-
"@jini-ai/core": "^0.4.0",
|
|
181
|
-
"parse5": "7.3.0",
|
|
182
|
-
"hast-util-from-parse5": "8.0.3",
|
|
183
|
-
"hast-util-to-mdast": "10.1.2",
|
|
184
|
-
"mdast-util-to-markdown": "2.1.2",
|
|
185
|
-
"mdast-util-gfm-table": "2.0.0"
|
|
197
|
+
"@jini-ai/core": "^0.4.0"
|
|
186
198
|
},
|
|
187
199
|
"publishConfig": {
|
|
188
200
|
"access": "public",
|
|
189
201
|
"registry": "https://registry.npmjs.org"
|
|
190
202
|
},
|
|
191
203
|
"devDependencies": {
|
|
192
|
-
"@vitest/coverage-v8": "^2.1.9"
|
|
204
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
205
|
+
"undici": "^7.25.0",
|
|
206
|
+
"hast-util-from-parse5": "8.0.3",
|
|
207
|
+
"hast-util-to-mdast": "10.1.2",
|
|
208
|
+
"mdast-util-to-markdown": "2.1.2",
|
|
209
|
+
"mdast-util-gfm-table": "2.0.0",
|
|
210
|
+
"parse5": "7.3.0"
|
|
211
|
+
},
|
|
212
|
+
"peerDependencies": {
|
|
213
|
+
"undici": "^7.25.0",
|
|
214
|
+
"hast-util-from-parse5": "8.0.3",
|
|
215
|
+
"hast-util-to-mdast": "10.1.2",
|
|
216
|
+
"mdast-util-to-markdown": "2.1.2",
|
|
217
|
+
"mdast-util-gfm-table": "2.0.0",
|
|
218
|
+
"parse5": "7.3.0"
|
|
219
|
+
},
|
|
220
|
+
"peerDependenciesMeta": {
|
|
221
|
+
"undici": {
|
|
222
|
+
"optional": true
|
|
223
|
+
},
|
|
224
|
+
"hast-util-from-parse5": {
|
|
225
|
+
"optional": true
|
|
226
|
+
},
|
|
227
|
+
"hast-util-to-mdast": {
|
|
228
|
+
"optional": true
|
|
229
|
+
},
|
|
230
|
+
"mdast-util-to-markdown": {
|
|
231
|
+
"optional": true
|
|
232
|
+
},
|
|
233
|
+
"mdast-util-gfm-table": {
|
|
234
|
+
"optional": true
|
|
235
|
+
},
|
|
236
|
+
"parse5": {
|
|
237
|
+
"optional": true
|
|
238
|
+
}
|
|
193
239
|
},
|
|
194
240
|
"scripts": {
|
|
195
241
|
"build": "tsc -p tsconfig.json",
|