@smthrs/platform-node 0.0.0-stage → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +211 -0
- package/LICENSE +21 -0
- package/README.md +165 -2
- package/bin/darwin-arm64/smithers-jj-export +0 -0
- package/bin/darwin-x64/smithers-jj-export +0 -0
- package/bin/linux-arm64/smithers-jj-export +0 -0
- package/bin/linux-x64/smithers-jj-export +4 -0
- package/bin/win32-x64/smithers-jj-export.exe +0 -0
- package/dist/cjs/AtomicFileSystem.d.ts +147 -0
- package/dist/cjs/AtomicFileSystem.d.ts.map +1 -0
- package/dist/cjs/AtomicFileSystem.js +234 -0
- package/dist/cjs/AtomicFileSystem.js.map +7 -0
- package/dist/cjs/EgressHttpClient.d.ts +106 -0
- package/dist/cjs/EgressHttpClient.d.ts.map +1 -0
- package/dist/cjs/EgressHttpClient.js +202 -0
- package/dist/cjs/EgressHttpClient.js.map +7 -0
- package/dist/cjs/HostLiveness.d.ts +81 -0
- package/dist/cjs/HostLiveness.d.ts.map +1 -0
- package/dist/cjs/HostLiveness.js +49 -0
- package/dist/cjs/HostLiveness.js.map +7 -0
- package/dist/cjs/NodeHost.d.ts +145 -0
- package/dist/cjs/NodeHost.d.ts.map +1 -0
- package/dist/cjs/NodeHost.js +128 -0
- package/dist/cjs/NodeHost.js.map +7 -0
- package/dist/cjs/ProcessConfinement.d.ts +61 -0
- package/dist/cjs/ProcessConfinement.d.ts.map +1 -0
- package/dist/cjs/ProcessConfinement.js +292 -0
- package/dist/cjs/ProcessConfinement.js.map +7 -0
- package/dist/cjs/ProcessReaper.d.ts +457 -0
- package/dist/cjs/ProcessReaper.d.ts.map +1 -0
- package/dist/cjs/ProcessReaper.js +349 -0
- package/dist/cjs/ProcessReaper.js.map +7 -0
- package/dist/cjs/ProcessSandbox.d.ts +391 -0
- package/dist/cjs/ProcessSandbox.d.ts.map +1 -0
- package/dist/cjs/ProcessSandbox.js +774 -0
- package/dist/cjs/ProcessSandbox.js.map +7 -0
- package/dist/cjs/ScopedProcess.d.ts +66 -0
- package/dist/cjs/ScopedProcess.d.ts.map +1 -0
- package/dist/cjs/ScopedProcess.js +87 -0
- package/dist/cjs/ScopedProcess.js.map +7 -0
- package/dist/cjs/index.d.ts +38 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +47 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts +61 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.js +250 -0
- package/dist/cjs/internal/AtomicFileSystemExecutable.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts +78 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.js +382 -0
- package/dist/cjs/internal/AtomicFileSystemProtocol.js.map +7 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.d.ts +44 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.js +197 -0
- package/dist/cjs/internal/AtomicFileSystemTransport.js.map +7 -0
- package/dist/cjs/internal/AtomicHelperError.d.ts +35 -0
- package/dist/cjs/internal/AtomicHelperError.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicHelperError.js +45 -0
- package/dist/cjs/internal/AtomicHelperError.js.map +7 -0
- package/dist/cjs/internal/AtomicHelperFault.d.ts +59 -0
- package/dist/cjs/internal/AtomicHelperFault.d.ts.map +1 -0
- package/dist/cjs/internal/AtomicHelperFault.js +66 -0
- package/dist/cjs/internal/AtomicHelperFault.js.map +7 -0
- package/dist/cjs/internal/PipedProcess.d.ts +35 -0
- package/dist/cjs/internal/PipedProcess.d.ts.map +1 -0
- package/dist/cjs/internal/PipedProcess.js +309 -0
- package/dist/cjs/internal/PipedProcess.js.map +7 -0
- package/dist/cjs/internal/ProcSnapshot.d.ts +85 -0
- package/dist/cjs/internal/ProcSnapshot.d.ts.map +1 -0
- package/dist/cjs/internal/ProcSnapshot.js +123 -0
- package/dist/cjs/internal/ProcSnapshot.js.map +7 -0
- package/dist/cjs/internal/ProcessCleanup.d.ts +64 -0
- package/dist/cjs/internal/ProcessCleanup.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessCleanup.js +62 -0
- package/dist/cjs/internal/ProcessCleanup.js.map +7 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts +30 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.js +33 -0
- package/dist/cjs/internal/ProcessCleanupPolicyError.js.map +7 -0
- package/dist/cjs/internal/ProcessFault.d.ts +63 -0
- package/dist/cjs/internal/ProcessFault.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessFault.js +63 -0
- package/dist/cjs/internal/ProcessFault.js.map +7 -0
- package/dist/cjs/internal/ProcessSupervisor.d.ts +143 -0
- package/dist/cjs/internal/ProcessSupervisor.d.ts.map +1 -0
- package/dist/cjs/internal/ProcessSupervisor.js +685 -0
- package/dist/cjs/internal/ProcessSupervisor.js.map +7 -0
- package/dist/cjs/internal/SupervisorProgram.d.ts +9 -0
- package/dist/cjs/internal/SupervisorProgram.d.ts.map +1 -0
- package/dist/cjs/internal/SupervisorProgram.js +326 -0
- package/dist/cjs/internal/SupervisorProgram.js.map +7 -0
- package/dist/cjs/internal/WindowsProcessJob.d.ts +39 -0
- package/dist/cjs/internal/WindowsProcessJob.d.ts.map +1 -0
- package/dist/cjs/internal/WindowsProcessJob.js +113 -0
- package/dist/cjs/internal/WindowsProcessJob.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/AtomicFileSystem.d.ts +147 -0
- package/dist/esm/AtomicFileSystem.d.ts.map +1 -0
- package/dist/esm/AtomicFileSystem.js +290 -0
- package/dist/esm/AtomicFileSystem.js.map +1 -0
- package/dist/esm/EgressHttpClient.d.ts +106 -0
- package/dist/esm/EgressHttpClient.d.ts.map +1 -0
- package/dist/esm/EgressHttpClient.js +259 -0
- package/dist/esm/EgressHttpClient.js.map +1 -0
- package/dist/esm/HostLiveness.d.ts +81 -0
- package/dist/esm/HostLiveness.d.ts.map +1 -0
- package/dist/esm/HostLiveness.js +68 -0
- package/dist/esm/HostLiveness.js.map +1 -0
- package/dist/esm/NodeHost.d.ts +145 -0
- package/dist/esm/NodeHost.d.ts.map +1 -0
- package/dist/esm/NodeHost.js +162 -0
- package/dist/esm/NodeHost.js.map +1 -0
- package/dist/esm/ProcessConfinement.d.ts +61 -0
- package/dist/esm/ProcessConfinement.d.ts.map +1 -0
- package/dist/esm/ProcessConfinement.js +311 -0
- package/dist/esm/ProcessConfinement.js.map +1 -0
- package/dist/esm/ProcessReaper.d.ts +457 -0
- package/dist/esm/ProcessReaper.d.ts.map +1 -0
- package/dist/esm/ProcessReaper.js +711 -0
- package/dist/esm/ProcessReaper.js.map +1 -0
- package/dist/esm/ProcessSandbox.d.ts +391 -0
- package/dist/esm/ProcessSandbox.d.ts.map +1 -0
- package/dist/esm/ProcessSandbox.js +1043 -0
- package/dist/esm/ProcessSandbox.js.map +1 -0
- package/dist/esm/ScopedProcess.d.ts +66 -0
- package/dist/esm/ScopedProcess.d.ts.map +1 -0
- package/dist/esm/ScopedProcess.js +67 -0
- package/dist/esm/ScopedProcess.js.map +1 -0
- package/dist/esm/index.d.ts +38 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +38 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.d.ts +61 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.js +350 -0
- package/dist/esm/internal/AtomicFileSystemExecutable.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.d.ts +78 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.js +412 -0
- package/dist/esm/internal/AtomicFileSystemProtocol.js.map +1 -0
- package/dist/esm/internal/AtomicFileSystemTransport.d.ts +44 -0
- package/dist/esm/internal/AtomicFileSystemTransport.d.ts.map +1 -0
- package/dist/esm/internal/AtomicFileSystemTransport.js +242 -0
- package/dist/esm/internal/AtomicFileSystemTransport.js.map +1 -0
- package/dist/esm/internal/AtomicHelperError.d.ts +35 -0
- package/dist/esm/internal/AtomicHelperError.d.ts.map +1 -0
- package/dist/esm/internal/AtomicHelperError.js +39 -0
- package/dist/esm/internal/AtomicHelperError.js.map +1 -0
- package/dist/esm/internal/AtomicHelperFault.d.ts +59 -0
- package/dist/esm/internal/AtomicHelperFault.d.ts.map +1 -0
- package/dist/esm/internal/AtomicHelperFault.js +66 -0
- package/dist/esm/internal/AtomicHelperFault.js.map +1 -0
- package/dist/esm/internal/PipedProcess.d.ts +35 -0
- package/dist/esm/internal/PipedProcess.d.ts.map +1 -0
- package/dist/esm/internal/PipedProcess.js +321 -0
- package/dist/esm/internal/PipedProcess.js.map +1 -0
- package/dist/esm/internal/ProcSnapshot.d.ts +85 -0
- package/dist/esm/internal/ProcSnapshot.d.ts.map +1 -0
- package/dist/esm/internal/ProcSnapshot.js +188 -0
- package/dist/esm/internal/ProcSnapshot.js.map +1 -0
- package/dist/esm/internal/ProcessCleanup.d.ts +64 -0
- package/dist/esm/internal/ProcessCleanup.d.ts.map +1 -0
- package/dist/esm/internal/ProcessCleanup.js +45 -0
- package/dist/esm/internal/ProcessCleanup.js.map +1 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.d.ts +30 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.d.ts.map +1 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.js +25 -0
- package/dist/esm/internal/ProcessCleanupPolicyError.js.map +1 -0
- package/dist/esm/internal/ProcessFault.d.ts +63 -0
- package/dist/esm/internal/ProcessFault.d.ts.map +1 -0
- package/dist/esm/internal/ProcessFault.js +64 -0
- package/dist/esm/internal/ProcessFault.js.map +1 -0
- package/dist/esm/internal/ProcessSupervisor.d.ts +143 -0
- package/dist/esm/internal/ProcessSupervisor.d.ts.map +1 -0
- package/dist/esm/internal/ProcessSupervisor.js +689 -0
- package/dist/esm/internal/ProcessSupervisor.js.map +1 -0
- package/dist/esm/internal/SupervisorProgram.d.ts +9 -0
- package/dist/esm/internal/SupervisorProgram.d.ts.map +1 -0
- package/dist/esm/internal/SupervisorProgram.js +310 -0
- package/dist/esm/internal/SupervisorProgram.js.map +1 -0
- package/dist/esm/internal/WindowsProcessJob.d.ts +39 -0
- package/dist/esm/internal/WindowsProcessJob.d.ts.map +1 -0
- package/dist/esm/internal/WindowsProcessJob.js +115 -0
- package/dist/esm/internal/WindowsProcessJob.js.map +1 -0
- package/dist/vendor/adapters.json +1757 -0
- package/dist/vendor/chunk-2Y7WC4KU.js +109 -0
- package/dist/vendor/chunk-3GR5VZ2M.js +118 -0
- package/dist/vendor/chunk-42QKY6T6.js +40 -0
- package/dist/vendor/chunk-54RLBMTZ.js +61 -0
- package/dist/vendor/chunk-5ZMHBXIK.js +55 -0
- package/dist/vendor/chunk-6ME2W7TF.js +28 -0
- package/dist/vendor/chunk-AMQKOQNT.js +34 -0
- package/dist/vendor/chunk-B3FZ67QU.js +59 -0
- package/dist/vendor/chunk-BKTBUBQY.js +437 -0
- package/dist/vendor/chunk-DS7GF46S.js +34 -0
- package/dist/vendor/chunk-DVOAHXPG.js +104 -0
- package/dist/vendor/chunk-DWSHTSVX.js +229 -0
- package/dist/vendor/chunk-EGBNVEEW.js +14 -0
- package/dist/vendor/chunk-EZWY45HP.js +18 -0
- package/dist/vendor/chunk-FNZOJHSV.js +71 -0
- package/dist/vendor/chunk-GXCHI7BM.js +131 -0
- package/dist/vendor/chunk-IIJ52ZU6.js +20 -0
- package/dist/vendor/chunk-J7A4CZDO.js +92 -0
- package/dist/vendor/chunk-JG5TTWPT.js +85 -0
- package/dist/vendor/chunk-JJ24ARBQ.js +394 -0
- package/dist/vendor/chunk-KOZMM5PZ.js +426 -0
- package/dist/vendor/chunk-KUUXSID7.js +18 -0
- package/dist/vendor/chunk-LEUPYT3Q.js +36 -0
- package/dist/vendor/chunk-M32LDTW7.js +18 -0
- package/dist/vendor/chunk-M7CLUILA.js +0 -0
- package/dist/vendor/chunk-MBSKBQ5D.js +21 -0
- package/dist/vendor/chunk-MLKGABMK.js +9 -0
- package/dist/vendor/chunk-NBVRTDTV.js +129 -0
- package/dist/vendor/chunk-OXNGN5H7.js +81 -0
- package/dist/vendor/chunk-QPLDT6A6.js +564 -0
- package/dist/vendor/chunk-QYBKAIA6.js +18 -0
- package/dist/vendor/chunk-RO2R4MJH.js +62 -0
- package/dist/vendor/chunk-SIR62W3Y.js +398 -0
- package/dist/vendor/chunk-TFIKFFSC.js +26 -0
- package/dist/vendor/chunk-TXKLEBBL.js +143 -0
- package/dist/vendor/chunk-UFH5UUZK.js +48 -0
- package/dist/vendor/chunk-VANKHF46.js +96 -0
- package/dist/vendor/chunk-VZBDV3TV.js +18 -0
- package/dist/vendor/chunk-XDKNKFBW.js +22 -0
- package/dist/vendor/chunk-XH4U3JSV.js +249 -0
- package/dist/vendor/chunk-Y35ZAO5U.js +53 -0
- package/dist/vendor/chunk-ZJMRMY57.js +0 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
- package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node/NodePath.js +1 -0
- package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/cjs/node/NodeRedis.js +1 -0
- package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
- package/dist/vendor/cjs/node/NodeServices.js +1 -0
- package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSink.js +1 -0
- package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/cjs/node/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/cjs/node/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
- package/dist/vendor/cjs/node/NodeStream.js +1 -0
- package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/cjs/node/NodeWorker.js +1 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
- package/dist/vendor/cjs/node/Undici.d.ts +28 -0
- package/dist/vendor/cjs/node/Undici.js +1 -0
- package/dist/vendor/cjs/node/index.d.ts +100 -0
- package/dist/vendor/cjs/node/index.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
- package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
- package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
- package/dist/vendor/cjs/node-shared/index.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
- package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
- package/dist/vendor/cjs/package.json +1 -0
- package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
- package/dist/vendor/cjs/platform-node-shared.js +1 -0
- package/dist/vendor/cjs/platform-node.d.ts +100 -0
- package/dist/vendor/cjs/platform-node.js +1 -0
- package/dist/vendor/node/LICENSE +21 -0
- package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
- package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
- package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
- package/dist/vendor/node/NodeClusterHttp.js +43 -0
- package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
- package/dist/vendor/node/NodeClusterSocket.js +30 -0
- package/dist/vendor/node/NodeCrypto.d.ts +10 -0
- package/dist/vendor/node/NodeCrypto.js +8 -0
- package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
- package/dist/vendor/node/NodeFileSystem.js +9 -0
- package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
- package/dist/vendor/node/NodeHttpClient.js +46 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
- package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
- package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
- package/dist/vendor/node/NodeHttpPlatform.js +16 -0
- package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
- package/dist/vendor/node/NodeHttpServer.js +46 -0
- package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
- package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
- package/dist/vendor/node/NodeMultipart.d.ts +46 -0
- package/dist/vendor/node/NodeMultipart.js +15 -0
- package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
- package/dist/vendor/node/NodeMultipartParser.js +11 -0
- package/dist/vendor/node/NodePath.d.ts +27 -0
- package/dist/vendor/node/NodePath.js +12 -0
- package/dist/vendor/node/NodeRedis.d.ts +74 -0
- package/dist/vendor/node/NodeRedis.js +11 -0
- package/dist/vendor/node/NodeRuntime.d.ts +85 -0
- package/dist/vendor/node/NodeRuntime.js +8 -0
- package/dist/vendor/node/NodeServices.d.ts +34 -0
- package/dist/vendor/node/NodeServices.js +23 -0
- package/dist/vendor/node/NodeSink.d.ts +8 -0
- package/dist/vendor/node/NodeSink.js +12 -0
- package/dist/vendor/node/NodeSocket.d.ts +38 -0
- package/dist/vendor/node/NodeSocket.js +31 -0
- package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
- package/dist/vendor/node/NodeSocketServer.js +21 -0
- package/dist/vendor/node/NodeStdio.d.ts +11 -0
- package/dist/vendor/node/NodeStdio.js +10 -0
- package/dist/vendor/node/NodeStream.d.ts +8 -0
- package/dist/vendor/node/NodeStream.js +27 -0
- package/dist/vendor/node/NodeTerminal.d.ts +21 -0
- package/dist/vendor/node/NodeTerminal.js +10 -0
- package/dist/vendor/node/NodeWorker.d.ts +22 -0
- package/dist/vendor/node/NodeWorker.js +9 -0
- package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
- package/dist/vendor/node/NodeWorkerRunner.js +7 -0
- package/dist/vendor/node/Undici.d.ts +28 -0
- package/dist/vendor/node/Undici.js +9 -0
- package/dist/vendor/node/index.d.ts +100 -0
- package/dist/vendor/node/index.js +115 -0
- package/dist/vendor/node-shared/LICENSE +21 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
- package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
- package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
- package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
- package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
- package/dist/vendor/node-shared/NodeCrypto.js +9 -0
- package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
- package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
- package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
- package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
- package/dist/vendor/node-shared/NodePath.d.ts +27 -0
- package/dist/vendor/node-shared/NodePath.js +11 -0
- package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
- package/dist/vendor/node-shared/NodeRuntime.js +7 -0
- package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
- package/dist/vendor/node-shared/NodeSink.js +11 -0
- package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
- package/dist/vendor/node-shared/NodeSocket.js +23 -0
- package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
- package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
- package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
- package/dist/vendor/node-shared/NodeStdio.js +9 -0
- package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
- package/dist/vendor/node-shared/NodeStream.js +26 -0
- package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
- package/dist/vendor/node-shared/NodeTerminal.js +9 -0
- package/dist/vendor/node-shared/index.d.ts +56 -0
- package/dist/vendor/node-shared/index.js +58 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
- package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
- package/dist/vendor/node-shared/internal/utils.js +7 -0
- package/dist/vendor/platform-node-shared.d.ts +56 -0
- package/dist/vendor/platform-node-shared.js +58 -0
- package/dist/vendor/platform-node.d.ts +100 -0
- package/dist/vendor/platform-node.js +115 -0
- package/docs/README.md +129 -0
- package/docs/api.md +553 -0
- package/docs/concepts/descriptor-relative-filesystem.md +181 -0
- package/docs/concepts/host-bundle.md +125 -0
- package/docs/concepts/process-containment.md +190 -0
- package/docs/guides/answer-run-ownership.md +87 -0
- package/docs/guides/configure-the-filesystem-helper.md +152 -0
- package/docs/guides/contain-child-processes.md +139 -0
- package/docs/guides/match-files-with-glob.md +151 -0
- package/docs/installation.md +204 -0
- package/docs/quickstart.md +147 -0
- package/docs/troubleshooting.md +130 -0
- package/package.json +202 -3
- package/src/AtomicFileSystem.ts +415 -0
- package/src/EgressHttpClient.ts +327 -0
- package/src/HostLiveness.ts +103 -0
- package/src/NodeHost.ts +253 -0
- package/src/ProcessConfinement.ts +363 -0
- package/src/ProcessReaper.ts +951 -0
- package/src/ProcessSandbox.ts +1307 -0
- package/src/ScopedProcess.ts +124 -0
- package/src/index.ts +44 -0
- package/src/internal/AtomicFileSystemExecutable.ts +379 -0
- package/src/internal/AtomicFileSystemProtocol.ts +502 -0
- package/src/internal/AtomicFileSystemTransport.ts +272 -0
- package/src/internal/AtomicHelperError.ts +50 -0
- package/src/internal/AtomicHelperFault.ts +84 -0
- package/src/internal/PipedProcess.ts +357 -0
- package/src/internal/ProcSnapshot.ts +193 -0
- package/src/internal/ProcessCleanup.ts +99 -0
- package/src/internal/ProcessCleanupPolicyError.ts +30 -0
- package/src/internal/ProcessFault.ts +82 -0
- package/src/internal/ProcessSupervisor.ts +807 -0
- package/src/internal/SupervisorProgram.ts +309 -0
- package/src/internal/WindowsProcessJob.ts +114 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The adapter's half of the helper wire protocol: the request frame it sends,
|
|
3
|
+
* the response frame it accepts, and the typed value or `PlatformError` each
|
|
4
|
+
* operation's answer decodes to. Every check a helper answer has to pass lives
|
|
5
|
+
* here, so a malformed or hostile response fails closed in one place.
|
|
6
|
+
* @since 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
import { Effect, Option, PlatformError, Result } from "effect";
|
|
9
|
+
import * as ByteSize from "effect/ByteSize";
|
|
10
|
+
import { TextDecoder } from "node:util";
|
|
11
|
+
import { atomicHelperFault, AtomicHelperRejection } from "./AtomicHelperFault.js";
|
|
12
|
+
/**
|
|
13
|
+
* The `module` every `PlatformError` this adapter reports names.
|
|
14
|
+
* @private
|
|
15
|
+
* @since 1.0.0
|
|
16
|
+
*/
|
|
17
|
+
export const moduleName = "AtomicFileSystem";
|
|
18
|
+
const protocol = "flows-atomic/1";
|
|
19
|
+
/**
|
|
20
|
+
* Room for `flows-atomic/1 <digits>\n` above the payload ceiling.
|
|
21
|
+
* @private
|
|
22
|
+
* @since 1.0.0
|
|
23
|
+
*/
|
|
24
|
+
export const frameHeaderBytes = 64;
|
|
25
|
+
const decimal = /^[0-9]+$/;
|
|
26
|
+
const fatalUtf8 = new TextDecoder("utf-8", { fatal: true });
|
|
27
|
+
/**
|
|
28
|
+
* The errno-to-reason table `@effect/platform-node` applies to a Node
|
|
29
|
+
* `ErrnoException`, so a caller reads the same typed reason it would get from
|
|
30
|
+
* the native filesystem. `EPERM` and `ENOTSUP` are added because they are how
|
|
31
|
+
* this helper reports its own refusals — outside the pinned root, a hard link,
|
|
32
|
+
* a symlink, a special file, the root itself, or a host without
|
|
33
|
+
* descriptor-relative POSIX. `EFBIG` and `ENXIO` are how it reports a payload
|
|
34
|
+
* over the documented limit and a write-only open of a reader-less FIFO.
|
|
35
|
+
* `EPROTO` is a framing failure and stays fail-closed. `EOPNOTSUPP` is the
|
|
36
|
+
* same number as `ENOTSUP` on Linux, where which of the two names Python
|
|
37
|
+
* reports for it is an implementation detail.
|
|
38
|
+
*/
|
|
39
|
+
const reasons = {
|
|
40
|
+
EACCES: "PermissionDenied",
|
|
41
|
+
EBUSY: "Busy",
|
|
42
|
+
EEXIST: "AlreadyExists",
|
|
43
|
+
EFBIG: "BadResource",
|
|
44
|
+
EISDIR: "BadResource",
|
|
45
|
+
ELOOP: "BadResource",
|
|
46
|
+
ENOENT: "NotFound",
|
|
47
|
+
ENOTDIR: "BadResource",
|
|
48
|
+
ENOTSUP: "PermissionDenied",
|
|
49
|
+
ENXIO: "BadResource",
|
|
50
|
+
EOPNOTSUPP: "PermissionDenied",
|
|
51
|
+
EPERM: "PermissionDenied",
|
|
52
|
+
EPROTO: "PermissionDenied"
|
|
53
|
+
};
|
|
54
|
+
/** The operand a framed request names, for a failure's `pathOrDescriptor`. */
|
|
55
|
+
const operand = (request) => "path" in request ?
|
|
56
|
+
request.path :
|
|
57
|
+
request.operation === "rename" ?
|
|
58
|
+
request.from :
|
|
59
|
+
request.operation === "glob" ?
|
|
60
|
+
request.pattern :
|
|
61
|
+
undefined;
|
|
62
|
+
/**
|
|
63
|
+
* A rejection carrying no errno is a transport or host failure — an absent
|
|
64
|
+
* helper, a killed child, output that is not a helper result — and stays
|
|
65
|
+
* `PermissionDenied` so the boundary fails closed rather than reporting a
|
|
66
|
+
* benign-looking reason for an operation that never ran.
|
|
67
|
+
* @private
|
|
68
|
+
* @since 1.0.0
|
|
69
|
+
*/
|
|
70
|
+
export const failure = (request, cause, rejection) => {
|
|
71
|
+
const method = request.operation;
|
|
72
|
+
if (rejection?.badArgument === true) {
|
|
73
|
+
return PlatformError.badArgument({ module: moduleName, method, description: rejection.message, cause });
|
|
74
|
+
}
|
|
75
|
+
const code = rejection?.code ?? undefined;
|
|
76
|
+
return PlatformError.systemError({
|
|
77
|
+
module: moduleName,
|
|
78
|
+
method,
|
|
79
|
+
pathOrDescriptor: operand(request),
|
|
80
|
+
// `@effect/platform-node` sets `syscall` on every system error it reports,
|
|
81
|
+
// so a consumer that switches on it has to read a populated field here too.
|
|
82
|
+
// It names the operation's own syscall rather than whichever of the calls
|
|
83
|
+
// that operation makes actually raised, so it says what was attempted, not
|
|
84
|
+
// which step failed. A transport failure names no syscall at all, because
|
|
85
|
+
// no syscall ran.
|
|
86
|
+
syscall: rejection?.syscall ?? undefined,
|
|
87
|
+
_tag: code === undefined ? "PermissionDenied" : reasons[code] ?? "Unknown",
|
|
88
|
+
// The cause is repeated into the description because a fail-closed refusal
|
|
89
|
+
// that says only "failed closed" is unactionable: an absent helper, a
|
|
90
|
+
// response over the limit, and a mangled frame all look alike otherwise.
|
|
91
|
+
description: code === undefined
|
|
92
|
+
? `descriptor-relative filesystem isolation failed closed: ${String(cause)}`
|
|
93
|
+
: rejection?.message,
|
|
94
|
+
// Match the native Node adapter's errno contract. Artifact path checks
|
|
95
|
+
// distinguish a non-link (EINVAL) from a helper or transport failure.
|
|
96
|
+
cause: code === undefined ? cause : new AtomicHelperRejection({
|
|
97
|
+
code,
|
|
98
|
+
syscall: rejection?.syscall ?? undefined,
|
|
99
|
+
message: rejection?.message ?? "",
|
|
100
|
+
cause
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Frames a serialized request: the protocol tag, the body length, and the
|
|
106
|
+
* request, content, and response ceilings the helper enforces on its side,
|
|
107
|
+
* then the body.
|
|
108
|
+
* @private
|
|
109
|
+
* @since 1.0.0
|
|
110
|
+
*/
|
|
111
|
+
export const encode = (body, limits) => {
|
|
112
|
+
const header = Buffer.from(`${protocol} ${body.byteLength} ${limits.request} ${limits.content} ${limits.response}\n`, "ascii");
|
|
113
|
+
return Buffer.concat([header, body], header.byteLength + body.byteLength);
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Decodes one complete response frame into a result envelope. Anything that
|
|
117
|
+
* is not exactly one well-formed frame within the response ceiling throws.
|
|
118
|
+
* @private
|
|
119
|
+
* @since 1.0.0
|
|
120
|
+
*/
|
|
121
|
+
export const decode = (frame, limits) => {
|
|
122
|
+
const newline = frame.indexOf(10);
|
|
123
|
+
if (newline < 0 || newline >= frameHeaderBytes) {
|
|
124
|
+
throw atomicHelperFault("response_unframed", "atomic helper response is not framed");
|
|
125
|
+
}
|
|
126
|
+
const fields = frame.subarray(0, newline).toString("ascii").split(" ");
|
|
127
|
+
if (fields.length !== 2 || fields[0] !== protocol) {
|
|
128
|
+
throw atomicHelperFault("response_tag_unknown", "atomic helper response carries an unknown protocol tag");
|
|
129
|
+
}
|
|
130
|
+
const declared = fields[1];
|
|
131
|
+
if (!decimal.test(declared)) {
|
|
132
|
+
throw atomicHelperFault("response_length_invalid", `atomic helper declared a non-decimal response length: ${declared}`);
|
|
133
|
+
}
|
|
134
|
+
const length = Number(declared);
|
|
135
|
+
if (!Number.isSafeInteger(length) || length < 0 || length > limits.response) {
|
|
136
|
+
throw atomicHelperFault("response_length_invalid", `atomic helper declared an out-of-range response length: ${declared}`);
|
|
137
|
+
}
|
|
138
|
+
const body = frame.subarray(newline + 1);
|
|
139
|
+
if (body.byteLength !== length) {
|
|
140
|
+
// Fewer bytes is a truncated response (a killed helper); more is a second
|
|
141
|
+
// frame appended to the first. Either way the stream is not one answer.
|
|
142
|
+
throw atomicHelperFault("response_length_mismatch", `atomic helper declared ${length} response bytes and wrote ${body.byteLength}`);
|
|
143
|
+
}
|
|
144
|
+
// Decoded from the complete frame, so a multi-byte character split across
|
|
145
|
+
// two stdout chunks is never mangled on the way in.
|
|
146
|
+
return resultEnvelope(JSON.parse(fatalUtf8.decode(body)));
|
|
147
|
+
};
|
|
148
|
+
const resultEnvelope = (input) => {
|
|
149
|
+
const value = input;
|
|
150
|
+
if (value === null || typeof value !== "object" || typeof value.ok !== "boolean") {
|
|
151
|
+
throw atomicHelperFault("envelope_malformed", "atomic helper response is not a result envelope");
|
|
152
|
+
}
|
|
153
|
+
if (value.code !== undefined && value.code !== null && typeof value.code !== "string") {
|
|
154
|
+
throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string error code");
|
|
155
|
+
}
|
|
156
|
+
if (value.syscall !== undefined && value.syscall !== null && typeof value.syscall !== "string") {
|
|
157
|
+
throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string syscall");
|
|
158
|
+
}
|
|
159
|
+
if (value.badArgument !== undefined && typeof value.badArgument !== "boolean") {
|
|
160
|
+
throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-boolean badArgument flag");
|
|
161
|
+
}
|
|
162
|
+
if (value.message !== undefined && typeof value.message !== "string") {
|
|
163
|
+
throw atomicHelperFault("envelope_malformed", "atomic helper response carries a non-string message");
|
|
164
|
+
}
|
|
165
|
+
return value;
|
|
166
|
+
};
|
|
167
|
+
const record = (value, what) => {
|
|
168
|
+
if (value === null || typeof value !== "object") {
|
|
169
|
+
throw atomicHelperFault("field_malformed", `atomic helper returned a non-object ${what}`);
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
};
|
|
173
|
+
const finite = (value, field) => {
|
|
174
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
175
|
+
throw atomicHelperFault("field_malformed", `atomic helper returned a non-numeric ${field}`);
|
|
176
|
+
}
|
|
177
|
+
return value;
|
|
178
|
+
};
|
|
179
|
+
const integer = (value, field) => {
|
|
180
|
+
const numeric = finite(value, field);
|
|
181
|
+
if (!Number.isSafeInteger(numeric) || numeric < 0) {
|
|
182
|
+
throw atomicHelperFault("field_malformed", `atomic helper returned an out-of-range ${field}: ${numeric}`);
|
|
183
|
+
}
|
|
184
|
+
return numeric;
|
|
185
|
+
};
|
|
186
|
+
const date = (value, field) => {
|
|
187
|
+
const result = new Date(finite(value, field));
|
|
188
|
+
if (!Number.isFinite(result.getTime())) {
|
|
189
|
+
throw atomicHelperFault("field_malformed", `atomic helper returned an out-of-range ${field}`);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
const size = (value, field) => {
|
|
194
|
+
if (typeof value === "string" && decimal.test(value)) {
|
|
195
|
+
return ByteSize.bytes(BigInt(value));
|
|
196
|
+
}
|
|
197
|
+
return ByteSize.bytes(BigInt(integer(value, field)));
|
|
198
|
+
};
|
|
199
|
+
const optional = (value, read) => value === null || value === undefined ? Option.none() : Option.some(read(value));
|
|
200
|
+
/** Effect's own `FileSystem.File.Type`; anything else is a helper defect. */
|
|
201
|
+
const fileTypes = new Set([
|
|
202
|
+
"File",
|
|
203
|
+
"Directory",
|
|
204
|
+
"SymbolicLink",
|
|
205
|
+
"BlockDevice",
|
|
206
|
+
"CharacterDevice",
|
|
207
|
+
"FIFO",
|
|
208
|
+
"Socket",
|
|
209
|
+
"Unknown"
|
|
210
|
+
]);
|
|
211
|
+
const toInfo = (value) => {
|
|
212
|
+
const info = record(value, "stat");
|
|
213
|
+
if (!fileTypes.has(info.type)) {
|
|
214
|
+
throw atomicHelperFault("file_type_unknown", `atomic helper returned an unknown file type: ${String(info.type)}`);
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
type: info.type,
|
|
218
|
+
mtime: Option.some(date(info.mtime, "mtime")),
|
|
219
|
+
atime: Option.some(date(info.atime, "atime")),
|
|
220
|
+
birthtime: optional(info.birthtime, (raw) => date(raw, "birthtime")),
|
|
221
|
+
dev: integer(info.dev, "dev"),
|
|
222
|
+
ino: optional(info.ino, (raw) => integer(raw, "ino")),
|
|
223
|
+
mode: integer(info.mode, "mode"),
|
|
224
|
+
nlink: Option.some(integer(info.nlink, "nlink")),
|
|
225
|
+
uid: Option.some(integer(info.uid, "uid")),
|
|
226
|
+
gid: Option.some(integer(info.gid, "gid")),
|
|
227
|
+
rdev: Option.some(integer(info.rdev, "rdev")),
|
|
228
|
+
size: size(info.size, "size"),
|
|
229
|
+
blksize: optional(info.blksize, (raw) => size(raw, "blksize")),
|
|
230
|
+
blocks: optional(info.blocks, (raw) => integer(raw, "blocks"))
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
const isBase64 = (encoded) => {
|
|
234
|
+
if (encoded.length % 4 !== 0)
|
|
235
|
+
return false;
|
|
236
|
+
let end = encoded.length;
|
|
237
|
+
if (encoded.endsWith("=")) {
|
|
238
|
+
end--;
|
|
239
|
+
if (encoded[end - 1] === "=")
|
|
240
|
+
end--;
|
|
241
|
+
}
|
|
242
|
+
// A repeated-group regexp exhausts V8's stack on ordinary multi-MiB reads.
|
|
243
|
+
// Scan the alphabet once, excluding at most two trailing padding characters.
|
|
244
|
+
for (let index = 0; index < end; index++) {
|
|
245
|
+
const code = encoded.charCodeAt(index);
|
|
246
|
+
if (!(code >= 65 && code <= 90) && !(code >= 97 && code <= 122) &&
|
|
247
|
+
!(code >= 48 && code <= 57) && code !== 43 && code !== 47)
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
};
|
|
252
|
+
const toBytes = (value, limit) => {
|
|
253
|
+
const payload = record(value, "read result");
|
|
254
|
+
const encoded = payload.base64;
|
|
255
|
+
// Buffer.from silently drops characters it does not recognise, so the shape
|
|
256
|
+
// is checked before the decode rather than inferred from its output.
|
|
257
|
+
if (typeof encoded !== "string" || !isBase64(encoded)) {
|
|
258
|
+
throw atomicHelperFault("payload_malformed", "atomic helper returned a malformed base64 payload");
|
|
259
|
+
}
|
|
260
|
+
const bytes = Buffer.from(encoded, "base64");
|
|
261
|
+
if (bytes.byteLength > limit) {
|
|
262
|
+
throw atomicHelperFault("read_limit_exceeded", `atomic helper returned ${bytes.byteLength} bytes, over the ${limit} byte read limit`);
|
|
263
|
+
}
|
|
264
|
+
return Uint8Array.from(bytes);
|
|
265
|
+
};
|
|
266
|
+
const toStringResult = (value, what) => {
|
|
267
|
+
if (typeof value !== "string" || value.includes("\0")) {
|
|
268
|
+
throw atomicHelperFault("entries_malformed", `atomic helper returned an invalid ${what}`);
|
|
269
|
+
}
|
|
270
|
+
return value;
|
|
271
|
+
};
|
|
272
|
+
const maxListingEntries = 100_000;
|
|
273
|
+
const toStringArray = (value, what) => {
|
|
274
|
+
if (!Array.isArray(value) || value.length > maxListingEntries) {
|
|
275
|
+
throw atomicHelperFault("entries_malformed", `atomic helper returned an invalid ${what}`);
|
|
276
|
+
}
|
|
277
|
+
const result = value.map((entry) => toStringResult(entry, `${what} entry`));
|
|
278
|
+
if (new Set(result).size !== result.length) {
|
|
279
|
+
throw atomicHelperFault("entries_malformed", `atomic helper returned duplicate ${what} entries`);
|
|
280
|
+
}
|
|
281
|
+
return result;
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Converts a successful helper value into the result the request's operation
|
|
285
|
+
* promises, and throws when the value does not have that shape.
|
|
286
|
+
* @private
|
|
287
|
+
* @since 1.0.0
|
|
288
|
+
*/
|
|
289
|
+
export const convert = (request, value, limits) => {
|
|
290
|
+
if (request.operation === "batch") {
|
|
291
|
+
const response = record(value, "batch");
|
|
292
|
+
const requests = request.requests;
|
|
293
|
+
if (response.rootIdentity !== request.rootIdentity || !Array.isArray(response.entries) ||
|
|
294
|
+
response.entries.length !== requests.length) {
|
|
295
|
+
throw atomicHelperFault("batch_malformed", "atomic helper returned a foreign or incomplete batch");
|
|
296
|
+
}
|
|
297
|
+
const seen = new Set();
|
|
298
|
+
let previous = "";
|
|
299
|
+
let previousIndex = -1;
|
|
300
|
+
const pending = response.entries.map((raw) => {
|
|
301
|
+
const entry = record(raw, "batch entry");
|
|
302
|
+
const index = integer(entry.index, "batch index");
|
|
303
|
+
const member = requests[index];
|
|
304
|
+
if (member === undefined || seen.has(index) || entry.path !== member.path ||
|
|
305
|
+
member.path < previous || (member.path === previous && index <= previousIndex)) {
|
|
306
|
+
throw atomicHelperFault("batch_malformed", "atomic helper returned an invalid batch member identity or order");
|
|
307
|
+
}
|
|
308
|
+
seen.add(index);
|
|
309
|
+
previous = member.path;
|
|
310
|
+
previousIndex = index;
|
|
311
|
+
if (Buffer.byteLength(JSON.stringify(entry.result), "utf8") > limits.batchEntry) {
|
|
312
|
+
throw atomicHelperFault("batch_malformed", "atomic helper returned an oversized batch entry");
|
|
313
|
+
}
|
|
314
|
+
const envelope = resultEnvelope(entry.result);
|
|
315
|
+
const identity = { index, path: member.path };
|
|
316
|
+
if (!envelope.ok) {
|
|
317
|
+
return Effect.succeed({
|
|
318
|
+
...identity,
|
|
319
|
+
result: Result.fail(failure(member, atomicHelperFault("helper_rejected", envelope.message ?? "atomic batch member failed"), envelope))
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (member.operation === "digest") {
|
|
323
|
+
const measured = record(envelope.value, "digest");
|
|
324
|
+
if (typeof measured.digest !== "string" || !/^[a-f0-9]{64}$/.test(measured.digest)) {
|
|
325
|
+
throw atomicHelperFault("digest_malformed", "atomic helper returned an invalid SHA-256 digest");
|
|
326
|
+
}
|
|
327
|
+
const sizeBytes = integer(measured.sizeBytes, "digest size");
|
|
328
|
+
if (sizeBytes > limits.content) {
|
|
329
|
+
throw atomicHelperFault("digest_malformed", "atomic helper returned an oversized digest measurement");
|
|
330
|
+
}
|
|
331
|
+
const bytes = member.content === true ? toBytes(measured, limits.content) : undefined;
|
|
332
|
+
if (bytes !== undefined && bytes.length !== sizeBytes) {
|
|
333
|
+
throw atomicHelperFault("digest_malformed", "atomic helper returned a mismatched digest size");
|
|
334
|
+
}
|
|
335
|
+
return Effect.succeed({
|
|
336
|
+
...identity,
|
|
337
|
+
result: Result.succeed({
|
|
338
|
+
operation: "digest",
|
|
339
|
+
digest: measured.digest,
|
|
340
|
+
sizeBytes,
|
|
341
|
+
...(bytes === undefined ? {} : { bytes })
|
|
342
|
+
})
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
return Effect.map(convert(member, envelope.value, limits), (converted) => ({
|
|
346
|
+
...identity,
|
|
347
|
+
result: Result.succeed(member.operation === "stat"
|
|
348
|
+
? { operation: "stat", info: converted }
|
|
349
|
+
: member.operation === "resolve"
|
|
350
|
+
? { operation: "resolve", resolution: converted }
|
|
351
|
+
: { operation: member.operation, paths: converted.sort() })
|
|
352
|
+
}));
|
|
353
|
+
});
|
|
354
|
+
return Effect.map(Effect.all(pending), (entries) => ({ rootIdentity: response.rootIdentity, entries }));
|
|
355
|
+
}
|
|
356
|
+
if (request.operation === "readFile" || request.operation === "readFileString") {
|
|
357
|
+
// An empty file encodes to an empty string, so the payload is read by
|
|
358
|
+
// shape: truthiness would return the raw envelope for it instead.
|
|
359
|
+
const bytes = toBytes(value, limits.content);
|
|
360
|
+
if (request.operation === "readFile") {
|
|
361
|
+
return Effect.succeed(bytes);
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
return Effect.succeed(new TextDecoder(request.encoding).decode(bytes));
|
|
365
|
+
}
|
|
366
|
+
catch (cause) {
|
|
367
|
+
// Effect's own `readFileString` reports a rejected encoding as a
|
|
368
|
+
// BadArgument, not as a filesystem failure.
|
|
369
|
+
return Effect.fail(PlatformError.badArgument({
|
|
370
|
+
module: "FileSystem",
|
|
371
|
+
method: "readFileString",
|
|
372
|
+
description: "invalid encoding",
|
|
373
|
+
cause
|
|
374
|
+
}));
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (request.operation === "stat") {
|
|
378
|
+
return Effect.succeed(toInfo(value));
|
|
379
|
+
}
|
|
380
|
+
if (request.operation === "exists") {
|
|
381
|
+
if (typeof value !== "boolean") {
|
|
382
|
+
throw atomicHelperFault("result_malformed", "atomic helper returned a non-boolean exists result");
|
|
383
|
+
}
|
|
384
|
+
return Effect.succeed(value);
|
|
385
|
+
}
|
|
386
|
+
if (request.operation === "readLink" || request.operation === "realPath") {
|
|
387
|
+
return Effect.succeed(toStringResult(value, `${request.operation} result`));
|
|
388
|
+
}
|
|
389
|
+
if (request.operation === "resolve") {
|
|
390
|
+
const resolution = record(value, "resolve result");
|
|
391
|
+
const target = resolution.target === null ? null : toStringResult(resolution.target, "resolve target");
|
|
392
|
+
const answer = { path: toStringResult(resolution.path, "resolve path"), target };
|
|
393
|
+
return Effect.succeed(answer);
|
|
394
|
+
}
|
|
395
|
+
if (request.operation === "readDirectory" || request.operation === "glob") {
|
|
396
|
+
return Effect.succeed(toStringArray(value, `${request.operation} result`));
|
|
397
|
+
}
|
|
398
|
+
if (request.operation === "writeFile" ||
|
|
399
|
+
request.operation === "writeFileString" ||
|
|
400
|
+
request.operation === "chmod" ||
|
|
401
|
+
request.operation === "chown" ||
|
|
402
|
+
request.operation === "makeDirectory" ||
|
|
403
|
+
request.operation === "remove" ||
|
|
404
|
+
request.operation === "rename") {
|
|
405
|
+
if (value !== null) {
|
|
406
|
+
throw atomicHelperFault("result_malformed", `atomic helper returned a non-null ${request.operation} result`);
|
|
407
|
+
}
|
|
408
|
+
return Effect.succeed(undefined);
|
|
409
|
+
}
|
|
410
|
+
throw atomicHelperFault("operation_unsupported", `atomic helper returned success for unsupported operation ${request.operation}`);
|
|
411
|
+
};
|
|
412
|
+
//# sourceMappingURL=AtomicFileSystemProtocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AtomicFileSystemProtocol.js","sourceRoot":"","sources":["../../../src/internal/AtomicFileSystemProtocol.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The adapter's half of the helper wire protocol: the request frame it sends,\n * the response frame it accepts, and the typed value or `PlatformError` each\n * operation's answer decodes to. Every check a helper answer has to pass lives\n * here, so a malformed or hostile response fails closed in one place.\n * @since 1.0.0\n */\n\nimport type * as KernelFileSystem from \"@smthrs/kernel/FileSystem\"\nimport { Effect, type FileSystem, Option, PlatformError, Result } from \"effect\"\nimport * as ByteSize from \"effect/ByteSize\"\nimport { TextDecoder } from \"node:util\"\nimport type { Limits } from \"../AtomicFileSystem.ts\"\nimport { atomicHelperFault, AtomicHelperRejection } from \"./AtomicHelperFault.ts\"\n\n/**\n * One helper answer: a value, or a rejection carrying the errno name and the\n * syscall the helper observed.\n * @private\n * @since 1.0.0\n */\nexport interface HelperResult {\n readonly ok: boolean\n readonly value?: unknown\n readonly code?: string | null\n readonly syscall?: string | null\n readonly badArgument?: boolean\n readonly message?: string\n}\n\n/**\n * The `module` every `PlatformError` this adapter reports names.\n * @private\n * @since 1.0.0\n */\nexport const moduleName = \"AtomicFileSystem\"\n\nconst protocol = \"flows-atomic/1\"\n/**\n * Room for `flows-atomic/1 <digits>\\n` above the payload ceiling.\n * @private\n * @since 1.0.0\n */\nexport const frameHeaderBytes = 64\nconst decimal = /^[0-9]+$/\nconst fatalUtf8 = new TextDecoder(\"utf-8\", { fatal: true })\n\n/**\n * The errno-to-reason table `@effect/platform-node` applies to a Node\n * `ErrnoException`, so a caller reads the same typed reason it would get from\n * the native filesystem. `EPERM` and `ENOTSUP` are added because they are how\n * this helper reports its own refusals — outside the pinned root, a hard link,\n * a symlink, a special file, the root itself, or a host without\n * descriptor-relative POSIX. `EFBIG` and `ENXIO` are how it reports a payload\n * over the documented limit and a write-only open of a reader-less FIFO.\n * `EPROTO` is a framing failure and stays fail-closed. `EOPNOTSUPP` is the\n * same number as `ENOTSUP` on Linux, where which of the two names Python\n * reports for it is an implementation detail.\n */\nconst reasons: Record<string, PlatformError.SystemErrorTag | undefined> = {\n EACCES: \"PermissionDenied\",\n EBUSY: \"Busy\",\n EEXIST: \"AlreadyExists\",\n EFBIG: \"BadResource\",\n EISDIR: \"BadResource\",\n ELOOP: \"BadResource\",\n ENOENT: \"NotFound\",\n ENOTDIR: \"BadResource\",\n ENOTSUP: \"PermissionDenied\",\n ENXIO: \"BadResource\",\n EOPNOTSUPP: \"PermissionDenied\",\n EPERM: \"PermissionDenied\",\n EPROTO: \"PermissionDenied\"\n}\n\n/**\n * A request framed for the helper: one atomic operation, or one member of a\n * batch. The two protocols name their operands differently — a batch `glob`\n * carries the `path` it expands where an atomic `glob` carries a `pattern` —\n * so the reporting helpers read the operand by narrowing on the operation\n * rather than by taking whichever of three optional fields happened to be set.\n * @private\n * @since 1.0.0\n */\nexport type FramedRequest = KernelFileSystem.AtomicRequest | KernelFileSystem.AtomicBatchRequest\n\n/** The operand a framed request names, for a failure's `pathOrDescriptor`. */\nconst operand = (request: FramedRequest): string | undefined =>\n \"path\" in request ?\n request.path :\n request.operation === \"rename\" ?\n request.from :\n request.operation === \"glob\" ?\n request.pattern :\n undefined\n\n/**\n * A rejection carrying no errno is a transport or host failure — an absent\n * helper, a killed child, output that is not a helper result — and stays\n * `PermissionDenied` so the boundary fails closed rather than reporting a\n * benign-looking reason for an operation that never ran.\n * @private\n * @since 1.0.0\n */\nexport const failure = (\n request: FramedRequest,\n cause: unknown,\n rejection?: HelperResult\n): PlatformError.PlatformError => {\n const method = request.operation\n if (rejection?.badArgument === true) {\n return PlatformError.badArgument({ module: moduleName, method, description: rejection.message, cause })\n }\n const code = rejection?.code ?? undefined\n return PlatformError.systemError({\n module: moduleName,\n method,\n pathOrDescriptor: operand(request),\n // `@effect/platform-node` sets `syscall` on every system error it reports,\n // so a consumer that switches on it has to read a populated field here too.\n // It names the operation's own syscall rather than whichever of the calls\n // that operation makes actually raised, so it says what was attempted, not\n // which step failed. A transport failure names no syscall at all, because\n // no syscall ran.\n syscall: rejection?.syscall ?? undefined,\n _tag: code === undefined ? \"PermissionDenied\" : reasons[code] ?? \"Unknown\",\n // The cause is repeated into the description because a fail-closed refusal\n // that says only \"failed closed\" is unactionable: an absent helper, a\n // response over the limit, and a mangled frame all look alike otherwise.\n description: code === undefined\n ? `descriptor-relative filesystem isolation failed closed: ${String(cause)}`\n : rejection?.message,\n // Match the native Node adapter's errno contract. Artifact path checks\n // distinguish a non-link (EINVAL) from a helper or transport failure.\n cause: code === undefined ? cause : new AtomicHelperRejection({\n code,\n syscall: rejection?.syscall ?? undefined,\n message: rejection?.message ?? \"\",\n cause\n })\n })\n}\n\n/**\n * Frames a serialized request: the protocol tag, the body length, and the\n * request, content, and response ceilings the helper enforces on its side,\n * then the body.\n * @private\n * @since 1.0.0\n */\nexport const encode = (body: Buffer, limits: Limits): Buffer => {\n const header = Buffer.from(\n `${protocol} ${body.byteLength} ${limits.request} ${limits.content} ${limits.response}\\n`,\n \"ascii\"\n )\n return Buffer.concat([header, body], header.byteLength + body.byteLength)\n}\n\n/**\n * Decodes one complete response frame into a result envelope. Anything that\n * is not exactly one well-formed frame within the response ceiling throws.\n * @private\n * @since 1.0.0\n */\nexport const decode = (frame: Buffer, limits: Limits): HelperResult => {\n const newline = frame.indexOf(10)\n if (newline < 0 || newline >= frameHeaderBytes) {\n throw atomicHelperFault(\"response_unframed\", \"atomic helper response is not framed\")\n }\n const fields = frame.subarray(0, newline).toString(\"ascii\").split(\" \")\n if (fields.length !== 2 || fields[0] !== protocol) {\n throw atomicHelperFault(\"response_tag_unknown\", \"atomic helper response carries an unknown protocol tag\")\n }\n const declared = fields[1]!\n if (!decimal.test(declared)) {\n throw atomicHelperFault(\n \"response_length_invalid\",\n `atomic helper declared a non-decimal response length: ${declared}`\n )\n }\n const length = Number(declared)\n if (!Number.isSafeInteger(length) || length < 0 || length > limits.response) {\n throw atomicHelperFault(\n \"response_length_invalid\",\n `atomic helper declared an out-of-range response length: ${declared}`\n )\n }\n const body = frame.subarray(newline + 1)\n if (body.byteLength !== length) {\n // Fewer bytes is a truncated response (a killed helper); more is a second\n // frame appended to the first. Either way the stream is not one answer.\n throw atomicHelperFault(\n \"response_length_mismatch\",\n `atomic helper declared ${length} response bytes and wrote ${body.byteLength}`\n )\n }\n // Decoded from the complete frame, so a multi-byte character split across\n // two stdout chunks is never mangled on the way in.\n return resultEnvelope(JSON.parse(fatalUtf8.decode(body)))\n}\n\nconst resultEnvelope = (input: unknown): HelperResult => {\n const value = input as HelperResult\n if (value === null || typeof value !== \"object\" || typeof value.ok !== \"boolean\") {\n throw atomicHelperFault(\"envelope_malformed\", \"atomic helper response is not a result envelope\")\n }\n if (value.code !== undefined && value.code !== null && typeof value.code !== \"string\") {\n throw atomicHelperFault(\"envelope_malformed\", \"atomic helper response carries a non-string error code\")\n }\n if (value.syscall !== undefined && value.syscall !== null && typeof value.syscall !== \"string\") {\n throw atomicHelperFault(\"envelope_malformed\", \"atomic helper response carries a non-string syscall\")\n }\n if (value.badArgument !== undefined && typeof value.badArgument !== \"boolean\") {\n throw atomicHelperFault(\"envelope_malformed\", \"atomic helper response carries a non-boolean badArgument flag\")\n }\n if (value.message !== undefined && typeof value.message !== \"string\") {\n throw atomicHelperFault(\"envelope_malformed\", \"atomic helper response carries a non-string message\")\n }\n return value\n}\n\nconst record = (value: unknown, what: string): Record<string, unknown> => {\n if (value === null || typeof value !== \"object\") {\n throw atomicHelperFault(\"field_malformed\", `atomic helper returned a non-object ${what}`)\n }\n return value as Record<string, unknown>\n}\n\nconst finite = (value: unknown, field: string): number => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw atomicHelperFault(\"field_malformed\", `atomic helper returned a non-numeric ${field}`)\n }\n return value\n}\n\nconst integer = (value: unknown, field: string): number => {\n const numeric = finite(value, field)\n if (!Number.isSafeInteger(numeric) || numeric < 0) {\n throw atomicHelperFault(\"field_malformed\", `atomic helper returned an out-of-range ${field}: ${numeric}`)\n }\n return numeric\n}\n\nconst date = (value: unknown, field: string): Date => {\n const result = new Date(finite(value, field))\n if (!Number.isFinite(result.getTime())) {\n throw atomicHelperFault(\"field_malformed\", `atomic helper returned an out-of-range ${field}`)\n }\n return result\n}\n\nconst size = (value: unknown, field: string): ByteSize.ByteSize => {\n if (typeof value === \"string\" && decimal.test(value)) {\n return ByteSize.bytes(BigInt(value))\n }\n return ByteSize.bytes(BigInt(integer(value, field)))\n}\n\nconst optional = <A>(value: unknown, read: (value: unknown) => A): Option.Option<A> =>\n value === null || value === undefined ? Option.none() : Option.some(read(value))\n\n/** Effect's own `FileSystem.File.Type`; anything else is a helper defect. */\nconst fileTypes = new Set<string>([\n \"File\",\n \"Directory\",\n \"SymbolicLink\",\n \"BlockDevice\",\n \"CharacterDevice\",\n \"FIFO\",\n \"Socket\",\n \"Unknown\"\n])\n\nconst toInfo = (value: unknown): FileSystem.File.Info => {\n const info = record(value, \"stat\")\n if (!fileTypes.has(info.type as string)) {\n throw atomicHelperFault(\"file_type_unknown\", `atomic helper returned an unknown file type: ${String(info.type)}`)\n }\n return {\n type: info.type as FileSystem.File.Type,\n mtime: Option.some(date(info.mtime, \"mtime\")),\n atime: Option.some(date(info.atime, \"atime\")),\n birthtime: optional(info.birthtime, (raw) => date(raw, \"birthtime\")),\n dev: integer(info.dev, \"dev\"),\n ino: optional(info.ino, (raw) => integer(raw, \"ino\")),\n mode: integer(info.mode, \"mode\"),\n nlink: Option.some(integer(info.nlink, \"nlink\")),\n uid: Option.some(integer(info.uid, \"uid\")),\n gid: Option.some(integer(info.gid, \"gid\")),\n rdev: Option.some(integer(info.rdev, \"rdev\")),\n size: size(info.size, \"size\"),\n blksize: optional(info.blksize, (raw) => size(raw, \"blksize\")),\n blocks: optional(info.blocks, (raw) => integer(raw, \"blocks\"))\n }\n}\n\nconst isBase64 = (encoded: string): boolean => {\n if (encoded.length % 4 !== 0) return false\n let end = encoded.length\n if (encoded.endsWith(\"=\")) {\n end--\n if (encoded[end - 1] === \"=\") end--\n }\n // A repeated-group regexp exhausts V8's stack on ordinary multi-MiB reads.\n // Scan the alphabet once, excluding at most two trailing padding characters.\n for (let index = 0; index < end; index++) {\n const code = encoded.charCodeAt(index)\n if (\n !(code >= 65 && code <= 90) && !(code >= 97 && code <= 122) &&\n !(code >= 48 && code <= 57) && code !== 43 && code !== 47\n ) return false\n }\n return true\n}\n\nconst toBytes = (value: unknown, limit: number): Uint8Array => {\n const payload = record(value, \"read result\")\n const encoded = payload.base64\n // Buffer.from silently drops characters it does not recognise, so the shape\n // is checked before the decode rather than inferred from its output.\n if (typeof encoded !== \"string\" || !isBase64(encoded)) {\n throw atomicHelperFault(\"payload_malformed\", \"atomic helper returned a malformed base64 payload\")\n }\n const bytes = Buffer.from(encoded, \"base64\")\n if (bytes.byteLength > limit) {\n throw atomicHelperFault(\n \"read_limit_exceeded\",\n `atomic helper returned ${bytes.byteLength} bytes, over the ${limit} byte read limit`\n )\n }\n return Uint8Array.from(bytes)\n}\n\nconst toStringResult = (value: unknown, what: string): string => {\n if (typeof value !== \"string\" || value.includes(\"\\0\")) {\n throw atomicHelperFault(\"entries_malformed\", `atomic helper returned an invalid ${what}`)\n }\n return value\n}\n\nconst maxListingEntries = 100_000\n\nconst toStringArray = (value: unknown, what: string): Array<string> => {\n if (!Array.isArray(value) || value.length > maxListingEntries) {\n throw atomicHelperFault(\"entries_malformed\", `atomic helper returned an invalid ${what}`)\n }\n const result = value.map((entry) => toStringResult(entry, `${what} entry`))\n if (new Set(result).size !== result.length) {\n throw atomicHelperFault(\"entries_malformed\", `atomic helper returned duplicate ${what} entries`)\n }\n return result\n}\n\n/**\n * Converts a successful helper value into the result the request's operation\n * promises, and throws when the value does not have that shape.\n * @private\n * @since 1.0.0\n */\nexport const convert = <A>(\n request: FramedRequest,\n value: unknown,\n limits: Limits\n): Effect.Effect<A, PlatformError.PlatformError> => {\n if (request.operation === \"batch\") {\n const response = record(value, \"batch\")\n const requests = request.requests\n if (\n response.rootIdentity !== request.rootIdentity || !Array.isArray(response.entries) ||\n response.entries.length !== requests.length\n ) {\n throw atomicHelperFault(\"batch_malformed\", \"atomic helper returned a foreign or incomplete batch\")\n }\n const seen = new Set<number>()\n let previous = \"\"\n let previousIndex = -1\n const pending = response.entries.map((raw) => {\n const entry = record(raw, \"batch entry\")\n const index = integer(entry.index, \"batch index\")\n const member = requests[index]\n if (\n member === undefined || seen.has(index) || entry.path !== member.path ||\n member.path < previous || (member.path === previous && index <= previousIndex)\n ) {\n throw atomicHelperFault(\"batch_malformed\", \"atomic helper returned an invalid batch member identity or order\")\n }\n seen.add(index)\n previous = member.path\n previousIndex = index\n if (Buffer.byteLength(JSON.stringify(entry.result), \"utf8\") > limits.batchEntry) {\n throw atomicHelperFault(\"batch_malformed\", \"atomic helper returned an oversized batch entry\")\n }\n const envelope = resultEnvelope(entry.result)\n const identity = { index, path: member.path }\n if (!envelope.ok) {\n return Effect.succeed({\n ...identity,\n result: Result.fail(\n failure(\n member,\n atomicHelperFault(\"helper_rejected\", envelope.message ?? \"atomic batch member failed\"),\n envelope\n )\n )\n })\n }\n if (member.operation === \"digest\") {\n const measured = record(envelope.value, \"digest\")\n if (typeof measured.digest !== \"string\" || !/^[a-f0-9]{64}$/.test(measured.digest)) {\n throw atomicHelperFault(\"digest_malformed\", \"atomic helper returned an invalid SHA-256 digest\")\n }\n const sizeBytes = integer(measured.sizeBytes, \"digest size\")\n if (sizeBytes > limits.content) {\n throw atomicHelperFault(\"digest_malformed\", \"atomic helper returned an oversized digest measurement\")\n }\n const bytes = member.content === true ? toBytes(measured, limits.content) : undefined\n if (bytes !== undefined && bytes.length !== sizeBytes) {\n throw atomicHelperFault(\"digest_malformed\", \"atomic helper returned a mismatched digest size\")\n }\n return Effect.succeed({\n ...identity,\n result: Result.succeed<KernelFileSystem.AtomicBatchValue>({\n operation: \"digest\",\n digest: measured.digest,\n sizeBytes,\n ...(bytes === undefined ? {} : { bytes })\n })\n })\n }\n return Effect.map(convert(member, envelope.value, limits), (converted) => ({\n ...identity,\n result: Result.succeed<KernelFileSystem.AtomicBatchValue>(\n member.operation === \"stat\"\n ? { operation: \"stat\", info: converted as FileSystem.File.Info }\n : member.operation === \"resolve\"\n ? { operation: \"resolve\", resolution: converted as KernelFileSystem.Resolution }\n : { operation: member.operation, paths: (converted as Array<string>).sort() }\n )\n }))\n })\n return Effect.map(Effect.all(pending), (entries) => ({ rootIdentity: response.rootIdentity, entries }) as A)\n }\n if (request.operation === \"readFile\" || request.operation === \"readFileString\") {\n // An empty file encodes to an empty string, so the payload is read by\n // shape: truthiness would return the raw envelope for it instead.\n const bytes = toBytes(value, limits.content)\n if (request.operation === \"readFile\") {\n return Effect.succeed(bytes as A)\n }\n try {\n return Effect.succeed(new TextDecoder(request.encoding).decode(bytes) as A)\n } catch (cause) {\n // Effect's own `readFileString` reports a rejected encoding as a\n // BadArgument, not as a filesystem failure.\n return Effect.fail(PlatformError.badArgument({\n module: \"FileSystem\",\n method: \"readFileString\",\n description: \"invalid encoding\",\n cause\n }))\n }\n }\n if (request.operation === \"stat\") {\n return Effect.succeed(toInfo(value) as A)\n }\n if (request.operation === \"exists\") {\n if (typeof value !== \"boolean\") {\n throw atomicHelperFault(\"result_malformed\", \"atomic helper returned a non-boolean exists result\")\n }\n return Effect.succeed(value as A)\n }\n if (request.operation === \"readLink\" || request.operation === \"realPath\") {\n return Effect.succeed(toStringResult(value, `${request.operation} result`) as A)\n }\n if (request.operation === \"resolve\") {\n const resolution = record(value, \"resolve result\")\n const target = resolution.target === null ? null : toStringResult(resolution.target, \"resolve target\")\n const answer: KernelFileSystem.Resolution = { path: toStringResult(resolution.path, \"resolve path\"), target }\n return Effect.succeed(answer as A)\n }\n if (request.operation === \"readDirectory\" || request.operation === \"glob\") {\n return Effect.succeed(toStringArray(value, `${request.operation} result`) as A)\n }\n if (\n request.operation === \"writeFile\" ||\n request.operation === \"writeFileString\" ||\n request.operation === \"chmod\" ||\n request.operation === \"chown\" ||\n request.operation === \"makeDirectory\" ||\n request.operation === \"remove\" ||\n request.operation === \"rename\"\n ) {\n if (value !== null) {\n throw atomicHelperFault(\"result_malformed\", `atomic helper returned a non-null ${request.operation} result`)\n }\n return Effect.succeed(undefined as A)\n }\n throw atomicHelperFault(\n \"operation_unsupported\",\n `atomic helper returned success for unsupported operation ${(request as FramedRequest).operation}`\n )\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The process transport beneath the atomic filesystem: resolving the
|
|
3
|
+
* configured helper to a file the confined workspace cannot have
|
|
4
|
+
* supplied, and running one isolated, bounded helper process per framed
|
|
5
|
+
* request.
|
|
6
|
+
* @since 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
import type * as KernelFileSystem from "@smthrs/kernel/FileSystem";
|
|
9
|
+
import { Effect, type PlatformError } from "effect";
|
|
10
|
+
import type { Limits } from "../AtomicFileSystem.ts";
|
|
11
|
+
/**
|
|
12
|
+
* Process-local helper starts, including helpers later cancelled or refused.
|
|
13
|
+
* @private
|
|
14
|
+
* @since 1.0.0
|
|
15
|
+
*/
|
|
16
|
+
export declare const started: () => number;
|
|
17
|
+
/**
|
|
18
|
+
* True when `target` is at or below `root`. Both are absolute and already
|
|
19
|
+
* canonical. A different Windows drive produces an absolute relative result.
|
|
20
|
+
* @private
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
*/
|
|
23
|
+
export declare const inside: (root: string, target: string) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Resolves the configured helper to an absolute, executable regular file
|
|
26
|
+
* that the confined workspace cannot have supplied. Every failure throws, and
|
|
27
|
+
* every throw becomes a fail-closed `PermissionDenied`, so a host without a
|
|
28
|
+
* usable helper performs no filesystem operation at all.
|
|
29
|
+
* @private
|
|
30
|
+
* @since 1.0.0
|
|
31
|
+
*/
|
|
32
|
+
export declare const usableExecutable: (configured: string, boundaryRoot: string | undefined) => string;
|
|
33
|
+
/**
|
|
34
|
+
* Runs one helper over one framed request and settles with its converted
|
|
35
|
+
* answer. Every exit path kills the child, releases its pipes, and waits for
|
|
36
|
+
* the operating system to report that the process has closed.
|
|
37
|
+
* @private
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
export declare const spawnHelper: <A>(request: KernelFileSystem.AtomicRequest, executable: string, payload: Buffer, settings: {
|
|
41
|
+
readonly limits: Limits;
|
|
42
|
+
readonly timeoutMs: number;
|
|
43
|
+
}) => Effect.Effect<A, PlatformError.PlatformError>;
|
|
44
|
+
//# sourceMappingURL=AtomicFileSystemTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AtomicFileSystemTransport.d.ts","sourceRoot":"","sources":["../../../src/internal/AtomicFileSystemTransport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,gBAAgB,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAA;AAInD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAOpD;;;;GAIG;AACH,eAAO,MAAM,OAAO,QAAO,MAAwB,CAAA;AAKnD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,OAGrD,CAAA;AA6BD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,cAAc,MAAM,GAAG,SAAS,KAAG,MAwBvF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,SAAS,gBAAgB,CAAC,aAAa,EACvC,YAAY,MAAM,EAClB,SAAS,MAAM,EACf,UAAU;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAChE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,aAAa,CA6J3C,CAAA"}
|