@graftland/plugin-remote 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +76 -2
- package/README.zh-CN.md +71 -0
- package/README.zh-TW.md +71 -0
- package/dist/Auth-BElTC9_X.js +6 -0
- package/dist/Auth.d.ts +49 -0
- package/dist/Auth.d.ts.map +1 -0
- package/dist/Auth.js +8 -0
- package/dist/Auth.js.map +1 -0
- package/dist/Bootstrap-MCwivGN1.js +9 -0
- package/dist/ConfigDirectory-BCC6q2R4.js +5 -0
- package/dist/Contract-CcpSIJm4.js +121 -0
- package/dist/Contract.d.ts +71 -0
- package/dist/Contract.d.ts.map +1 -0
- package/dist/Contract.js +1 -0
- package/dist/Contract.js.map +1 -0
- package/dist/Errors-oPsTLY7l.js +45 -0
- package/dist/Errors.d.ts +67 -0
- package/dist/Errors.d.ts.map +1 -0
- package/dist/Errors.js +47 -0
- package/dist/Errors.js.map +1 -0
- package/dist/FailureGroup-BcH0XOBi.js +53 -0
- package/dist/Framing-zaYdOJnT.js +61 -0
- package/dist/Graft-BsYq3F-J.js +985 -0
- package/dist/Instance.d.ts +7 -0
- package/dist/Instance.d.ts.map +1 -0
- package/dist/Instance.js +14 -0
- package/dist/Instance.js.map +1 -0
- package/dist/Packages-B1TPk8pa.js +111 -0
- package/dist/Peer-IJgFK6mD.js +342 -0
- package/dist/ProcessObservation-DEGrEMfP.js +38 -0
- package/dist/ServeLifecycle-CJM0gG5B.js +24 -0
- package/dist/Testing.d.ts +26 -0
- package/dist/Testing.d.ts.map +1 -0
- package/dist/Testing.js +69 -0
- package/dist/Testing.js.map +1 -0
- package/dist/Transport-DULzpsgR.js +6 -0
- package/dist/Transport.d.ts +39 -0
- package/dist/Transport.d.ts.map +1 -0
- package/dist/Transport.js +8 -0
- package/dist/Transport.js.map +1 -0
- package/dist/WatchdogProtocol-BZmVxrBP.js +17 -0
- package/dist/_virtual/_rolldown/runtime.js +12 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +28275 -0
- package/dist/bin.js.map +1 -0
- package/dist/childRuntime-DSqtFN9o.js +188 -0
- package/dist/cleanup-BPWr-5U9.js +13 -0
- package/dist/command-9zrHdbwT.js +7 -0
- package/dist/connectionEnded-DUgcobEd.js +9 -0
- package/dist/directTransport-DrexuPSm.js +5 -0
- package/dist/entry-SYsx9VNb.js +708 -0
- package/dist/host/auth/bearer.d.ts +5 -0
- package/dist/host/auth/bearer.d.ts.map +1 -0
- package/dist/host/auth/bearer.js +4 -0
- package/dist/host/auth/bearer.js.map +1 -0
- package/dist/host/auth/jwt.d.ts +5 -0
- package/dist/host/auth/jwt.d.ts.map +1 -0
- package/dist/host/auth/jwt.js +4 -0
- package/dist/host/auth/jwt.js.map +1 -0
- package/dist/host/auth/mtls.d.ts +8 -0
- package/dist/host/auth/mtls.d.ts.map +1 -0
- package/dist/host/auth/mtls.js +34 -0
- package/dist/host/auth/mtls.js.map +1 -0
- package/dist/host/auth/none.d.ts +3 -0
- package/dist/host/auth/none.d.ts.map +1 -0
- package/dist/host/auth/none.js +13 -0
- package/dist/host/auth/none.js.map +1 -0
- package/dist/host/command.d.ts +22 -0
- package/dist/host/command.d.ts.map +1 -0
- package/dist/host/command.js +61 -0
- package/dist/host/command.js.map +1 -0
- package/dist/host/local.d.ts +4 -0
- package/dist/host/local.d.ts.map +1 -0
- package/dist/host/local.js +52 -0
- package/dist/host/local.js.map +1 -0
- package/dist/host/unix.d.ts +11 -0
- package/dist/host/unix.d.ts.map +1 -0
- package/dist/host/unix.js +39 -0
- package/dist/host/unix.js.map +1 -0
- package/dist/host/websocket.d.ts +13 -0
- package/dist/host/websocket.d.ts.map +1 -0
- package/dist/host/websocket.js +36 -0
- package/dist/host/websocket.js.map +1 -0
- package/dist/host/worker.d.ts +4 -0
- package/dist/host/worker.d.ts.map +1 -0
- package/dist/host/worker.js +52 -0
- package/dist/host/worker.js.map +1 -0
- package/dist/importer-D7zSgqxq.js +347 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/Certificates.js +182 -0
- package/dist/internal/Certificates.js.map +1 -0
- package/dist/internal/FailureGroup.js +55 -0
- package/dist/internal/FailureGroup.js.map +1 -0
- package/dist/internal/Limits.d.ts +1 -0
- package/dist/internal/Limits.js +17 -0
- package/dist/internal/Limits.js.map +1 -0
- package/dist/internal/Peer.js +6 -0
- package/dist/internal/Peer.js.map +1 -0
- package/dist/internal/ServeLifecycle.js +26 -0
- package/dist/internal/ServeLifecycle.js.map +1 -0
- package/dist/internal/Supervisor.js +7 -0
- package/dist/internal/Supervisor.js.map +1 -0
- package/dist/internal/assembly.d.ts +5 -0
- package/dist/internal/assembly.js +138 -0
- package/dist/internal/assembly.js.map +1 -0
- package/dist/internal/auth/mtls.js +23 -0
- package/dist/internal/auth/mtls.js.map +1 -0
- package/dist/internal/auth/token.js +19 -0
- package/dist/internal/auth/token.js.map +1 -0
- package/dist/internal/auth/tokenCredentials.d.ts +8 -0
- package/dist/internal/auth/tokenCredentials.d.ts.map +1 -0
- package/dist/internal/auth/tokenCredentials.js +33 -0
- package/dist/internal/auth/tokenCredentials.js.map +1 -0
- package/dist/internal/child.js +125 -0
- package/dist/internal/child.js.map +1 -0
- package/dist/internal/childErrors.d.ts +33 -0
- package/dist/internal/childErrors.d.ts.map +1 -0
- package/dist/internal/childErrors.js +29 -0
- package/dist/internal/childErrors.js.map +1 -0
- package/dist/internal/childRuntime.js +59 -0
- package/dist/internal/childRuntime.js.map +1 -0
- package/dist/internal/cleanup.js +15 -0
- package/dist/internal/cleanup.js.map +1 -0
- package/dist/internal/config.js +6 -0
- package/dist/internal/config.js.map +1 -0
- package/dist/internal/control.js +42 -0
- package/dist/internal/control.js.map +1 -0
- package/dist/internal/credentials.d.ts +44 -0
- package/dist/internal/credentials.d.ts.map +1 -0
- package/dist/internal/credentials.js +54 -0
- package/dist/internal/credentials.js.map +1 -0
- package/dist/internal/directTransport.d.ts +3 -0
- package/dist/internal/directTransport.js +7 -0
- package/dist/internal/directTransport.js.map +1 -0
- package/dist/internal/entry.d.ts +9 -0
- package/dist/internal/entry.d.ts.map +1 -0
- package/dist/internal/entry.js +144 -0
- package/dist/internal/entry.js.map +1 -0
- package/dist/internal/entryConfig.d.ts +202 -0
- package/dist/internal/entryConfig.d.ts.map +1 -0
- package/dist/internal/entryConfig.js +176 -0
- package/dist/internal/entryConfig.js.map +1 -0
- package/dist/internal/execution.d.ts +5 -0
- package/dist/internal/execution.js +43 -0
- package/dist/internal/execution.js.map +1 -0
- package/dist/internal/follow.js +11 -0
- package/dist/internal/follow.js.map +1 -0
- package/dist/internal/forkTree.js +7 -0
- package/dist/internal/forkTree.js.map +1 -0
- package/dist/internal/host/local.js +28 -0
- package/dist/internal/host/local.js.map +1 -0
- package/dist/internal/host/runner.js +100 -0
- package/dist/internal/host/runner.js.map +1 -0
- package/dist/internal/host.js +71 -0
- package/dist/internal/host.js.map +1 -0
- package/dist/internal/importer.js +18 -0
- package/dist/internal/importer.js.map +1 -0
- package/dist/internal/listenerStartup.js +17 -0
- package/dist/internal/listenerStartup.js.map +1 -0
- package/dist/internal/loadModule.js +20 -0
- package/dist/internal/loadModule.js.map +1 -0
- package/dist/internal/platform.js +9 -0
- package/dist/internal/platform.js.map +1 -0
- package/dist/internal/port.d.ts +13 -0
- package/dist/internal/port.d.ts.map +1 -0
- package/dist/internal/port.js +275 -0
- package/dist/internal/port.js.map +1 -0
- package/dist/internal/release.js +25 -0
- package/dist/internal/release.js.map +1 -0
- package/dist/internal/runner/Bootstrap.js +11 -0
- package/dist/internal/runner/Bootstrap.js.map +1 -0
- package/dist/internal/runner/Connection.d.ts +11 -0
- package/dist/internal/runner/Connection.js +56 -0
- package/dist/internal/runner/Connection.js.map +1 -0
- package/dist/internal/runner/Execution.js +115 -0
- package/dist/internal/runner/Execution.js.map +1 -0
- package/dist/internal/runner/Framing.d.ts +11 -0
- package/dist/internal/runner/Framing.d.ts.map +1 -0
- package/dist/internal/runner/Framing.js +63 -0
- package/dist/internal/runner/Framing.js.map +1 -0
- package/dist/internal/runner/Local.js +46 -0
- package/dist/internal/runner/Local.js.map +1 -0
- package/dist/internal/runner/Lock.js +25 -0
- package/dist/internal/runner/Lock.js.map +1 -0
- package/dist/internal/runner/Multiplex.d.ts +5 -0
- package/dist/internal/runner/Multiplex.js +49 -0
- package/dist/internal/runner/Multiplex.js.map +1 -0
- package/dist/internal/runner/Packages.d.ts +3 -0
- package/dist/internal/runner/Packages.js +108 -0
- package/dist/internal/runner/Packages.js.map +1 -0
- package/dist/internal/runner/ProcessObservation.js +40 -0
- package/dist/internal/runner/ProcessObservation.js.map +1 -0
- package/dist/internal/runner/Processes.js +83 -0
- package/dist/internal/runner/Processes.js.map +1 -0
- package/dist/internal/runner/Retention.js +13 -0
- package/dist/internal/runner/Retention.js.map +1 -0
- package/dist/internal/runner/Store.js +78 -0
- package/dist/internal/runner/Store.js.map +1 -0
- package/dist/internal/runner/Supervisor.js +375 -0
- package/dist/internal/runner/Supervisor.js.map +1 -0
- package/dist/internal/runner/Watchdog.js +47 -0
- package/dist/internal/runner/Watchdog.js.map +1 -0
- package/dist/internal/runner/WatchdogProtocol.js +19 -0
- package/dist/internal/runner/WatchdogProtocol.js.map +1 -0
- package/dist/internal/runner/Wire.d.ts +5 -0
- package/dist/internal/runner/Wire.js +64 -0
- package/dist/internal/runner/Wire.js.map +1 -0
- package/dist/internal/runner/accept.js +57 -0
- package/dist/internal/runner/accept.js.map +1 -0
- package/dist/internal/runner/command.js +9 -0
- package/dist/internal/runner/command.js.map +1 -0
- package/dist/internal/runner/connectionEnded.js +11 -0
- package/dist/internal/runner/connectionEnded.js.map +1 -0
- package/dist/internal/runner/model.d.ts +17 -0
- package/dist/internal/runner/model.d.ts.map +1 -0
- package/dist/internal/runner/model.js +231 -0
- package/dist/internal/runner/model.js.map +1 -0
- package/dist/internal/serve.js +60 -0
- package/dist/internal/serve.js.map +1 -0
- package/dist/internal/services.d.ts +18 -0
- package/dist/internal/services.d.ts.map +1 -0
- package/dist/internal/services.js +22 -0
- package/dist/internal/services.js.map +1 -0
- package/dist/internal/socketChannel.js +24 -0
- package/dist/internal/socketChannel.js.map +1 -0
- package/dist/internal/stdioChannel.js +23 -0
- package/dist/internal/stdioChannel.js.map +1 -0
- package/dist/internal/supervisorPlugin.js +1 -0
- package/dist/internal/supervisorPlugin.js.map +1 -0
- package/dist/internal/transportOptions.d.ts +18 -0
- package/dist/internal/transportOptions.d.ts.map +1 -0
- package/dist/internal/watchdogMain.d.ts +1 -0
- package/dist/internal/watchdogMain.js +55 -0
- package/dist/internal/watchdogMain.js.map +1 -0
- package/dist/internal/websocket.js +46 -0
- package/dist/internal/websocket.js.map +1 -0
- package/dist/internal/websocketServer.js +61 -0
- package/dist/internal/websocketServer.js.map +1 -0
- package/dist/internal/workerBootstrap.js +9 -0
- package/dist/internal/workerBootstrap.js.map +1 -0
- package/dist/internal/workerChannel.js +24 -0
- package/dist/internal/workerChannel.js.map +1 -0
- package/dist/internal/workerMain.d.ts +1 -0
- package/dist/internal/workerMain.js +18 -0
- package/dist/internal/workerMain.js.map +1 -0
- package/dist/port-Blbh8tms.js +285 -0
- package/dist/release-BY4Mlluy.js +23 -0
- package/dist/rolldown-runtime-DYf_mQCB.js +34 -0
- package/dist/runner/auth/bearer.d.ts +7 -0
- package/dist/runner/auth/bearer.d.ts.map +1 -0
- package/dist/runner/auth/bearer.js +42 -0
- package/dist/runner/auth/bearer.js.map +1 -0
- package/dist/runner/auth/jwt.d.ts +19 -0
- package/dist/runner/auth/jwt.d.ts.map +1 -0
- package/dist/runner/auth/jwt.js +65 -0
- package/dist/runner/auth/jwt.js.map +1 -0
- package/dist/runner/auth/mtls.d.ts +11 -0
- package/dist/runner/auth/mtls.d.ts.map +1 -0
- package/dist/runner/auth/mtls.js +48 -0
- package/dist/runner/auth/mtls.js.map +1 -0
- package/dist/runner/auth/none.d.ts +3 -0
- package/dist/runner/auth/none.d.ts.map +1 -0
- package/dist/runner/auth/none.js +13 -0
- package/dist/runner/auth/none.js.map +1 -0
- package/dist/runner/index.d.ts +3 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +71 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/stdio.d.ts +7 -0
- package/dist/runner/stdio.d.ts.map +1 -0
- package/dist/runner/stdio.js +39 -0
- package/dist/runner/stdio.js.map +1 -0
- package/dist/runner/unix.d.ts +7 -0
- package/dist/runner/unix.d.ts.map +1 -0
- package/dist/runner/unix.js +42 -0
- package/dist/runner/unix.js.map +1 -0
- package/dist/runner/websocket.d.ts +28 -0
- package/dist/runner/websocket.d.ts.map +1 -0
- package/dist/runner/websocket.js +77 -0
- package/dist/runner/websocket.js.map +1 -0
- package/dist/socketChannel-KmtzF-9G.js +3658 -0
- package/dist/supervisorPlugin-Inb1S5IV.js +737 -0
- package/dist/token-v5ne2I0-.js +17 -0
- package/dist/tokenCredentials-WUJm2AKm.js +31 -0
- package/dist/websocketServer-MXcCJx0v.js +58 -0
- package/dist/workerChannel-P82YdNjh.js +27 -0
- package/package.json +69 -3
- package/src/Auth.ts +62 -0
- package/src/Contract.ts +100 -0
- package/src/Errors.ts +82 -0
- package/src/Instance.ts +12 -0
- package/src/Testing.ts +135 -0
- package/src/Transport.ts +52 -0
- package/src/bin.ts +145 -0
- package/src/host/auth/bearer.ts +10 -0
- package/src/host/auth/jwt.ts +10 -0
- package/src/host/auth/mtls.ts +48 -0
- package/src/host/auth/none.ts +13 -0
- package/src/host/command.ts +131 -0
- package/src/host/local.ts +41 -0
- package/src/host/unix.ts +65 -0
- package/src/host/websocket.ts +66 -0
- package/src/host/worker.ts +90 -0
- package/src/index.ts +115 -0
- package/src/internal/Certificates.ts +330 -0
- package/src/internal/FailureGroup.ts +176 -0
- package/src/internal/Limits.ts +12 -0
- package/src/internal/Peer.ts +4 -0
- package/src/internal/ServeLifecycle.ts +53 -0
- package/src/internal/Supervisor.ts +14 -0
- package/src/internal/assembly.ts +337 -0
- package/src/internal/auth/mtls.ts +40 -0
- package/src/internal/auth/token.ts +26 -0
- package/src/internal/auth/tokenCredentials.ts +65 -0
- package/src/internal/child.ts +323 -0
- package/src/internal/childErrors.ts +44 -0
- package/src/internal/childRuntime.ts +111 -0
- package/src/internal/cleanup.ts +34 -0
- package/src/internal/config.ts +8 -0
- package/src/internal/control.ts +49 -0
- package/src/internal/credentials.ts +112 -0
- package/src/internal/directTransport.ts +38 -0
- package/src/internal/entry.ts +288 -0
- package/src/internal/entryConfig.ts +190 -0
- package/src/internal/execution.ts +121 -0
- package/src/internal/follow.ts +17 -0
- package/src/internal/forkTree.ts +13 -0
- package/src/internal/host/local.ts +53 -0
- package/src/internal/host/runner.ts +187 -0
- package/src/internal/host.ts +209 -0
- package/src/internal/importer.ts +27 -0
- package/src/internal/listenerStartup.ts +55 -0
- package/src/internal/loadModule.ts +23 -0
- package/src/internal/platform.ts +12 -0
- package/src/internal/port.ts +623 -0
- package/src/internal/release.ts +71 -0
- package/src/internal/runner/Bootstrap.ts +9 -0
- package/src/internal/runner/Connection.ts +184 -0
- package/src/internal/runner/Execution.ts +244 -0
- package/src/internal/runner/Framing.ts +122 -0
- package/src/internal/runner/Local.ts +73 -0
- package/src/internal/runner/Lock.ts +29 -0
- package/src/internal/runner/Multiplex.ts +120 -0
- package/src/internal/runner/Packages.ts +178 -0
- package/src/internal/runner/ProcessObservation.ts +63 -0
- package/src/internal/runner/Processes.ts +109 -0
- package/src/internal/runner/Retention.ts +49 -0
- package/src/internal/runner/Store.ts +160 -0
- package/src/internal/runner/Supervisor.ts +901 -0
- package/src/internal/runner/Watchdog.ts +83 -0
- package/src/internal/runner/WatchdogProtocol.ts +12 -0
- package/src/internal/runner/Wire.ts +99 -0
- package/src/internal/runner/accept.ts +103 -0
- package/src/internal/runner/command.ts +15 -0
- package/src/internal/runner/connectionEnded.ts +28 -0
- package/src/internal/runner/model.ts +364 -0
- package/src/internal/serve.ts +117 -0
- package/src/internal/services.ts +74 -0
- package/src/internal/socketChannel.ts +64 -0
- package/src/internal/stdioChannel.ts +25 -0
- package/src/internal/supervisorPlugin.ts +67 -0
- package/src/internal/transportOptions.ts +17 -0
- package/src/internal/watchdogMain.ts +72 -0
- package/src/internal/websocket.ts +81 -0
- package/src/internal/websocketServer.ts +152 -0
- package/src/internal/workerBootstrap.ts +6 -0
- package/src/internal/workerChannel.ts +54 -0
- package/src/internal/workerMain.ts +23 -0
- package/src/runner/auth/bearer.ts +66 -0
- package/src/runner/auth/jwt.ts +114 -0
- package/src/runner/auth/mtls.ts +37 -0
- package/src/runner/auth/none.ts +13 -0
- package/src/runner/index.ts +97 -0
- package/src/runner/stdio.ts +76 -0
- package/src/runner/unix.ts +53 -0
- package/src/runner/websocket.ts +143 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { s as fromModule } from "./Graft-BsYq3F-J.js";
|
|
2
|
+
import { t as ConfigDirectory } from "./ConfigDirectory-BCC6q2R4.js";
|
|
3
|
+
import { registerHooks } from "node:module";
|
|
4
|
+
import { Array, Cause, Config, Context, Data, Effect, Exit, HashMap, MutableList, Option, Path, Predicate, Record, Ref, Result, Schema, Scope, String } from "effect";
|
|
5
|
+
import { SecureRandom } from "effect/crypto";
|
|
6
|
+
// packages/remote/src/internal/forkTree.ts
|
|
7
|
+
const findSubtree = (trees, id) => Array.findFirst(trees, (tree) => tree.id === id ? Option.some(tree) : findSubtree(tree.children, id));
|
|
8
|
+
const isSubtreeActive = (tree) => tree.state._tag === "Active" && Array.every(tree.children, isSubtreeActive);
|
|
9
|
+
// packages/loader/src/internal/snapshot.ts
|
|
10
|
+
/** Class instances are opaque; only arrays and plain records belong to the data graph. */
|
|
11
|
+
const isContainer = (value) => Predicate.isObjectOrArray(value) && (Array.isArray(value) || Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
12
|
+
const owned = /* @__PURE__ */ new WeakSet();
|
|
13
|
+
/** Internal evidence that every plain container in this graph has been captured. */
|
|
14
|
+
const isSnapshot = (value) => owned.has(value);
|
|
15
|
+
/**
|
|
16
|
+
* Copy and freeze a data graph without changing the caller's objects. Sharing,
|
|
17
|
+
* cycles, sparse arrays and null prototypes survive the copy. Own properties
|
|
18
|
+
* are captured as values; class instances (including Env) retain their identity.
|
|
19
|
+
*/
|
|
20
|
+
const snapshot = (value) => {
|
|
21
|
+
const copies = /* @__PURE__ */ new WeakMap();
|
|
22
|
+
const pending = MutableList.make();
|
|
23
|
+
const copyOf = (source) => {
|
|
24
|
+
if (!isContainer(source) || owned.has(source)) return source;
|
|
25
|
+
const existing = copies.get(source);
|
|
26
|
+
if (existing !== void 0) return existing;
|
|
27
|
+
const copy = Array.isArray(source) ? [] : Object.create(Object.getPrototypeOf(source));
|
|
28
|
+
copies.set(source, copy);
|
|
29
|
+
MutableList.append(pending, {
|
|
30
|
+
source,
|
|
31
|
+
copy
|
|
32
|
+
});
|
|
33
|
+
return copy;
|
|
34
|
+
};
|
|
35
|
+
const result = copyOf(value);
|
|
36
|
+
while (pending.length > 0) {
|
|
37
|
+
const item = MutableList.take(pending);
|
|
38
|
+
if (item === MutableList.Empty) break;
|
|
39
|
+
const { source, copy } = item;
|
|
40
|
+
for (const key of Reflect.ownKeys(source)) Object.defineProperty(copy, key, {
|
|
41
|
+
value: copyOf(Reflect.get(source, key)),
|
|
42
|
+
enumerable: Object.prototype.propertyIsEnumerable.call(source, key),
|
|
43
|
+
configurable: !(Array.isArray(source) && key === "length"),
|
|
44
|
+
writable: true
|
|
45
|
+
});
|
|
46
|
+
Object.freeze(copy);
|
|
47
|
+
owned.add(copy);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
// packages/loader/src/Entry.ts
|
|
52
|
+
/**
|
|
53
|
+
* Entries describe which plugins to load and how, as plain data that a
|
|
54
|
+
* config file can hold.
|
|
55
|
+
*/
|
|
56
|
+
/** A value read from an environment variable when the entry is loaded (`!env NAME` in YAML). */
|
|
57
|
+
var Env = class extends Data.TaggedClass("Env") {};
|
|
58
|
+
/**
|
|
59
|
+
* The id of the entry a plugin was loaded from. Ids persist in the config
|
|
60
|
+
* file, so a plugin can use this as a name that survives restarts.
|
|
61
|
+
*/
|
|
62
|
+
const CurrentId = Context.Reference("@graftland/loader/Entry/CurrentId", { defaultValue: () => Option.none() });
|
|
63
|
+
/** The descriptions also document the config file's JSON Schema. */
|
|
64
|
+
const Fields = Schema.Struct({
|
|
65
|
+
id: Schema.String.annotate({ description: "Identifies the entry." }),
|
|
66
|
+
name: Schema.String.annotate({ description: "The plugin's module: a relative path, a package name, or a short name. Ignored for groups." }),
|
|
67
|
+
config: Schema.optionalKey(Schema.Unknown).annotateKey({ description: "The plugin's input. For a group, its list of entries." }),
|
|
68
|
+
disabled: Schema.optionalKey(Schema.Boolean.annotate({ description: "true unloads the entry but keeps it in the file." })),
|
|
69
|
+
group: Schema.optionalKey(Schema.Boolean.annotate({ description: "true makes the entry a group of other entries." })),
|
|
70
|
+
inject: Schema.optionalKey(Schema.Array(Schema.String).annotate({ description: "Service keys to wait for before loading the plugin, in addition to its own inject." })),
|
|
71
|
+
isolate: Schema.optionalKey(Schema.Record(Schema.String, Schema.Union([Schema.Literal(true), Schema.String])).annotate({ description: "Service or event keys to isolate: true for a private realm, or a label for a shared one." })),
|
|
72
|
+
intercept: Schema.optionalKey(Schema.Record(Schema.String, Schema.Unknown).annotate({ description: "Patches for registered references, applying to this entry and its descendants. Each value is resolved, decoded with the registered Schema, then merged." }))
|
|
73
|
+
});
|
|
74
|
+
/** Known fields are validated; additional entry metadata is preserved as unknown data. */
|
|
75
|
+
const Entry = Schema.StructWithRest(Fields, [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
76
|
+
var CyclicConfig = class extends Schema.TaggedError()("CyclicConfig", { path: Schema.Array(Schema.String) }) {
|
|
77
|
+
get message() {
|
|
78
|
+
return `Configuration contains a cycle at ${Array.join(this.path, ".") || "<root>"}`;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
/** Identity-based graph traversal; sharing is allowed, but a back edge is not. */
|
|
82
|
+
const checkAcyclic = (value) => {
|
|
83
|
+
const active = /* @__PURE__ */ new WeakSet();
|
|
84
|
+
const finished = /* @__PURE__ */ new WeakSet();
|
|
85
|
+
const work = MutableList.make();
|
|
86
|
+
MutableList.prepend(work, {
|
|
87
|
+
value,
|
|
88
|
+
path: [],
|
|
89
|
+
leave: false
|
|
90
|
+
});
|
|
91
|
+
while (work.length > 0) {
|
|
92
|
+
const frame = MutableList.take(work);
|
|
93
|
+
if (frame === MutableList.Empty) break;
|
|
94
|
+
const { value, path, leave } = frame;
|
|
95
|
+
if (!isContainer(value)) continue;
|
|
96
|
+
if (leave) {
|
|
97
|
+
active.delete(value);
|
|
98
|
+
finished.add(value);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (active.has(value)) return Result.fail(CyclicConfig.make({ path }));
|
|
102
|
+
if (finished.has(value)) continue;
|
|
103
|
+
active.add(value);
|
|
104
|
+
MutableList.prepend(work, {
|
|
105
|
+
value,
|
|
106
|
+
path,
|
|
107
|
+
leave: true
|
|
108
|
+
});
|
|
109
|
+
for (const [key, child] of Record.toEntries(value)) MutableList.prepend(work, {
|
|
110
|
+
value: child,
|
|
111
|
+
path: [...path, key],
|
|
112
|
+
leave: false
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return Result.succeed(void 0);
|
|
116
|
+
};
|
|
117
|
+
/** Rejects cycles and resolves Env while preserving sharing within each execution. */
|
|
118
|
+
const resolveEnv = (value) => Effect.suspend(() => {
|
|
119
|
+
const resolved = /* @__PURE__ */ new WeakMap();
|
|
120
|
+
const resolve = (value) => Effect.suspend(() => {
|
|
121
|
+
if (value instanceof Env) return Config.String(value.name);
|
|
122
|
+
if (!isContainer(value)) return Effect.succeed(value);
|
|
123
|
+
if (resolved.has(value)) return Effect.succeed(resolved.get(value));
|
|
124
|
+
const result = Array.isArray(value) ? Effect.forEach(value, resolve) : Effect.map(Effect.forEach(Record.toEntries(value), ([key, inner]) => Effect.map(resolve(inner), (value) => [key, value])), Record.fromEntries);
|
|
125
|
+
return Effect.map(result, (result) => {
|
|
126
|
+
resolved.set(value, result);
|
|
127
|
+
return result;
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
return Effect.andThen(Effect.fromResult(checkAcyclic(value)), resolve(value));
|
|
131
|
+
});
|
|
132
|
+
// packages/loader/src/internal/recovery.ts
|
|
133
|
+
/** Recovery is safe only when no companion failure, defect or interruption would be discarded. */
|
|
134
|
+
const isOnlyFailure = (cause, matches) => cause.reasons.length === 1 && Array.some(cause.reasons, (reason) => Cause.isFailReason(reason) && matches(reason.error));
|
|
135
|
+
// packages/loader/src/ModuleResolver.ts
|
|
136
|
+
/**
|
|
137
|
+
* Turns the `name` of an entry into a plugin.
|
|
138
|
+
*/
|
|
139
|
+
var ModuleNotFound = class extends Schema.TaggedError()("ModuleNotFound", {
|
|
140
|
+
plugin: Schema.String,
|
|
141
|
+
tried: Schema.Array(Schema.String)
|
|
142
|
+
}) {
|
|
143
|
+
get message() {
|
|
144
|
+
return `No plugin found for "${this.plugin}" (tried ${Array.join(this.tried, ", ")})`;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
/** A module could not be imported, or plugin resolution found no plugin export. */
|
|
148
|
+
var ModuleInvalid = class extends Schema.TaggedError()("ModuleInvalid", {
|
|
149
|
+
specifier: Schema.String,
|
|
150
|
+
cause: Schema.Unknown
|
|
151
|
+
}) {
|
|
152
|
+
get message() {
|
|
153
|
+
return `Module "${this.specifier}" could not be loaded`;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var ModuleResolver = class extends Context.Service()("@graftland/loader/ModuleResolver") {};
|
|
157
|
+
const isPath = (name) => String.startsWith(".")(name) || String.startsWith("/")(name);
|
|
158
|
+
/** The specifiers tried for a name, in order: as written, then the naming conventions for short names. */
|
|
159
|
+
const candidates = (name) => isPath(name) || String.includes(":")(name) || String.startsWith("@")(name) ? [name] : [
|
|
160
|
+
name,
|
|
161
|
+
`@graftland/plugin-${name}`,
|
|
162
|
+
`graft-plugin-${name}`
|
|
163
|
+
];
|
|
164
|
+
/** An error followed by its causes, outermost first. */
|
|
165
|
+
const causes = (error, depth = 0) => depth < 8 && Predicate.hasProperty(error, "cause") && error.cause !== void 0 ? [error, ...causes(error.cause, depth + 1)] : [error];
|
|
166
|
+
/** Node's message for a missing package or file, followed by its importer. */
|
|
167
|
+
const decodeNotFound = Schema.decodeUnknownOption(Schema.TemplateLiteralParser([
|
|
168
|
+
"Cannot find ",
|
|
169
|
+
Schema.Literals(["package", "module"]),
|
|
170
|
+
" '",
|
|
171
|
+
Schema.String.check(Schema.isPattern(/^[^']+$/)),
|
|
172
|
+
"'",
|
|
173
|
+
Schema.String
|
|
174
|
+
]));
|
|
175
|
+
/** What a module resolution error says is missing, if it is one. */
|
|
176
|
+
const missingName = (error) => Predicate.hasProperty(error, "code") && error.code === "ERR_MODULE_NOT_FOUND" && Predicate.hasProperty(error, "message") && Predicate.isString(error.message) ? Option.map(decodeNotFound(error.message), ([, , , name]) => name) : Option.none();
|
|
177
|
+
/**
|
|
178
|
+
* Whether an import failed because the candidate itself does not exist, as
|
|
179
|
+
* opposed to something it imports. Only then is the next candidate tried.
|
|
180
|
+
*/
|
|
181
|
+
const isMissing = (error, candidate) => Array.some(causes(error), (error) => Option.exists(missingName(error), (name) => Array.contains(candidate, name)));
|
|
182
|
+
/** The package a bare specifier belongs to: `@scope/name` or `name`. */
|
|
183
|
+
const packageOf = (specifier) => Array.join(Array.take(String.split("/")(specifier), String.startsWith("@")(specifier) ? 2 : 1), "/");
|
|
184
|
+
var PlanKey = class extends Data.Class {};
|
|
185
|
+
/** Failed attempts release their resources before recovery; successful leases stay with the entry. */
|
|
186
|
+
const inCandidateScope = (effect) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
187
|
+
const parent = yield* Effect.scope;
|
|
188
|
+
const scope = yield* Scope.fork(parent);
|
|
189
|
+
const result = yield* Effect.exit(restore(effect).pipe(Scope.provide(scope)));
|
|
190
|
+
if (Exit.isSuccess(result)) return result.value;
|
|
191
|
+
const closed = yield* Effect.exit(Scope.close(scope, result));
|
|
192
|
+
return yield* Effect.failCause(Exit.isFailure(closed) ? Cause.combine(result.cause, closed.cause) : result.cause);
|
|
193
|
+
}));
|
|
194
|
+
/**
|
|
195
|
+
* Resolves names with dynamic `import`. Relative specifiers are resolved
|
|
196
|
+
* against `ConfigDirectory` when supplied, otherwise `base`; file URLs retain their query and fragment for importing, while
|
|
197
|
+
* their decoded paths identify missing candidates. Bare specifiers go through
|
|
198
|
+
* `importer`, which should run in the application so its dependencies are visible.
|
|
199
|
+
* Effect importers may acquire
|
|
200
|
+
* resources in a candidate scope owned by the entry lifecycle. A failed candidate
|
|
201
|
+
* closes before fallback; a successful candidate remains leased until entry disposal.
|
|
202
|
+
* Importers may attach observation-only leases to the separate observationScope.
|
|
203
|
+
* The caller keeps that scope through failure and closes it on retry or disposal.
|
|
204
|
+
*/
|
|
205
|
+
const make$1 = (options) => Effect.gen(function* () {
|
|
206
|
+
const path = yield* Path.Path;
|
|
207
|
+
/** Keep the import target and Node's possible missing names in one normalization step. */
|
|
208
|
+
const normalize = Effect.fnUntraced(function* (specifier) {
|
|
209
|
+
const invalid = (cause) => ModuleInvalid.make({
|
|
210
|
+
specifier,
|
|
211
|
+
cause
|
|
212
|
+
});
|
|
213
|
+
if (isPath(specifier)) {
|
|
214
|
+
const directory = yield* ConfigDirectory;
|
|
215
|
+
const file = path.resolve(Option.getOrElse(directory, () => options.base), specifier);
|
|
216
|
+
const url = yield* path.toFileUrl(file).pipe(Effect.mapError(invalid));
|
|
217
|
+
return {
|
|
218
|
+
target: url.href,
|
|
219
|
+
names: [
|
|
220
|
+
specifier,
|
|
221
|
+
file,
|
|
222
|
+
url.href
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
if (String.startsWith("file:")(String.toLowerCase(specifier))) {
|
|
227
|
+
const url = yield* Effect.try({
|
|
228
|
+
try: () => new URL(specifier),
|
|
229
|
+
catch: invalid
|
|
230
|
+
});
|
|
231
|
+
return {
|
|
232
|
+
target: specifier,
|
|
233
|
+
names: [
|
|
234
|
+
specifier,
|
|
235
|
+
yield* path.fromFileUrl(url).pipe(Effect.mapError(invalid)),
|
|
236
|
+
url.href
|
|
237
|
+
]
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
target: specifier,
|
|
242
|
+
names: String.includes(":")(specifier) ? [specifier] : [specifier, packageOf(specifier)]
|
|
243
|
+
};
|
|
244
|
+
});
|
|
245
|
+
const plans = yield* Ref.make({
|
|
246
|
+
revision: -1,
|
|
247
|
+
entries: HashMap.empty()
|
|
248
|
+
});
|
|
249
|
+
const plan = Effect.fnUntraced(function* (name) {
|
|
250
|
+
const key = new PlanKey({
|
|
251
|
+
name,
|
|
252
|
+
target: (yield* normalize(name)).target
|
|
253
|
+
});
|
|
254
|
+
const environment = options.resolution;
|
|
255
|
+
const revision = environment === void 0 ? 0 : yield* environment.revision;
|
|
256
|
+
const cached = yield* Ref.get(plans);
|
|
257
|
+
if (cached.revision === revision) {
|
|
258
|
+
const found = HashMap.get(cached.entries, key);
|
|
259
|
+
if (Option.isSome(found)) return found.value;
|
|
260
|
+
} else yield* Ref.set(plans, {
|
|
261
|
+
revision,
|
|
262
|
+
entries: HashMap.empty()
|
|
263
|
+
});
|
|
264
|
+
const normalized = yield* Effect.forEach(candidates(name), (specifier) => Effect.map(normalize(specifier), (candidate) => ({
|
|
265
|
+
...candidate,
|
|
266
|
+
specifier
|
|
267
|
+
})));
|
|
268
|
+
const selected = yield* Effect.forEach(normalized, (candidate) => Effect.map(environment === void 0 ? Effect.succeed(Result.succeed(true)) : environment.exists(candidate.target).pipe(Effect.mapError((cause) => ModuleInvalid.make({
|
|
269
|
+
specifier: candidate.specifier,
|
|
270
|
+
cause
|
|
271
|
+
})), Effect.result), (exists) => ({
|
|
272
|
+
...candidate,
|
|
273
|
+
exists
|
|
274
|
+
})));
|
|
275
|
+
yield* Ref.update(plans, (current) => current.revision !== revision || Array.some(selected, (candidate) => Result.isFailure(candidate.exists)) ? current : {
|
|
276
|
+
...current,
|
|
277
|
+
entries: HashMap.set(current.entries, key, selected)
|
|
278
|
+
});
|
|
279
|
+
return selected;
|
|
280
|
+
});
|
|
281
|
+
const load = Effect.fnUntraced(function* (specifier, candidate, observationScope) {
|
|
282
|
+
const context = yield* Effect.context();
|
|
283
|
+
return yield* Effect.tryPromise({
|
|
284
|
+
try: (signal) => {
|
|
285
|
+
const imported = options.importer(candidate.target, { observationScope });
|
|
286
|
+
return Effect.isEffect(imported) ? Promise.resolve(imported) : imported.then(Effect.succeed, (cause) => {
|
|
287
|
+
if (signal.aborted) Effect.runSyncWith(context)(Effect.logError("Module import failed after cancellation", Cause.die(cause)).pipe(Effect.annotateLogs({ specifier })));
|
|
288
|
+
throw cause;
|
|
289
|
+
});
|
|
290
|
+
},
|
|
291
|
+
catch: (cause) => ModuleInvalid.make({
|
|
292
|
+
specifier,
|
|
293
|
+
cause
|
|
294
|
+
})
|
|
295
|
+
}).pipe(Effect.flatMap((imported) => imported.pipe(Effect.mapError((cause) => ModuleInvalid.make({
|
|
296
|
+
specifier,
|
|
297
|
+
cause
|
|
298
|
+
})))));
|
|
299
|
+
});
|
|
300
|
+
/** Only a missing candidate permits short-name fallback. */
|
|
301
|
+
const attempt = Effect.fnUntraced(function* (candidate, observationScope) {
|
|
302
|
+
const { specifier } = candidate;
|
|
303
|
+
return yield* load(specifier, candidate, observationScope).pipe(Effect.flatMap((module) => Effect.fromOption(fromModule(module), () => ModuleInvalid.make({
|
|
304
|
+
specifier,
|
|
305
|
+
cause: "it exports no plugin"
|
|
306
|
+
}))), inCandidateScope, Effect.asSome, Effect.catchCauseIf((cause) => isOnlyFailure(cause, (error) => isMissing(error.cause, candidate.names)), () => Effect.succeedNone));
|
|
307
|
+
});
|
|
308
|
+
return {
|
|
309
|
+
importModule: Effect.fnUntraced(function* (specifier, options) {
|
|
310
|
+
const caller = yield* Effect.scope;
|
|
311
|
+
const candidate = yield* normalize(specifier);
|
|
312
|
+
return yield* load(specifier, candidate, options?.observationScope ?? caller).pipe(inCandidateScope);
|
|
313
|
+
}),
|
|
314
|
+
resolve: Effect.fnUntraced(function* (name, importOptions) {
|
|
315
|
+
const caller = yield* Effect.scope;
|
|
316
|
+
const observationScope = importOptions?.observationScope ?? caller;
|
|
317
|
+
const tried = candidates(name);
|
|
318
|
+
if (options.resolution !== void 0) yield* inCandidateScope(options.resolution.observe(tried, { observationScope }).pipe(Effect.mapError((cause) => ModuleInvalid.make({
|
|
319
|
+
specifier: name,
|
|
320
|
+
cause
|
|
321
|
+
}))));
|
|
322
|
+
const selected = yield* plan(name);
|
|
323
|
+
for (const candidate of selected) {
|
|
324
|
+
if (!(yield* Effect.fromResult(candidate.exists))) continue;
|
|
325
|
+
const plugin = yield* attempt(candidate, observationScope);
|
|
326
|
+
if (Option.isSome(plugin)) return plugin.value;
|
|
327
|
+
}
|
|
328
|
+
return yield* ModuleNotFound.make({
|
|
329
|
+
plugin: name,
|
|
330
|
+
tried
|
|
331
|
+
});
|
|
332
|
+
})
|
|
333
|
+
};
|
|
334
|
+
});
|
|
335
|
+
// packages/remote/src/internal/importer.ts
|
|
336
|
+
/** Bare names resolve from the application; imported dependencies keep their own parent URLs. */
|
|
337
|
+
const make = Effect.fnUntraced(function* (directory) {
|
|
338
|
+
const path = yield* Path.Path;
|
|
339
|
+
const base = yield* path.toFileUrl(path.join(directory, "graft.yml"));
|
|
340
|
+
const prefix = `graft-remote-${yield* (yield* SecureRandom.SecureRandom).uuidV4()}:`;
|
|
341
|
+
yield* Effect.acquireRelease(Effect.sync(() => registerHooks({ resolve: (specifier, context, next) => String.startsWith(prefix)(specifier) ? next(String.slice(prefix.length)(specifier), {
|
|
342
|
+
...context,
|
|
343
|
+
parentURL: base.href
|
|
344
|
+
}) : next(specifier, context) })), (hooks) => Effect.sync(() => hooks.deregister()));
|
|
345
|
+
return (specifier) => import(prefix + specifier);
|
|
346
|
+
});
|
|
347
|
+
export { isOnlyFailure as a, Env as c, isSnapshot as d, snapshot as f, make$1 as i, resolveEnv as l, isSubtreeActive as m, ModuleInvalid as n, CurrentId as o, findSubtree as p, ModuleResolver as r, Entry as s, make as t, isContainer as u };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Connect, Source } from "./internal/credentials.js";
|
|
2
|
+
import { ChildFailure } from "./internal/childErrors.js";
|
|
3
|
+
import { MissingInstance, RemoteError, RemoteWithdrawn } from "./Errors.js";
|
|
4
|
+
import { Contract, Contract_d_exports, UndeclaredFailure } from "./Contract.js";
|
|
5
|
+
import { Instance } from "./Instance.js";
|
|
6
|
+
import { RemoteTerminationUnconfirmed } from "./internal/runner/model.js";
|
|
7
|
+
import { host } from "./internal/entry.js";
|
|
8
|
+
import { Plugin } from "@graftland/graft";
|
|
9
|
+
import { Duration, Schedule, Schema } from "effect";
|
|
10
|
+
export interface Options<D extends ReadonlyArray<Plugin.Dependency> = readonly []> {
|
|
11
|
+
readonly connect: Connect<D>;
|
|
12
|
+
/** Contract module resolved independently in each execution environment. */
|
|
13
|
+
readonly contractModule: string;
|
|
14
|
+
readonly config?: Schema.Json;
|
|
15
|
+
readonly retry?: Schedule.Schedule<unknown, unknown> | undefined;
|
|
16
|
+
readonly shutdownTimeout?: Duration.Input | undefined;
|
|
17
|
+
}
|
|
18
|
+
export declare const plugin: <S extends Schema.Top & {
|
|
19
|
+
readonly Encoded: Schema.Json;
|
|
20
|
+
readonly DecodingServices: never;
|
|
21
|
+
readonly EncodingServices: never;
|
|
22
|
+
}, E extends Schema.Top & {
|
|
23
|
+
readonly DecodingServices: never;
|
|
24
|
+
readonly EncodingServices: never;
|
|
25
|
+
}, const D extends ReadonlyArray<Plugin.Dependency> = readonly []>(contract: Contract<S, E>, options: Options<D> & {
|
|
26
|
+
readonly config?: S["Encoded"];
|
|
27
|
+
}) => Plugin.Plugin<void, void, E["Type"] | UndeclaredFailure | RemoteError | RemoteWithdrawn | MissingInstance>;
|
|
28
|
+
export { ChildFailure, type Connect, Contract_d_exports as Contract, type Source as CredentialSource, Instance, MissingInstance, RemoteError, RemoteTerminationUnconfirmed, RemoteWithdrawn, UndeclaredFailure, host as default };
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["Credential.Connect","Contract.Contract","Contract.UndeclaredFailure"],"sources":["../src/index.ts"],"mappings":";;;;;;;;;iBAwBiB,QAChB,UAAU,cAAc,OAAO;WAEtB,SAASA,QAAmB;;WAE5B;WACA,SAAS,OAAO;WAChB,QAAQ,SAAS;WACjB,kBAAkB,SAAS;;qBA4BxB,SACZ,UAAU,OAAO;WACP,SAAS,OAAO;WAChB;WACA;GAEV,UAAU,OAAO;WACP;WACA;SAEJ,UAAU,cAAc,OAAO,2BAAyB,UAEpDC,SAAkB,GAAG,IAAE,SACxB,QAAQ;WAAgB,SAAS;MACxC,OAAO,mBAGP,YACAC,oBACA,cACA,kBACA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { a as provide, l as make, u as optional } from "./Graft-BsYq3F-J.js";
|
|
2
|
+
import { r as ModuleResolver } from "./importer-D7zSgqxq.js";
|
|
3
|
+
import { a as publicError, d as follow, f as Host, n as host, r as launch, s as CapabilityFailed } from "./entry-SYsx9VNb.js";
|
|
4
|
+
import { n as Credentials } from "./Auth-BElTC9_X.js";
|
|
5
|
+
import { i as MissingInstance, n as CredentialsError, o as RemoteError, s as RemoteWithdrawn } from "./Errors-oPsTLY7l.js";
|
|
6
|
+
import { n as prepare } from "./token-v5ne2I0-.js";
|
|
7
|
+
import { d as ChildFailure, n as UndeclaredFailure, t as Contract_exports } from "./Contract-CcpSIJm4.js";
|
|
8
|
+
import { O as Instance, l as RemoteTerminationUnconfirmed } from "./Peer-IJgFK6mD.js";
|
|
9
|
+
import { Array, Cause, Context, Effect, Path, Schema, Scope } from "effect";
|
|
10
|
+
import { SecureRandom } from "effect/crypto";
|
|
11
|
+
import { ChildProcessSpawner } from "effect/process";
|
|
12
|
+
// packages/remote/src/internal/credentials.ts
|
|
13
|
+
const provider = (source, encode) => {
|
|
14
|
+
const input = Effect.isEffect(source) ? {
|
|
15
|
+
inject: [],
|
|
16
|
+
read: source
|
|
17
|
+
} : source;
|
|
18
|
+
return make({
|
|
19
|
+
name: "remote-effect-credentials",
|
|
20
|
+
inject: input.inject,
|
|
21
|
+
apply: Effect.fnUntraced(function* () {
|
|
22
|
+
const context = yield* Effect.context().pipe(Effect.map(Context.omit(Scope.Scope)));
|
|
23
|
+
const read = input.read.pipe(Effect.provideContext(context), Effect.mapError((error) => CredentialsError.make({ cause: Cause.fail(error) })));
|
|
24
|
+
yield* provide(Credentials, encode(read));
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const invocation = (connect) => {
|
|
29
|
+
const auth = connect.auth;
|
|
30
|
+
if (auth === void 0) return void 0;
|
|
31
|
+
if ("mtls" in auth) {
|
|
32
|
+
const source = auth.mtls;
|
|
33
|
+
if (Effect.isEffect(source) || "read" in source) return {
|
|
34
|
+
plugin: provider(source, (read) => ({
|
|
35
|
+
kind: "Certificate",
|
|
36
|
+
read: read.pipe(Effect.map((value) => ({
|
|
37
|
+
_tag: "Certificate",
|
|
38
|
+
value
|
|
39
|
+
})))
|
|
40
|
+
})),
|
|
41
|
+
config: void 0
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if ("bearer" in auth || "jwt" in auth) {
|
|
45
|
+
const source = "bearer" in auth ? auth.bearer.token : auth.jwt.token;
|
|
46
|
+
if (typeof source !== "string" && (Effect.isEffect(source) || "read" in source)) return {
|
|
47
|
+
plugin: provider(source, (read) => ({
|
|
48
|
+
kind: "Authorization",
|
|
49
|
+
read: read.pipe(Effect.flatMap(prepare), Effect.map((value) => ({
|
|
50
|
+
_tag: "Authorization",
|
|
51
|
+
value
|
|
52
|
+
})))
|
|
53
|
+
})),
|
|
54
|
+
config: void 0
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// packages/remote/src/index.ts
|
|
59
|
+
const publicCause = (declared, cause) => Cause.fromReasons(Array.flatMap(cause.reasons, (reason) => {
|
|
60
|
+
if (reason._tag !== "Fail") return [reason];
|
|
61
|
+
return Schema.is(CapabilityFailed)(reason.error) ? Array.map(publicCause(declared, reason.error.cause).reasons, (inner) => inner.annotate(Cause.reasonAnnotations(reason))) : [Cause.makeFailReason(publicError(declared, reason.error)).annotate(Cause.reasonAnnotations(reason))];
|
|
62
|
+
}));
|
|
63
|
+
const plugin = (contract, options) => make({
|
|
64
|
+
name: contract.name,
|
|
65
|
+
inject: [
|
|
66
|
+
optional(ModuleResolver),
|
|
67
|
+
Path.Path,
|
|
68
|
+
SecureRandom.SecureRandom,
|
|
69
|
+
ChildProcessSpawner.ChildProcessSpawner
|
|
70
|
+
],
|
|
71
|
+
retry: options.retry,
|
|
72
|
+
apply: () => Effect.gen(function* () {
|
|
73
|
+
const input = yield* Schema.decodeUnknownEffect(Host)({
|
|
74
|
+
contract: options.contractModule,
|
|
75
|
+
connect: options.connect,
|
|
76
|
+
config: options.config === void 0 ? {} : options.config
|
|
77
|
+
});
|
|
78
|
+
yield* Schema.decodeEffect(contract.config)(input.config);
|
|
79
|
+
const child = yield* launch(contract, input, {
|
|
80
|
+
contractModule: options.contractModule,
|
|
81
|
+
shutdownTimeout: options.shutdownTimeout
|
|
82
|
+
}, invocation(options.connect));
|
|
83
|
+
yield* follow(child, (cause) => Effect.failCause(publicCause(contract.error, cause)));
|
|
84
|
+
}).pipe(Effect.mapError((error) => publicError(contract.error, error)))
|
|
85
|
+
});
|
|
86
|
+
export { ChildFailure, Contract_exports as Contract, Instance, MissingInstance, RemoteError, RemoteTerminationUnconfirmed, RemoteWithdrawn, UndeclaredFailure, host as default, plugin };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["Configuration.Host","Credential.invocation"],"sources":["../src/index.ts"],"sourcesContent":["import { Plugin } from \"@graftland/graft\"\nimport { ModuleResolver } from \"@graftland/loader\"\nimport { Array, Cause, Effect, Path, Schema } from \"effect\"\nimport type { Duration, Schedule } from \"effect\"\nimport { SecureRandom } from \"effect/crypto\"\nimport { ChildProcessSpawner } from \"effect/process\"\nimport { launch } from \"./internal/entry\"\nimport { follow } from \"./internal/follow\"\nimport { CapabilityFailed } from \"./internal/assembly\"\nimport { publicError } from \"./internal/execution\"\nimport * as Configuration from \"./internal/entryConfig\"\nimport * as Credential from \"./internal/credentials\"\nimport { RemoteWithdrawn, RemoteError, MissingInstance } from \"./Errors\"\nimport * as Contract from \"./Contract\"\nexport { Contract }\nexport { Instance } from \"./Instance\"\nexport { RemoteTerminationUnconfirmed } from \"./internal/runner/model\"\nexport { RemoteError, RemoteWithdrawn, MissingInstance } from \"./Errors\"\nexport { UndeclaredFailure, ChildFailure } from \"./Contract\"\nexport type {\n\tConnect,\n\tSource as CredentialSource,\n} from \"./internal/credentials\"\n\nexport interface Options<\n\tD extends ReadonlyArray<Plugin.Dependency> = readonly [],\n> {\n\treadonly connect: Credential.Connect<D>\n\t/** Contract module resolved independently in each execution environment. */\n\treadonly contractModule: string\n\treadonly config?: Schema.Json\n\treadonly retry?: Schedule.Schedule<unknown, unknown> | undefined\n\treadonly shutdownTimeout?: Duration.Input | undefined\n}\nconst publicCause = <E extends Schema.Top>(\n\tdeclared: E,\n\tcause: Cause.Cause<unknown>,\n): Cause.Cause<\n\t| E[\"Type\"]\n\t| Contract.UndeclaredFailure\n\t| RemoteWithdrawn\n\t| RemoteError\n\t| MissingInstance\n> =>\n\tCause.fromReasons(\n\t\tArray.flatMap(cause.reasons, (reason) => {\n\t\t\tif (reason._tag !== \"Fail\") return [reason]\n\t\t\treturn Schema.is(CapabilityFailed)(reason.error)\n\t\t\t\t? Array.map(\n\t\t\t\t\t\tpublicCause(declared, reason.error.cause).reasons,\n\t\t\t\t\t\t(inner) => inner.annotate(Cause.reasonAnnotations(reason)),\n\t\t\t\t\t)\n\t\t\t\t: [\n\t\t\t\t\t\tCause.makeFailReason(publicError(declared, reason.error)).annotate(\n\t\t\t\t\t\t\tCause.reasonAnnotations(reason),\n\t\t\t\t\t\t),\n\t\t\t\t\t]\n\t\t}),\n\t)\n\nexport const plugin = <\n\tS extends Schema.Top & {\n\t\treadonly Encoded: Schema.Json\n\t\treadonly DecodingServices: never\n\t\treadonly EncodingServices: never\n\t},\n\tE extends Schema.Top & {\n\t\treadonly DecodingServices: never\n\t\treadonly EncodingServices: never\n\t},\n\tconst D extends ReadonlyArray<Plugin.Dependency> = readonly [],\n>(\n\tcontract: Contract.Contract<S, E>,\n\toptions: Options<D> & { readonly config?: S[\"Encoded\"] },\n): Plugin.Plugin<\n\tvoid,\n\tvoid,\n\t| E[\"Type\"]\n\t| Contract.UndeclaredFailure\n\t| RemoteError\n\t| RemoteWithdrawn\n\t| MissingInstance\n> =>\n\tPlugin.make({\n\t\tname: contract.name,\n\t\tinject: [\n\t\t\tPlugin.optional(ModuleResolver.ModuleResolver),\n\t\t\tPath.Path,\n\t\t\tSecureRandom.SecureRandom,\n\t\t\tChildProcessSpawner.ChildProcessSpawner,\n\t\t],\n\t\tretry: options.retry,\n\t\tapply: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst input = yield* Schema.decodeUnknownEffect(Configuration.Host)({\n\t\t\t\t\tcontract: options.contractModule,\n\t\t\t\t\tconnect: options.connect,\n\t\t\t\t\tconfig: options.config === undefined ? {} : options.config,\n\t\t\t\t})\n\t\t\t\tyield* Schema.decodeEffect(contract.config)(input.config)\n\t\t\t\tconst child = yield* launch(\n\t\t\t\t\tcontract,\n\t\t\t\t\tinput,\n\t\t\t\t\t{\n\t\t\t\t\t\tcontractModule: options.contractModule,\n\t\t\t\t\t\tshutdownTimeout: options.shutdownTimeout,\n\t\t\t\t\t},\n\t\t\t\t\tCredential.invocation(options.connect),\n\t\t\t\t)\n\t\t\t\tyield* follow(child, (cause) =>\n\t\t\t\t\tEffect.failCause(publicCause(contract.error, cause)),\n\t\t\t\t)\n\t\t\t}).pipe(Effect.mapError((error) => publicError(contract.error, error))),\n\t})\nexport { host as default } from \"./internal/entry\"\n"],"mappings":";;;;;;;;;;;;;;;;;AAkCA,MAAM,eACL,UACA,UAQA,MAAM,YACL,MAAM,QAAQ,MAAM,UAAU,WAAW;CACxC,IAAI,OAAO,SAAS,QAAQ,OAAO,CAAC,MAAM;CAC1C,OAAO,OAAO,GAAG,gBAAgB,CAAC,CAAC,OAAO,KAAK,IAC5C,MAAM,IACN,YAAY,UAAU,OAAO,MAAM,KAAK,CAAC,CAAC,UACzC,UAAU,MAAM,SAAS,MAAM,kBAAkB,MAAM,CAAC,CAC1D,IACC,CACA,MAAM,eAAe,YAAY,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,SACzD,MAAM,kBAAkB,MAAM,CAC/B,CACD;AACH,CAAC,CACF;AAED,MAAa,UAYZ,UACA,YAUA,OAAO,KAAK;CACX,MAAM,SAAS;CACf,QAAQ;EACP,OAAO,SAAS,eAAe,cAAc;EAC7C,KAAK;EACL,aAAa;EACb,oBAAoB;CACrB;CACA,OAAO,QAAQ;CACf,aACC,OAAO,IAAI,aAAa;EACvB,MAAM,QAAQ,OAAO,OAAO,oBAAoBA,IAAkB,CAAC,CAAC;GACnE,UAAU,QAAQ;GAClB,SAAS,QAAQ;GACjB,QAAQ,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,QAAQ;EACrD,CAAC;EACD,OAAO,OAAO,aAAa,SAAS,MAAM,CAAC,CAAC,MAAM,MAAM;EACxD,MAAM,QAAQ,OAAO,OACpB,UACA,OACA;GACC,gBAAgB,QAAQ;GACxB,iBAAiB,QAAQ;EAC1B,GACAC,WAAsB,QAAQ,OAAO,CACtC;EACA,OAAO,OAAO,QAAQ,UACrB,OAAO,UAAU,YAAY,SAAS,OAAO,KAAK,CAAC,CACpD;CACD,CAAC,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,YAAY,SAAS,OAAO,KAAK,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Array, DateTime, Effect, FileSystem, Path, Redacted, Result, Schema, String } from "effect";
|
|
2
|
+
import { SecureRandom, WebCrypto } from "effect/crypto";
|
|
3
|
+
import { Base64 } from "effect/encoding";
|
|
4
|
+
import { NetAddress } from "effect/net";
|
|
5
|
+
import * as asn1js from "asn1js";
|
|
6
|
+
import * as pki from "pkijs";
|
|
7
|
+
// src/internal/Certificates.ts
|
|
8
|
+
var CertificateError = class extends Schema.TaggedError()("CertificateError", {
|
|
9
|
+
detail: Schema.String,
|
|
10
|
+
cause: Schema.optional(Schema.Defect())
|
|
11
|
+
}) {
|
|
12
|
+
get message() {
|
|
13
|
+
return this.detail;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/** A requested output already exists and replacing it was not asked for. */
|
|
17
|
+
var CertificateExists = class extends Schema.TaggedError()("CertificateExists", { file: Schema.String }) {
|
|
18
|
+
get message() {
|
|
19
|
+
return `${this.file} already exists; use --force to replace the requested certificates`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const pem = (label, bytes) => `-----BEGIN ${label}-----\n${String.replace(/.{64}(?=.)/g, "$&\n")(Base64.encode(new Uint8Array(bytes)))}\n-----END ${label}-----\n`;
|
|
23
|
+
const der = (value) => Effect.fromResult(Base64.decode(String.replace(/-----[^-]+-----|\s/g, "")(value))).pipe(Effect.map((bytes) => new Uint8Array(bytes)));
|
|
24
|
+
const subject = (name) => new pki.RelativeDistinguishedNames({ typesAndValues: [new pki.AttributeTypeAndValue({
|
|
25
|
+
type: "2.5.4.3",
|
|
26
|
+
value: new asn1js.Utf8String({ value: name })
|
|
27
|
+
})] });
|
|
28
|
+
const hostName = (host) => Result.match(NetAddress.ipFromString(host), {
|
|
29
|
+
onFailure: () => new pki.GeneralName({
|
|
30
|
+
type: 2,
|
|
31
|
+
value: host
|
|
32
|
+
}),
|
|
33
|
+
onSuccess: (ip) => new pki.GeneralName({
|
|
34
|
+
type: 7,
|
|
35
|
+
value: new asn1js.OctetString({ valueHex: new Uint8Array(ip._tag === "Ipv4Address" ? NetAddress.ipv4ToOctets(ip) : NetAddress.ipv6ToOctets(ip)) })
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
const issue = Effect.fn("Certificates.issue")(function* (options) {
|
|
39
|
+
const serial = yield* (yield* SecureRandom.SecureRandom).randomBytes(19);
|
|
40
|
+
const now = yield* DateTime.now;
|
|
41
|
+
const webcrypto = yield* WebCrypto.WebCrypto;
|
|
42
|
+
const engine = new pki.CryptoEngine({
|
|
43
|
+
name: "Node WebCrypto",
|
|
44
|
+
crypto: webcrypto
|
|
45
|
+
});
|
|
46
|
+
const failure = (cause) => CertificateError.make({
|
|
47
|
+
detail: `Could not issue the certificate for ${options.name}`,
|
|
48
|
+
cause
|
|
49
|
+
});
|
|
50
|
+
const keys = yield* Effect.tryPromise({
|
|
51
|
+
try: () => webcrypto.subtle.generateKey({
|
|
52
|
+
name: "ECDSA",
|
|
53
|
+
namedCurve: "P-256"
|
|
54
|
+
}, true, ["sign", "verify"]),
|
|
55
|
+
catch: failure
|
|
56
|
+
});
|
|
57
|
+
const authority = options.issuer === void 0 ? void 0 : {
|
|
58
|
+
certificate: yield* Effect.mapError(der(options.issuer.certificate), failure),
|
|
59
|
+
privateKey: yield* Effect.mapError(der(Redacted.value(options.issuer.privateKey)), failure)
|
|
60
|
+
};
|
|
61
|
+
const signingKey = authority === void 0 ? keys.privateKey : yield* Effect.tryPromise({
|
|
62
|
+
try: () => webcrypto.subtle.importKey("pkcs8", authority.privateKey, {
|
|
63
|
+
name: "ECDSA",
|
|
64
|
+
namedCurve: "P-256"
|
|
65
|
+
}, false, ["sign"]),
|
|
66
|
+
catch: failure
|
|
67
|
+
});
|
|
68
|
+
const certificate = yield* Effect.try({
|
|
69
|
+
try: () => {
|
|
70
|
+
const issuer = authority === void 0 ? void 0 : pki.Certificate.fromBER(authority.certificate);
|
|
71
|
+
const names = [...Array.map(options.hosts ?? [], hostName), ...Array.map(options.identities ?? [], (identity) => new pki.GeneralName({
|
|
72
|
+
type: 6,
|
|
73
|
+
value: `graft://${identity}`
|
|
74
|
+
}))];
|
|
75
|
+
return new pki.Certificate({
|
|
76
|
+
version: 2,
|
|
77
|
+
serialNumber: new asn1js.Integer({ valueHex: new Uint8Array([1, ...serial]) }),
|
|
78
|
+
subject: subject(options.name),
|
|
79
|
+
issuer: issuer?.subject ?? subject(options.name),
|
|
80
|
+
notBefore: new pki.Time({ value: DateTime.toDateUtc(now) }),
|
|
81
|
+
notAfter: new pki.Time({ value: DateTime.toDateUtc(DateTime.add(now, { days: options.days })) }),
|
|
82
|
+
extensions: [
|
|
83
|
+
new pki.Extension({
|
|
84
|
+
extnID: "2.5.29.19",
|
|
85
|
+
critical: true,
|
|
86
|
+
extnValue: new pki.BasicConstraints({ cA: options.usage === "ca" }).toSchema().toBER()
|
|
87
|
+
}),
|
|
88
|
+
new pki.Extension({
|
|
89
|
+
extnID: "2.5.29.15",
|
|
90
|
+
critical: true,
|
|
91
|
+
extnValue: new asn1js.BitString({ valueHex: new Uint8Array([options.usage === "ca" ? 6 : 128]) }).toBER()
|
|
92
|
+
}),
|
|
93
|
+
...options.usage === "ca" ? [] : [new pki.Extension({
|
|
94
|
+
extnID: "2.5.29.37",
|
|
95
|
+
extnValue: new pki.ExtKeyUsage({ keyPurposes: [options.usage === "server" ? "1.3.6.1.5.5.7.3.1" : "1.3.6.1.5.5.7.3.2"] }).toSchema().toBER()
|
|
96
|
+
})],
|
|
97
|
+
...names.length === 0 ? [] : [new pki.Extension({
|
|
98
|
+
extnID: "2.5.29.17",
|
|
99
|
+
extnValue: new pki.AltName({ altNames: names }).toSchema().toBER()
|
|
100
|
+
})]
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
catch: failure
|
|
105
|
+
});
|
|
106
|
+
yield* Effect.tryPromise({
|
|
107
|
+
try: () => certificate.subjectPublicKeyInfo.importKey(keys.publicKey, engine),
|
|
108
|
+
catch: failure
|
|
109
|
+
});
|
|
110
|
+
yield* Effect.tryPromise({
|
|
111
|
+
try: () => certificate.sign(signingKey, "SHA-256", engine),
|
|
112
|
+
catch: failure
|
|
113
|
+
});
|
|
114
|
+
const privateKey = yield* Effect.tryPromise({
|
|
115
|
+
try: () => webcrypto.subtle.exportKey("pkcs8", keys.privateKey),
|
|
116
|
+
catch: failure
|
|
117
|
+
});
|
|
118
|
+
return yield* Effect.try({
|
|
119
|
+
try: () => ({
|
|
120
|
+
certificate: pem("CERTIFICATE", certificate.toSchema().toBER()),
|
|
121
|
+
privateKey: Redacted.make(pem("PRIVATE KEY", privateKey))
|
|
122
|
+
}),
|
|
123
|
+
catch: failure
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
const read = Effect.fn("Certificates.read")(function* (base) {
|
|
127
|
+
const fs = yield* FileSystem.FileSystem;
|
|
128
|
+
const certificate = yield* fs.readFileString(base + ".crt");
|
|
129
|
+
const privateKey = yield* fs.readFileString(base + ".key");
|
|
130
|
+
return {
|
|
131
|
+
certificate,
|
|
132
|
+
privateKey: Redacted.make(privateKey)
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
const write = Effect.fn("Certificates.write")(function* (base, pair, force = false) {
|
|
136
|
+
const fs = yield* FileSystem.FileSystem;
|
|
137
|
+
yield* fs.writeFileString(base + ".key", Redacted.value(pair.privateKey), {
|
|
138
|
+
flag: force ? "w" : "wx",
|
|
139
|
+
mode: 384
|
|
140
|
+
}).pipe(Effect.uninterruptible);
|
|
141
|
+
yield* fs.chmod(base + ".key", 384).pipe(Effect.uninterruptible);
|
|
142
|
+
yield* fs.writeFileString(base + ".crt", pair.certificate, { flag: force ? "w" : "wx" }).pipe(Effect.uninterruptible);
|
|
143
|
+
});
|
|
144
|
+
/** URI-encode names so each identity has a distinct filename, including names with slashes. */
|
|
145
|
+
const clientName = (identity) => `client-${encodeURIComponent(identity)}`;
|
|
146
|
+
const generate = Effect.fn("Certificates.generate")(function* (options) {
|
|
147
|
+
const fs = yield* FileSystem.FileSystem;
|
|
148
|
+
const path = yield* Path.Path;
|
|
149
|
+
const outputs = [...options.server.length === 0 ? [] : ["server"], ...Array.map(Array.dedupe(options.identity), clientName)];
|
|
150
|
+
if (!options.force) {
|
|
151
|
+
const files = Array.flatMap(outputs, (name) => Array.map([".crt", ".key"], (extension) => path.join(options.out, name + extension)));
|
|
152
|
+
const taken = yield* Effect.filter(files, fs.exists);
|
|
153
|
+
if (Array.isReadonlyArrayNonEmpty(taken)) return yield* CertificateExists.make({ file: taken[0] });
|
|
154
|
+
}
|
|
155
|
+
yield* fs.makeDirectory(options.out, { recursive: true }).pipe(Effect.uninterruptible);
|
|
156
|
+
const ca = path.join(options.out, "ca");
|
|
157
|
+
const issuer = (yield* fs.exists(ca + ".crt")) || (yield* fs.exists(ca + ".key")) ? yield* read(ca) : yield* issue({
|
|
158
|
+
name: "Graft CA",
|
|
159
|
+
usage: "ca",
|
|
160
|
+
days: options.days
|
|
161
|
+
}).pipe(Effect.tap((pair) => write(ca, pair)));
|
|
162
|
+
if (options.server.length > 0) {
|
|
163
|
+
const pair = yield* issue({
|
|
164
|
+
name: "Graft runner",
|
|
165
|
+
usage: "server",
|
|
166
|
+
hosts: options.server,
|
|
167
|
+
days: options.days,
|
|
168
|
+
issuer
|
|
169
|
+
});
|
|
170
|
+
yield* write(path.join(options.out, "server"), pair, options.force);
|
|
171
|
+
}
|
|
172
|
+
yield* Effect.forEach(Array.dedupe(options.identity), (identity) => issue({
|
|
173
|
+
name: identity,
|
|
174
|
+
usage: "client",
|
|
175
|
+
identities: [identity],
|
|
176
|
+
days: options.days,
|
|
177
|
+
issuer
|
|
178
|
+
}).pipe(Effect.flatMap((pair) => write(path.join(options.out, clientName(identity)), pair, options.force))), { discard: true });
|
|
179
|
+
});
|
|
180
|
+
export { CertificateError, CertificateExists, clientName, generate, issue, read, write };
|
|
181
|
+
|
|
182
|
+
//# sourceMappingURL=Certificates.js.map
|