@smthrs/kernel 1.0.0-rc.5 → 1.0.0-rc.6
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 +4 -4
- package/dist/cjs/ChildProcessSpawner.d.ts +4 -4
- package/dist/cjs/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/cjs/ChildProcessSpawner.js +4 -4
- package/dist/cjs/ChildProcessSpawner.js.map +1 -1
- package/dist/cjs/CommandLine.d.ts +2 -2
- package/dist/cjs/CommandLine.d.ts.map +1 -1
- package/dist/cjs/CommandLine.js.map +1 -1
- package/dist/cjs/ContainedSpawner.d.ts +2 -2
- package/dist/cjs/ContainedSpawner.d.ts.map +1 -1
- package/dist/cjs/ContainedSpawner.js +2 -2
- package/dist/cjs/ContainedSpawner.js.map +2 -2
- package/dist/cjs/FileSystem.d.ts.map +1 -1
- package/dist/cjs/FileSystem.js +4 -3
- package/dist/cjs/FileSystem.js.map +2 -2
- package/dist/cjs/HostServices.d.ts +3 -3
- package/dist/cjs/HostServices.d.ts.map +1 -1
- package/dist/cjs/HostServices.js +2 -2
- package/dist/cjs/HostServices.js.map +1 -1
- package/dist/cjs/HttpClient.d.ts +5 -5
- package/dist/cjs/HttpClient.d.ts.map +1 -1
- package/dist/cjs/HttpClient.js +9 -9
- package/dist/cjs/HttpClient.js.map +1 -1
- package/dist/cjs/ProcessConfinement.d.ts +1 -1
- package/dist/cjs/ProcessConfinement.d.ts.map +1 -1
- package/dist/cjs/ProcessConfinement.js.map +1 -1
- package/dist/cjs/Rooted.d.ts +2 -2
- package/dist/cjs/Rooted.d.ts.map +1 -1
- package/dist/cjs/Rooted.js +2 -2
- package/dist/cjs/Rooted.js.map +1 -1
- package/dist/cjs/internal/Containment.d.ts +1 -1
- package/dist/cjs/internal/Containment.d.ts.map +1 -1
- package/dist/cjs/internal/Containment.js.map +1 -1
- package/dist/cjs/internal/Pipeline.d.ts +2 -2
- package/dist/cjs/internal/Pipeline.d.ts.map +1 -1
- package/dist/cjs/internal/Pipeline.js +2 -2
- package/dist/cjs/internal/Pipeline.js.map +2 -2
- package/dist/cjs/test/HostContract.d.ts +5 -5
- package/dist/cjs/test/HostContract.d.ts.map +1 -1
- package/dist/cjs/test/HostContract.js +4 -4
- package/dist/cjs/test/HostContract.js.map +1 -1
- package/dist/esm/ChildProcessSpawner.d.ts +4 -4
- package/dist/esm/ChildProcessSpawner.d.ts.map +1 -1
- package/dist/esm/ChildProcessSpawner.js +5 -5
- package/dist/esm/ChildProcessSpawner.js.map +1 -1
- package/dist/esm/CommandLine.d.ts +2 -2
- package/dist/esm/CommandLine.d.ts.map +1 -1
- package/dist/esm/CommandLine.js +1 -1
- package/dist/esm/CommandLine.js.map +1 -1
- package/dist/esm/ContainedSpawner.d.ts +2 -2
- package/dist/esm/ContainedSpawner.d.ts.map +1 -1
- package/dist/esm/ContainedSpawner.js +2 -2
- package/dist/esm/ContainedSpawner.js.map +1 -1
- package/dist/esm/FileSystem.d.ts.map +1 -1
- package/dist/esm/FileSystem.js +5 -4
- package/dist/esm/FileSystem.js.map +1 -1
- package/dist/esm/HostServices.d.ts +3 -3
- package/dist/esm/HostServices.d.ts.map +1 -1
- package/dist/esm/HostServices.js +2 -2
- package/dist/esm/HostServices.js.map +1 -1
- package/dist/esm/HttpClient.d.ts +5 -5
- package/dist/esm/HttpClient.d.ts.map +1 -1
- package/dist/esm/HttpClient.js +9 -9
- package/dist/esm/HttpClient.js.map +1 -1
- package/dist/esm/ProcessConfinement.d.ts +1 -1
- package/dist/esm/ProcessConfinement.d.ts.map +1 -1
- package/dist/esm/ProcessConfinement.js.map +1 -1
- package/dist/esm/Rooted.d.ts +2 -2
- package/dist/esm/Rooted.d.ts.map +1 -1
- package/dist/esm/Rooted.js +2 -2
- package/dist/esm/Rooted.js.map +1 -1
- package/dist/esm/internal/Containment.d.ts +1 -1
- package/dist/esm/internal/Containment.d.ts.map +1 -1
- package/dist/esm/internal/Containment.js.map +1 -1
- package/dist/esm/internal/Pipeline.d.ts +2 -2
- package/dist/esm/internal/Pipeline.d.ts.map +1 -1
- package/dist/esm/internal/Pipeline.js +2 -2
- package/dist/esm/internal/Pipeline.js.map +1 -1
- package/dist/esm/test/HostContract.d.ts +5 -5
- package/dist/esm/test/HostContract.d.ts.map +1 -1
- package/dist/esm/test/HostContract.js +4 -4
- package/dist/esm/test/HostContract.js.map +1 -1
- package/docs/api.md +2 -2
- package/docs/guides/adapt-a-new-host-platform.md +3 -3
- package/docs/installation.md +3 -3
- package/docs/quickstart.md +1 -1
- package/docs/testing.md +1 -1
- package/package.json +10 -11
- package/src/ChildProcessSpawner.ts +5 -5
- package/src/CommandLine.ts +2 -2
- package/src/ContainedSpawner.ts +2 -6
- package/src/FileSystem.ts +4 -4
- package/src/HostServices.ts +3 -3
- package/src/HttpClient.ts +9 -9
- package/src/ProcessConfinement.ts +1 -1
- package/src/Rooted.ts +2 -2
- package/src/internal/Containment.ts +1 -1
- package/src/internal/Pipeline.ts +2 -2
- package/src/test/HostContract.ts +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostServices.d.ts","sourceRoot":"","sources":["../../src/HostServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAA;AAClF,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"HostServices.d.ts","sourceRoot":"","sources":["../../src/HostServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAA;AAClF,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,mBAAmB,IAAI,uBAAuB,EAAE,MAAM,oCAAoC,CAAA;AAOnG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,MAAM,WAAW,GACnB,gBAAgB,CAAC,UAAU,GAC3B,UAAU,CAAC,IAAI,GACf,uBAAuB,GACvB,MAAM,GACN,cAAc,CAAA;AAElB;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,+TAMlB,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,2HAMjB,CAAA;AAEV;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK,6UAMjB,CAAA"}
|
package/dist/esm/HostServices.js
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { Jj as JjPort } from "@smthrs/jj";
|
|
18
18
|
import { FileSystem as EffectFileSystem, Layer, Path as EffectPath } from "effect";
|
|
19
|
-
import { HttpClient as HttpClientPort } from "effect/
|
|
20
|
-
import { ChildProcessSpawner as ChildProcessSpawnerPort } from "effect/
|
|
19
|
+
import { HttpClient as HttpClientPort } from "effect/http/HttpClient";
|
|
20
|
+
import { ChildProcessSpawner as ChildProcessSpawnerPort } from "effect/process/ChildProcessSpawner";
|
|
21
21
|
import * as ChildProcessSpawner from "./ChildProcessSpawner.js";
|
|
22
22
|
import * as FileSystem from "./FileSystem.js";
|
|
23
23
|
import * as HttpClient from "./HttpClient.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostServices.js","sourceRoot":"","sources":["../../src/HostServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAA;AAClF,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"HostServices.js","sourceRoot":"","sources":["../../src/HostServices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,KAAK,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAA;AAClF,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,mBAAmB,IAAI,uBAAuB,EAAE,MAAM,oCAAoC,CAAA;AACnG,OAAO,KAAK,mBAAmB,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAkDjC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,gBAAgB,CAAC,UAAU;IAC3B,UAAU,CAAC,IAAI;IACf,uBAAuB;IACvB,MAAM;IACN,cAAc;CACN,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,mBAAmB;IACnB,aAAa;IACb,oCAAoC;IACpC,eAAe;IACf,mBAAmB;CACX,CAAA;AAEV;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CACjC,UAAU,CAAC,KAAK,EAChB,IAAI,CAAC,KAAK,EACV,mBAAmB,CAAC,KAAK,EACzB,EAAE,CAAC,KAAK,EACR,UAAU,CAAC,KAAK,CACjB,CAAA","sourcesContent":["/**\n * The closed Host service list.\n *\n * One list, one set of tags. The kernel decorates each slot **in place** — a\n * middleware `Layer` over the very tag the platform adapter provides — so\n * there is no second, \"protected\" tag to keep in slot-order sync with this\n * one, and no cast to force a guarded implementation onto a narrower error\n * contract.\n *\n * Governing design:\n * `docs/specs/Concepts/Permission Kernel.md`,\n * `docs/specs/Concepts/Trust Granularity.md`, and\n * `docs/specs/Concepts/Host Adapters.md`.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { Jj as JjPort } from \"@smthrs/jj\"\nimport { FileSystem as EffectFileSystem, Layer, Path as EffectPath } from \"effect\"\nimport { HttpClient as HttpClientPort } from \"effect/http/HttpClient\"\nimport { ChildProcessSpawner as ChildProcessSpawnerPort } from \"effect/process/ChildProcessSpawner\"\nimport * as ChildProcessSpawner from \"./ChildProcessSpawner.ts\"\nimport * as FileSystem from \"./FileSystem.ts\"\nimport * as HttpClient from \"./HttpClient.ts\"\nimport * as Jj from \"./Jj.ts\"\nimport * as Path from \"./Path.ts\"\n\n/**\n * The CLOSED LIST of platform ports the kernel protects.\n * Optional filesystem batches belong to the existing FileSystem slot. The\n * decorator grants each member separately and exposes no additional tag or\n * unguarded executor to consumers; host slot identities remain unchanged.\n *\n * Everything that touches the outside world enters Smithers through exactly one\n * of these tags — there is no ambient `node:fs`, no bare `spawn`, no global\n * `Date.now()`. Two things depend on that closure:\n *\n * 1. The capability kernel wraps precisely this list. A service that is not\n * here cannot be attenuated, denied, or audited, so it must not exist.\n * 2. Step keys digest this list as their `layers` component. Which platform\n * implementations were in scope is part of a step's identity, so a replay\n * under different layers is a different step rather than a silent lie.\n *\n * Each slot's guarded implementation replaces the raw one under the same tag,\n * so a consumer that never heard of the kernel still cannot bypass it. Where\n * Effect owns the tag (`FileSystem`, `Path`, `ChildProcessSpawner`,\n * `HttpClient`) the error channel stays Effect's own — `PlatformError`, or\n * `HttpClientError` for the network — and permission failures are projected\n * into it by `Permission.toPlatformError` and `HttpClient.toHttpClientError`;\n * where Smithers owns the service (`Jj`) the interface names the kernel's\n * failures directly.\n *\n * `Path` is intentionally retained as an explicit decision: it checks nothing\n * and resolves relative paths against `Workspace.root`.\n * Network access is Effect's own `HttpClient`: there is no Smithers transport\n * port beneath it, because a raw port would be a second way to reach the\n * network whose contract never mentions permission.\n *\n * `Clock` and `Random` are Effect core built-ins: already port-shaped, already\n * swappable via `Effect.provideService`, and never decorated here — a `Clock`\n * or a `Random` carries no host authority to guard, so they are not ours to\n * define. `ChildProcessSpawner` is the same story one layer out: process spawning is\n * `effect/process`, and the slot holds Effect's tag rather than a\n * Smithers wrapper around it.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type HostService =\n | EffectFileSystem.FileSystem\n | EffectPath.Path\n | ChildProcessSpawnerPort\n | JjPort\n | HttpClientPort\n\n/**\n * The Host tags consumed by the kernel at runtime, decorated in place by\n * {@link layer}, and digested by the step-key planner.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport const HostServiceTags = [\n EffectFileSystem.FileSystem,\n EffectPath.Path,\n ChildProcessSpawnerPort,\n JjPort,\n HttpClientPort\n] as const\n\n/**\n * Stable slot identifiers shared by host composition, kernel attenuation, and\n * step-layer resolution.\n *\n * Each id is the tag key of its slot's service — Effect's own key for the\n * services Effect ships, the defining module's path for ours. The ids are\n * digested into step keys, so a rename invalidates every cached step naming\n * the slot; rename only when the service itself changes, as when `Shell` was\n * replaced by Effect's `ChildProcessSpawner`.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport const HostServiceIds = [\n \"effect/FileSystem\",\n \"effect/Path\",\n \"effect/process/ChildProcessSpawner\",\n \"@smthrs/jj/Jj\",\n \"effect/HttpClient\"\n] as const\n\n/**\n * Builds the full protected Host surface over a host platform bundle and a\n * `GrantStore`. `Workspace` remains a requirement so the exact same root\n * service can be supplied to both the grant store and filesystem decorators.\n *\n * Every member both requires and provides its own slot's tag: provide this\n * layer over a raw platform bundle and the guarded implementation shadows the\n * raw one for everything downstream. There is no exception and no second tag\n * list — `HttpClient` decorates Effect's network tag exactly the way\n * `FileSystem` decorates Effect's filesystem tag. The host supplies\n * `ProcessConfinement` for approved processes; absence refuses spawning.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layer = Layer.mergeAll(\n FileSystem.layer,\n Path.layer,\n ChildProcessSpawner.layer,\n Jj.layer,\n HttpClient.layer\n)\n"]}
|
package/dist/esm/HttpClient.d.ts
CHANGED
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import { type PermissionError, type PermissionErrorPayload } from "@smthrs/capability/Permission";
|
|
38
38
|
import { Context, Effect, Layer, Option } from "effect";
|
|
39
|
-
import * as EffectHttpClient from "effect/
|
|
40
|
-
import * as HttpClientError from "effect/
|
|
41
|
-
import * as HttpClientRequest from "effect/
|
|
39
|
+
import * as EffectHttpClient from "effect/http/HttpClient";
|
|
40
|
+
import * as HttpClientError from "effect/http/HttpClientError";
|
|
41
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
42
42
|
import { GrantStore } from "./GrantStore.ts";
|
|
43
43
|
/**
|
|
44
44
|
* Effect's own outgoing HTTP client tag, unchanged. Re-exported so the kernel
|
|
@@ -47,7 +47,7 @@ import { GrantStore } from "./GrantStore.ts";
|
|
|
47
47
|
* @category services
|
|
48
48
|
* @since 1.0.0-rc.0
|
|
49
49
|
*/
|
|
50
|
-
export { HttpClient } from "effect/
|
|
50
|
+
export { HttpClient } from "effect/http/HttpClient";
|
|
51
51
|
/**
|
|
52
52
|
* Constructs a client from a low-level request runner, keeping Effect's own
|
|
53
53
|
* URL construction, tracing, header redaction, and interruption behavior.
|
|
@@ -55,7 +55,7 @@ export { HttpClient } from "effect/unstable/http/HttpClient";
|
|
|
55
55
|
* @category constructors
|
|
56
56
|
* @since 1.0.0-rc.0
|
|
57
57
|
*/
|
|
58
|
-
export { make } from "effect/
|
|
58
|
+
export { make } from "effect/http/HttpClient";
|
|
59
59
|
/**
|
|
60
60
|
* The model identity an outgoing request is made on behalf of, if any.
|
|
61
61
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.d.ts","sourceRoot":"","sources":["../../src/HttpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAIvD,OAAO,KAAK,gBAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"HttpClient.d.ts","sourceRoot":"","sources":["../../src/HttpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC5B,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAIvD,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAA;AAC9D,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAA;AAElE,OAAO,EAAE,UAAU,EAAgC,MAAM,iBAAiB,CAAA;AAyD1E;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEnD;;;;;;GAMG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAE7C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAG3D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAC/D,CAAA;AAEnD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS;IACzC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,CAAA;IACrD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;CAChC,KAAG,eAAe,CAAC,eAOhB,CAAA;AAEJ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,eAAe,CAAC,eAAe,KACrC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAGpB,CAAA;AAEnB;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,QAAO,gBAAgB,CAAC,UAU1C,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QAAO,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,CACZ,CAAA;AA6CxD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EACxC,SAAS,iBAAiB,CAAC,iBAAiB,EAC5C,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,eAAe,EAAE,CAAC,GAAG,UAAU,CAQnE,CAAA;AAYJ;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAC7B,gBAAgB,CAAC,UAAU,EAC3B,KAAK,EACL,gBAAgB,CAAC,UAAU,GAAG,UAAU,CAiDzC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW;qBAEH,MAAM;wBACH,aAAa,CAAC,MAAM,CAAC;cAEgC,CAAA;AAI7E;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAG,CAGzF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAI,QAAQ,gBAAgB,CAAC,UAAU,KAAG,OAAoC,CAAA"}
|
package/dist/esm/HttpClient.js
CHANGED
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import { formatError, isPermissionError, PermissionDenied } from "@smthrs/capability/Permission";
|
|
38
38
|
import { Context, Effect, Layer, Option } from "effect";
|
|
39
|
-
import * as FetchHttpClient from "effect/
|
|
40
|
-
import * as Headers from "effect/
|
|
41
|
-
import * as HttpBody from "effect/
|
|
42
|
-
import * as EffectHttpClient from "effect/
|
|
43
|
-
import * as HttpClientError from "effect/
|
|
44
|
-
import * as HttpClientRequest from "effect/
|
|
45
|
-
import * as UrlParams from "effect/
|
|
39
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
40
|
+
import * as Headers from "effect/http/Headers";
|
|
41
|
+
import * as HttpBody from "effect/http/HttpBody";
|
|
42
|
+
import * as EffectHttpClient from "effect/http/HttpClient";
|
|
43
|
+
import * as HttpClientError from "effect/http/HttpClientError";
|
|
44
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
45
|
+
import * as UrlParams from "effect/http/UrlParams";
|
|
46
46
|
import { GrantStore } from "./GrantStore.js";
|
|
47
47
|
import { makeCapability } from "./internal/makeCapability.js";
|
|
48
48
|
const snapshotRawBody = (value) => {
|
|
@@ -95,7 +95,7 @@ const invalidRequest = (request) => new HttpClientError.HttpClientError({
|
|
|
95
95
|
* @category services
|
|
96
96
|
* @since 1.0.0-rc.0
|
|
97
97
|
*/
|
|
98
|
-
export { HttpClient } from "effect/
|
|
98
|
+
export { HttpClient } from "effect/http/HttpClient";
|
|
99
99
|
/**
|
|
100
100
|
* Constructs a client from a low-level request runner, keeping Effect's own
|
|
101
101
|
* URL construction, tracing, header redaction, and interruption behavior.
|
|
@@ -103,7 +103,7 @@ export { HttpClient } from "effect/unstable/http/HttpClient";
|
|
|
103
103
|
* @category constructors
|
|
104
104
|
* @since 1.0.0-rc.0
|
|
105
105
|
*/
|
|
106
|
-
export { make } from "effect/
|
|
106
|
+
export { make } from "effect/http/HttpClient";
|
|
107
107
|
/**
|
|
108
108
|
* The model identity an outgoing request is made on behalf of, if any.
|
|
109
109
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/HttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Permission-aware outgoing HTTP requests.\n *\n * There is no kernel `HttpClient` interface and no kernel `HttpClient` tag.\n * Effect owns both, and its tag fixes the error channel to `HttpClientError`,\n * so this module is only the middleware: a `Layer` over Effect's own tag that\n * reads the raw client out of context and returns a guarded one in its place.\n * Permission failures are projected into `HttpClientError` by\n * {@link toHttpClientError}, which keeps the structured kernel failure on the\n * transport reason's `cause` so {@link fromHttpClientError} can hand it back.\n *\n * **Redirects.** A redirect is a second network destination, so it needs a\n * second grant check. Two halves guarantee that:\n *\n * 1. The client below this layer must **not** follow redirects on its own.\n * That is a precondition on the host: Undici without a redirect\n * interceptor, or Effect's fetch layer with `redirect: \"manual\"`. This\n * layer also forces `RequestInit { redirect: \"manual\" }` over the ambient\n * value for every request it executes, so a plain `FetchHttpClient.layer`,\n * which follows redirects by default, cannot walk to another origin below\n * the guard either. A custom client that ignores `RequestInit` must meet\n * the precondition itself.\n * 2. This layer composes Effect's own `HttpClient.followRedirects` *above*\n * the guard. That combinator re-enters `postprocess` for every hop, and\n * `postprocess` is the guarded one, so hop *n* is checked exactly like hop\n * zero and an authorized origin cannot lend its grant to another.\n * A caller that sets `FetchHttpClient.RequestInit.redirect` to `manual`\n * receives one guarded hop and owns any further redirect requests itself.\n *\n * Governing design:\n * `docs/specs/Concepts/Permission Kernel.md`,\n * `docs/specs/Concepts/Effect Taxonomy.md`, and\n * `docs/specs/Concepts/Host Adapters.md`.\n *\n * @since 1.0.0-rc.0\n */\n\nimport type { Capability } from \"@smthrs/capability/Capability\"\nimport {\n formatError,\n isPermissionError,\n PermissionDenied,\n type PermissionError,\n type PermissionErrorPayload\n} from \"@smthrs/capability/Permission\"\nimport { Context, Effect, Layer, Option } from \"effect\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport * as Headers from \"effect/unstable/http/Headers\"\nimport * as HttpBody from \"effect/unstable/http/HttpBody\"\nimport * as EffectHttpClient from \"effect/unstable/http/HttpClient\"\nimport * as HttpClientError from \"effect/unstable/http/HttpClientError\"\nimport * as HttpClientRequest from \"effect/unstable/http/HttpClientRequest\"\nimport * as UrlParams from \"effect/unstable/http/UrlParams\"\nimport { GrantStore, type Service as GrantService } from \"./GrantStore.ts\"\nimport { makeCapability } from \"./internal/makeCapability.ts\"\n\nconst snapshotRawBody = (value: unknown): unknown => {\n if (value instanceof globalThis.Uint8Array) return value.slice()\n if (value instanceof ArrayBuffer) return value.slice(0)\n if (value instanceof URLSearchParams) {\n return new URLSearchParams(value)\n }\n if (value instanceof Blob) return value\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value\n }\n throw new TypeError(\"raw HTTP bodies must be immutable or copyable\")\n}\n\nconst snapshotBody = (body: HttpBody.HttpBody): HttpBody.HttpBody => {\n switch (body._tag) {\n case \"Empty\":\n return HttpBody.empty\n case \"Raw\":\n return HttpBody.raw(snapshotRawBody(body.body), {\n contentType: body.contentType,\n contentLength: body.contentLength\n })\n case \"Uint8Array\":\n return HttpBody.uint8Array(body.body.slice(), body.contentType)\n case \"FormData\": {\n const formData = new globalThis.FormData()\n for (const [name, value] of body.formData.entries()) formData.append(name, value)\n return HttpBody.formData(formData)\n }\n case \"Stream\":\n return HttpBody.stream(body.stream, body.contentType, body.contentLength)\n }\n}\n\nconst snapshotRequest = (request: HttpClientRequest.HttpClientRequest): HttpClientRequest.HttpClientRequest =>\n HttpClientRequest.makeWith(\n request.method,\n request.url,\n UrlParams.make(\n Object.freeze(request.urlParams.params.map(([name, value]) => Object.freeze([name, value] as const)))\n ),\n Option.map(request.hash, (value) => value),\n Headers.fromInput(request.headers),\n snapshotBody(request.body)\n )\n\nconst invalidRequest = (request: HttpClientRequest.HttpClientRequest): HttpClientError.HttpClientError =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"HTTP request must be an immutable supported request description\"\n })\n })\n\n/**\n * Effect's own outgoing HTTP client tag, unchanged. Re-exported so the kernel\n * namespace stays one-stop; it is the *same* tag, never a second one.\n *\n * @category services\n * @since 1.0.0-rc.0\n */\nexport { HttpClient } from \"effect/unstable/http/HttpClient\"\n\n/**\n * Constructs a client from a low-level request runner, keeping Effect's own\n * URL construction, tracing, header redaction, and interruption behavior.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport { make } from \"effect/unstable/http/HttpClient\"\n\n/**\n * The model identity an outgoing request is made on behalf of, if any.\n *\n * A model call is not a general `net:*` effect: the same host answers many\n * models, and a grant for one must not be a grant for the rest. Effect's tag\n * has no room for an extra method, so the intent rides on a `Context`\n * reference instead — set it with {@link withModelCall} and the decorator asks\n * for `model:call` rather than `net:get`/`net:post`.\n *\n * @category references\n * @since 1.0.0-rc.0\n */\nexport const ModelCall: Context.Reference<string | undefined> = Context.Reference<string | undefined>(\n \"@smthrs/kernel/HttpClient/ModelCall\",\n { defaultValue: (): string | undefined => undefined }\n)\n\n/**\n * Runs `effect` with every outgoing request in it checked as a `model:call` on\n * `modelId` instead of as plain network access.\n *\n * @category references\n * @since 1.0.0-rc.0\n */\nexport const withModelCall = (modelId: string) => <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.provideService(effect, ModelCall, modelId)\n\n/**\n * Projects a permission failure into the error channel Effect's `HttpClient`\n * tag fixes.\n *\n * Nothing is lost: the reason is always a `TransportError` — the request did\n * not leave the host because the capability kernel refused, suspended, or\n * could not decide it — `description` carries the human rendering from\n * `Permission.formatError`, and `cause` carries the structured failure itself,\n * so {@link fromHttpClientError} hands the attended surface back the original\n * `capability`, `tier`, `requestId`, and `reason`.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const toHttpClientError = (options: {\n readonly request: HttpClientRequest.HttpClientRequest\n readonly error: PermissionError\n}): HttpClientError.HttpClientError =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request: options.request,\n description: formatError(options.error),\n cause: options.error\n })\n })\n\n/**\n * Recovers the structured permission failure a {@link toHttpClientError}\n * projection carries, so an attended surface can still reply to the request\n * and an unattended report can still name the capability.\n *\n * Recovery validates data fields and the transport reason tag, not origin or\n * class operations. Establish producer or request identity separately across\n * a trust boundary.\n *\n * @category refinements\n * @since 1.0.0-rc.0\n */\nexport const fromHttpClientError = (\n error: HttpClientError.HttpClientError\n): Option.Option<PermissionErrorPayload> =>\n error.reason._tag === \"TransportError\" && isPermissionError(error.reason.cause)\n ? Option.some(error.reason.cause)\n : Option.none()\n\n/**\n * Constructs an unavailable HTTP client stub.\n *\n * Every request reports the missing host as a `TransportError` naming the\n * request, so an unconfigured capability answers rather than vanishing.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const makeNoop = (): EffectHttpClient.HttpClient =>\n EffectHttpClient.make((request) =>\n Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n cause: new Error(\"HTTP is unavailable on this host\")\n })\n })\n )\n )\n\n/**\n * Provides an unavailable HTTP client stub.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layerNoop = (): Layer.Layer<EffectHttpClient.HttpClient> =>\n Layer.succeed(EffectHttpClient.HttpClient)(makeNoop())\n\n/**\n * Keeps HTTPS resources host-only so existing grants remain valid. Every\n * other scheme is explicit, which prevents an HTTPS grant from authorizing a\n * cleartext or otherwise different transport.\n */\nconst capabilityFor = (\n request: HttpClientRequest.HttpClientRequest,\n modelId: string | undefined\n): Effect.Effect<Capability, PermissionError> => {\n const action = modelId === undefined\n ? request.method === \"GET\" || request.method === \"HEAD\" ? \"net:get\" : \"net:post\"\n : \"model:call\"\n let url: URL\n try {\n url = new URL(request.url)\n } catch {\n return makeCapability(action, request.url).pipe(\n Effect.flatMap((capability) =>\n Effect.fail(\n new PermissionDenied({\n code: \"permission_denied\",\n capability,\n reason: \"HTTP capability checks require an absolute, parseable URL\"\n })\n )\n )\n )\n }\n const host = url.host.toLowerCase()\n const resource = url.protocol === \"https:\" ? host : `${url.protocol}//${host}`\n return makeCapability(action, modelId === undefined ? resource : `${resource}/${modelId}`)\n}\n\ninterface PreflightAdmission {\n readonly store: GrantService\n readonly capability: Capability\n consumed: boolean\n}\n\nconst Admission = Context.Reference<PreflightAdmission | undefined>(\"@smthrs/kernel/HttpClient/Admission\", {\n defaultValue: () => undefined\n})\n\n/**\n * Authorizes a request before a caller performs network preflight work such as\n * DNS. The guarded transport consumes the same admission once, so a one-shot\n * grant is not spent twice. Admissions match both store identity and the exact\n * capability; redirects and retries require their own authorization.\n *\n * @category authorization\n * @since 1.0.0\n */\nexport const authorizePreflight = <A, E, R>(\n request: HttpClientRequest.HttpClientRequest,\n effect: Effect.Effect<A, E, R>\n): Effect.Effect<A, E | HttpClientError.HttpClientError, R | GrantStore> =>\n Effect.gen(function*() {\n const store = yield* GrantStore\n const capability = yield* Effect.withFiber((fiber) => capabilityFor(request, fiber.getRef(ModelCall))).pipe(\n Effect.tap((capability) => store.check(capability)),\n Effect.mapError((error) => toHttpClientError({ request, error }))\n )\n return yield* Effect.provideService(effect, Admission, { store, capability, consumed: false })\n })\n\n/**\n * Forces `redirect: \"manual\"` on the fetch options a fetch-backed client reads\n * at execute time, keeping every other ambient field.\n */\nconst manualRedirects = (context: Context.Context<never>): Context.Context<never> =>\n Context.add(context, FetchHttpClient.RequestInit, {\n ...Context.getOrUndefined(context, FetchHttpClient.RequestInit),\n redirect: \"manual\"\n })\n\n/**\n * Decorates the HTTP client in place with a `net:get`/`net:post`/`model:call`\n * capability check, then follows redirects *through* that check.\n *\n * The layer provides the tag it also requires: compose it over a host client\n * layer with `Layer.provide` and a consumer that never heard of the kernel is\n * guarded too. Because every hop re-enters the guarded `postprocess`, an\n * authorized first URL that redirects to an unauthorized one is denied at the\n * second hop instead of being fetched.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layer: Layer.Layer<\n EffectHttpClient.HttpClient,\n never,\n EffectHttpClient.HttpClient | GrantStore\n> = Layer.effect(\n EffectHttpClient.HttpClient,\n Effect.gen(function*() {\n const client = yield* EffectHttpClient.HttpClient\n const grants = yield* GrantStore\n const snapshotted = EffectHttpClient.mapRequestEffect(\n client,\n (request) =>\n Effect.try({\n try: () => snapshotRequest(request),\n catch: () => invalidRequest(request)\n })\n )\n const guarded = EffectHttpClient.transform(\n snapshotted,\n (execute, request) =>\n Effect.withFiber((fiber) =>\n capabilityFor(request, fiber.getRef(ModelCall)).pipe(\n Effect.flatMap((capability) => {\n const admission = fiber.getRef(Admission)\n if (\n admission !== undefined && !admission.consumed && admission.store === grants\n && admission.capability.action === capability.action &&\n admission.capability.resource === capability.resource\n ) {\n admission.consumed = true\n return Effect.void\n }\n return grants.check(capability)\n }),\n Effect.mapError((error: PermissionError) => toHttpClientError({ request, error })),\n Effect.andThen(Effect.updateContext(execute, manualRedirects))\n )\n )\n )\n const followed = EffectHttpClient.followRedirects(guarded)\n const result = EffectHttpClient.makeWith(\n (request) =>\n Effect.withFiber((fiber) =>\n // Read caller policy before the guard forces manual transport.\n Context.getOrUndefined(fiber.context, FetchHttpClient.RequestInit)?.redirect === \"manual\"\n ? guarded.postprocess(request)\n : followed.postprocess(request)\n ),\n guarded.preprocess\n )\n return supportsDestinationPinning(client) ? withDestinationPinning(result) : result\n })\n)\n\n/**\n * Address snapshot authorized for one web request. Host transports must reject\n * a different origin and use only these addresses for every connection attempt.\n * Ordinary model traffic leaves this reference unset.\n * @category references\n * @since 1.0.0\n */\nexport const Destination = Context.Reference<\n {\n readonly origin: string\n readonly addresses: ReadonlyArray<string>\n } | undefined\n>(\"@smthrs/kernel/HttpClient/Destination\", { defaultValue: () => undefined })\n\nconst pinnedClients = new WeakSet<EffectHttpClient.HttpClient>()\n\n/**\n * Marks a trusted transport that enforces Destination on every connection.\n * The assertion belongs to this client instance, not ambient context. A\n * replacement client must establish its own transport guarantee.\n * @category constructors\n * @since 1.0.0\n */\nexport const withDestinationPinning = <A extends EffectHttpClient.HttpClient>(client: A): A => {\n pinnedClients.add(client)\n return client\n}\n\n/**\n * Whether this exact client implements the Destination transport contract.\n * @category predicates\n * @since 1.0.0\n */\nexport const supportsDestinationPinning = (client: EffectHttpClient.HttpClient): boolean => pinnedClients.has(client)\n"]}
|
|
1
|
+
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/HttpClient.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Permission-aware outgoing HTTP requests.\n *\n * There is no kernel `HttpClient` interface and no kernel `HttpClient` tag.\n * Effect owns both, and its tag fixes the error channel to `HttpClientError`,\n * so this module is only the middleware: a `Layer` over Effect's own tag that\n * reads the raw client out of context and returns a guarded one in its place.\n * Permission failures are projected into `HttpClientError` by\n * {@link toHttpClientError}, which keeps the structured kernel failure on the\n * transport reason's `cause` so {@link fromHttpClientError} can hand it back.\n *\n * **Redirects.** A redirect is a second network destination, so it needs a\n * second grant check. Two halves guarantee that:\n *\n * 1. The client below this layer must **not** follow redirects on its own.\n * That is a precondition on the host: Undici without a redirect\n * interceptor, or Effect's fetch layer with `redirect: \"manual\"`. This\n * layer also forces `RequestInit { redirect: \"manual\" }` over the ambient\n * value for every request it executes, so a plain `FetchHttpClient.layer`,\n * which follows redirects by default, cannot walk to another origin below\n * the guard either. A custom client that ignores `RequestInit` must meet\n * the precondition itself.\n * 2. This layer composes Effect's own `HttpClient.followRedirects` *above*\n * the guard. That combinator re-enters `postprocess` for every hop, and\n * `postprocess` is the guarded one, so hop *n* is checked exactly like hop\n * zero and an authorized origin cannot lend its grant to another.\n * A caller that sets `FetchHttpClient.RequestInit.redirect` to `manual`\n * receives one guarded hop and owns any further redirect requests itself.\n *\n * Governing design:\n * `docs/specs/Concepts/Permission Kernel.md`,\n * `docs/specs/Concepts/Effect Taxonomy.md`, and\n * `docs/specs/Concepts/Host Adapters.md`.\n *\n * @since 1.0.0-rc.0\n */\n\nimport type { Capability } from \"@smthrs/capability/Capability\"\nimport {\n formatError,\n isPermissionError,\n PermissionDenied,\n type PermissionError,\n type PermissionErrorPayload\n} from \"@smthrs/capability/Permission\"\nimport { Context, Effect, Layer, Option } from \"effect\"\nimport * as FetchHttpClient from \"effect/http/FetchHttpClient\"\nimport * as Headers from \"effect/http/Headers\"\nimport * as HttpBody from \"effect/http/HttpBody\"\nimport * as EffectHttpClient from \"effect/http/HttpClient\"\nimport * as HttpClientError from \"effect/http/HttpClientError\"\nimport * as HttpClientRequest from \"effect/http/HttpClientRequest\"\nimport * as UrlParams from \"effect/http/UrlParams\"\nimport { GrantStore, type Service as GrantService } from \"./GrantStore.ts\"\nimport { makeCapability } from \"./internal/makeCapability.ts\"\n\nconst snapshotRawBody = (value: unknown): unknown => {\n if (value instanceof globalThis.Uint8Array) return value.slice()\n if (value instanceof ArrayBuffer) return value.slice(0)\n if (value instanceof URLSearchParams) {\n return new URLSearchParams(value)\n }\n if (value instanceof Blob) return value\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value\n }\n throw new TypeError(\"raw HTTP bodies must be immutable or copyable\")\n}\n\nconst snapshotBody = (body: HttpBody.HttpBody): HttpBody.HttpBody => {\n switch (body._tag) {\n case \"Empty\":\n return HttpBody.empty\n case \"Raw\":\n return HttpBody.raw(snapshotRawBody(body.body), {\n contentType: body.contentType,\n contentLength: body.contentLength\n })\n case \"Uint8Array\":\n return HttpBody.uint8Array(body.body.slice(), body.contentType)\n case \"FormData\": {\n const formData = new globalThis.FormData()\n for (const [name, value] of body.formData.entries()) formData.append(name, value)\n return HttpBody.formData(formData)\n }\n case \"Stream\":\n return HttpBody.stream(body.stream, body.contentType, body.contentLength)\n }\n}\n\nconst snapshotRequest = (request: HttpClientRequest.HttpClientRequest): HttpClientRequest.HttpClientRequest =>\n HttpClientRequest.makeWith(\n request.method,\n request.url,\n UrlParams.make(\n Object.freeze(request.urlParams.params.map(([name, value]) => Object.freeze([name, value] as const)))\n ),\n Option.map(request.hash, (value) => value),\n Headers.fromInput(request.headers),\n snapshotBody(request.body)\n )\n\nconst invalidRequest = (request: HttpClientRequest.HttpClientRequest): HttpClientError.HttpClientError =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n description: \"HTTP request must be an immutable supported request description\"\n })\n })\n\n/**\n * Effect's own outgoing HTTP client tag, unchanged. Re-exported so the kernel\n * namespace stays one-stop; it is the *same* tag, never a second one.\n *\n * @category services\n * @since 1.0.0-rc.0\n */\nexport { HttpClient } from \"effect/http/HttpClient\"\n\n/**\n * Constructs a client from a low-level request runner, keeping Effect's own\n * URL construction, tracing, header redaction, and interruption behavior.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport { make } from \"effect/http/HttpClient\"\n\n/**\n * The model identity an outgoing request is made on behalf of, if any.\n *\n * A model call is not a general `net:*` effect: the same host answers many\n * models, and a grant for one must not be a grant for the rest. Effect's tag\n * has no room for an extra method, so the intent rides on a `Context`\n * reference instead — set it with {@link withModelCall} and the decorator asks\n * for `model:call` rather than `net:get`/`net:post`.\n *\n * @category references\n * @since 1.0.0-rc.0\n */\nexport const ModelCall: Context.Reference<string | undefined> = Context.Reference<string | undefined>(\n \"@smthrs/kernel/HttpClient/ModelCall\",\n { defaultValue: (): string | undefined => undefined }\n)\n\n/**\n * Runs `effect` with every outgoing request in it checked as a `model:call` on\n * `modelId` instead of as plain network access.\n *\n * @category references\n * @since 1.0.0-rc.0\n */\nexport const withModelCall = (modelId: string) => <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.provideService(effect, ModelCall, modelId)\n\n/**\n * Projects a permission failure into the error channel Effect's `HttpClient`\n * tag fixes.\n *\n * Nothing is lost: the reason is always a `TransportError` — the request did\n * not leave the host because the capability kernel refused, suspended, or\n * could not decide it — `description` carries the human rendering from\n * `Permission.formatError`, and `cause` carries the structured failure itself,\n * so {@link fromHttpClientError} hands the attended surface back the original\n * `capability`, `tier`, `requestId`, and `reason`.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const toHttpClientError = (options: {\n readonly request: HttpClientRequest.HttpClientRequest\n readonly error: PermissionError\n}): HttpClientError.HttpClientError =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request: options.request,\n description: formatError(options.error),\n cause: options.error\n })\n })\n\n/**\n * Recovers the structured permission failure a {@link toHttpClientError}\n * projection carries, so an attended surface can still reply to the request\n * and an unattended report can still name the capability.\n *\n * Recovery validates data fields and the transport reason tag, not origin or\n * class operations. Establish producer or request identity separately across\n * a trust boundary.\n *\n * @category refinements\n * @since 1.0.0-rc.0\n */\nexport const fromHttpClientError = (\n error: HttpClientError.HttpClientError\n): Option.Option<PermissionErrorPayload> =>\n error.reason._tag === \"TransportError\" && isPermissionError(error.reason.cause)\n ? Option.some(error.reason.cause)\n : Option.none()\n\n/**\n * Constructs an unavailable HTTP client stub.\n *\n * Every request reports the missing host as a `TransportError` naming the\n * request, so an unconfigured capability answers rather than vanishing.\n *\n * @category constructors\n * @since 1.0.0-rc.0\n */\nexport const makeNoop = (): EffectHttpClient.HttpClient =>\n EffectHttpClient.make((request) =>\n Effect.fail(\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n cause: new Error(\"HTTP is unavailable on this host\")\n })\n })\n )\n )\n\n/**\n * Provides an unavailable HTTP client stub.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layerNoop = (): Layer.Layer<EffectHttpClient.HttpClient> =>\n Layer.succeed(EffectHttpClient.HttpClient)(makeNoop())\n\n/**\n * Keeps HTTPS resources host-only so existing grants remain valid. Every\n * other scheme is explicit, which prevents an HTTPS grant from authorizing a\n * cleartext or otherwise different transport.\n */\nconst capabilityFor = (\n request: HttpClientRequest.HttpClientRequest,\n modelId: string | undefined\n): Effect.Effect<Capability, PermissionError> => {\n const action = modelId === undefined\n ? request.method === \"GET\" || request.method === \"HEAD\" ? \"net:get\" : \"net:post\"\n : \"model:call\"\n let url: URL\n try {\n url = new URL(request.url)\n } catch {\n return makeCapability(action, request.url).pipe(\n Effect.flatMap((capability) =>\n Effect.fail(\n new PermissionDenied({\n code: \"permission_denied\",\n capability,\n reason: \"HTTP capability checks require an absolute, parseable URL\"\n })\n )\n )\n )\n }\n const host = url.host.toLowerCase()\n const resource = url.protocol === \"https:\" ? host : `${url.protocol}//${host}`\n return makeCapability(action, modelId === undefined ? resource : `${resource}/${modelId}`)\n}\n\ninterface PreflightAdmission {\n readonly store: GrantService\n readonly capability: Capability\n consumed: boolean\n}\n\nconst Admission = Context.Reference<PreflightAdmission | undefined>(\"@smthrs/kernel/HttpClient/Admission\", {\n defaultValue: () => undefined\n})\n\n/**\n * Authorizes a request before a caller performs network preflight work such as\n * DNS. The guarded transport consumes the same admission once, so a one-shot\n * grant is not spent twice. Admissions match both store identity and the exact\n * capability; redirects and retries require their own authorization.\n *\n * @category authorization\n * @since 1.0.0\n */\nexport const authorizePreflight = <A, E, R>(\n request: HttpClientRequest.HttpClientRequest,\n effect: Effect.Effect<A, E, R>\n): Effect.Effect<A, E | HttpClientError.HttpClientError, R | GrantStore> =>\n Effect.gen(function*() {\n const store = yield* GrantStore\n const capability = yield* Effect.withFiber((fiber) => capabilityFor(request, fiber.getRef(ModelCall))).pipe(\n Effect.tap((capability) => store.check(capability)),\n Effect.mapError((error) => toHttpClientError({ request, error }))\n )\n return yield* Effect.provideService(effect, Admission, { store, capability, consumed: false })\n })\n\n/**\n * Forces `redirect: \"manual\"` on the fetch options a fetch-backed client reads\n * at execute time, keeping every other ambient field.\n */\nconst manualRedirects = (context: Context.Context<never>): Context.Context<never> =>\n Context.add(context, FetchHttpClient.RequestInit, {\n ...Context.getOrUndefined(context, FetchHttpClient.RequestInit),\n redirect: \"manual\"\n })\n\n/**\n * Decorates the HTTP client in place with a `net:get`/`net:post`/`model:call`\n * capability check, then follows redirects *through* that check.\n *\n * The layer provides the tag it also requires: compose it over a host client\n * layer with `Layer.provide` and a consumer that never heard of the kernel is\n * guarded too. Because every hop re-enters the guarded `postprocess`, an\n * authorized first URL that redirects to an unauthorized one is denied at the\n * second hop instead of being fetched.\n *\n * @category layers\n * @since 1.0.0-rc.0\n */\nexport const layer: Layer.Layer<\n EffectHttpClient.HttpClient,\n never,\n EffectHttpClient.HttpClient | GrantStore\n> = Layer.effect(\n EffectHttpClient.HttpClient,\n Effect.gen(function*() {\n const client = yield* EffectHttpClient.HttpClient\n const grants = yield* GrantStore\n const snapshotted = EffectHttpClient.mapRequestEffect(\n client,\n (request) =>\n Effect.try({\n try: () => snapshotRequest(request),\n catch: () => invalidRequest(request)\n })\n )\n const guarded = EffectHttpClient.transform(\n snapshotted,\n (execute, request) =>\n Effect.withFiber((fiber) =>\n capabilityFor(request, fiber.getRef(ModelCall)).pipe(\n Effect.flatMap((capability) => {\n const admission = fiber.getRef(Admission)\n if (\n admission !== undefined && !admission.consumed && admission.store === grants\n && admission.capability.action === capability.action &&\n admission.capability.resource === capability.resource\n ) {\n admission.consumed = true\n return Effect.void\n }\n return grants.check(capability)\n }),\n Effect.mapError((error: PermissionError) => toHttpClientError({ request, error })),\n Effect.andThen(Effect.updateContext(execute, manualRedirects))\n )\n )\n )\n const followed = EffectHttpClient.followRedirects(guarded)\n const result = EffectHttpClient.makeWith(\n (request) =>\n Effect.withFiber((fiber) =>\n // Read caller policy before the guard forces manual transport.\n Context.getOrUndefined(fiber.context, FetchHttpClient.RequestInit)?.redirect === \"manual\"\n ? guarded.postprocess(request)\n : followed.postprocess(request)\n ),\n guarded.preprocess\n )\n return supportsDestinationPinning(client) ? withDestinationPinning(result) : result\n })\n)\n\n/**\n * Address snapshot authorized for one web request. Host transports must reject\n * a different origin and use only these addresses for every connection attempt.\n * Ordinary model traffic leaves this reference unset.\n * @category references\n * @since 1.0.0\n */\nexport const Destination = Context.Reference<\n {\n readonly origin: string\n readonly addresses: ReadonlyArray<string>\n } | undefined\n>(\"@smthrs/kernel/HttpClient/Destination\", { defaultValue: () => undefined })\n\nconst pinnedClients = new WeakSet<EffectHttpClient.HttpClient>()\n\n/**\n * Marks a trusted transport that enforces Destination on every connection.\n * The assertion belongs to this client instance, not ambient context. A\n * replacement client must establish its own transport guarantee.\n * @category constructors\n * @since 1.0.0\n */\nexport const withDestinationPinning = <A extends EffectHttpClient.HttpClient>(client: A): A => {\n pinnedClients.add(client)\n return client\n}\n\n/**\n * Whether this exact client implements the Destination transport contract.\n * @category predicates\n * @since 1.0.0\n */\nexport const supportsDestinationPinning = (client: EffectHttpClient.HttpClient): boolean => pinnedClients.has(client)\n"]}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import type { GrantStoreError } from "@smthrs/capability/Permission";
|
|
5
5
|
import { Context, Effect, Layer, type Path, type Scope } from "effect";
|
|
6
6
|
import type { PlatformError } from "effect/PlatformError";
|
|
7
|
-
import type * as ChildProcess from "effect/
|
|
7
|
+
import type * as ChildProcess from "effect/process/ChildProcess";
|
|
8
8
|
import type { Service as GrantService } from "./GrantStore.ts";
|
|
9
9
|
/** Workspace-relative trees; `.` names the workspace. No path opens its parent.
|
|
10
10
|
* @category models
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProcessConfinement.d.ts","sourceRoot":"","sources":["../../src/ProcessConfinement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"ProcessConfinement.d.ts","sourceRoot":"","sources":["../../src/ProcessConfinement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,KAAK,YAAY,MAAM,6BAA6B,CAAA;AAChE,OAAO,KAAK,EAAsB,OAAO,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAElF;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAClC;AACD;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,OAAO,EAAE,CAChB,OAAO,EAAE,YAAY,CAAC,eAAe,EACrC,OAAO,EAAE,OAAO,KACb,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;CAC7E;;AACD;;;GAGG;AACH,qBAAa,kBACX,SAAQ,uBAAmF;CAC3F;AACF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,OAAkF,CAAA;AACzG;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAA+C,CAAA;AAqCrG;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,YAAY,EACpB,eAAe,MAAM,EACrB,MAAM,IAAI,CAAC,IAAI,KACd,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAiDrC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProcessConfinement.js","sourceRoot":"","sources":["../../src/ProcessConfinement.ts"],"names":[],"mappings":"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","sourcesContent":["/** Operating-system confinement derived conservatively from effective grants.\n * @since 1.0.0-rc.1\n */\n\nimport {\n type Action,\n Capability,\n CapabilityPattern,\n matches,\n maxResourceLength,\n subsumes,\n withinMatchBudget\n} from \"@smthrs/capability/Capability\"\nimport type { GrantStoreError } from \"@smthrs/capability/Permission\"\nimport { Context, Effect, Layer, type Path, type Scope } from \"effect\"\nimport type { PlatformError } from \"effect/PlatformError\"\nimport type * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport type { Policy, PolicyRule, Service as GrantService } from \"./GrantStore.ts\"\n\n/** Workspace-relative trees; `.` names the workspace. No path opens its parent.\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface Profile {\n readonly workspaceRoot: string\n readonly reads: ReadonlyArray<string>\n readonly writes: ReadonlyArray<string>\n readonly readOnly: ReadonlyArray<string>\n readonly network: \"none\" | \"open\"\n}\n/** Host wrapper for one process stage. Failure must occur before spawning.\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface Service {\n readonly confine: (\n command: ChildProcess.StandardCommand,\n profile: Profile\n ) => Effect.Effect<ChildProcess.StandardCommand, PlatformError, Scope.Scope>\n}\n/** Host confinement seam; missing service refuses spawning.\n * @category services\n * @since 1.0.0-rc.1\n */\nexport class ProcessConfinement\n extends Context.Service<ProcessConfinement, Service>()(\"@smthrs/kernel/ProcessConfinement\")\n{}\n/** Explicit unconfined composition.\n * @category constructors\n * @since 1.0.0-rc.1\n */\nexport const makeNoop: Service = ProcessConfinement.of({ confine: (command) => Effect.succeed(command) })\n/** Explicit unconfined layer.\n * @category layers\n * @since 1.0.0-rc.1\n */\nexport const layerNoop: Layer.Layer<ProcessConfinement> = Layer.succeed(ProcessConfinement)(makeNoop)\n\nconst decidable = (pattern: CapabilityPattern, action: Action) =>\n withinMatchBudget(pattern, new Capability({ action, resource: \"x\".repeat(maxResourceLength) }))\n\n// The capability matcher permits a single star to cross separators. Only\n// this universal spelling is equivalent to **; arbitrary globs stay closed.\nconst universal = (pattern: CapabilityPattern): CapabilityPattern =>\n pattern.resource === \"*\" ? new CapabilityPattern({ action: pattern.action, resource: \"**\" }) : pattern\n\nconst coversCeiling = (ceiling: PolicyRule[\"ceiling\"], target: CapabilityPattern): boolean =>\n ceiling.groups.every((group) =>\n group.some((pattern) => decidable(pattern, target.action as Action) && subsumes(universal(pattern), target))\n )\nconst actionRelevant = (pattern: CapabilityPattern, action: Action): boolean =>\n matches(new CapabilityPattern({ action: pattern.action, resource: \"**\" }), new Capability({ action, resource: \"\" }))\n\n// A covering rule resolves the complete region. A narrower/conditional refusal\n// makes it unknown until a later covering rule resolves it. Unknown configured\n// denial vetoes all later grant groups, just as evaluate's configured veto does.\nconst prove = (policy: Policy, target: CapabilityPattern): boolean => {\n if (!coversCeiling(policy.ceiling, target)) return false\n let decision: \"allow\" | \"deny\" | \"ask\" | \"unknown\" = \"ask\"\n let configured: \"allow\" | \"deny\" | \"ask\" | \"unknown\" = \"ask\"\n for (const [index, group] of policy.groups.entries()) {\n for (const { rule, ceiling } of group) {\n if (!decidable(rule.pattern, target.action as Action)) return false\n if (!actionRelevant(rule.pattern, target.action as Action)) continue\n if (target.action === \"net:private\" && rule.effect === \"allow\" && rule.pattern.action !== \"net:private\") continue\n if (coversCeiling(ceiling, target) && subsumes(universal(rule.pattern), target)) decision = rule.effect\n else if (rule.effect !== \"allow\") decision = \"unknown\"\n if (index === 0) configured = decision\n }\n }\n return configured !== \"deny\" && configured !== \"unknown\" && decision === \"allow\"\n}\n\n/** Derives a subset of authority, never a widening. Literal filesystem grants,\n * complex globs and unrepresentable restrictions conservatively open nothing.\n * Writable trees also require read authority and write authority over their\n * exact directory root: native mounts permit reads and directory metadata\n * changes. Only whole-tree grants prove filesystem trees; unrestricted\n * authority for each of get/post/private is required to open network access.\n * @category resolution\n * @since 1.0.0-rc.1\n */\nexport const profile = (\n grants: GrantService,\n workspaceRoot: string,\n path: Path.Path\n): Effect.Effect<Profile, GrantStoreError> =>\n Effect.gen(function*() {\n const policy = yield* grants.policy\n const root = path.resolve(workspaceRoot)\n const resources = [\n ...policy.groups.flatMap((group) =>\n group.flatMap(({ rule, ceiling }) => [rule.pattern, ...ceiling.groups.flat()])\n ),\n ...policy.ceiling.groups.flat()\n ]\n const candidates = new Set<string>()\n for (const { resource } of resources) {\n if (resource === \"**\" || resource === \"*\") {\n candidates.add(\".\")\n continue\n }\n if (!resource.endsWith(\"/**\") || /[*?]/.test(resource.slice(0, -3))) continue\n const base = resource.slice(0, -3)\n // Relative policy resources do not authorize absolute kernel resources.\n if (!path.isAbsolute(base) || path.normalize(base) !== base) continue\n const relative = path.relative(root, base)\n if (path.isAbsolute(relative) || relative.split(path.sep)[0] === \"..\") continue\n candidates.add(relative === \"\" ? \".\" : relative.split(path.sep).join(\"/\"))\n }\n const opened = (action: Action) =>\n [...candidates].filter((relative) => {\n const directory = relative === \".\" ? root : path.resolve(root, relative)\n const resource = `${directory}/**`\n return prove(policy, new CapabilityPattern({ action, resource })) &&\n (action !== \"fs:write\" || (\n prove(policy, new CapabilityPattern({ action: \"fs:read\", resource })) &&\n prove(policy, new CapabilityPattern({ action: \"fs:write\", resource: directory }))\n ))\n })\n .filter((relative, _, all) =>\n !all.some((parent) => parent !== relative && (parent === \".\" || relative.startsWith(`${parent}/`)))\n )\n .sort()\n return Object.freeze({\n workspaceRoot: root,\n reads: Object.freeze(opened(\"fs:read\")),\n writes: Object.freeze(opened(\"fs:write\")),\n readOnly: Object.freeze([]),\n network: ([\"net:get\", \"net:post\", \"net:private\"] as const).every((action) =>\n prove(policy, new CapabilityPattern({ action, resource: \"**\" }))\n ) ?\n \"open\" as const :\n \"none\" as const\n })\n })\n"]}
|
|
1
|
+
{"version":3,"file":"ProcessConfinement.js","sourceRoot":"","sources":["../../src/ProcessConfinement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAEL,UAAU,EACV,iBAAiB,EACjB,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,iBAAiB,EAClB,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAyB,MAAM,QAAQ,CAAA;AA0BtE;;;GAGG;AACH,MAAM,OAAO,kBACX,SAAQ,OAAO,CAAC,OAAO,EAA+B,CAAC,mCAAmC,CAAC;CAC3F;AACF;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAY,kBAAkB,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AACzG;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAoC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAA;AAErG,MAAM,SAAS,GAAG,CAAC,OAA0B,EAAE,MAAc,EAAE,EAAE,CAC/D,iBAAiB,CAAC,OAAO,EAAE,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAA;AAEjG,yEAAyE;AACzE,4EAA4E;AAC5E,MAAM,SAAS,GAAG,CAAC,OAA0B,EAAqB,EAAE,CAClE,OAAO,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AAExG,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAE,MAAyB,EAAW,EAAE,CAC3F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7B,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAgB,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAC7G,CAAA;AACH,MAAM,cAAc,GAAG,CAAC,OAA0B,EAAE,MAAc,EAAW,EAAE,CAC7E,OAAO,CAAC,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;AAEtH,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,MAAyB,EAAW,EAAE;IACnE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IACxD,IAAI,QAAQ,GAAyC,KAAK,CAAA;IAC1D,IAAI,UAAU,GAAyC,KAAK,CAAA;IAC5D,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACrD,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAgB,CAAC;gBAAE,OAAO,KAAK,CAAA;YACnE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAgB,CAAC;gBAAE,SAAQ;YACpE,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,aAAa;gBAAE,SAAQ;YACjH,IAAI,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAE,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAA;iBAClG,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO;gBAAE,QAAQ,GAAG,SAAS,CAAA;YACtD,IAAI,KAAK,KAAK,CAAC;gBAAE,UAAU,GAAG,QAAQ,CAAA;QACxC,CAAC;IACH,CAAC;IACD,OAAO,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,OAAO,CAAA;AAClF,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,MAAoB,EACpB,aAAqB,EACrB,IAAe,EAC0B,EAAE,CAC3C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG;QAChB,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACjC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAC/E;QACD,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;KAChC,CAAA;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IACpC,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,SAAS,EAAE,CAAC;QACrC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YAC1C,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACnB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAAE,SAAQ;QAC7E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAClC,wEAAwE;QACxE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,SAAQ;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,SAAQ;QAC/E,UAAU,CAAC,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAC5E,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,EAAE,CAChC,CAAC,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;QAClC,MAAM,SAAS,GAAG,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACxE,MAAM,QAAQ,GAAG,GAAG,SAAS,KAAK,CAAA;QAClC,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/D,CAAC,MAAM,KAAK,UAAU,IAAI,CACxB,KAAK,CAAC,MAAM,EAAE,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACrE,KAAK,CAAC,MAAM,EAAE,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAClF,CAAC,CAAA;IACN,CAAC,CAAC;SACC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAC3B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CACpG;SACA,IAAI,EAAE,CAAA;IACX,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAG,CAAC,SAAS,EAAE,UAAU,EAAE,aAAa,CAAW,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CACxE,KAAK,CAAC,MAAM,EAAE,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CACjE,CAAC,CAAC;YACH,MAAe,CAAC,CAAC;YACjB,MAAe;KAClB,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["/** Operating-system confinement derived conservatively from effective grants.\n * @since 1.0.0-rc.1\n */\n\nimport {\n type Action,\n Capability,\n CapabilityPattern,\n matches,\n maxResourceLength,\n subsumes,\n withinMatchBudget\n} from \"@smthrs/capability/Capability\"\nimport type { GrantStoreError } from \"@smthrs/capability/Permission\"\nimport { Context, Effect, Layer, type Path, type Scope } from \"effect\"\nimport type { PlatformError } from \"effect/PlatformError\"\nimport type * as ChildProcess from \"effect/process/ChildProcess\"\nimport type { Policy, PolicyRule, Service as GrantService } from \"./GrantStore.ts\"\n\n/** Workspace-relative trees; `.` names the workspace. No path opens its parent.\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface Profile {\n readonly workspaceRoot: string\n readonly reads: ReadonlyArray<string>\n readonly writes: ReadonlyArray<string>\n readonly readOnly: ReadonlyArray<string>\n readonly network: \"none\" | \"open\"\n}\n/** Host wrapper for one process stage. Failure must occur before spawning.\n * @category models\n * @since 1.0.0-rc.1\n */\nexport interface Service {\n readonly confine: (\n command: ChildProcess.StandardCommand,\n profile: Profile\n ) => Effect.Effect<ChildProcess.StandardCommand, PlatformError, Scope.Scope>\n}\n/** Host confinement seam; missing service refuses spawning.\n * @category services\n * @since 1.0.0-rc.1\n */\nexport class ProcessConfinement\n extends Context.Service<ProcessConfinement, Service>()(\"@smthrs/kernel/ProcessConfinement\")\n{}\n/** Explicit unconfined composition.\n * @category constructors\n * @since 1.0.0-rc.1\n */\nexport const makeNoop: Service = ProcessConfinement.of({ confine: (command) => Effect.succeed(command) })\n/** Explicit unconfined layer.\n * @category layers\n * @since 1.0.0-rc.1\n */\nexport const layerNoop: Layer.Layer<ProcessConfinement> = Layer.succeed(ProcessConfinement)(makeNoop)\n\nconst decidable = (pattern: CapabilityPattern, action: Action) =>\n withinMatchBudget(pattern, new Capability({ action, resource: \"x\".repeat(maxResourceLength) }))\n\n// The capability matcher permits a single star to cross separators. Only\n// this universal spelling is equivalent to **; arbitrary globs stay closed.\nconst universal = (pattern: CapabilityPattern): CapabilityPattern =>\n pattern.resource === \"*\" ? new CapabilityPattern({ action: pattern.action, resource: \"**\" }) : pattern\n\nconst coversCeiling = (ceiling: PolicyRule[\"ceiling\"], target: CapabilityPattern): boolean =>\n ceiling.groups.every((group) =>\n group.some((pattern) => decidable(pattern, target.action as Action) && subsumes(universal(pattern), target))\n )\nconst actionRelevant = (pattern: CapabilityPattern, action: Action): boolean =>\n matches(new CapabilityPattern({ action: pattern.action, resource: \"**\" }), new Capability({ action, resource: \"\" }))\n\n// A covering rule resolves the complete region. A narrower/conditional refusal\n// makes it unknown until a later covering rule resolves it. Unknown configured\n// denial vetoes all later grant groups, just as evaluate's configured veto does.\nconst prove = (policy: Policy, target: CapabilityPattern): boolean => {\n if (!coversCeiling(policy.ceiling, target)) return false\n let decision: \"allow\" | \"deny\" | \"ask\" | \"unknown\" = \"ask\"\n let configured: \"allow\" | \"deny\" | \"ask\" | \"unknown\" = \"ask\"\n for (const [index, group] of policy.groups.entries()) {\n for (const { rule, ceiling } of group) {\n if (!decidable(rule.pattern, target.action as Action)) return false\n if (!actionRelevant(rule.pattern, target.action as Action)) continue\n if (target.action === \"net:private\" && rule.effect === \"allow\" && rule.pattern.action !== \"net:private\") continue\n if (coversCeiling(ceiling, target) && subsumes(universal(rule.pattern), target)) decision = rule.effect\n else if (rule.effect !== \"allow\") decision = \"unknown\"\n if (index === 0) configured = decision\n }\n }\n return configured !== \"deny\" && configured !== \"unknown\" && decision === \"allow\"\n}\n\n/** Derives a subset of authority, never a widening. Literal filesystem grants,\n * complex globs and unrepresentable restrictions conservatively open nothing.\n * Writable trees also require read authority and write authority over their\n * exact directory root: native mounts permit reads and directory metadata\n * changes. Only whole-tree grants prove filesystem trees; unrestricted\n * authority for each of get/post/private is required to open network access.\n * @category resolution\n * @since 1.0.0-rc.1\n */\nexport const profile = (\n grants: GrantService,\n workspaceRoot: string,\n path: Path.Path\n): Effect.Effect<Profile, GrantStoreError> =>\n Effect.gen(function*() {\n const policy = yield* grants.policy\n const root = path.resolve(workspaceRoot)\n const resources = [\n ...policy.groups.flatMap((group) =>\n group.flatMap(({ rule, ceiling }) => [rule.pattern, ...ceiling.groups.flat()])\n ),\n ...policy.ceiling.groups.flat()\n ]\n const candidates = new Set<string>()\n for (const { resource } of resources) {\n if (resource === \"**\" || resource === \"*\") {\n candidates.add(\".\")\n continue\n }\n if (!resource.endsWith(\"/**\") || /[*?]/.test(resource.slice(0, -3))) continue\n const base = resource.slice(0, -3)\n // Relative policy resources do not authorize absolute kernel resources.\n if (!path.isAbsolute(base) || path.normalize(base) !== base) continue\n const relative = path.relative(root, base)\n if (path.isAbsolute(relative) || relative.split(path.sep)[0] === \"..\") continue\n candidates.add(relative === \"\" ? \".\" : relative.split(path.sep).join(\"/\"))\n }\n const opened = (action: Action) =>\n [...candidates].filter((relative) => {\n const directory = relative === \".\" ? root : path.resolve(root, relative)\n const resource = `${directory}/**`\n return prove(policy, new CapabilityPattern({ action, resource })) &&\n (action !== \"fs:write\" || (\n prove(policy, new CapabilityPattern({ action: \"fs:read\", resource })) &&\n prove(policy, new CapabilityPattern({ action: \"fs:write\", resource: directory }))\n ))\n })\n .filter((relative, _, all) =>\n !all.some((parent) => parent !== relative && (parent === \".\" || relative.startsWith(`${parent}/`)))\n )\n .sort()\n return Object.freeze({\n workspaceRoot: root,\n reads: Object.freeze(opened(\"fs:read\")),\n writes: Object.freeze(opened(\"fs:write\")),\n readOnly: Object.freeze([]),\n network: ([\"net:get\", \"net:post\", \"net:private\"] as const).every((action) =>\n prove(policy, new CapabilityPattern({ action, resource: \"**\" }))\n ) ?\n \"open\" as const :\n \"none\" as const\n })\n })\n"]}
|
package/dist/esm/Rooted.d.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* @since 1.0.0
|
|
11
11
|
*/
|
|
12
12
|
import { FileSystem, Layer, Path } from "effect";
|
|
13
|
-
import * as ChildProcess from "effect/
|
|
14
|
-
import * as ChildProcessSpawner from "effect/
|
|
13
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
14
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
15
15
|
/**
|
|
16
16
|
* `base` with every relative path resolved against the absolute `root`.
|
|
17
17
|
*
|
package/dist/esm/Rooted.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rooted.d.ts","sourceRoot":"","sources":["../../src/Rooted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAmB,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,KAAK,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"Rooted.d.ts","sourceRoot":"","sources":["../../src/Rooted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAmB,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAA;AAGzE;;;;;GAKG;AACH,eAAO,MAAM,IAAI,GAAI,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,MAAM,KAAG,IAAI,CAAC,IAQzD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,UAAU,CAAC,UAAU,EAAE,QAAQ,IAAI,CAAC,IAAI,KAAG,UAAU,CAAC,UAqCtF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,YAAY,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,KAAG,YAAY,CAAC,OAGa,CAAA;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAClB,MAAM,mBAAmB,CAAC,mBAAmB,CAAC,SAAS,CAAC,EACxD,QAAQ,IAAI,CAAC,IAAI,KAChB,mBAAmB,CAAC,mBAAmB,CAAC,SAAS,CACgD,CAAA;AAEpG;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GAChB,MAAM,MAAM,KACX,KAAK,CAAC,KAAK,CACZ,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC,mBAAmB,EAC3E,KAAK,EACL,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC,mBAAmB,CAYxE,CAAA"}
|
package/dist/esm/Rooted.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* @since 1.0.0
|
|
11
11
|
*/
|
|
12
12
|
import { Context, Effect, FileSystem, Layer, Path } from "effect";
|
|
13
|
-
import * as ChildProcess from "effect/
|
|
14
|
-
import * as ChildProcessSpawner from "effect/
|
|
13
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
14
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
15
15
|
import * as Containment from "./internal/Containment.js";
|
|
16
16
|
/**
|
|
17
17
|
* `base` with every relative path resolved against the absolute `root`.
|
package/dist/esm/Rooted.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rooted.js","sourceRoot":"","sources":["../../src/Rooted.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Filesystem, path and process services bound to one root directory.\n *\n * Node resolves a relative path against `process.cwd()`. A host serves one\n * directory whatever the process's own, so here every relative path, and every\n * command spawned without a `cwd`, resolves against `root`. Absolute paths pass\n * through unchanged, and so does a symlink's target, which is relative to the\n * link rather than to any directory.\n *\n * @since 1.0.0\n */\n\nimport { Context, Effect, FileSystem, Layer, Path } from \"effect\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport * as ChildProcessSpawner from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as Containment from \"./internal/Containment.ts\"\n\n/**\n * `base` with every relative path resolved against the absolute `root`.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const path = (base: Path.Path, root: string): Path.Path => {\n const resolve = (...segments: ReadonlyArray<string>) => base.resolve(root, ...segments)\n return {\n ...base,\n resolve,\n relative: (from, to) => base.relative(resolve(from), resolve(to)),\n toFileUrl: (value) => base.toFileUrl(resolve(value))\n }\n}\n\n/**\n * `base` with every relative path resolved by `rooted`, a {@link path}.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const fileSystem = (base: FileSystem.FileSystem, rooted: Path.Path): FileSystem.FileSystem => {\n const at = (value: string) => rooted.resolve(value)\n const temp = <O extends { readonly directory?: string | undefined }>(options: O | undefined) =>\n options?.directory === undefined ? options : { ...options, directory: at(options.directory) }\n return {\n ...base,\n access: (value, options) => base.access(at(value), options),\n copy: (from, to, options) => base.copy(at(from), at(to), options),\n copyFile: (from, to) => base.copyFile(at(from), at(to)),\n chmod: (value, mode) => base.chmod(at(value), mode),\n chown: (value, uid, gid) => base.chown(at(value), uid, gid),\n glob: (pattern, options) => base.glob(pattern, { ...options, root: at(options?.root ?? \".\") }),\n exists: (value) => base.exists(at(value)),\n link: (from, to) => base.link(at(from), at(to)),\n makeDirectory: (value, options) => base.makeDirectory(at(value), options),\n makeTempDirectory: (options) => base.makeTempDirectory(temp(options)),\n makeTempDirectoryScoped: (options) => base.makeTempDirectoryScoped(temp(options)),\n makeTempFile: (options) => base.makeTempFile(temp(options)),\n makeTempFileScoped: (options) => base.makeTempFileScoped(temp(options)),\n open: (value, options) => base.open(at(value), options),\n readDirectory: (value, options) => base.readDirectory(at(value), options),\n readFile: (value) => base.readFile(at(value)),\n readFileString: (value, encoding) => base.readFileString(at(value), encoding),\n readLink: (value) => base.readLink(at(value)),\n realPath: (value) => base.realPath(at(value)),\n remove: (value, options) => base.remove(at(value), options),\n rename: (from, to) => base.rename(at(from), at(to)),\n sink: (value, options) => base.sink(at(value), options),\n stat: (value) => base.stat(at(value)),\n stream: (value, options) => base.stream(at(value), options),\n symlink: (target, value) => base.symlink(target, at(value)),\n truncate: (value, length) => base.truncate(at(value), length),\n utimes: (value, atime, mtime) => base.utimes(at(value), atime, mtime),\n watch: (value, options) => base.watch(at(value), options),\n writeFile: (value, data, options) => base.writeFile(at(value), data, options),\n writeFileString: (value, data, options) => base.writeFileString(at(value), data, options)\n }\n}\n\n/**\n * `value` with every stage's `cwd` resolved by `rooted`, a {@link path}; its\n * root for a stage without one.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const command = (value: ChildProcess.Command, rooted: Path.Path): ChildProcess.Command =>\n ChildProcess.isStandardCommand(value)\n ? ChildProcess.setCwd(value, rooted.resolve(value.options.cwd ?? \".\"))\n : ChildProcess.pipeTo(command(value.left, rooted), command(value.right, rooted), value.options)\n\n/**\n * `base` spawning each command as {@link command} roots it. A contained `base`\n * stays contained.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const spawner = (\n base: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n rooted: Path.Path\n): ChildProcessSpawner.ChildProcessSpawner[\"Service\"] =>\n Containment.inherit(base, ChildProcessSpawner.make((value) => base.spawn(command(value, rooted))))\n\n/**\n * Decorates the `FileSystem`, `Path` and `ChildProcessSpawner` it is provided\n * in place, so everything downstream resolves against `root`.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layer = (\n root: string\n): Layer.Layer<\n FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner,\n never,\n FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner\n> =>\n Layer.effectContext(Effect.gen(function*() {\n const base = yield* Path.Path\n const rooted = path(base, base.resolve(root))\n return Context.make(Path.Path, rooted).pipe(\n Context.add(FileSystem.FileSystem, fileSystem(yield* FileSystem.FileSystem, rooted)),\n Context.add(\n ChildProcessSpawner.ChildProcessSpawner,\n spawner(yield* ChildProcessSpawner.ChildProcessSpawner, rooted)\n )\n )\n }))\n"]}
|
|
1
|
+
{"version":3,"file":"Rooted.js","sourceRoot":"","sources":["../../src/Rooted.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Filesystem, path and process services bound to one root directory.\n *\n * Node resolves a relative path against `process.cwd()`. A host serves one\n * directory whatever the process's own, so here every relative path, and every\n * command spawned without a `cwd`, resolves against `root`. Absolute paths pass\n * through unchanged, and so does a symlink's target, which is relative to the\n * link rather than to any directory.\n *\n * @since 1.0.0\n */\n\nimport { Context, Effect, FileSystem, Layer, Path } from \"effect\"\nimport * as ChildProcess from \"effect/process/ChildProcess\"\nimport * as ChildProcessSpawner from \"effect/process/ChildProcessSpawner\"\nimport * as Containment from \"./internal/Containment.ts\"\n\n/**\n * `base` with every relative path resolved against the absolute `root`.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const path = (base: Path.Path, root: string): Path.Path => {\n const resolve = (...segments: ReadonlyArray<string>) => base.resolve(root, ...segments)\n return {\n ...base,\n resolve,\n relative: (from, to) => base.relative(resolve(from), resolve(to)),\n toFileUrl: (value) => base.toFileUrl(resolve(value))\n }\n}\n\n/**\n * `base` with every relative path resolved by `rooted`, a {@link path}.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const fileSystem = (base: FileSystem.FileSystem, rooted: Path.Path): FileSystem.FileSystem => {\n const at = (value: string) => rooted.resolve(value)\n const temp = <O extends { readonly directory?: string | undefined }>(options: O | undefined) =>\n options?.directory === undefined ? options : { ...options, directory: at(options.directory) }\n return {\n ...base,\n access: (value, options) => base.access(at(value), options),\n copy: (from, to, options) => base.copy(at(from), at(to), options),\n copyFile: (from, to) => base.copyFile(at(from), at(to)),\n chmod: (value, mode) => base.chmod(at(value), mode),\n chown: (value, uid, gid) => base.chown(at(value), uid, gid),\n glob: (pattern, options) => base.glob(pattern, { ...options, root: at(options?.root ?? \".\") }),\n exists: (value) => base.exists(at(value)),\n link: (from, to) => base.link(at(from), at(to)),\n makeDirectory: (value, options) => base.makeDirectory(at(value), options),\n makeTempDirectory: (options) => base.makeTempDirectory(temp(options)),\n makeTempDirectoryScoped: (options) => base.makeTempDirectoryScoped(temp(options)),\n makeTempFile: (options) => base.makeTempFile(temp(options)),\n makeTempFileScoped: (options) => base.makeTempFileScoped(temp(options)),\n open: (value, options) => base.open(at(value), options),\n readDirectory: (value, options) => base.readDirectory(at(value), options),\n readFile: (value) => base.readFile(at(value)),\n readFileString: (value, encoding) => base.readFileString(at(value), encoding),\n readLink: (value) => base.readLink(at(value)),\n realPath: (value) => base.realPath(at(value)),\n remove: (value, options) => base.remove(at(value), options),\n rename: (from, to) => base.rename(at(from), at(to)),\n sink: (value, options) => base.sink(at(value), options),\n stat: (value) => base.stat(at(value)),\n stream: (value, options) => base.stream(at(value), options),\n symlink: (target, value) => base.symlink(target, at(value)),\n truncate: (value, length) => base.truncate(at(value), length),\n utimes: (value, atime, mtime) => base.utimes(at(value), atime, mtime),\n watch: (value, options) => base.watch(at(value), options),\n writeFile: (value, data, options) => base.writeFile(at(value), data, options),\n writeFileString: (value, data, options) => base.writeFileString(at(value), data, options)\n }\n}\n\n/**\n * `value` with every stage's `cwd` resolved by `rooted`, a {@link path}; its\n * root for a stage without one.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const command = (value: ChildProcess.Command, rooted: Path.Path): ChildProcess.Command =>\n ChildProcess.isStandardCommand(value)\n ? ChildProcess.setCwd(value, rooted.resolve(value.options.cwd ?? \".\"))\n : ChildProcess.pipeTo(command(value.left, rooted), command(value.right, rooted), value.options)\n\n/**\n * `base` spawning each command as {@link command} roots it. A contained `base`\n * stays contained.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const spawner = (\n base: ChildProcessSpawner.ChildProcessSpawner[\"Service\"],\n rooted: Path.Path\n): ChildProcessSpawner.ChildProcessSpawner[\"Service\"] =>\n Containment.inherit(base, ChildProcessSpawner.make((value) => base.spawn(command(value, rooted))))\n\n/**\n * Decorates the `FileSystem`, `Path` and `ChildProcessSpawner` it is provided\n * in place, so everything downstream resolves against `root`.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layer = (\n root: string\n): Layer.Layer<\n FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner,\n never,\n FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner\n> =>\n Layer.effectContext(Effect.gen(function*() {\n const base = yield* Path.Path\n const rooted = path(base, base.resolve(root))\n return Context.make(Path.Path, rooted).pipe(\n Context.add(FileSystem.FileSystem, fileSystem(yield* FileSystem.FileSystem, rooted)),\n Context.add(\n ChildProcessSpawner.ChildProcessSpawner,\n spawner(yield* ChildProcessSpawner.ChildProcessSpawner, rooted)\n )\n )\n }))\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Trusted composition metadata shared by contained and permission-aware spawners.
|
|
3
3
|
* @since 1.0.0
|
|
4
4
|
*/
|
|
5
|
-
import type { ChildProcessSpawner } from "effect/
|
|
5
|
+
import type { ChildProcessSpawner } from "effect/process/ChildProcessSpawner";
|
|
6
6
|
/**
|
|
7
7
|
* Reads only an own data property, without invoking an accessor.
|
|
8
8
|
* @private
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Containment.d.ts","sourceRoot":"","sources":["../../../src/internal/Containment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"Containment.d.ts","sourceRoot":"","sources":["../../../src/internal/Containment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAA;AAO7E;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,mBAAmB,CAAC,SAAS,CAAC,KAAG,OACP,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAI,SAAS,mBAAmB,CAAC,SAAS,CAAC,KAAG,mBAAmB,CAAC,SAAS,CACmB,CAAA;AAE/G;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,mBAAmB,CAAC,SAAS,CAAC,EACtC,SAAS,mBAAmB,CAAC,SAAS,CAAC,KACtC,mBAAmB,CAAC,SAAS,CAAkD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Containment.js","sourceRoot":"","sources":["../../../src/internal/Containment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAuC,EAAW,EAAE,CAC9E,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAuC,EAAkC,EAAE,CAC9F,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;AAE/G;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,MAAsC,EACtC,OAAuC,EACP,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA","sourcesContent":["/**\n * Trusted composition metadata shared by contained and permission-aware spawners.\n * @since 1.0.0\n */\n\nimport type { ChildProcessSpawner } from \"effect/
|
|
1
|
+
{"version":3,"file":"Containment.js","sourceRoot":"","sources":["../../../src/internal/Containment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAC3E,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,OAAuC,EAAW,EAAE,CAC9E,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;AAE/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,OAAuC,EAAkC,EAAE,CAC9F,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;AAE/G;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,MAAsC,EACtC,OAAuC,EACP,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA","sourcesContent":["/**\n * Trusted composition metadata shared by contained and permission-aware spawners.\n * @since 1.0.0\n */\n\nimport type { ChildProcessSpawner } from \"effect/process/ChildProcessSpawner\"\n\n// The registry key also works when a service crosses the ESM/CJS projections.\n// This declares a trusted lifecycle contract; it cannot prove a supplied\n// lifecycle is honest or turn process containment into a security sandbox.\nconst key = Symbol.for(\"@smthrs/kernel/ContainedSpawner/Lifecycle/v1\")\n\n/**\n * Reads only an own data property, without invoking an accessor.\n * @private\n * @since 1.0.0\n */\nexport const isContained = (spawner: ChildProcessSpawner[\"Service\"]): boolean =>\n Object.getOwnPropertyDescriptor(spawner, key)?.value === true\n\n/**\n * Marks a newly constructed service without copying through object spreads.\n * @private\n * @since 1.0.0\n */\nexport const mark = (spawner: ChildProcessSpawner[\"Service\"]): ChildProcessSpawner[\"Service\"] =>\n Object.defineProperty(spawner, key, { value: true, enumerable: false, writable: false, configurable: false })\n\n/**\n * Preserves the declaration on a wrapper that delegates its process lifetime.\n * @private\n * @since 1.0.0\n */\nexport const inherit = (\n source: ChildProcessSpawner[\"Service\"],\n wrapper: ChildProcessSpawner[\"Service\"]\n): ChildProcessSpawner[\"Service\"] => isContained(source) ? mark(wrapper) : wrapper\n"]}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
6
|
import type * as PlatformError from "effect/PlatformError";
|
|
7
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
8
|
+
import { type ChildProcessHandle } from "effect/process/ChildProcessSpawner";
|
|
7
9
|
import type * as Scope from "effect/Scope";
|
|
8
|
-
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
9
|
-
import { type ChildProcessHandle } from "effect/unstable/process/ChildProcessSpawner";
|
|
10
10
|
type Spawn = (command: ChildProcess.StandardCommand) => Effect.Effect<ChildProcessHandle, PlatformError.PlatformError, Scope.Scope>;
|
|
11
11
|
/**
|
|
12
12
|
* Preserve Effect's rightmost output/status and reverse-order kill/reref semantics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pipeline.d.ts","sourceRoot":"","sources":["../../../src/internal/Pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,aAAa,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Pipeline.d.ts","sourceRoot":"","sources":["../../../src/internal/Pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,aAAa,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,oCAAoC,CAAA;AACxF,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAG1C,KAAK,KAAK,GAAG,CACX,OAAO,EAAE,YAAY,CAAC,eAAe,KAClC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;AAsChF;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAChB,SAAS,YAAY,CAAC,OAAO,EAC7B,UAAU,KAAK,KACd,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,aAAa,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,CAuBzE,CAAA"}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
6
|
import * as Exit from "effect/Exit";
|
|
7
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
8
|
+
import { makeHandle } from "effect/process/ChildProcessSpawner";
|
|
7
9
|
import * as Stream from "effect/Stream";
|
|
8
|
-
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
9
|
-
import { makeHandle } from "effect/unstable/process/ChildProcessSpawner";
|
|
10
10
|
const source = (handle, from) => {
|
|
11
11
|
if (from === "stderr")
|
|
12
12
|
return handle.stderr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pipeline.js","sourceRoot":"","sources":["../../../src/internal/Pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"Pipeline.js","sourceRoot":"","sources":["../../../src/internal/Pipeline.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pipeline wiring around a per-process spawner, so every leg has its own lifecycle.\n * @since 1.0.0\n */\n\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport type * as PlatformError from \"effect/PlatformError\"\nimport * as ChildProcess from \"effect/process/ChildProcess\"\nimport { type ChildProcessHandle, makeHandle } from \"effect/process/ChildProcessSpawner\"\nimport type * as Scope from \"effect/Scope\"\nimport * as Stream from \"effect/Stream\"\n\ntype Spawn = (\n command: ChildProcess.StandardCommand\n) => Effect.Effect<ChildProcessHandle, PlatformError.PlatformError, Scope.Scope>\n\nconst source = (handle: ChildProcessHandle, from: ChildProcess.PipeFromOption | undefined) => {\n if (from === \"stderr\") return handle.stderr\n if (from === \"all\") return handle.all\n const fd = from === undefined ? undefined : ChildProcess.parseFdName(from)\n return fd === undefined ? handle.stdout : handle.getOutputFd(fd)\n}\n\n/** An edge feeds the first process of its destination, including a nested pipeline. */\nconst withInput = (\n command: ChildProcess.Command,\n stream: Stream.Stream<Uint8Array, PlatformError.PlatformError>,\n to: ChildProcess.PipeToOption | undefined\n): ChildProcess.Command => {\n if (command._tag === \"PipedCommand\") {\n return ChildProcess.pipeTo(withInput(command.left, stream, to), command.right, command.options)\n }\n const fd = to === undefined ? undefined : ChildProcess.parseFdName(to)\n if (fd !== undefined) {\n return ChildProcess.make(command.command, command.args, {\n ...command.options,\n additionalFds: {\n ...command.options.additionalFds,\n [ChildProcess.fdName(fd)]: { type: \"input\", stream }\n }\n })\n }\n const stdin = command.options.stdin\n return ChildProcess.make(command.command, command.args, {\n ...command.options,\n stdin: {\n ...(typeof stdin === \"object\" && !Stream.isStream(stdin) ? stdin : {}),\n stream\n }\n })\n}\n\n/**\n * Preserve Effect's rightmost output/status and reverse-order kill/reref semantics.\n * @private\n * @since 1.0.0\n */\nexport const spawn = (\n command: ChildProcess.Command,\n standard: Spawn\n): Effect.Effect<ChildProcessHandle, PlatformError.PlatformError, Scope.Scope> =>\n Effect.gen(function*() {\n if (command._tag === \"StandardCommand\") return yield* standard(command)\n const left = yield* spawn(command.left, standard)\n const right = yield* spawn(\n withInput(command.right, source(left, command.options.from), command.options.to),\n standard\n )\n return makeHandle({\n ...right,\n kill: (options) =>\n Effect.gen(function*() {\n const rightExit = yield* Effect.exit(right.kill(options))\n const leftExit = yield* Effect.exit(left.kill(options))\n if (Exit.isFailure(rightExit)) return yield* Effect.failCause(rightExit.cause)\n return yield* leftExit\n }),\n unref: Effect.gen(function*() {\n const leftReref = yield* left.unref\n const rightReref = yield* right.unref\n return Effect.andThen(rightReref, leftReref)\n })\n })\n })\n"]}
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { Jj, JjErrorCode } from "@smthrs/jj";
|
|
11
11
|
import { Effect, FileSystem, type Layer, Path } from "effect";
|
|
12
|
-
import { HttpClient } from "effect/
|
|
13
|
-
import * as HttpClientRequest from "effect/
|
|
14
|
-
import type * as HttpClientResponse from "effect/
|
|
15
|
-
import * as ChildProcess from "effect/
|
|
16
|
-
import { ChildProcessSpawner } from "effect/
|
|
12
|
+
import { HttpClient } from "effect/http/HttpClient";
|
|
13
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
14
|
+
import type * as HttpClientResponse from "effect/http/HttpClientResponse";
|
|
15
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
16
|
+
import { ChildProcessSpawner } from "effect/process/ChildProcessSpawner";
|
|
17
17
|
export { check as checkFileSystemBatch } from "./FileSystemBatchContract.ts";
|
|
18
18
|
/**
|
|
19
19
|
* A capability that must fail with a stable typed code.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostContract.d.ts","sourceRoot":"","sources":["../../../src/test/HostContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAY,MAAM,EAAS,UAAU,EAAE,KAAK,KAAK,EAAU,IAAI,EAAU,MAAM,QAAQ,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"HostContract.d.ts","sourceRoot":"","sources":["../../../src/test/HostContract.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
import { describe, expect, it } from "@effect/vitest";
|
|
14
14
|
import * as JjService from "@smthrs/jj";
|
|
15
15
|
import { Deferred, Effect, Fiber, FileSystem, Option, Path, Stream } from "effect";
|
|
16
|
-
import { HttpClient } from "effect/
|
|
17
|
-
import * as HttpClientRequest from "effect/
|
|
18
|
-
import * as ChildProcess from "effect/
|
|
19
|
-
import { ChildProcessSpawner } from "effect/
|
|
16
|
+
import { HttpClient } from "effect/http/HttpClient";
|
|
17
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
18
|
+
import * as ChildProcess from "effect/process/ChildProcess";
|
|
19
|
+
import { ChildProcessSpawner } from "effect/process/ChildProcessSpawner";
|
|
20
20
|
import { tmpdir } from "node:os";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import * as FileSystemBatchContract from "./FileSystemBatchContract.js";
|