@smthrs/std 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 +130 -0
- package/LICENSE +21 -0
- package/README.md +152 -2
- package/dist/cjs/ApplyPatch.d.ts +174 -0
- package/dist/cjs/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/ApplyPatch.js +309 -0
- package/dist/cjs/ApplyPatch.js.map +7 -0
- package/dist/cjs/Bash.d.ts +380 -0
- package/dist/cjs/Bash.d.ts.map +1 -0
- package/dist/cjs/Bash.js +332 -0
- package/dist/cjs/Bash.js.map +7 -0
- package/dist/cjs/Checkpoints.d.ts +279 -0
- package/dist/cjs/Checkpoints.d.ts.map +1 -0
- package/dist/cjs/Checkpoints.js +145 -0
- package/dist/cjs/Checkpoints.js.map +7 -0
- package/dist/cjs/Container.d.ts +132 -0
- package/dist/cjs/Container.d.ts.map +1 -0
- package/dist/cjs/Container.js +113 -0
- package/dist/cjs/Container.js.map +7 -0
- package/dist/cjs/Edit.d.ts +203 -0
- package/dist/cjs/Edit.d.ts.map +1 -0
- package/dist/cjs/Edit.js +258 -0
- package/dist/cjs/Edit.js.map +7 -0
- package/dist/cjs/ExaWebSearch.d.ts +22 -0
- package/dist/cjs/ExaWebSearch.d.ts.map +1 -0
- package/dist/cjs/ExaWebSearch.js +138 -0
- package/dist/cjs/ExaWebSearch.js.map +7 -0
- package/dist/cjs/Explore.d.ts +328 -0
- package/dist/cjs/Explore.d.ts.map +1 -0
- package/dist/cjs/Explore.js +90 -0
- package/dist/cjs/Explore.js.map +7 -0
- package/dist/cjs/Fetch.d.ts +130 -0
- package/dist/cjs/Fetch.d.ts.map +1 -0
- package/dist/cjs/Fetch.js +64 -0
- package/dist/cjs/Fetch.js.map +7 -0
- package/dist/cjs/Glob.d.ts +204 -0
- package/dist/cjs/Glob.d.ts.map +1 -0
- package/dist/cjs/Glob.js +94 -0
- package/dist/cjs/Glob.js.map +7 -0
- package/dist/cjs/Grep.d.ts +347 -0
- package/dist/cjs/Grep.d.ts.map +1 -0
- package/dist/cjs/Grep.js +181 -0
- package/dist/cjs/Grep.js.map +7 -0
- package/dist/cjs/HttpPost.d.ts +130 -0
- package/dist/cjs/HttpPost.d.ts.map +1 -0
- package/dist/cjs/HttpPost.js +72 -0
- package/dist/cjs/HttpPost.js.map +7 -0
- package/dist/cjs/LanguageServer.d.ts +90 -0
- package/dist/cjs/LanguageServer.d.ts.map +1 -0
- package/dist/cjs/LanguageServer.js +60 -0
- package/dist/cjs/LanguageServer.js.map +7 -0
- package/dist/cjs/Ls.d.ts +164 -0
- package/dist/cjs/Ls.d.ts.map +1 -0
- package/dist/cjs/Ls.js +136 -0
- package/dist/cjs/Ls.js.map +7 -0
- package/dist/cjs/Lsp.d.ts +125 -0
- package/dist/cjs/Lsp.d.ts.map +1 -0
- package/dist/cjs/Lsp.js +137 -0
- package/dist/cjs/Lsp.js.map +7 -0
- package/dist/cjs/Manifest.d.ts +918 -0
- package/dist/cjs/Manifest.d.ts.map +1 -0
- package/dist/cjs/Manifest.js +144 -0
- package/dist/cjs/Manifest.js.map +7 -0
- package/dist/cjs/NativeSearch.d.ts +38 -0
- package/dist/cjs/NativeSearch.d.ts.map +1 -0
- package/dist/cjs/NativeSearch.js +326 -0
- package/dist/cjs/NativeSearch.js.map +7 -0
- package/dist/cjs/NodeLanguageServer.d.ts +128 -0
- package/dist/cjs/NodeLanguageServer.d.ts.map +1 -0
- package/dist/cjs/NodeLanguageServer.js +796 -0
- package/dist/cjs/NodeLanguageServer.js.map +7 -0
- package/dist/cjs/PortableSearch.d.ts +24 -0
- package/dist/cjs/PortableSearch.d.ts.map +1 -0
- package/dist/cjs/PortableSearch.js +233 -0
- package/dist/cjs/PortableSearch.js.map +7 -0
- package/dist/cjs/Probe.d.ts +193 -0
- package/dist/cjs/Probe.d.ts.map +1 -0
- package/dist/cjs/Probe.js +134 -0
- package/dist/cjs/Probe.js.map +7 -0
- package/dist/cjs/Read.d.ts +189 -0
- package/dist/cjs/Read.d.ts.map +1 -0
- package/dist/cjs/Read.js +223 -0
- package/dist/cjs/Read.js.map +7 -0
- package/dist/cjs/Relocate.d.ts +73 -0
- package/dist/cjs/Relocate.d.ts.map +1 -0
- package/dist/cjs/Relocate.js +72 -0
- package/dist/cjs/Relocate.js.map +7 -0
- package/dist/cjs/Search.d.ts +163 -0
- package/dist/cjs/Search.d.ts.map +1 -0
- package/dist/cjs/Search.js +51 -0
- package/dist/cjs/Search.js.map +7 -0
- package/dist/cjs/SearchConformance.d.ts +115 -0
- package/dist/cjs/SearchConformance.d.ts.map +1 -0
- package/dist/cjs/SearchConformance.js +172 -0
- package/dist/cjs/SearchConformance.js.map +7 -0
- package/dist/cjs/SearchContract.d.ts +114 -0
- package/dist/cjs/SearchContract.d.ts.map +1 -0
- package/dist/cjs/SearchContract.js +339 -0
- package/dist/cjs/SearchContract.js.map +7 -0
- package/dist/cjs/ShellCommand.d.ts +164 -0
- package/dist/cjs/ShellCommand.d.ts.map +1 -0
- package/dist/cjs/ShellCommand.js +102 -0
- package/dist/cjs/ShellCommand.js.map +7 -0
- package/dist/cjs/StdError.d.ts +55 -0
- package/dist/cjs/StdError.d.ts.map +1 -0
- package/dist/cjs/StdError.js +74 -0
- package/dist/cjs/StdError.js.map +7 -0
- package/dist/cjs/TestRun.d.ts +311 -0
- package/dist/cjs/TestRun.d.ts.map +1 -0
- package/dist/cjs/TestRun.js +228 -0
- package/dist/cjs/TestRun.js.map +7 -0
- package/dist/cjs/TestRunner.d.ts +102 -0
- package/dist/cjs/TestRunner.d.ts.map +1 -0
- package/dist/cjs/TestRunner.js +54 -0
- package/dist/cjs/TestRunner.js.map +7 -0
- package/dist/cjs/TreeFingerprint.d.ts +140 -0
- package/dist/cjs/TreeFingerprint.d.ts.map +1 -0
- package/dist/cjs/TreeFingerprint.js +87 -0
- package/dist/cjs/TreeFingerprint.js.map +7 -0
- package/dist/cjs/UpdatePlan.d.ts +152 -0
- package/dist/cjs/UpdatePlan.d.ts.map +1 -0
- package/dist/cjs/UpdatePlan.js +87 -0
- package/dist/cjs/UpdatePlan.js.map +7 -0
- package/dist/cjs/WebFetch.d.ts +134 -0
- package/dist/cjs/WebFetch.d.ts.map +1 -0
- package/dist/cjs/WebFetch.js +140 -0
- package/dist/cjs/WebFetch.js.map +7 -0
- package/dist/cjs/WebSearch.d.ts +181 -0
- package/dist/cjs/WebSearch.d.ts.map +1 -0
- package/dist/cjs/WebSearch.js +86 -0
- package/dist/cjs/WebSearch.js.map +7 -0
- package/dist/cjs/Write.d.ts +147 -0
- package/dist/cjs/Write.d.ts.map +1 -0
- package/dist/cjs/Write.js +122 -0
- package/dist/cjs/Write.js.map +7 -0
- package/dist/cjs/index.d.ts +127 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/ApplyPatch.d.ts +145 -0
- package/dist/cjs/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/internal/ApplyPatch.js +462 -0
- package/dist/cjs/internal/ApplyPatch.js.map +7 -0
- package/dist/cjs/internal/CodexText.d.ts +73 -0
- package/dist/cjs/internal/CodexText.d.ts.map +1 -0
- package/dist/cjs/internal/CodexText.js +108 -0
- package/dist/cjs/internal/CodexText.js.map +7 -0
- package/dist/cjs/internal/Declaration.d.ts +49 -0
- package/dist/cjs/internal/Declaration.d.ts.map +1 -0
- package/dist/cjs/internal/Declaration.js +46 -0
- package/dist/cjs/internal/Declaration.js.map +7 -0
- package/dist/cjs/internal/Diagnostics.d.ts +77 -0
- package/dist/cjs/internal/Diagnostics.d.ts.map +1 -0
- package/dist/cjs/internal/Diagnostics.js +89 -0
- package/dist/cjs/internal/Diagnostics.js.map +7 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts +67 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/cjs/internal/EnvelopePrecheck.js +124 -0
- package/dist/cjs/internal/EnvelopePrecheck.js.map +7 -0
- package/dist/cjs/internal/Exec.d.ts +139 -0
- package/dist/cjs/internal/Exec.d.ts.map +1 -0
- package/dist/cjs/internal/Exec.js +158 -0
- package/dist/cjs/internal/Exec.js.map +7 -0
- package/dist/cjs/internal/FileMutation.d.ts +109 -0
- package/dist/cjs/internal/FileMutation.d.ts.map +1 -0
- package/dist/cjs/internal/FileMutation.js +116 -0
- package/dist/cjs/internal/FileMutation.js.map +7 -0
- package/dist/cjs/internal/FsFailure.d.ts +38 -0
- package/dist/cjs/internal/FsFailure.d.ts.map +1 -0
- package/dist/cjs/internal/FsFailure.js +40 -0
- package/dist/cjs/internal/FsFailure.js.map +7 -0
- package/dist/cjs/internal/GitWorktree.d.ts +108 -0
- package/dist/cjs/internal/GitWorktree.d.ts.map +1 -0
- package/dist/cjs/internal/GitWorktree.js +276 -0
- package/dist/cjs/internal/GitWorktree.js.map +7 -0
- package/dist/cjs/internal/Grouping.d.ts +51 -0
- package/dist/cjs/internal/Grouping.d.ts.map +1 -0
- package/dist/cjs/internal/Grouping.js +83 -0
- package/dist/cjs/internal/Grouping.js.map +7 -0
- package/dist/cjs/internal/Html.d.ts +20 -0
- package/dist/cjs/internal/Html.d.ts.map +1 -0
- package/dist/cjs/internal/Html.js +81 -0
- package/dist/cjs/internal/Html.js.map +7 -0
- package/dist/cjs/internal/Http.d.ts +95 -0
- package/dist/cjs/internal/Http.d.ts.map +1 -0
- package/dist/cjs/internal/Http.js +153 -0
- package/dist/cjs/internal/Http.js.map +7 -0
- package/dist/cjs/internal/HttpNetwork.d.ts +27 -0
- package/dist/cjs/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/cjs/internal/HttpNetwork.js +146 -0
- package/dist/cjs/internal/HttpNetwork.js.map +7 -0
- package/dist/cjs/internal/Ignore.d.ts +37 -0
- package/dist/cjs/internal/Ignore.d.ts.map +1 -0
- package/dist/cjs/internal/Ignore.js +100 -0
- package/dist/cjs/internal/Ignore.js.map +7 -0
- package/dist/cjs/internal/LinearRegex.d.ts +19 -0
- package/dist/cjs/internal/LinearRegex.d.ts.map +1 -0
- package/dist/cjs/internal/LinearRegex.js +166 -0
- package/dist/cjs/internal/LinearRegex.js.map +7 -0
- package/dist/cjs/internal/Match.d.ts +85 -0
- package/dist/cjs/internal/Match.d.ts.map +1 -0
- package/dist/cjs/internal/Match.js +99 -0
- package/dist/cjs/internal/Match.js.map +7 -0
- package/dist/cjs/internal/Paths.d.ts +23 -0
- package/dist/cjs/internal/Paths.d.ts.map +1 -0
- package/dist/cjs/internal/Paths.js +52 -0
- package/dist/cjs/internal/Paths.js.map +7 -0
- package/dist/cjs/internal/Preserve.d.ts +25 -0
- package/dist/cjs/internal/Preserve.d.ts.map +1 -0
- package/dist/cjs/internal/Preserve.js +88 -0
- package/dist/cjs/internal/Preserve.js.map +7 -0
- package/dist/cjs/internal/Prune.d.ts +35 -0
- package/dist/cjs/internal/Prune.d.ts.map +1 -0
- package/dist/cjs/internal/Prune.js +54 -0
- package/dist/cjs/internal/Prune.js.map +7 -0
- package/dist/cjs/internal/SearchContract.d.ts +63 -0
- package/dist/cjs/internal/SearchContract.d.ts.map +1 -0
- package/dist/cjs/internal/SearchContract.js +46 -0
- package/dist/cjs/internal/SearchContract.js.map +7 -0
- package/dist/cjs/internal/Symbols.d.ts +39 -0
- package/dist/cjs/internal/Symbols.d.ts.map +1 -0
- package/dist/cjs/internal/Symbols.js +59 -0
- package/dist/cjs/internal/Symbols.js.map +7 -0
- package/dist/cjs/internal/TestReport.d.ts +52 -0
- package/dist/cjs/internal/TestReport.d.ts.map +1 -0
- package/dist/cjs/internal/TestReport.js +131 -0
- package/dist/cjs/internal/TestReport.js.map +7 -0
- package/dist/cjs/internal/Text.d.ts +114 -0
- package/dist/cjs/internal/Text.d.ts.map +1 -0
- package/dist/cjs/internal/Text.js +82 -0
- package/dist/cjs/internal/Text.js.map +7 -0
- package/dist/cjs/internal/Url.d.ts +13 -0
- package/dist/cjs/internal/Url.d.ts.map +1 -0
- package/dist/cjs/internal/Url.js +35 -0
- package/dist/cjs/internal/Url.js.map +7 -0
- package/dist/cjs/internal/Walk.d.ts +72 -0
- package/dist/cjs/internal/Walk.d.ts.map +1 -0
- package/dist/cjs/internal/Walk.js +108 -0
- package/dist/cjs/internal/Walk.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/ApplyPatch.d.ts +174 -0
- package/dist/esm/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/ApplyPatch.js +346 -0
- package/dist/esm/ApplyPatch.js.map +1 -0
- package/dist/esm/Bash.d.ts +380 -0
- package/dist/esm/Bash.d.ts.map +1 -0
- package/dist/esm/Bash.js +505 -0
- package/dist/esm/Bash.js.map +1 -0
- package/dist/esm/Checkpoints.d.ts +279 -0
- package/dist/esm/Checkpoints.d.ts.map +1 -0
- package/dist/esm/Checkpoints.js +298 -0
- package/dist/esm/Checkpoints.js.map +1 -0
- package/dist/esm/Container.d.ts +132 -0
- package/dist/esm/Container.d.ts.map +1 -0
- package/dist/esm/Container.js +151 -0
- package/dist/esm/Container.js.map +1 -0
- package/dist/esm/Edit.d.ts +203 -0
- package/dist/esm/Edit.d.ts.map +1 -0
- package/dist/esm/Edit.js +296 -0
- package/dist/esm/Edit.js.map +1 -0
- package/dist/esm/ExaWebSearch.d.ts +22 -0
- package/dist/esm/ExaWebSearch.d.ts.map +1 -0
- package/dist/esm/ExaWebSearch.js +107 -0
- package/dist/esm/ExaWebSearch.js.map +1 -0
- package/dist/esm/Explore.d.ts +328 -0
- package/dist/esm/Explore.d.ts.map +1 -0
- package/dist/esm/Explore.js +106 -0
- package/dist/esm/Explore.js.map +1 -0
- package/dist/esm/Fetch.d.ts +130 -0
- package/dist/esm/Fetch.d.ts.map +1 -0
- package/dist/esm/Fetch.js +91 -0
- package/dist/esm/Fetch.js.map +1 -0
- package/dist/esm/Glob.d.ts +204 -0
- package/dist/esm/Glob.d.ts.map +1 -0
- package/dist/esm/Glob.js +177 -0
- package/dist/esm/Glob.js.map +1 -0
- package/dist/esm/Grep.d.ts +347 -0
- package/dist/esm/Grep.d.ts.map +1 -0
- package/dist/esm/Grep.js +289 -0
- package/dist/esm/Grep.js.map +1 -0
- package/dist/esm/HttpPost.d.ts +130 -0
- package/dist/esm/HttpPost.d.ts.map +1 -0
- package/dist/esm/HttpPost.js +89 -0
- package/dist/esm/HttpPost.js.map +1 -0
- package/dist/esm/LanguageServer.d.ts +90 -0
- package/dist/esm/LanguageServer.d.ts.map +1 -0
- package/dist/esm/LanguageServer.js +57 -0
- package/dist/esm/LanguageServer.js.map +1 -0
- package/dist/esm/Ls.d.ts +164 -0
- package/dist/esm/Ls.d.ts.map +1 -0
- package/dist/esm/Ls.js +178 -0
- package/dist/esm/Ls.js.map +1 -0
- package/dist/esm/Lsp.d.ts +125 -0
- package/dist/esm/Lsp.d.ts.map +1 -0
- package/dist/esm/Lsp.js +165 -0
- package/dist/esm/Lsp.js.map +1 -0
- package/dist/esm/Manifest.d.ts +918 -0
- package/dist/esm/Manifest.d.ts.map +1 -0
- package/dist/esm/Manifest.js +153 -0
- package/dist/esm/Manifest.js.map +1 -0
- package/dist/esm/NativeSearch.d.ts +38 -0
- package/dist/esm/NativeSearch.d.ts.map +1 -0
- package/dist/esm/NativeSearch.js +378 -0
- package/dist/esm/NativeSearch.js.map +1 -0
- package/dist/esm/NodeLanguageServer.d.ts +128 -0
- package/dist/esm/NodeLanguageServer.d.ts.map +1 -0
- package/dist/esm/NodeLanguageServer.js +843 -0
- package/dist/esm/NodeLanguageServer.js.map +1 -0
- package/dist/esm/PortableSearch.d.ts +24 -0
- package/dist/esm/PortableSearch.d.ts.map +1 -0
- package/dist/esm/PortableSearch.js +240 -0
- package/dist/esm/PortableSearch.js.map +1 -0
- package/dist/esm/Probe.d.ts +193 -0
- package/dist/esm/Probe.d.ts.map +1 -0
- package/dist/esm/Probe.js +225 -0
- package/dist/esm/Probe.js.map +1 -0
- package/dist/esm/Read.d.ts +189 -0
- package/dist/esm/Read.d.ts.map +1 -0
- package/dist/esm/Read.js +300 -0
- package/dist/esm/Read.js.map +1 -0
- package/dist/esm/Relocate.d.ts +73 -0
- package/dist/esm/Relocate.d.ts.map +1 -0
- package/dist/esm/Relocate.js +153 -0
- package/dist/esm/Relocate.js.map +1 -0
- package/dist/esm/Search.d.ts +163 -0
- package/dist/esm/Search.d.ts.map +1 -0
- package/dist/esm/Search.js +47 -0
- package/dist/esm/Search.js.map +1 -0
- package/dist/esm/SearchConformance.d.ts +115 -0
- package/dist/esm/SearchConformance.d.ts.map +1 -0
- package/dist/esm/SearchConformance.js +193 -0
- package/dist/esm/SearchConformance.js.map +1 -0
- package/dist/esm/SearchContract.d.ts +114 -0
- package/dist/esm/SearchContract.d.ts.map +1 -0
- package/dist/esm/SearchContract.js +461 -0
- package/dist/esm/SearchContract.js.map +1 -0
- package/dist/esm/ShellCommand.d.ts +164 -0
- package/dist/esm/ShellCommand.d.ts.map +1 -0
- package/dist/esm/ShellCommand.js +159 -0
- package/dist/esm/ShellCommand.js.map +1 -0
- package/dist/esm/StdError.d.ts +55 -0
- package/dist/esm/StdError.d.ts.map +1 -0
- package/dist/esm/StdError.js +71 -0
- package/dist/esm/StdError.js.map +1 -0
- package/dist/esm/TestRun.d.ts +311 -0
- package/dist/esm/TestRun.d.ts.map +1 -0
- package/dist/esm/TestRun.js +316 -0
- package/dist/esm/TestRun.js.map +1 -0
- package/dist/esm/TestRunner.d.ts +102 -0
- package/dist/esm/TestRunner.d.ts.map +1 -0
- package/dist/esm/TestRunner.js +68 -0
- package/dist/esm/TestRunner.js.map +1 -0
- package/dist/esm/TreeFingerprint.d.ts +140 -0
- package/dist/esm/TreeFingerprint.d.ts.map +1 -0
- package/dist/esm/TreeFingerprint.js +170 -0
- package/dist/esm/TreeFingerprint.js.map +1 -0
- package/dist/esm/UpdatePlan.d.ts +152 -0
- package/dist/esm/UpdatePlan.d.ts.map +1 -0
- package/dist/esm/UpdatePlan.js +129 -0
- package/dist/esm/UpdatePlan.js.map +1 -0
- package/dist/esm/WebFetch.d.ts +134 -0
- package/dist/esm/WebFetch.d.ts.map +1 -0
- package/dist/esm/WebFetch.js +151 -0
- package/dist/esm/WebFetch.js.map +1 -0
- package/dist/esm/WebSearch.d.ts +181 -0
- package/dist/esm/WebSearch.d.ts.map +1 -0
- package/dist/esm/WebSearch.js +134 -0
- package/dist/esm/WebSearch.js.map +1 -0
- package/dist/esm/Write.d.ts +147 -0
- package/dist/esm/Write.d.ts.map +1 -0
- package/dist/esm/Write.js +144 -0
- package/dist/esm/Write.js.map +1 -0
- package/dist/esm/index.d.ts +127 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +127 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/ApplyPatch.d.ts +145 -0
- package/dist/esm/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/internal/ApplyPatch.js +489 -0
- package/dist/esm/internal/ApplyPatch.js.map +1 -0
- package/dist/esm/internal/CodexText.d.ts +73 -0
- package/dist/esm/internal/CodexText.d.ts.map +1 -0
- package/dist/esm/internal/CodexText.js +156 -0
- package/dist/esm/internal/CodexText.js.map +1 -0
- package/dist/esm/internal/Declaration.d.ts +49 -0
- package/dist/esm/internal/Declaration.d.ts.map +1 -0
- package/dist/esm/internal/Declaration.js +42 -0
- package/dist/esm/internal/Declaration.js.map +1 -0
- package/dist/esm/internal/Diagnostics.d.ts +77 -0
- package/dist/esm/internal/Diagnostics.d.ts.map +1 -0
- package/dist/esm/internal/Diagnostics.js +99 -0
- package/dist/esm/internal/Diagnostics.js.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts +67 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.js +167 -0
- package/dist/esm/internal/EnvelopePrecheck.js.map +1 -0
- package/dist/esm/internal/Exec.d.ts +139 -0
- package/dist/esm/internal/Exec.d.ts.map +1 -0
- package/dist/esm/internal/Exec.js +193 -0
- package/dist/esm/internal/Exec.js.map +1 -0
- package/dist/esm/internal/FileMutation.d.ts +109 -0
- package/dist/esm/internal/FileMutation.d.ts.map +1 -0
- package/dist/esm/internal/FileMutation.js +123 -0
- package/dist/esm/internal/FileMutation.js.map +1 -0
- package/dist/esm/internal/FsFailure.d.ts +38 -0
- package/dist/esm/internal/FsFailure.d.ts.map +1 -0
- package/dist/esm/internal/FsFailure.js +39 -0
- package/dist/esm/internal/FsFailure.js.map +1 -0
- package/dist/esm/internal/GitWorktree.d.ts +108 -0
- package/dist/esm/internal/GitWorktree.d.ts.map +1 -0
- package/dist/esm/internal/GitWorktree.js +352 -0
- package/dist/esm/internal/GitWorktree.js.map +1 -0
- package/dist/esm/internal/Grouping.d.ts +51 -0
- package/dist/esm/internal/Grouping.d.ts.map +1 -0
- package/dist/esm/internal/Grouping.js +99 -0
- package/dist/esm/internal/Grouping.js.map +1 -0
- package/dist/esm/internal/Html.d.ts +20 -0
- package/dist/esm/internal/Html.d.ts.map +1 -0
- package/dist/esm/internal/Html.js +70 -0
- package/dist/esm/internal/Html.js.map +1 -0
- package/dist/esm/internal/Http.d.ts +95 -0
- package/dist/esm/internal/Http.d.ts.map +1 -0
- package/dist/esm/internal/Http.js +154 -0
- package/dist/esm/internal/Http.js.map +1 -0
- package/dist/esm/internal/HttpNetwork.d.ts +27 -0
- package/dist/esm/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/esm/internal/HttpNetwork.js +114 -0
- package/dist/esm/internal/HttpNetwork.js.map +1 -0
- package/dist/esm/internal/Ignore.d.ts +37 -0
- package/dist/esm/internal/Ignore.d.ts.map +1 -0
- package/dist/esm/internal/Ignore.js +128 -0
- package/dist/esm/internal/Ignore.js.map +1 -0
- package/dist/esm/internal/LinearRegex.d.ts +19 -0
- package/dist/esm/internal/LinearRegex.d.ts.map +1 -0
- package/dist/esm/internal/LinearRegex.js +176 -0
- package/dist/esm/internal/LinearRegex.js.map +1 -0
- package/dist/esm/internal/Match.d.ts +85 -0
- package/dist/esm/internal/Match.d.ts.map +1 -0
- package/dist/esm/internal/Match.js +142 -0
- package/dist/esm/internal/Match.js.map +1 -0
- package/dist/esm/internal/Paths.d.ts +23 -0
- package/dist/esm/internal/Paths.d.ts.map +1 -0
- package/dist/esm/internal/Paths.js +40 -0
- package/dist/esm/internal/Paths.js.map +1 -0
- package/dist/esm/internal/Preserve.d.ts +25 -0
- package/dist/esm/internal/Preserve.d.ts.map +1 -0
- package/dist/esm/internal/Preserve.js +70 -0
- package/dist/esm/internal/Preserve.js.map +1 -0
- package/dist/esm/internal/Prune.d.ts +35 -0
- package/dist/esm/internal/Prune.d.ts.map +1 -0
- package/dist/esm/internal/Prune.js +60 -0
- package/dist/esm/internal/Prune.js.map +1 -0
- package/dist/esm/internal/SearchContract.d.ts +63 -0
- package/dist/esm/internal/SearchContract.d.ts.map +1 -0
- package/dist/esm/internal/SearchContract.js +66 -0
- package/dist/esm/internal/SearchContract.js.map +1 -0
- package/dist/esm/internal/Symbols.d.ts +39 -0
- package/dist/esm/internal/Symbols.d.ts.map +1 -0
- package/dist/esm/internal/Symbols.js +79 -0
- package/dist/esm/internal/Symbols.js.map +1 -0
- package/dist/esm/internal/TestReport.d.ts +52 -0
- package/dist/esm/internal/TestReport.d.ts.map +1 -0
- package/dist/esm/internal/TestReport.js +172 -0
- package/dist/esm/internal/TestReport.js.map +1 -0
- package/dist/esm/internal/Text.d.ts +114 -0
- package/dist/esm/internal/Text.d.ts.map +1 -0
- package/dist/esm/internal/Text.js +130 -0
- package/dist/esm/internal/Text.js.map +1 -0
- package/dist/esm/internal/Url.d.ts +13 -0
- package/dist/esm/internal/Url.d.ts.map +1 -0
- package/dist/esm/internal/Url.js +27 -0
- package/dist/esm/internal/Url.js.map +1 -0
- package/dist/esm/internal/Walk.d.ts +72 -0
- package/dist/esm/internal/Walk.d.ts.map +1 -0
- package/dist/esm/internal/Walk.js +126 -0
- package/dist/esm/internal/Walk.js.map +1 -0
- package/docs/README.md +117 -0
- package/docs/api.md +472 -0
- package/docs/concepts/effects-and-capabilities.md +136 -0
- package/docs/concepts/flows-and-handlers.md +115 -0
- package/docs/concepts/limits-and-disclosure.md +102 -0
- package/docs/concepts/search-contract.md +182 -0
- package/docs/guides/bind-the-standard-flows.md +114 -0
- package/docs/guides/implement-a-search-peer.md +133 -0
- package/docs/guides/pin-a-checkpoint.md +141 -0
- package/docs/guides/query-a-language-server.md +257 -0
- package/docs/guides/reach-the-network.md +141 -0
- package/docs/guides/read-and-edit-a-file.md +240 -0
- package/docs/guides/run-a-shell-command.md +215 -0
- package/docs/guides/run-the-test-suite.md +154 -0
- package/docs/guides/search-a-workspace.md +148 -0
- package/docs/installation.md +111 -0
- package/docs/quickstart.md +125 -0
- package/docs/reference/flows.md +556 -0
- package/docs/troubleshooting.md +322 -0
- package/package.json +439 -3
- package/src/ApplyPatch.ts +458 -0
- package/src/Bash.ts +607 -0
- package/src/Checkpoints.ts +422 -0
- package/src/Container.ts +212 -0
- package/src/Edit.ts +366 -0
- package/src/ExaWebSearch.ts +145 -0
- package/src/Explore.ts +139 -0
- package/src/Fetch.ts +117 -0
- package/src/Glob.ts +200 -0
- package/src/Grep.ts +320 -0
- package/src/HttpPost.ts +120 -0
- package/src/LanguageServer.ts +110 -0
- package/src/Ls.ts +228 -0
- package/src/Lsp.ts +184 -0
- package/src/Manifest.ts +162 -0
- package/src/NativeSearch.ts +457 -0
- package/src/NodeLanguageServer.ts +1148 -0
- package/src/PortableSearch.ts +264 -0
- package/src/Probe.ts +284 -0
- package/src/Read.ts +359 -0
- package/src/Relocate.ts +166 -0
- package/src/Search.ts +185 -0
- package/src/SearchConformance.ts +288 -0
- package/src/SearchContract.ts +489 -0
- package/src/ShellCommand.ts +201 -0
- package/src/StdError.ts +80 -0
- package/src/TestRun.ts +401 -0
- package/src/TestRunner.ts +119 -0
- package/src/TreeFingerprint.ts +200 -0
- package/src/UpdatePlan.ts +171 -0
- package/src/WebFetch.ts +194 -0
- package/src/WebSearch.ts +165 -0
- package/src/Write.ts +195 -0
- package/src/index.ts +154 -0
- package/src/internal/ApplyPatch.ts +601 -0
- package/src/internal/CodexText.ts +182 -0
- package/src/internal/Declaration.ts +60 -0
- package/src/internal/Diagnostics.ts +134 -0
- package/src/internal/EnvelopePrecheck.ts +233 -0
- package/src/internal/Exec.ts +314 -0
- package/src/internal/FileMutation.ts +231 -0
- package/src/internal/FsFailure.ts +51 -0
- package/src/internal/GitWorktree.ts +491 -0
- package/src/internal/Grouping.ts +106 -0
- package/src/internal/Html.ts +87 -0
- package/src/internal/Http.ts +209 -0
- package/src/internal/HttpNetwork.ts +153 -0
- package/src/internal/Ignore.ts +135 -0
- package/src/internal/LinearRegex.ts +173 -0
- package/src/internal/Match.ts +172 -0
- package/src/internal/Paths.ts +42 -0
- package/src/internal/Preserve.ts +108 -0
- package/src/internal/Prune.ts +62 -0
- package/src/internal/SearchContract.ts +77 -0
- package/src/internal/Symbols.ts +88 -0
- package/src/internal/TestReport.ts +194 -0
- package/src/internal/Text.ts +170 -0
- package/src/internal/Url.ts +23 -0
- package/src/internal/Walk.ts +176 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small, dependency-free HTML renderers for web retrieval.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
const comments = /<!--[\s\S]*?-->/g;
|
|
7
|
+
const entities = { amp: "&", lt: "<", gt: ">", quot: "\"", apos: "'", nbsp: " " };
|
|
8
|
+
const dropSkipped = (html) => {
|
|
9
|
+
const lower = html.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
10
|
+
const opening = /<(head|script|style|noscript|iframe|object|embed)\b/gi;
|
|
11
|
+
let output = "";
|
|
12
|
+
let cursor = 0;
|
|
13
|
+
let match;
|
|
14
|
+
while ((match = opening.exec(html)) !== null) {
|
|
15
|
+
output += html.slice(cursor, match.index);
|
|
16
|
+
const marker = `</${match[1].toLowerCase()}`;
|
|
17
|
+
let close = lower.indexOf(marker, opening.lastIndex);
|
|
18
|
+
while (close !== -1) {
|
|
19
|
+
let end = close + marker.length;
|
|
20
|
+
while (/\s/.test(lower[end] ?? ""))
|
|
21
|
+
end++;
|
|
22
|
+
if (lower[end] === ">") {
|
|
23
|
+
cursor = end + 1;
|
|
24
|
+
opening.lastIndex = cursor;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
close = lower.indexOf(marker, close + marker.length);
|
|
28
|
+
}
|
|
29
|
+
if (close === -1)
|
|
30
|
+
return output;
|
|
31
|
+
}
|
|
32
|
+
return output + html.slice(cursor);
|
|
33
|
+
};
|
|
34
|
+
const decode = (value) => value.replace(/&(#x[\da-f]+|#\d+|[a-z]+);/gi, (match, entity) => {
|
|
35
|
+
if (entity[0] === "#") {
|
|
36
|
+
const number = Number.parseInt(entity.slice(entity[1].toLowerCase() === "x" ? 2 : 1), entity[1].toLowerCase() === "x" ? 16 : 10);
|
|
37
|
+
return number <= 0x10ffff
|
|
38
|
+
&& !(number >= 0xd800 && number <= 0xdfff)
|
|
39
|
+
? String.fromCodePoint(number)
|
|
40
|
+
: match;
|
|
41
|
+
}
|
|
42
|
+
const key = entity.toLowerCase();
|
|
43
|
+
return Object.hasOwn(entities, key) ? entities[key] : match;
|
|
44
|
+
});
|
|
45
|
+
const source = (html) => dropSkipped(html.replace(comments, ""));
|
|
46
|
+
/**
|
|
47
|
+
* Extracts readable text while dropping executable and presentation-only elements.
|
|
48
|
+
*
|
|
49
|
+
* @category rendering
|
|
50
|
+
* @since 1.0.0
|
|
51
|
+
*/
|
|
52
|
+
export const toText = (html) => decode(source(html).replace(/<(br|\/p|\/div|\/li|\/h[1-6]|\/tr)\b[^>]*>/gi, "\n").replace(/<[^>]*>/g, " "))
|
|
53
|
+
.replace(/[ \t]+\n/g, "\n").replace(/\n[ \t]+/g, "\n").replace(/\n{3,}/g, "\n\n").replace(/[ \t]{2,}/g, " ").trim();
|
|
54
|
+
/**
|
|
55
|
+
* Converts a conservative subset of HTML into readable Markdown.
|
|
56
|
+
*
|
|
57
|
+
* @category rendering
|
|
58
|
+
* @since 1.0.0
|
|
59
|
+
*/
|
|
60
|
+
export const toMarkdown = (html) => {
|
|
61
|
+
const markdown = source(html)
|
|
62
|
+
.replace(/<h([1-6])\b[^>]*>([\s\S]*?)<\/h\1>/gi, (_all, level, text) => `\n\n${"#".repeat(Number(level))} ${toText(text)}\n\n`)
|
|
63
|
+
.replace(/<(strong|b)\b[^>]*>([\s\S]*?)<\/\1>/gi, "**$2**")
|
|
64
|
+
.replace(/<(em|i)\b[^>]*>([\s\S]*?)<\/\1>/gi, "*$2*")
|
|
65
|
+
.replace(/<a\b[^>]*href=["']([^"']+)["'][^>]*>([\s\S]*?)<\/a>/gi, (_all, href, text) => `[${toText(text)}](${href})`)
|
|
66
|
+
.replace(/<li\b[^>]*>/gi, "\n- ").replace(/<\/?(ul|ol|p|div|section|article|main|blockquote|pre|tr)\b[^>]*>/gi, "\n")
|
|
67
|
+
.replace(/<br\b[^>]*>/gi, "\n").replace(/<[^>]*>/g, "");
|
|
68
|
+
return decode(markdown).replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=Html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Html.js","sourceRoot":"","sources":["../../../src/internal/Html.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Small, dependency-free HTML renderers for web retrieval.\n *\n * @since 1.0.0\n */\n\nconst comments = /<!--[\\s\\S]*?-->/g\nconst entities: Readonly<Record<string, string>> = { amp: \"&\", lt: \"<\", gt: \">\", quot: \"\\\"\", apos: \"'\", nbsp: \" \" }\n\nconst dropSkipped = (html: string): string => {\n const lower = html.replace(/[A-Z]/g, (letter) => letter.toLowerCase())\n const opening = /<(head|script|style|noscript|iframe|object|embed)\\b/gi\n let output = \"\"\n let cursor = 0\n let match: RegExpExecArray | null\n while ((match = opening.exec(html)) !== null) {\n output += html.slice(cursor, match.index)\n const marker = `</${match[1]!.toLowerCase()}`\n let close = lower.indexOf(marker, opening.lastIndex)\n while (close !== -1) {\n let end = close + marker.length\n while (/\\s/.test(lower[end] ?? \"\")) end++\n if (lower[end] === \">\") {\n cursor = end + 1\n opening.lastIndex = cursor\n break\n }\n close = lower.indexOf(marker, close + marker.length)\n }\n if (close === -1) return output\n }\n return output + html.slice(cursor)\n}\n\nconst decode = (value: string): string =>\n value.replace(/&(#x[\\da-f]+|#\\d+|[a-z]+);/gi, (match, entity: string) => {\n if (entity[0] === \"#\") {\n const number = Number.parseInt(\n entity.slice(entity[1]!.toLowerCase() === \"x\" ? 2 : 1),\n entity[1]!.toLowerCase() === \"x\" ? 16 : 10\n )\n return number <= 0x10ffff\n && !(number >= 0xd800 && number <= 0xdfff)\n ? String.fromCodePoint(number)\n : match\n }\n const key = entity.toLowerCase()\n return Object.hasOwn(entities, key) ? entities[key]! : match\n })\n\nconst source = (html: string): string => dropSkipped(html.replace(comments, \"\"))\n\n/**\n * Extracts readable text while dropping executable and presentation-only elements.\n *\n * @category rendering\n * @since 1.0.0\n */\nexport const toText = (html: string): string =>\n decode(source(html).replace(/<(br|\\/p|\\/div|\\/li|\\/h[1-6]|\\/tr)\\b[^>]*>/gi, \"\\n\").replace(/<[^>]*>/g, \" \"))\n .replace(/[ \\t]+\\n/g, \"\\n\").replace(/\\n[ \\t]+/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").replace(/[ \\t]{2,}/g, \" \").trim()\n\n/**\n * Converts a conservative subset of HTML into readable Markdown.\n *\n * @category rendering\n * @since 1.0.0\n */\nexport const toMarkdown = (html: string): string => {\n const markdown = source(html)\n .replace(\n /<h([1-6])\\b[^>]*>([\\s\\S]*?)<\\/h\\1>/gi,\n (_all, level: string, text: string) => `\\n\\n${\"#\".repeat(Number(level))} ${toText(text)}\\n\\n`\n )\n .replace(/<(strong|b)\\b[^>]*>([\\s\\S]*?)<\\/\\1>/gi, \"**$2**\")\n .replace(/<(em|i)\\b[^>]*>([\\s\\S]*?)<\\/\\1>/gi, \"*$2*\")\n .replace(\n /<a\\b[^>]*href=[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)<\\/a>/gi,\n (_all, href: string, text: string) => `[${toText(text)}](${href})`\n )\n .replace(/<li\\b[^>]*>/gi, \"\\n- \").replace(\n /<\\/?(ul|ol|p|div|section|article|main|blockquote|pre|tr)\\b[^>]*>/gi,\n \"\\n\"\n )\n .replace(/<br\\b[^>]*>/gi, \"\\n\").replace(/<[^>]*>/g, \"\")\n return decode(markdown).replace(/[ \\t]+\\n/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim()\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP response limits, error mapping, and request deadlines.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import type { GrantStore } from "@smthrs/kernel/GrantStore";
|
|
7
|
+
import * as HttpClient from "@smthrs/kernel/HttpClient";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Schema from "effect/Schema";
|
|
10
|
+
import * as Stream from "effect/Stream";
|
|
11
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
12
|
+
import * as StdError from "../StdError.ts";
|
|
13
|
+
/**
|
|
14
|
+
* Maximum captured response bytes before decoding.
|
|
15
|
+
*
|
|
16
|
+
* @category http
|
|
17
|
+
* @since 1.0.0
|
|
18
|
+
*/
|
|
19
|
+
export declare const MAX_RESPONSE_BYTES: number;
|
|
20
|
+
/**
|
|
21
|
+
* Reads a response up to the shared byte limit and finalizes the stream on failure.
|
|
22
|
+
*
|
|
23
|
+
* @category http
|
|
24
|
+
* @since 1.0.0
|
|
25
|
+
*/
|
|
26
|
+
export declare const readBounded: <E, R>(stream: Stream.Stream<Uint8Array, E, R>, url: string) => Effect.Effect<Uint8Array, E | StdError.StdError, R>;
|
|
27
|
+
/**
|
|
28
|
+
* Maps transport failures while preserving standard HTTP failure codes.
|
|
29
|
+
*
|
|
30
|
+
* @category http
|
|
31
|
+
* @since 1.0.0
|
|
32
|
+
*/
|
|
33
|
+
export declare const requestError: (url: string, error: unknown) => StdError.StdError;
|
|
34
|
+
/**
|
|
35
|
+
* Looks up a response header without depending on transport normalization.
|
|
36
|
+
*
|
|
37
|
+
* @category http
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
export declare const header: (headers: Readonly<Record<string, string | undefined>>, name: string) => string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Seconds; the runtime caps valid overrides at 120.
|
|
43
|
+
*
|
|
44
|
+
* @category http
|
|
45
|
+
* @since 1.0.0
|
|
46
|
+
*/
|
|
47
|
+
export declare const Timeout: Schema.Number;
|
|
48
|
+
/**
|
|
49
|
+
* Bounds the entire request and body read with one timer. Interruption reaches
|
|
50
|
+
* HttpClient.execute and response.stream so Effect aborts the transport and
|
|
51
|
+
* finalizes the body reader before returning the timeout failure.
|
|
52
|
+
* `timeoutError` preserves a tool's own timeout message while sharing the
|
|
53
|
+
* validation, duration cap, and interruption behavior.
|
|
54
|
+
*
|
|
55
|
+
* @category http
|
|
56
|
+
* @since 1.0.0
|
|
57
|
+
*/
|
|
58
|
+
export declare const withDeadline: <A, E, R>(effect: Effect.Effect<A, E, R>, url: string, timeout?: number, timeoutError?: (seconds: number) => StdError.StdError) => Effect.Effect<A, E | StdError.StdError, R>;
|
|
59
|
+
/**
|
|
60
|
+
* Keeps the head of rendered response text within the shared output budget and
|
|
61
|
+
* discloses the cut.
|
|
62
|
+
*
|
|
63
|
+
* @since 1.0.0
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
export declare const capOutput: (text: string) => {
|
|
67
|
+
readonly text: string;
|
|
68
|
+
readonly truncated: boolean;
|
|
69
|
+
readonly notice?: string;
|
|
70
|
+
};
|
|
71
|
+
/** Shared response contract for the GET and POST tools.
|
|
72
|
+
* @since 1.0.0
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
export declare const Response: Schema.Struct<{
|
|
76
|
+
readonly status: Schema.Number;
|
|
77
|
+
readonly body: Schema.String;
|
|
78
|
+
readonly truncated: Schema.Boolean;
|
|
79
|
+
readonly notice: Schema.optional<Schema.String>;
|
|
80
|
+
}>;
|
|
81
|
+
/** Validate, execute, and render one bounded HTTP request.
|
|
82
|
+
* @since 1.0.0
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
export declare const execute: (input: {
|
|
86
|
+
readonly url: string;
|
|
87
|
+
readonly headers?: Readonly<Record<string, string>> | undefined;
|
|
88
|
+
readonly timeout?: number | undefined;
|
|
89
|
+
}, makeRequest: (url: string) => HttpClientRequest.HttpClientRequest) => Effect.Effect<{
|
|
90
|
+
readonly status: number;
|
|
91
|
+
readonly body: string;
|
|
92
|
+
readonly truncated: boolean;
|
|
93
|
+
readonly notice?: string | undefined;
|
|
94
|
+
}, StdError.StdError, GrantStore | HttpClient.HttpClient>;
|
|
95
|
+
//# sourceMappingURL=Http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Http.d.ts","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,UAAU,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,iBAAiB,MAAM,wCAAwC,CAAA;AAC3E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAK1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAkB,CAAA;AAOjD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC9B,QAAQ,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,EACvC,KAAK,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CA6BlD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,EAAE,OAAO,OAAO,KAAG,QAAQ,CAAC,QAIhE,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,MAAM,KAAG,MAAM,GAAG,SAGrG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,eAAkE,CAAA;AAEtF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAClC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,KAAK,MAAM,EACX,gBAAY,EACZ,eAAe,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC,QAAQ,KACpD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAsB3C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,MAAM,KACX;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAShF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ;;;;;EAKnB,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO;kBAEF,MAAM;uBACD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS;uBAC5C,MAAM,GAAG,SAAS;sBAEpB,MAAM,KAAK,iBAAiB,CAAC,iBAAiB;;;;;yDA2BjE,CAAA"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP response limits, error mapping, and request deadlines.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import * as HttpClient from "@smthrs/kernel/HttpClient";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import * as Schema from "effect/Schema";
|
|
9
|
+
import * as Stream from "effect/Stream";
|
|
10
|
+
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
|
|
11
|
+
import * as StdError from "../StdError.js";
|
|
12
|
+
import { guarded, refusal } from "./HttpNetwork.js";
|
|
13
|
+
import { MAX_OUTPUT_BYTES, notice, truncateBytes } from "./Text.js";
|
|
14
|
+
import { parseHttpUrl } from "./Url.js";
|
|
15
|
+
/**
|
|
16
|
+
* Maximum captured response bytes before decoding.
|
|
17
|
+
*
|
|
18
|
+
* @category http
|
|
19
|
+
* @since 1.0.0
|
|
20
|
+
*/
|
|
21
|
+
export const MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
22
|
+
/**
|
|
23
|
+
* Reads a response up to the shared byte limit and finalizes the stream on failure.
|
|
24
|
+
*
|
|
25
|
+
* @category http
|
|
26
|
+
* @since 1.0.0
|
|
27
|
+
*/
|
|
28
|
+
export const readBounded = (stream, url) => Stream.runFoldEffect(stream, () => ({ chunks: [], size: 0 }), (state, chunk) => {
|
|
29
|
+
const size = state.size + chunk.byteLength;
|
|
30
|
+
if (size > MAX_RESPONSE_BYTES) {
|
|
31
|
+
return Effect.fail(new StdError.StdError({
|
|
32
|
+
code: "response_too_large",
|
|
33
|
+
message: "Response exceeds the 5 MiB limit",
|
|
34
|
+
path: url
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
state.chunks.push(chunk);
|
|
38
|
+
state.size = size;
|
|
39
|
+
return Effect.succeed(state);
|
|
40
|
+
}).pipe(Effect.map((state) => {
|
|
41
|
+
const output = new Uint8Array(state.size);
|
|
42
|
+
let offset = 0;
|
|
43
|
+
for (const chunk of state.chunks) {
|
|
44
|
+
output.set(chunk, offset);
|
|
45
|
+
offset += chunk.byteLength;
|
|
46
|
+
}
|
|
47
|
+
return output;
|
|
48
|
+
}));
|
|
49
|
+
/**
|
|
50
|
+
* Maps transport failures while preserving standard HTTP failure codes.
|
|
51
|
+
*
|
|
52
|
+
* @category http
|
|
53
|
+
* @since 1.0.0
|
|
54
|
+
*/
|
|
55
|
+
export const requestError = (url, error) => error instanceof StdError.StdError ? error : refusal(error) ?? new StdError.StdError({
|
|
56
|
+
code: "request_failed",
|
|
57
|
+
message: `Request failed: ${url}${error instanceof Error ? ` (${error.message})` : ""}`
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Looks up a response header without depending on transport normalization.
|
|
61
|
+
*
|
|
62
|
+
* @category http
|
|
63
|
+
* @since 1.0.0
|
|
64
|
+
*/
|
|
65
|
+
export const header = (headers, name) => {
|
|
66
|
+
const lower = name.toLowerCase();
|
|
67
|
+
return Object.entries(headers).find(([key]) => key.toLowerCase() === lower)?.[1];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Seconds; the runtime caps valid overrides at 120.
|
|
71
|
+
*
|
|
72
|
+
* @category http
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
*/
|
|
75
|
+
export const Timeout = Schema.Number.check(Schema.isFinite(), Schema.isGreaterThan(0));
|
|
76
|
+
/**
|
|
77
|
+
* Bounds the entire request and body read with one timer. Interruption reaches
|
|
78
|
+
* HttpClient.execute and response.stream so Effect aborts the transport and
|
|
79
|
+
* finalizes the body reader before returning the timeout failure.
|
|
80
|
+
* `timeoutError` preserves a tool's own timeout message while sharing the
|
|
81
|
+
* validation, duration cap, and interruption behavior.
|
|
82
|
+
*
|
|
83
|
+
* @category http
|
|
84
|
+
* @since 1.0.0
|
|
85
|
+
*/
|
|
86
|
+
export const withDeadline = (effect, url, timeout = 30, timeoutError) => {
|
|
87
|
+
if (!Schema.is(Timeout)(timeout)) {
|
|
88
|
+
return Effect.fail(new StdError.StdError({
|
|
89
|
+
code: "invalid_input",
|
|
90
|
+
message: "Timeout must be a finite number greater than zero seconds",
|
|
91
|
+
path: url
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
const seconds = Math.min(timeout, 120);
|
|
95
|
+
return Effect.timeoutOrElse(effect, {
|
|
96
|
+
duration: seconds * 1_000,
|
|
97
|
+
orElse: () => Effect.fail(timeoutError?.(seconds) ?? new StdError.StdError({
|
|
98
|
+
code: "timeout",
|
|
99
|
+
message: `Request timed out after ${seconds} seconds`,
|
|
100
|
+
path: url
|
|
101
|
+
}))
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Keeps the head of rendered response text within the shared output budget and
|
|
106
|
+
* discloses the cut.
|
|
107
|
+
*
|
|
108
|
+
* @since 1.0.0
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
export const capOutput = (text) => {
|
|
112
|
+
const rendered = truncateBytes(text, MAX_OUTPUT_BYTES, { keep: "head" });
|
|
113
|
+
return {
|
|
114
|
+
text: rendered.text,
|
|
115
|
+
truncated: rendered.truncated,
|
|
116
|
+
...(rendered.truncated
|
|
117
|
+
? { notice: notice("bytes", rendered.keptBytes, rendered.keptBytes + rendered.droppedBytes) }
|
|
118
|
+
: {})
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/** Shared response contract for the GET and POST tools.
|
|
122
|
+
* @since 1.0.0
|
|
123
|
+
* @private
|
|
124
|
+
*/
|
|
125
|
+
export const Response = Schema.Struct({
|
|
126
|
+
status: Schema.Number.annotate({ description: "HTTP status code, including error statuses" }),
|
|
127
|
+
body: Schema.String.annotate({ description: "Response body as text" }),
|
|
128
|
+
truncated: Schema.Boolean.annotate({ description: "Whether the body exceeded the display budget" }),
|
|
129
|
+
notice: Schema.optional(Schema.String.annotate({ description: "Truncation disclosure" }))
|
|
130
|
+
});
|
|
131
|
+
/** Validate, execute, and render one bounded HTTP request.
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
export const execute = Effect.fn("Http.execute")(function* (input, makeRequest) {
|
|
136
|
+
const url = parseHttpUrl(input.url);
|
|
137
|
+
if (url === undefined) {
|
|
138
|
+
return yield* Effect.fail(new StdError.StdError({
|
|
139
|
+
code: "invalid_input",
|
|
140
|
+
message: `URL must use http or https without user information: ${input.url}`,
|
|
141
|
+
path: input.url
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
144
|
+
const client = guarded(yield* HttpClient.HttpClient);
|
|
145
|
+
const request = makeRequest(url.toString());
|
|
146
|
+
const { status, bytes } = yield* withDeadline(Effect.gen(function* () {
|
|
147
|
+
const response = yield* client.execute(input.headers === undefined ? request : HttpClientRequest.setHeaders(request, input.headers));
|
|
148
|
+
const bytes = yield* readBounded(response.stream, input.url);
|
|
149
|
+
return { status: response.status, bytes };
|
|
150
|
+
}).pipe(Effect.mapError((error) => requestError(input.url, error))), input.url, input.timeout);
|
|
151
|
+
const { text, ...disclosure } = capOutput(new TextDecoder().decode(bytes));
|
|
152
|
+
return { status, body: text, ...disclosure };
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=Http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Http.js","sourceRoot":"","sources":["../../../src/internal/Http.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared HTTP response limits, error mapping, and request deadlines.\n *\n * @since 1.0.0\n */\n\nimport type { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport * as HttpClient from \"@smthrs/kernel/HttpClient\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as Stream from \"effect/Stream\"\nimport * as HttpClientRequest from \"effect/unstable/http/HttpClientRequest\"\nimport * as StdError from \"../StdError.ts\"\nimport { guarded, refusal } from \"./HttpNetwork.ts\"\nimport { MAX_OUTPUT_BYTES, notice, truncateBytes } from \"./Text.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/**\n * Maximum captured response bytes before decoding.\n *\n * @category http\n * @since 1.0.0\n */\nexport const MAX_RESPONSE_BYTES = 5 * 1024 * 1024\n\ninterface BodyState {\n readonly chunks: Array<Uint8Array>\n size: number\n}\n\n/**\n * Reads a response up to the shared byte limit and finalizes the stream on failure.\n *\n * @category http\n * @since 1.0.0\n */\nexport const readBounded = <E, R>(\n stream: Stream.Stream<Uint8Array, E, R>,\n url: string\n): Effect.Effect<Uint8Array, E | StdError.StdError, R> =>\n Stream.runFoldEffect(\n stream,\n (): BodyState => ({ chunks: [], size: 0 }),\n (state, chunk) => {\n const size = state.size + chunk.byteLength\n if (size > MAX_RESPONSE_BYTES) {\n return Effect.fail(\n new StdError.StdError({\n code: \"response_too_large\",\n message: \"Response exceeds the 5 MiB limit\",\n path: url\n })\n )\n }\n state.chunks.push(chunk)\n state.size = size\n return Effect.succeed(state)\n }\n ).pipe(\n Effect.map((state) => {\n const output = new Uint8Array(state.size)\n let offset = 0\n for (const chunk of state.chunks) {\n output.set(chunk, offset)\n offset += chunk.byteLength\n }\n return output\n })\n )\n\n/**\n * Maps transport failures while preserving standard HTTP failure codes.\n *\n * @category http\n * @since 1.0.0\n */\nexport const requestError = (url: string, error: unknown): StdError.StdError =>\n error instanceof StdError.StdError ? error : refusal(error) ?? new StdError.StdError({\n code: \"request_failed\",\n message: `Request failed: ${url}${error instanceof Error ? ` (${error.message})` : \"\"}`\n })\n\n/**\n * Looks up a response header without depending on transport normalization.\n *\n * @category http\n * @since 1.0.0\n */\nexport const header = (headers: Readonly<Record<string, string | undefined>>, name: string): string | undefined => {\n const lower = name.toLowerCase()\n return Object.entries(headers).find(([key]) => key.toLowerCase() === lower)?.[1]\n}\n\n/**\n * Seconds; the runtime caps valid overrides at 120.\n *\n * @category http\n * @since 1.0.0\n */\nexport const Timeout = Schema.Number.check(Schema.isFinite(), Schema.isGreaterThan(0))\n\n/**\n * Bounds the entire request and body read with one timer. Interruption reaches\n * HttpClient.execute and response.stream so Effect aborts the transport and\n * finalizes the body reader before returning the timeout failure.\n * `timeoutError` preserves a tool's own timeout message while sharing the\n * validation, duration cap, and interruption behavior.\n *\n * @category http\n * @since 1.0.0\n */\nexport const withDeadline = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n url: string,\n timeout = 30,\n timeoutError?: (seconds: number) => StdError.StdError\n): Effect.Effect<A, E | StdError.StdError, R> => {\n if (!Schema.is(Timeout)(timeout)) {\n return Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: \"Timeout must be a finite number greater than zero seconds\",\n path: url\n })\n )\n }\n const seconds = Math.min(timeout, 120)\n return Effect.timeoutOrElse(effect, {\n duration: seconds * 1_000,\n orElse: () =>\n Effect.fail(\n timeoutError?.(seconds) ?? new StdError.StdError({\n code: \"timeout\",\n message: `Request timed out after ${seconds} seconds`,\n path: url\n })\n )\n })\n}\n\n/**\n * Keeps the head of rendered response text within the shared output budget and\n * discloses the cut.\n *\n * @since 1.0.0\n * @private\n */\nexport const capOutput = (\n text: string\n): { readonly text: string; readonly truncated: boolean; readonly notice?: string } => {\n const rendered = truncateBytes(text, MAX_OUTPUT_BYTES, { keep: \"head\" })\n return {\n text: rendered.text,\n truncated: rendered.truncated,\n ...(rendered.truncated\n ? { notice: notice(\"bytes\", rendered.keptBytes, rendered.keptBytes + rendered.droppedBytes) }\n : {})\n }\n}\n\n/** Shared response contract for the GET and POST tools.\n * @since 1.0.0\n * @private\n */\nexport const Response = Schema.Struct({\n status: Schema.Number.annotate({ description: \"HTTP status code, including error statuses\" }),\n body: Schema.String.annotate({ description: \"Response body as text\" }),\n truncated: Schema.Boolean.annotate({ description: \"Whether the body exceeded the display budget\" }),\n notice: Schema.optional(Schema.String.annotate({ description: \"Truncation disclosure\" }))\n})\n\n/** Validate, execute, and render one bounded HTTP request.\n * @since 1.0.0\n * @private\n */\nexport const execute = Effect.fn(\"Http.execute\")(function*(\n input: {\n readonly url: string\n readonly headers?: Readonly<Record<string, string>> | undefined\n readonly timeout?: number | undefined\n },\n makeRequest: (url: string) => HttpClientRequest.HttpClientRequest\n): Effect.fn.Return<typeof Response.Type, StdError.StdError, HttpClient.HttpClient | GrantStore> {\n const url = parseHttpUrl(input.url)\n if (url === undefined) {\n return yield* Effect.fail(\n new StdError.StdError({\n code: \"invalid_input\",\n message: `URL must use http or https without user information: ${input.url}`,\n path: input.url\n })\n )\n }\n const client = guarded(yield* HttpClient.HttpClient)\n const request = makeRequest(url.toString())\n const { status, bytes } = yield* withDeadline(\n Effect.gen(function*() {\n const response = yield* client.execute(\n input.headers === undefined ? request : HttpClientRequest.setHeaders(request, input.headers)\n )\n const bytes = yield* readBounded(response.stream, input.url)\n return { status: response.status, bytes }\n }).pipe(Effect.mapError((error) => requestError(input.url, error))),\n input.url,\n input.timeout\n )\n const { text, ...disclosure } = capOutput(new TextDecoder().decode(bytes))\n return { status, body: text, ...disclosure }\n})\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination policy shared by the web tools, including every redirect hop.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import { GrantStore } from "@smthrs/kernel/GrantStore";
|
|
7
|
+
import { Context, Effect } from "effect";
|
|
8
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
9
|
+
import * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
10
|
+
import * as StdError from "../StdError.ts";
|
|
11
|
+
/** Resolver seam: all addresses must be public before an unprivileged request.
|
|
12
|
+
* @since 1.0.0
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
export declare const ResolveHost: Context.Reference<(hostname: string) => Effect.Effect<ReadonlyArray<string>, unknown>>;
|
|
16
|
+
/** Decorates the supplied client before following redirects through the guard.
|
|
17
|
+
* The transport must honor manual redirects, as required by the kernel client.
|
|
18
|
+
* @since 1.0.0
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
export declare const guarded: (client: HttpClient.HttpClient, follow?: boolean) => HttpClient.HttpClient.With<HttpClientError.HttpClientError, GrantStore>;
|
|
22
|
+
/** Recovers the typed refusal carried through Effect's HTTP error channel.
|
|
23
|
+
* @since 1.0.0
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
export declare const refusal: (error: unknown) => StdError.StdError | undefined;
|
|
27
|
+
//# sourceMappingURL=HttpNetwork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpNetwork.d.ts","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAOtD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAEhD,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAA;AAC7D,OAAO,KAAK,eAAe,MAAM,sCAAsC,CAAA;AAGvE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAG1C;;;GAGG;AACH,eAAO,MAAM,WAAW,+BACX,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAInE,CAAA;AAwEF;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,UAAU,CAAC,UAAU,EAC7B,gBAAa,KACZ,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,UAAU,CAuBxE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,QAAQ,CAAC,QAAQ,GAAG,SAW5D,CAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destination policy shared by the web tools, including every redirect hop.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import * as Capability from "@smthrs/capability/Capability";
|
|
7
|
+
import { GrantStore } from "@smthrs/kernel/GrantStore";
|
|
8
|
+
import { authorizePreflight, Destination, fromHttpClientError, supportsDestinationPinning } from "@smthrs/kernel/HttpClient";
|
|
9
|
+
import { Context, Effect, Option } from "effect";
|
|
10
|
+
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
11
|
+
import * as HttpClient from "effect/unstable/http/HttpClient";
|
|
12
|
+
import * as HttpClientError from "effect/unstable/http/HttpClientError";
|
|
13
|
+
import { lookup } from "node:dns/promises";
|
|
14
|
+
import { BlockList, isIP } from "node:net";
|
|
15
|
+
import * as StdError from "../StdError.js";
|
|
16
|
+
import { parseHttpUrl } from "./Url.js";
|
|
17
|
+
/** Resolver seam: all addresses must be public before an unprivileged request.
|
|
18
|
+
* @since 1.0.0
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
export const ResolveHost = Context.Reference("@smthrs/std/HttpNetwork/ResolveHost", {
|
|
22
|
+
defaultValue: () => (hostname) => Effect.tryPromise(async () => (await lookup(hostname, { all: true })).map((a) => a.address))
|
|
23
|
+
});
|
|
24
|
+
const blocked = new BlockList();
|
|
25
|
+
for (const [address, prefix] of [
|
|
26
|
+
["0.0.0.0", 8],
|
|
27
|
+
["10.0.0.0", 8],
|
|
28
|
+
["127.0.0.0", 8],
|
|
29
|
+
["169.254.0.0", 16],
|
|
30
|
+
["172.16.0.0", 12],
|
|
31
|
+
["192.168.0.0", 16],
|
|
32
|
+
["192.0.0.0", 24],
|
|
33
|
+
["100.64.0.0", 10],
|
|
34
|
+
["198.18.0.0", 15],
|
|
35
|
+
["224.0.0.0", 4],
|
|
36
|
+
["240.0.0.0", 4]
|
|
37
|
+
])
|
|
38
|
+
blocked.addSubnet(address, prefix, "ipv4");
|
|
39
|
+
// Allow global IPv6 and mapped IPv4 only, excluding transition tunnels.
|
|
40
|
+
const publicV6 = new BlockList();
|
|
41
|
+
publicV6.addSubnet("2000::", 3, "ipv6");
|
|
42
|
+
publicV6.addSubnet("::ffff:0:0", 96, "ipv6");
|
|
43
|
+
blocked.addSubnet("2002::", 16, "ipv6");
|
|
44
|
+
blocked.addSubnet("2001::", 32, "ipv6");
|
|
45
|
+
const isPublic = (address) => {
|
|
46
|
+
const family = isIP(address);
|
|
47
|
+
if (family === 4)
|
|
48
|
+
return !blocked.check(address, "ipv4");
|
|
49
|
+
return family === 6 && publicV6.check(address, "ipv6") && !blocked.check(address, "ipv6");
|
|
50
|
+
};
|
|
51
|
+
const failure = (code, message, path) => new StdError.StdError({ code, message, path });
|
|
52
|
+
const check = Effect.fn("HttpNetwork.check")(function* (value, client) {
|
|
53
|
+
const url = parseHttpUrl(value);
|
|
54
|
+
if (url === undefined) {
|
|
55
|
+
return yield* Effect.fail(failure("invalid_input", "URL must use http or https without user information", value));
|
|
56
|
+
}
|
|
57
|
+
if (!supportsDestinationPinning(client)) {
|
|
58
|
+
return yield* Effect.fail(failure("unsupported", "HTTP host must support destination pinning", value));
|
|
59
|
+
}
|
|
60
|
+
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
61
|
+
const local = hostname.replace(/\.$/, "").toLowerCase();
|
|
62
|
+
const literal = isIP(hostname) !== 0;
|
|
63
|
+
const localhost = local === "localhost" || local.endsWith(".localhost");
|
|
64
|
+
const resolve = yield* ResolveHost;
|
|
65
|
+
// Refuse localhost before DNS unless the origin is explicitly authorized.
|
|
66
|
+
const privateGrant = Effect.gen(function* () {
|
|
67
|
+
const store = yield* GrantStore;
|
|
68
|
+
const capability = yield* Effect.try({
|
|
69
|
+
try: () => Capability.make("net:private", url.origin),
|
|
70
|
+
catch: () => failure("invalid_input", "Private HTTP origin exceeds the capability resource limit", value)
|
|
71
|
+
});
|
|
72
|
+
yield* store.check(capability).pipe(Effect.mapError(() => failure("permission_denied", "Private HTTP destination requires a net:private grant", value)));
|
|
73
|
+
});
|
|
74
|
+
if (localhost)
|
|
75
|
+
yield* privateGrant;
|
|
76
|
+
const addresses = literal ? [hostname] : [
|
|
77
|
+
...yield* resolve(hostname).pipe(Effect.mapError(() => failure("request_failed", "Could not resolve HTTP destination", value)))
|
|
78
|
+
];
|
|
79
|
+
if (addresses.length === 0 || addresses.some((address) => isIP(address) === 0)) {
|
|
80
|
+
return yield* Effect.fail(failure("request_failed", "HTTP destination has no valid addresses", value));
|
|
81
|
+
}
|
|
82
|
+
if (!localhost && !addresses.every(isPublic))
|
|
83
|
+
yield* privateGrant;
|
|
84
|
+
return Object.freeze({ origin: url.origin, addresses: Object.freeze(addresses) });
|
|
85
|
+
});
|
|
86
|
+
/** Decorates the supplied client before following redirects through the guard.
|
|
87
|
+
* The transport must honor manual redirects, as required by the kernel client.
|
|
88
|
+
* @since 1.0.0
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
export const guarded = (client, follow = true) => {
|
|
92
|
+
const checked = HttpClient.transform(client, (execute, request) => authorizePreflight(request, check(request.url, client).pipe(Effect.mapError((cause) => new HttpClientError.HttpClientError({
|
|
93
|
+
reason: new HttpClientError.TransportError({ request, cause, description: cause.message })
|
|
94
|
+
})), Effect.flatMap((destination) => Effect.updateContext(execute, (context) => Context.add(Context.add(context, Destination, destination), FetchHttpClient.RequestInit, {
|
|
95
|
+
...Context.getOrUndefined(context, FetchHttpClient.RequestInit),
|
|
96
|
+
redirect: "manual"
|
|
97
|
+
}))))));
|
|
98
|
+
return follow ? HttpClient.followRedirects(checked) : checked;
|
|
99
|
+
};
|
|
100
|
+
/** Recovers the typed refusal carried through Effect's HTTP error channel.
|
|
101
|
+
* @since 1.0.0
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
export const refusal = (error) => {
|
|
105
|
+
if (!(error instanceof HttpClientError.HttpClientError) || error.reason._tag !== "TransportError")
|
|
106
|
+
return undefined;
|
|
107
|
+
if (error.reason.cause instanceof StdError.StdError)
|
|
108
|
+
return error.reason.cause;
|
|
109
|
+
if (Option.isSome(fromHttpClientError(error))) {
|
|
110
|
+
return failure("permission_denied", error.reason.description ?? "HTTP permission was refused", error.reason.request.url);
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=HttpNetwork.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpNetwork.js","sourceRoot":"","sources":["../../../src/internal/HttpNetwork.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Destination policy shared by the web tools, including every redirect hop.\n *\n * @since 1.0.0\n */\n\nimport * as Capability from \"@smthrs/capability/Capability\"\nimport { GrantStore } from \"@smthrs/kernel/GrantStore\"\nimport {\n authorizePreflight,\n Destination,\n fromHttpClientError,\n supportsDestinationPinning\n} from \"@smthrs/kernel/HttpClient\"\nimport { Context, Effect, Option } from \"effect\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport * as HttpClient from \"effect/unstable/http/HttpClient\"\nimport * as HttpClientError from \"effect/unstable/http/HttpClientError\"\nimport { lookup } from \"node:dns/promises\"\nimport { BlockList, isIP } from \"node:net\"\nimport * as StdError from \"../StdError.ts\"\nimport { parseHttpUrl } from \"./Url.ts\"\n\n/** Resolver seam: all addresses must be public before an unprivileged request.\n * @since 1.0.0\n * @private\n */\nexport const ResolveHost = Context.Reference<\n (hostname: string) => Effect.Effect<ReadonlyArray<string>, unknown>\n>(\"@smthrs/std/HttpNetwork/ResolveHost\", {\n defaultValue: () => (hostname) =>\n Effect.tryPromise(async () => (await lookup(hostname, { all: true })).map((a) => a.address))\n})\n\nconst blocked = new BlockList()\nfor (\n const [address, prefix] of [\n [\"0.0.0.0\", 8],\n [\"10.0.0.0\", 8],\n [\"127.0.0.0\", 8],\n [\"169.254.0.0\", 16],\n [\"172.16.0.0\", 12],\n [\"192.168.0.0\", 16],\n [\"192.0.0.0\", 24],\n [\"100.64.0.0\", 10],\n [\"198.18.0.0\", 15],\n [\"224.0.0.0\", 4],\n [\"240.0.0.0\", 4]\n ] as const\n) blocked.addSubnet(address, prefix, \"ipv4\")\n// Allow global IPv6 and mapped IPv4 only, excluding transition tunnels.\nconst publicV6 = new BlockList()\npublicV6.addSubnet(\"2000::\", 3, \"ipv6\")\npublicV6.addSubnet(\"::ffff:0:0\", 96, \"ipv6\")\nblocked.addSubnet(\"2002::\", 16, \"ipv6\")\nblocked.addSubnet(\"2001::\", 32, \"ipv6\")\n\nconst isPublic = (address: string): boolean => {\n const family = isIP(address)\n if (family === 4) return !blocked.check(address, \"ipv4\")\n return family === 6 && publicV6.check(address, \"ipv6\") && !blocked.check(address, \"ipv6\")\n}\n\nconst failure = (code: StdError.Code, message: string, path: string) => new StdError.StdError({ code, message, path })\n\nconst check = Effect.fn(\"HttpNetwork.check\")(function*(value: string, client: HttpClient.HttpClient) {\n const url = parseHttpUrl(value)\n if (url === undefined) {\n return yield* Effect.fail(failure(\"invalid_input\", \"URL must use http or https without user information\", value))\n }\n if (!supportsDestinationPinning(client)) {\n return yield* Effect.fail(failure(\"unsupported\", \"HTTP host must support destination pinning\", value))\n }\n const hostname = url.hostname.replace(/^\\[|\\]$/g, \"\")\n const local = hostname.replace(/\\.$/, \"\").toLowerCase()\n const literal = isIP(hostname) !== 0\n const localhost = local === \"localhost\" || local.endsWith(\".localhost\")\n const resolve = yield* ResolveHost\n // Refuse localhost before DNS unless the origin is explicitly authorized.\n const privateGrant = Effect.gen(function*() {\n const store = yield* GrantStore\n const capability = yield* Effect.try({\n try: () => Capability.make(\"net:private\", url.origin),\n catch: () => failure(\"invalid_input\", \"Private HTTP origin exceeds the capability resource limit\", value)\n })\n yield* store.check(capability).pipe(\n Effect.mapError(() =>\n failure(\"permission_denied\", \"Private HTTP destination requires a net:private grant\", value)\n )\n )\n })\n if (localhost) yield* privateGrant\n const addresses = literal ? [hostname] : [\n ...yield* resolve(hostname).pipe(\n Effect.mapError(() => failure(\"request_failed\", \"Could not resolve HTTP destination\", value))\n )\n ]\n if (addresses.length === 0 || addresses.some((address) => isIP(address) === 0)) {\n return yield* Effect.fail(failure(\"request_failed\", \"HTTP destination has no valid addresses\", value))\n }\n if (!localhost && !addresses.every(isPublic)) yield* privateGrant\n return Object.freeze({ origin: url.origin, addresses: Object.freeze(addresses) })\n})\n\n/** Decorates the supplied client before following redirects through the guard.\n * The transport must honor manual redirects, as required by the kernel client.\n * @since 1.0.0\n * @private\n */\nexport const guarded = (\n client: HttpClient.HttpClient,\n follow = true\n): HttpClient.HttpClient.With<HttpClientError.HttpClientError, GrantStore> => {\n const checked = HttpClient.transform(\n client,\n (execute, request) =>\n authorizePreflight(\n request,\n check(request.url, client).pipe(\n Effect.mapError((cause) =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({ request, cause, description: cause.message })\n })\n ),\n Effect.flatMap((destination) =>\n Effect.updateContext(execute, (context: Context.Context<never>) =>\n Context.add(Context.add(context, Destination, destination), FetchHttpClient.RequestInit, {\n ...Context.getOrUndefined(context, FetchHttpClient.RequestInit),\n redirect: \"manual\"\n }))\n )\n )\n )\n )\n return follow ? HttpClient.followRedirects(checked) : checked\n}\n\n/** Recovers the typed refusal carried through Effect's HTTP error channel.\n * @since 1.0.0\n * @private\n */\nexport const refusal = (error: unknown): StdError.StdError | undefined => {\n if (!(error instanceof HttpClientError.HttpClientError) || error.reason._tag !== \"TransportError\") return undefined\n if (error.reason.cause instanceof StdError.StdError) return error.reason.cause\n if (Option.isSome(fromHttpClientError(error))) {\n return failure(\n \"permission_denied\",\n error.reason.description ?? \"HTTP permission was refused\",\n error.reason.request.url\n )\n }\n return undefined\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Root-scoped gitignore rules, compiled once per visited directory.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
interface Rule {
|
|
7
|
+
readonly expression: RegExp;
|
|
8
|
+
readonly directoryOnly: boolean;
|
|
9
|
+
readonly negated: boolean;
|
|
10
|
+
readonly byPath: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Rules belonging to one visited directory.
|
|
14
|
+
*
|
|
15
|
+
* @private
|
|
16
|
+
* @since 1.0.0
|
|
17
|
+
*/
|
|
18
|
+
export interface Scope {
|
|
19
|
+
readonly directory: string;
|
|
20
|
+
readonly rules: ReadonlyArray<Rule>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Parses gitignore lines without widening the caller-glob grammar.
|
|
24
|
+
*
|
|
25
|
+
* @private
|
|
26
|
+
* @since 1.0.0
|
|
27
|
+
*/
|
|
28
|
+
export declare const parse: (directory: string, content: string) => Scope;
|
|
29
|
+
/**
|
|
30
|
+
* Tests an entry before descent; deeper scopes and later rules take priority.
|
|
31
|
+
*
|
|
32
|
+
* @private
|
|
33
|
+
* @since 1.0.0
|
|
34
|
+
*/
|
|
35
|
+
export declare const ignored: (scopes: ReadonlyArray<Scope>, candidate: string, basename: string, directory: boolean, relative: (from: string, to: string) => string) => boolean;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=Ignore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ignore.d.ts","sourceRoot":"","sources":["../../../src/internal/Ignore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,UAAU,IAAI;IACZ,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAA;CACpC;AAyDD;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,KAqB1D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,GAClB,QAAQ,aAAa,CAAC,KAAK,CAAC,EAC5B,WAAW,MAAM,EACjB,UAAU,MAAM,EAChB,WAAW,OAAO,EAClB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,KAC7C,OAYF,CAAA"}
|