@poe-platform/safe-bash 0.1.630 → 0.1.632
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 -0
- package/dist/office-package/compression.d.ts +19 -0
- package/dist/office-package/compression.js +186 -0
- package/dist/office-package/runtime.d.ts +11 -0
- package/dist/office-package/runtime.js +28 -0
- package/dist/safe-bash/chunks/{bz2-B2RXT4EX.js → bz2-ACU4EOVE.js} +2 -2
- package/dist/safe-bash/chunks/chunk-2E4KBFO6.js +239 -0
- package/dist/safe-bash/chunks/chunk-2E4KBFO6.js.map +7 -0
- package/dist/safe-bash/chunks/chunk-3E5M2WEL.js +33 -0
- package/dist/safe-bash/chunks/chunk-3E5M2WEL.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-KQ6J7JHQ.js → chunk-3LD67SER.js} +12 -10
- package/dist/safe-bash/chunks/{chunk-KQ6J7JHQ.js.map → chunk-3LD67SER.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-6LSSEOG7.js → chunk-6HNK7Q66.js} +11 -7
- package/dist/safe-bash/chunks/{chunk-6LSSEOG7.js.map → chunk-6HNK7Q66.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-AD7UAP5B.js → chunk-7EEWZY5S.js} +10 -8
- package/dist/safe-bash/chunks/{chunk-AD7UAP5B.js.map → chunk-7EEWZY5S.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-RNKTWFEM.js → chunk-CDBQXRWL.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-UYX72YHY.js → chunk-CHHAB5SS.js} +10 -74
- package/dist/safe-bash/chunks/{chunk-UYX72YHY.js.map → chunk-CHHAB5SS.js.map} +3 -3
- package/dist/safe-bash/chunks/{chunk-6YSBXTTJ.js → chunk-EI4X5ETX.js} +12 -10
- package/dist/safe-bash/chunks/{chunk-6YSBXTTJ.js.map → chunk-EI4X5ETX.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-KZ7QCYNT.js → chunk-GIBLUW2U.js} +13 -9
- package/dist/safe-bash/chunks/{chunk-KZ7QCYNT.js.map → chunk-GIBLUW2U.js.map} +1 -1
- package/dist/safe-bash/chunks/chunk-GPV7ZFYS.js +1528 -0
- package/dist/safe-bash/chunks/chunk-GPV7ZFYS.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-N5CYTGBN.js → chunk-H3E67KTZ.js} +13 -9
- package/dist/safe-bash/chunks/{chunk-N5CYTGBN.js.map → chunk-H3E67KTZ.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-AFH57PPL.js → chunk-IEKESMO4.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-DPJWEGIX.js → chunk-JLBIUYT3.js} +2 -2
- package/dist/safe-bash/chunks/chunk-JZDO5MC3.js +77 -0
- package/dist/safe-bash/chunks/chunk-JZDO5MC3.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-GFZKQIPL.js → chunk-LA6BX562.js} +8 -6
- package/dist/safe-bash/chunks/{chunk-GFZKQIPL.js.map → chunk-LA6BX562.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-PVJJFCGA.js → chunk-M3GPCYSP.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-FWDMJTQO.js → chunk-NDCZ3UBP.js} +13 -9
- package/dist/safe-bash/chunks/{chunk-FWDMJTQO.js.map → chunk-NDCZ3UBP.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-2KL6W6NB.js → chunk-O2EVBRKF.js} +1 -2
- package/dist/safe-bash/chunks/chunk-OFT77XIB.js +389 -0
- package/dist/safe-bash/chunks/chunk-OFT77XIB.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-PCLOK32J.js → chunk-PC6BEIAF.js} +13 -9
- package/dist/safe-bash/chunks/{chunk-PCLOK32J.js.map → chunk-PC6BEIAF.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-3M5F7LD5.js → chunk-QWKP7ZU7.js} +13 -9
- package/dist/safe-bash/chunks/{chunk-3M5F7LD5.js.map → chunk-QWKP7ZU7.js.map} +1 -1
- package/dist/safe-bash/chunks/chunk-THXJ6CLF.js +53 -0
- package/dist/safe-bash/chunks/chunk-THXJ6CLF.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-K7W6Q6FN.js → chunk-V73A742N.js} +58 -16
- package/dist/safe-bash/chunks/chunk-V73A742N.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-4BYUV5PA.js → chunk-VN3ZGME3.js} +12 -8
- package/dist/safe-bash/chunks/{chunk-4BYUV5PA.js.map → chunk-VN3ZGME3.js.map} +1 -1
- package/dist/safe-bash/chunks/{chunk-3BZ5NQ73.js → chunk-WECHUK3Y.js} +369 -36
- package/dist/safe-bash/chunks/chunk-WECHUK3Y.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-X55AMTNM.js → chunk-WIOEUR7D.js} +14 -10
- package/dist/safe-bash/chunks/{chunk-X55AMTNM.js.map → chunk-WIOEUR7D.js.map} +1 -1
- package/dist/safe-bash/chunks/chunk-WPIOO4NX.js +443 -0
- package/dist/safe-bash/chunks/chunk-WPIOO4NX.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-C7QNJ3D4.js → chunk-WYTI64IU.js} +2 -2
- package/dist/safe-bash/chunks/{xz-AVXFDXW4.js → xz-U4QDTPZL.js} +2 -2
- package/dist/safe-bash/chunks/{zstd-R6RPHJYO.js → zstd-OG5RPYXO.js} +2 -2
- package/dist/safe-bash/commands/archive/zip/crc.d.ts +2 -0
- package/dist/safe-bash/commands/archive/zip/crc.d.ts.map +1 -0
- package/dist/safe-bash/commands/archive/zip/crc.js +7 -0
- package/dist/safe-bash/commands/archive/zip/crc.js.map +1 -0
- package/dist/safe-bash/commands/archive/zip/crypto.d.ts +4 -0
- package/dist/safe-bash/commands/archive/zip/crypto.d.ts.map +1 -0
- package/dist/safe-bash/commands/archive/zip/crypto.js +34 -0
- package/dist/safe-bash/commands/archive/zip/crypto.js.map +1 -0
- package/dist/safe-bash/commands/archive/zip/help.d.ts +3 -0
- package/dist/safe-bash/commands/archive/zip/help.d.ts.map +1 -0
- package/dist/safe-bash/commands/archive/zip/help.js +87 -0
- package/dist/safe-bash/commands/archive/zip/help.js.map +1 -0
- package/dist/safe-bash/commands/archive/zip/move.d.ts +12 -0
- package/dist/safe-bash/commands/archive/zip/move.d.ts.map +1 -0
- package/dist/safe-bash/commands/archive/zip/move.js +60 -0
- package/dist/safe-bash/commands/archive/zip/move.js.map +1 -0
- package/dist/safe-bash/commands/archive/zip/options.js +5 -5
- package/dist/safe-bash/commands/archive/zip/options.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.d.ts +1 -1
- package/dist/safe-bash/commands/archive/zip-format.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip-format.js +14 -17
- package/dist/safe-bash/commands/archive/zip-format.js.map +1 -1
- package/dist/safe-bash/commands/archive/zip.d.ts.map +1 -1
- package/dist/safe-bash/commands/archive/zip.js +45 -15
- package/dist/safe-bash/commands/archive/zip.js.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/bounded-codec.d.ts +2 -0
- package/dist/safe-bash/commands/bytes/compression/bounded-codec.d.ts.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/bounded-codec.js +4 -0
- package/dist/safe-bash/commands/bytes/compression/bounded-codec.js.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/codec.d.ts +4 -24
- package/dist/safe-bash/commands/bytes/compression/codec.d.ts.map +1 -1
- package/dist/safe-bash/commands/bytes/compression/codec.js +12 -168
- package/dist/safe-bash/commands/bytes/compression/codec.js.map +1 -1
- package/dist/safe-bash/commands/cmp.js +1 -1
- package/dist/safe-bash/commands/cmp.js.map +1 -1
- package/dist/safe-bash/commands/csplit/index.browser.js +10 -7
- package/dist/safe-bash/commands/docx/index.browser.js +54 -0
- package/dist/safe-bash/commands/docx/index.browser.js.map +7 -0
- package/dist/safe-bash/commands/docx/index.d.ts +25 -0
- package/dist/safe-bash/commands/docx/index.d.ts.map +1 -0
- package/dist/safe-bash/commands/docx/index.js +42 -0
- package/dist/safe-bash/commands/docx/index.js.map +1 -0
- package/dist/safe-bash/commands/docx/io.d.ts +15 -0
- package/dist/safe-bash/commands/docx/io.d.ts.map +1 -0
- package/dist/safe-bash/commands/docx/io.js +16 -0
- package/dist/safe-bash/commands/docx/io.js.map +1 -0
- package/dist/safe-bash/commands/factor/index.browser.js +7 -5
- package/dist/safe-bash/commands/filesystem.d.ts.map +1 -1
- package/dist/safe-bash/commands/filesystem.js +9 -1
- package/dist/safe-bash/commands/filesystem.js.map +1 -1
- package/dist/safe-bash/commands/getopt/index.browser.js +7 -5
- package/dist/safe-bash/commands/hexdump/index.browser.js +8 -6
- package/dist/safe-bash/commands/iconv/index.browser.js +8 -6
- package/dist/safe-bash/commands/line-endings/index.browser.js +10 -7
- package/dist/safe-bash/commands/llm/index.browser.js +10 -8
- package/dist/safe-bash/commands/llm/providers/index.browser.js +3 -3
- package/dist/safe-bash/commands/network/index.browser.js +11 -8
- package/dist/safe-bash/commands/node/index.browser.js +8 -6
- package/dist/safe-bash/commands/op/index.browser.js +3 -3
- package/dist/safe-bash/commands/op/index.js +0 -1
- package/dist/safe-bash/commands/op/index.js.map +2 -2
- package/dist/safe-bash/commands/pptx/index.d.ts +29 -0
- package/dist/safe-bash/commands/pptx/index.d.ts.map +1 -0
- package/dist/safe-bash/commands/pptx/index.js +153 -0
- package/dist/safe-bash/commands/pptx/index.js.map +1 -0
- package/dist/safe-bash/commands/pr/index.browser.js +8 -6
- package/dist/safe-bash/commands/predicates.js +1 -1
- package/dist/safe-bash/commands/python/execution.d.ts +3 -0
- package/dist/safe-bash/commands/python/execution.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/execution.js +193 -0
- package/dist/safe-bash/commands/python/execution.js.map +1 -0
- package/dist/safe-bash/commands/python/index.browser.js +21 -0
- package/dist/safe-bash/commands/python/index.browser.js.map +7 -0
- package/dist/safe-bash/commands/python/index.d.ts +49 -0
- package/dist/safe-bash/commands/python/index.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/index.js +317 -0
- package/dist/safe-bash/commands/python/index.js.map +1 -0
- package/dist/safe-bash/commands/python/installation.d.ts +9 -0
- package/dist/safe-bash/commands/python/installation.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/installation.js +80 -0
- package/dist/safe-bash/commands/python/installation.js.map +1 -0
- package/dist/safe-bash/commands/python/invocation.d.ts +10 -0
- package/dist/safe-bash/commands/python/invocation.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/invocation.js +81 -0
- package/dist/safe-bash/commands/python/invocation.js.map +1 -0
- package/dist/safe-bash/commands/python/node.d.ts +12 -0
- package/dist/safe-bash/commands/python/node.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/node.js +33 -0
- package/dist/safe-bash/commands/python/node.js.map +1 -0
- package/dist/safe-bash/commands/python/provisioning-runtime.d.ts +5 -0
- package/dist/safe-bash/commands/python/provisioning-runtime.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/provisioning-runtime.js +179 -0
- package/dist/safe-bash/commands/python/provisioning-runtime.js.map +1 -0
- package/dist/safe-bash/commands/python/provisioning.d.ts +49 -0
- package/dist/safe-bash/commands/python/provisioning.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/provisioning.js +320 -0
- package/dist/safe-bash/commands/python/provisioning.js.map +1 -0
- package/dist/safe-bash/commands/python/reply.d.ts +3 -0
- package/dist/safe-bash/commands/python/reply.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/reply.js +103 -0
- package/dist/safe-bash/commands/python/reply.js.map +1 -0
- package/dist/safe-bash/commands/python/worker.browser.js +736 -0
- package/dist/safe-bash/commands/python/worker.browser.js.map +7 -0
- package/dist/safe-bash/commands/python/worker.d.ts +47 -0
- package/dist/safe-bash/commands/python/worker.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/worker.js +373 -0
- package/dist/safe-bash/commands/python/worker.js.map +1 -0
- package/dist/safe-bash/commands/tsort/index.browser.js +8 -6
- package/dist/safe-bash/commands/xml/index.browser.js +9 -7
- package/dist/safe-bash/commands/yq/index.browser.js +10 -8
- package/dist/safe-bash/commands/yq/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/yq/index.js +32 -4
- package/dist/safe-bash/commands/yq/index.js.map +1 -1
- package/dist/safe-bash/commands/yq/parser.d.ts.map +1 -1
- package/dist/safe-bash/commands/yq/parser.js +21 -5
- package/dist/safe-bash/commands/yq/parser.js.map +1 -1
- package/dist/safe-bash/contracts/command.d.ts +2 -0
- package/dist/safe-bash/contracts/command.d.ts.map +1 -1
- package/dist/safe-bash/contracts/command.js +6 -2
- package/dist/safe-bash/contracts/command.js.map +1 -1
- package/dist/safe-bash/contracts/filesystem-descriptor.d.ts +13 -0
- package/dist/safe-bash/contracts/filesystem-descriptor.d.ts.map +1 -0
- package/dist/safe-bash/contracts/filesystem-descriptor.js +189 -0
- package/dist/safe-bash/contracts/filesystem-descriptor.js.map +1 -0
- package/dist/safe-bash/contracts/filesystem-output-budget.d.ts +15 -0
- package/dist/safe-bash/contracts/filesystem-output-budget.d.ts.map +1 -0
- package/dist/safe-bash/contracts/filesystem-output-budget.js +69 -0
- package/dist/safe-bash/contracts/filesystem-output-budget.js.map +1 -0
- package/dist/safe-bash/contracts/filesystem-output.d.ts +11 -5
- package/dist/safe-bash/contracts/filesystem-output.d.ts.map +1 -1
- package/dist/safe-bash/contracts/filesystem-output.js +229 -20
- package/dist/safe-bash/contracts/filesystem-output.js.map +1 -1
- package/dist/safe-bash/contracts/io.d.ts +29 -0
- package/dist/safe-bash/contracts/io.d.ts.map +1 -1
- package/dist/safe-bash/contracts/io.js +317 -37
- package/dist/safe-bash/contracts/io.js.map +1 -1
- package/dist/safe-bash/core.browser.js +5502 -2210
- package/dist/safe-bash/core.browser.js.map +4 -4
- package/dist/safe-bash/core.d.ts +1 -0
- package/dist/safe-bash/core.d.ts.map +1 -1
- package/dist/safe-bash/core.js +1 -0
- package/dist/safe-bash/core.js.map +1 -1
- package/dist/safe-bash/opt-in/commands/cmp/compare.js +95 -0
- package/dist/safe-bash/opt-in/commands/cmp/index.d.ts +6 -0
- package/dist/safe-bash/opt-in/commands/cmp/index.js +99 -0
- package/dist/safe-bash/opt-in/commands/cmp/io.js +218 -0
- package/dist/safe-bash/opt-in/commands/cmp/options.d.ts +24 -0
- package/dist/safe-bash/opt-in/commands/cmp/options.js +195 -0
- package/dist/safe-bash/opt-in/commands/dd/conversions.js +152 -0
- package/dist/safe-bash/opt-in/commands/dd/index.d.ts +18 -0
- package/dist/safe-bash/opt-in/commands/dd/index.js +561 -0
- package/dist/safe-bash/opt-in/commands/dd/io.d.ts +31 -0
- package/dist/safe-bash/opt-in/commands/dd/io.js +244 -0
- package/dist/safe-bash/opt-in/commands/dd/options.js +184 -0
- package/dist/safe-bash/opt-in/commands/dd/report.js +69 -0
- package/dist/safe-bash/opt-in/commands/install/arguments.js +224 -0
- package/dist/safe-bash/opt-in/commands/install/index.d.ts +6 -0
- package/dist/safe-bash/opt-in/commands/install/index.js +678 -0
- package/dist/safe-bash/opt-in/commands/install/mode.js +71 -0
- package/dist/safe-bash/opt-in/commands/install/options.d.ts +36 -0
- package/dist/safe-bash/opt-in/commands/install/options.js +27 -0
- package/dist/safe-bash/opt-in/commands/shuf/args.js +179 -0
- package/dist/safe-bash/opt-in/commands/shuf/index.d.ts +6 -0
- package/dist/safe-bash/opt-in/commands/shuf/index.js +20 -0
- package/dist/safe-bash/opt-in/commands/shuf/input.js +93 -0
- package/dist/safe-bash/opt-in/commands/shuf/options.d.ts +9 -0
- package/dist/safe-bash/opt-in/commands/shuf/options.js +8 -0
- package/dist/safe-bash/opt-in/commands/shuf/random.js +114 -0
- package/dist/safe-bash/opt-in/commands/shuf/shuf.d.ts +3 -0
- package/dist/safe-bash/opt-in/commands/shuf/shuf.js +230 -0
- package/dist/safe-bash/opt-in/commands/shuf/usage.js +24 -0
- package/dist/safe-bash/opt-in/commands/truncate/arguments.js +186 -0
- package/dist/safe-bash/opt-in/commands/truncate/index.d.ts +9 -0
- package/dist/safe-bash/opt-in/commands/truncate/index.js +244 -0
- package/dist/safe-bash/opt-in/commands/yes/index.d.ts +11 -0
- package/dist/safe-bash/opt-in/commands/yes/index.js +167 -0
- package/dist/safe-bash/opt-in/commands/yq/arguments.js +177 -0
- package/dist/safe-bash/opt-in/commands/yq/evaluate.js +564 -0
- package/dist/safe-bash/opt-in/commands/yq/expression.js +183 -0
- package/dist/safe-bash/opt-in/commands/yq/inplace.js +65 -0
- package/dist/safe-bash/opt-in/commands/yq/mike.d.ts +9 -0
- package/dist/safe-bash/opt-in/commands/yq/mike.js +192 -0
- package/dist/safe-bash/opt-in/commands/yq/native-encoder.js +165 -0
- package/dist/safe-bash/opt-in/commands/yq/native-work.d.ts +44 -0
- package/dist/safe-bash/opt-in/commands/yq/native-work.js +188 -0
- package/dist/safe-bash/opt-in/commands/yq/nodes.js +621 -0
- package/dist/safe-bash/opt-in/entrypoints/arrays.d.ts +1 -0
- package/dist/safe-bash/opt-in/entrypoints/arrays.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/cmp.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/cmp.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/dd.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/dd.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/devices.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/devices.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/install.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/install.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/jobs.d.ts +1 -0
- package/dist/safe-bash/opt-in/entrypoints/jobs.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/mapfile.d.ts +1 -0
- package/dist/safe-bash/opt-in/entrypoints/mapfile.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/read.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/read.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/shuf.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/shuf.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/trap.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/trap.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/truncate.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/truncate.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/yes.d.ts +2 -0
- package/dist/safe-bash/opt-in/entrypoints/yes.js +1 -0
- package/dist/safe-bash/opt-in/entrypoints/yq.d.ts +3 -0
- package/dist/safe-bash/opt-in/entrypoints/yq.js +1 -0
- package/dist/safe-bash/opt-in/fs/devices/index.d.ts +8 -0
- package/dist/safe-bash/opt-in/fs/devices/index.js +292 -0
- package/dist/safe-bash/opt-in/optional.d.ts +28 -0
- package/dist/safe-bash/opt-in/optional.js +14 -0
- package/dist/safe-bash/opt-in/shell/extensions/arrays/index.d.ts +2 -0
- package/dist/safe-bash/opt-in/shell/extensions/arrays/index.js +4 -0
- package/dist/safe-bash/opt-in/shell/extensions/jobs/index.d.ts +2 -0
- package/dist/safe-bash/opt-in/shell/extensions/jobs/index.js +291 -0
- package/dist/safe-bash/opt-in/shell/extensions/jobs/state.js +374 -0
- package/dist/safe-bash/opt-in/shell/extensions/mapfile/index.d.ts +24 -0
- package/dist/safe-bash/opt-in/shell/extensions/mapfile/index.js +338 -0
- package/dist/safe-bash/opt-in/shell/extensions/read/index.d.ts +5 -0
- package/dist/safe-bash/opt-in/shell/extensions/read/index.js +351 -0
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.d.ts +9 -0
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.js +210 -0
- package/dist/safe-bash/optional-host.d.ts +5 -0
- package/dist/safe-bash/optional-host.d.ts.map +1 -0
- package/dist/safe-bash/optional-host.js +3 -0
- package/dist/safe-bash/optional-host.js.map +1 -0
- package/dist/safe-bash/shell/arrays/bindings.d.ts +15 -5
- package/dist/safe-bash/shell/arrays/bindings.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/bindings.js +131 -23
- package/dist/safe-bash/shell/arrays/bindings.js.map +1 -1
- package/dist/safe-bash/shell/arrays/ledger.d.ts +1 -0
- package/dist/safe-bash/shell/arrays/ledger.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/ledger.js +19 -0
- package/dist/safe-bash/shell/arrays/ledger.js.map +1 -1
- package/dist/safe-bash/shell/arrays/state.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/state.js +3 -1
- package/dist/safe-bash/shell/arrays/state.js.map +1 -1
- package/dist/safe-bash/shell/arrays/syntax.d.ts +4 -1
- package/dist/safe-bash/shell/arrays/syntax.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/syntax.js +3 -3
- package/dist/safe-bash/shell/arrays/syntax.js.map +1 -1
- package/dist/safe-bash/shell/conditional.js +1 -1
- package/dist/safe-bash/shell/descriptors.d.ts +31 -0
- package/dist/safe-bash/shell/descriptors.d.ts.map +1 -0
- package/dist/safe-bash/shell/descriptors.js +234 -0
- package/dist/safe-bash/shell/descriptors.js.map +1 -0
- package/dist/safe-bash/shell/diagnostic-name-ranges.d.ts +2 -0
- package/dist/safe-bash/shell/diagnostic-name-ranges.d.ts.map +1 -0
- package/dist/safe-bash/shell/diagnostic-name-ranges.js +717 -0
- package/dist/safe-bash/shell/diagnostic-name-ranges.js.map +1 -0
- package/dist/safe-bash/shell/diagnostic-name.d.ts +3 -0
- package/dist/safe-bash/shell/diagnostic-name.d.ts.map +1 -0
- package/dist/safe-bash/shell/diagnostic-name.js +89 -0
- package/dist/safe-bash/shell/diagnostic-name.js.map +1 -0
- package/dist/safe-bash/shell/display.js +1 -1
- package/dist/safe-bash/shell/display.js.map +1 -1
- package/dist/safe-bash/shell/extensions.d.ts +188 -0
- package/dist/safe-bash/shell/extensions.d.ts.map +1 -0
- package/dist/safe-bash/shell/extensions.js +141 -0
- package/dist/safe-bash/shell/extensions.js.map +1 -0
- package/dist/safe-bash/shell/input.d.ts +66 -14
- package/dist/safe-bash/shell/input.d.ts.map +1 -1
- package/dist/safe-bash/shell/input.js +947 -173
- package/dist/safe-bash/shell/input.js.map +1 -1
- package/dist/safe-bash/shell/parser.d.ts +38 -6
- package/dist/safe-bash/shell/parser.d.ts.map +1 -1
- package/dist/safe-bash/shell/parser.js +339 -52
- package/dist/safe-bash/shell/parser.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts +92 -20
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +2547 -689
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/dist/safe-bash/shell/shell.d.ts.map +1 -1
- package/dist/safe-bash/shell/shell.js +52 -21
- package/dist/safe-bash/shell/shell.js.map +1 -1
- package/dist/safe-bash/shell/types.d.ts +4 -0
- package/dist/safe-bash/shell/types.d.ts.map +1 -1
- package/dist/safe-bash/shell/types.js.map +1 -1
- package/package.json +92 -4
- package/dist/safe-bash/chunks/chunk-3BZ5NQ73.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-4DBWBEU7.js +0 -194
- package/dist/safe-bash/chunks/chunk-4DBWBEU7.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-CXMIIXJA.js +0 -178
- package/dist/safe-bash/chunks/chunk-CXMIIXJA.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-K7W6Q6FN.js.map +0 -7
- /package/dist/safe-bash/chunks/{bz2-B2RXT4EX.js.map → bz2-ACU4EOVE.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-RNKTWFEM.js.map → chunk-CDBQXRWL.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-AFH57PPL.js.map → chunk-IEKESMO4.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-DPJWEGIX.js.map → chunk-JLBIUYT3.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-PVJJFCGA.js.map → chunk-M3GPCYSP.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-2KL6W6NB.js.map → chunk-O2EVBRKF.js.map} +0 -0
- /package/dist/safe-bash/chunks/{chunk-C7QNJ3D4.js.map → chunk-WYTI64IU.js.map} +0 -0
- /package/dist/safe-bash/chunks/{xz-AVXFDXW4.js.map → xz-U4QDTPZL.js.map} +0 -0
- /package/dist/safe-bash/chunks/{zstd-R6RPHJYO.js.map → zstd-OG5RPYXO.js.map} +0 -0
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parsePythonInvocation
|
|
3
|
+
} from "../../chunks/chunk-JZDO5MC3.js";
|
|
4
|
+
import {
|
|
5
|
+
init_platform
|
|
6
|
+
} from "../../chunks/chunk-O2EVBRKF.js";
|
|
7
|
+
|
|
8
|
+
// packages/safe-bash/src/commands/python/worker.ts
|
|
9
|
+
init_platform();
|
|
10
|
+
import { mountPythonFileSystem } from "@poe-platform/safe-fs/core";
|
|
11
|
+
|
|
12
|
+
// packages/safe-bash/src/commands/python/execution.ts
|
|
13
|
+
init_platform();
|
|
14
|
+
var pythonExecution = `
|
|
15
|
+
import sys, os, json, runpy, traceback, types, warnings, textwrap, io, struct, linecache
|
|
16
|
+
_safe_invocation = json.loads(_safe_invocation_json)
|
|
17
|
+
os.environ.clear()
|
|
18
|
+
os.environ.update(_safe_invocation['env'])
|
|
19
|
+
_safe_args = list(_safe_invocation['args'])
|
|
20
|
+
_safe_exit = 0
|
|
21
|
+
|
|
22
|
+
class _SafeOptionError(ValueError):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
def _safe_system_exit(_error):
|
|
26
|
+
if isinstance(_error.code, int):
|
|
27
|
+
_status = int.__index__(_error.code)
|
|
28
|
+
_long_bound = 1 << (8 * struct.calcsize('@l') - 1)
|
|
29
|
+
status = (_status & 255) if -_long_bound <= _status < _long_bound else 255
|
|
30
|
+
else:
|
|
31
|
+
status = 0 if _error.code is None else 1
|
|
32
|
+
if _error.code is not None and not isinstance(_error.code, int):
|
|
33
|
+
print(_error.code, file=sys.stderr)
|
|
34
|
+
return status
|
|
35
|
+
|
|
36
|
+
def _safe_launch():
|
|
37
|
+
args = list(_safe_args)
|
|
38
|
+
unbuffered = False
|
|
39
|
+
ignore_env = bool(sys.flags.ignore_environment)
|
|
40
|
+
safe_path = bool(sys.flags.safe_path)
|
|
41
|
+
native_warning_options = list(sys.warnoptions)
|
|
42
|
+
warning_options = []
|
|
43
|
+
version_count = 0
|
|
44
|
+
options_terminated = False
|
|
45
|
+
while args and args[0].startswith('-') and args[0] != '-':
|
|
46
|
+
option = args.pop(0)
|
|
47
|
+
if option == '--':
|
|
48
|
+
options_terminated = True
|
|
49
|
+
break
|
|
50
|
+
if option in ('--help', '-h', '-?'):
|
|
51
|
+
print('usage: python [-uBEPOsSIbdvqR] [-W filter] [-X option] [-c code | -m module | file | -] [args ...]')
|
|
52
|
+
print('Dedicated Pyodide interpreter; stdin is noninteractive.')
|
|
53
|
+
print('-u: unbuffered binary output; -B: disable bytecode writes; -E: ignore PYTHON* settings')
|
|
54
|
+
print('-P: omit automatic unsafe sys.path entry; -W: Python warning filter')
|
|
55
|
+
print('-O/-OO, -S/-s/-I, -b/-bb, -d/-v/-q/-R: CPython startup flags')
|
|
56
|
+
print('-X: utf8, dev, warn_default_encoding, int_max_str_digits; interactive flags are unsupported.')
|
|
57
|
+
return
|
|
58
|
+
if option == '--version':
|
|
59
|
+
version_count += 1
|
|
60
|
+
continue
|
|
61
|
+
if option.startswith('--'):
|
|
62
|
+
raise _SafeOptionError('unsupported option ' + option)
|
|
63
|
+
index = 1
|
|
64
|
+
while index < len(option):
|
|
65
|
+
flag = option[index]
|
|
66
|
+
if flag in ('h', '?'):
|
|
67
|
+
args = ['--help']
|
|
68
|
+
break
|
|
69
|
+
if flag == 'V':
|
|
70
|
+
version_count += 1
|
|
71
|
+
index += 1
|
|
72
|
+
continue
|
|
73
|
+
if flag in ('c', 'm', 'W', 'X'):
|
|
74
|
+
operand = option[index + 1:] if index + 1 < len(option) else args.pop(0) if args else None
|
|
75
|
+
if operand is None:
|
|
76
|
+
raise _SafeOptionError('argument expected for -' + flag)
|
|
77
|
+
if flag in ('W', 'X'):
|
|
78
|
+
if flag == 'W': warning_options.append(operand)
|
|
79
|
+
break
|
|
80
|
+
args = ['-' + flag, operand] + args
|
|
81
|
+
break
|
|
82
|
+
elif flag in ('O', 'S', 's', 'I', 'b', 'd', 'v', 'q', 'R'):
|
|
83
|
+
pass # Applied by CPython startup configuration before bootstrap.
|
|
84
|
+
elif flag == 'u':
|
|
85
|
+
unbuffered = True
|
|
86
|
+
elif flag == 'B':
|
|
87
|
+
sys.dont_write_bytecode = True
|
|
88
|
+
elif flag == 'E':
|
|
89
|
+
ignore_env = True
|
|
90
|
+
elif flag == 'P':
|
|
91
|
+
safe_path = True
|
|
92
|
+
else:
|
|
93
|
+
raise _SafeOptionError('unsupported option -' + flag)
|
|
94
|
+
index += 1
|
|
95
|
+
if args and args[0] in ('-c', '-m'):
|
|
96
|
+
break
|
|
97
|
+
if version_count:
|
|
98
|
+
print('Python ' + (sys.version if version_count > 1 else sys.version.split()[0]))
|
|
99
|
+
return
|
|
100
|
+
if not ignore_env:
|
|
101
|
+
unbuffered = unbuffered or bool(os.environ.get('PYTHONUNBUFFERED'))
|
|
102
|
+
sys.dont_write_bytecode = sys.dont_write_bytecode or bool(os.environ.get('PYTHONDONTWRITEBYTECODE'))
|
|
103
|
+
safe_path = safe_path or bool(os.environ.get('PYTHONSAFEPATH'))
|
|
104
|
+
path = os.environ.get('PYTHONPATH')
|
|
105
|
+
if path:
|
|
106
|
+
sys.path[0:0] = [os.path.abspath(entry) for entry in path.split(os.pathsep)]
|
|
107
|
+
if os.environ.get('PYTHONWARNINGS'):
|
|
108
|
+
warning_options[0:0] = os.environ['PYTHONWARNINGS'].split(',')
|
|
109
|
+
encoding = os.environ.get('PYTHONIOENCODING')
|
|
110
|
+
if encoding:
|
|
111
|
+
name, separator, errors = encoding.partition(':')
|
|
112
|
+
for stream in (sys.stdin, sys.stdout):
|
|
113
|
+
stream.reconfigure(encoding=name or None, errors=(errors or 'strict'))
|
|
114
|
+
sys.stderr.reconfigure(encoding=name or None, errors='backslashreplace')
|
|
115
|
+
# CPython's -b/-bb filter follows environment and command-line -W filters.
|
|
116
|
+
byte_warning = ('error' if sys.flags.bytes_warning > 1 else 'default') + '::BytesWarning'
|
|
117
|
+
native_before = [value for value in native_warning_options if not (sys.flags.bytes_warning and value == byte_warning)]
|
|
118
|
+
warning_options = native_before + warning_options + ([byte_warning] if sys.flags.bytes_warning else [])
|
|
119
|
+
warnings._processoptions(warning_options)
|
|
120
|
+
sys.warnoptions[:] = warning_options
|
|
121
|
+
if unbuffered:
|
|
122
|
+
for name in ('stdout', 'stderr'):
|
|
123
|
+
stream = getattr(sys, name)
|
|
124
|
+
stream.flush()
|
|
125
|
+
encoding, errors = stream.encoding, stream.errors
|
|
126
|
+
binary = stream.detach()
|
|
127
|
+
raw = binary.detach() if hasattr(binary, 'detach') else binary
|
|
128
|
+
replacement = io.TextIOWrapper(raw, encoding=encoding, errors=errors, write_through=True)
|
|
129
|
+
setattr(sys, name, replacement)
|
|
130
|
+
setattr(sys, '__' + name + '__', replacement)
|
|
131
|
+
main = types.ModuleType('__main__')
|
|
132
|
+
main.__dict__.update(__package__=None, __spec__=None, __loader__=None, __builtins__=__builtins__)
|
|
133
|
+
sys.modules['__main__'] = main
|
|
134
|
+
if not options_terminated and args and args[0] == '-c':
|
|
135
|
+
sys.argv = ['-c'] + args[2:]
|
|
136
|
+
if not safe_path: sys.path.insert(0, '')
|
|
137
|
+
source = textwrap.dedent(args[1])
|
|
138
|
+
code = compile(source, '<string>', 'exec')
|
|
139
|
+
# CPython 3.14 retains -c source for both top-level and nested tracebacks.
|
|
140
|
+
linecache._register_code(code, source, '<string>')
|
|
141
|
+
exec(code, main.__dict__)
|
|
142
|
+
elif not options_terminated and args and args[0] == '-m':
|
|
143
|
+
sys.argv = args[1:]
|
|
144
|
+
if not safe_path: sys.path.insert(0, os.getcwd())
|
|
145
|
+
runpy._run_module_as_main(args[1], alter_argv=True)
|
|
146
|
+
elif not args or args[0] == '-':
|
|
147
|
+
sys.argv = (['-'] + args[1:]) if args else ['']
|
|
148
|
+
if not safe_path: sys.path.insert(0, '')
|
|
149
|
+
main.__file__ = '<stdin>'
|
|
150
|
+
exec(compile(sys.stdin.buffer.read(), '<stdin>', 'exec'), main.__dict__)
|
|
151
|
+
else:
|
|
152
|
+
sys.argv = args
|
|
153
|
+
# CPython makes __file__ absolute without collapsing ./ or ../ components.
|
|
154
|
+
path = args[0] if os.path.isabs(args[0]) else os.path.join(os.getcwd(), args[0])
|
|
155
|
+
importer = __import__('pkgutil').get_importer(path)
|
|
156
|
+
if importer is not None:
|
|
157
|
+
sys.path.insert(0, path)
|
|
158
|
+
runpy._run_module_as_main('__main__', alter_argv=False)
|
|
159
|
+
else:
|
|
160
|
+
if not safe_path: sys.path.insert(0, os.path.dirname(os.path.realpath(path)))
|
|
161
|
+
try:
|
|
162
|
+
with open(path, 'rb') as source:
|
|
163
|
+
code = source.read()
|
|
164
|
+
except OSError as error:
|
|
165
|
+
print("python: can't open file " + repr(path) + ': [Errno ' + str(error.errno) + '] ' + error.strerror, file=sys.stderr)
|
|
166
|
+
return 2
|
|
167
|
+
main.__file__ = path
|
|
168
|
+
main.__loader__ = __import__('importlib.machinery', fromlist=['SourceFileLoader']).SourceFileLoader('__main__', path)
|
|
169
|
+
exec(compile(code, path, 'exec'), main.__dict__)
|
|
170
|
+
return 0
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
_safe_exit = _safe_launch() or 0
|
|
174
|
+
except SystemExit as _error:
|
|
175
|
+
_safe_exit = _safe_system_exit(_error)
|
|
176
|
+
except _SafeOptionError as _error:
|
|
177
|
+
print('python: ' + str(_error), file=sys.stderr)
|
|
178
|
+
_safe_exit = 2
|
|
179
|
+
except BaseException as _error:
|
|
180
|
+
# Hide bridge frames while preserving actual Python frames and chained errors.
|
|
181
|
+
_trace = _error.__traceback__
|
|
182
|
+
while _trace is not None and _trace.tb_frame.f_code.co_filename == '<exec>':
|
|
183
|
+
_trace = _trace.tb_next
|
|
184
|
+
_error.__traceback__ = _trace
|
|
185
|
+
sys.last_exc = _error
|
|
186
|
+
_safe_exit = 130 if isinstance(_error, KeyboardInterrupt) else 1
|
|
187
|
+
try:
|
|
188
|
+
sys.excepthook(type(_error), _error, _trace)
|
|
189
|
+
except SystemExit as _hook_error:
|
|
190
|
+
_safe_exit = _safe_system_exit(_hook_error)
|
|
191
|
+
except BaseException as _hook_error:
|
|
192
|
+
print('Error in sys.excepthook:', file=sys.stderr)
|
|
193
|
+
traceback.print_exception(type(_hook_error), _hook_error, _hook_error.__traceback__.tb_next)
|
|
194
|
+
print('\\nOriginal exception was:', file=sys.stderr)
|
|
195
|
+
sys.__excepthook__(type(_error), _error, _trace)
|
|
196
|
+
finally:
|
|
197
|
+
for _stream in (sys.stdout, sys.stderr):
|
|
198
|
+
if _stream is not None and not getattr(_stream, 'closed', False):
|
|
199
|
+
try:
|
|
200
|
+
_stream.flush()
|
|
201
|
+
except BaseException:
|
|
202
|
+
_safe_exit = 120
|
|
203
|
+
_safe_exit
|
|
204
|
+
`;
|
|
205
|
+
|
|
206
|
+
// packages/safe-bash/src/commands/python/provisioning-runtime.ts
|
|
207
|
+
init_platform();
|
|
208
|
+
async function installPythonPackages(supplied, start, request, maxTransferBytes) {
|
|
209
|
+
if (start.requirements.length === 0) return;
|
|
210
|
+
const runtime = supplied;
|
|
211
|
+
if (runtime.version !== "314.0.6" || !runtime._api?.packageManager || !runtime._api.lockfile_packages || typeof runtime.loadPackage !== "function" || typeof runtime.runPythonAsync !== "function") throw new Error("Python package installer ABI requires Pyodide 314.0.6");
|
|
212
|
+
const fetch = (url, expected) => {
|
|
213
|
+
const opened = request("package-open", start.session, url, expected);
|
|
214
|
+
try {
|
|
215
|
+
const bytes = new Uint8Array(opened.size);
|
|
216
|
+
for (let offset = 0; offset < bytes.length; ) {
|
|
217
|
+
const chunk = request("package-read", start.session, opened.key, offset, Math.min(maxTransferBytes, 65536, bytes.length - offset));
|
|
218
|
+
if (!Array.isArray(chunk) || chunk.length === 0 || offset + chunk.length > bytes.length) throw new Error("Invalid Python package chunk");
|
|
219
|
+
bytes.set(chunk, offset);
|
|
220
|
+
offset += chunk.length;
|
|
221
|
+
}
|
|
222
|
+
return { bytes, headers: opened.headers };
|
|
223
|
+
} finally {
|
|
224
|
+
request("package-close", start.session, opened.key);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
runtime._api.packageManager.downloadPackage = async (metadata) => {
|
|
228
|
+
if (metadata.channel === runtime._api.packageManager.defaultChannel) {
|
|
229
|
+
const pkg = runtime._api.lockfile_packages[metadata.normalizedName];
|
|
230
|
+
if (!pkg) throw new Error(`Missing matching Pyodide package: ${metadata.normalizedName}`);
|
|
231
|
+
return fetch(new URL(pkg.file_name, "https://cdn.jsdelivr.net/pyodide/v314.0.6/full/").href, pkg.sha256).bytes;
|
|
232
|
+
}
|
|
233
|
+
return fetch(metadata.channel).bytes;
|
|
234
|
+
};
|
|
235
|
+
const loadPackages = async (names) => {
|
|
236
|
+
const errors = [];
|
|
237
|
+
await runtime.loadPackage(names, { messageCallback() {
|
|
238
|
+
}, errorCallback(message) {
|
|
239
|
+
errors.push(message);
|
|
240
|
+
} });
|
|
241
|
+
if (errors.length) throw new Error(errors.join("\n"));
|
|
242
|
+
};
|
|
243
|
+
const installedGlobals = [];
|
|
244
|
+
try {
|
|
245
|
+
await loadPackages(["micropip"]);
|
|
246
|
+
runtime.globals.set("_safe_package_native", loadPackages);
|
|
247
|
+
installedGlobals.push("_safe_package_native");
|
|
248
|
+
runtime.globals.set("_safe_package_bytes", (url, hash) => fetch(url, hash).bytes);
|
|
249
|
+
installedGlobals.push("_safe_package_bytes");
|
|
250
|
+
runtime.globals.set("_safe_package_metadata", (url) => {
|
|
251
|
+
const result = fetch(url);
|
|
252
|
+
return JSON.stringify({ text: new TextDecoder().decode(result.bytes), headers: Object.fromEntries(result.headers.map(([name, value]) => [name.toLowerCase(), value])) });
|
|
253
|
+
});
|
|
254
|
+
installedGlobals.push("_safe_package_metadata");
|
|
255
|
+
runtime.globals.set("_safe_package_requirements_json", JSON.stringify(start.requirements));
|
|
256
|
+
installedGlobals.push("_safe_package_requirements_json");
|
|
257
|
+
await runtime.runPythonAsync(`
|
|
258
|
+
import json as _safe_json
|
|
259
|
+
import micropip as _safe_micropip
|
|
260
|
+
from micropip._compat import compatibility_layer as _safe_compat
|
|
261
|
+
from micropip.package_manager import PackageManager as _SafePackageManager
|
|
262
|
+
from micropip.wheelinfo import WheelInfo as _SafeWheelInfo
|
|
263
|
+
from micropip._utils import check_compatible as _safe_check_compatible
|
|
264
|
+
from micropip._vendored.packaging.src.packaging.requirements import Requirement as _SafeRequirement, InvalidRequirement as _SafeInvalidRequirement
|
|
265
|
+
from micropip._vendored.packaging.src.packaging.utils import canonicalize_name as _safe_name
|
|
266
|
+
|
|
267
|
+
class _SafePackageCompatibility(_safe_compat):
|
|
268
|
+
@staticmethod
|
|
269
|
+
async def loadPackage(names):
|
|
270
|
+
return await _safe_package_native(names)
|
|
271
|
+
@staticmethod
|
|
272
|
+
async def fetch_bytes(url, kwargs):
|
|
273
|
+
return _safe_package_bytes(url).to_bytes()
|
|
274
|
+
@staticmethod
|
|
275
|
+
async def fetch_string_and_headers(url, kwargs):
|
|
276
|
+
value = _safe_json.loads(_safe_package_metadata(url))
|
|
277
|
+
return value['text'], value['headers']
|
|
278
|
+
|
|
279
|
+
# Require index/URL digests before publishing wheel bytes to the host cache.
|
|
280
|
+
# Local wheels are host-trusted inputs and receive a content digest on first read.
|
|
281
|
+
async def _safe_wheel_fetch(self, url, kwargs, compat):
|
|
282
|
+
expected = self.sha256 if url == self.url else None
|
|
283
|
+
if url == self.metadata_url and isinstance(self.core_metadata, dict):
|
|
284
|
+
expected = self.core_metadata.get('sha256')
|
|
285
|
+
return _safe_package_bytes(url, expected).to_bytes()
|
|
286
|
+
_SafeWheelInfo._fetch_bytes = _safe_wheel_fetch
|
|
287
|
+
_safe_manager = _SafePackageManager(_SafePackageCompatibility)
|
|
288
|
+
_safe_requirements = _safe_json.loads(_safe_package_requirements_json)
|
|
289
|
+
# A persisted base wheel may be visited before a newly requested extra. Micropip
|
|
290
|
+
# skips already locked names, so every occurrence must carry the requested extras.
|
|
291
|
+
_safe_roots = []
|
|
292
|
+
_safe_extras = {}
|
|
293
|
+
for _safe_source in _safe_requirements:
|
|
294
|
+
try:
|
|
295
|
+
_safe_root = _SafeRequirement(_safe_source)
|
|
296
|
+
if _safe_root.name.endswith('.whl'):
|
|
297
|
+
raise _SafeInvalidRequirement(_safe_source)
|
|
298
|
+
except _SafeInvalidRequirement:
|
|
299
|
+
_safe_wheel = _SafeWheelInfo.from_url(_safe_source)
|
|
300
|
+
_safe_root = _SafeRequirement(_safe_wheel.name + ' @ ' + _safe_source)
|
|
301
|
+
_safe_roots.append(_safe_root)
|
|
302
|
+
if not _safe_root.marker or _safe_root.marker.evaluate({'extra': ''}):
|
|
303
|
+
# Named requirements may be skipped when already locked. Validate direct
|
|
304
|
+
# wheels even then, rather than letting an incompatible URL report success.
|
|
305
|
+
if _safe_root.url:
|
|
306
|
+
_safe_direct_wheel = _SafeWheelInfo.from_url(_safe_root.url)
|
|
307
|
+
_safe_check_compatible(_safe_direct_wheel.filename)
|
|
308
|
+
# Validate the actual archive and host-checked digest even if micropip's
|
|
309
|
+
# satisfied-name fast path will skip installing this explicit operand.
|
|
310
|
+
await _safe_direct_wheel.download({}, _SafePackageCompatibility)
|
|
311
|
+
_safe_extras.setdefault(_safe_name(_safe_root.name), set()).update(_safe_root.extras)
|
|
312
|
+
for _safe_root in _safe_roots:
|
|
313
|
+
_safe_root.extras.update(_safe_extras.get(_safe_name(_safe_root.name), set()))
|
|
314
|
+
await _safe_manager.install([str(root) for root in _safe_roots], deps=True)
|
|
315
|
+
# Resolve selected extras from distribution metadata, including extras added to
|
|
316
|
+
# an already satisfied transitive dependency. Micropip skips those names early.
|
|
317
|
+
# Keep its installer and conflict policy; do not infer dependencies from imports.
|
|
318
|
+
import importlib.metadata as _safe_metadata
|
|
319
|
+
_safe_previous_pending = None
|
|
320
|
+
while True:
|
|
321
|
+
_safe_distributions = [d for d in _safe_metadata.distributions() if d.metadata['Name']]
|
|
322
|
+
_safe_versions = {_safe_name(d.metadata['Name']): d.version for d in _safe_distributions}
|
|
323
|
+
while True:
|
|
324
|
+
_safe_changed = False
|
|
325
|
+
_safe_dependencies = []
|
|
326
|
+
for _safe_dist in _safe_distributions:
|
|
327
|
+
_safe_contexts = {''} | _safe_extras.get(_safe_name(_safe_dist.metadata['Name']), set())
|
|
328
|
+
for _safe_dep in _safe_dist.requires or []:
|
|
329
|
+
_safe_requirement = _SafeRequirement(_safe_dep)
|
|
330
|
+
if _safe_requirement.marker and not any(_safe_requirement.marker.evaluate({'extra': extra}) for extra in _safe_contexts):
|
|
331
|
+
continue
|
|
332
|
+
# The marker belongs to the requesting distribution's extra context, already
|
|
333
|
+
# evaluated above; a separate installer transaction must not reinterpret it.
|
|
334
|
+
_safe_requirement.marker = None
|
|
335
|
+
_safe_dependencies.append(_safe_requirement)
|
|
336
|
+
_safe_selected = _safe_extras.setdefault(_safe_name(_safe_requirement.name), set())
|
|
337
|
+
if not _safe_requirement.extras.issubset(_safe_selected):
|
|
338
|
+
_safe_selected.update(_safe_requirement.extras)
|
|
339
|
+
_safe_changed = True
|
|
340
|
+
if not _safe_changed:
|
|
341
|
+
break
|
|
342
|
+
_safe_pending = set()
|
|
343
|
+
for _safe_requirement in _safe_dependencies:
|
|
344
|
+
_safe_version = _safe_versions.get(_safe_name(_safe_requirement.name))
|
|
345
|
+
if _safe_version is None:
|
|
346
|
+
_safe_pending.add(str(_safe_requirement))
|
|
347
|
+
elif not _safe_requirement.specifier.contains(_safe_version, prereleases=True):
|
|
348
|
+
raise ValueError('Python package dependency conflict: ' + str(_safe_requirement))
|
|
349
|
+
if not _safe_pending:
|
|
350
|
+
break
|
|
351
|
+
if _safe_pending == _safe_previous_pending:
|
|
352
|
+
raise ValueError('Python package dependencies remain missing: ' + ', '.join(sorted(_safe_pending)))
|
|
353
|
+
_safe_previous_pending = _safe_pending
|
|
354
|
+
await _safe_manager.install(sorted(_safe_pending), deps=True)
|
|
355
|
+
# Explicit roots also constrain the result: direct URLs can bypass micropip's
|
|
356
|
+
# already-installed version check, including when another root pins that name.
|
|
357
|
+
for _safe_root in _safe_roots:
|
|
358
|
+
if _safe_root.marker and not _safe_root.marker.evaluate({'extra': ''}):
|
|
359
|
+
continue
|
|
360
|
+
_safe_version = _safe_versions.get(_safe_name(_safe_root.name))
|
|
361
|
+
if _safe_version is None or not _safe_root.specifier.contains(_safe_version, prereleases=True):
|
|
362
|
+
raise ValueError('Python package version conflict: ' + str(_safe_root))
|
|
363
|
+
if _safe_root.url:
|
|
364
|
+
_safe_wheel = _SafeWheelInfo.from_url(_safe_root.url)
|
|
365
|
+
_safe_wheel_pin = _SafeRequirement(_safe_wheel.name + '==' + str(_safe_wheel.version))
|
|
366
|
+
if _safe_name(_safe_wheel.name) != _safe_name(_safe_root.name) or not _safe_wheel_pin.specifier.contains(_safe_version, prereleases=True):
|
|
367
|
+
raise ValueError('Python package wheel version conflict: ' + str(_safe_root))
|
|
368
|
+
_safe_installed_json = _safe_json.dumps([name + '==' + version for name, version in sorted(_safe_versions.items())])
|
|
369
|
+
`);
|
|
370
|
+
const pinned = JSON.parse(runtime.runPython("_safe_installed_json"));
|
|
371
|
+
request("package-commit", start.session, pinned);
|
|
372
|
+
} finally {
|
|
373
|
+
runtime._api.packageManager.downloadPackage = async () => {
|
|
374
|
+
throw new Error("Python package transport is only available during installation");
|
|
375
|
+
};
|
|
376
|
+
for (const name of installedGlobals) runtime.globals.delete(name);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// packages/safe-bash/src/commands/python/worker.ts
|
|
381
|
+
function createPythonWorkerRequest(shared, postMessage, error) {
|
|
382
|
+
const control = new Int32Array(shared, 0, 2);
|
|
383
|
+
const payload = new Uint8Array(shared, 8);
|
|
384
|
+
return (op, ...args) => {
|
|
385
|
+
Atomics.store(control, 0, 0);
|
|
386
|
+
postMessage({ op, args });
|
|
387
|
+
while (Atomics.load(control, 0) === 0) Atomics.wait(control, 0, 0);
|
|
388
|
+
const length = Atomics.load(control, 1);
|
|
389
|
+
if (length < 0 || length > payload.length) throw error("EIO");
|
|
390
|
+
const result = JSON.parse(new TextDecoder().decode(payload.slice(0, length)));
|
|
391
|
+
if (Atomics.load(control, 0) !== 1) {
|
|
392
|
+
if (op.startsWith("package-") && typeof result.message === "string") throw new Error(result.message);
|
|
393
|
+
throw error(result.code ?? "EIO");
|
|
394
|
+
}
|
|
395
|
+
return result;
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
var relocateRuntime = `
|
|
399
|
+
import sys, zipimport, importlib.machinery
|
|
400
|
+
|
|
401
|
+
def _rebase_runtime_path(value):
|
|
402
|
+
return _safe_runtime_mount + value if isinstance(value, str) and (value == '/lib' or value.startswith('/lib/')) else value
|
|
403
|
+
|
|
404
|
+
def _rebase_runtime_loader(loader):
|
|
405
|
+
if isinstance(loader, zipimport.zipimporter):
|
|
406
|
+
archive = _rebase_runtime_path(loader.archive)
|
|
407
|
+
if archive != loader.archive:
|
|
408
|
+
return zipimport.zipimporter(archive + '/' + loader.prefix)
|
|
409
|
+
elif isinstance(loader, (importlib.machinery.SourceFileLoader, importlib.machinery.SourcelessFileLoader, importlib.machinery.ExtensionFileLoader)):
|
|
410
|
+
path = _rebase_runtime_path(loader.path)
|
|
411
|
+
if path != loader.path:
|
|
412
|
+
return type(loader)(loader.name, path)
|
|
413
|
+
return loader
|
|
414
|
+
sys.path[:] = [_rebase_runtime_path(value) for value in sys.path]
|
|
415
|
+
for _module in list(sys.modules.values()):
|
|
416
|
+
if _module is None:
|
|
417
|
+
continue
|
|
418
|
+
for _attribute in ('__file__', '__cached__'):
|
|
419
|
+
if hasattr(_module, _attribute):
|
|
420
|
+
setattr(_module, _attribute, _rebase_runtime_path(getattr(_module, _attribute)))
|
|
421
|
+
if hasattr(_module, '__path__'):
|
|
422
|
+
_module.__path__ = [_rebase_runtime_path(value) for value in _module.__path__]
|
|
423
|
+
if hasattr(_module, '__loader__'):
|
|
424
|
+
_module.__loader__ = _rebase_runtime_loader(_module.__loader__)
|
|
425
|
+
_spec = getattr(_module, '__spec__', None)
|
|
426
|
+
if _spec is not None:
|
|
427
|
+
_spec.origin = _rebase_runtime_path(_spec.origin)
|
|
428
|
+
_spec.loader = _rebase_runtime_loader(_spec.loader)
|
|
429
|
+
if _spec.submodule_search_locations is not None:
|
|
430
|
+
_spec.submodule_search_locations = [_rebase_runtime_path(value) for value in _spec.submodule_search_locations]
|
|
431
|
+
sys.path_importer_cache.clear()
|
|
432
|
+
`;
|
|
433
|
+
async function loadPythonRuntime(load) {
|
|
434
|
+
const wasm = globalThis.WebAssembly;
|
|
435
|
+
const instantiate = wasm.instantiate;
|
|
436
|
+
const instantiateStreaming = wasm.instantiateStreaming;
|
|
437
|
+
let protectedSystem = false;
|
|
438
|
+
let protectedSockets = false;
|
|
439
|
+
const restrict = (imports) => {
|
|
440
|
+
const env = imports?.env;
|
|
441
|
+
if (!env) return;
|
|
442
|
+
if (typeof env._emscripten_system === "function") {
|
|
443
|
+
env._emscripten_system = (command) => command === 0 ? 0 : -52;
|
|
444
|
+
protectedSystem = true;
|
|
445
|
+
}
|
|
446
|
+
if (typeof env.__syscall_socket === "function") protectedSockets = true;
|
|
447
|
+
for (const name of ["__syscall_socket", "__syscall_connect", "__syscall_bind", "__syscall_listen", "__syscall_accept4", "__syscall_sendto", "__syscall_sendmsg", "_maybe_connect_async"]) {
|
|
448
|
+
if (typeof env[name] === "function") env[name] = () => -52;
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
wasm.instantiate = ((source, imports) => {
|
|
452
|
+
restrict(imports);
|
|
453
|
+
return instantiate(source, imports);
|
|
454
|
+
});
|
|
455
|
+
if (instantiateStreaming) wasm.instantiateStreaming = (source, imports) => {
|
|
456
|
+
restrict(imports);
|
|
457
|
+
return instantiateStreaming(source, imports);
|
|
458
|
+
};
|
|
459
|
+
try {
|
|
460
|
+
const runtime = await load();
|
|
461
|
+
if (!protectedSystem || !protectedSockets) throw new Error("Python native syscall isolation ABI unavailable");
|
|
462
|
+
const unavailable = () => {
|
|
463
|
+
throw new Error("Host filesystem and native socket capabilities are unavailable");
|
|
464
|
+
};
|
|
465
|
+
const api = runtime;
|
|
466
|
+
for (const name of ["mountNodeFS", "mountNativeFS", "useNodeSockFS"]) {
|
|
467
|
+
if (name in api) api[name] = unavailable;
|
|
468
|
+
}
|
|
469
|
+
if (runtime.FS?.filesystems) delete runtime.FS.filesystems.NODEFS;
|
|
470
|
+
if (runtime._module) {
|
|
471
|
+
delete runtime._module.NODEFS;
|
|
472
|
+
if ("__emscripten_system" in runtime._module) runtime._module.__emscripten_system = (command) => command === 0 ? 0 : -52;
|
|
473
|
+
if (runtime._module.SOCKFS) runtime._module.SOCKFS.createSocket = unavailable;
|
|
474
|
+
}
|
|
475
|
+
return runtime;
|
|
476
|
+
} finally {
|
|
477
|
+
wasm.instantiate = instantiate;
|
|
478
|
+
if (instantiateStreaming) wasm.instantiateStreaming = instantiateStreaming;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
async function runPythonWorker(options) {
|
|
482
|
+
const { start, postMessage } = options;
|
|
483
|
+
try {
|
|
484
|
+
const startupRequest = createPythonWorkerRequest(start.shared, postMessage, (code) => new Error(code));
|
|
485
|
+
const startupWrite = (stream, message) => {
|
|
486
|
+
const bytes = new TextEncoder().encode(message + "\n");
|
|
487
|
+
for (let offset = 0; offset < bytes.length; offset += start.maxTransferBytes) {
|
|
488
|
+
startupRequest(stream, Array.from(bytes.subarray(offset, offset + start.maxTransferBytes)));
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
let configuration;
|
|
492
|
+
try {
|
|
493
|
+
configuration = parsePythonInvocation(start.invocation.args, start.invocation.env);
|
|
494
|
+
} catch (error) {
|
|
495
|
+
startupWrite("stderr", "python: " + (error instanceof Error ? error.message : String(error)));
|
|
496
|
+
postMessage({ type: "exit", exitCode: 2 });
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const runtime = await loadPythonRuntime(() => options.loadRuntime({
|
|
500
|
+
jsglobals: /* @__PURE__ */ Object.create(null),
|
|
501
|
+
args: [...configuration.startupArgs],
|
|
502
|
+
env: { ...configuration.env },
|
|
503
|
+
stdout: (message) => {
|
|
504
|
+
startupWrite("stdout", message);
|
|
505
|
+
},
|
|
506
|
+
stderr: (message) => {
|
|
507
|
+
startupWrite("stderr", message);
|
|
508
|
+
}
|
|
509
|
+
}));
|
|
510
|
+
if (runtime.version !== "314.0.6") throw new Error("Python worker requires Pyodide 314.0.6");
|
|
511
|
+
if (start.packages) await installPythonPackages(runtime, start.packages, startupRequest, start.maxTransferBytes);
|
|
512
|
+
const unavailablePackage = () => {
|
|
513
|
+
throw new Error("Python package transport is only available during installation");
|
|
514
|
+
};
|
|
515
|
+
const publicRuntime = runtime;
|
|
516
|
+
if ("loadPackage" in publicRuntime) publicRuntime.loadPackage = unavailablePackage;
|
|
517
|
+
if (publicRuntime._api?.packageManager) publicRuntime._api.packageManager.downloadPackage = unavailablePackage;
|
|
518
|
+
if (start.installOnly) {
|
|
519
|
+
startupWrite("stdout", "Successfully installed requested Python packages");
|
|
520
|
+
postMessage({ type: "exit", exitCode: 0 });
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const errno = JSON.parse(runtime.runPython("__import__('json').dumps({k:v for k,v in vars(__import__('errno')).items() if k.startswith('E') and isinstance(v,int)})"));
|
|
524
|
+
const request = createPythonWorkerRequest(start.shared, postMessage, (code) => new runtime.FS.ErrnoError(errno[code] ?? errno.EIO));
|
|
525
|
+
const libraries = runtime._module?.LDSO?.loadedLibsByName;
|
|
526
|
+
if (!libraries) throw new Error("Python runtime native loader ABI unavailable");
|
|
527
|
+
if (typeof runtime._module._Py_FinalizeEx !== "function") throw new Error("Python runtime finalization ABI unavailable");
|
|
528
|
+
runtime.runPython("import sys, zipimport, importlib.machinery, json, os, runpy, traceback");
|
|
529
|
+
runtime.setStdin({ read(buffer) {
|
|
530
|
+
const bytes = request("stdin", Math.min(buffer.length, start.maxTransferBytes));
|
|
531
|
+
if (!Array.isArray(bytes) || bytes.length > buffer.length) throw new runtime.FS.ErrnoError(errno.EIO);
|
|
532
|
+
buffer.set(bytes);
|
|
533
|
+
return bytes.length;
|
|
534
|
+
} });
|
|
535
|
+
for (const [name, configure] of [
|
|
536
|
+
["stdout", runtime.setStdout.bind(runtime)],
|
|
537
|
+
["stderr", runtime.setStderr.bind(runtime)]
|
|
538
|
+
]) {
|
|
539
|
+
configure({ write(buffer) {
|
|
540
|
+
let offset = 0;
|
|
541
|
+
while (offset < buffer.length) {
|
|
542
|
+
const chunk = Array.from(Uint8Array.from(buffer.subarray(offset, offset + start.maxTransferBytes)));
|
|
543
|
+
try {
|
|
544
|
+
request(name, chunk);
|
|
545
|
+
} catch (error) {
|
|
546
|
+
if (offset) return offset;
|
|
547
|
+
throw error;
|
|
548
|
+
}
|
|
549
|
+
offset += chunk.length;
|
|
550
|
+
}
|
|
551
|
+
return offset;
|
|
552
|
+
} });
|
|
553
|
+
}
|
|
554
|
+
mountPythonFileSystem(runtime.FS, {
|
|
555
|
+
request,
|
|
556
|
+
cwd: start.invocation.cwd,
|
|
557
|
+
runtimeMount: start.runtimeMount,
|
|
558
|
+
maxTransferBytes: start.maxTransferBytes,
|
|
559
|
+
errno,
|
|
560
|
+
runtimeModule: runtime._module,
|
|
561
|
+
synchronizationFlags: runtime.runPython("__import__('os').O_SYNC | __import__('os').O_DSYNC")
|
|
562
|
+
});
|
|
563
|
+
for (const [name, library] of Object.entries(libraries)) {
|
|
564
|
+
if (name.startsWith("/lib/")) libraries[start.runtimeMount + name] = library;
|
|
565
|
+
}
|
|
566
|
+
runtime.globals.set("_safe_runtime_mount", start.runtimeMount);
|
|
567
|
+
runtime.runPython(relocateRuntime);
|
|
568
|
+
runtime.globals.set("_safe_import_stat", (path) => {
|
|
569
|
+
try {
|
|
570
|
+
const stat = runtime.FS.stat(path);
|
|
571
|
+
return JSON.stringify({ mode: stat.mode, size: stat.size, mtimeMs: stat.mtimeMs ?? stat.mtime.getTime() });
|
|
572
|
+
} catch (error) {
|
|
573
|
+
return JSON.stringify({ errno: error.errno ?? errno.EIO });
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
runtime.runPython(`
|
|
577
|
+
import importlib._bootstrap_external, types, json
|
|
578
|
+
_safe_import_stat_callback = _safe_import_stat
|
|
579
|
+
_safe_original_import_stat = importlib._bootstrap_external._path_stat
|
|
580
|
+
def _safe_import_path_stat(path):
|
|
581
|
+
if path == _safe_runtime_mount or path.startswith(_safe_runtime_mount + '/'):
|
|
582
|
+
return _safe_original_import_stat(path)
|
|
583
|
+
value = json.loads(_safe_import_stat_callback(path))
|
|
584
|
+
if 'errno' in value:
|
|
585
|
+
raise OSError(value['errno'], 'filesystem import metadata unavailable', path)
|
|
586
|
+
return types.SimpleNamespace(st_mode=value['mode'], st_size=value['size'], st_mtime=value['mtimeMs'] / 1000)
|
|
587
|
+
importlib._bootstrap_external._path_stat = _safe_import_path_stat
|
|
588
|
+
`);
|
|
589
|
+
runtime.globals.set("_safe_directory_entries", (path) => {
|
|
590
|
+
try {
|
|
591
|
+
return JSON.stringify({ entries: runtime.FS.readdir(path).filter((name) => name !== "." && name !== "..") });
|
|
592
|
+
} catch (error) {
|
|
593
|
+
return JSON.stringify({ errno: error.errno ?? errno.EIO });
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
runtime.runPython(`
|
|
597
|
+
import os, json, errno
|
|
598
|
+
_safe_directory_callback = _safe_directory_entries
|
|
599
|
+
def _safe_listdir(path='.'):
|
|
600
|
+
if isinstance(path, int):
|
|
601
|
+
raise OSError(errno.ENOTSUP, 'retained directory descriptors are unsupported')
|
|
602
|
+
original = os.fspath(path) if path is not None else '.'
|
|
603
|
+
value = json.loads(_safe_directory_callback(os.fsdecode(original)))
|
|
604
|
+
if 'errno' in value:
|
|
605
|
+
raise OSError(value['errno'], 'directory enumeration failed', path)
|
|
606
|
+
return [os.fsencode(name) for name in value['entries']] if isinstance(original, bytes) else value['entries']
|
|
607
|
+
os.listdir = _safe_listdir
|
|
608
|
+
# The frozen importer holds the posix module separately from os.
|
|
609
|
+
importlib._bootstrap_external._os.listdir = _safe_listdir
|
|
610
|
+
`);
|
|
611
|
+
runtime.globals.set("_safe_stat_projection", (path, follow) => {
|
|
612
|
+
try {
|
|
613
|
+
const value = typeof path === "number" ? runtime.FS.fstat(path) : follow ? runtime.FS.stat(path) : runtime.FS.lstat(path);
|
|
614
|
+
return JSON.stringify({
|
|
615
|
+
mode: value.mode,
|
|
616
|
+
ino: value.ino,
|
|
617
|
+
dev: value.dev,
|
|
618
|
+
nlink: value.nlink,
|
|
619
|
+
uid: value.uid,
|
|
620
|
+
gid: value.gid,
|
|
621
|
+
size: value.size,
|
|
622
|
+
atimeMs: value.atimeMs ?? value.atime.getTime(),
|
|
623
|
+
mtimeMs: value.mtimeMs ?? value.mtime.getTime(),
|
|
624
|
+
ctimeMs: value.ctimeMs ?? value.ctime.getTime(),
|
|
625
|
+
blocks: value.blocks,
|
|
626
|
+
blksize: value.blksize,
|
|
627
|
+
rdev: value.rdev
|
|
628
|
+
});
|
|
629
|
+
} catch (error) {
|
|
630
|
+
return JSON.stringify({ errno: error.errno ?? errno.EIO });
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
runtime.runPython(`
|
|
634
|
+
import os, json, errno
|
|
635
|
+
_safe_stat_callback = _safe_stat_projection
|
|
636
|
+
_safe_stat_type = os.stat_result
|
|
637
|
+
_safe_fspath = os.fspath
|
|
638
|
+
_safe_fsdecode = os.fsdecode
|
|
639
|
+
|
|
640
|
+
def _safe_stat(path, *, dir_fd=None, follow_symlinks=True):
|
|
641
|
+
if dir_fd is not None:
|
|
642
|
+
raise OSError(errno.ENOTSUP, 'dir_fd metadata is unsupported')
|
|
643
|
+
if isinstance(path, int):
|
|
644
|
+
if not follow_symlinks:
|
|
645
|
+
raise ValueError('stat: cannot use fd and follow_symlinks together')
|
|
646
|
+
else:
|
|
647
|
+
path = _safe_fsdecode(_safe_fspath(path))
|
|
648
|
+
value = json.loads(_safe_stat_callback(path, follow_symlinks))
|
|
649
|
+
if 'errno' in value:
|
|
650
|
+
raise OSError(value['errno'], 'filesystem metadata unavailable', path)
|
|
651
|
+
keys = ('mode','ino','dev','nlink','uid','gid','size')
|
|
652
|
+
if any(key not in value for key in keys):
|
|
653
|
+
raise OSError(errno.EOVERFLOW, 'canonical identity or required stat metadata unavailable', path)
|
|
654
|
+
times = [value[key] / 1000 for key in ('atimeMs','mtimeMs','ctimeMs')]
|
|
655
|
+
extras = dict(zip(('st_atime','st_mtime','st_ctime'), times))
|
|
656
|
+
for name, milliseconds in zip(('atime','mtime','ctime'), (value['atimeMs'],value['mtimeMs'],value['ctimeMs'])):
|
|
657
|
+
seconds = int(milliseconds // 1000)
|
|
658
|
+
extras['st_' + name + '_ns'] = seconds * 1000000000 + round((milliseconds - seconds * 1000) * 1000000)
|
|
659
|
+
for key in ('blocks','blksize','rdev'):
|
|
660
|
+
if key in value:
|
|
661
|
+
extras['st_' + key] = value[key]
|
|
662
|
+
return _safe_stat_type(tuple(value[key] for key in keys) + tuple(int(time // 1) for time in times), extras)
|
|
663
|
+
|
|
664
|
+
def _safe_lstat(path, *, dir_fd=None):
|
|
665
|
+
return _safe_stat(path, dir_fd=dir_fd, follow_symlinks=False)
|
|
666
|
+
|
|
667
|
+
def _safe_fstat(fd):
|
|
668
|
+
if not isinstance(fd, int):
|
|
669
|
+
raise TypeError('file descriptor must be an integer')
|
|
670
|
+
return _safe_stat(fd)
|
|
671
|
+
os.stat = _safe_stat
|
|
672
|
+
os.lstat = _safe_lstat
|
|
673
|
+
os.fstat = _safe_fstat
|
|
674
|
+
import stat as _safe_stat_module
|
|
675
|
+
class _SafeDirEntry:
|
|
676
|
+
def __init__(self, root, name):
|
|
677
|
+
self.name = name
|
|
678
|
+
self.path = os.path.join(root, name)
|
|
679
|
+
self._cache = {}
|
|
680
|
+
def __fspath__(self):
|
|
681
|
+
return self.path
|
|
682
|
+
def stat(self, *, follow_symlinks=True):
|
|
683
|
+
if follow_symlinks not in self._cache:
|
|
684
|
+
self._cache[follow_symlinks] = os.stat(self.path, follow_symlinks=follow_symlinks)
|
|
685
|
+
return self._cache[follow_symlinks]
|
|
686
|
+
def inode(self):
|
|
687
|
+
return self.stat(follow_symlinks=False).st_ino
|
|
688
|
+
def is_dir(self, *, follow_symlinks=True):
|
|
689
|
+
try:
|
|
690
|
+
return _safe_stat_module.S_ISDIR(self.stat(follow_symlinks=follow_symlinks).st_mode)
|
|
691
|
+
except FileNotFoundError:
|
|
692
|
+
return False
|
|
693
|
+
def is_file(self, *, follow_symlinks=True):
|
|
694
|
+
try:
|
|
695
|
+
return _safe_stat_module.S_ISREG(self.stat(follow_symlinks=follow_symlinks).st_mode)
|
|
696
|
+
except FileNotFoundError:
|
|
697
|
+
return False
|
|
698
|
+
def is_symlink(self):
|
|
699
|
+
try:
|
|
700
|
+
return _safe_stat_module.S_ISLNK(self.stat(follow_symlinks=False).st_mode)
|
|
701
|
+
except FileNotFoundError:
|
|
702
|
+
return False
|
|
703
|
+
class _SafeScandir:
|
|
704
|
+
def __init__(self, path):
|
|
705
|
+
self._entries = iter([_SafeDirEntry(path, name) for name in os.listdir(path)])
|
|
706
|
+
def __iter__(self):
|
|
707
|
+
return self
|
|
708
|
+
def __next__(self):
|
|
709
|
+
return next(self._entries)
|
|
710
|
+
def close(self):
|
|
711
|
+
self._entries = iter(())
|
|
712
|
+
def __enter__(self):
|
|
713
|
+
return self
|
|
714
|
+
def __exit__(self, *args):
|
|
715
|
+
self.close()
|
|
716
|
+
def _safe_scandir(path='.'):
|
|
717
|
+
if isinstance(path, int):
|
|
718
|
+
raise OSError(errno.ENOTSUP, 'retained directory descriptors are unsupported')
|
|
719
|
+
return _SafeScandir(os.fspath(path) if path is not None else '.')
|
|
720
|
+
os.scandir = _safe_scandir
|
|
721
|
+
|
|
722
|
+
`);
|
|
723
|
+
runtime.globals.set("_safe_invocation_json", JSON.stringify(start.invocation));
|
|
724
|
+
postMessage({ type: "ready" });
|
|
725
|
+
const exitCode = runtime.runPython(pythonExecution);
|
|
726
|
+
const finalized = runtime._module._Py_FinalizeEx();
|
|
727
|
+
postMessage({ type: "exit", exitCode: finalized < 0 ? 120 : Number(exitCode) & 255 });
|
|
728
|
+
} catch (error) {
|
|
729
|
+
postMessage({ type: "error", message: String(error) });
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
export {
|
|
733
|
+
createPythonWorkerRequest,
|
|
734
|
+
runPythonWorker
|
|
735
|
+
};
|
|
736
|
+
//# sourceMappingURL=worker.browser.js.map
|