@poe-platform/safe-bash 0.1.788 → 0.1.790
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/image-ast/index.browser.js +147 -80
- package/dist/image-ast/index.js +147 -80
- package/dist/mp4-ast/mp4.d.ts +2 -0
- package/dist/pdf-ast/cos/parser.d.ts +1 -0
- package/dist/pdf-ast/cos/security.d.ts +2 -0
- package/dist/pdf-ast/cos/writer.d.ts +1 -0
- package/dist/pdf-ast/document.d.ts +3 -0
- package/dist/pdf-ast/edit/forms.d.ts +1 -0
- package/dist/pdf-ast/index.js +171 -82
- package/dist/safe-bash/chunks/{chunk-L5QQLNTO.js → chunk-22PI65AH.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-Q3E6C3DX.js → chunk-2TAGYMPK.js} +49 -34
- package/dist/safe-bash/chunks/{chunk-Z3HX3ZBA.js → chunk-2W4HTMEK.js} +52 -48
- package/dist/safe-bash/chunks/{chunk-FFZXP6ZC.js → chunk-3M7L7XU2.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-XNODZRVD.js → chunk-3QAO6UYS.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-YPETOVQU.js → chunk-3VKFK3NF.js} +2 -2
- package/dist/safe-bash/chunks/chunk-5OST7NOX.js +42 -0
- package/dist/safe-bash/chunks/{chunk-KEBSX2AX.js → chunk-6HLURHVU.js} +2 -2
- package/dist/safe-bash/chunks/chunk-DYEUZE6Z.js +19 -0
- package/dist/safe-bash/chunks/{chunk-T2TGCHKE.js → chunk-FM3WBSZT.js} +2 -2
- package/dist/safe-bash/chunks/chunk-GAYRKQM6.js +22 -0
- package/dist/safe-bash/chunks/{chunk-Q45QCA4J.js → chunk-I3KSESCR.js} +0 -7
- package/dist/safe-bash/chunks/{chunk-OSKDIBQS.js → chunk-JLIMK5TD.js} +1 -1
- package/dist/safe-bash/chunks/{chunk-2AYZCT5X.js → chunk-JQ2FAJJT.js} +27 -23
- package/dist/safe-bash/chunks/{chunk-QA3NVP43.js → chunk-JRE6Z3T7.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-DC5EHLKS.js → chunk-NDIL6T7Y.js} +5 -5
- package/dist/safe-bash/chunks/{chunk-747G42FY.js → chunk-OPR4UAIT.js} +2 -2
- package/dist/safe-bash/chunks/chunk-OSMQCYSP.js +19 -0
- package/dist/safe-bash/chunks/chunk-OYB332PQ.js +17 -0
- package/dist/safe-bash/chunks/{chunk-ZMYVCRAF.js → chunk-QTIH2AFE.js} +77 -69
- package/dist/safe-bash/chunks/{chunk-PYTLIUST.js → chunk-SBESXWT2.js} +43 -44
- package/dist/safe-bash/chunks/{chunk-4FDQJUFW.js → chunk-SDEPGTOF.js} +1 -1
- package/dist/safe-bash/chunks/chunk-UZU5BIJI.js +32 -0
- package/dist/safe-bash/chunks/{chunk-BI6JV62X.js → chunk-VCCMROTL.js} +7 -10
- package/dist/safe-bash/chunks/chunk-W47GHRRF.js +13 -0
- package/dist/safe-bash/chunks/{chunk-NPMQWZUZ.js → chunk-WS7KZIUM.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-3PZYHMGM.js → chunk-YYAERCWS.js} +7 -7
- package/dist/safe-bash/chunks/{chunk-5U7JECDB.js → chunk-ZPGVEUKF.js} +8 -7
- package/dist/safe-bash/chunks/{csvkit-K55OYAQC.js → csvkit-USUJG62I.js} +65 -11
- package/dist/safe-bash/chunks/{ffmpeg-BEFTQ6DZ.js → ffmpeg-KRGG5DLH.js} +21 -10
- package/dist/safe-bash/chunks/{gh-HQWOWLWE.js → gh-UCFDUZCX.js} +16 -8
- package/dist/safe-bash/chunks/{git-UFNPAOYZ.js → git-LPAF6KDG.js} +7 -9
- package/dist/safe-bash/chunks/{imagemagick-53BMHH6D.js → imagemagick-KGREKK4G.js} +38 -7
- package/dist/safe-bash/chunks/{implementation-QUTAAYMT.js → implementation-FXDRYS5A.js} +34 -8
- package/dist/safe-bash/chunks/{pdfimages-4OYI6FLG.js → pdfimages-UADCF4G4.js} +12 -8
- package/dist/safe-bash/chunks/{pdfinfo-I7U6TQPP.js → pdfinfo-O7UWPF4W.js} +38 -13
- package/dist/safe-bash/chunks/{pdftk-SUA6FMHI.js → pdftk-AERXIJTN.js} +13 -8
- package/dist/safe-bash/chunks/{pdftoppm-4C5DGEWX.js → pdftoppm-L466JQKI.js} +17 -10
- package/dist/safe-bash/chunks/{pdftotext-Y4WI225Y.js → pdftotext-SUSI4WXS.js} +19 -9
- package/dist/safe-bash/chunks/{qpdf-IORB4RV5.js → qpdf-YL24KVRH.js} +14 -8
- package/dist/safe-bash/chunks/{sips-WHAMJFEU.js → sips-QXEQZERX.js} +14 -7
- package/dist/safe-bash/chunks/{soffice-SYEK6WJS.js → soffice-TBITRML3.js} +16 -8
- package/dist/safe-bash/chunks/{wkhtmltopdf-ZIICWJLF.js → wkhtmltopdf-NJA2THRC.js} +27 -7
- package/dist/safe-bash/command-chunks/chunk-2C5BEBPY.js +1388 -0
- package/dist/safe-bash/command-chunks/{chunk-FXYWQ6S4.js → chunk-2EXV2ZLV.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-PFBJR2PY.js → chunk-2KRKKW5S.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-4DSJDVBM.js → chunk-32F3RBUW.js} +10 -749
- package/dist/safe-bash/command-chunks/{chunk-L3MLMXL4.js → chunk-3ZK5F23O.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-4QX6XCDD.js → chunk-4RNIZ3RT.js} +79 -0
- package/dist/safe-bash/command-chunks/{chunk-D7TADAYG.js → chunk-64LG3EVJ.js} +17 -0
- package/dist/safe-bash/command-chunks/{chunk-TOSM3T3A.js → chunk-6EASC5EC.js} +20 -9
- package/dist/safe-bash/command-chunks/{chunk-ZF3ZVGQC.js → chunk-7JRITHKW.js} +150 -80
- package/dist/safe-bash/command-chunks/{chunk-IJ3FXP4Q.js → chunk-A3ZX6SCY.js} +1 -1
- package/dist/safe-bash/{chunks/chunk-LD76P7AG.js → command-chunks/chunk-AKDMCNX4.js} +74 -39
- package/dist/safe-bash/command-chunks/{chunk-KSIGF4AG.js → chunk-BK4CMEE6.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-JUDOV5MJ.js → chunk-CBDVLMJB.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-XGMWWUHV.js → chunk-CZ5DAK4K.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-Z57TV6TC.js → chunk-EZ2DTOLI.js} +4 -2
- package/dist/safe-bash/command-chunks/{chunk-ADCGH6A7.js → chunk-FH3D75FC.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-WYJTWJZ5.js → chunk-G3G6W5ZE.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-3HDIDEUJ.js → chunk-GF54KE2M.js} +1 -1
- package/dist/safe-bash/command-chunks/chunk-H4LWTITX.js +169 -0
- package/dist/safe-bash/command-chunks/chunk-I2MQNBGR.js +145 -0
- package/dist/safe-bash/command-chunks/{chunk-Z7TYZG3A.js → chunk-IHHTTQX6.js} +5 -3
- package/dist/safe-bash/command-chunks/{chunk-5GRLAARV.js → chunk-IOXI5ZAJ.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-INDIFLBW.js → chunk-JTAGNROA.js} +4 -0
- package/dist/safe-bash/command-chunks/{chunk-Y5IHIAY3.js → chunk-MDPIOQUD.js} +12 -8
- package/dist/safe-bash/command-chunks/chunk-PGEYORBZ.js +25 -0
- package/dist/safe-bash/command-chunks/chunk-QI4MGIN6.js +6 -0
- package/dist/safe-bash/command-chunks/chunk-QM4UZF3C.js +753 -0
- package/dist/safe-bash/command-chunks/chunk-QTYZAWSB.js +91 -0
- package/dist/safe-bash/command-chunks/chunk-SNK7K3XW.js +90 -0
- package/dist/safe-bash/command-chunks/chunk-T5OLGM43.js +314 -0
- package/dist/safe-bash/command-chunks/chunk-TB7IFMUZ.js +802 -0
- package/dist/safe-bash/command-chunks/{chunk-YNT4ZJHW.js → chunk-TPPBPIWL.js} +3 -3
- package/dist/safe-bash/command-chunks/chunk-VMK4XVKO.js +82 -0
- package/dist/safe-bash/command-chunks/chunk-VNSJKXDU.js +130 -0
- package/dist/safe-bash/command-chunks/{chunk-2LP3VMPA.js → chunk-WFDW4XXD.js} +1 -17
- package/dist/safe-bash/command-chunks/chunk-WR37IS4O.js +318 -0
- package/dist/safe-bash/command-chunks/chunk-YFNTMH6Z.js +6 -0
- package/dist/safe-bash/commands/basic.js +148 -48
- package/dist/safe-bash/commands/bytes/compression/index.js +5 -6
- package/dist/safe-bash/commands/cmp.d.ts +2 -3
- package/dist/safe-bash/commands/cmp.js +2 -689
- package/dist/safe-bash/commands/csplit/index.browser.js +2 -2
- package/dist/safe-bash/commands/docx/index.browser.js +4 -47
- package/dist/safe-bash/commands/docx/index.d.ts +2 -24
- package/dist/safe-bash/commands/docx/index.js +2 -41
- package/dist/safe-bash/commands/docx/io.d.ts +1 -14
- package/dist/safe-bash/commands/docx/io.js +1 -15
- package/dist/safe-bash/commands/factor/index.browser.js +2 -2
- package/dist/safe-bash/commands/getopt/index.browser.js +2 -2
- package/dist/safe-bash/commands/hexdump/index.browser.js +2 -2
- package/dist/safe-bash/commands/iconv/index.browser.js +2 -2
- package/dist/safe-bash/commands/line-endings/index.browser.js +2 -2
- package/dist/safe-bash/commands/llm/command.d.ts +1 -4
- package/dist/safe-bash/commands/llm/command.js +1 -248
- package/dist/safe-bash/commands/llm/elevenlabs-stream.d.ts +1 -2
- package/dist/safe-bash/commands/llm/elevenlabs-stream.js +1 -117
- package/dist/safe-bash/commands/llm/elevenlabs.d.ts +1 -15
- package/dist/safe-bash/commands/llm/elevenlabs.js +1 -123
- package/dist/safe-bash/commands/llm/index.browser.js +20 -15
- package/dist/safe-bash/commands/llm/index.d.ts +1 -6
- package/dist/safe-bash/commands/llm/index.js +1 -4
- package/dist/safe-bash/commands/llm/mime.d.ts +1 -2
- package/dist/safe-bash/commands/llm/mime.js +1 -136
- package/dist/safe-bash/commands/llm/openai-http.d.ts +1 -8
- package/dist/safe-bash/commands/llm/openai-http.js +1 -143
- package/dist/safe-bash/commands/llm/openai-sse.d.ts +1 -3
- package/dist/safe-bash/commands/llm/openai-sse.js +1 -78
- package/dist/safe-bash/commands/llm/openai.d.ts +1 -14
- package/dist/safe-bash/commands/llm/openai.js +1 -288
- package/dist/safe-bash/commands/llm/providers/elevenlabs.d.ts +1 -1
- package/dist/safe-bash/commands/llm/providers/elevenlabs.js +1 -1
- package/dist/safe-bash/commands/llm/providers/index.browser.js +6 -6
- package/dist/safe-bash/commands/llm/providers/index.d.ts +1 -3
- package/dist/safe-bash/commands/llm/providers/index.js +1 -2
- package/dist/safe-bash/commands/llm/providers/openai.d.ts +1 -1
- package/dist/safe-bash/commands/llm/providers/openai.js +1 -1
- package/dist/safe-bash/commands/llm/providers/shared.d.ts +1 -23
- package/dist/safe-bash/commands/llm/providers/shared.js +1 -65
- package/dist/safe-bash/commands/llm/service.d.ts +1 -37
- package/dist/safe-bash/commands/llm/service.js +1 -151
- package/dist/safe-bash/commands/llm/types.d.ts +1 -52
- package/dist/safe-bash/commands/llm/types.js +1 -1
- package/dist/safe-bash/commands/mdq/index.browser.js +3 -3
- package/dist/safe-bash/commands/media/index.browser.js +1 -1
- package/dist/safe-bash/commands/network/index.browser.js +9 -9
- package/dist/safe-bash/commands/network/types.d.ts +2 -40
- package/dist/safe-bash/commands/node/index.browser.js +6 -8
- package/dist/safe-bash/commands/op/index.browser.js +3 -3
- package/dist/safe-bash/commands/op/index.js +12 -28
- package/dist/safe-bash/commands/pptx/index.d.ts +2 -28
- package/dist/safe-bash/commands/pptx/index.js +2 -152
- package/dist/safe-bash/commands/pr/index.browser.js +2 -2
- package/dist/safe-bash/commands/printf-float.d.ts +1 -0
- package/dist/safe-bash/commands/printf-float.js +48 -38
- package/dist/safe-bash/commands/printf-format.js +9 -6
- package/dist/safe-bash/commands/printf-quote.d.ts +3 -0
- package/dist/safe-bash/commands/printf-quote.js +62 -0
- package/dist/safe-bash/commands/printf-wide.d.ts +5 -0
- package/dist/safe-bash/commands/printf-wide.js +41 -0
- package/dist/safe-bash/commands/python/index.browser.js +8 -8
- package/dist/safe-bash/commands/python/worker.browser.js +2 -2
- package/dist/safe-bash/commands/truncate.d.ts +2 -3
- package/dist/safe-bash/commands/truncate.js +2 -686
- package/dist/safe-bash/commands/tsort/index.browser.js +2 -2
- package/dist/safe-bash/commands/xml/index.browser.js +2 -2
- package/dist/safe-bash/commands/yq/index.browser.js +3 -3
- package/dist/safe-bash/contracts/diagnostics.d.ts +2 -0
- package/dist/safe-bash/contracts/diagnostics.js +2 -0
- package/dist/safe-bash/contracts/runtime-control.d.ts +2 -0
- package/dist/safe-bash/contracts/runtime-control.js +2 -0
- package/dist/safe-bash/core.browser.d.ts +1 -1
- package/dist/safe-bash/core.browser.js +10645 -14065
- package/dist/safe-bash/core.d.ts +10 -1
- package/dist/safe-bash/core.js +0 -1
- package/dist/safe-bash/jobs.browser.js +5 -4
- package/dist/safe-bash/opt-in/commands/cmp/index.d.ts +6 -2
- package/dist/safe-bash/opt-in/commands/cmp/index.js +776 -79
- package/dist/safe-bash/opt-in/commands/cmp/options.d.ts +0 -12
- package/dist/safe-bash/opt-in/commands/cmp/options.js +0 -153
- package/dist/safe-bash/opt-in/commands/truncate/index.d.ts +8 -3
- package/dist/safe-bash/opt-in/commands/truncate/index.js +790 -272
- package/dist/safe-bash/opt-in/commands/truncate/sync.d.ts +1 -0
- package/dist/safe-bash/opt-in/commands/truncate/sync.js +60 -0
- package/dist/safe-bash/optional-host.browser.js +61 -80
- package/dist/safe-bash/optional-host.d.ts +3 -1
- package/dist/safe-bash/optional-host.js +3 -1
- package/dist/safe-bash/shell/runtime.js +44 -18
- package/dist/safe-bash/yq-browser/index.js +1 -1
- package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
- package/dist/safe-bash-checksum-engine/index.js +14 -2
- package/dist/safe-bash-command-bzip2/index.js +2 -1
- package/dist/safe-bash-command-cmp/index.d.ts +10 -0
- package/dist/safe-bash-command-cmp/index.js +796 -0
- package/dist/safe-bash-command-cmp/options.d.ts +12 -0
- package/dist/safe-bash-command-cmp/options.js +42 -0
- package/dist/safe-bash-command-csvcut/index.js +11 -8
- package/dist/safe-bash-command-csvgrep/index.js +35 -7
- package/dist/safe-bash-command-csvkit/codecs/python.js +4 -3
- package/dist/safe-bash-command-csvkit/codecs/utf8.js +3 -2
- package/dist/safe-bash-command-csvkit/index.js +80 -324
- package/dist/safe-bash-command-csvkit/python-regex.d.ts +5 -0
- package/dist/safe-bash-command-csvkit/python-regex.js +14 -0
- package/dist/safe-bash-command-csvkit/runtime.d.ts +1 -0
- package/dist/safe-bash-command-csvkit/sync-support.js +4 -2
- package/dist/safe-bash-command-diff3/index.js +3 -0
- package/dist/safe-bash-command-docx/LICENSE +21 -0
- package/dist/safe-bash-command-docx/index.d.ts +30 -0
- package/dist/safe-bash-command-docx/index.js +67 -0
- package/dist/safe-bash-command-docx/io.d.ts +14 -0
- package/dist/safe-bash-command-docx/io.js +26 -0
- package/dist/safe-bash-command-envsubst/index.js +34 -3
- package/dist/safe-bash-command-exiftool/index.js +3 -0
- package/dist/safe-bash-command-ffmpeg/index.js +8073 -7940
- package/dist/safe-bash-command-fold/family.js +1 -1
- package/dist/safe-bash-command-fold/index.js +1 -1
- package/dist/safe-bash-command-git/git_rust.wasm +0 -0
- package/dist/safe-bash-command-git/wasm.generated.js +1 -1
- package/dist/safe-bash-command-htmlq/index.js +5 -0
- package/dist/safe-bash-command-imagemagick/index.d.ts +25 -21
- package/dist/safe-bash-command-imagemagick/index.js +671 -273
- package/dist/safe-bash-command-llm/LICENSE +21 -0
- package/dist/safe-bash-command-llm/command.d.ts +5 -0
- package/dist/safe-bash-command-llm/command.js +14 -0
- package/dist/safe-bash-command-llm/configuration.d.ts +18 -0
- package/dist/safe-bash-command-llm/elevenlabs-stream.d.ts +2 -0
- package/dist/safe-bash-command-llm/elevenlabs-stream.js +7 -0
- package/dist/safe-bash-command-llm/elevenlabs.d.ts +15 -0
- package/dist/safe-bash-command-llm/elevenlabs.js +10 -0
- package/dist/safe-bash-command-llm/index.d.ts +10 -0
- package/dist/safe-bash-command-llm/index.js +46 -0
- package/dist/safe-bash-command-llm/mime.d.ts +2 -0
- package/dist/safe-bash-command-llm/mime.js +9 -0
- package/dist/safe-bash-command-llm/model-options.d.ts +3 -0
- package/dist/safe-bash-command-llm/openai-http.d.ts +8 -0
- package/dist/safe-bash-command-llm/openai-http.js +17 -0
- package/dist/safe-bash-command-llm/openai-sse.d.ts +3 -0
- package/dist/safe-bash-command-llm/openai-sse.js +8 -0
- package/dist/safe-bash-command-llm/openai.d.ts +14 -0
- package/dist/safe-bash-command-llm/openai.js +12 -0
- package/dist/safe-bash-command-llm/providers/elevenlabs.d.ts +1 -0
- package/dist/safe-bash-command-llm/providers/elevenlabs.js +11 -0
- package/dist/safe-bash-command-llm/providers/index.d.ts +3 -0
- package/dist/safe-bash-command-llm/providers/index.js +24 -0
- package/dist/safe-bash-command-llm/providers/openai.d.ts +1 -0
- package/dist/safe-bash-command-llm/providers/openai.js +13 -0
- package/dist/safe-bash-command-llm/providers/shared.d.ts +23 -0
- package/dist/safe-bash-command-llm/providers/shared.js +13 -0
- package/dist/safe-bash-command-llm/schemas.d.ts +2 -0
- package/dist/safe-bash-command-llm/service.d.ts +42 -0
- package/dist/safe-bash-command-llm/service.js +9 -0
- package/dist/safe-bash-command-llm/templates.d.ts +27 -0
- package/dist/safe-bash-command-llm/types.d.ts +87 -0
- package/dist/safe-bash-command-llm/types.js +6 -0
- package/dist/safe-bash-command-mmdc/command.d.ts +4 -0
- package/dist/safe-bash-command-mmdc/index.d.ts +1 -1
- package/dist/safe-bash-command-mmdc/index.js +7134 -6699
- package/dist/safe-bash-command-mmdc/layout.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/parser.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/png.d.ts +3 -0
- package/dist/safe-bash-command-mmdc/raster.d.ts +1 -0
- package/dist/safe-bash-command-mmdc/svg.d.ts +1 -0
- package/dist/safe-bash-command-op/index.js +19 -14
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.js +3 -3
- package/dist/safe-bash-command-pdfimages/index.d.ts +7 -1
- package/dist/safe-bash-command-pdfimages/index.js +210 -113
- package/dist/safe-bash-command-pdfinfo/index.d.ts +24 -20
- package/dist/safe-bash-command-pdfinfo/index.js +517 -241
- package/dist/safe-bash-command-pdftk/index.d.ts +7 -3
- package/dist/safe-bash-command-pdftk/index.js +261 -125
- package/dist/safe-bash-command-pdftoppm/index.d.ts +15 -7
- package/dist/safe-bash-command-pdftoppm/index.js +326 -189
- package/dist/safe-bash-command-pdftotext/index.d.ts +9 -5
- package/dist/safe-bash-command-pdftotext/index.js +237 -107
- package/dist/safe-bash-command-pptx/LICENSE +21 -0
- package/dist/safe-bash-command-pptx/index.d.ts +33 -0
- package/dist/safe-bash-command-pptx/index.js +168 -0
- package/dist/safe-bash-command-qpdf/index.d.ts +9 -3
- package/dist/safe-bash-command-qpdf/index.js +254 -130
- package/dist/safe-bash-command-sha512sum/index.js +12 -475
- package/dist/safe-bash-command-sips/index.d.ts +9 -5
- package/dist/safe-bash-command-sips/index.js +65 -46
- package/dist/safe-bash-command-soffice/index.d.ts +9 -3
- package/dist/safe-bash-command-soffice/index.js +66 -25
- package/dist/safe-bash-command-sqlite3/engine.d.ts +9 -0
- package/dist/safe-bash-command-sqlite3/index.d.ts +1 -0
- package/dist/safe-bash-command-sqlite3/index.js +851 -352
- package/dist/safe-bash-command-ssconvert/formats/xls.js +3 -3
- package/dist/safe-bash-command-ssconvert/index.js +147 -80
- package/dist/safe-bash-command-timeout/index.js +3 -3
- package/dist/safe-bash-command-truncate/index.d.ts +8 -3
- package/dist/safe-bash-command-truncate/index.js +790 -272
- package/dist/safe-bash-command-truncate/sync.d.ts +1 -0
- package/dist/safe-bash-command-truncate/sync.js +60 -0
- package/dist/safe-bash-command-wkhtmltopdf/index.js +239 -118
- package/dist/safe-bash-command-wkhtmltopdf/pdf-renderer.d.ts +1 -1
- package/dist/safe-bash-command-xxd/index.js +78 -20
- package/dist/safe-bash-command-xz/command.d.ts +4 -0
- package/dist/safe-bash-command-xz/index.d.ts +1 -1
- package/dist/safe-bash-command-xz/index.js +1 -1
- package/dist/safe-bash-compression-engine/bounded-codec.js +3 -3
- package/dist/safe-bash-compression-engine/codec-loader.js +2 -2
- package/dist/safe-bash-compression-engine/files.js +6 -6
- package/dist/safe-bash-compression-engine/index.js +5 -5
- package/dist/safe-bash-compression-engine/operand.js +6 -6
- package/dist/safe-bash-compression-engine/stream.js +5 -5
- package/dist/safe-bash-compression-engine/zstd-decode.js +4 -4
- package/dist/safe-bash-contracts/command.js +3 -3
- package/dist/safe-bash-contracts/default-executor.d.ts +5 -0
- package/dist/safe-bash-contracts/default-executor.js +37 -0
- package/dist/safe-bash-contracts/diagnostics.js +3 -3
- package/dist/safe-bash-contracts/escaping.js +9 -9
- package/dist/safe-bash-contracts/filesystem-descriptor.js +3 -3
- package/dist/safe-bash-contracts/filesystem-output.js +8 -8
- package/dist/safe-bash-contracts/http.d.ts +41 -0
- package/dist/safe-bash-contracts/http.js +6 -0
- package/dist/safe-bash-contracts/index.js +21 -19
- package/dist/safe-bash-contracts/io.d.ts +12 -0
- package/dist/safe-bash-contracts/io.js +4 -1
- package/dist/safe-bash-contracts/output.js +3 -2
- package/dist/safe-bash-contracts/runtime-control.js +2 -2
- package/dist/safe-bash-contracts/signals.js +1 -1
- package/dist/safe-bash-contracts/yield.d.ts +1 -0
- package/dist/safe-bash-contracts/yield.js +3 -1
- package/dist/safe-bash-csv-engine/index.d.ts +10 -1
- package/dist/safe-bash-csv-engine/index.js +78 -6
- package/dist/safe-bash-io-engine/commands/search/requirements.js +3 -3
- package/dist/safe-bash-io-engine/commands/text-programs/shared.js +3 -3
- package/dist/safe-bash-io-engine/gnu-information.d.ts +1 -1
- package/dist/safe-bash-io-engine/gnu-information.js +1 -1
- package/dist/safe-bash-io-engine/internal.d.ts +1 -1
- package/dist/safe-bash-io-engine/internal.js +2 -2
- package/dist/safe-bash-query-engine/index.js +5 -5
- package/dist/safe-bash-query-engine/interpreter.js +3 -3
- package/dist/safe-bash-query-engine/query-core.js +5 -5
- package/package.json +2 -2
- package/dist/safe-bash/chunks/chunk-2G2T5MEM.js +0 -14
- package/dist/safe-bash/chunks/chunk-FJZNUUOQ.js +0 -81
- package/dist/safe-bash/chunks/chunk-GJWUEOT6.js +0 -14
- package/dist/safe-bash/chunks/chunk-LAPF2XE6.js +0 -14
- package/dist/safe-bash/chunks/chunk-O6356Z27.js +0 -37
- package/dist/safe-bash/chunks/chunk-S2LSZFZ6.js +0 -758
- package/dist/safe-bash/chunks/chunk-T3VDYWKZ.js +0 -21
- package/dist/safe-bash/chunks/chunk-VYW4Q6KF.js +0 -12
- package/dist/safe-bash/chunks/chunk-WHURJBET.js +0 -409
- package/dist/safe-bash/opt-in/commands/cmp/compare.js +0 -95
- package/dist/safe-bash/opt-in/commands/cmp/io.js +0 -218
- package/dist/safe-bash/command-chunks/{chunk-RTOJNFFL.js → chunk-KNI4GRXF.js} +7 -7
- package/dist/safe-bash/command-chunks/{chunk-DEH3CMGL.js → chunk-QJ3ONEBI.js} +3 -3
|
@@ -1,99 +1,796 @@
|
|
|
1
|
-
import { commandRuntimeIdentity } from "@poe-platform/safe-bash/contracts";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { commandRuntimeIdentity, FsError, getCommandArguments, isFsError } from "@poe-platform/safe-bash/contracts";
|
|
2
|
+
import { yieldTurn } from "@poe-platform/safe-bash/contracts/yield";
|
|
3
|
+
import { assertCommandRequirements } from "@poe-platform/safe-bash/contracts/command-requirements";
|
|
4
|
+
import { PublicDiagnostic, publicDiagnosticMessage } from "@poe-platform/safe-bash/contracts/diagnostics";
|
|
5
|
+
import { ByteInputBudget } from "@poe-platform/safe-bash/optional-host";
|
|
6
|
+
import { registerDefaultExecutor, output, pathOf, UsageError } from "@poe-platform/safe-bash/optional-host";
|
|
7
|
+
import { inputRequirements } from "@poe-platform/safe-bash/optional-host";
|
|
8
|
+
import { compareCopyIdentity, compareObservedEntries } from "@poe-platform/safe-bash/contracts/filesystem-identity";
|
|
9
|
+
import { limitsFor, quote } from "./options.js";
|
|
10
|
+
const defaultBlockBytes = 4096;
|
|
11
|
+
const maxCount = 18446744073709551616n;
|
|
12
|
+
function byteCount(text, option = "bytes", legacy = true) {
|
|
13
|
+
const invalid = () => { throw new UsageError(`invalid --${option} value '${text}'`); };
|
|
14
|
+
let position = 0;
|
|
15
|
+
while (text[position] === " " || text.charCodeAt(position) >= 9 && text.charCodeAt(position) <= 13)
|
|
16
|
+
position++;
|
|
17
|
+
if (text[position] === "+")
|
|
18
|
+
position++;
|
|
19
|
+
let base = 10;
|
|
20
|
+
if (text[position] === "0") {
|
|
21
|
+
base = 8;
|
|
22
|
+
if (text[position + 1]?.toLowerCase() === "x") {
|
|
23
|
+
base = 16;
|
|
24
|
+
position += 2;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const start = position;
|
|
28
|
+
let count = 0n;
|
|
29
|
+
const maximum = option === "bytes" ? 18446744073709551615n : 9223372036854775807n;
|
|
30
|
+
while (position < text.length) {
|
|
31
|
+
const digit = "0123456789abcdef".indexOf(text[position].toLowerCase());
|
|
32
|
+
if (digit < 0 || digit >= base)
|
|
33
|
+
break;
|
|
34
|
+
count = count * BigInt(base) + BigInt(digit);
|
|
35
|
+
if (legacy && count > maximum)
|
|
36
|
+
invalid();
|
|
37
|
+
if (!legacy && count > 9223372036854775807n)
|
|
38
|
+
count = 9223372036854775808n;
|
|
39
|
+
position++;
|
|
40
|
+
}
|
|
41
|
+
const suffix = text.slice(position);
|
|
42
|
+
if (position === start) {
|
|
43
|
+
if (position !== 0 || !"kKMGTPEZY".includes(suffix[0] ?? " "))
|
|
44
|
+
invalid();
|
|
45
|
+
count = 1n;
|
|
46
|
+
}
|
|
47
|
+
if (suffix) {
|
|
48
|
+
const power = "KMGTPEZY".indexOf(suffix[0] === "k" ? "K" : suffix[0]) + 1;
|
|
49
|
+
if (!power || !["", "B", "D", "iB"].includes(suffix.slice(1)))
|
|
50
|
+
invalid();
|
|
51
|
+
count *= (suffix.endsWith("B") && !suffix.endsWith("iB") || suffix.endsWith("D") ? 1000n : 1024n) ** BigInt(power);
|
|
52
|
+
}
|
|
53
|
+
if (legacy && count > maximum)
|
|
54
|
+
invalid();
|
|
55
|
+
return !legacy && count > 9223372036854775807n ? 9223372036854775808n : count;
|
|
56
|
+
}
|
|
57
|
+
function parse(context, legacy) {
|
|
58
|
+
const parsed = { names: [], skips: [0n, 0n], limit: maxCount, silent: false, verbose: false, printBytes: false };
|
|
59
|
+
const long = { "print-bytes": "b", "print-chars": "c", "ignore-initial": "i", verbose: "l", bytes: "n", silent: "s", quiet: "s", version: "v", help: "help" };
|
|
60
|
+
const operands = [];
|
|
61
|
+
const argumentsWithBytes = getCommandArguments(context);
|
|
62
|
+
const args = context.args.map((_argument, index) => {
|
|
63
|
+
const bytes = argumentsWithBytes.bytes(index);
|
|
64
|
+
return Array.from(bytes, byte => String.fromCharCode(byte)).join("");
|
|
65
|
+
});
|
|
66
|
+
let ended = false;
|
|
67
|
+
const apply = (key, argument) => {
|
|
68
|
+
if (key === "s" || key === "l") {
|
|
69
|
+
if (key === "s" ? parsed.verbose : parsed.silent)
|
|
70
|
+
throw new UsageError("options -l and -s are incompatible");
|
|
71
|
+
if (key === "s")
|
|
72
|
+
parsed.silent = true;
|
|
73
|
+
else
|
|
74
|
+
parsed.verbose = true;
|
|
75
|
+
}
|
|
76
|
+
else if (key === "b" || key === "c")
|
|
77
|
+
parsed.printBytes = true;
|
|
78
|
+
else if (key === "n") {
|
|
79
|
+
const next = byteCount(argument, "bytes", legacy);
|
|
80
|
+
if (next < parsed.limit)
|
|
81
|
+
parsed.limit = next;
|
|
82
|
+
}
|
|
83
|
+
else if (key === "i") {
|
|
84
|
+
const delimiter = argument.indexOf(":");
|
|
85
|
+
const first = delimiter < 0 ? argument : argument.slice(0, delimiter);
|
|
86
|
+
let firstSkip;
|
|
87
|
+
try {
|
|
88
|
+
firstSkip = byteCount(first, "ignore-initial", legacy);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new UsageError(`invalid --ignore-initial value '${argument}'`);
|
|
92
|
+
}
|
|
93
|
+
if (firstSkip > parsed.skips[0])
|
|
94
|
+
parsed.skips[0] = firstSkip;
|
|
95
|
+
const secondSkip = delimiter < 0 ? firstSkip : byteCount(argument.slice(delimiter + 1), "ignore-initial", legacy);
|
|
96
|
+
if (secondSkip > parsed.skips[1])
|
|
97
|
+
parsed.skips[1] = secondSkip;
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
parsed.information = key === "v" ? "version" : "help";
|
|
101
|
+
};
|
|
102
|
+
for (let index = 0; index < args.length; index++) {
|
|
103
|
+
const argument = args[index];
|
|
104
|
+
if (ended || argument === "-" || !argument.startsWith("-")) {
|
|
105
|
+
operands.push(argument);
|
|
106
|
+
if (Object.hasOwn(context.env, "POSIXLY_CORRECT"))
|
|
107
|
+
ended = true;
|
|
108
|
+
}
|
|
109
|
+
else if (argument === "--")
|
|
110
|
+
ended = true;
|
|
111
|
+
else if (argument.startsWith("--")) {
|
|
112
|
+
const equals = argument.indexOf("=");
|
|
113
|
+
const name = argument.slice(2, equals < 0 ? undefined : equals);
|
|
114
|
+
const matches = Object.keys(long).filter(candidate => candidate.startsWith(name));
|
|
115
|
+
const selected = Object.hasOwn(long, name) ? name : matches[0];
|
|
116
|
+
if (!Object.hasOwn(long, name) && matches.length > 1 && new Set(matches.map(match => long[match])).size > 1) {
|
|
117
|
+
throw new UsageError(`option '${argument}' is ambiguous; possibilities: ${matches.map(match => `'--${match}'`).join(" ")}`);
|
|
118
|
+
}
|
|
119
|
+
if (!selected)
|
|
120
|
+
throw new UsageError(`unrecognized option '${argument}'`);
|
|
121
|
+
const key = long[selected];
|
|
122
|
+
let value;
|
|
123
|
+
if (key === "i" || key === "n") {
|
|
124
|
+
value = equals < 0 ? args[++index] : argument.slice(equals + 1);
|
|
125
|
+
if (value === undefined)
|
|
126
|
+
throw new UsageError(`option '--${selected}' requires an argument`);
|
|
127
|
+
}
|
|
128
|
+
else if (equals >= 0)
|
|
129
|
+
throw new UsageError(`option '--${selected}' doesn't allow an argument`);
|
|
130
|
+
apply(key, value);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
for (let offset = 1; offset < argument.length; offset++) {
|
|
134
|
+
const key = argument[offset];
|
|
135
|
+
if (!"bcilnsv".includes(key))
|
|
136
|
+
throw new UsageError(`invalid option -- '${key}'`);
|
|
137
|
+
let value;
|
|
138
|
+
if (key === "i" || key === "n") {
|
|
139
|
+
value = argument.slice(offset + 1) || args[++index];
|
|
140
|
+
if (value === undefined)
|
|
141
|
+
throw new UsageError(`option requires an argument -- '${key}'`);
|
|
142
|
+
offset = argument.length;
|
|
143
|
+
}
|
|
144
|
+
apply(key, value);
|
|
145
|
+
if (parsed.information)
|
|
146
|
+
return parsed;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (parsed.information)
|
|
150
|
+
return parsed;
|
|
151
|
+
}
|
|
152
|
+
if (!operands.length)
|
|
153
|
+
throw new UsageError(`missing operand after '${args.at(-1) ?? "cmp"}'`);
|
|
154
|
+
parsed.names = [operands[0], operands[1] ?? "-"];
|
|
155
|
+
for (const index of [0, 1]) {
|
|
156
|
+
if (operands[index + 2] !== undefined) {
|
|
157
|
+
const next = byteCount(operands[index + 2], "ignore-initial", legacy);
|
|
158
|
+
if (next > parsed.skips[index])
|
|
159
|
+
parsed.skips[index] = next;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (operands.length > 4)
|
|
163
|
+
throw new UsageError(`extra operand '${operands[4]}'`);
|
|
164
|
+
return parsed;
|
|
165
|
+
}
|
|
166
|
+
async function observe(operation, signal) {
|
|
167
|
+
signal.throwIfAborted();
|
|
168
|
+
return new Promise((resolve, reject) => {
|
|
169
|
+
const abort = () => { signal.removeEventListener("abort", abort); reject(signal.reason); };
|
|
170
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
171
|
+
Promise.resolve().then(() => { signal.throwIfAborted(); return operation(); }).then(value => {
|
|
172
|
+
signal.removeEventListener("abort", abort);
|
|
173
|
+
resolve(value);
|
|
174
|
+
}, error => { signal.removeEventListener("abort", abort); reject(error); });
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
class InvocationClosed extends Error {
|
|
178
|
+
}
|
|
179
|
+
class InputError extends PublicDiagnostic {
|
|
180
|
+
suppressInSilent;
|
|
181
|
+
constructor(message, suppressInSilent) {
|
|
182
|
+
super(message);
|
|
183
|
+
this.suppressInSilent = suppressInSilent;
|
|
10
184
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
185
|
+
}
|
|
186
|
+
function inputError(error, name, opening = false) {
|
|
187
|
+
if (!(error instanceof FsError))
|
|
188
|
+
return error;
|
|
189
|
+
const messages = {
|
|
190
|
+
EACCES: "Permission denied", EBADF: "Bad file descriptor", EIO: "Input/output error", EISDIR: "Is a directory",
|
|
191
|
+
ELOOP: "Too many levels of symbolic links", ENAMETOOLONG: "File name too long", ENOENT: "No such file or directory",
|
|
192
|
+
ENOTDIR: "Not a directory", ENOTSUP: "Operation not supported", EPERM: "Operation not permitted",
|
|
193
|
+
};
|
|
194
|
+
const detail = messages[error.code];
|
|
195
|
+
return detail ? new InputError(`${name}: ${detail}`, opening) : error;
|
|
196
|
+
}
|
|
197
|
+
function printByte(byte) {
|
|
198
|
+
const prefix = byte >= 128 ? "M-" : "";
|
|
199
|
+
const character = byte & 127;
|
|
200
|
+
return prefix + (character < 32 ? `^${String.fromCharCode(character + 64)}` : character === 127 ? "^?" : String.fromCharCode(character));
|
|
201
|
+
}
|
|
202
|
+
async function discardsOutput(context) {
|
|
203
|
+
if (!context.stdoutFile)
|
|
204
|
+
return false;
|
|
205
|
+
const options = { signal: context.signal };
|
|
206
|
+
try {
|
|
207
|
+
const paths = [context.stdoutFile.path, "/dev/null"];
|
|
208
|
+
for (const path of paths) {
|
|
209
|
+
const capabilities = await context.fs.capabilitiesFor?.(path, options) ?? context.fs.capabilities;
|
|
14
210
|
context.signal.throwIfAborted();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
211
|
+
if (capabilities.stat === false)
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
const target = await context.fs.stat(paths[0], options);
|
|
215
|
+
const empty = await context.fs.stat(paths[1], options);
|
|
216
|
+
return await compareObservedEntries(context.fs, paths[0], target, context.fs, paths[1], empty, options) === "same";
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
context.signal.throwIfAborted();
|
|
220
|
+
if (error instanceof FsError)
|
|
221
|
+
return false;
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
class Cursor {
|
|
226
|
+
name;
|
|
227
|
+
context;
|
|
228
|
+
budget;
|
|
229
|
+
signal;
|
|
230
|
+
chargeChunk;
|
|
231
|
+
blockBytes;
|
|
232
|
+
limits;
|
|
233
|
+
legacy;
|
|
234
|
+
bytes = new Uint8Array();
|
|
235
|
+
offset = 0;
|
|
236
|
+
size = Infinity;
|
|
237
|
+
stat;
|
|
238
|
+
position = 0n;
|
|
239
|
+
skip = 0;
|
|
240
|
+
retained;
|
|
241
|
+
requestBytes = defaultBlockBytes;
|
|
242
|
+
reader;
|
|
243
|
+
iterator;
|
|
244
|
+
source;
|
|
245
|
+
finished = false;
|
|
246
|
+
retirement;
|
|
247
|
+
handle;
|
|
248
|
+
acquisition;
|
|
249
|
+
handleClosing;
|
|
250
|
+
operations = new Set();
|
|
251
|
+
constructor(name, context, budget, signal, chargeChunk, blockBytes, limits, legacy) {
|
|
252
|
+
this.name = name;
|
|
253
|
+
this.context = context;
|
|
254
|
+
this.budget = budget;
|
|
255
|
+
this.signal = signal;
|
|
256
|
+
this.chargeChunk = chargeChunk;
|
|
257
|
+
this.blockBytes = blockBytes;
|
|
258
|
+
this.limits = limits;
|
|
259
|
+
this.legacy = legacy;
|
|
260
|
+
}
|
|
261
|
+
async open(limit, skip) {
|
|
262
|
+
this.signal.throwIfAborted();
|
|
263
|
+
const numericSkip = skip > BigInt(Number.MAX_SAFE_INTEGER) ? Number.MAX_SAFE_INTEGER : Number(skip);
|
|
264
|
+
this.skip = numericSkip;
|
|
265
|
+
if (this.name === "-") {
|
|
266
|
+
const input = this.context.stdinInput;
|
|
267
|
+
this.stat = input?.stat;
|
|
268
|
+
this.position = BigInt(input?.position ?? 0);
|
|
269
|
+
if (this.stat?.type === "file" && Number.isSafeInteger(this.stat.size) && this.stat.size >= 0) {
|
|
270
|
+
const remaining = BigInt(this.stat.size) - this.position - skip;
|
|
271
|
+
this.size = remaining > 0n ? Number(remaining) : 0;
|
|
272
|
+
}
|
|
273
|
+
this.source = input ? () => ({ [Symbol.asyncIterator]: () => ({ next: () => input.read(this.requestBytes, this.signal) }) }) : () => this.context.stdin;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
let name;
|
|
18
277
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
278
|
+
name = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(Uint8Array.from(this.name, unit => unit.charCodeAt(0)));
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
throw new FsError("ENOENT");
|
|
282
|
+
}
|
|
283
|
+
const path = pathOf(this.context, name);
|
|
284
|
+
const capabilities = await this.context.fs.capabilitiesFor?.(path, { signal: this.signal }) ?? this.context.fs.capabilities;
|
|
285
|
+
this.signal.throwIfAborted();
|
|
286
|
+
assertCommandRequirements({ ...this.context, signal: this.signal }, inputRequirements, ["file"], capabilities);
|
|
287
|
+
let stat;
|
|
288
|
+
if (capabilities.stat !== false) {
|
|
289
|
+
try {
|
|
290
|
+
stat = await observe(() => this.context.fs.stat(path, { signal: this.signal }), this.signal);
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
this.signal.throwIfAborted();
|
|
294
|
+
if (!isFsError(error, "ENOTSUP"))
|
|
295
|
+
throw error;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
this.signal.throwIfAborted();
|
|
299
|
+
if (stat?.type !== "directory" && capabilities.retainedRead === true && this.context.fs.openReadFile) {
|
|
300
|
+
this.acquisition = this.context.fs.openReadFile(path, { signal: this.signal }).then(handle => { this.handle = handle; return handle; });
|
|
301
|
+
try {
|
|
302
|
+
const handle = await this.acquisition;
|
|
303
|
+
this.signal.throwIfAborted();
|
|
304
|
+
stat = await this.work(() => handle.stat({ signal: this.signal }));
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
this.signal.throwIfAborted();
|
|
308
|
+
if (this.handle || !isFsError(error, "ENOTSUP"))
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (!this.handle && capabilities.access !== false) {
|
|
313
|
+
try {
|
|
314
|
+
await observe(() => this.context.fs.access(path, 4, { signal: this.signal }), this.signal);
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
this.signal.throwIfAborted();
|
|
318
|
+
if (!isFsError(error, "ENOTSUP"))
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
this.signal.throwIfAborted();
|
|
323
|
+
if (!stat && limit === 0)
|
|
324
|
+
throw new FsError("ENOTSUP", { path, message: "zero-byte comparison requires metadata admission" });
|
|
325
|
+
this.stat = stat;
|
|
326
|
+
this.position = skip;
|
|
327
|
+
if (stat?.type === "file" && Number.isSafeInteger(stat.size) && stat.size >= 0) {
|
|
328
|
+
const remaining = BigInt(stat.size) - skip;
|
|
329
|
+
this.size = remaining > 0n ? Number(remaining) : 0;
|
|
330
|
+
}
|
|
331
|
+
if (limit === 0 && (this.handle || Number.isFinite(this.size) || this.skip === 0)) {
|
|
332
|
+
this.skip = 0;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (!this.legacy && stat?.type === "file" && skip > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
336
|
+
this.skip = 0;
|
|
337
|
+
this.source = () => ({ async *[Symbol.asyncIterator]() { } });
|
|
338
|
+
}
|
|
339
|
+
else if (this.handle) {
|
|
340
|
+
const handle = this.handle;
|
|
341
|
+
let position = Number.isFinite(this.size) ? Math.min(numericSkip, stat.size) : numericSkip;
|
|
342
|
+
this.skip = 0;
|
|
343
|
+
this.source = () => ({ [Symbol.asyncIterator]: () => ({ next: async () => {
|
|
344
|
+
const bytes = await this.work(() => handle.read(position, this.requestBytes, { signal: this.signal }));
|
|
345
|
+
if (!(bytes instanceof Uint8Array) || bytes.length > this.requestBytes)
|
|
346
|
+
throw new FsError("EIO", { path, message: "invalid retained read size" });
|
|
347
|
+
position += bytes.length;
|
|
348
|
+
return bytes.length ? { done: false, value: bytes } : { done: true, value: undefined };
|
|
349
|
+
} }) });
|
|
350
|
+
}
|
|
351
|
+
else if (this.context.fs.readStream && capabilities.streamingRead !== false) {
|
|
352
|
+
const start = Number.isFinite(this.size) ? Math.min(numericSkip, stat.size) : 0;
|
|
353
|
+
if (Number.isFinite(this.size))
|
|
354
|
+
this.skip = 0;
|
|
355
|
+
this.source = () => this.context.fs.readStream(path, { signal: this.signal, chunkSize: Math.min(this.blockBytes, this.limits.maxChunkBytes, limit || this.skip),
|
|
356
|
+
...(start ? { start } : {}),
|
|
357
|
+
...(limit === Infinity || this.skip ? {} : { endExclusive: Math.min(Number.MAX_SAFE_INTEGER, start + limit) }) });
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
if (capabilities.read === false)
|
|
361
|
+
throw new FsError("ENOTSUP", { syscall: "readFile", path });
|
|
362
|
+
const context = this.context;
|
|
363
|
+
const signal = this.signal;
|
|
364
|
+
const maximum = this.limits.maxFallbackBytes;
|
|
365
|
+
if (!this.legacy && (!stat || !Number.isSafeInteger(stat.size) || stat.size < 0 || stat.size > maximum)) {
|
|
366
|
+
throw new InputError(this.name + ": bounded comparison requires readStream or a file within maxFallbackBytes", false);
|
|
367
|
+
}
|
|
368
|
+
const chunkBytes = this.limits.maxChunkBytes;
|
|
369
|
+
this.source = () => ({ async *[Symbol.asyncIterator]() {
|
|
370
|
+
const bytes = await context.fs.readFile(path, { signal, ...(maximum === Infinity ? {} : { maxBytes: maximum }) });
|
|
371
|
+
if (bytes.byteLength > maximum)
|
|
372
|
+
throw new FsError("EFBIG", { message: "cmp fallback byte limit exceeded" });
|
|
373
|
+
for (let offset = 0; offset < bytes.length; offset += chunkBytes)
|
|
374
|
+
yield bytes.subarray(offset, offset + chunkBytes);
|
|
375
|
+
} });
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async prepare() {
|
|
380
|
+
const input = this.name === "-" ? this.context.stdinInput : undefined;
|
|
381
|
+
if (input?.seek) {
|
|
382
|
+
this.signal.throwIfAborted();
|
|
383
|
+
const targetPosition = Math.min(Number.MAX_SAFE_INTEGER, input.position + this.skip);
|
|
384
|
+
this.position = BigInt(input.position) + BigInt(this.skip);
|
|
385
|
+
if (this.skip) {
|
|
386
|
+
try {
|
|
387
|
+
await input.seek(targetPosition, this.signal);
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
throw inputError(error, this.name);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
this.signal.throwIfAborted();
|
|
394
|
+
this.skip = 0;
|
|
395
|
+
if (this.stat?.type === "file") {
|
|
396
|
+
const remaining = BigInt(this.stat.size) - this.position;
|
|
397
|
+
this.size = remaining > 0n ? Number(remaining) : 0;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async fill(remaining) {
|
|
402
|
+
this.signal.throwIfAborted();
|
|
403
|
+
if (remaining === 0 && this.skip === 0)
|
|
404
|
+
return false;
|
|
405
|
+
if (!this.reader) {
|
|
406
|
+
try {
|
|
407
|
+
this.iterator = this.source()[Symbol.asyncIterator]();
|
|
54
408
|
}
|
|
55
409
|
catch (error) {
|
|
56
|
-
|
|
410
|
+
throw inputError(error, this.name);
|
|
57
411
|
}
|
|
412
|
+
this.reader = this.budget.read({ [Symbol.asyncIterator]: () => ({
|
|
413
|
+
next: async () => {
|
|
414
|
+
let result;
|
|
415
|
+
try {
|
|
416
|
+
result = await this.iterator.next();
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
throw inputError(error, this.name);
|
|
420
|
+
}
|
|
421
|
+
if (result.done)
|
|
422
|
+
this.finished = true;
|
|
423
|
+
return result;
|
|
424
|
+
},
|
|
425
|
+
return: async () => { await this.retire(); return { done: true, value: undefined }; },
|
|
426
|
+
}) }, this.signal)[Symbol.asyncIterator]();
|
|
427
|
+
}
|
|
428
|
+
while (this.offset === this.bytes.length) {
|
|
429
|
+
this.signal.throwIfAborted();
|
|
430
|
+
if (remaining === 0 && this.skip === 0)
|
|
431
|
+
return false;
|
|
432
|
+
this.requestBytes = Math.min(this.blockBytes, this.limits.maxChunkBytes, this.skip || remaining);
|
|
433
|
+
const item = await this.reader.next();
|
|
434
|
+
if (item.done)
|
|
435
|
+
return false;
|
|
436
|
+
await this.chargeChunk();
|
|
437
|
+
if (!this.legacy && item.value.byteLength >= 65536)
|
|
438
|
+
await yieldTurn(this.signal);
|
|
439
|
+
if (item.value.byteLength > this.limits.maxChunkBytes)
|
|
440
|
+
throw new FsError("EFBIG", { message: "cmp chunk byte limit exceeded" });
|
|
441
|
+
this.bytes = new Uint8Array(item.value);
|
|
442
|
+
this.offset = Math.min(this.skip, this.bytes.length);
|
|
443
|
+
this.skip -= this.offset;
|
|
444
|
+
}
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
async block(count) {
|
|
448
|
+
if (this.retained) {
|
|
449
|
+
this.bytes = this.retained.bytes;
|
|
450
|
+
this.offset = this.retained.offset;
|
|
451
|
+
}
|
|
452
|
+
const bytes = new Uint8Array(count);
|
|
453
|
+
let size = 0;
|
|
454
|
+
while (size < count && await this.fill(count - size)) {
|
|
455
|
+
const length = Math.min(count - size, this.bytes.length - this.offset);
|
|
456
|
+
bytes.set(this.bytes.subarray(this.offset, this.offset + length), size);
|
|
457
|
+
this.offset += length;
|
|
458
|
+
size += length;
|
|
459
|
+
}
|
|
460
|
+
this.retained = { bytes: this.bytes, offset: this.offset };
|
|
461
|
+
this.bytes = bytes.subarray(0, size);
|
|
462
|
+
this.offset = 0;
|
|
463
|
+
}
|
|
464
|
+
retire() {
|
|
465
|
+
this.retirement ??= Promise.resolve().then(async () => {
|
|
58
466
|
try {
|
|
59
|
-
|
|
467
|
+
if (!this.finished)
|
|
468
|
+
await this.iterator?.return?.();
|
|
60
469
|
}
|
|
61
470
|
catch (error) {
|
|
62
|
-
|
|
471
|
+
throw !this.legacy && error instanceof Error ? new InputError(this.name + ": " + error.message, false) : inputError(error, this.name);
|
|
63
472
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
473
|
+
});
|
|
474
|
+
return this.retirement;
|
|
475
|
+
}
|
|
476
|
+
work(operation) {
|
|
477
|
+
this.signal.throwIfAborted();
|
|
478
|
+
if (this.handleClosing)
|
|
479
|
+
throw new FsError("EBADF", { path: this.name });
|
|
480
|
+
const pending = Promise.resolve().then(() => {
|
|
481
|
+
this.signal.throwIfAborted();
|
|
482
|
+
return operation();
|
|
483
|
+
});
|
|
484
|
+
this.operations.add(pending);
|
|
485
|
+
void pending.then(() => { this.operations.delete(pending); }, () => { this.operations.delete(pending); });
|
|
486
|
+
return pending;
|
|
487
|
+
}
|
|
488
|
+
async close() {
|
|
489
|
+
this.handleClosing ??= Promise.resolve().then(async () => {
|
|
490
|
+
await this.acquisition?.catch(() => undefined);
|
|
491
|
+
await Promise.allSettled(this.operations);
|
|
492
|
+
try {
|
|
493
|
+
await this.handle?.close();
|
|
74
494
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
throw inputError(error, this.name);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
const results = await Promise.allSettled([this.retire(), this.reader?.return?.(), this.handleClosing]);
|
|
500
|
+
this.bytes = new Uint8Array();
|
|
501
|
+
for (const result of results)
|
|
502
|
+
if (result.status === "rejected")
|
|
503
|
+
throw result.reason;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
async function compare(context, parsed, blockBytes, limits, legacy, preferredBlock) {
|
|
507
|
+
const { names, skips, silent, verbose, printBytes } = parsed;
|
|
508
|
+
const limit = parsed.limit >= maxCount ? Infinity : parsed.limit > BigInt(Number.MAX_SAFE_INTEGER) ? Number.MAX_SAFE_INTEGER : Number(parsed.limit);
|
|
509
|
+
const controller = new AbortController();
|
|
510
|
+
const signal = AbortSignal.any([context.signal, controller.signal]);
|
|
511
|
+
const budget = new ByteInputBudget(Infinity);
|
|
512
|
+
let chunks = 0;
|
|
513
|
+
const chargeChunk = async () => {
|
|
514
|
+
if (++chunks % 64 === 0)
|
|
515
|
+
await yieldTurn(signal);
|
|
516
|
+
};
|
|
517
|
+
const cursors = names.map(name => new Cursor(name, context, budget, signal, chargeChunk, blockBytes, limits, legacy));
|
|
518
|
+
let closing;
|
|
519
|
+
const cleanupErrors = [];
|
|
520
|
+
const close = () => {
|
|
521
|
+
if (!closing) {
|
|
522
|
+
controller.abort(legacy ? new FsError("EPIPE", { message: "cmp input closed" }) : new InvocationClosed("cmp invocation closed"));
|
|
523
|
+
closing = Promise.allSettled(cursors.map(cursor => cursor.close())).then(results => {
|
|
524
|
+
for (const result of results)
|
|
525
|
+
if (result.status === "rejected")
|
|
526
|
+
cleanupErrors.push(result.reason);
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
return closing;
|
|
530
|
+
};
|
|
531
|
+
context.registerCleanup?.(close);
|
|
532
|
+
let duplicateStdinClose = false;
|
|
533
|
+
const run = async () => {
|
|
534
|
+
assertCommandRequirements({ ...context, signal }, inputRequirements, [names.some(name => name !== "-") ? "file" : "stdin"]);
|
|
535
|
+
const sharedStdin = names.every(name => name === "-");
|
|
536
|
+
if (sharedStdin && (!legacy || skips[0] === skips[1] || !context.stdinInput?.seek && context.stdinInput?.stat?.type !== "file"))
|
|
537
|
+
return 0;
|
|
538
|
+
for (const index of [0, 1]) {
|
|
539
|
+
const cursor = cursors[index];
|
|
540
|
+
try {
|
|
541
|
+
await cursor.open(limit, skips[index]);
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
throw inputError(error, cursor.name, true);
|
|
545
|
+
}
|
|
546
|
+
if (index === 0 && names[0] === names[1] && skips[0] === skips[1] && cursor.stat)
|
|
547
|
+
return 0;
|
|
548
|
+
}
|
|
549
|
+
const [left, right] = cursors;
|
|
550
|
+
if (!legacy && preferredBlock) {
|
|
551
|
+
blockBytes = left.stat?.ioBlockSize ?? 65536;
|
|
552
|
+
if (!Number.isSafeInteger(blockBytes) || blockBytes < 1)
|
|
553
|
+
throw new InputError(left.name + ": invalid preferred I/O block size", false);
|
|
554
|
+
}
|
|
555
|
+
for (const cursor of cursors)
|
|
556
|
+
await cursor.prepare();
|
|
557
|
+
if (!sharedStdin && left.position === right.position && compareCopyIdentity(left.stat, right.stat) === "same")
|
|
558
|
+
return 0;
|
|
559
|
+
if (silent && Number.isFinite(left.size) && Number.isFinite(right.size) && left.size !== right.size && Math.min(left.size, right.size) < limit)
|
|
560
|
+
return 1;
|
|
561
|
+
for (const cursor of cursors)
|
|
562
|
+
if (cursor.stat?.type === "directory")
|
|
563
|
+
throw inputError(new FsError("EISDIR"), cursor.name);
|
|
564
|
+
const noStdout = !silent && await discardsOutput(context);
|
|
565
|
+
const known = Math.min(left.size, right.size, limit);
|
|
566
|
+
const width = Number.isFinite(known) ? String(known).length : 19;
|
|
567
|
+
duplicateStdinClose = sharedStdin;
|
|
568
|
+
let compared = 0;
|
|
569
|
+
let newlines = 0;
|
|
570
|
+
let lastByte = -1;
|
|
571
|
+
let different = false;
|
|
572
|
+
let report = "";
|
|
573
|
+
const flush = async () => {
|
|
574
|
+
if (report) {
|
|
575
|
+
await output(context, report);
|
|
576
|
+
report = "";
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
for (const cursor of cursors)
|
|
580
|
+
await cursor.fill(0);
|
|
581
|
+
let blockRemaining = 0;
|
|
582
|
+
while (compared < limit || !legacy && blockRemaining === blockBytes) {
|
|
583
|
+
if (!legacy) {
|
|
584
|
+
const requested = Math.min(blockBytes, limit - compared);
|
|
585
|
+
await flush();
|
|
586
|
+
await left.block(requested);
|
|
587
|
+
await right.block(requested);
|
|
588
|
+
different = false;
|
|
589
|
+
blockRemaining = Math.min(left.bytes.length, right.bytes.length);
|
|
590
|
+
}
|
|
591
|
+
const hasLeft = (legacy ? await left.fill(limit - compared) : left.bytes.length > 0);
|
|
592
|
+
const hasRight = (legacy ? await right.fill(limit - compared) : right.bytes.length > 0);
|
|
593
|
+
if (!hasLeft || !hasRight) {
|
|
594
|
+
await flush();
|
|
595
|
+
if (hasLeft === hasRight)
|
|
596
|
+
return different ? 1 : 0;
|
|
597
|
+
if (!silent) {
|
|
598
|
+
const shorter = hasLeft ? right.name : left.name;
|
|
599
|
+
const detail = compared === 0 ? "which is empty" : `after byte ${compared}${verbose || noStdout ? "" : `, ${lastByte === 10 ? "" : "in "}line ${newlines + (lastByte === 10 ? 0 : 1)}`}`;
|
|
600
|
+
await output({ ...context, stdout: context.stderr }, Uint8Array.from(`cmp: EOF on ${legacy ? shorter : quote(shorter)} ${detail}\n`, unit => unit.charCodeAt(0)));
|
|
601
|
+
}
|
|
602
|
+
return 1;
|
|
603
|
+
}
|
|
604
|
+
const count = Math.min(left.bytes.length - left.offset, right.bytes.length - right.offset, limit - compared, blockBytes - compared % blockBytes);
|
|
605
|
+
for (let index = 0; index < count; index++) {
|
|
606
|
+
const leftByte = left.bytes[left.offset++];
|
|
607
|
+
const rightByte = right.bytes[right.offset++];
|
|
608
|
+
compared++;
|
|
609
|
+
if (leftByte !== rightByte) {
|
|
610
|
+
different = true;
|
|
611
|
+
if (silent || noStdout)
|
|
612
|
+
return 1;
|
|
613
|
+
if (!verbose) {
|
|
614
|
+
const locale = context.env.LC_ALL || context.env.LC_MESSAGES || context.env.LANG;
|
|
615
|
+
const unit = !printBytes && (!locale || locale === "C" || locale === "POSIX") ? "char" : "byte";
|
|
616
|
+
const detail = printBytes ? ` is ${leftByte.toString(8).padStart(3)} ${printByte(leftByte)} ${rightByte.toString(8).padStart(3)} ${printByte(rightByte)}` : "";
|
|
617
|
+
await output(context, Uint8Array.from(`${left.name} ${right.name} differ: ${unit} ${compared}, line ${newlines + 1}${detail}\n`, character => character.charCodeAt(0)));
|
|
618
|
+
return 1;
|
|
619
|
+
}
|
|
620
|
+
report += `${String(compared).padStart(width)} ${leftByte.toString(8).padStart(3)} ${printBytes ? `${printByte(leftByte).padEnd(4)} ` : ""}${rightByte.toString(8).padStart(3)}${printBytes ? ` ${printByte(rightByte)}` : ""}\n`;
|
|
621
|
+
if (report.length >= 16384)
|
|
622
|
+
await flush();
|
|
623
|
+
}
|
|
624
|
+
if (leftByte === 10)
|
|
625
|
+
newlines++;
|
|
626
|
+
lastByte = leftByte;
|
|
627
|
+
}
|
|
628
|
+
if (!legacy && left.bytes.length !== right.bytes.length) {
|
|
629
|
+
await flush();
|
|
630
|
+
if (!silent) {
|
|
631
|
+
const shorter = left.bytes.length < right.bytes.length ? left.name : right.name;
|
|
632
|
+
const detail = compared === 0 ? "which is empty" : `after byte ${compared}${verbose || noStdout ? "" : `, ${lastByte === 10 ? "" : "in "}line ${newlines + (lastByte === 10 ? 0 : 1)}`}`;
|
|
633
|
+
await output({ ...context, stdout: context.stderr }, `cmp: EOF on ${quote(shorter)} ${detail}\n`);
|
|
634
|
+
}
|
|
635
|
+
return 1;
|
|
636
|
+
}
|
|
637
|
+
if (!legacy && blockRemaining !== blockBytes) {
|
|
638
|
+
await flush();
|
|
639
|
+
return different ? 1 : 0;
|
|
640
|
+
}
|
|
641
|
+
if (compared % blockBytes === 0)
|
|
642
|
+
await yieldTurn(signal);
|
|
643
|
+
}
|
|
644
|
+
await flush();
|
|
645
|
+
return different ? 1 : 0;
|
|
79
646
|
};
|
|
647
|
+
let result;
|
|
648
|
+
try {
|
|
649
|
+
result = await run();
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
await close();
|
|
653
|
+
throw error;
|
|
654
|
+
}
|
|
655
|
+
await close();
|
|
656
|
+
if (cleanupErrors.length)
|
|
657
|
+
throw cleanupErrors[0];
|
|
658
|
+
if (duplicateStdinClose)
|
|
659
|
+
throw inputError(new FsError("EBADF"), "-");
|
|
660
|
+
return result;
|
|
80
661
|
}
|
|
81
|
-
|
|
82
|
-
|
|
662
|
+
function buildCmpCommand(legacy, options = {}) {
|
|
663
|
+
const limits = limitsFor(options);
|
|
664
|
+
const blockBytes = options.comparisonBlockBytes ?? (legacy ? defaultBlockBytes : 65536);
|
|
665
|
+
if (!Number.isSafeInteger(blockBytes) || blockBytes < 1)
|
|
666
|
+
throw new RangeError("cmp comparisonBlockBytes must be positive");
|
|
667
|
+
const definition = { name: "cmp", runtimeIdentity: commandRuntimeIdentity, filesystemRequirements: inputRequirements, async execute(context) {
|
|
668
|
+
context.signal.throwIfAborted();
|
|
669
|
+
let silent = false;
|
|
670
|
+
try {
|
|
671
|
+
const parsed = parse(context, legacy);
|
|
672
|
+
if (parsed.information) {
|
|
673
|
+
await output(context, parsed.information === "version" ? (legacy ? "cmp (virtual-bash)\n" : "cmp (virtual-bash, GNU diffutils 3.12 profile)\n") : "Usage: cmp [OPTION]... FILE1 [FILE2 [SKIP1 [SKIP2]]]\nCompare bytes in the virtual filesystem; omitted FILE2 or '-' reads stdin.\n -s, --silent, --quiet report status only\n -l, --verbose list differing bytes in octal\n -b, -c, --print-bytes also display byte characters\n -i, --ignore-initial=SKIP[:SKIP2] skip initial bytes\n -n, --bytes=LIMIT compare at most LIMIT bytes\n --help, -v, --version show virtual-bash command information\n");
|
|
674
|
+
return { exitCode: 0 };
|
|
675
|
+
}
|
|
676
|
+
silent = parsed.silent;
|
|
677
|
+
return { exitCode: await compare(context, parsed, blockBytes, limits, legacy, options.comparisonBlockBytes === undefined) };
|
|
678
|
+
}
|
|
679
|
+
catch (error) {
|
|
680
|
+
context.signal.throwIfAborted();
|
|
681
|
+
if (error instanceof InvocationClosed)
|
|
682
|
+
throw error;
|
|
683
|
+
if (!silent || !(error instanceof InputError) || !error.suppressInSilent) {
|
|
684
|
+
const message = !legacy && error instanceof Error ? error.message : publicDiagnosticMessage(error, context.onInternalError);
|
|
685
|
+
const diagnostic = `cmp: ${message}\n${error instanceof UsageError ? "cmp: Try 'cmp --help' for more information.\n" : ""}`;
|
|
686
|
+
await output({ ...context, stdout: context.stderr }, error instanceof UsageError || error instanceof InputError ? Uint8Array.from(diagnostic, unit => unit.charCodeAt(0)) : diagnostic);
|
|
687
|
+
}
|
|
688
|
+
return { exitCode: 2 };
|
|
689
|
+
}
|
|
690
|
+
} };
|
|
691
|
+
return registerDefaultExecutor(definition, options);
|
|
692
|
+
}
|
|
693
|
+
export function evalSyncCmp(inBytes, opArgs, readFileSync) {
|
|
694
|
+
try {
|
|
695
|
+
const operands = [];
|
|
696
|
+
const skips = [0n, 0n];
|
|
697
|
+
let count = 9223372036854775807n;
|
|
698
|
+
let stopped = false;
|
|
699
|
+
const setSkip = (idx, text) => {
|
|
700
|
+
const p = byteCount(text, "ignore-initial");
|
|
701
|
+
if (p > skips[idx])
|
|
702
|
+
skips[idx] = p;
|
|
703
|
+
};
|
|
704
|
+
for (let i = 0; i < opArgs.length; i++) {
|
|
705
|
+
const a = opArgs[i];
|
|
706
|
+
if (stopped || a === "-" || !a.startsWith("-")) {
|
|
707
|
+
operands.push(a);
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
if (a === "--") {
|
|
711
|
+
stopped = true;
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
if (a === "-s" || a === "--silent" || a === "--quiet" || a === "-b" || a === "-c" || a === "--print-bytes" || a === "-l" || a === "--verbose")
|
|
715
|
+
continue;
|
|
716
|
+
if (a === "-i" || a === "--ignore-initial" || a.startsWith("-i") || a.startsWith("--ignore-initial=")) {
|
|
717
|
+
const v = (a === "-i" || a === "--ignore-initial") ? opArgs[++i] : (a.startsWith("--ignore-initial=") ? a.slice(17) : a.slice(2));
|
|
718
|
+
if (v === undefined || v === "")
|
|
719
|
+
return undefined;
|
|
720
|
+
const d = v.indexOf(":");
|
|
721
|
+
if (d < 0) {
|
|
722
|
+
setSkip(0, v);
|
|
723
|
+
if (skips[0] > skips[1])
|
|
724
|
+
skips[1] = skips[0];
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
setSkip(0, v.slice(0, d));
|
|
728
|
+
setSkip(1, v.slice(d + 1));
|
|
729
|
+
}
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (a === "-n" || a === "--bytes" || a.startsWith("-n") || a.startsWith("--bytes=")) {
|
|
733
|
+
const v = (a === "-n" || a === "--bytes") ? opArgs[++i] : (a.startsWith("--bytes=") ? a.slice(8) : a.slice(2));
|
|
734
|
+
if (v === undefined || v === "")
|
|
735
|
+
return undefined;
|
|
736
|
+
const p = byteCount(v, "bytes");
|
|
737
|
+
if (p < count)
|
|
738
|
+
count = p;
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
return undefined;
|
|
742
|
+
}
|
|
743
|
+
if (operands.length < 1 || operands.length > 4)
|
|
744
|
+
return undefined;
|
|
745
|
+
if (operands[2] !== undefined)
|
|
746
|
+
setSkip(0, operands[2]);
|
|
747
|
+
if (operands[3] !== undefined)
|
|
748
|
+
setSkip(1, operands[3]);
|
|
749
|
+
const f0 = operands[0];
|
|
750
|
+
const f1 = operands[1] ?? "-";
|
|
751
|
+
if (f0 === "-" && f1 === "-") {
|
|
752
|
+
if (skips[0] === skips[1])
|
|
753
|
+
return "";
|
|
754
|
+
return undefined;
|
|
755
|
+
}
|
|
756
|
+
const b0 = f0 === "-" ? inBytes : readFileSync?.(f0);
|
|
757
|
+
const b1 = f1 === "-" ? inBytes : readFileSync?.(f1);
|
|
758
|
+
if (!b0 || !b1 || b0.byteLength > 16384 || b1.byteLength > 16384)
|
|
759
|
+
return undefined;
|
|
760
|
+
if (skips[0] > BigInt(b0.byteLength) || skips[1] > BigInt(b1.byteLength))
|
|
761
|
+
return undefined;
|
|
762
|
+
const s0 = Number(skips[0]);
|
|
763
|
+
const s1 = Number(skips[1]);
|
|
764
|
+
const rem0 = b0.byteLength - s0;
|
|
765
|
+
const rem1 = b1.byteLength - s1;
|
|
766
|
+
const limit = count < BigInt(Math.max(rem0, rem1)) ? Number(count) : Math.max(rem0, rem1);
|
|
767
|
+
const len0 = Math.min(rem0, limit);
|
|
768
|
+
const len1 = Math.min(rem1, limit);
|
|
769
|
+
if (len0 !== len1)
|
|
770
|
+
return undefined;
|
|
771
|
+
for (let i = 0; i < len0; i++) {
|
|
772
|
+
if (b0[s0 + i] !== b1[s1 + i])
|
|
773
|
+
return undefined;
|
|
774
|
+
}
|
|
775
|
+
return "";
|
|
776
|
+
}
|
|
777
|
+
catch {
|
|
778
|
+
return undefined;
|
|
779
|
+
}
|
|
83
780
|
}
|
|
781
|
+
/** Opt-in GNU comparison-block behavior; producer fragments do not define blocks. */
|
|
782
|
+
export const createCmpCommand = buildCmpCommand.bind(undefined, false);
|
|
783
|
+
/** Existing default-shell behavior, sharing the same retained-input engine. */
|
|
784
|
+
export const cmpCommand = buildCmpCommand.bind(undefined, true);
|
|
785
|
+
export function createCmpCommands(options = {}) { return [createCmpCommand(options)]; }
|
|
84
786
|
export function cmpCommands(options = {}) {
|
|
85
787
|
const commands = createCmpCommands(options);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
setup(host) {
|
|
90
|
-
if (!replace)
|
|
91
|
-
for (const command of commands) {
|
|
788
|
+
return { name: "cmp-commands", setup(host) {
|
|
789
|
+
if (!options.replace)
|
|
790
|
+
for (const command of commands)
|
|
92
791
|
if (host.commands.has(command.name))
|
|
93
792
|
throw new Error(`Command already registered: ${command.name}`);
|
|
94
|
-
}
|
|
95
793
|
for (const command of commands)
|
|
96
|
-
host.commands.register(command, { replace });
|
|
97
|
-
}
|
|
98
|
-
};
|
|
794
|
+
host.commands.register(command, { replace: options.replace ?? false });
|
|
795
|
+
} };
|
|
99
796
|
}
|