diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..53a1c12c --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,10 @@ +[alias] +xtask = "run --package xtask --" +x = "run --package xtask --" + +[build] +rustflags = [ + # for use with tokio-rs/console + "--cfg", + "tokio_unstable" +] diff --git a/.ghjk/deno.lock b/.ghjk/deno.lock index fbcc9519..8ec1e4b0 100644 --- a/.ghjk/deno.lock +++ b/.ghjk/deno.lock @@ -1,93 +1,95 @@ { - "version": "3", - "packages": { - "specifiers": { - "jsr:@david/dax@0.41.0": "jsr:@david/dax@0.41.0", - "jsr:@david/which@^0.4.1": "jsr:@david/which@0.4.1", - "jsr:@std/assert@^0.221.0": "jsr:@std/assert@0.221.0", - "jsr:@std/bytes@^0.221.0": "jsr:@std/bytes@0.221.0", - "jsr:@std/fmt@^0.221.0": "jsr:@std/fmt@0.221.0", - "jsr:@std/fs@0.221.0": "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/io@^0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/path@^0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0": "jsr:@std/streams@0.221.0", - "npm:@noble/hashes@1.4.0": "npm:@noble/hashes@1.4.0", - "npm:multiformats@13.1.0": "npm:multiformats@13.1.0", - "npm:zod-validation-error@3.3.0": "npm:zod-validation-error@3.3.0_zod@3.23.8", - "npm:zod@3.23.8": "npm:zod@3.23.8" + "version": "4", + "specifiers": { + "jsr:@david/dax@0.41.0": "0.41.0", + "jsr:@david/which@~0.4.1": "0.4.1", + "jsr:@std/assert@0.221": "0.221.0", + "jsr:@std/bytes@0.221": "0.221.0", + "jsr:@std/fmt@0.221": "0.221.0", + "jsr:@std/fs@0.221.0": "0.221.0", + "jsr:@std/io@0.221": "0.221.0", + "jsr:@std/io@0.221.0": "0.221.0", + "jsr:@std/path@0.221": "0.221.0", + "jsr:@std/path@0.221.0": "0.221.0", + "jsr:@std/streams@0.221.0": "0.221.0", + "npm:@noble/hashes@1.4.0": "1.4.0", + "npm:multiformats@13.1.0": "13.1.0", + "npm:zod-validation-error@3.3.0": "3.3.0_zod@3.23.8", + "npm:zod-validation-error@3.4.0": "3.4.0_zod@3.23.8", + "npm:zod@3.23.8": "3.23.8" + }, + "jsr": { + "@david/dax@0.41.0": { + "integrity": "9e1ecf66a0415962cc8ad3ba4e3fa93ce0f1a1cc797dd95c36fdfb6977dc7fc8", + "dependencies": [ + "jsr:@david/which", + "jsr:@std/fmt", + "jsr:@std/fs", + "jsr:@std/io@0.221.0", + "jsr:@std/path@0.221.0", + "jsr:@std/streams" + ] + }, + "@david/which@0.4.1": { + "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" + }, + "@std/assert@0.221.0": { + "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" + }, + "@std/bytes@0.221.0": { + "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" + }, + "@std/fmt@0.221.0": { + "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" + }, + "@std/fs@0.221.0": { + "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/path@0.221" + ] + }, + "@std/io@0.221.0": { + "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/bytes" + ] + }, + "@std/path@0.221.0": { + "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", + "dependencies": [ + "jsr:@std/assert" + ] + }, + "@std/streams@0.221.0": { + "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", + "dependencies": [ + "jsr:@std/io@0.221" + ] + } + }, + "npm": { + "@noble/hashes@1.4.0": { + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==" + }, + "multiformats@13.1.0": { + "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==" + }, + "zod-validation-error@3.3.0_zod@3.23.8": { + "integrity": "sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw==", + "dependencies": [ + "zod" + ] }, - "jsr": { - "@david/dax@0.41.0": { - "integrity": "9e1ecf66a0415962cc8ad3ba4e3fa93ce0f1a1cc797dd95c36fdfb6977dc7fc8", - "dependencies": [ - "jsr:@david/which@^0.4.1", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@david/which@0.4.1": { - "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" - }, - "@std/assert@0.221.0": { - "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" - }, - "@std/bytes@0.221.0": { - "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" - }, - "@std/fmt@0.221.0": { - "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" - }, - "@std/fs@0.221.0": { - "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/path@^0.221.0" - ] - }, - "@std/io@0.221.0": { - "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/bytes@^0.221.0" - ] - }, - "@std/path@0.221.0": { - "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", - "dependencies": [ - "jsr:@std/assert@^0.221.0" - ] - }, - "@std/streams@0.221.0": { - "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", - "dependencies": [ - "jsr:@std/io@^0.221.0" - ] - } + "zod-validation-error@3.4.0_zod@3.23.8": { + "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==", + "dependencies": [ + "zod" + ] }, - "npm": { - "@noble/hashes@1.4.0": { - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dependencies": {} - }, - "multiformats@13.1.0": { - "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==", - "dependencies": {} - }, - "zod-validation-error@3.3.0_zod@3.23.8": { - "integrity": "sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw==", - "dependencies": { - "zod": "zod@3.23.8" - } - }, - "zod@3.23.8": { - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "dependencies": {} - } + "zod@3.23.8": { + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" } }, "remote": { @@ -394,145 +396,8 @@ "https://deno.land/x/foras@v2.1.4/wasm/pkg/foras.wasm.js": "2df8522df7243b0f05b1d188e220629cd5d2c92080a5f1407e15396fc35bebb3", "https://deno.land/x/json_hash@0.2.0/canon.ts": "ce7c07abd871cd7f0eb1280ad9f58f6382f02f84a217898ce977cf35ad315877", "https://deno.land/x/jszip@0.11.0/mod.ts": "5661ddc18e9ac9c07e3c5d2483bc912a7022b6af0d784bb7b05035973e640ba1", - "https://deno.land/x/zod@v3.23.8/ZodError.ts": "528da200fbe995157b9ae91498b103c4ef482217a5c086249507ac850bd78f52", - "https://deno.land/x/zod@v3.23.8/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", - "https://deno.land/x/zod@v3.23.8/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", - "https://deno.land/x/zod@v3.23.8/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", - "https://deno.land/x/zod@v3.23.8/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", - "https://deno.land/x/zod@v3.23.8/helpers/parseUtil.ts": "c14814d167cc286972b6e094df88d7d982572a08424b7cd50f862036b6fcaa77", - "https://deno.land/x/zod@v3.23.8/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", - "https://deno.land/x/zod@v3.23.8/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", - "https://deno.land/x/zod@v3.23.8/helpers/util.ts": "30c273131661ca5dc973f2cfb196fa23caf3a43e224cdde7a683b72e101a31fc", - "https://deno.land/x/zod@v3.23.8/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", - "https://deno.land/x/zod@v3.23.8/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", - "https://deno.land/x/zod@v3.23.8/mod.ts": "ec6e2b1255c1a350b80188f97bd0a6bac45801bb46fc48f50b9763aa66046039", - "https://deno.land/x/zod@v3.23.8/types.ts": "1b172c90782b1eaa837100ebb6abd726d79d6c1ec336350c8e851e0fd706bf5c", "https://esm.sh/jszip@3.7.1": "f3872a819b015715edb05f81d973b5cd05d3d213d8eb28293ca5471fe7a71773", "https://esm.sh/v135/jszip@3.7.1/denonext/jszip.mjs": "d31d7f9e0de9c6db3c07ca93f7301b756273d4dccb41b600461978fc313504c9", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/deps/cli.ts": "aac025f9372ad413b9c2663dc7f61affd597820d9448f010a510d541df3b56ea", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/deps/common.ts": "f775710b66a9099b98651cd3831906466e9b83ef98f2e5c080fd59ee801c28d4", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/deps/ports.ts": "3c60d1f7ab626ffdd81b37f4e83a780910936480da8fe24f4ccceaefa207d339", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/files/deno/mod.ts": "1b8204c3df18b908408b2148b48af788e669d0debbeb8ba119418ab1ddf1ab8f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/files/deno/worker.ts": "8ded400d70a0bd40e281ceb1ffcdc82578443caf9c481b9eee77166472784282", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/host/mod.ts": "cc25d1f82e54e6a27eef4571145c3f34c4c8ad9148b3aa48bd3b53d1e078d95d", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/host/types.ts": "f450d9b9c0eced2650262d02455aa6f794de0edd6b052aade256882148e5697f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/install/mod.ts": "aa54eb3e119f28d33e61645c89669da292ee00376068ead8f45be2807e7a9989", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/install/utils.ts": "d4634d4fc0e963f540402b4ca7eb5dcba340eaa0d8fceb43af57d722ad267115", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/main.ts": "ecd5e83be2d8f351058ad44424cad1f36dd2e3d76f6e8409afc47682a9eff01a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/envs/inter.ts": "84805fa208754a08f185dca7a5236de3760bbc1d0df96af86ea5fd7778f827a2", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/envs/mod.ts": "5f37b9f155808f8d6d51e1f16f58c07914d8c7d8070bc5c2fb5076ab748798a7", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/envs/posix.ts": "09e410e3fea9c303a5148ff2a22697474320442b9fea0bd3fc932d6828fe820f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/envs/reducer.ts": "50517084caaf73ce6618141ee4d97795060a0d3169651da7abd7251a3204465a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/envs/types.ts": "ab9715cf02e9d73f553ae757db347863be23e1e9daf94d18aab716fc27b3dbc1", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/mod.ts": "fc1cb9176c6557b44ae9c6536fa51c6c4f80ac01fc476d15b0a217e70cb0d176", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/ambient.ts": "823ec8d98702a60e6bfcdbeb64b69dc9f5039e73a1f10e87cd51210c1aaf52d5", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/base.ts": "8ef8a8de372420bddcd63a1b363937f43d898059e99478a58621e8432bcd5891", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/db.ts": "a309d1058f66079a481141c3f1733d928b9af8a37b7ce911b1228f70fd24df0f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/ghrel.ts": "ebbc30a5c31244131d937eadca73fbc099c9e7bdf0ad4f668766d4388ede143c", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/inter.ts": "b3999e73d73d7f928a8de86e5e2261fe6b1450ceedfb54f24537bf0803532ed0", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/mod.ts": "78db7040e724f84c95b1a0fdeaf0cfc53382482e8905cd352189756b953556cc", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/reducers.ts": "d04e813652101f67f946242df68429ed5540e499fbdb7776b8be5703f16754c8", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/sync.ts": "a7a297f6b098360d56af168692f3cff96f8ceeb5189e5baa249e094f8d9c42ef", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/types.ts": "f4dbd1a3f4b7f539b3a85418617d25adbf710b54144161880d48f6c4ec032eee", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/types/platform.ts": "0ecffeda71919293f9ffdb6c564ddea4f23bc85c4e640b08ea78225d34387fdc", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/utils.ts": "6b14b331cce66bd46e7aec51f02424327d819150f16d3f72a6b0aaf7aee43c09", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/ports/worker.ts": "6b76ba1efb2e47a82582fc48bcc6264fe153a166beffccde1a9a3a185024c337", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/std.ts": "419d6b04680f73f7b252257ab287d68c1571cee4347301c53278e2b53df21c4a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/tasks/deno.ts": "2b9f33253ac1257eb79a4981cd221509aa9ecf8a3c36d7bd8be1cd6c1150100b", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/tasks/exec.ts": "6adcfe13f8d2da5d65331fd1601d4f950d9fc6f164bc9592204e5b08c23c5c30", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/tasks/inter.ts": "63e8f2860f7e3b4d95b6f61ca56aeb8567e4f265aa9c22cace6c8075edd6210f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/tasks/mod.ts": "334b18d7c110cc05483be96353e342425c0033b7410c271a8a47d2b18308c73e", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/tasks/types.ts": "072a34bd0749428bad4d612cc86abe463d4d4f74dc56cf0a48a1f41650e2399b", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/modules/types.ts": "c0f212b686a2721d076e9aeb127596c7cbc939758e2cc32fd1d165a8fb320a87", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/port.ts": "c039a010dee7dfd978478cf4c5e2256c643135e10f33c30a09f8db9915e9d89d", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/setup_logger.ts": "f8a206bda0595497d6f4718032d4a959000b32ef3346d4b507777eec6a169458", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/utils/logger.ts": "fcbafb35ae4b812412b9b301ce6d06b8b9798f94ebebe3f92677e25e4b19af3c", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/utils/mod.ts": "25bfdd222d6afec5b3f0a7e647e3d9b12abed6d222b49a4b2e95c6bbe266f533", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/utils/unarchive.ts": "f6d0e9e75f470eeef5aecd0089169f4350fc30ebfdc05466bb7b30042294d6d3", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/utils/url.ts": "e1ada6fd30fc796b8918c88456ea1b5bbd87a07d0a0538b092b91fd2bb9b7623", - "https://raw.githubusercontent.com/metatypedev/ghjk/0.2.0/utils/worker.ts": "ac4caf72a36d2e4af4f4e92f2e0a95f9fc2324b568640f24c7c2ff6dc0c11d62", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/deps/cli.ts": "22fdbfe7f39dc2caa9dd056a57a57051deec6b2a7ba9381e20e2ce7ab6af07e1", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/deps/common.ts": "5d676e006bb1485056935c263a967eee9fcfc1517249d1ca05a7645dca5e2e68", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/deps/ports.ts": "3c60d1f7ab626ffdd81b37f4e83a780910936480da8fe24f4ccceaefa207d339", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/files/deno/mod.ts": "1b8204c3df18b908408b2148b48af788e669d0debbeb8ba119418ab1ddf1ab8f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/files/deno/worker.ts": "71f3cee9dba3c2bd59c85d2909eac325da556a9917ed6ea01222f6c217638dd9", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/host/mod.ts": "faea10bf051dc22443e0bb3cadb74599d2ef5e4543f065a75777bb57b818c022", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/host/types.ts": "359ceb8a800c5acd9ef4778e40ccfe039fd7724c06205ae3998398641a9b2370", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/install/mod.ts": "f78083efd15e82c8cc302dd801565f39c947497cfaa039fde1023f7e0d5ab368", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/install/utils.ts": "d4634d4fc0e963f540402b4ca7eb5dcba340eaa0d8fceb43af57d722ad267115", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/main.ts": "fb82696926c97ea6749151275cafce049c35c2d500188661ac8b1d205a3b9939", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/envs/mod.ts": "33ddee364795c1f22028e74071063fe85211949682bb94f1ca38396314cbd01e", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/envs/posix.ts": "3193141953de1bfe2d73549e651711f4e1a1d05f5fcc7655ab74160b25be09d0", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/envs/reducer.ts": "853347377f4b265792da2ece78dfde7602c2555341bbd9f8dfd7ac5fd7d989ad", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/envs/types.ts": "a03173fe013a41163471446f41c636bd23acc6e4956ea910e12cb203dc449a9e", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/mod.ts": "fc1cb9176c6557b44ae9c6536fa51c6c4f80ac01fc476d15b0a217e70cb0d176", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/ambient.ts": "823ec8d98702a60e6bfcdbeb64b69dc9f5039e73a1f10e87cd51210c1aaf52d5", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/base.ts": "8ef8a8de372420bddcd63a1b363937f43d898059e99478a58621e8432bcd5891", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/db.ts": "a309d1058f66079a481141c3f1733d928b9af8a37b7ce911b1228f70fd24df0f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/ghrel.ts": "a1bf0e244080b8b2a62093f536bb7eff0b5a9c596f7eef9f516c11a80aad0be1", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/inter.ts": "62ddc0dede33b059dbd84d18411d0b0acceb145ff96b076401a96c980ae9bfc0", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/mod.ts": "6d4b907ad70a9946299bc5931c976fad1cb1b405466cf4cc8d2acb7d0ba3310c", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/reducers.ts": "eaabbc2cf5d16a55cff5b3f95180f3e1ddb09b1a755776da2931f8817f28a0df", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/sync.ts": "6bbaca38024fd1f6c6ba5811abe65052d2061527539f1893f768ace40016ab5f", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/types.ts": "1adbe5a901f765de106db6513eb770356eed156c435e94d51b7432dce401530e", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/types/platform.ts": "0ecffeda71919293f9ffdb6c564ddea4f23bc85c4e640b08ea78225d34387fdc", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/utils.ts": "6b14b331cce66bd46e7aec51f02424327d819150f16d3f72a6b0aaf7aee43c09", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/ports/worker.ts": "6b76ba1efb2e47a82582fc48bcc6264fe153a166beffccde1a9a3a185024c337", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/std.ts": "419d6b04680f73f7b252257ab287d68c1571cee4347301c53278e2b53df21c4a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/tasks/deno.ts": "15d5bb6379f3add73cb0d8aa4b578998d87bcfaa939518166c30a7f906ea5750", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/tasks/exec.ts": "cc5db628d85a84b6193f59d7f5d98868f22a59f038716dc3d4fc5ac70494d625", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/tasks/mod.ts": "71a16751895ce8bb687c565602938773ac276ccb62d28a793db0b1715438ee9a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/tasks/types.ts": "0bf2cf9ac1f5735dc95ac348175866abf602bd90d01c9275c708f767baa976c1", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/types.ts": "53de8906ea0149871e35c937f3e52dee1a615907971fa8ec3f322f4dfe6d40f3", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/modules/utils.ts": "b5866a52cd4e0e1c0dc8ccb56c7281aeff2e2bf5e16866b77eda36e0529e312a", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/port.ts": "c039a010dee7dfd978478cf4c5e2256c643135e10f33c30a09f8db9915e9d89d", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/setup_logger.ts": "f8a206bda0595497d6f4718032d4a959000b32ef3346d4b507777eec6a169458", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/utils/logger.ts": "fcbafb35ae4b812412b9b301ce6d06b8b9798f94ebebe3f92677e25e4b19af3c", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/utils/mod.ts": "d4d0c0198168f63bd084872bf7dfb40925301ecb65fd0501520db942f6c0c961", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/utils/unarchive.ts": "f6d0e9e75f470eeef5aecd0089169f4350fc30ebfdc05466bb7b30042294d6d3", - "https://raw.githubusercontent.com/metatypedev/ghjk/0c5f78/utils/url.ts": "e1ada6fd30fc796b8918c88456ea1b5bbd87a07d0a0538b092b91fd2bb9b7623", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/deps/cli.ts": "aac025f9372ad413b9c2663dc7f61affd597820d9448f010a510d541df3b56ea", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/deps/common.ts": "f775710b66a9099b98651cd3831906466e9b83ef98f2e5c080fd59ee801c28d4", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/deps/ports.ts": "3c60d1f7ab626ffdd81b37f4e83a780910936480da8fe24f4ccceaefa207d339", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/files/deno/mod.ts": "1b8204c3df18b908408b2148b48af788e669d0debbeb8ba119418ab1ddf1ab8f", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/files/deno/worker.ts": "8ded400d70a0bd40e281ceb1ffcdc82578443caf9c481b9eee77166472784282", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/host/mod.ts": "604e2729145c16226af91e6880e3eca30ea060688fb4941ab39d9489109dd62c", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/host/types.ts": "f450d9b9c0eced2650262d02455aa6f794de0edd6b052aade256882148e5697f", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/install/mod.ts": "f78083efd15e82c8cc302dd801565f39c947497cfaa039fde1023f7e0d5ab368", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/install/utils.ts": "d4634d4fc0e963f540402b4ca7eb5dcba340eaa0d8fceb43af57d722ad267115", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/main.ts": "21ea4582db19e163f4dd68ccdb19578c3c48e48dd23c094d8f8f88ab785e34e5", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/envs/inter.ts": "84805fa208754a08f185dca7a5236de3760bbc1d0df96af86ea5fd7778f827a2", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/envs/mod.ts": "b9483be6dbd4c282d1c5b134864b2ff0f53d8bfb25dba6c96e591c84ccf25e01", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/envs/posix.ts": "09e410e3fea9c303a5148ff2a22697474320442b9fea0bd3fc932d6828fe820f", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/envs/reducer.ts": "853347377f4b265792da2ece78dfde7602c2555341bbd9f8dfd7ac5fd7d989ad", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/envs/types.ts": "ab9715cf02e9d73f553ae757db347863be23e1e9daf94d18aab716fc27b3dbc1", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/mod.ts": "fc1cb9176c6557b44ae9c6536fa51c6c4f80ac01fc476d15b0a217e70cb0d176", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/ambient.ts": "823ec8d98702a60e6bfcdbeb64b69dc9f5039e73a1f10e87cd51210c1aaf52d5", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/base.ts": "8ef8a8de372420bddcd63a1b363937f43d898059e99478a58621e8432bcd5891", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/db.ts": "a309d1058f66079a481141c3f1733d928b9af8a37b7ce911b1228f70fd24df0f", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/ghrel.ts": "a1bf0e244080b8b2a62093f536bb7eff0b5a9c596f7eef9f516c11a80aad0be1", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/inter.ts": "b3999e73d73d7f928a8de86e5e2261fe6b1450ceedfb54f24537bf0803532ed0", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/mod.ts": "2b5d4773d64641cdc0aacf09ece6c40d094feb090280647c68f33bbfa8dceee7", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/reducers.ts": "eaabbc2cf5d16a55cff5b3f95180f3e1ddb09b1a755776da2931f8817f28a0df", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/sync.ts": "a7a297f6b098360d56af168692f3cff96f8ceeb5189e5baa249e094f8d9c42ef", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/types.ts": "f4dbd1a3f4b7f539b3a85418617d25adbf710b54144161880d48f6c4ec032eee", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/types/platform.ts": "0ecffeda71919293f9ffdb6c564ddea4f23bc85c4e640b08ea78225d34387fdc", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/utils.ts": "6b14b331cce66bd46e7aec51f02424327d819150f16d3f72a6b0aaf7aee43c09", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/ports/worker.ts": "6b76ba1efb2e47a82582fc48bcc6264fe153a166beffccde1a9a3a185024c337", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/std.ts": "419d6b04680f73f7b252257ab287d68c1571cee4347301c53278e2b53df21c4a", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/tasks/deno.ts": "2b9f33253ac1257eb79a4981cd221509aa9ecf8a3c36d7bd8be1cd6c1150100b", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/tasks/exec.ts": "eaf6b2f9639185fa76f560276e0d28d262a6c78d2bdc0d579e7683e062d7b542", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/tasks/inter.ts": "63e8f2860f7e3b4d95b6f61ca56aeb8567e4f265aa9c22cace6c8075edd6210f", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/tasks/mod.ts": "438f1cbb5e96470f380b6954bb18ad7693ed33bb99314137ff7080d82d026615", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/tasks/types.ts": "072a34bd0749428bad4d612cc86abe463d4d4f74dc56cf0a48a1f41650e2399b", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/modules/types.ts": "c0f212b686a2721d076e9aeb127596c7cbc939758e2cc32fd1d165a8fb320a87", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/port.ts": "c039a010dee7dfd978478cf4c5e2256c643135e10f33c30a09f8db9915e9d89d", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/setup_logger.ts": "f8a206bda0595497d6f4718032d4a959000b32ef3346d4b507777eec6a169458", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/utils/logger.ts": "fcbafb35ae4b812412b9b301ce6d06b8b9798f94ebebe3f92677e25e4b19af3c", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/utils/mod.ts": "fe8b14465fbcbf3a952af48083a17304c294f296591752dff3ca141386c2d46b", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/utils/unarchive.ts": "f6d0e9e75f470eeef5aecd0089169f4350fc30ebfdc05466bb7b30042294d6d3", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/utils/url.ts": "e1ada6fd30fc796b8918c88456ea1b5bbd87a07d0a0538b092b91fd2bb9b7623", - "https://raw.githubusercontent.com/metatypedev/ghjk/5bb0d24/utils/worker.ts": "ac4caf72a36d2e4af4f4e92f2e0a95f9fc2324b568640f24c7c2ff6dc0c11d62", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/deps/cli.ts": "aac025f9372ad413b9c2663dc7f61affd597820d9448f010a510d541df3b56ea", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/deps/common.ts": "f775710b66a9099b98651cd3831906466e9b83ef98f2e5c080fd59ee801c28d4", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/deps/ports.ts": "3c60d1f7ab626ffdd81b37f4e83a780910936480da8fe24f4ccceaefa207d339", @@ -570,6 +435,7 @@ "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/modules/types.ts": "c0f212b686a2721d076e9aeb127596c7cbc939758e2cc32fd1d165a8fb320a87", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/port.ts": "c039a010dee7dfd978478cf4c5e2256c643135e10f33c30a09f8db9915e9d89d", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/ports/act.ts": "2ce6b8fddf61db12ba69b7cad6985237a2962ca79853edbddee5bfb49c47d1ab", + "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/ports/deno_ghrel.ts": "eca02a93ceb62ad9fb7f395361d32da0d5657aba5f7856c8ae0109135da0e070", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/setup_logger.ts": "f8a206bda0595497d6f4718032d4a959000b32ef3346d4b507777eec6a169458", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/utils/logger.ts": "fcbafb35ae4b812412b9b301ce6d06b8b9798f94ebebe3f92677e25e4b19af3c", "https://raw.githubusercontent.com/metatypedev/ghjk/v0.2.1/utils/mod.ts": "25901b5a03625353cc0d9c024daca806eb2513b153faede5ecad73b428542721", diff --git a/.ghjk/lock.json b/.ghjk/lock.json index eed51968..32181f40 100644 --- a/.ghjk/lock.json +++ b/.ghjk/lock.json @@ -1,21 +1,127 @@ { "version": "0", - "platform": "x86_64-linux", - "moduleEntries": { + "sys_entries": { "ports": { "version": "0", "configResolutions": { - "bciqjlw6cxddajjmznoemlmnu7mgbbm7a3hfmnd2x5oivwajmiqui5ey": { - "version": "v0.2.69", + "bciqeosxosr6ur7pu7gny33gy7dqubmxbcs4775xazb4zvaxavkd5rha": { + "version": "0.1.13", + "buildDepConfigs": { + "cargo_binstall_ghrel": { + "version": "v1.10.18", + "buildDepConfigs": {}, + "portRef": "cargo_binstall_ghrel@0.1.0", + "specifiedVersion": false + }, + "rust_rustup": { + "version": "1.82.0", + "buildDepConfigs": { + "rustup_rustlang": { + "version": "1.27.1", + "buildDepConfigs": { + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "rustup_rustlang@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "rust_rustup@0.1.0", + "profile": "default", + "components": [ + "rust-src" + ], + "specifiedVersion": true + } + }, + "portRef": "cargobi_cratesio@0.1.0", + "crateName": "tokio-console", + "specifiedVersion": false + }, + "bciqeal5okt5zj763vhgsmf3afr5thrkqaitv6pb3wwegcwyb74gdyjq": { + "version": "v1.10.18", "buildDepConfigs": {}, - "portRef": "act_ghrel@0.1.0", + "portRef": "cargo_binstall_ghrel@0.1.0", "specifiedVersion": false }, - "bciqao2s3r3r33ruox4qknfrxqrmemuccxn64dze2ylojrzp2bwvt4ji": { - "version": "4.0.1", + "bciqar6zz2xgxmu5i2jp5nuj4wsogcl7pxsqs3w55mibcsbks5iimsyy": { + "version": "1.82.0", + "buildDepConfigs": { + "rustup_rustlang": { + "version": "1.27.1", + "buildDepConfigs": { + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "rustup_rustlang@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "rust_rustup@0.1.0", + "profile": "default", + "components": [ + "rust-src" + ], + "specifiedVersion": true + }, + "bciqay4m4kmzfduj5t2clgejxgpe5zwper6lyyaxt7rhbjalaqd32nhq": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + }, + "bciqewpyjyfnnk4rbd6bbu5who2w6ve7dyt3inal72zg23cs4qnln32q": { + "version": "1.27.1", + "buildDepConfigs": { + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "rustup_rustlang@0.1.0", + "specifiedVersion": false + }, + "bciqkv7foyoio4wpti4yf2qrw5nphkgk2din6ba7mjv2w7hmgrv725ja": { + "version": "v2.4.0", + "buildDepConfigs": { + "tar_aa": { + "version": "1.35", + "buildDepConfigs": {}, + "portRef": "tar_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "mold_ghrel@0.1.0", + "replaceLd": true, + "specifiedVersion": true + }, + "bciqj4p5hoqweghbuvz52rupja7sqze34z63dd62nz632c5zxikv6ezy": { + "version": "1.35", + "buildDepConfigs": {}, + "portRef": "tar_aa@0.1.0", + "specifiedVersion": false + }, + "bciqkpfuyqchouu5o3whigod3f5coscq2jdlwde6fztypy3x6fg6xb5q": { + "version": "v29.2", + "buildDepConfigs": {}, + "portRef": "protoc_ghrel@0.1.0", + "specifiedVersion": false + }, + "bciqe6tpdv6hffdbc7hql52w3ivpdls47lgpuhsa3hzsryrwx7ty5dgy": { + "version": "3.31.2", "buildDepConfigs": { "cpy_bs_ghrel": { - "version": "3.12.7", + "version": "3.13.1", "buildDepConfigs": { "tar_aa": { "version": "1.35", @@ -35,11 +141,11 @@ } }, "portRef": "pipi_pypi@0.1.0", - "packageName": "pre-commit", + "packageName": "cmake", "specifiedVersion": false }, - "bciqh4dfyevkzzvmnhuz7lcfqttkg5neg4ewhoxzofyuicavgk6pb7ia": { - "version": "3.12.7", + "bciqicl4snbxiu6ikns3zjrriwo3qpo4dv3ooxjkwnr35utnqshubdcq": { + "version": "3.13.1", "buildDepConfigs": { "tar_aa": { "version": "1.35", @@ -57,23 +163,50 @@ "portRef": "cpy_bs_ghrel@0.1.0", "specifiedVersion": true }, - "bciqj4p5hoqweghbuvz52rupja7sqze34z63dd62nz632c5zxikv6ezy": { - "version": "1.35", - "buildDepConfigs": {}, - "portRef": "tar_aa@0.1.0", - "specifiedVersion": false - }, "bciqe6fwheayositrdk7rkr2ngdr4wizldakex23tgivss7w6z7g3q3y": { "version": "v1.5.6", "buildDepConfigs": {}, "portRef": "zstd_aa@0.1.0", "specifiedVersion": false }, + "bciqjlw6cxddajjmznoemlmnu7mgbbm7a3hfmnd2x5oivwajmiqui5ey": { + "version": "v0.2.71", + "buildDepConfigs": {}, + "portRef": "act_ghrel@0.1.0", + "specifiedVersion": false + }, + "bciqao2s3r3r33ruox4qknfrxqrmemuccxn64dze2ylojrzp2bwvt4ji": { + "version": "4.0.1", + "buildDepConfigs": { + "cpy_bs_ghrel": { + "version": "3.13.1", + "buildDepConfigs": { + "tar_aa": { + "version": "1.35", + "buildDepConfigs": {}, + "portRef": "tar_aa@0.1.0", + "specifiedVersion": false + }, + "zstd_aa": { + "version": "v1.5.6", + "buildDepConfigs": {}, + "portRef": "zstd_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "cpy_bs_ghrel@0.1.0", + "specifiedVersion": true + } + }, + "portRef": "pipi_pypi@0.1.0", + "packageName": "pre-commit", + "specifiedVersion": false + }, "bciqoawx3omfmmhaw25mgrujoxl5wkdwfzbmidfqah2zst7cildtcpeq": { - "version": "3.9.0.0", + "version": "3.9.1.0", "buildDepConfigs": { "cpy_bs_ghrel": { - "version": "3.12.7", + "version": "3.13.1", "buildDepConfigs": { "tar_aa": { "version": "1.35", @@ -96,11 +229,72 @@ "packageName": "vale", "specifiedVersion": false }, - "bciqfvlwwndlfuqibybkgee3fgt7cst5ltpztmm3by6hib5veial5spy": { - "version": "v1.44.2", + "bciqe7g5m4v5jkg3ubqhogjjntsduyrwxcirqcp6tc3jmjr5af7ojq6a": { + "version": "v2.1.2", "buildDepConfigs": {}, "portRef": "deno_ghrel@0.1.0", "specifiedVersion": true + }, + "bciqmpujkkyxmzdz7sxpvi2pmajzfmg6gofplyqn43av2styxu2ng7sy": { + "version": "8.9.1", + "buildDepConfigs": {}, + "portRef": "curl_aa@0.1.0", + "specifiedVersion": false + }, + "bciqldq3d5ozrnh64liohwl5epkckja37mokbbjiddhsco6yh2n2ppda": { + "version": "1.7.1", + "buildDepConfigs": { + "curl_aa": { + "version": "8.9.1", + "buildDepConfigs": {}, + "portRef": "curl_aa@0.1.0", + "specifiedVersion": false + }, + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + }, + "asdf_plugin_git": { + "version": "addae51180", + "buildDepConfigs": { + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "asdf_plugin_git@0.1.0", + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "specifiedVersion": false + } + }, + "resolutionDepConfigs": { + "asdf_plugin_git": { + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "portRef": "asdf_plugin_git@0.1.0" + } + }, + "portRef": "asdf@0.1.0", + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "installType": "version", + "specifiedVersion": false + }, + "bciqjatixpjgnlwlrdxmz2r5g2werxjkkvs4wsw4c57fbipdza4qexua": { + "version": "addae51180", + "buildDepConfigs": { + "git_aa": { + "version": "2.47.1", + "buildDepConfigs": {}, + "portRef": "git_aa@0.1.0", + "specifiedVersion": false + } + }, + "portRef": "asdf_plugin_git@0.1.0", + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "specifiedVersion": false } } }, @@ -119,16 +313,45 @@ "sets": { "ghjkEnvProvInstSet___main": { "installs": [ + "bciqjucge6yrzcawqzcljvrpmtwrocecsww6pcjwipzn5j2hfwjof7za", "bciqe72molvtvcuj3tuh47ziue2oqd6t4qetxn3rsoa764ofup6uwjmi", "bciqe4zlekl4uqqbhxunac7br24mrf6cdpfrfblahqa4vrgaqjujcl4i", "bciqpu4klxr3hl6ujhmflrlfd3dxp47ijq26mnathb26ojzwkeggy5ii", - "bciqmgggy7hd5as3zz7pzbx54va7lq657bdxvthntxphhlbsl2434dgq" + "bciqelae2kzmf7umbo62flzq2mnlhnc4ilbfmn4va2fzrqwx7w7zusji" ], - "allowedBuildDeps": "bciqoo3t36t4pphdox5wa5ugn34wkar7rwkqgb5l55lwnxbuabcc3nyq" + "allowedBuildDeps": "bciqdg64uhkvlkqyc7nli33cja3aolbcdr75qepnrhj5ojlifsvxqzgq" }, - "ghjkEnvProvInstSet___test": { + "ghjkEnvProvInstSet____rust": { + "installs": [ + "bciqikjfnbntvagpghawbzlfp2es6lnqzhba3qx5de7tdrmvhuzhsjqa", + "bciqfrfun7z7soj7yxzziyvmt2jnebqvneeoozk5vynmg5pa6wqynhvi", + "bciqgkc6fegmxehj4whmusfuurxyp4ayeysn6qa2t6q64baac5is7uui", + "bciqjucge6yrzcawqzcljvrpmtwrocecsww6pcjwipzn5j2hfwjof7za", + "bciqe72molvtvcuj3tuh47ziue2oqd6t4qetxn3rsoa764ofup6uwjmi", + "bciqe4zlekl4uqqbhxunac7br24mrf6cdpfrfblahqa4vrgaqjujcl4i", + "bciqpu4klxr3hl6ujhmflrlfd3dxp47ijq26mnathb26ojzwkeggy5ii", + "bciqelae2kzmf7umbo62flzq2mnlhnc4ilbfmn4va2fzrqwx7w7zusji" + ], + "allowedBuildDeps": "bciqdg64uhkvlkqyc7nli33cja3aolbcdr75qepnrhj5ojlifsvxqzgq" + }, + "ghjkEnvProvInstSet___dev": { + "installs": [ + "bciqlfx3mm5hi37g75snjknph6fkniixjhnvyyfxeua7f5z4h7nnqtna", + "bciqlmoqot4jk2lb2b34pldr5iiwsfm3biuipzesjkkwmc2n2o6nlw4q", + "bciqikjfnbntvagpghawbzlfp2es6lnqzhba3qx5de7tdrmvhuzhsjqa", + "bciqfrfun7z7soj7yxzziyvmt2jnebqvneeoozk5vynmg5pa6wqynhvi", + "bciqgkc6fegmxehj4whmusfuurxyp4ayeysn6qa2t6q64baac5is7uui", + "bciqjucge6yrzcawqzcljvrpmtwrocecsww6pcjwipzn5j2hfwjof7za", + "bciqe72molvtvcuj3tuh47ziue2oqd6t4qetxn3rsoa764ofup6uwjmi", + "bciqe4zlekl4uqqbhxunac7br24mrf6cdpfrfblahqa4vrgaqjujcl4i", + "bciqpu4klxr3hl6ujhmflrlfd3dxp47ijq26mnathb26ojzwkeggy5ii", + "bciqelae2kzmf7umbo62flzq2mnlhnc4ilbfmn4va2fzrqwx7w7zusji" + ], + "allowedBuildDeps": "bciqdg64uhkvlkqyc7nli33cja3aolbcdr75qepnrhj5ojlifsvxqzgq" + }, + "ghjkEnvProvInstSet_______task_env_cache-v8": { "installs": [], - "allowedBuildDeps": "bciqoo3t36t4pphdox5wa5ugn34wkar7rwkqgb5l55lwnxbuabcc3nyq" + "allowedBuildDeps": "bciqeie3punk3gz4kcfdk2fxx5bsj5fh3j7bb7z36qmimayhwdsvp7cq" } } } @@ -140,11 +363,18 @@ "lock-sed": { "ty": "denoFile@v1", "key": "lock-sed", - "envKey": "bciqekhy7ndyc6hmkzspdsguxjgvyz5yedr5weigsqsa72kyloity4jy" + "envKey": "bciqocjamyeiuh6llwcdqg4q4ceantuzpbm5bmnlz7pkqz4r2ca7w2eq" + }, + "cache-v8": { + "ty": "denoFile@v1", + "key": "cache-v8", + "desc": "Install the V8 builds to a local cache.", + "envKey": "bciqngtgh6vxbmug3jgfhtc6t2o7d4375gzfwxca2hmq2mhwbe4tajvq" } }, "tasksNamed": [ - "lock-sed" + "lock-sed", + "cache-v8" ] } }, @@ -152,32 +382,133 @@ "id": "envs", "config": { "envs": { - "bciqekhy7ndyc6hmkzspdsguxjgvyz5yedr5weigsqsa72kyloity4jy": { + "bciqngtgh6vxbmug3jgfhtc6t2o7d4375gzfwxca2hmq2mhwbe4tajvq": { "provides": [ { "ty": "ghjk.ports.InstallSetRef", - "setId": "ghjkEnvProvInstSet___test" + "setId": "ghjkEnvProvInstSet_______task_env_cache-v8" } ] }, - "bciqfzekhtsrjd72noxifmici3ssck4jgvbjwhxwhhwtirzm7yomhxya": { + "bciqfnku2tswsz4gapwhys5ox5uiyzcb5r7bmuwzljjeziljcu7efroi": { "desc": "the default default environment.", "provides": [ + { + "ty": "posix.envVar", + "key": "RUST_LOG", + "val": "info,deno::npm=info,deno::file_fetcher=info,swc_ecma_transforms_base=info,swc_common=info,h2=info,rustls=info,mio=info,hyper_util=info" + }, + { + "ty": "ghjk.ports.InstallSetRef", + "setId": "ghjkEnvProvInstSet___main" + } + ] + }, + "bciqocjamyeiuh6llwcdqg4q4ceantuzpbm5bmnlz7pkqz4r2ca7w2eq": { + "provides": [ + { + "ty": "posix.envVar", + "key": "RUST_LOG", + "val": "info,deno::npm=info,deno::file_fetcher=info,swc_ecma_transforms_base=info,swc_common=info,h2=info,rustls=info,mio=info,hyper_util=info" + }, { "ty": "ghjk.ports.InstallSetRef", "setId": "ghjkEnvProvInstSet___main" } ] + }, + "bciqex5g2cetqvfipwhu6fb3mmyke3y6jvrscjrykf2zl7wfwupiqhca": { + "provides": [ + { + "ty": "posix.envVar", + "key": "RUST_LOG", + "val": "info,deno::npm=info,deno::file_fetcher=info,swc_ecma_transforms_base=info,swc_common=info,h2=info,rustls=info,mio=info,hyper_util=info" + }, + { + "ty": "ghjk.ports.InstallSetRef", + "setId": "ghjkEnvProvInstSet____rust" + } + ] + }, + "bciqgcwltl3sbuyrqlhxz2spihe2asdzrgt3axosw3mre7ived23syhy": { + "provides": [ + { + "ty": "posix.envVar", + "key": "RUST_LOG", + "val": "info,deno::npm=info,deno::file_fetcher=info,swc_ecma_transforms_base=info,swc_common=info,h2=info,rustls=info,mio=info,hyper_util=info" + }, + { + "ty": "posix.envVar", + "key": "RUSTY_V8_MIRROR", + "val": "/var/home/asdf/repos/ecma/ghjk/.dev/rusty_v8" + }, + { + "ty": "ghjk.ports.InstallSetRef", + "setId": "ghjkEnvProvInstSet___dev" + } + ] } }, - "defaultEnv": "main", + "defaultEnv": "dev", "envsNamed": { - "main": "bciqfzekhtsrjd72noxifmici3ssck4jgvbjwhxwhhwtirzm7yomhxya" + "main": "bciqfnku2tswsz4gapwhys5ox5uiyzcb5r7bmuwzljjeziljcu7efroi", + "_rust": "bciqex5g2cetqvfipwhu6fb3mmyke3y6jvrscjrykf2zl7wfwupiqhca", + "dev": "bciqgcwltl3sbuyrqlhxz2spihe2asdzrgt3axosw3mre7ived23syhy" } } } ], "blackboard": { + "bciqjucge6yrzcawqzcljvrpmtwrocecsww6pcjwipzn5j2hfwjof7za": { + "buildDepConfigs": { + "asdf_plugin_git": { + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "portRef": "asdf_plugin_git@0.1.0" + } + }, + "resolutionDepConfigs": { + "asdf_plugin_git": { + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "portRef": "asdf_plugin_git@0.1.0" + } + }, + "port": { + "ty": "denoWorker@v1", + "name": "asdf", + "platforms": [ + "x86_64-linux", + "aarch64-linux", + "x86_64-darwin", + "aarch64-darwin" + ], + "version": "0.1.0", + "buildDeps": [ + { + "name": "curl_aa" + }, + { + "name": "git_aa" + }, + { + "name": "asdf_plugin_git" + } + ], + "resolutionDeps": [ + { + "name": "curl_aa" + }, + { + "name": "git_aa" + }, + { + "name": "asdf_plugin_git" + } + ], + "moduleSpecifier": "file:///ports/asdf.ts" + }, + "pluginRepo": "https://github.com/lsanwick/asdf-jq", + "installType": "version" + }, "bciqe72molvtvcuj3tuh47ziue2oqd6t4qetxn3rsoa764ofup6uwjmi": { "port": { "ty": "denoWorker@v1", @@ -262,8 +593,8 @@ }, "packageName": "vale" }, - "bciqmgggy7hd5as3zz7pzbx54va7lq657bdxvthntxphhlbsl2434dgq": { - "version": "1.44.2", + "bciqelae2kzmf7umbo62flzq2mnlhnc4ilbfmn4va2fzrqwx7w7zusji": { + "version": "2.1.2", "port": { "ty": "denoWorker@v1", "name": "deno_ghrel", @@ -279,6 +610,75 @@ "moduleSpecifier": "file:///ports/deno_ghrel.ts" } }, + "bciqdfarczmlu3r5dkvcdoultfbnuvn6saao55h4fbb3jg72kv6mkr3y": { + "manifest": { + "ty": "denoWorker@v1", + "name": "cpy_bs_ghrel", + "platforms": [ + "x86_64-linux", + "aarch64-linux", + "x86_64-darwin", + "aarch64-darwin", + "x86_64-windows", + "aarch64-windows" + ], + "version": "0.1.0", + "buildDeps": [ + { + "name": "tar_aa" + }, + { + "name": "zstd_aa" + } + ], + "moduleSpecifier": "file:///ports/cpy_bs.ts" + }, + "defaultInst": { + "version": "3.13.1", + "portRef": "cpy_bs_ghrel@0.1.0" + } + }, + "bciqgze4knhjfbiypt5axkjslfsduq6tbwszbiuy5zsgpacrm5h6cg4a": { + "manifest": { + "ty": "denoWorker@v1", + "name": "rust_rustup", + "platforms": [ + "x86_64-linux", + "aarch64-linux", + "x86_64-darwin", + "aarch64-darwin", + "x86_64-windows", + "aarch64-windows", + "x86_64-freebsd", + "aarch64-freebsd", + "x86_64-netbsd", + "aarch64-netbsd", + "x86_64-aix", + "aarch64-aix", + "x86_64-solaris", + "aarch64-solaris", + "x86_64-illumos", + "aarch64-illumos", + "x86_64-android", + "aarch64-android" + ], + "version": "0.1.0", + "buildDeps": [ + { + "name": "rustup_rustlang" + } + ], + "moduleSpecifier": "file:///ports/rust.ts" + }, + "defaultInst": { + "version": "1.82.0", + "portRef": "rust_rustup@0.1.0", + "profile": "default", + "components": [ + "rust-src" + ] + } + }, "bciqb6ua63xodzwxngnbjq35hfikiwzb3dclbqkc7e6xgjdt5jin4pia": { "manifest": { "ty": "ambientAccess@v1", @@ -457,38 +857,34 @@ "portRef": "cargo_binstall_ghrel@0.1.0" } }, - "bciqakxf4wsx3mtku4x5exrl44k4r4kyq6gaw4va5hsb3v26cipmmekq": { + "bciqboouqnp54fnumgxvl7uay2k6ho4vhlbibvgoyyt5yt3rkwqaohzi": { "manifest": { "ty": "denoWorker@v1", - "name": "cpy_bs_ghrel", + "name": "node_org", "platforms": [ - "x86_64-linux", "aarch64-linux", - "x86_64-darwin", + "x86_64-linux", "aarch64-darwin", - "x86_64-windows", - "aarch64-windows" + "x86_64-darwin", + "aarch64-windows", + "x86_64-windows" ], "version": "0.1.0", "buildDeps": [ { "name": "tar_aa" - }, - { - "name": "zstd_aa" } ], - "moduleSpecifier": "file:///ports/cpy_bs.ts" + "moduleSpecifier": "file:///ports/node.ts" }, "defaultInst": { - "version": "3.12.7", - "portRef": "cpy_bs_ghrel@0.1.0" + "portRef": "node_org@0.1.0" } }, - "bciqboouqnp54fnumgxvl7uay2k6ho4vhlbibvgoyyt5yt3rkwqaohzi": { + "bciqoxx4uhfhw77sux6kzqhy6bvxhxkk4cqigrxdrmggillzkfjgjnli": { "manifest": { "ty": "denoWorker@v1", - "name": "node_org", + "name": "asdf_plugin_git", "platforms": [ "aarch64-linux", "x86_64-linux", @@ -500,17 +896,84 @@ "version": "0.1.0", "buildDeps": [ { - "name": "tar_aa" + "name": "git_aa" } ], - "moduleSpecifier": "file:///ports/node.ts" + "resolutionDeps": [ + { + "name": "git_aa" + } + ], + "moduleSpecifier": "file:///ports/asdf_plugin_git.ts" }, "defaultInst": { - "portRef": "node_org@0.1.0" + "portRef": "asdf_plugin_git@0.1.0" } }, - "bciqhjmjvlo4aqvwxjkrmoiledobmhkfe7iovqe3wndxiw2aootwn4lq": { - "manifest": { + "bciqdg64uhkvlkqyc7nli33cja3aolbcdr75qepnrhj5ojlifsvxqzgq": { + "cpy_bs_ghrel": "bciqdfarczmlu3r5dkvcdoultfbnuvn6saao55h4fbb3jg72kv6mkr3y", + "rust_rustup": "bciqgze4knhjfbiypt5axkjslfsduq6tbwszbiuy5zsgpacrm5h6cg4a", + "tar_aa": "bciqb6ua63xodzwxngnbjq35hfikiwzb3dclbqkc7e6xgjdt5jin4pia", + "git_aa": "bciqfl5s36w335ducrb6f6gwb3vuwup7vzqwwg67pq42xtkngsnxqobi", + "curl_aa": "bciqcfe7qyxmokpn6pgtaj35r5qg74jkehuu6cvyrtcsnegvwlm64oqy", + "unzip_aa": "bciqgkpwxjmo5phw5se4ugyiz4xua3xrd54quzmk7wdwpq3vghglogjy", + "zstd_aa": "bciqpezvwy56igv7hqdpb3qreewqmyftjyej7zhcyhz6afcgfxgy3rjy", + "rustup_rustlang": "bciqk4ivbyqvpxwcaj5reufmveqldiizo6xmqiqq7njtaczgappydoka", + "cargo_binstall_ghrel": "bciqpgt5wsiw4y7qzovqbt2yrdgq5mvhhjpcg6cxzt4w4taudyen44ca", + "node_org": "bciqboouqnp54fnumgxvl7uay2k6ho4vhlbibvgoyyt5yt3rkwqaohzi", + "asdf_plugin_git": "bciqoxx4uhfhw77sux6kzqhy6bvxhxkk4cqigrxdrmggillzkfjgjnli" + }, + "bciqikjfnbntvagpghawbzlfp2es6lnqzhba3qx5de7tdrmvhuzhsjqa": { + "port": { + "ty": "denoWorker@v1", + "name": "protoc_ghrel", + "platforms": [ + "aarch64-linux", + "x86_64-linux", + "aarch64-darwin", + "x86_64-darwin" + ], + "version": "0.1.0", + "moduleSpecifier": "file:///ports/protoc.ts" + } + }, + "bciqfrfun7z7soj7yxzziyvmt2jnebqvneeoozk5vynmg5pa6wqynhvi": { + "port": { + "ty": "denoWorker@v1", + "name": "pipi_pypi", + "platforms": [ + "x86_64-linux", + "aarch64-linux", + "x86_64-darwin", + "aarch64-darwin", + "x86_64-windows", + "aarch64-windows", + "x86_64-freebsd", + "aarch64-freebsd", + "x86_64-netbsd", + "aarch64-netbsd", + "x86_64-aix", + "aarch64-aix", + "x86_64-solaris", + "aarch64-solaris", + "x86_64-illumos", + "aarch64-illumos", + "x86_64-android", + "aarch64-android" + ], + "version": "0.1.0", + "buildDeps": [ + { + "name": "cpy_bs_ghrel" + } + ], + "moduleSpecifier": "file:///ports/pipi.ts" + }, + "packageName": "cmake" + }, + "bciqgkc6fegmxehj4whmusfuurxyp4ayeysn6qa2t6q64baac5is7uui": { + "version": "1.82.0", + "port": { "ty": "denoWorker@v1", "name": "rust_rustup", "platforms": [ @@ -541,53 +1004,68 @@ ], "moduleSpecifier": "file:///ports/rust.ts" }, - "defaultInst": { - "portRef": "rust_rustup@0.1.0", - "profile": "minimal" - } + "profile": "default", + "components": [ + "rust-src" + ] }, - "bciqoxx4uhfhw77sux6kzqhy6bvxhxkk4cqigrxdrmggillzkfjgjnli": { - "manifest": { + "bciqlfx3mm5hi37g75snjknph6fkniixjhnvyyfxeua7f5z4h7nnqtna": { + "port": { "ty": "denoWorker@v1", - "name": "asdf_plugin_git", + "name": "cargobi_cratesio", "platforms": [ - "aarch64-linux", "x86_64-linux", - "aarch64-darwin", + "aarch64-linux", "x86_64-darwin", + "aarch64-darwin", + "x86_64-windows", "aarch64-windows", - "x86_64-windows" + "x86_64-freebsd", + "aarch64-freebsd", + "x86_64-netbsd", + "aarch64-netbsd", + "x86_64-aix", + "aarch64-aix", + "x86_64-solaris", + "aarch64-solaris", + "x86_64-illumos", + "aarch64-illumos", + "x86_64-android", + "aarch64-android" ], "version": "0.1.0", "buildDeps": [ { - "name": "git_aa" + "name": "cargo_binstall_ghrel" + }, + { + "name": "rust_rustup" } ], - "resolutionDeps": [ + "moduleSpecifier": "file:///ports/cargobi.ts" + }, + "crateName": "tokio-console" + }, + "bciqlmoqot4jk2lb2b34pldr5iiwsfm3biuipzesjkkwmc2n2o6nlw4q": { + "version": "v2.4.0", + "port": { + "ty": "denoWorker@v1", + "name": "mold_ghrel", + "platforms": [ + "aarch64-linux", + "x86_64-linux" + ], + "version": "0.1.0", + "buildDeps": [ { - "name": "git_aa" + "name": "tar_aa" } ], - "moduleSpecifier": "file:///ports/asdf_plugin_git.ts" + "moduleSpecifier": "file:///ports/mold.ts" }, - "defaultInst": { - "portRef": "asdf_plugin_git@0.1.0" - } + "replaceLd": true }, - "bciqoo3t36t4pphdox5wa5ugn34wkar7rwkqgb5l55lwnxbuabcc3nyq": { - "tar_aa": "bciqb6ua63xodzwxngnbjq35hfikiwzb3dclbqkc7e6xgjdt5jin4pia", - "git_aa": "bciqfl5s36w335ducrb6f6gwb3vuwup7vzqwwg67pq42xtkngsnxqobi", - "curl_aa": "bciqcfe7qyxmokpn6pgtaj35r5qg74jkehuu6cvyrtcsnegvwlm64oqy", - "unzip_aa": "bciqgkpwxjmo5phw5se4ugyiz4xua3xrd54quzmk7wdwpq3vghglogjy", - "zstd_aa": "bciqpezvwy56igv7hqdpb3qreewqmyftjyej7zhcyhz6afcgfxgy3rjy", - "rustup_rustlang": "bciqk4ivbyqvpxwcaj5reufmveqldiizo6xmqiqq7njtaczgappydoka", - "cargo_binstall_ghrel": "bciqpgt5wsiw4y7qzovqbt2yrdgq5mvhhjpcg6cxzt4w4taudyen44ca", - "cpy_bs_ghrel": "bciqakxf4wsx3mtku4x5exrl44k4r4kyq6gaw4va5hsb3v26cipmmekq", - "node_org": "bciqboouqnp54fnumgxvl7uay2k6ho4vhlbibvgoyyt5yt3rkwqaohzi", - "rust_rustup": "bciqhjmjvlo4aqvwxjkrmoiledobmhkfe7iovqe3wndxiw2aootwn4lq", - "asdf_plugin_git": "bciqoxx4uhfhw77sux6kzqhy6bvxhxkk4cqigrxdrmggillzkfjgjnli" - } + "bciqeie3punk3gz4kcfdk2fxx5bsj5fh3j7bb7z36qmimayhwdsvp7cq": {} } } -} +} \ No newline at end of file diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index fdb034a8..7d50999d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,71 +1,66 @@ +name: nightly jobs on: schedule: - cron: "0 2 * * *" workflow_dispatch: env: - DENO_VERSION: "1.44.2" - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DENO_VERSION: "2.1.2" + GHJK_LOG: debug GHJK_LOG_PANIC_LEVEL: error DENO_DIR: .deno-dir - DOCKER_NO_RMI: 1 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: test-e2e: + timeout-minutes: 60 runs-on: "${{ matrix.os }}" strategy: fail-fast: false matrix: include: - os: ubuntu-latest - e2eType: "local" + platform: linux/x86_64 + - os: custom-arm + platform: linux/aarch64 - os: macos-latest - e2eType: "local" + platform: darwin/x86_64 - os: macos-14 - e2eType: "local" + platform: darwin/aarch64 # - os: windows-latest - # e2eType: "local" - env: - GHJK_TEST_E2E_TYPE: ${{ matrix.e2eType }} steps: - uses: actions/checkout@v4 + - uses: dsherret/rust-toolchain-file@v1 - uses: denoland/setup-deno@v1 with: deno-version: ${{ env.DENO_VERSION }} - - if: "${{ matrix.os == 'ubuntu-latest' || matrix.os == 'custom-arm' }}" - run: | - # we need coreutils on max for the `timeout` command - sudo apt update - sudo apt install -y --no-install-recommends fish zsh - - if: "${{ matrix.os == 'macos-latest' || matrix.os == 'macos-14' }}" - # we need coreutils on max for the `timeout` command - run: brew install fish zsh coreutils - name: Cache deno dir - if: "${{ matrix.os == 'macos-latest' || matrix.os == 'macos-14' }}" uses: actions/cache@v4 with: path: ${{ env.DENO_DIR }} - key: deno-mac-${{ hashFiles('**/deno.lock') }} - - - if: "${{ matrix.e2eType == 'docker' }}" - uses: docker/setup-buildx-action@v3 - - if: "${{ matrix.e2eType == 'docker' }}" - uses: actions-hub/docker/cli@master - env: - SKIP_LOGIN: true - + key: deno-${{ hashFiles('**/deno.lock') }} + - if: "${{ matrix.os == 'ubuntu-latest' || matrix.os == 'custom-arm' }}" + # need coreutils on max for the `timeout` command + # need cmake to build the rust deps + run: | + sudo apt update + sudo apt install -y --no-install-recommends fish zsh cmake + - if: "${{ matrix.os == 'macos-latest' || matrix.os == 'macos-14' }}" + # need cmake to build the rust deps + # need coreutils on max for the `timeout` command + run: brew install fish zsh coreutils cmake - run: deno task test - test-action: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: metatypedev/setup-ghjk@318209a9d215f70716a4ac89dbeb9653a2deb8bc - with: - installer-url: ./install.ts - env: - GHJKFILE: ./examples/protoc/ghjk.ts - - run: | - cd examples/tasks - . $(ghjk print share-dir-path)/env.sh - ghjk x hey + # test-action: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: metatypedev/setup-ghjk@318209a9d215f70716a4ac89dbeb9653a2deb8bc + # with: + # installer-url: ./install.ts + # env: + # GHJKFILE: ./examples/protoc/ghjk.ts + # - run: | + # cd examples/tasks + # . $(ghjk print share-dir-path)/env.sh + # ghjk x hey diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..383e77f4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,90 @@ +name: release jobs +run-name: release jobs for ${{ github.ref }} +on: + workflow_dispatch: + inputs: + ovewriteArtifacts: + description: Ovewrite artifacts on the release. Some will only be skipped. + required: true + type: boolean + default: true + checkBump: + description: check-bump adds a release entry to github so it's disabled by default. + required: true + type: boolean + default: false + push: + tags: + - v* + +jobs: + check-bump: + runs-on: ubuntu-latest + if: github.ref_type == 'tag' || ( github.event_name == 'workflow_dispatch' && inputs.checkBump ) + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: WyriHaximus/github-action-get-previous-tag@v1.4.0 + id: latest-tag + - uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.latest-tag.outputs.tag }} + allowUpdates: ${{ github.event_name == 'workflow_dispatch' }} + generateReleaseNotes: true + discussionCategory: "Announcements" + prerelease: ${{ contains(steps.latest-tag.outputs.tag, 'rc') || contains(steps.latest-tag.outputs.tag, 'dev') }} + + pub-cli: + needs: + - check-bump + # using `always()` makes the job evaulte despite + # status of check-bump + # we combine that with our own conditions + if: | + always() + && ( + needs.check-bump.result == 'success' + || github.event_name == 'workflow_dispatch' + ) + runs-on: "${{ matrix.os }}" + strategy: + fail-fast: false + matrix: + include: + - os: macos-13 + target: x86_64-apple-darwin + - os: macos-14 + target: aarch64-apple-darwin + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + # FIXME: deno doesn't support musl today https://github.com/denoland/deno/issues/3711 + # - os: ubuntu-latest + # target: x86_64-unknown-linux-musl + - os: custom-arm + target: aarch64-unknown-linux-gnu + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + # some targets don't use cross so will require the deps in the host + - uses: WyriHaximus/github-action-get-previous-tag@v1.4.0 + id: latest-tag + - uses: dsherret/rust-toolchain-file@v1 + with: + targets: ${{ matrix.target }} + - uses: mozilla-actions/sccache-action@v0.0.6 + - run: | + rustup target add ${{ matrix.target }} + - shell: bash + run: | + cargo build --release --locked --package ghjk --target ${{ matrix.target }} + cd target/${{ matrix.target }}/release/ + tar czvf ../../../ghjk-${{ steps.latest-tag.outputs.tag }}-${{ matrix.target }}.tar.gz ghjk + cd ../../../ + - uses: svenstaro/upload-release-action@v2 + with: + tag: ${{ steps.latest-tag.outputs.tag }} + file: "ghjk-${{ steps.latest-tag.outputs.tag }}-${{ matrix.target }}.tar.gz" + asset_name: "ghjk-${{ steps.latest-tag.outputs.tag }}-${{ matrix.target }}.tar.gz" + overwrite: ${{ inputs.ovewriteArtifacts }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 521cced9..1517cffc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,3 +1,5 @@ +name: test suite +run-name: test suite for ${{ github.event.pull_request.title || github.ref }} on: push: branches: @@ -8,14 +10,16 @@ on: - synchronize - ready_for_review +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: - DENO_VERSION: "1.44.2" + DENO_VERSION: "2.1.2" GHJK_LOG: debug GHJK_LOG_PANIC_LEVEL: error DENO_DIR: .deno-dir GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # removing the images after every test is unncessary - DOCKER_NO_RMI: 1 jobs: changes: @@ -26,9 +30,11 @@ jobs: - uses: actions/checkout@v4 test-pre-commit: + timeout-minutes: 60 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - uses: dsherret/rust-toolchain-file@v1 - uses: denoland/setup-deno@v1 with: deno-version: ${{ env.DENO_VERSION }} @@ -36,12 +42,13 @@ jobs: # pre commit runs ghjk. We'll always see changes # to lock.json since GITHUB_TOKEN is different # in the CI - - run: deno run --unstable -A main.ts print config + - run: deno task self envs cook -t lock-sed - uses: pre-commit/action@v3.0.1 env: SKIP: ghjk-resolve test-e2e: + timeout-minutes: 60 runs-on: "${{ matrix.os }}" strategy: fail-fast: false @@ -49,22 +56,16 @@ jobs: include: - os: ubuntu-latest platform: linux/x86_64 - e2eType: "local" - os: custom-arm platform: linux/aarch64 - e2eType: "local" - os: macos-latest platform: darwin/x86_64 - e2eType: "local" - os: macos-14 platform: darwin/aarch64 - e2eType: "local" # - os: windows-latest - # e2eType: "local" - env: - GHJK_TEST_E2E_TYPE: ${{ matrix.e2eType }} steps: - uses: actions/checkout@v4 + - uses: dsherret/rust-toolchain-file@v1 - uses: denoland/setup-deno@v1 with: deno-version: ${{ env.DENO_VERSION }} @@ -73,31 +74,29 @@ jobs: with: path: ${{ env.DENO_DIR }} key: deno-${{ hashFiles('**/deno.lock') }} - - if: "${{ matrix.e2eType == 'docker' }}" - uses: docker/setup-buildx-action@v3 - if: "${{ matrix.os == 'ubuntu-latest' || matrix.os == 'custom-arm' }}" + # need coreutils on max for the `timeout` command + # need cmake to build the rust deps run: | - # we need coreutils on max for the `timeout` command sudo apt update - sudo apt install -y --no-install-recommends fish zsh + sudo apt install -y --no-install-recommends fish zsh cmake - if: "${{ matrix.os == 'macos-latest' || matrix.os == 'macos-14' }}" - # we need coreutils on max for the `timeout` command - run: brew install fish zsh coreutils - - env: - DOCKER_PLATFORM: ${{ matrix.platform }} - run: deno task test - + # need cmake to build the rust deps + # need coreutils on max for the `timeout` command + run: brew install fish zsh coreutils cmake + - run: deno task test - test-action: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: metatypedev/setup-ghjk@318209a9d215f70716a4ac89dbeb9653a2deb8bc - with: - installer-url: ./install.ts - env: - GHJKFILE: ./examples/protoc/ghjk.ts - - run: | - cd examples/tasks - . $(ghjk print share-dir-path)/env.sh - ghjk x hey + # test-action: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: dsherret/rust-toolchain-file@v1 + # - uses: metatypedev/setup-ghjk@318209a9d215f70716a4ac89dbeb9653a2deb8bc + # with: + # installer-url: ./install.ts + # env: + # GHJKFILE: ./examples/protoc/ghjk.ts + # - run: | + # cd examples/tasks + # . $(ghjk print share-dir-path)/env.sh + # ghjk x hey diff --git a/.gitignore b/.gitignore index 6e7b8fb3..269d8a0a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,9 @@ npm deno.land jsr.io esm.sh + +src/play/*.rs + +# Added by cargo + +/target diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ebf0045..a0766cc4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,13 +15,13 @@ repos: - id: end-of-file-fixer # exclude all generated files exclude: | - (?x)^( - .ghjk/lock.json| - .ghjk/hash.json| - .ghjk/deno.lock| - deno.lock| - gh_action/.*.js - )$ + (?x)^( + .ghjk/lock.json| + .ghjk/hash.json| + .ghjk/deno.lock| + deno.lock| + gh_action/.*.js + )$ - repo: https://github.com/python-jsonschema/check-jsonschema rev: 0.28.2 hooks: @@ -38,12 +38,12 @@ repos: - id: ghjk-resolve name: Ghjk resolve language: system - entry: bash -c 'deno run --unstable -A main.ts p resolve' + entry: bash -c 'deno task self p resolve' pass_filenames: false - id: lock-sed name: Sed lock language: system - entry: bash -c 'deno run --unstable -A main.ts x lock-sed' + entry: bash -c 'deno task self x lock-sed' pass_filenames: false - id: deno-fmt name: Deno format @@ -66,3 +66,15 @@ repos: pass_filenames: false types: - ts + - repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: fmt + - id: clippy + args: + - "--locked" + - "--all-features" + - "--all-targets" + - "--" + - "--deny" + - "warnings" diff --git a/.vscode/settings.json b/.vscode/settings.json index cd2b6816..6317ba2c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,7 +22,10 @@ "DENO", "ghjk", "ghjkfile", + "ghjkfiles", "Hashfile", + "indexmap", + "kwargs", "POSIX", "runtimes", "sophon" diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..6b1776b2 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,9366 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aead-gcm-stream" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4947a169074c7e038fa43051d1c4e073f4488b0e4b0a30658f1e1a1b06449ce8" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-kw" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fa2b352dcefb5f7f3a5fb840e02665d311d878955380515e4fd50095dd3d8c" +dependencies = [ + "aes", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +dependencies = [ + "serde", +] + +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ast_node" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "async-compression" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "asynchronous-codec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" +dependencies = [ + "bytes", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64-simd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" +dependencies = [ + "simd-abstraction", +] + +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref 0.5.1", + "vsimd", +] + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "better_scoped_tls" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de" +dependencies = [ + "scoped-tls", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.87", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "boxed_error" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4f95e880cfd28c4ca5a006cf7f6af52b4bcb7b5866f573b2faa126fb7affb" +dependencies = [ + "quote", + "syn 2.0.87", +] + +[[package]] +name = "brotli" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "bytemuck" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cache_control" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" + +[[package]] +name = "caseless" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f" +dependencies = [ + "regex", + "unicode-normalization", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading 0.8.4", +] + +[[package]] +name = "clap" +version = "4.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "terminal_size", +] + +[[package]] +name = "clap_complete" +version = "4.5.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7db6eca8c205649e8d3ccd05aa5042b1800a784e56bc7c43524fde8abbfa9b" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_fig" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d494102c8ff3951810c72baf96910b980fb065ca5d3101243e6a8dc19747c86b" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "clap_lex" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" + +[[package]] +name = "clipboard-win" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79f4473f5144e20d9aceaf2972478f06ddf687831eafeeb434fbaf0acc4144ad" +dependencies = [ + "error-code", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-print" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" +dependencies = [ + "color-print-proc-macro", +] + +[[package]] +name = "color-print-proc-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" +dependencies = [ + "nom 7.1.3", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "comrak" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c32ff8b21372fab0e9ecc4e42536055702dc5faa418362bffd1544f9d12637" +dependencies = [ + "caseless", + "derive_builder", + "entities", + "memchr", + "once_cell", + "regex", + "slug", + "typed-arena", + "unicode_categories", +] + +[[package]] +name = "config" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" +dependencies = [ + "async-trait", + "json5", + "nom 7.1.3", + "pathdiff", + "serde", + "serde_json", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "console-api" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857" +dependencies = [ + "futures-core", + "prost", + "prost-types", + "tonic", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime", + "hyper-util", + "prost", + "prost-types", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "console_static_text" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4be93df536dfbcbd39ff7c129635da089901116b88bfc29ec1acb9b56f8ff35" +dependencies = [ + "unicode-width", + "vte", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_fn" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373e9fafaa20882876db20562275ff58d50e0caa2590077fe7ce7bef90211d0d" + +[[package]] +name = "const_format" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cooked-waker" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147be55d677052dabc6b22252d5dd0fd4c29c8c27aa4f2fbef0f94aa003b406f" + +[[package]] +name = "cordyceps" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec10f0a762d93c4498d2e97a333805cb6250d60bead623f71d8034f9a4152ba3" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "css_dataset" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25670139e591f1c2869eb8d0d977028f8d05e859132b4c874ecd02a00d3c9174" + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto 0.2.9", + "rustc_version 0.4.0", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "d3d12" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28bfe653d79bd16c77f659305b195b82bb5ce0c0eb2a4846b82ddbd77586813" +dependencies = [ + "bitflags 2.6.0", + "libloading 0.8.4", + "winapi", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.87", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", + "serde", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "data-url" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f" + +[[package]] +name = "debug-ignore" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe7ed1d93f4553003e20b629abe9085e1e81b1429520f897f8f8860bc6dfc21" + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + +[[package]] +name = "deno" +version = "2.1.2" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "anstream", + "async-trait", + "base64 0.21.7", + "bincode", + "bytes", + "cache_control", + "chrono", + "clap", + "clap_complete", + "clap_complete_fig", + "color-print", + "console_static_text", + "dashmap", + "data-encoding", + "deno_ast", + "deno_cache_dir", + "deno_config", + "deno_core", + "deno_doc", + "deno_graph", + "deno_lint", + "deno_lockfile", + "deno_npm", + "deno_package_json", + "deno_path_util", + "deno_resolver", + "deno_runtime", + "deno_semver", + "deno_task_shell", + "deno_telemetry", + "deno_terminal 0.2.0", + "deno_tower_lsp", + "dissimilar", + "dotenvy", + "dprint-plugin-json", + "dprint-plugin-jupyter", + "dprint-plugin-markdown", + "dprint-plugin-typescript", + "env_logger", + "fancy-regex", + "faster-hex", + "flate2", + "fs3", + "glibc_version", + "glob", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper-util", + "import_map", + "indexmap 2.6.0", + "jsonc-parser", + "junction", + "lazy-regex", + "libc", + "libsui", + "libz-sys", + "log", + "lsp-types", + "malva", + "markup_fmt", + "memmem", + "monch", + "nix 0.27.1", + "node_resolver", + "notify", + "once_cell", + "open", + "p256", + "pathdiff", + "percent-encoding", + "phf", + "pretty_yaml", + "quick-junit", + "rand", + "regex", + "ring", + "runtimelib", + "rustyline", + "rustyline-derive", + "serde", + "serde_json", + "serde_repr", + "sha2", + "shell-escape", + "spki", + "sqlformat", + "strsim", + "tar", + "tempfile", + "text-size", + "text_lines", + "thiserror", + "tokio", + "tokio-util", + "tracing", + "twox-hash", + "typed-arena", + "uuid", + "walkdir", + "which 4.4.2", + "winapi", + "winres", + "zeromq", + "zip", + "zstd", +] + +[[package]] +name = "deno-tower-lsp-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d59a1cfd445fd86f63616127a434aabca000e03d963b01b03ce813520565b9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "deno_ast" +version = "0.43.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d00b724e06d2081a141ec1155756a0b465d413d8e2a7515221f61d482eb2ee" +dependencies = [ + "base64 0.21.7", + "deno_media_type", + "deno_terminal 0.1.1", + "dprint-swc-ext", + "once_cell", + "percent-encoding", + "serde", + "sourcemap 9.1.0", + "swc_atoms", + "swc_bundler", + "swc_common", + "swc_config", + "swc_config_macro", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_codegen_macros", + "swc_ecma_loader", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_transforms_macros", + "swc_ecma_transforms_optimization", + "swc_ecma_transforms_proposal", + "swc_ecma_transforms_react", + "swc_ecma_transforms_typescript", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_eq_ignore_macros", + "swc_graph_analyzer", + "swc_macros_common", + "swc_visit", + "swc_visit_macros", + "text_lines", + "thiserror", + "unicode-width", + "url", +] + +[[package]] +name = "deno_broadcast_channel" +version = "0.174.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "deno_core", + "thiserror", + "tokio", + "uuid", +] + +[[package]] +name = "deno_cache" +version = "0.112.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "deno_core", + "rusqlite", + "serde", + "sha2", + "thiserror", + "tokio", +] + +[[package]] +name = "deno_cache_dir" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c1f52170cd7715f8006da54cde1444863a0d6fbd9c11d037a737db2dec8e22" +dependencies = [ + "base32", + "deno_media_type", + "deno_path_util", + "indexmap 2.6.0", + "log", + "once_cell", + "parking_lot", + "serde", + "serde_json", + "sha2", + "thiserror", + "url", +] + +[[package]] +name = "deno_canvas" +version = "0.49.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_webgpu", + "image", + "serde", + "thiserror", +] + +[[package]] +name = "deno_config" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38fb809500238be2b10eee42944a47b3ac38974e1edbb47f73afcfca7df143bf" +dependencies = [ + "anyhow", + "deno_package_json", + "deno_path_util", + "deno_semver", + "glob", + "ignore", + "import_map", + "indexmap 2.6.0", + "jsonc-parser", + "log", + "percent-encoding", + "phf", + "serde", + "serde_json", + "thiserror", + "url", +] + +[[package]] +name = "deno_console" +version = "0.180.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", +] + +[[package]] +name = "deno_core" +version = "0.323.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a781bcfe1b5211b8497f45bf5b3dba73036b8d5d1533c1f05d26ccf0afb25a78" +dependencies = [ + "anyhow", + "az", + "bincode", + "bit-set", + "bit-vec", + "bytes", + "cooked-waker", + "deno_core_icudata", + "deno_ops", + "deno_unsync", + "futures", + "indexmap 2.6.0", + "libc", + "memoffset", + "parking_lot", + "percent-encoding", + "pin-project", + "serde", + "serde_json", + "serde_v8", + "smallvec", + "sourcemap 8.0.1", + "static_assertions", + "tokio", + "url", + "v8", + "wasm_dep_analyzer", +] + +[[package]] +name = "deno_core_icudata" +version = "0.74.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" + +[[package]] +name = "deno_cron" +version = "0.60.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "deno_core", + "saffron", + "thiserror", + "tokio", +] + +[[package]] +name = "deno_crypto" +version = "0.194.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "aes", + "aes-gcm", + "aes-kw", + "base64 0.21.7", + "cbc", + "const-oid", + "ctr", + "curve25519-dalek", + "deno_core", + "deno_web", + "ed448-goldilocks", + "elliptic-curve", + "num-traits", + "once_cell", + "p256", + "p384", + "p521", + "rand", + "ring", + "rsa", + "sec1", + "serde", + "serde_bytes", + "sha1", + "sha2", + "signature", + "spki", + "thiserror", + "tokio", + "uuid", + "x25519-dalek", +] + +[[package]] +name = "deno_doc" +version = "0.161.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d994915f85e873865fc341e592080a487b0a987d06177016b2d93fd62162f8" +dependencies = [ + "anyhow", + "cfg-if", + "comrak", + "deno_ast", + "deno_graph", + "deno_path_util", + "handlebars", + "html-escape", + "import_map", + "indexmap 2.6.0", + "itoa", + "js-sys", + "lazy_static", + "percent-encoding", + "regex", + "serde", + "serde-wasm-bindgen", + "serde_json", + "termcolor", + "url", + "wasm-bindgen", +] + +[[package]] +name = "deno_fetch" +version = "0.204.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "base64 0.21.7", + "bytes", + "data-url", + "deno_core", + "deno_permissions", + "deno_tls", + "dyn-clone", + "error_reporter", + "hickory-resolver", + "http 1.1.0", + "http-body-util", + "hyper 1.5.0", + "hyper-rustls", + "hyper-util", + "ipnet", + "percent-encoding", + "rustls-webpki", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-socks", + "tokio-util", + "tower", + "tower-http", + "tower-service", +] + +[[package]] +name = "deno_ffi" +version = "0.167.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_permissions", + "dlopen2 0.6.1", + "dynasmrt", + "libffi", + "libffi-sys", + "log", + "num-bigint", + "serde", + "serde-value", + "serde_json", + "thiserror", + "tokio", + "winapi", +] + +[[package]] +name = "deno_fs" +version = "0.90.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "base32", + "boxed_error", + "deno_core", + "deno_io", + "deno_path_util", + "deno_permissions", + "filetime", + "junction", + "libc", + "nix 0.27.1", + "rand", + "rayon", + "serde", + "thiserror", + "winapi", + "windows-sys 0.52.0", +] + +[[package]] +name = "deno_graph" +version = "0.86.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3f4be49dad28e794ff4eeb2daaf7956c97f8557097ef6f9c3ff1292e0a5c28" +dependencies = [ + "anyhow", + "async-trait", + "data-url", + "deno_ast", + "deno_semver", + "deno_unsync", + "encoding_rs", + "futures", + "import_map", + "indexmap 2.6.0", + "log", + "monch", + "once_cell", + "parking_lot", + "regex", + "serde", + "serde_json", + "sha2", + "thiserror", + "twox-hash", + "url", + "wasm_dep_analyzer", +] + +[[package]] +name = "deno_http" +version = "0.178.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-compression", + "async-trait", + "base64 0.21.7", + "brotli", + "bytes", + "cache_control", + "deno_core", + "deno_net", + "deno_websocket", + "flate2", + "http 0.2.12", + "http 1.1.0", + "httparse", + "hyper 0.14.29", + "hyper 1.5.0", + "hyper-util", + "itertools 0.10.5", + "memmem", + "mime", + "once_cell", + "percent-encoding", + "phf", + "pin-project", + "ring", + "scopeguard", + "serde", + "smallvec", + "thiserror", + "tokio", + "tokio-util", +] + +[[package]] +name = "deno_io" +version = "0.90.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "deno_core", + "filetime", + "fs3", + "libc", + "log", + "once_cell", + "os_pipe", + "parking_lot", + "pin-project", + "rand", + "tokio", + "uuid", + "winapi", + "windows-sys 0.52.0", +] + +[[package]] +name = "deno_kv" +version = "0.88.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.7", + "boxed_error", + "bytes", + "chrono", + "deno_core", + "deno_fetch", + "deno_path_util", + "deno_permissions", + "deno_tls", + "denokv_proto", + "denokv_remote", + "denokv_sqlite", + "faster-hex", + "http 1.1.0", + "http-body-util", + "log", + "num-bigint", + "prost", + "prost-build", + "rand", + "rusqlite", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "deno_lint" +version = "0.68.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb994e6d1b18223df0a756c7948143b35682941d615edffef60d5b38822f38ac" +dependencies = [ + "anyhow", + "deno_ast", + "derive_more", + "if_chain", + "log", + "once_cell", + "phf", + "regex", + "serde", + "serde_json", +] + +[[package]] +name = "deno_lockfile" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579117d5815aa9bae0212637d6f4d5f45f9649bb2c8988dca434077545535039" +dependencies = [ + "deno_semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "deno_media_type" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf552fbdedbe81c89705349d7d2485c7051382b000dfddbdbf7fc25931cf83" +dependencies = [ + "data-url", + "serde", + "url", +] + +[[package]] +name = "deno_napi" +version = "0.111.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_permissions", + "libc", + "libloading 0.7.4", + "log", + "napi_sym", + "thiserror", + "windows-sys 0.52.0", +] + +[[package]] +name = "deno_native_certs" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bc737e098a45aa5742d51ce694ac7236a1e69fb0d9df8c862e9b4c9583c5f9" +dependencies = [ + "dlopen2 0.7.0", + "dlopen2_derive", + "once_cell", + "rustls-native-certs", + "rustls-pemfile", +] + +[[package]] +name = "deno_net" +version = "0.172.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_permissions", + "deno_tls", + "hickory-proto", + "hickory-resolver", + "pin-project", + "rustls-tokio-stream", + "serde", + "socket2", + "thiserror", + "tokio", +] + +[[package]] +name = "deno_node" +version = "0.117.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "aead-gcm-stream", + "aes", + "async-trait", + "base64 0.21.7", + "blake2", + "boxed_error", + "brotli", + "bytes", + "cbc", + "const-oid", + "data-encoding", + "deno_core", + "deno_fetch", + "deno_fs", + "deno_io", + "deno_media_type", + "deno_net", + "deno_package_json", + "deno_path_util", + "deno_permissions", + "deno_whoami", + "der", + "digest", + "dsa", + "ecb", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "errno 0.2.8", + "faster-hex", + "h2 0.4.5", + "hkdf", + "home", + "http 1.1.0", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "idna 1.0.3", + "indexmap 2.6.0", + "ipnetwork", + "k256", + "lazy-regex", + "libc", + "libz-sys", + "md-5", + "md4", + "memchr", + "node_resolver", + "num-bigint", + "num-bigint-dig", + "num-integer", + "num-traits", + "once_cell", + "p224", + "p256", + "p384", + "path-clean", + "pbkdf2", + "pin-project-lite", + "pkcs8", + "rand", + "regex", + "ring", + "ripemd", + "rsa", + "scrypt", + "sec1", + "serde", + "sha1", + "sha2", + "sha3", + "signature", + "simd-json", + "sm3", + "spki", + "stable_deref_trait", + "thiserror", + "tokio", + "tokio-eld", + "url", + "webpki-root-certs", + "winapi", + "windows-sys 0.52.0", + "x25519-dalek", + "x509-parser", + "yoke", +] + +[[package]] +name = "deno_npm" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b4dc4a9f1cff63d5638e7d93042f24f46300d1cc77b86f3caaa699a7ddccf7" +dependencies = [ + "anyhow", + "async-trait", + "deno_lockfile", + "deno_semver", + "futures", + "log", + "monch", + "serde", + "serde_json", + "thiserror", + "url", +] + +[[package]] +name = "deno_ops" +version = "0.199.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24a1f3e22029a57d3094b32070b8328eac793920b5a022027d360f085e6b245" +dependencies = [ + "proc-macro-rules", + "proc-macro2", + "quote", + "stringcase", + "strum", + "strum_macros", + "syn 2.0.87", + "thiserror", +] + +[[package]] +name = "deno_package_json" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbc4c4d3eb0960b58e8f43f9fc2d3f620fcac9a03cd85203e08db5b04e83c1f" +dependencies = [ + "deno_semver", + "indexmap 2.6.0", + "serde", + "serde_json", + "thiserror", + "url", +] + +[[package]] +name = "deno_path_util" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff25f6e08e7a0214bbacdd6f7195c7f1ebcd850c87a624e4ff06326b68b42d99" +dependencies = [ + "percent-encoding", + "thiserror", + "url", +] + +[[package]] +name = "deno_permissions" +version = "0.40.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_path_util", + "deno_terminal 0.2.0", + "fqdn", + "libc", + "log", + "once_cell", + "percent-encoding", + "serde", + "thiserror", + "which 4.4.2", + "winapi", +] + +[[package]] +name = "deno_resolver" +version = "0.12.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "anyhow", + "base32", + "boxed_error", + "dashmap", + "deno_config", + "deno_media_type", + "deno_package_json", + "deno_path_util", + "deno_semver", + "node_resolver", + "thiserror", + "url", +] + +[[package]] +name = "deno_runtime" +version = "0.189.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "color-print", + "deno_ast", + "deno_broadcast_channel", + "deno_cache", + "deno_canvas", + "deno_console", + "deno_core", + "deno_cron", + "deno_crypto", + "deno_fetch", + "deno_ffi", + "deno_fs", + "deno_http", + "deno_io", + "deno_kv", + "deno_napi", + "deno_net", + "deno_node", + "deno_path_util", + "deno_permissions", + "deno_telemetry", + "deno_terminal 0.2.0", + "deno_tls", + "deno_url", + "deno_web", + "deno_webgpu", + "deno_webidl", + "deno_websocket", + "deno_webstorage", + "dlopen2 0.6.1", + "encoding_rs", + "fastwebsockets", + "flate2", + "http 1.1.0", + "http-body-util", + "hyper 0.14.29", + "hyper 1.5.0", + "hyper-util", + "libc", + "log", + "netif", + "nix 0.27.1", + "node_resolver", + "notify", + "ntapi", + "once_cell", + "percent-encoding", + "regex", + "rustyline", + "same-file", + "serde", + "signal-hook", + "signal-hook-registry", + "tempfile", + "thiserror", + "tokio", + "tokio-metrics", + "twox-hash", + "uuid", + "which 4.4.2", + "winapi", + "windows-sys 0.52.0", +] + +[[package]] +name = "deno_semver" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c957c6a57c38b7dde2315df0da0ec228911e56a74f185b108a488d0401841a67" +dependencies = [ + "monch", + "once_cell", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "deno_task_shell" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f444918f7102c1a5a143e9d57809e499fb4d365070519bf2e8bdb16d586af2a" +dependencies = [ + "anyhow", + "futures", + "glob", + "monch", + "os_pipe", + "path-dedot", + "thiserror", + "tokio", + "tokio-util", +] + +[[package]] +name = "deno_telemetry" +version = "0.2.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "deno_core", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "log", + "once_cell", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "pin-project", + "serde", + "tokio", +] + +[[package]] +name = "deno_terminal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6337d4e7f375f8b986409a76fbeecfa4bd8a1343e63355729ae4befa058eaf" +dependencies = [ + "once_cell", + "termcolor", +] + +[[package]] +name = "deno_terminal" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daef12499e89ee99e51ad6000a91f600d3937fb028ad4918af76810c5bc9e0d5" +dependencies = [ + "once_cell", + "termcolor", +] + +[[package]] +name = "deno_tls" +version = "0.167.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_native_certs", + "rustls", + "rustls-pemfile", + "rustls-tokio-stream", + "rustls-webpki", + "serde", + "thiserror", + "tokio", + "webpki-roots", +] + +[[package]] +name = "deno_tower_lsp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afb4d257c084fd889e8cf1ba3ad58db0002428c819cc7717815f996f97777a" +dependencies = [ + "async-trait", + "auto_impl", + "bytes", + "dashmap", + "deno-tower-lsp-macros", + "futures", + "httparse", + "lsp-types", + "memchr", + "serde", + "serde_json", + "tokio", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "deno_unsync" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f36b4ef61a04ce201b925a5dffa90f88437d37fee4836c758470dd15ba7f05e" +dependencies = [ + "parking_lot", + "tokio", +] + +[[package]] +name = "deno_url" +version = "0.180.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "thiserror", + "urlpattern", +] + +[[package]] +name = "deno_web" +version = "0.211.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "async-trait", + "base64-simd 0.8.0", + "bytes", + "deno_core", + "deno_permissions", + "encoding_rs", + "flate2", + "futures", + "serde", + "thiserror", + "tokio", + "uuid", +] + +[[package]] +name = "deno_webgpu" +version = "0.147.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "raw-window-handle", + "serde", + "thiserror", + "tokio", + "wgpu-core", + "wgpu-types", +] + +[[package]] +name = "deno_webidl" +version = "0.180.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", +] + +[[package]] +name = "deno_websocket" +version = "0.185.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "bytes", + "deno_core", + "deno_net", + "deno_permissions", + "deno_tls", + "fastwebsockets", + "h2 0.4.5", + "http 1.1.0", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "once_cell", + "rustls-tokio-stream", + "serde", + "thiserror", + "tokio", +] + +[[package]] +name = "deno_webstorage" +version = "0.175.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "deno_core", + "deno_web", + "rusqlite", + "thiserror", +] + +[[package]] +name = "deno_whoami" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75e4caa92b98a27f09c671d1399aee0f5970aa491b9a598523aac000a2192e3" +dependencies = [ + "libc", + "whoami", +] + +[[package]] +name = "denokv_proto" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7ba1f99ed11a9c11e868a8521b1f71a7e1aba785d7f42ea9ecbdc01146c89ec" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "futures", + "num-bigint", + "prost", + "serde", + "uuid", +] + +[[package]] +name = "denokv_remote" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ed833073189e8f6d03155fe3b05a024e75e29d8a28a4c2e9ec3b5c925e727b" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "bytes", + "chrono", + "denokv_proto", + "futures", + "http 1.1.0", + "log", + "prost", + "rand", + "serde", + "serde_json", + "tokio", + "tokio-util", + "url", + "uuid", +] + +[[package]] +name = "denokv_sqlite" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b790f01d1302d53a0c3cbd27de88a06b3abd64ec8ab8673924e490541c7c713" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "chrono", + "denokv_proto", + "futures", + "hex", + "log", + "num-bigint", + "rand", + "rusqlite", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "uuid", + "v8_valueserializer", +] + +[[package]] +name = "denort" +version = "0.3.0-rc.1" +dependencies = [ + "anyhow", + "color-eyre", + "deno", + "educe", + "tokio", + "tracing", + "tracing-subscriber", + "tracing-unwrap", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "der_derive", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.87", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" + +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror", + "zeroize", +] + +[[package]] +name = "diatomic-waker" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "dissimilar" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c97b9233581d84b8e1e689cdd3a47b6f69770084fc246e86a7f78b0d9c1d4a5" + +[[package]] +name = "dlopen2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc2c7ed06fd72a8513ded8d0d2f6fd2655a85d6885c48cae8625d80faf28c03" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dprint-core" +version = "0.66.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab0dd2bedc109d25f0d21afb09b7d329f6c6fa83b095daf31d2d967e091548" +dependencies = [ + "anyhow", + "bumpalo", + "hashbrown 0.14.5", + "indexmap 2.6.0", + "rustc-hash", + "serde", + "unicode-width", +] + +[[package]] +name = "dprint-core-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1675ad2b358481f3cc46202040d64ac7a36c4ade414a696df32e0e45421a6e9f" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dprint-plugin-json" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57f91e594559b450b7c5d6a0ba9f3f9fe951c1ea371168f7c95973da3fdbd85a" +dependencies = [ + "anyhow", + "dprint-core", + "dprint-core-macros", + "jsonc-parser", + "serde", + "text_lines", +] + +[[package]] +name = "dprint-plugin-jupyter" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d20684e37b3824e2bc917cfcb14e2cdf88398eef507335d839cbd78172bfee" +dependencies = [ + "anyhow", + "dprint-core", + "jsonc-parser", + "serde", + "serde_json", +] + +[[package]] +name = "dprint-plugin-markdown" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934a8e33f6f373b2fb66c288a468e3dae9a56a6c66bfecd5504fe566131afd3f" +dependencies = [ + "anyhow", + "dprint-core", + "dprint-core-macros", + "pulldown-cmark", + "regex", + "serde", + "unicode-width", +] + +[[package]] +name = "dprint-plugin-typescript" +version = "0.93.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff29fd136541e59d51946f0d2d353fefc886776f61a799ebfb5838b06cef13b" +dependencies = [ + "anyhow", + "deno_ast", + "dprint-core", + "dprint-core-macros", + "percent-encoding", + "rustc-hash", + "serde", +] + +[[package]] +name = "dprint-swc-ext" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba28c12892aadb751c2ba7001d8460faee4748a04b4edc51c7121cc67ee03db" +dependencies = [ + "allocator-api2", + "bumpalo", + "num-bigint", + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "text_lines", +] + +[[package]] +name = "dsa" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48bc224a9084ad760195584ce5abb3c2c34a225fa312a128ad245a6b412b7689" +dependencies = [ + "digest", + "num-bigint-dig", + "num-traits", + "pkcs8", + "rfc6979", + "sha2", + "signature", + "zeroize", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "dynasm" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dynasmrt" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" +dependencies = [ + "byteorder", + "dynasm", + "memmap2", +] + +[[package]] +name = "ecb" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a8bfa975b1aec2145850fcaa1c6fe269a16578c44705a532ae3edc92b8881c7" +dependencies = [ + "cipher", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core", + "serde", + "sha2", + "signature", + "subtle", + "zeroize", +] + +[[package]] +name = "ed448-goldilocks" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06924531e9e90130842b012e447f85bdaf9161bc8a0f8092be8cb70b01ebe092" +dependencies = [ + "fiat-crypto 0.1.20", + "hex", + "subtle", + "zeroize", +] + +[[package]] +name = "editpe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cede2bb1b07dd598d269f973792c43e0cd92686d3b452bd6e01d7a8eb01211" +dependencies = [ + "debug-ignore", + "indexmap 2.6.0", + "log", + "thiserror", + "zerocopy", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "serde_json", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "error-code" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" + +[[package]] +name = "error_reporter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ae425815400e5ed474178a7a22e275a9687086a12ca63ec793ff292d8fdae8" + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fancy-regex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fastwebsockets" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26da0c7b5cef45c521a6f9cdfffdfeb6c9f5804fbac332deb5ae254634c7a6be" +dependencies = [ + "base64 0.21.7", + "bytes", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "pin-project", + "rand", + "sha1", + "simdutf8", + "thiserror", + "tokio", + "utf-8", +] + +[[package]] +name = "fd-lock" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5768da2206272c81ef0b5e951a41862938a6070da63bcea197899942d3b947" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "libz-sys", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fqdn" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08b1eaa7dfddeab6036292995620bf0435712e619db6d7690605897e76975eb0" + +[[package]] +name = "from_variant" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" +dependencies = [ + "proc-macro2", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "fs3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb17cf6ed704f72485332f6ab65257460c4f9f3083934cf402bf9f5b3b600a90" +dependencies = [ + "libc", + "rustc_version 0.2.3", + "winapi", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "fslock" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04412b8935272e3a9bae6f48c7bfff74c2911f60525404edfdd28e49884c3bfb" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-buffered" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34acda8ae8b63fbe0b2195c998b180cff89a8212fb2622a78b572a9f1c6f7684" +dependencies = [ + "cordyceps", + "diatomic-waker", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-concurrency" +version = "7.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b724496da7c26fcce66458526ce68fc2ecf4aaaa994281cf322ded5755520c" +dependencies = [ + "fixedbitset 0.5.7", + "futures-buffered", + "futures-core", + "futures-lite", + "pin-project", + "slab", + "smallvec", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "ghjk" +version = "0.3.0-rc.1" +dependencies = [ + "ahash", + "anyhow", + "async-trait", + "bitflags 2.6.0", + "clap", + "clap_complete", + "color-eyre", + "config", + "console", + "console-subscriber", + "dashmap", + "data-encoding", + "deno_core", + "denort", + "dialoguer", + "directories", + "educe", + "futures", + "indexmap 2.6.0", + "itertools 0.13.0", + "json-canon", + "multihash", + "nix 0.29.0", + "once_cell", + "parking_lot", + "pathdiff", + "rand", + "regex", + "serde", + "serde_json", + "sha2", + "shadow-rs", + "smallvec", + "smartstring", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tracing", + "tracing-appender", + "tracing-error", + "tracing-futures", + "tracing-subscriber", + "tracing-unwrap", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glibc_version" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "803ff7635f1ab4e2c064b68a0c60da917d3d18dc8d086130f689d62ce4f1c33e" +dependencies = [ + "regex", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.6.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" +dependencies = [ + "bitflags 2.6.0", + "gpu-descriptor-types", + "hashbrown 0.14.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "gzip-header" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" +dependencies = [ + "crc32fast", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "halfbrown" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" +dependencies = [ + "hashbrown 0.14.5", + "serde", +] + +[[package]] +name = "handlebars" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315" +dependencies = [ + "heck 0.5.0", + "log", + "num-order", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64 0.21.7", + "byteorder", + "crossbeam-channel", + "flate2", + "nom 7.1.3", + "num-traits", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "serde", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "serde", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "hstr" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96274be293b8877e61974a607105d09c84caebe9620b47774aa8a6b942042dd4" +dependencies = [ + "hashbrown 0.14.5", + "new_debug_unreachable", + "once_cell", + "phf", + "rustc-hash", + "triomphe", +] + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.5.0", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper 1.5.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.5.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", + "png", +] + +[[package]] +name = "import_map" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "351a787decc56f38d65d16d32687265045d6d6a4531b4a0e1b649def3590354e" +dependencies = [ + "indexmap 2.6.0", + "log", + "percent-encoding", + "serde", + "serde_json", + "thiserror", + "url", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", + "serde", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "is_debug" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-canon" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447ae153a2bd47d61acc0d131295408e32ef87ed9785825a6f4ecef85afc0edb" +dependencies = [ + "ryu-js 0.2.2", + "serde", + "serde_json", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "jsonc-parser" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b558af6b49fd918e970471374e7a798b2c9bbcda624a210ffa3901ee5614bc8e" +dependencies = [ + "serde_json", +] + +[[package]] +name = "junction" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be39922b087cecaba4e2d5592dedfc8bda5d4a5a1231f143337cca207950b61d" +dependencies = [ + "scopeguard", + "winapi", +] + +[[package]] +name = "jupyter-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd71aa17c4fa65e6d7536ab2728881a41f8feb2ee5841c2240516c3c3d65d8b3" +dependencies = [ + "anyhow", + "serde", + "serde_json", + "thiserror", + "uuid", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading 0.8.4", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "lazy-regex" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.87", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libffi" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" +dependencies = [ + "libc", + "libffi-sys", +] + +[[package]] +name = "libffi-sys" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c" +dependencies = [ + "cc", +] + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +dependencies = [ + "cfg-if", + "windows-targets 0.52.5", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libsui" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89795977654ad6250d6c0915411b622bac22f9efb4f852af94b2e00964cab832" +dependencies = [ + "editpe", + "libc", + "sha2", + "windows-sys 0.48.0", + "zerocopy", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "cmake", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "serde", +] + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lsp-types" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071" +dependencies = [ + "bitflags 1.3.2", + "fluent-uri", + "serde", + "serde_json", + "serde_repr", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "malva" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c67b97ed99f56b86fa3c010843441f1fcdb71884bab96b8551bb3d1e7c6d529" +dependencies = [ + "aho-corasick", + "itertools 0.13.0", + "memchr", + "raffia", + "tiny_pretty", +] + +[[package]] +name = "markup_fmt" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f303c36143671ac6c54112eb5aa95649b169dae783fdb6ead2c0e88b408c425c" +dependencies = [ + "aho-corasick", + "css_dataset", + "itertools 0.13.0", + "memchr", + "tiny_pretty", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "md4" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da5ac363534dce5fabf69949225e174fbf111a498bf0ff794c8ea1fba9f3dda" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memmem" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" +dependencies = [ + "bitflags 2.6.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "monch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" + +[[package]] +name = "multihash" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" +dependencies = [ + "core2", + "unsigned-varint", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "naga" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.6.0", + "codespan-reporting", + "hexf-parse", + "indexmap 2.6.0", + "log", + "num-traits", + "rustc-hash", + "serde", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "napi_sym" +version = "0.110.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "quote", + "serde", + "serde_json", + "syn 2.0.87", +] + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "netif" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29a01b9f018d6b7b277fef6c79fdbd9bf17bb2d1e298238055cafab49baa5ee" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "node_resolver" +version = "0.19.0" +source = "git+https://github.com/metatypedev/deno?branch=v2.1.2-embeddable#56aa322605a14bb3911b75376846c8624e4f4104" +dependencies = [ + "anyhow", + "async-trait", + "boxed_error", + "deno_media_type", + "deno_package_json", + "deno_path_util", + "futures", + "lazy-regex", + "once_cell", + "path-clean", + "regex", + "serde_json", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "nom" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.6.0", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand", + "serde", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "oid-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open" +version = "5.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "opentelemetry" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab70038c28ed37b97d8ed414b6429d343a8bbf44c9f79ec854f3a643029ba6d7" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite", + "thiserror", + "tracing", +] + +[[package]] +name = "opentelemetry-http" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a8a7f5f6ba7c1b286c2fbca0454eaba116f63bbe69ed250b642d36fbb04d80" +dependencies = [ + "async-trait", + "bytes", + "http 1.1.0", + "opentelemetry", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cf61a1868dacc576bf2b2a1c3e9ab150af7272909e80085c3173384fe11f76" +dependencies = [ + "async-trait", + "futures-core", + "http 1.1.0", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "serde_json", + "thiserror", + "tokio", + "tonic", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e05acbfada5ec79023c85368af14abd0b307c015e9064d249b2a950ef459a6" +dependencies = [ + "hex", + "opentelemetry", + "opentelemetry_sdk", + "prost", + "serde", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc1b6902ff63b32ef6c489e8048c5e253e2e4a803ea3ea7e783914536eb15c52" + +[[package]] +name = "opentelemetry_sdk" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231e9d6ceef9b0b2546ddf52335785ce41252bc7474ee8ba05bfad277be13ab8" +dependencies = [ + "async-trait", + "futures-channel", + "futures-executor", + "futures-util", + "glob", + "opentelemetry", + "percent-encoding", + "rand", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "outref" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" + +[[package]] +name = "outref" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "p224" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c06436d66652bc2f01ade021592c80a2aad401570a18aa18b82e440d2b9aa1" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core", + "sha2", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.2", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "path-clean" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" + +[[package]] +name = "path-dedot" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" +dependencies = [ + "once_cell", +] + +[[package]] +name = "pathdiff" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "pest_meta" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset 0.4.2", + "indexmap 2.6.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "aes", + "cbc", + "der", + "pbkdf2", + "scrypt", + "sha2", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "pkcs5", + "rand_core", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "play" +version = "0.3.0-rc.1" +dependencies = [ + "clap", + "color-eyre", + "data-encoding", + "futures-concurrency", + "once_cell", + "sha2", + "tokio", + "tracing", + "tracing-subscriber", + "tracing-unwrap", +] + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_yaml" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda9a64ee7296e82d1e0f4389383e6a7d8e6e2487d8391f7d028c131395fd376" +dependencies = [ + "rowan", + "tiny_pretty", + "yaml_parser", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.87", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-rules" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c277e4e643ef00c1233393c673f655e3672cf7eb3ba08a00bdd0ea59139b5f" +dependencies = [ + "proc-macro-rules-macros", + "proc-macro2", + "syn 2.0.87", +] + +[[package]] +name = "proc-macro-rules-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "207fffb0fe655d1d47f6af98cc2793405e85929bdbc420d685554ff07be27ac7" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" + +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" +dependencies = [ + "bytes", + "heck 0.5.0", + "itertools 0.13.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.87", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "prost-types" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +dependencies = [ + "prost", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pulldown-cmark" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625" +dependencies = [ + "bitflags 2.6.0", + "memchr", + "unicase", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-junit" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1a341ae463320e9f8f34adda49c8a85d81d4e8f34cce4397fb0350481552224" +dependencies = [ + "chrono", + "indexmap 2.6.0", + "quick-xml", + "strip-ansi-escapes", + "thiserror", + "uuid", +] + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_fmt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "raffia" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36f58fa7ad2f26bca656054c902becddeac5582df2bb31d4b4d2a148c62cfd5" +dependencies = [ + "raffia_macro", + "smallvec", +] + +[[package]] +name = "raffia_macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fdb50eb5bf734fa5a770680a61876a6ec77b99c1e0e52d1f18ad6ebfa85759f" +dependencies = [ + "heck 0.5.0", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags 2.6.0", + "serde", + "serde_derive", +] + +[[package]] +name = "rowan" +version = "0.15.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d" +dependencies = [ + "countme", + "hashbrown 0.14.5", + "rustc-hash", + "text-size", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "runtimelib" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe23ba9967355bbb1be2fb9a8e51bd239ffdf9c791fad5a9b765122ee2bde2e4" +dependencies = [ + "anyhow", + "base64 0.22.1", + "bytes", + "chrono", + "data-encoding", + "dirs", + "futures", + "glob", + "jupyter-serde", + "rand", + "ring", + "serde", + "serde_json", + "shellexpand", + "tokio", + "uuid", + "zeromq", +] + +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +dependencies = [ + "bitflags 2.6.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno 0.3.9", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-tokio-stream" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22557157d7395bc30727745b365d923f1ecc230c4c80b176545f3f4f08c46e33" +dependencies = [ + "futures", + "rustls", + "socket2", + "tokio", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "rustyline" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix 0.27.1", + "radix_trie", + "unicode-segmentation", + "unicode-width", + "utf8parse", + "winapi", +] + +[[package]] +name = "rustyline-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "107c3d5d7f370ac09efa62a78375f94d94b8a33c61d8c278b96683fb4dbf2d8d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "ryu-js" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f" + +[[package]] +name = "ryu-js" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" + +[[package]] +name = "saffron" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fb9a628596fc7590eb7edbf7b0613287be78df107f5f97b118aad59fb2eea9" +dependencies = [ + "chrono", + "nom 5.1.3", +] + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +dependencies = [ + "password-hash", + "pbkdf2", + "salsa20", + "sha2", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "indexmap 2.6.0", + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "serde_v8" +version = "0.232.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c9feae92f7293fcc1a32a86be1a399859c0637e55dad8991d5258c43f7ff4d2" +dependencies = [ + "num-bigint", + "serde", + "smallvec", + "thiserror", + "v8", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shadow-rs" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cfcd0643497a9f780502063aecbcc4a3212cbe4948fd25ee8fd179c2cf9a18" +dependencies = [ + "const_format", + "git2", + "is_debug", + "time", + "tzdb", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shell-escape" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simd-abstraction" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" +dependencies = [ + "outref 0.1.0", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd-json" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1df0290e9bfe79ddd5ff8798ca887cd107b75353d2957efe9777296e17f26b5" +dependencies = [ + "getrandom", + "halfbrown", + "ref-cast", + "serde", + "serde_json", + "simdutf8", + "value-trait", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + +[[package]] +name = "sm3" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb9a3b702d0a7e33bc4d85a14456633d2b165c2ad839c5fd9a8417c1ab15860" +dependencies = [ + "digest", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "sourcemap" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" +dependencies = [ + "base64-simd 0.7.0", + "bitvec", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash", + "rustc_version 0.2.3", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + +[[package]] +name = "sourcemap" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d146f02f4bbbabbbe3da0f9cd3ea2ab779defc4ed1f070b5bd83ea48ed78811" +dependencies = [ + "base64-simd 0.7.0", + "bitvec", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash", + "rustc_version 0.2.3", + "serde", + "serde_json", + "unicode-id-start", + "url", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c38684453189293372e6fffa3bed1015d20488ce4cc09a23de050fd7411e46" +dependencies = [ + "nom 7.1.3", + "once_cell", + "regex", + "unicode_categories", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_enum" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "stringcase" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04028eeb851ed08af6aba5caa29f2d59a13ed168cee4d6bd753aeefcf1d636b0" + +[[package]] +name = "strip-ansi-escapes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +dependencies = [ + "vte", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.87", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "swc_allocator" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76aa0eb65c0f39f9b6d82a7e5192c30f7ac9a78f084a21f270de1d8c600ca388" +dependencies = [ + "bumpalo", + "hashbrown 0.14.5", + "ptr_meta", + "rustc-hash", + "triomphe", +] + +[[package]] +name = "swc_atoms" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" +dependencies = [ + "hstr", + "once_cell", + "rustc-hash", + "serde", +] + +[[package]] +name = "swc_bundler" +version = "0.237.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77c112c218a09635d99a45802a81b4f341d6c28c81076aa2c29ba3bcd9151a9" +dependencies = [ + "anyhow", + "crc", + "indexmap 2.6.0", + "is-macro", + "once_cell", + "parking_lot", + "petgraph", + "radix_fmt", + "relative-path", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_loader", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_optimization", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_fast_graph", + "swc_graph_analyzer", + "tracing", +] + +[[package]] +name = "swc_cached" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83406221c501860fce9c27444f44125eafe9e598b8b81be7563d7036784cd05c" +dependencies = [ + "ahash", + "anyhow", + "dashmap", + "once_cell", + "regex", + "serde", +] + +[[package]] +name = "swc_common" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12d0a8eaaf1606c9207077d75828008cb2dfb51b095a766bd2b72ef893576e31" +dependencies = [ + "ast_node", + "better_scoped_tls", + "cfg-if", + "either", + "from_variant", + "new_debug_unreachable", + "num-bigint", + "once_cell", + "rustc-hash", + "serde", + "siphasher", + "sourcemap 9.1.0", + "swc_allocator", + "swc_atoms", + "swc_eq_ignore_macros", + "swc_visit", + "tracing", + "unicode-width", + "url", +] + +[[package]] +name = "swc_config" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000" +dependencies = [ + "anyhow", + "indexmap 2.6.0", + "serde", + "serde_json", + "swc_cached", + "swc_config_macro", +] + +[[package]] +name = "swc_config_macro" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f56139042c1a95b54f5ca48baa0e0172d369bcc9d3d473dad1de36bae8399" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "swc_ecma_ast" +version = "0.118.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f866d12e4d519052b92a0a86d1ac7ff17570da1272ca0c89b3d6f802cd79df" +dependencies = [ + "bitflags 2.6.0", + "is-macro", + "num-bigint", + "phf", + "scoped-tls", + "serde", + "string_enum", + "swc_atoms", + "swc_common", + "unicode-id-start", +] + +[[package]] +name = "swc_ecma_codegen" +version = "0.155.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7641608ef117cfbef9581a99d02059b522fcca75e5244fa0cbbd8606689c6f" +dependencies = [ + "memchr", + "num-bigint", + "once_cell", + "serde", + "sourcemap 9.1.0", + "swc_allocator", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_codegen_macros", + "tracing", +] + +[[package]] +name = "swc_ecma_codegen_macros" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859fabde36db38634f3fad548dd5e3410c1aebba1b67a3c63e67018fa57a0bca" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "swc_ecma_loader" +version = "0.49.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55fa3d55045b97894bfb04d38aff6d6302ac8a6a38e3bb3dfb0d20475c4974a9" +dependencies = [ + "anyhow", + "pathdiff", + "serde", + "swc_atoms", + "swc_common", + "tracing", +] + +[[package]] +name = "swc_ecma_parser" +version = "0.149.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683dada14722714588b56481399c699378b35b2ba4deb5c4db2fb627a97fb54b" +dependencies = [ + "either", + "new_debug_unreachable", + "num-bigint", + "num-traits", + "phf", + "serde", + "smallvec", + "smartstring", + "stacker", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "tracing", + "typed-arena", +] + +[[package]] +name = "swc_ecma_transforms_base" +version = "0.145.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65f21494e75d0bd8ef42010b47cabab9caaed8f2207570e809f6f4eb51a710d1" +dependencies = [ + "better_scoped_tls", + "bitflags 2.6.0", + "indexmap 2.6.0", + "once_cell", + "phf", + "rustc-hash", + "serde", + "smallvec", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_utils", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms_classes" +version = "0.134.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3d884594385bea9405a2e1721151470d9a14d3ceec5dd773c0ca6894791601" +dependencies = [ + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_macros" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500a1dadad1e0e41e417d633b3d6d5de677c9e0d3159b94ba3348436cdb15aab" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "swc_ecma_transforms_optimization" +version = "0.208.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d8447ea20ef76958a8240feef95743702485a84331e6df5bdbe7e383c87838" +dependencies = [ + "dashmap", + "indexmap 2.6.0", + "once_cell", + "petgraph", + "rustc-hash", + "serde_json", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_macros", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_fast_graph", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms_proposal" +version = "0.179.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79938ff510fc647febd8c6c3ef4143d099fdad87a223680e632623d056dae2dd" +dependencies = [ + "either", + "rustc-hash", + "serde", + "smallvec", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_transforms_macros", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_react" +version = "0.191.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c76d8b9792ce51401d38da0fa62158d61f6d80d16d68fe5b03ce4bf5fba383" +dependencies = [ + "base64 0.21.7", + "dashmap", + "indexmap 2.6.0", + "once_cell", + "serde", + "sha1", + "string_enum", + "swc_allocator", + "swc_atoms", + "swc_common", + "swc_config", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_macros", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_typescript" +version = "0.198.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15455da4768f97186c40523e83600495210c11825d3a44db43383fd81eace88d" +dependencies = [ + "ryu-js 1.0.1", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_react", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_utils" +version = "0.134.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029eec7dd485923a75b5a45befd04510288870250270292fc2c1b3a9e7547408" +dependencies = [ + "indexmap 2.6.0", + "num_cpus", + "once_cell", + "rustc-hash", + "ryu-js 1.0.1", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_visit", + "tracing", + "unicode-id", +] + +[[package]] +name = "swc_ecma_visit" +version = "0.104.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1c6802e68e51f336e8bc9644e9ff9da75d7da9c1a6247d532f2e908aa33e81" +dependencies = [ + "new_debug_unreachable", + "num-bigint", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_visit", + "tracing", +] + +[[package]] +name = "swc_eq_ignore_macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "swc_fast_graph" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357e2c97bb51431d65080f25b436bc4e2fc1a7f64a643bc21a8353e478dc799f" +dependencies = [ + "indexmap 2.6.0", + "petgraph", + "rustc-hash", + "swc_common", +] + +[[package]] +name = "swc_graph_analyzer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84e1d24a0d6e4066b42cfc00ab9b3109e314465aa199dd3e16849ed9566dce7" +dependencies = [ + "auto_impl", + "petgraph", + "swc_common", + "swc_fast_graph", + "tracing", +] + +[[package]] +name = "swc_macros_common" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "swc_visit" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ceb044142ba2719ef9eb3b6b454fce61ab849eb696c34d190f04651955c613d" +dependencies = [ + "either", + "new_debug_unreachable", +] + +[[package]] +name = "swc_visit_macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "swc_macros_common", + "syn 2.0.87", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand 2.1.0", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "text-size" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a" + +[[package]] +name = "text_lines" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd5828de7deaa782e1dd713006ae96b3bee32d3279b79eb67ecf8072c059bcf" +dependencies = [ + "serde", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny_pretty" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b3f46f0549180b9c6f7f76270903f1a06867c43a03998b99dce81aa1760c3b2" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-eld" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9166030f05d6bc5642bdb8f8c2be31eb3c02cd465d662bcdc2df82d4aa41a584" +dependencies = [ + "hdrhistogram", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tokio-metrics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eace09241d62c98b7eeb1107d4c5c64ca3bd7da92e8c218c153ab3a78f9be112" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "futures-util", + "hashbrown 0.14.5", + "pin-project-lite", + "slab", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.5.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +dependencies = [ + "async-compression", + "bitflags 2.6.0", + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "parking_lot", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-unwrap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4e33415be97f5ae70322d6fefc696bbc08887d8835400d6c77f059469b30354" +dependencies = [ + "tracing", +] + +[[package]] +name = "triomphe" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" +dependencies = [ + "serde", + "stable_deref_trait", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "rand", + "static_assertions", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "tz-rs" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33851b15c848fad2cf4b105c6bb66eb9512b6f6c44a4b13f57c53c73c707e2b4" +dependencies = [ + "const_fn", +] + +[[package]] +name = "tzdb" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b580f6b365fa89f5767cdb619a55d534d04a4e14c2d7e5b9a31e94598687fb1" +dependencies = [ + "iana-time-zone", + "tz-rs", + "tzdb_data", +] + +[[package]] +name = "tzdb_data" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "654c1ec546942ce0594e8d220e6b8e3899e0a0a8fe70ddd54d32a376dfefe3f8" +dependencies = [ + "tz-rs", +] + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-id" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" + +[[package]] +name = "unicode-id-start" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna 1.0.3", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +dependencies = [ + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +dependencies = [ + "getrandom", + "serde", + "sha1_smol", +] + +[[package]] +name = "v8" +version = "130.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c23b5c2caff00209b03a716609b275acae94b02dd3b63c4648e7232a84a8402f" +dependencies = [ + "bindgen", + "bitflags 2.6.0", + "fslock", + "gzip-header", + "home", + "miniz_oxide", + "once_cell", + "paste", + "which 6.0.1", +] + +[[package]] +name = "v8_valueserializer" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97599c400fc79925922b58303e98fcb8fa88f573379a08ddb652e72cbd2e70f6" +dependencies = [ + "bitflags 2.6.0", + "encoding_rs", + "indexmap 2.6.0", + "num-bigint", + "serde", + "thiserror", + "wtf8", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "value-trait" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9170e001f458781e92711d2ad666110f153e4e50bfd5cbd02db6547625714187" +dependencies = [ + "float-cmp", + "halfbrown", + "itoa", + "ryu", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "vte" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" +dependencies = [ + "arrayvec", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.87", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm_dep_analyzer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8" +dependencies = [ + "thiserror", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c6dfa3ac045bc517de14c7b1384298de1dbd229d38e08e169d9ae8c170937c" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "wgpu-core" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "document-features", + "indexmap 2.6.0", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "ron", + "rustc-hash", + "serde", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "172e490a87295564f3fcc0f165798d87386f6231b04d4548bca458cbbfd63222" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.6.0", + "block", + "cfg_aliases 0.1.1", + "core-graphics-types", + "d3d12", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.4", + "log", + "metal", + "naga", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" +dependencies = [ + "bitflags 2.6.0", + "js-sys", + "serde", + "web-sys", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "which" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" +dependencies = [ + "either", + "home", + "rustix", + "winsafe", +] + +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "winres" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +dependencies = [ + "toml", +] + +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wtf8" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01ae8492c38f52376efd3a17d0994b6bcf3df1e39c0226d458b7d81670b2a06" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core", + "serde", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "xtask" +version = "0.3.0-rc.1" +dependencies = [ + "clap", + "color-eyre", + "denort", + "once_cell", + "tracing", + "tracing-subscriber", + "tracing-unwrap", +] + +[[package]] +name = "yaml_parser" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c551c67700672ec050a94d5d917487c0ecd644a12735133df65564779c5b7b" +dependencies = [ + "rowan", + "winnow", +] + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "zeromq" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a4528179201f6eecf211961a7d3276faa61554c82651ecc66387f68fc3004bd" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "crossbeam-queue", + "dashmap", + "futures-channel", + "futures-io", + "futures-task", + "futures-util", + "log", + "num-traits", + "once_cell", + "parking_lot", + "rand", + "regex", + "thiserror", + "tokio", + "tokio-util", + "uuid", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "zip" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" +dependencies = [ + "arbitrary", + "crc32fast", + "crossbeam-utils", + "displaydoc", + "flate2", + "indexmap 2.6.0", + "memchr", + "thiserror", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.11+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..c3eefa37 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,38 @@ +[workspace] +members = ["src/*"] +exclude = ["src/deno_systems"] +resolver = "2" + +[workspace.package] +version = "0.3.0-rc.1" +edition = "2021" + +[workspace.dependencies] +denort = { path = "src/denort" } +deno = { git = "https://github.com/metatypedev/deno", branch = "v2.1.2-embeddable" } +# needed to get deno_core::op2 working +# WARN: must track version used by deno +deno_core = "=0.323.0" + +educe = "0.6" + +color-eyre = "0.6" +anyhow = "1" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = [ + "env-filter", + "parking_lot", + "tracing-log" +] } +tracing-unwrap = "1.0" + +once_cell = "1" + +# WARN: version must match on clap in `deno` +clap = "=4.5" +clap_complete = "=4.5.24" + +shadow-rs = "0.36.0" + + +tokio = "1" diff --git a/README.md b/README.md index 809c7aa3..c5f884fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ghjk -ghjk /gk/ is a programmable runtime manager and an attempt at a successor for [asdf](https://github.com/asdf-vm/asdf). +ghjk /gk/ is a set of tools for managing developer environments and an attempt at a successor for [asdf](https://github.com/asdf-vm/asdf). > ghjk is part of the > [Metatype ecosystem](https://github.com/metatypedev/metatype). Consider @@ -46,7 +46,7 @@ Before anything, make sure the following programs are available on the system. Install the ghjk cli using the installer scripts like so: ```bash -curl -fsSL https://raw.github.com/metatypedev/ghjk/v0.3.0/install.sh | bash +curl -fsSL https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/install.sh | bash ``` Use the following command to create a starter `ghjk.ts` in your project directory: @@ -61,9 +61,9 @@ Ghjk is primarily configured through constructs called "environments" or "envs" They serve as recipes for making (mostly) reproducible posix shells. ```ts -import { file } from "https://raw.github.com/metatypedev/ghjk/v0.3.0/mod.ts"; +import { file } from "https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/mod.ts"; // ports are small programs that install sowtware to your envs -import * as ports from "https://raw.github.com/metatypedev/ghjk/v0.3.0/ports/mod.ts"; +import * as ports from "https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/ports/mod.ts"; const ghjk = file({}); @@ -151,7 +151,6 @@ Run the tests in the repository through the deno task: ```bash $ deno task test +# this supports filtering +$ deno task test --filter envHooks ``` - -Most tests are isolated from each other using containers. -Set `$GHJK_TEST_E2E_TYPE` to `local` to use the local test runner. diff --git a/deno.jsonc b/deno.jsonc index 65dde402..b2f858e2 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,10 +1,10 @@ { "tasks": { - "test": "deno test --parallel --unstable-worker-options --unstable-kv -A tests/*", - "self": "deno run -A --unstable-kv --unstable-worker-options main.ts ", + "test": "cargo build -p ghjk && deno test --unstable-worker-options --unstable-kv -A tests/*", + "self": "cargo run -p ghjk", "cache": "deno cache deps/*", - "check": "deno run -A ./scripts/check.ts", - "dev": "deno run -A ./scripts/dev.ts" + "check": "deno run -A ./tools/check.ts", + "dev": "deno run -A ./tools/dev.ts" }, "fmt": { "exclude": [ @@ -14,7 +14,8 @@ "**/*.md", ".ghjk/**", ".deno-dir/**", - "vendor/**" + "vendor/**", + "./target/" ] }, "lint": { @@ -24,7 +25,8 @@ ".deno-dir/**", "ghjk.ts", "play.ts", - "vendor/**" + "vendor/**", + "./target/" ], "rules": { "include": [ diff --git a/deno.lock b/deno.lock index 77a12939..840393da 100644 --- a/deno.lock +++ b/deno.lock @@ -1,381 +1,98 @@ { - "version": "3", - "packages": { - "specifiers": { - "jsr:@david/dax@0.40.1": "jsr:@david/dax@0.40.1", - "jsr:@david/dax@0.41.0": "jsr:@david/dax@0.41.0", - "jsr:@david/which@0.3": "jsr:@david/which@0.3.0", - "jsr:@david/which@^0.4.1": "jsr:@david/which@0.4.1", - "jsr:@ghjk/dax@0.40.2-alpha-ghjk": "jsr:@ghjk/dax@0.40.2-alpha-ghjk", - "jsr:@std/assert@^0.221.0": "jsr:@std/assert@0.221.0", - "jsr:@std/bytes@^0.221.0": "jsr:@std/bytes@0.221.0", - "jsr:@std/fmt@^0.221.0": "jsr:@std/fmt@0.221.0", - "jsr:@std/fs@0.221.0": "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/io@^0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/path@^0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0": "jsr:@std/streams@0.221.0", - "npm:@livekit/rtc-node@0.11.1": "npm:@livekit/rtc-node@0.11.1", - "npm:@noble/hashes@1.4.0": "npm:@noble/hashes@1.4.0", - "npm:@types/node": "npm:@types/node@18.16.19", - "npm:livekit-server-sdk@2.7.2": "npm:livekit-server-sdk@2.7.2", - "npm:lodash": "npm:lodash@4.17.21", - "npm:mathjs@11.11.1": "npm:mathjs@11.11.1", - "npm:multiformats@13.1.0": "npm:multiformats@13.1.0", - "npm:pg": "npm:pg@8.12.0", - "npm:validator": "npm:validator@13.12.0", - "npm:zod-validation-error": "npm:zod-validation-error@3.1.0_zod@3.23.3", - "npm:zod-validation-error@3.2.0": "npm:zod-validation-error@3.2.0_zod@3.23.3", - "npm:zod-validation-error@3.3.0": "npm:zod-validation-error@3.3.0_zod@3.23.3", - "npm:zod@3.23.8": "npm:zod@3.23.8" + "version": "4", + "specifiers": { + "jsr:@david/dax@0.41.0": "0.41.0", + "jsr:@david/which@~0.4.1": "0.4.1", + "jsr:@std/assert@0.221": "0.221.0", + "jsr:@std/bytes@0.221": "0.221.0", + "jsr:@std/fmt@0.221": "0.221.0", + "jsr:@std/fs@0.221.0": "0.221.0", + "jsr:@std/io@0.221": "0.221.0", + "jsr:@std/io@0.221.0": "0.221.0", + "jsr:@std/path@0.221": "0.221.0", + "jsr:@std/path@0.221.0": "0.221.0", + "jsr:@std/streams@0.221.0": "0.221.0", + "npm:@noble/hashes@1.4.0": "1.4.0", + "npm:@types/node@*": "22.5.4", + "npm:multiformats@13.1.0": "13.1.0", + "npm:zod-validation-error@3.4.0": "3.4.0_zod@3.23.8", + "npm:zod@3.23.8": "3.23.8" + }, + "jsr": { + "@david/dax@0.41.0": { + "integrity": "9e1ecf66a0415962cc8ad3ba4e3fa93ce0f1a1cc797dd95c36fdfb6977dc7fc8", + "dependencies": [ + "jsr:@david/which", + "jsr:@std/fmt", + "jsr:@std/fs", + "jsr:@std/io@0.221.0", + "jsr:@std/path@0.221.0", + "jsr:@std/streams" + ] + }, + "@david/which@0.4.1": { + "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" + }, + "@std/assert@0.221.0": { + "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" + }, + "@std/bytes@0.221.0": { + "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" + }, + "@std/fmt@0.221.0": { + "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" + }, + "@std/fs@0.221.0": { + "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/path@0.221" + ] + }, + "@std/io@0.221.0": { + "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", + "dependencies": [ + "jsr:@std/assert", + "jsr:@std/bytes" + ] + }, + "@std/path@0.221.0": { + "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", + "dependencies": [ + "jsr:@std/assert" + ] + }, + "@std/streams@0.221.0": { + "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", + "dependencies": [ + "jsr:@std/io@0.221" + ] + } + }, + "npm": { + "@noble/hashes@1.4.0": { + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==" + }, + "@types/node@22.5.4": { + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": [ + "undici-types" + ] + }, + "multiformats@13.1.0": { + "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==" + }, + "undici-types@6.19.8": { + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, - "jsr": { - "@david/dax@0.40.1": { - "integrity": "0c71d32a0484d3904f586417995f8ec26d45144f0eba95d3e5bb03b640b6df59", - "dependencies": [ - "jsr:@david/which@0.3", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@david/dax@0.41.0": { - "integrity": "9e1ecf66a0415962cc8ad3ba4e3fa93ce0f1a1cc797dd95c36fdfb6977dc7fc8", - "dependencies": [ - "jsr:@david/which@^0.4.1", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@david/which@0.3.0": { - "integrity": "6bdb62c40ac90edcf328e854fa8103a8db21e7c326089cbe3c3a1cf7887d3204" - }, - "@david/which@0.4.1": { - "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" - }, - "@ghjk/dax@0.40.2-alpha-ghjk": { - "integrity": "87bc93e9947779cb2f3922fe277e21ea8c716de804b2627f80ba9e7bc3d0d019", - "dependencies": [ - "jsr:@david/which@0.3", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@std/assert@0.221.0": { - "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" - }, - "@std/bytes@0.221.0": { - "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" - }, - "@std/fmt@0.221.0": { - "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" - }, - "@std/fs@0.221.0": { - "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/path@^0.221.0" - ] - }, - "@std/io@0.221.0": { - "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/bytes@^0.221.0" - ] - }, - "@std/path@0.221.0": { - "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", - "dependencies": [ - "jsr:@std/assert@^0.221.0" - ] - }, - "@std/streams@0.221.0": { - "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", - "dependencies": [ - "jsr:@std/io@^0.221.0" - ] - } + "zod-validation-error@3.4.0_zod@3.23.8": { + "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==", + "dependencies": [ + "zod" + ] }, - "npm": { - "@babel/runtime@7.24.7": { - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dependencies": { - "regenerator-runtime": "regenerator-runtime@0.14.1" - } - }, - "@bufbuild/protobuf@1.10.0": { - "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==", - "dependencies": {} - }, - "@bufbuild/protobuf@2.2.2": { - "integrity": "sha512-UNtPCbrwrenpmrXuRwn9jYpPoweNXj8X5sMvYgsqYyaH8jQ6LfUJSk3dJLnBK+6sfYPrF4iAIo5sd5HQ+tg75A==", - "dependencies": {} - }, - "@livekit/mutex@1.1.0": { - "integrity": "sha512-XRLG+z/0uoyDioupjUiskjI06Y51U/IXVPJn7qJ+R3J75XX01irYVBM9MpxeJahpVoe9QhU4moIEolX+HO9U9g==", - "dependencies": {} - }, - "@livekit/protocol@1.27.1": { - "integrity": "sha512-ISEp7uWdV82mtCR1eyHFTzdRZTVbe2+ZztjmjiMPzR/KPrI1Ma/u5kLh87NNuY3Rn8wv1VlEvGHHsFjQ+dKVUw==", - "dependencies": { - "@bufbuild/protobuf": "@bufbuild/protobuf@1.10.0" - } - }, - "@livekit/rtc-node-darwin-arm64@0.11.1": { - "integrity": "sha512-M+Ui87H06ae19GGI7r937dS6hI84MBBTQAkkNlL7qd+pvdCAk25u0FYa8r4SOElKJ0VR3AbzeDoXTihLgpvjMg==", - "dependencies": {} - }, - "@livekit/rtc-node-darwin-x64@0.11.1": { - "integrity": "sha512-7G92fyuK2p+jdTH2cUJTNeAmtknTGsXuy0xbI727V7VzQvHFDXULCExRlgwn4t9TxvNlIjUpiltiQ6RCSai6zw==", - "dependencies": {} - }, - "@livekit/rtc-node-linux-arm64-gnu@0.11.1": { - "integrity": "sha512-vqZN9+87Pvxit7auYVW69M+GvUPnf+EwipIJ92GgCJA3Ir1Tcceu5ud5/Ic+0FzSoV0cotVVlQNm74F0tQvyCg==", - "dependencies": {} - }, - "@livekit/rtc-node-linux-x64-gnu@0.11.1": { - "integrity": "sha512-smHZUMfgILQh6/eoauYNe/VlKwQCp4/4jWxiIADHY+mtDtVSvQ9zB6y4GP8FrpohRwFWesKCUpvPBypU0Icrng==", - "dependencies": {} - }, - "@livekit/rtc-node-win32-x64-msvc@0.11.1": { - "integrity": "sha512-bTWVtb+UiRPFjiuhrqq40gt5vs5mMPTa1e+kd2jGQPTOlKZPLArQ0WgFcep2TAy1zmcpOgfeM1XRPVFhZl7G1A==", - "dependencies": {} - }, - "@livekit/rtc-node@0.11.1": { - "integrity": "sha512-EFw+giPll12fcXATZpN2zKkE3umYJAdHvfjW+Yu0aBjwfxbUBXu8rz6le2CzDNvGmRwR888DSZXFZfYikwZgiw==", - "dependencies": { - "@bufbuild/protobuf": "@bufbuild/protobuf@2.2.2", - "@livekit/mutex": "@livekit/mutex@1.1.0", - "@livekit/rtc-node-darwin-arm64": "@livekit/rtc-node-darwin-arm64@0.11.1", - "@livekit/rtc-node-darwin-x64": "@livekit/rtc-node-darwin-x64@0.11.1", - "@livekit/rtc-node-linux-arm64-gnu": "@livekit/rtc-node-linux-arm64-gnu@0.11.1", - "@livekit/rtc-node-linux-x64-gnu": "@livekit/rtc-node-linux-x64-gnu@0.11.1", - "@livekit/rtc-node-win32-x64-msvc": "@livekit/rtc-node-win32-x64-msvc@0.11.1", - "@livekit/typed-emitter": "@livekit/typed-emitter@3.0.0" - } - }, - "@livekit/typed-emitter@3.0.0": { - "integrity": "sha512-9bl0k4MgBPZu3Qu3R3xy12rmbW17e3bE9yf4YY85gJIQ3ezLEj/uzpKHWBsLaDoL5Mozz8QCgggwIBudYQWeQg==", - "dependencies": {} - }, - "@noble/hashes@1.4.0": { - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dependencies": {} - }, - "@types/node@18.16.19": { - "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", - "dependencies": {} - }, - "camelcase-keys@9.1.3": { - "integrity": "sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg==", - "dependencies": { - "camelcase": "camelcase@8.0.0", - "map-obj": "map-obj@5.0.0", - "quick-lru": "quick-lru@6.1.2", - "type-fest": "type-fest@4.26.1" - } - }, - "camelcase@8.0.0": { - "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", - "dependencies": {} - }, - "complex.js@2.1.1": { - "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", - "dependencies": {} - }, - "decimal.js@10.4.3": { - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dependencies": {} - }, - "escape-latex@1.2.0": { - "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", - "dependencies": {} - }, - "fraction.js@4.3.4": { - "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", - "dependencies": {} - }, - "javascript-natural-sort@0.7.1": { - "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", - "dependencies": {} - }, - "jose@5.9.6": { - "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", - "dependencies": {} - }, - "livekit-server-sdk@2.7.2": { - "integrity": "sha512-qDNRXeo+WMnY5nKSug7KHJ9er9JIuKi+r7H9ZaSBbmbaOt62i0b4BrHBMFSMr8pAuWzuSxihCFa29q5QvFc5fw==", - "dependencies": { - "@livekit/protocol": "@livekit/protocol@1.27.1", - "camelcase-keys": "camelcase-keys@9.1.3", - "jose": "jose@5.9.6" - } - }, - "lodash@4.17.21": { - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dependencies": {} - }, - "map-obj@5.0.0": { - "integrity": "sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==", - "dependencies": {} - }, - "mathjs@11.11.1": { - "integrity": "sha512-uWrwMrhU31TCqHKmm1yFz0C352njGUVr/I1UnpMOxI/VBTTbCktx/mREUXx5Vyg11xrFdg/F3wnMM7Ql/csVsQ==", - "dependencies": { - "@babel/runtime": "@babel/runtime@7.24.7", - "complex.js": "complex.js@2.1.1", - "decimal.js": "decimal.js@10.4.3", - "escape-latex": "escape-latex@1.2.0", - "fraction.js": "fraction.js@4.3.4", - "javascript-natural-sort": "javascript-natural-sort@0.7.1", - "seedrandom": "seedrandom@3.0.5", - "tiny-emitter": "tiny-emitter@2.1.0", - "typed-function": "typed-function@4.2.1" - } - }, - "multiformats@13.1.0": { - "integrity": "sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ==", - "dependencies": {} - }, - "pg-cloudflare@1.1.1": { - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "dependencies": {} - }, - "pg-connection-string@2.6.4": { - "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", - "dependencies": {} - }, - "pg-int8@1.0.1": { - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "dependencies": {} - }, - "pg-pool@3.6.2_pg@8.12.0": { - "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", - "dependencies": { - "pg": "pg@8.12.0" - } - }, - "pg-protocol@1.6.1": { - "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==", - "dependencies": {} - }, - "pg-types@2.2.0": { - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dependencies": { - "pg-int8": "pg-int8@1.0.1", - "postgres-array": "postgres-array@2.0.0", - "postgres-bytea": "postgres-bytea@1.0.0", - "postgres-date": "postgres-date@1.0.7", - "postgres-interval": "postgres-interval@1.2.0" - } - }, - "pg@8.12.0": { - "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", - "dependencies": { - "pg-cloudflare": "pg-cloudflare@1.1.1", - "pg-connection-string": "pg-connection-string@2.6.4", - "pg-pool": "pg-pool@3.6.2_pg@8.12.0", - "pg-protocol": "pg-protocol@1.6.1", - "pg-types": "pg-types@2.2.0", - "pgpass": "pgpass@1.0.5" - } - }, - "pgpass@1.0.5": { - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "dependencies": { - "split2": "split2@4.2.0" - } - }, - "postgres-array@2.0.0": { - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "dependencies": {} - }, - "postgres-bytea@1.0.0": { - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "dependencies": {} - }, - "postgres-date@1.0.7": { - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "dependencies": {} - }, - "postgres-interval@1.2.0": { - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": { - "xtend": "xtend@4.0.2" - } - }, - "quick-lru@6.1.2": { - "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", - "dependencies": {} - }, - "regenerator-runtime@0.14.1": { - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dependencies": {} - }, - "seedrandom@3.0.5": { - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", - "dependencies": {} - }, - "split2@4.2.0": { - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dependencies": {} - }, - "tiny-emitter@2.1.0": { - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dependencies": {} - }, - "type-fest@4.26.1": { - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dependencies": {} - }, - "typed-function@4.2.1": { - "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", - "dependencies": {} - }, - "validator@13.12.0": { - "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", - "dependencies": {} - }, - "xtend@4.0.2": { - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dependencies": {} - }, - "zod-validation-error@3.1.0_zod@3.23.3": { - "integrity": "sha512-zujS6HqJjMZCsvjfbnRs7WI3PXN39ovTcY1n8a+KTm4kOH0ZXYsNiJkH1odZf4xZKMkBDL7M2rmQ913FCS1p9w==", - "dependencies": { - "zod": "zod@3.23.3" - } - }, - "zod-validation-error@3.2.0_zod@3.23.3": { - "integrity": "sha512-cYlPR6zuyrgmu2wRTdumEAJGuwI7eHVHGT+VyneAQxmRAKtGRL1/7pjz4wfLhz4J05f5qoSZc3rGacswgyTjjw==", - "dependencies": { - "zod": "zod@3.23.3" - } - }, - "zod-validation-error@3.3.0_zod@3.23.3": { - "integrity": "sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw==", - "dependencies": { - "zod": "zod@3.23.3" - } - }, - "zod@3.23.3": { - "integrity": "sha512-tPvq1B/2Yu/dh2uAIH2/BhUlUeLIUvAjr6dpL/75I0pCYefHgjhXk1o1Kob3kTU8C7yU1j396jFHlsVWFi9ogg==", - "dependencies": {} - }, - "zod@3.23.8": { - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "dependencies": {} - } + "zod@3.23.8": { + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" } }, "remote": { @@ -391,12 +108,17 @@ "https://deno.land/std@0.116.0/path/posix.ts": "34349174b9cd121625a2810837a82dd8b986bbaaad5ade690d1de75bbb4555b2", "https://deno.land/std@0.116.0/path/separator.ts": "8fdcf289b1b76fd726a508f57d3370ca029ae6976fcde5044007f062e643ff1c", "https://deno.land/std@0.116.0/path/win32.ts": "11549e8c6df8307a8efcfa47ad7b2a75da743eac7d4c89c9723a944661c8bd2e", - "https://deno.land/std@0.120.0/_wasm_crypto/crypto.js": "5c283a80e1059d16589b79fa026be5fb0a28424302a99487cadceef8c17f8afa", - "https://deno.land/std@0.120.0/_wasm_crypto/crypto.wasm.js": "0e6df3c18beb1187b442ec7f0a03df4d18b21212172d6b4a50ee4816404771d7", - "https://deno.land/std@0.120.0/_wasm_crypto/mod.ts": "7d02009ef3ddc953c8f90561d213e02fa0a6f3eaed9b8baf0c241c8cbeec1ed3", - "https://deno.land/std@0.120.0/crypto/mod.ts": "5760510eaa0b250f78cce81ce92d83cf8c40e9bb3c3efeedd4ef1a5bb0801ef4", - "https://deno.land/std@0.120.0/encoding/ascii85.ts": "b42b041e9c668afa356dd07ccf69a6b3ee49b9ae080fdf3b03f0ac3981f4d1e6", - "https://deno.land/std@0.120.0/encoding/base64.ts": "0b58bd6477214838bf711eef43eac21e47ba9e5c81b2ce185fe25d9ecab3ebb3", + "https://deno.land/std@0.134.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.134.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617", + "https://deno.land/std@0.134.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.134.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.134.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.134.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.134.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.134.0/path/mod.ts": "4275129bb766f0e475ecc5246aa35689eeade419d72a48355203f31802640be7", + "https://deno.land/std@0.134.0/path/posix.ts": "663e4a6fe30a145f56aa41a22d95114c4c5582d8b57d2d7c9ed27ad2c47636bb", + "https://deno.land/std@0.134.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.134.0/path/win32.ts": "e7bdf63e8d9982b4d8a01ef5689425c93310ece950e517476e22af10f41a136e", "https://deno.land/std@0.213.0/archive/_common.ts": "85edd5cdd4324833f613c1bc055f8e2f935cc9229c6b3044421268d9959997ef", "https://deno.land/std@0.213.0/archive/untar.ts": "7677c136f2188cd8c33363ccaaee6e77d4ca656cca3e2093d08de8f294d4353d", "https://deno.land/std@0.213.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975", @@ -653,12 +375,6 @@ "https://deno.land/std@0.213.0/url/join.ts": "00c7e9088cafaa24963ce4081119e58b3afe2c58f033701383f359ea02620dd2", "https://deno.land/std@0.213.0/url/mod.ts": "e2621f6a0db6fdbe7fbbd240064095bb203014657e5e1ab81db1c44d80dce6c9", "https://deno.land/std@0.213.0/url/normalize.ts": "6328c75df0fab300f74bc4a1c255062a0db882240e15ab646606d0009e7e40d7", - "https://deno.land/std@0.219.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", - "https://deno.land/std@0.219.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", - "https://deno.land/std@0.219.0/cli/mod.ts": "58f75df8ce43fb8266bdd26ec4465f73176b910316d72eb8e090b6a0549391da", - "https://deno.land/std@0.219.0/cli/parse_args.ts": "475b3edc8105c9acea09b83b100afc383d7bddbba9828da3f0c4adced006607a", - "https://deno.land/std@0.219.0/cli/prompt_secret.ts": "831cfb4efa83bfaf9bfd320ddbfd619e03cd87e81260909f93ca199ebe214ec2", - "https://deno.land/std@0.219.0/cli/spinner.ts": "005395c4e00b1086bfa2ae44e8c9413c1231c4741a08a55aa0d3c9ea267cecb5", "https://deno.land/std@0.221.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", "https://deno.land/std@0.221.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", "https://deno.land/std@0.221.0/console/_data.json": "cf2cc9d039a192b3adbfe64627167c7e6212704c888c25c769fc8f1709e1e1b8", @@ -667,12 +383,6 @@ "https://deno.land/std@0.221.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a", "https://deno.land/std@0.221.0/text/closest_string.ts": "8a91ee8b6d69ff96addcb7c251dad53b476ac8be9c756a0ef786abe9e13a93a5", "https://deno.land/std@0.221.0/text/levenshtein_distance.ts": "24be5cc88326bbba83ca7c1ea89259af0050cffda2817ff3a6d240ad6495eae2", - "https://deno.land/std@0.76.0/encoding/base64.ts": "b1d8f99b778981548457ec74bc6273ad785ffd6f61b2233bd5b30925345b565d", - "https://deno.land/std@0.76.0/encoding/hex.ts": "07a03ba41c96060a4ed4ba272e50b9e23f3c5b3839f4b069cdebc24d57434386", - "https://deno.land/std@0.76.0/hash/_wasm/hash.ts": "005f64c4d9343ecbc91e0da9ae5e800f146c20930ad829bbb872c5c06bd89c5f", - "https://deno.land/std@0.76.0/hash/_wasm/wasm.js": "5ac48aa0c3931d7f31dba628be5ab0aa4e786354197eb4d7d0583f9b50be1397", - "https://deno.land/std@0.76.0/hash/hasher.ts": "099c9e2a91b9f106b9f01379705e17e7d9de392ee1ea2b8684a2adfa82ac3bfc", - "https://deno.land/std@0.76.0/hash/mod.ts": "e764a6a9ab2f5519a97f928e17cc13d984e3dd5c7f742ff9c1c8fb3114790f0c", "https://deno.land/x/cliffy@v1.0.0-rc.4/command/_argument_types.ts": "ab269dacea2030f865a07c2a1e953ec437a64419a05bad1f1ddaab3f99752ead", "https://deno.land/x/cliffy@v1.0.0-rc.4/command/_errors.ts": "d78e1b4d69d84b8b476b5f3c0b028e3906d48f21b8f1ca1d36d5abe9ccfe48bc", "https://deno.land/x/cliffy@v1.0.0-rc.4/command/_spread.ts": "0cc6eb70a6df97b5d7d26008822d39f3e8a1232ee0a27f395aa19e68de738245", @@ -738,56 +448,16 @@ "https://deno.land/x/foras@v2.1.4/wasm/pkg/foras.js": "06f8875b456918b9671d52133f64f3047f1c95540feda87fdd4a55ba3d30091d", "https://deno.land/x/foras@v2.1.4/wasm/pkg/foras.wasm.js": "2df8522df7243b0f05b1d188e220629cd5d2c92080a5f1407e15396fc35bebb3", "https://deno.land/x/json_hash@0.2.0/canon.ts": "ce7c07abd871cd7f0eb1280ad9f58f6382f02f84a217898ce977cf35ad315877", - "https://deno.land/x/json_hash@0.2.0/crypto.ts": "8738b601a0cf52c0ff58242707e2d5f7f5ff8f7ca4d51d0282ad3b0bb56548cf", - "https://deno.land/x/json_hash@0.2.0/digest.ts": "95e3d996377eebebb960ad2b6e4fdd70d71543378a651c31de75f1e86b637fc7", - "https://deno.land/x/json_hash@0.2.0/hex.ts": "104154a6408c6b5b36ff35361011aeb3047941bd5a652724f5aebeeb89fcf9a8", - "https://deno.land/x/json_hash@0.2.0/merkle.ts": "cf48004b45fdf0412afd48fea0ba8bb16bf78f717a66a5ff505f6400a88c08cf", - "https://deno.land/x/json_hash@0.2.0/mod.ts": "b0fdd79a540d3fc6aa3e0a9a93fe6735b1a174d9ba2aba103e4a18ee4872acad", "https://deno.land/x/jszip@0.11.0/mod.ts": "5661ddc18e9ac9c07e3c5d2483bc912a7022b6af0d784bb7b05035973e640ba1", "https://deno.land/x/jszip@0.11.0/types.ts": "1528d1279fbb64dd118c371331c641a3a5eff2b594336fb38a7659cf4c53b2d1", - "https://deno.land/x/object_hash@2.0.3.1/index.ts": "74b20a0065dc0066c60510174626db1d18e53ec966edb6f76fa33a67aa0c44e3", - "https://deno.land/x/object_hash@2.0.3.1/mod.ts": "648559bcafb54b930d4b6a283cc2eef20afa54de471371a97c2ccf8116941148", - "https://deno.land/x/object_hash@2.0.3/index.ts": "74b20a0065dc0066c60510174626db1d18e53ec966edb6f76fa33a67aa0c44e3", - "https://deno.land/x/object_hash@2.0.3/mod.ts": "648559bcafb54b930d4b6a283cc2eef20afa54de471371a97c2ccf8116941148", - "https://deno.land/x/zod@v3.22.4/ZodError.ts": "4de18ff525e75a0315f2c12066b77b5c2ae18c7c15ef7df7e165d63536fdf2ea", - "https://deno.land/x/zod@v3.22.4/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", - "https://deno.land/x/zod@v3.22.4/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", - "https://deno.land/x/zod@v3.22.4/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", - "https://deno.land/x/zod@v3.22.4/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", - "https://deno.land/x/zod@v3.22.4/helpers/parseUtil.ts": "f791e6e65a0340d85ad37d26cd7a3ba67126cd9957eac2b7163162155283abb1", - "https://deno.land/x/zod@v3.22.4/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", - "https://deno.land/x/zod@v3.22.4/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", - "https://deno.land/x/zod@v3.22.4/helpers/util.ts": "8baf19b19b2fca8424380367b90364b32503b6b71780269a6e3e67700bb02774", - "https://deno.land/x/zod@v3.22.4/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", - "https://deno.land/x/zod@v3.22.4/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", - "https://deno.land/x/zod@v3.22.4/mod.ts": "64e55237cb4410e17d968cd08975566059f27638ebb0b86048031b987ba251c4", - "https://deno.land/x/zod@v3.22.4/types.ts": "724185522fafe43ee56a52333958764c8c8cd6ad4effa27b42651df873fc151e", - "https://deno.land/x/zod@v3.23.5/ZodError.ts": "528da200fbe995157b9ae91498b103c4ef482217a5c086249507ac850bd78f52", - "https://deno.land/x/zod@v3.23.5/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", - "https://deno.land/x/zod@v3.23.5/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", - "https://deno.land/x/zod@v3.23.5/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", - "https://deno.land/x/zod@v3.23.5/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", - "https://deno.land/x/zod@v3.23.5/helpers/parseUtil.ts": "c14814d167cc286972b6e094df88d7d982572a08424b7cd50f862036b6fcaa77", - "https://deno.land/x/zod@v3.23.5/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", - "https://deno.land/x/zod@v3.23.5/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", - "https://deno.land/x/zod@v3.23.5/helpers/util.ts": "3301a69867c9e589ac5b3bc4d7a518b5212858cd6a25e8b02d635c9c32ba331c", - "https://deno.land/x/zod@v3.23.5/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", - "https://deno.land/x/zod@v3.23.5/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", - "https://deno.land/x/zod@v3.23.5/mod.ts": "ec6e2b1255c1a350b80188f97bd0a6bac45801bb46fc48f50b9763aa66046039", - "https://deno.land/x/zod@v3.23.5/types.ts": "78d3f06eb313ea754fad0ee389d3c0fa55bc01cf708e6ce0ea7fddd41f31eca2", - "https://deno.land/x/zod@v3.23.8/ZodError.ts": "528da200fbe995157b9ae91498b103c4ef482217a5c086249507ac850bd78f52", - "https://deno.land/x/zod@v3.23.8/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", - "https://deno.land/x/zod@v3.23.8/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", - "https://deno.land/x/zod@v3.23.8/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", - "https://deno.land/x/zod@v3.23.8/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", - "https://deno.land/x/zod@v3.23.8/helpers/parseUtil.ts": "c14814d167cc286972b6e094df88d7d982572a08424b7cd50f862036b6fcaa77", - "https://deno.land/x/zod@v3.23.8/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", - "https://deno.land/x/zod@v3.23.8/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", - "https://deno.land/x/zod@v3.23.8/helpers/util.ts": "30c273131661ca5dc973f2cfb196fa23caf3a43e224cdde7a683b72e101a31fc", - "https://deno.land/x/zod@v3.23.8/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", - "https://deno.land/x/zod@v3.23.8/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", - "https://deno.land/x/zod@v3.23.8/mod.ts": "ec6e2b1255c1a350b80188f97bd0a6bac45801bb46fc48f50b9763aa66046039", - "https://deno.land/x/zod@v3.23.8/types.ts": "1b172c90782b1eaa837100ebb6abd726d79d6c1ec336350c8e851e0fd706bf5c", + "https://deno.land/x/os_paths@v7.2.0/dist/esm/lib/OSPaths.js": "db4f5f05765a1c862e7b1e0f0c293fc752e94e213eabff19f3c03af9b2164f98", + "https://deno.land/x/os_paths@v7.2.0/src/mod.deno.ts": "5e34d7c1a033665276a1a06e3957a52218bf4711a801f38cf92978aacfad5666", + "https://deno.land/x/os_paths@v7.2.0/src/platform-adapters/_base.ts": "ca9adf679709824e070631921932620ab4dc2a39fff9706f95592d1620e34dc6", + "https://deno.land/x/os_paths@v7.2.0/src/platform-adapters/deno.deno.ts": "d184d709522bf2703dc12ff335eb6a10d758a3a5dd4d97524d2aef9d3d448c13", + "https://deno.land/x/xdg_portable@v10.6.0/dist/esm/lib/XDG.js": "4c04a45149d66e4ca29ea914aac137e7b0f0b6a8ef431ffc63fef46bc3747064", + "https://deno.land/x/xdg_portable@v10.6.0/src/mod.deno.ts": "e478cc109794bfc130ec81711f9a20d594e6fad848f796c68b75dbe510683c39", + "https://deno.land/x/xdg_portable@v10.6.0/src/platform-adapters/_base.ts": "c79a7f0e5b1d77e23cbc6c782a02958573338e9dfa644a7aa5a1f7c402ff56ef", + "https://deno.land/x/xdg_portable@v10.6.0/src/platform-adapters/deno.deno.ts": "5f5852dc4588c10ad8fd0450421fa728741838cf5839a209d53323ccc9ed4c00", "https://esm.sh/jszip@3.7.1": "f3872a819b015715edb05f81d973b5cd05d3d213d8eb28293ca5471fe7a71773", "https://esm.sh/v135/jszip@3.7.1/denonext/jszip.mjs": "d31d7f9e0de9c6db3c07ca93f7301b756273d4dccb41b600461978fc313504c9" } diff --git a/deps/common.ts b/deps/common.ts index d81d085f..8843e4b4 100644 --- a/deps/common.ts +++ b/deps/common.ts @@ -10,7 +10,7 @@ export * as std_fmt_colors from "https://deno.land/std@0.213.0/fmt/colors.ts"; export * as std_url from "https://deno.land/std@0.213.0/url/mod.ts"; export * as std_path from "https://deno.land/std@0.213.0/path/mod.ts"; export * as std_fs from "https://deno.land/std@0.213.0/fs/mod.ts"; -export * as zod_val_err from "npm:zod-validation-error@3.3.0"; +export * as zod_val_err from "npm:zod-validation-error@3.4.0"; // avoid using the following directly and go through the // wrappers in ./utils/mod.ts diff --git a/deps/install.ts b/deps/install.ts new file mode 100644 index 00000000..ba2dc07f --- /dev/null +++ b/deps/install.ts @@ -0,0 +1 @@ +export { default as xdg } from "https://deno.land/x/xdg_portable@v10.6.0/src/mod.deno.ts"; diff --git a/docs/known-issues.md b/docs/known-issues.md index 9560e6c6..22e06a63 100644 --- a/docs/known-issues.md +++ b/docs/known-issues.md @@ -1,10 +1,5 @@ # Known issues -## Cache invalidation of imported scripts - -Currently, ghjk is unable to track changes to local typescript files imported by the ghjk.ts file. -You can force re-serialization of the ghjkfile by deleting the `.ghjk/hash.json` file. - ## GitHub API rate-limit The GitHub API is rate-limited to 60 calls per hour for unauthenticated requests. diff --git a/docs/manual.md b/docs/manual.md index 72185530..f4dedf34 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -17,7 +17,7 @@ There are installer scripts available in the repo. ```bash # stable -curl -fsSL https://raw.github.com/metatypedev/ghjk/v0.3.0/install.sh | bash +curl -fsSL https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/install.sh | bash ``` This will install the CLI and add configuration your shell rc files the necessary hooks ghjk needs to function. @@ -39,7 +39,7 @@ Look through the following snippet to understand the basic structure of a `ghjk. ```ts // import the file function from `mod.ts` using the version of ghjk // one's using. For example -// https://raw.github.com/metatypedev/ghjk/v0.3.0/ +// https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/ import { file } from ".../mod.ts"; // import the port for the node program import node from ".../ports/node.ts"; @@ -412,10 +412,10 @@ Namely, it's good practice to: ```dockerfile # sample of how one would install ghjk for use in a Dockerfile -ARG GHJK_VERSION=v0.3.0 +ARG GHJK_VERSION=v0.3.0-rc.1 # /usr/bin is available in $PATH by default making ghjk immediately avail -RUN GHJK_INSTALL_EXE_DIR=/usr/bin \ - curl -fsSL https://raw.github.com/metatypedev/ghjk/$GHJK_VERSION/install.sh | bash +RUN curl -fsSL https://raw.github.com/metatypedev/ghjk/$GHJK_VERSION/install.sh \ + | GHJK_INSTALL_EXE_DIR=/usr/bin sh ``` ### Activation diff --git a/files/deno/bindings.ts b/files/deno/bindings.ts new file mode 100644 index 00000000..8bf47f10 --- /dev/null +++ b/files/deno/bindings.ts @@ -0,0 +1,35 @@ +//! this loads the ghjk.ts module and provides a program for it + +//// +/// + +// all imports in here should be dynamic imports as we want to +// modify the Deno namespace before anyone touches it + +// NOTE: only import types +import { shimDenoNamespace } from "../../utils/worker.ts"; +import { zod } from "../../deps/common.ts"; +import { Ghjk } from "../../src/ghjk/js/runtime.js"; + +const serializeArgs = zod.object({ + uri: zod.string(), +}); + +async function serialize(args: zod.infer) { + const shimHandle = shimDenoNamespace(Deno.env.toObject()); + const { setup: setupLogger } = await import("../../utils/logger.ts"); + setupLogger(); + const mod = await import(args.uri); + const rawConfig = await mod.sophon.getConfig(args.uri, mod.secureConfig); + const config = JSON.parse(JSON.stringify(rawConfig)); + return { + config, + accessedEnvKeys: shimHandle.getAccessedEnvKeys(), + readFilePaths: shimHandle.getReadFiles(), + listedFilePaths: shimHandle.getListedFiles(), + }; +} + +const args = serializeArgs.parse(Ghjk.blackboard.get("args")); +const resp = await serialize(args); +Ghjk.blackboard.set("resp", resp); diff --git a/files/deno/mod.ts b/files/deno/mod.ts index 4b566ceb..9eca6e14 100644 --- a/files/deno/mod.ts +++ b/files/deno/mod.ts @@ -53,6 +53,7 @@ async function rpc(moduleUri: string, req: DriverRequests) { write: false, run: false, ffi: false, + import: true, } as Deno.PermissionOptions, }, } as WorkerOptions); diff --git a/files/deno/worker.ts b/files/deno/worker.ts index 5a9528f7..ca55221d 100644 --- a/files/deno/worker.ts +++ b/files/deno/worker.ts @@ -6,8 +6,8 @@ // all imports in here should be dynamic imports as we want to // modify the Deno namespace before anyone touches it -// NOTE: only import types import { shimDenoNamespace } from "../../utils/worker.ts"; +// NOTE: only import types import type { DriverRequests, DriverResponse } from "./mod.ts"; self.onmessage = onMsg; diff --git a/ghjk.ts b/ghjk.ts index 8c7952b3..79e8be0c 100644 --- a/ghjk.ts +++ b/ghjk.ts @@ -1,20 +1,93 @@ // @ts-nocheck: Ghjkfile based on Deno export { sophon } from "./hack.ts"; -import { config, install, task } from "./hack.ts"; +import { config, env, install, task } from "./hack.ts"; +import { switchMap } from "./port.ts"; import * as ports from "./ports/mod.ts"; import { sedLock } from "./std.ts"; +import { downloadFile, DownloadFileArgs } from "./utils/mod.ts"; +import { unarchive } from "./utils/unarchive.ts"; +import dummy from "./ports/dummy.ts"; + +// keep in sync with the deno repo's ./rust-toolchain.toml +const RUST_VERSION = "1.82.0"; + +const installs = { + rust: ports.rust({ + version: RUST_VERSION, + profile: "default", + components: ["rust-src"], + }), +}; config({ - defaultBaseEnv: "test", + defaultEnv: "dev", enableRuntimes: true, - allowedBuildDeps: [ports.cpy_bs({ version: "3.12.7" })], + allowedBuildDeps: [ports.cpy_bs({ version: "3.13.1" }), installs.rust], +}); + +env("main").vars({ + RUST_LOG: [ + "info", + Object.entries({ + "TRACE": [ + // "denort", + // "deno", + ], + "DEBUG": [ + // "runtime", + // "tokio", + ], + "INFO": [ + "deno::npm", + "deno::file_fetcher", + "swc_ecma_transforms_base", + "swc_common", + "h2", + "rustls", + "mio", + "hyper_util", + ], + }).flatMap(([level, modules]) => + modules.map((module) => `${module}=${level.toLowerCase()}`) + ), + ].join(), }); +env("_rust") + .install( + ports.protoc(), + ports.pipi({ packageName: "cmake" })[0], + installs.rust, + ); + +const RUSTY_V8_MIRROR = `${import.meta.dirname}/.dev/rusty_v8`; + +env("dev") + .inherit("_rust") + .install(ports.cargobi({ crateName: "tokio-console" })) + .vars({ + // V8_FORCE_DEBUG: "true", + RUSTY_V8_MIRROR, + }); + +if (Deno.build.os == "linux" && !Deno.env.has("NO_MOLD")) { + const mold = ports.mold({ + version: "v2.4.0", + replaceLd: true, + }); + env("dev").install(mold); +} + // these are just for quick testing -install(); +install( + ports.asdf({ + pluginRepo: "https://github.com/lsanwick/asdf-jq", + installType: "version", + }), +); -const DENO_VERSION = "1.44.2"; +const DENO_VERSION = "2.1.2"; // these are used for developing ghjk install( @@ -24,23 +97,67 @@ install( ports.deno_ghrel({ version: DENO_VERSION }), ); +task( + "cache-v8", + { + desc: "Install the V8 builds to a local cache.", + inherit: false, + fn: async ($) => { + const tmpDirPath = await Deno.makeTempDir({}); + const v8Versions = [ + ...(await $`cargo tree -p v8 --depth 0 --locked` + .text()) + .matchAll(/^v8 (v[\d.]*)/g) + .map((match) => match[1]), + ]; + + await $.co( + v8Versions + .flatMap( + (version) => { + const os = switchMap(Deno.build.os, { + linux: "unknown-linux-gnu", + darwin: "apple-darwin", + }) ?? "NOT_SUPPORTED"; + const arch = Deno.build.arch; + return [ + `librusty_v8_release_${arch}-${os}.a.gz`, + `librusty_v8_debug_${arch}-${os}.a.gz`, + ].map((archiveName) => ({ + archiveName, + url: + `https://github.com/denoland/rusty_v8/releases/download/${version}/${archiveName}`, + downloadPath: $.path(RUSTY_V8_MIRROR).join(version).toString(), + tmpDirPath, + } satisfies DownloadFileArgs)); + }, + ) + .filter((args) => + !$.path(args.downloadPath).join(args.archiveName).existsSync() + ) + .map((args) => downloadFile(args)), + ); + await $.path(tmpDirPath).remove({ recursive: true }); + }, + }, +); + task( "lock-sed", async ($) => { - const GHJK_VERSION = "0.3.0"; + const GHJK_VERSION = "0.3.0-rc.1"; await sedLock( $.path(import.meta.dirname!), { lines: { - "./.github/workflows/*.yml": [ - [/(DENO_VERSION: ").*(")/, DENO_VERSION], + "./rust-toolchain.toml": [ + [/^(channel = ").*(")/, RUST_VERSION], ], - "./host/mod.ts": [ - [/(GHJK_VERSION = ").*(")/, GHJK_VERSION], + "./Cargo.toml": [ + [/^(version = ").*(")/, GHJK_VERSION], ], - "./install.sh": [ - [/(GHJK_VERSION="\$\{GHJK_VERSION:-v).*(\}")/, GHJK_VERSION], - [/(DENO_VERSION="\$\{DENO_VERSION:-v).*(\}")/, DENO_VERSION], + "./.github/workflows/*.yml": [ + [/(DENO_VERSION: ").*(")/, DENO_VERSION], ], "./docs/*.md": [ [ @@ -58,6 +175,13 @@ task( GHJK_VERSION, ], ], + "**/Cargo.toml": [ + [/^(version = ").+(")/, GHJK_VERSION], + [ + /(deno\s*=\s*\{\s*git\s*=\s*"https:\/\/github\.com\/metatypedev\/deno"\s*,\s*branch\s*=\s*"v).+(-embeddable"\s*\})/, + DENO_VERSION, + ], + ], }, ignores: [ // ignore this file to avoid hits on the regexps @@ -78,4 +202,5 @@ task( }, ); }, + { inherits: false }, ); diff --git a/host/mod.ts b/host/mod.ts deleted file mode 100644 index 811ed0d3..00000000 --- a/host/mod.ts +++ /dev/null @@ -1,627 +0,0 @@ -import { cliffy_cmd, deep_eql, zod, zod_val_err } from "../deps/cli.ts"; -import logger from "../utils/logger.ts"; -import { - $, - bufferHashAsync, - Json, - objectHash, - Path, - stringHash, -} from "../utils/mod.ts"; -import validators, { SerializedConfig } from "./types.ts"; -import * as std_modules from "../modules/std.ts"; -import * as denoFile from "../files/deno/mod.ts"; -import { task$ } from "../files/mod.ts"; -import type { ModuleBase } from "../modules/mod.ts"; -import { GhjkCtx } from "../modules/types.ts"; -import { serializePlatform } from "../modules/ports/types/platform.ts"; -import { default as initTasks } from "./init/mod.ts"; - -export interface CliArgs { - ghjkShareDir: string; - ghjkfilePath?: string; - ghjkDirPath?: string; - reFlagSet: boolean; - lockedFlagSet: boolean; -} - -type HostCtx = { - fileHashMemoStore: Map>; - curEnvVars: Record; - reFlagSet: boolean; - lockedFlagSet: boolean; -}; - -const GHJK_VERSION = "0.3.0"; - -export async function cli(args: CliArgs) { - logger().debug(`ghjk CLI`, GHJK_VERSION); - if (args.reFlagSet && args.lockedFlagSet) { - throw new Error("GHJK_LOCKED && GHJK_RE both set"); - } - // items to run at end of function - const defer = [] as (() => Promise)[]; - - const ghjkShareDir = $.path(args.ghjkShareDir).resolve().normalize(); - let serializedConfig: object | undefined; - let gcx: GhjkCtx | undefined; - - if (!args.ghjkDirPath && args.ghjkfilePath) { - args.ghjkDirPath = $.path(args.ghjkfilePath).parentOrThrow().join(".ghjk") - .toString(); - } - - const subcmds: Record = {}; - - // most of the CLI is only avail if there's a - // ghjkfile detected - if (args.ghjkDirPath) { - gcx = { - ghjkShareDir, - ghjkDir: $.path(args.ghjkDirPath).resolve().normalize(), - ghjkfilePath: args.ghjkfilePath - ? $.path(args.ghjkfilePath).resolve().normalize() - : undefined, - blackboard: new Map(), - }; - const hcx: HostCtx = { - fileHashMemoStore: new Map(), - curEnvVars: Deno.env.toObject(), - reFlagSet: args.reFlagSet, - lockedFlagSet: args.lockedFlagSet, - }; - logger().debug("context established", { - ghjkDir: gcx?.ghjkDir.toString(), - ghjkfilePath: gcx.ghjkfilePath?.toString(), - }); - - if (!await gcx.ghjkDir.join(".gitignore").exists()) { - gcx.ghjkDir.join(".gitignore").writeText($.dedent` - envs - hash.json`); - } - - // this returns nothing if no valid lockifle or ghjkfile - // is found - const commands = await commandsFromConfig(hcx, gcx); - if (commands) { - serializedConfig = commands.config; - // lock entries are also generated across program usage - // so we defer another write out until the end - defer.push(commands.writeLockFile); - - for ( - const [cmdName, [cmd, src]] of Object.entries(commands.subCommands) - ) { - const conflict = subcmds[cmdName]; - if (conflict) { - throw new Error( - `CLI command conflict under name "${cmdName}" from host and module "${src}"`, - ); - } - subcmds[cmdName] = cmd; - } - } - } - - const initCmd = new cliffy_cmd.Command() - .description("Commands for setting up cwd for ghjk.") - .action(function () { - this.showHelp(); - }); - for (const [name, def] of Object.entries(initTasks)) { - initCmd.command( - name.replace("init-", ""), - new cliffy_cmd.Command() - .description(def.desc!) - .useRawArgs() - .action(async (_, ...argv) => { - const env = Deno.env.toObject(); - const workingDir = Deno.cwd(); - const dollar = task$(argv, env, workingDir, name); - await def.fn!(dollar, { argv, workingDir, env, $: dollar }); - }), - ); - } - - const root = new cliffy_cmd.Command() - .name("ghjk") - .version(GHJK_VERSION) - .description("Programmable runtime manager.") - .action(function () { - this.showHelp(); - }) - .command( - "init", - initCmd, - ) - .command( - "print", - new cliffy_cmd.Command() - .description("Emit different discovered and built values to stdout.") - .action(function () { - this.showHelp(); - }) - .command( - "share-dir-path", - new cliffy_cmd.Command() - .description("Print the path where ghjk is installed in.") - .action(function () { - if (!ghjkShareDir) { - throw new Error("no ghjkfile found."); - } - // deno-lint-ignore no-console - console.log(ghjkShareDir.toString()); - }), - ) - .command( - "ghjkdir-path", - new cliffy_cmd.Command() - .description("Print the path where ghjk is installed in.") - .action(function () { - if (!gcx) { - throw new Error("no ghjkfile found."); - } - // deno-lint-ignore no-console - console.log(gcx.ghjkDir.toString()); - }), - ) - .command( - "ghjkfile-path", - new cliffy_cmd.Command() - .description("Print the path of the ghjk.ts used.") - .action(function () { - if (!gcx?.ghjkfilePath) { - throw new Error("no ghjkfile found."); - } - // deno-lint-ignore no-console - console.log(gcx.ghjkfilePath.toString()); - }), - ) - .command( - "config", - new cliffy_cmd.Command() - .description( - "Print the extracted and serialized config from the ghjkfile.", - ) - .option( - "--json", - `Use json format when printing config.`, - ) - .action(function ({ json }) { - if (!serializedConfig) { - throw new Error("no ghjkfile found."); - } - // deno-lint-ignore no-console - console.log( - json - ? JSON.stringify(serializedConfig) - : $.inspect(serializedConfig), - ); - }), - ), - ) - .command( - "completions", - new cliffy_cmd.CompletionsCommand(), - ) - .command( - "deno", - new cliffy_cmd.Command() - .description("Access the deno cli.") - .useRawArgs() - .action(async function (_, ...args) { - logger().debug(args); - await $.raw`${Deno.execPath()} ${args}` - .env("DENO_EXEC_PATH", Deno.execPath()); - }), - ); - - for (const [name, subcmd] of Object.entries(subcmds)) { - root.command(name, subcmd); - } - - try { - await root.parse(Deno.args); - } catch (err) { - logger().error(err); - Deno.exit(1); - } finally { - await Promise.all(defer.map((fn) => fn())); - } -} - -async function commandsFromConfig(hcx: HostCtx, gcx: GhjkCtx) { - const lockFilePath = gcx.ghjkDir.join("lock.json"); - const hashFilePath = gcx.ghjkDir.join("hash.json"); - - const foundLockObj = await readLockFile(lockFilePath); - const foundHashObj = await readHashFile(hashFilePath); - - if (hcx.lockedFlagSet) { - if (!foundLockObj) { - throw new Error("GHJK_LOCKED set but no lockfile found"); - } - if (!foundHashObj) { - throw new Error("GHJK_LOCKED set but no hashfile found"); - } - } - - const lockEntries = {} as Record; - - const ghjkfileHash = await gcx.ghjkfilePath?.exists() - ? await fileDigestHex(hcx, gcx.ghjkfilePath!) - : undefined; - - if (!hcx.reFlagSet && foundLockObj) { - logger().debug("loading lockfile", lockFilePath); - for (const man of foundLockObj.config.modules) { - const mod = std_modules.map[man.id]; - if (!mod) { - throw new Error( - `unrecognized module specified by lockfile config: ${man.id}`, - ); - } - const entry = foundLockObj.moduleEntries[man.id]; - if (!entry) { - throw new Error( - `no lock entry found for module specified by lockfile config: ${man.id}`, - ); - } - const instance: ModuleBase = new mod.ctor(); - lockEntries[man.id] = await instance.loadLockEntry( - gcx, - entry as Json, - ); - } - } - - let configExt: SerializedConfigExt | null = null; - let wasReSerialized = false; - if ( - !hcx.reFlagSet && - foundLockObj && - foundHashObj && - (hcx.lockedFlagSet || - // avoid reserializing the config if - // the ghjkfile and environment is _satisfcatorily_ - // similar. "cache validation" - foundLockObj.version == "0" && - await isHashFileValid(hcx, foundLockObj, foundHashObj, ghjkfileHash)) - ) { - configExt = { - config: foundLockObj.config, - envVarHashes: foundHashObj.envVarHashes, - readFileHashes: foundHashObj.readFileHashes, - listedFiles: foundHashObj.listedFiles, - }; - } else if (gcx.ghjkfilePath) { - logger().info("serializing ghjkfile", gcx.ghjkfilePath); - configExt = await readGhjkfile(hcx, gcx.ghjkfilePath); - wasReSerialized = true; - } else { - // nothing to get the commands from - return; - } - - const newHashObj: zod.infer = { - version: "0", - ghjkfileHash, - envVarHashes: configExt.envVarHashes, - readFileHashes: configExt.readFileHashes, - listedFiles: configExt.listedFiles, - }; - // command name to [cmd, source module id] - const subCommands = {} as Record; - const instances = [] as [string, ModuleBase, unknown][]; - - for (const man of configExt.config.modules) { - const mod = std_modules.map[man.id]; - if (!mod) { - throw new Error(`unrecognized module specified by ghjk.ts: ${man.id}`); - } - const instance: ModuleBase = new mod.ctor(); - const pMan = await instance.processManifest( - gcx, - man, - configExt.config.blackboard, - lockEntries[man.id], - ); - instances.push([man.id, instance, pMan] as const); - for (const [cmdName, cmd] of Object.entries(instance.commands(gcx, pMan))) { - const conflict = subCommands[cmdName]; - if (conflict) { - throw new Error( - `CLI command conflict under name "${cmdName}" from modules "${man.id}" & "${ - conflict[1] - }"`, - ); - } - subCommands[cmdName] = [cmd, man.id]; - } - } - - // `writeLockFile` can be invoked multiple times - // so we keep track of the last lockfile wrote - // out to disk - // TODO(#90): file system lock file while ghjk is running - // to avoid multiple instances from clobbering each other - let lastLockObj = { ...foundLockObj }; - return { - subCommands, - config: configExt.config, - async writeLockFile() { - if (hcx.lockedFlagSet) return; - - const newLockObj: zod.infer = { - version: "0", - platform: serializePlatform(Deno.build), - moduleEntries: {} as Record, - config: configExt!.config, - }; - - // generate the lock entries after *all* the modules - // are done processing their config to allow - // any shared stores to be properly populated - // e.g. the resolution memo store - newLockObj.moduleEntries = Object.fromEntries( - await Array.fromAsync( - instances.map( - async ( - [id, instance, pMan], - ) => [id, await instance.genLockEntry(gcx, pMan)], - ), - ), - ); - // avoid writing lockfile if nothing's changed - if (!lastLockObj || !deep_eql(newLockObj, lastLockObj)) { - lastLockObj = { ...newLockObj }; - await lockFilePath.writeJsonPretty(newLockObj); - } - - // we only write out hashfile when the serialization - // result was saved in the lock file - if ( - !hcx.lockedFlagSet && wasReSerialized && ( - !foundHashObj || !deep_eql(newHashObj, foundHashObj) - ) - ) { - await hashFilePath.writeJsonPretty(newHashObj); - } - }, - }; -} - -async function isHashFileValid( - hcx: HostCtx, - foundLockFile: zod.infer, - foundHashFile: zod.infer, - ghjkfileHash?: string, -) { - // TODO: figure out cross platform lockfiles :O - const platformMatch = () => - serializePlatform(Deno.build) == foundLockFile.platform; - - const envHashesMatch = () => { - const oldHashes = foundHashFile!.envVarHashes; - const newHashes = envVarDigests(hcx.curEnvVars, [ - ...Object.keys(oldHashes), - ]); - return deep_eql(oldHashes, newHashes); - }; - - const cwd = $.path(Deno.cwd()); - const fileHashesMatch = async () => { - const oldHashes = foundHashFile!.readFileHashes; - const newHashes = await fileDigests(hcx, [ - ...Object.keys(oldHashes), - ], cwd); - return deep_eql(oldHashes, newHashes); - }; - - const fileListingsMatch = async () => { - const oldListed = foundHashFile!.listedFiles; - for (const path of oldListed) { - if (!await cwd.resolve(path).exists()) { - return false; - } - } - return true; - }; - // NOTE: these are ordered by the amount effort it takes - // to check each - // we only check file hash of the ghjk file if it's present - return (ghjkfileHash ? foundHashFile.ghjkfileHash == ghjkfileHash : true) && - platformMatch() && - envHashesMatch() && - await fileListingsMatch() && - await fileHashesMatch(); -} - -type DigestsMap = Record; - -type SerializedConfigExt = Awaited< - ReturnType ->; - -async function readGhjkfile( - hcx: HostCtx, - configPath: Path, -) { - switch (configPath.extname()) { - case "": - logger().warn("config file has no extension, assuming deno config"); - /* falls through */ - case ".ts": { - logger().debug("serializing ts config", configPath); - const res = await denoFile.getSerializedConfig( - configPath.toFileUrl().href, - hcx.curEnvVars, - ); - const envVarHashes = envVarDigests(hcx.curEnvVars, res.accessedEnvKeys); - const cwd = $.path(Deno.cwd()); - const cwdStr = cwd.toString(); - const listedFiles = res.listedFiles - .map((path) => cwd.resolve(path).toString().replace(cwdStr, ".")); - // FIXME: this breaks if the version of the file the config reads - // has changed by this point - // consider reading mtime of files when read by the serializer and comparing - // them before hashing to make sure we get the same file - // not sure what to do if it has changed though, re-serialize? - const readFileHashes = await fileDigests(hcx, res.readFiles, cwd); - - return { - config: validateRawConfig(res.config, configPath), - envVarHashes, - readFileHashes, - listedFiles, - }; - } - // case ".jsonc": - // case ".json": - // raw = await configPath.readJson(); - // break; - default: - throw new Error( - `unrecognized ghjkfile type provided at path: ${configPath}`, - ); - } -} - -function validateRawConfig( - raw: unknown, - configPath: Path, -): SerializedConfig { - try { - return validators.serializedConfig.parse(raw); - } catch (err) { - const validationError = zod_val_err.fromError(err); - throw new Error( - `error parsing seralized config from ${configPath}: ${validationError.toString()}`, - { - cause: validationError, - }, - ); - } -} - -const lockObjValidator = zod.object({ - version: zod.string(), - platform: zod.string(), // TODO custom validator?? - moduleEntries: zod.record(zod.string(), zod.unknown()), - config: validators.serializedConfig, -}); - -/** - * The lock.json file stores the serialized config and some entries - * from modules. It's primary purpose is as a memo store to avoid - * re-serialization on each CLI invocation. - */ -async function readLockFile(lockFilePath: Path) { - const rawStr = await lockFilePath.readMaybeText(); - if (!rawStr) return; - try { - const rawJson = JSON.parse(rawStr); - return lockObjValidator.parse(rawJson); - } catch (err) { - const validationError = zod_val_err.fromError(err); - logger().error( - `error parsing lockfile from ${lockFilePath}: ${validationError.toString()}`, - ); - if (Deno.stderr.isTerminal() && await $.confirm("Discard lockfile?")) { - return; - } else { - throw validationError; - } - } -} - -const hashObjValidator = zod.object({ - version: zod.string(), - ghjkfileHash: zod.string().nullish(), - envVarHashes: zod.record(zod.string(), zod.string().nullish()), - readFileHashes: zod.record(zod.string(), zod.string().nullish()), - listedFiles: zod.string().array(), - // TODO: track listed dirs in case a `walk`ed directory has a new entry -}); - -/** - * The hash.json file stores the digests of all external accesses - * of a ghjkfile during serialization. The primary purpose is to - * do "cache invalidation" on ghjkfiles, re-serializing them if - * any of the digests change. - */ -async function readHashFile(hashFilePath: Path) { - const rawStr = await hashFilePath.readMaybeText(); - if (!rawStr) return; - try { - const rawJson = JSON.parse(rawStr); - return hashObjValidator.parse(rawJson); - } catch (err) { - logger().error( - `error parsing hashfile from ${hashObjValidator}: ${ - zod_val_err.fromError(err).toString() - }`, - ); - logger().warn("discarding invalid hashfile"); - return; - } -} - -function envVarDigests(all: Record, accessed: string[]) { - const hashes = {} as DigestsMap; - for (const key of accessed) { - const val = all[key]; - if (!val) { - // use null if the serializer accessed - hashes[key] = null; - } else { - hashes[key] = stringHash(val); - } - } - return hashes; -} - -async function fileDigests(hcx: HostCtx, readFiles: string[], cwd: Path) { - const cwdStr = cwd.toString(); - const readFileHashes = {} as DigestsMap; - await Promise.all(readFiles.map(async (pathStr) => { - const path = cwd.resolve(pathStr); - const relativePath = path - .toString() - .replace(cwdStr, "."); - // FIXME: stream read into hash to improve mem usage - const stat = await path.lstat(); - if (stat) { - const contentHash = (stat.isFile || stat.isSymlink) - ? await fileDigestHex(hcx, path) - : null; - readFileHashes[relativePath] = objectHash({ - ...JSON.parse(JSON.stringify(stat)), - contentHash, - }); - } else { - readFileHashes[relativePath] = null; - } - })); - return readFileHashes; -} - -/** - * Returns the hash digest of a file. Makes use of a memo - * to dedupe work. - */ -function fileDigestHex(hcx: HostCtx, path: Path) { - const absolute = path.resolve().toString(); - let promise = hcx.fileHashMemoStore.get(absolute); - if (!promise) { - promise = inner(); - hcx.fileHashMemoStore.set(absolute, promise); - } - return promise; - async function inner() { - return await bufferHashAsync( - await path.readBytes(), - ); - } -} diff --git a/install.sh b/install.sh index e9e6e58c..1eaa503b 100755 --- a/install.sh +++ b/install.sh @@ -2,33 +2,173 @@ set -e -u -GHJK_VERSION="${GHJK_VERSION:-v0.3.0}" -GHJK_INSTALLER_URL="${GHJK_INSTALLER_URL:-https://raw.github.com/metatypedev/ghjk/$GHJK_VERSION/install.ts}" -GHJK_SHARE_DIR="${GHJK_SHARE_DIR:-$HOME/.local/share/ghjk}" -DENO_VERSION="${DENO_VERSION:-v1.44.2}" +if ! command -v curl >/dev/null; then + echo "Error: curl is required to install ghjk." 1>&2 + exit 1 +fi + +if ! command -v tar >/dev/null; then + echo "Error: tar is required to install ghjk." 1>&2 + exit 1 +fi + +ORG=metatypedev +REPO=ghjk +EXT=tar.gz +NAME=ghjk +EXE=ghjk + +INSTALLER_URL="https://raw.githubusercontent.com/$ORG/$REPO/main/install.sh" +RELEASE_URL="https://github.com/$ORG/$REPO/releases" + +LATEST_VERSION=$(curl "$RELEASE_URL/latest" -s -L -I -o /dev/null -w '%{url_effective}') +LATEST_VERSION="${LATEST_VERSION##*v}" + +PLATFORM="${PLATFORM:-}" +TMP_DIR=$(mktemp -d) +GHJK_INSTALL_EXEC_DIR="${GHJK_INSTALL_EXEC_DIR:-$HOME/.local/bin}" +VERSION="${VERSION:-$LATEST_VERSION}" # make sure the version is prepended with v -if [ "${DENO_VERSION#"v"}" = "$DENO_VERSION" ]; then - DENO_VERSION="v$DENO_VERSION" +if [ "${VERSION#"v"}" = "$VERSION" ]; then + VERSION="v$VERSION" +fi + +if [ "${PLATFORM:-x}" = "x" ]; then + MACHINE=$(uname -m) + case "$(uname -s | tr '[:upper:]' '[:lower:]')" in + "linux") + case "$MACHINE" in + "arm64"* | "aarch64"* ) PLATFORM='aarch64-unknown-linux-gnu' ;; + *"64") PLATFORM='x86_64-unknown-linux-gnu' ;; + esac + ;; + "darwin") + case "$MACHINE" in + "arm64"* | "aarch64"* ) PLATFORM='aarch64-apple-darwin' ;; + *"64") PLATFORM='x86_64-apple-darwin' ;; + esac + ;; + "msys"*|"cygwin"*|"mingw"*|*"_nt"*|"win"*) + case "$MACHINE" in + *"64") PLATFORM='x86_64-pc-windows-msvc' ;; + esac + ;; + esac + if [ "${PLATFORM:-x}" = "x" ]; then + cat >&2 <&2 </dev/null; then - echo "Error: curl is required to install deno for ghjk." 1>&2 - exit 1 - fi +EOF + if [ ! -d "${GHJK_INSTALL_EXEC_DIR}" ]; then + mkdir -p "$GHJK_INSTALL_EXEC_DIR" + fi - curl -fsSL https://deno.land/x/install/install.sh | DENO_INSTALL="$GHJK_SHARE_DIR" sh -s "$DENO_VERSION" >/dev/null - fi + if [ -w "${GHJK_INSTALL_EXEC_DIR}" ]; then + printf "Press enter to continue (or cancel with Ctrl+C):" >&2 + read -r _throwaway + mv "$TMP_DIR/$EXE" "$GHJK_INSTALL_EXEC_DIR" + else + echo "$GHJK_INSTALL_EXEC_DIR is not writable." + exit 1 + fi fi -export GHJK_SHARE_DIR -export GHJK_INSTALL_DENO_EXEC -"$GHJK_INSTALL_DENO_EXEC" run -A "$GHJK_INSTALLER_URL" +GHJK_INSTALLER_URL="${GHJK_INSTALLER_URL:-https://raw.github.com/$ORG/$REPO/$VERSION/install.ts}" +"$TMP_DIR/$EXE" deno run -A "$GHJK_INSTALLER_URL" + +rm -r "$TMP_DIR" + +SHELL_TYPE=$(basename "$SHELL") + +case $SHELL_TYPE in + bash|zsh|ksh) + SHELL_CONFIG="$HOME/.$SHELL_TYPE"rc + ;; + fish) + SHELL_CONFIG="$HOME/.config/fish/config.fish" + ;; + *) + SHELL_CONFIG="" +esac + +if [ -n "$SHELL_CONFIG" ]; then + printf "\nDetected shell: %s\n" "$SHELL_TYPE" + echo "Do you want to append the new PATH to your configuration ($SHELL_CONFIG)? (y/n): " >&2 + read -r answer + + answer=$(echo "$answer" | tr "[:upper:]" "[:lower:]") + + case $SHELL_TYPE in + bash|zsh|ksh) + APPEND_CMD="export PATH=\"$GHJK_INSTALL_EXEC_DIR:\$PATH\"" + ;; + fish) + APPEND_CMD="fish_add_path $GHJK_INSTALL_EXEC_DIR" + ;; + esac + + if [ "$answer" = "y" ] || [ "$answer" = "yes" ]; then + echo "$APPEND_CMD" >> "$SHELL_CONFIG" + printf "Path added to %s\nRun 'source %s' to apply changes." "$SHELL_CONFIG" "$SHELL_CONFIG" + else + cat < str.trim()) @@ -24,20 +27,11 @@ if (import.meta.main) { // } await install({ ...defaultInstallArgs, - ghjkShareDir: Deno.env.get("GHJK_SHARE_DIR") ?? - defaultInstallArgs.ghjkShareDir, - skipExecInstall: !!skipBinInstall && skipBinInstall != "0" && - skipBinInstall != "false", + ghjkDataDir: Deno.env.get("GHJK_DATA_DIR") ?? + defaultInstallArgs.ghjkDataDir, shellsToHook, - ghjkExecInstallDir: Deno.env.get("GHJK_INSTALL_EXE_DIR") ?? - defaultInstallArgs.ghjkExecInstallDir, - ghjkExecDenoExec: Deno.env.get("GHJK_INSTALL_DENO_EXEC") ?? - defaultInstallArgs.ghjkExecDenoExec, shellHookMarker: Deno.env.get("GHJK_INSTALL_HOOK_MARKER") ?? defaultInstallArgs.shellHookMarker, - noLockfile: !!noLockfile && noLockfile != "0" && noLockfile != "false", - ghjkDenoCacheDir: Deno.env.get("GHJK_INSTALL_DENO_DIR") ?? - defaultInstallArgs.ghjkDenoCacheDir, }); } else { throw new Error( diff --git a/install/bash-preexec.sh b/install/bash-preexec.sh new file mode 100644 index 00000000..29c3f061 --- /dev/null +++ b/install/bash-preexec.sh @@ -0,0 +1,353 @@ +# bash-preexec.sh -- Bash support for ZSH-like 'preexec' and 'precmd' functions. +# https://github.com/rcaloras/bash-preexec +# +# +# 'preexec' functions are executed before each interactive command is +# executed, with the interactive command as its argument. The 'precmd' +# function is executed before each prompt is displayed. +# +# Author: Ryan Caloras (ryan@bashhub.com) +# Forked from Original Author: Glyph Lefkowitz +# +# V0.5.0 +# + +# General Usage: +# +# 1. Source this file at the end of your bash profile so as not to interfere +# with anything else that's using PROMPT_COMMAND. +# +# 2. Add any precmd or preexec functions by appending them to their arrays: +# e.g. +# precmd_functions+=(my_precmd_function) +# precmd_functions+=(some_other_precmd_function) +# +# preexec_functions+=(my_preexec_function) +# +# 3. Consider changing anything using the DEBUG trap or PROMPT_COMMAND +# to use preexec and precmd instead. Preexisting usages will be +# preserved, but doing so manually may be less surprising. +# +# Note: This module requires two Bash features which you must not otherwise be +# using: the "DEBUG" trap, and the "PROMPT_COMMAND" variable. If you override +# either of these after bash-preexec has been installed it will most likely break. + +# Make sure this is bash that's running and return otherwise. +if [[ -z "${BASH_VERSION:-}" ]]; then + return 1; +fi + +# Avoid duplicate inclusion +if [[ -n "${bash_preexec_imported:-}" ]]; then + return 0 +fi +bash_preexec_imported="defined" + +# WARNING: This variable is no longer used and should not be relied upon. +# Use ${bash_preexec_imported} instead. +__bp_imported="${bash_preexec_imported}" + +# Should be available to each precmd and preexec +# functions, should they want it. $? and $_ are available as $? and $_, but +# $PIPESTATUS is available only in a copy, $BP_PIPESTATUS. +# TODO: Figure out how to restore PIPESTATUS before each precmd or preexec +# function. +__bp_last_ret_value="$?" +BP_PIPESTATUS=("${PIPESTATUS[@]}") +__bp_last_argument_prev_command="$_" + +__bp_inside_precmd=0 +__bp_inside_preexec=0 + +# Initial PROMPT_COMMAND string that is removed from PROMPT_COMMAND post __bp_install +__bp_install_string=$'__bp_trap_string="$(trap -p DEBUG)"\ntrap - DEBUG\n__bp_install' + +# Fails if any of the given variables are readonly +# Reference https://stackoverflow.com/a/4441178 +__bp_require_not_readonly() { + local var + for var; do + if ! ( unset "$var" 2> /dev/null ); then + echo "bash-preexec requires write access to ${var}" >&2 + return 1 + fi + done +} + +# Remove ignorespace and or replace ignoreboth from HISTCONTROL +# so we can accurately invoke preexec with a command from our +# history even if it starts with a space. +__bp_adjust_histcontrol() { + local histcontrol + histcontrol="${HISTCONTROL:-}" + histcontrol="${histcontrol//ignorespace}" + # Replace ignoreboth with ignoredups + if [[ "$histcontrol" == *"ignoreboth"* ]]; then + histcontrol="ignoredups:${histcontrol//ignoreboth}" + fi; + export HISTCONTROL="$histcontrol" +} + +# This variable describes whether we are currently in "interactive mode"; +# i.e. whether this shell has just executed a prompt and is waiting for user +# input. It documents whether the current command invoked by the trace hook is +# run interactively by the user; it's set immediately after the prompt hook, +# and unset as soon as the trace hook is run. +__bp_preexec_interactive_mode="" + +# These arrays are used to add functions to be run before, or after, prompts. +declare -a precmd_functions +declare -a preexec_functions + +# Trims leading and trailing whitespace from $2 and writes it to the variable +# name passed as $1 +__bp_trim_whitespace() { + local var=${1:?} text=${2:-} + text="${text#"${text%%[![:space:]]*}"}" # remove leading whitespace characters + text="${text%"${text##*[![:space:]]}"}" # remove trailing whitespace characters + printf -v "$var" '%s' "$text" +} + + +# Trims whitespace and removes any leading or trailing semicolons from $2 and +# writes the resulting string to the variable name passed as $1. Used for +# manipulating substrings in PROMPT_COMMAND +__bp_sanitize_string() { + local var=${1:?} text=${2:-} sanitized + __bp_trim_whitespace sanitized "$text" + sanitized=${sanitized%;} + sanitized=${sanitized#;} + __bp_trim_whitespace sanitized "$sanitized" + printf -v "$var" '%s' "$sanitized" +} + +# This function is installed as part of the PROMPT_COMMAND; +# It sets a variable to indicate that the prompt was just displayed, +# to allow the DEBUG trap to know that the next command is likely interactive. +__bp_interactive_mode() { + __bp_preexec_interactive_mode="on"; +} + + +# This function is installed as part of the PROMPT_COMMAND. +# It will invoke any functions defined in the precmd_functions array. +__bp_precmd_invoke_cmd() { + # Save the returned value from our last command, and from each process in + # its pipeline. Note: this MUST be the first thing done in this function. + __bp_last_ret_value="$?" BP_PIPESTATUS=("${PIPESTATUS[@]}") + + # Don't invoke precmds if we are inside an execution of an "original + # prompt command" by another precmd execution loop. This avoids infinite + # recursion. + if (( __bp_inside_precmd > 0 )); then + return + fi + local __bp_inside_precmd=1 + + # Invoke every function defined in our function array. + local precmd_function + for precmd_function in "${precmd_functions[@]}"; do + + # Only execute this function if it actually exists. + # Test existence of functions with: declare -[Ff] + if type -t "$precmd_function" 1>/dev/null; then + __bp_set_ret_value "$__bp_last_ret_value" "$__bp_last_argument_prev_command" + # Quote our function invocation to prevent issues with IFS + "$precmd_function" + fi + done + + __bp_set_ret_value "$__bp_last_ret_value" +} + +# Sets a return value in $?. We may want to get access to the $? variable in our +# precmd functions. This is available for instance in zsh. We can simulate it in bash +# by setting the value here. +__bp_set_ret_value() { + return ${1:-} +} + +__bp_in_prompt_command() { + + local prompt_command_array + IFS=$'\n;' read -rd '' -a prompt_command_array <<< "${PROMPT_COMMAND:-}" + + local trimmed_arg + __bp_trim_whitespace trimmed_arg "${1:-}" + + local command trimmed_command + for command in "${prompt_command_array[@]:-}"; do + __bp_trim_whitespace trimmed_command "$command" + if [[ "$trimmed_command" == "$trimmed_arg" ]]; then + return 0 + fi + done + + return 1 +} + +# This function is installed as the DEBUG trap. It is invoked before each +# interactive prompt display. Its purpose is to inspect the current +# environment to attempt to detect if the current command is being invoked +# interactively, and invoke 'preexec' if so. +__bp_preexec_invoke_exec() { + + # Save the contents of $_ so that it can be restored later on. + # https://stackoverflow.com/questions/40944532/bash-preserve-in-a-debug-trap#40944702 + __bp_last_argument_prev_command="${1:-}" + # Don't invoke preexecs if we are inside of another preexec. + if (( __bp_inside_preexec > 0 )); then + return + fi + local __bp_inside_preexec=1 + + # Checks if the file descriptor is not standard out (i.e. '1') + # __bp_delay_install checks if we're in test. Needed for bats to run. + # Prevents preexec from being invoked for functions in PS1 + if [[ ! -t 1 && -z "${__bp_delay_install:-}" ]]; then + return + fi + + if [[ -n "${COMP_LINE:-}" ]]; then + # We're in the middle of a completer. This obviously can't be + # an interactively issued command. + return + fi + if [[ -z "${__bp_preexec_interactive_mode:-}" ]]; then + # We're doing something related to displaying the prompt. Let the + # prompt set the title instead of me. + return + else + # If we're in a subshell, then the prompt won't be re-displayed to put + # us back into interactive mode, so let's not set the variable back. + # In other words, if you have a subshell like + # (sleep 1; sleep 2) + # You want to see the 'sleep 2' as a set_command_title as well. + if [[ 0 -eq "${BASH_SUBSHELL:-}" ]]; then + __bp_preexec_interactive_mode="" + fi + fi + + if __bp_in_prompt_command "${BASH_COMMAND:-}"; then + # If we're executing something inside our prompt_command then we don't + # want to call preexec. Bash prior to 3.1 can't detect this at all :/ + __bp_preexec_interactive_mode="" + return + fi + + local this_command + this_command=$( + export LC_ALL=C + HISTTIMEFORMAT= builtin history 1 | sed '1 s/^ *[0-9][0-9]*[* ] //' + ) + + # Sanity check to make sure we have something to invoke our function with. + if [[ -z "$this_command" ]]; then + return + fi + + # Invoke every function defined in our function array. + local preexec_function + local preexec_function_ret_value + local preexec_ret_value=0 + for preexec_function in "${preexec_functions[@]:-}"; do + + # Only execute each function if it actually exists. + # Test existence of function with: declare -[fF] + if type -t "$preexec_function" 1>/dev/null; then + __bp_set_ret_value ${__bp_last_ret_value:-} + # Quote our function invocation to prevent issues with IFS + "$preexec_function" "$this_command" + preexec_function_ret_value="$?" + if [[ "$preexec_function_ret_value" != 0 ]]; then + preexec_ret_value="$preexec_function_ret_value" + fi + fi + done + + # Restore the last argument of the last executed command, and set the return + # value of the DEBUG trap to be the return code of the last preexec function + # to return an error. + # If `extdebug` is enabled a non-zero return value from any preexec function + # will cause the user's command not to execute. + # Run `shopt -s extdebug` to enable + __bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command" +} + +__bp_install() { + # Exit if we already have this installed. + if [[ "${PROMPT_COMMAND:-}" == *"__bp_precmd_invoke_cmd"* ]]; then + return 1; + fi + + trap '__bp_preexec_invoke_exec "$_"' DEBUG + + # Preserve any prior DEBUG trap as a preexec function + local prior_trap=$(sed "s/[^']*'\(.*\)'[^']*/\1/" <<<"${__bp_trap_string:-}") + unset __bp_trap_string + if [[ -n "$prior_trap" ]]; then + eval '__bp_original_debug_trap() { + '"$prior_trap"' + }' + preexec_functions+=(__bp_original_debug_trap) + fi + + # Adjust our HISTCONTROL Variable if needed. + __bp_adjust_histcontrol + + # Issue #25. Setting debug trap for subshells causes sessions to exit for + # backgrounded subshell commands (e.g. (pwd)& ). Believe this is a bug in Bash. + # + # Disabling this by default. It can be enabled by setting this variable. + if [[ -n "${__bp_enable_subshells:-}" ]]; then + + # Set so debug trap will work be invoked in subshells. + set -o functrace > /dev/null 2>&1 + shopt -s extdebug > /dev/null 2>&1 + fi; + + local existing_prompt_command + # Remove setting our trap install string and sanitize the existing prompt command string + existing_prompt_command="${PROMPT_COMMAND:-}" + existing_prompt_command="${existing_prompt_command//$__bp_install_string[;$'\n']}" # Edge case of appending to PROMPT_COMMAND + existing_prompt_command="${existing_prompt_command//$__bp_install_string}" + __bp_sanitize_string existing_prompt_command "$existing_prompt_command" + + # Install our hooks in PROMPT_COMMAND to allow our trap to know when we've + # actually entered something. + PROMPT_COMMAND=$'__bp_precmd_invoke_cmd\n' + if [[ -n "$existing_prompt_command" ]]; then + PROMPT_COMMAND+=${existing_prompt_command}$'\n' + fi; + PROMPT_COMMAND+='__bp_interactive_mode' + + # Add two functions to our arrays for convenience + # of definition. + precmd_functions+=(precmd) + preexec_functions+=(preexec) + + # Invoke our two functions manually that were added to $PROMPT_COMMAND + __bp_precmd_invoke_cmd + __bp_interactive_mode +} + +# Sets an installation string as part of our PROMPT_COMMAND to install +# after our session has started. This allows bash-preexec to be included +# at any point in our bash profile. +__bp_install_after_session_init() { + # bash-preexec needs to modify these variables in order to work correctly + # if it can't, just stop the installation + __bp_require_not_readonly PROMPT_COMMAND HISTCONTROL HISTTIMEFORMAT || return + + local sanitized_prompt_command + __bp_sanitize_string sanitized_prompt_command "${PROMPT_COMMAND:-}" + if [[ -n "$sanitized_prompt_command" ]]; then + PROMPT_COMMAND=${sanitized_prompt_command}$'\n' + fi; + PROMPT_COMMAND+=${__bp_install_string} +} + +# Run our install so long as we're not delaying it. +if [[ -z "${__bp_delay_install:-}" ]]; then + __bp_install_after_session_init +fi; diff --git a/install/ghjk.sh b/install/ghjk.sh deleted file mode 100644 index 49d0d83e..00000000 --- a/install/ghjk.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -export GHJK_SHARE_DIR="${GHJK_SHARE_DIR:-__GHJK_SHARE_DIR__}" -export DENO_DIR="${GHJK_DENO_DIR:-__DENO_CACHE_DIR}" -export DENO_NO_UPDATE_CHECK=1 -GHJK_MAIN_URL="${GHJK_MAIN_URL:-__MAIN_TS_URL__}" - -# NOTE: avoid putting too much in here as this is only one -# method of getting the ghjk bin which is all ultimately optional -# anyways. - -# NOTE: keep this in sync with impls in install/exec.ts - -# if ghjkfile var is set, set the GHJK_DIR overriding -# any set by the user -if [ -n "${GHJKFILE+x}" ]; then - - GHJK_DIR="$(dirname "$GHJKFILE")/.ghjk" - -# if both GHJKFILE and GHJK_DIR are unset -elif [ -z "${GHJK_DIR+x}" ]; then - - # look for ghjk dirs in parents - cur_dir=$PWD - while true; do - if [ -d "$cur_dir/.ghjk" ] || [ -e "$cur_dir/ghjk.ts" ]; then - GHJK_DIR="$cur_dir/.ghjk" - break - fi - # recursively look in parent directory - next_cur_dir="$(dirname "$cur_dir")" - if [ "$next_cur_dir" = / ] && [ "$cur_dir" = "/" ]; then - break - fi - cur_dir="$next_cur_dir" - done - -fi - -if [ -n "${GHJK_DIR+x}" ]; then - - export GHJK_DIR - mkdir -p "$GHJK_DIR" - lock_flag="--lock $GHJK_DIR/deno.lock" - -else - - lock_flag="--no-lock" - -fi - -# we don't want to quote $lock_flag as it's not exactly a single -# string param to deno -# shellcheck disable=SC2086 -exec __DENO_EXEC__ run __UNSTABLE_FLAGS__ -A $lock_flag $GHJK_MAIN_URL "$@" diff --git a/install/hook.fish b/install/hook.fish index 916890c4..0de6ecde 100644 --- a/install/hook.fish +++ b/install/hook.fish @@ -1,11 +1,13 @@ function __ghjk_get_mtime_ts switch (uname -s | tr '[:upper:]' '[:lower:]') case "linux" - stat -c "%Y" $argv + stat -c "%.Y" $argv case "darwin" - stat -f "%Sm" -t "%s" $argv + # darwin stat doesn't support ms since epoch so we bring out the big guns + deno eval 'console.log((await Deno.stat(Deno.args[0])).mtime.getTime())' $argv + # stat -f "%Sm" -t "%s" $argv case "*" - stat -c "%Y" $argv + stat -c "%.Y" $argv end end @@ -109,6 +111,7 @@ function __ghjk_preexec --on-event fish_preexec # activate script has reloaded else if set --query GHJK_LAST_ENV_DIR; + and test -e $GHJK_LAST_ENV_DIR/activate.fish; and test (__ghjk_get_mtime_ts $GHJK_LAST_ENV_DIR/activate.fish) -gt $GHJK_LAST_ENV_DIR_MTIME; ghjk_hook end diff --git a/install/hook.sh b/install/hook.sh index 2e697b98..f943e463 100644 --- a/install/hook.sh +++ b/install/hook.sh @@ -7,7 +7,9 @@ __ghjk_get_mtime_ts () { stat -c "%Y" "$1" ;; "darwin") - stat -f "%Sm" -t "%s" "$1" + # darwin stat doesn't support ms since epoch so we bring out the big guns + deno eval 'console.log((await Deno.stat(Deno.args[0])).mtime.getTime())' "$1" + # stat -f "%Sm" -t "%s" "$1" ;; "*") stat -c "%Y" "$1" @@ -109,7 +111,7 @@ precmd() { rm "$GHJK_NEXTFILE" # - the env dir loader mtime changes - elif [ -n "${GHJK_LAST_ENV_DIR+x}" ] && [ "$(__ghjk_get_mtime_ts "$GHJK_LAST_ENV_DIR/activate.sh")" -gt "$GHJK_LAST_ENV_DIR_MTIME" ]; then + elif [ -n "${GHJK_LAST_ENV_DIR+x}" ] && [ -e "$GHJK_LAST_ENV_DIR/activate.sh" ] && [ "$(__ghjk_get_mtime_ts "$GHJK_LAST_ENV_DIR/activate.sh")" -gt "$GHJK_LAST_ENV_DIR_MTIME" ]; then ghjk_hook diff --git a/install/mod.ts b/install/mod.ts index 32105067..fb764b03 100644 --- a/install/mod.ts +++ b/install/mod.ts @@ -5,19 +5,12 @@ // relying on --frozen-lockfile import getLogger from "../utils/logger.ts"; -import { $, dirs, importRaw } from "../utils/mod.ts"; +import { $, importRaw } from "../utils/mod.ts"; import type { Path } from "../utils/mod.ts"; +import { xdg } from "../deps/install.ts"; const logger = getLogger(import.meta); -/** - * Deno unstable flags needed for ghjk host. - */ -export const unstableFlags = [ - "--unstable-kv", - "--unstable-worker-options", -]; - // TODO: calculate and add integrity hashes to these raw imports // as they won't be covered by deno.lock // - use pre-commit-hook plus ghjk tasks to do find+replace @@ -39,7 +32,7 @@ const getHooksVfs = async () => ({ "env.bash": [ "# importing bash-preexec, see the ghjk hook at then end\n\n", await importRaw( - "https://raw.githubusercontent.com/rcaloras/bash-preexec/0.5.0/bash-preexec.sh", + import.meta.resolve("./bash-preexec.sh"), ), await importRaw(import.meta.resolve("./hook.sh")), ].join("\n"), @@ -104,51 +97,37 @@ async function filterAddContent( interface InstallArgs { homeDir: string; - ghjkShareDir: string; + ghjkDataDir: string; shellsToHook?: string[]; /** The mark used when adding the hook to the user's shell rcs. * Override to allow multiple hooks in your rc. */ shellHookMarker: string; - /** - * The ghjk bin is optional, one can always invoke it - * using `deno run --flags uri/to/ghjk/main.ts`; - */ - skipExecInstall: boolean; - /** The directory in which to install the ghjk exec - * Preferrably, one that's in PATH - */ - ghjkExecInstallDir: string; - /** - * The deno exec to be used by the ghjk executable - * by default will be "deno" i.e. whatever in $PATH that resolves that to. - */ - ghjkExecDenoExec: string; - /** - * The cache dir to use by the ghjk deno installation. - */ - ghjkDenoCacheDir?: string; - /** - * Disable using a lockfile for the ghjk command - */ - noLockfile: boolean; +} + +function getHomeDir() { + switch (Deno.build.os) { + case "linux": + case "darwin": + return Deno.env.get("HOME") ?? null; + case "windows": + return Deno.env.get("USERPROFILE") ?? null; + default: + return null; + } +} +const homeDir = getHomeDir(); +if (!homeDir) { + throw new Error("cannot find home dir"); } export const defaultInstallArgs: InstallArgs = { - ghjkShareDir: $.path(dirs().shareDir).resolve("ghjk").toString(), - homeDir: dirs().homeDir, + // remove first the xdg.data suffix added in windows by lib + ghjkDataDir: $.path(xdg.data().replace("xdg.data", "")).resolve("ghjk") + .toString(), + homeDir, shellsToHook: [], shellHookMarker: "ghjk-hook-default", - skipExecInstall: true, - // TODO: respect xdg dirs - ghjkExecInstallDir: $.path(dirs().homeDir).resolve(".local", "bin") - .toString(), - ghjkExecDenoExec: Deno.execPath(), - /** - * the default behvaior kicks in with ghjkDenoCacheDir is falsy - * ghjkDenoCacheDir: undefined, - */ - noLockfile: false, }; const shellConfig: Record = { @@ -165,14 +144,14 @@ export async function install( if (Deno.build.os == "windows") { throw new Error("windows is not yet supported, please use wsl"); } - const ghjkShareDir = $.path(Deno.cwd()) - .resolve(args.ghjkShareDir); + const ghjkDataDir = $.path(Deno.cwd()) + .resolve(args.ghjkDataDir); - logger.info("unpacking vfs", { ghjkShareDir }); + logger.info("unpacking vfs", { ghjkDataDir }); await unpackVFS( await getHooksVfs(), - ghjkShareDir, - [[/__GHJK_SHARE_DIR__/g, ghjkShareDir.toString()]], + ghjkDataDir, + [[/__GHJK_DATA_DIR__/g, ghjkDataDir.toString()]], ); for (const shell of args.shellsToHook ?? Object.keys(shellConfig)) { const { homeDir } = args; @@ -188,7 +167,7 @@ export async function install( continue; } logger.info("installing hook", { - ghjkShareDir, + ghjkDataDir, shell, marker: args.shellHookMarker, rcPath, @@ -196,60 +175,7 @@ export async function install( await filterAddContent( rcPath, new RegExp(args.shellHookMarker, "g"), - `. ${ghjkShareDir}/env.${shell} # ${args.shellHookMarker}`, - ); - } - - if (!args.skipExecInstall) { - const installDir = await $.path(args.ghjkExecInstallDir).ensureDir(); - switch (Deno.build.os) { - case "linux": - case "freebsd": - case "solaris": - case "illumos": - case "darwin": { - const exePath = installDir.resolve(`ghjk`); - logger.debug("installing executable", { exePath }); - - // use an isolated cache by default - const denoCacheDir = args.ghjkDenoCacheDir - ? $.path(args.ghjkDenoCacheDir) - : ghjkShareDir.resolve("deno"); - await exePath.writeText( - (await importRaw(import.meta.resolve("./ghjk.sh"))) - .replaceAll( - "__GHJK_SHARE_DIR__", - ghjkShareDir.toString(), - ) - .replaceAll( - "__DENO_CACHE_DIR", - denoCacheDir.toString(), - ) - .replaceAll( - "__DENO_EXEC__", - args.ghjkExecDenoExec, - ) - .replaceAll( - "__UNSTABLE_FLAGS__", - unstableFlags.join(" "), - ) - .replaceAll( - "__MAIN_TS_URL__", - import.meta.resolve("../main.ts"), - ), - { mode: 0o700 }, - ); - break; - } - default: - throw new Error(`${Deno.build.os} is not yet supported`); - } - logger.warn( - "make sure to add the following to your $PATH to access the ghjk CLI", - ); - logger.warn( - installDir.toString(), + `. ${ghjkDataDir}/env.${shell} # ${args.shellHookMarker}`, ); } - logger.info("install success"); } diff --git a/install/utils.ts b/install/utils.ts index 1f5bb9b5..a6796845 100644 --- a/install/utils.ts +++ b/install/utils.ts @@ -1,44 +1,31 @@ //! Please keep these in sync with `./ghjk.ts` import type { GhjkCtx } from "../modules/types.ts"; -import { unstableFlags } from "./mod.ts"; /** * Returns a simple posix function to invoke the ghjk CLI. + * This shim assumes it's running inside the ghjk embedded deno runtime. */ export function ghjk_sh( gcx: GhjkCtx, - denoDir: string, functionName = "__ghjk_shim", ) { return `${functionName} () { - GHJK_SHARE_DIR="${gcx.ghjkShareDir}" \\ - DENO_DIR="${denoDir}" \\ - DENO_NO_UPDATE_CHECK=1 \\ GHJK_DIR="${gcx.ghjkDir}" \\ - ${Deno.execPath()} run ${ - unstableFlags.join(" ") - } -A --lock ${gcx.ghjkDir}/deno.lock ${import.meta.resolve("../main.ts")} "$@" + ${Deno.execPath()} "$@" }`; } /** * Returns a simple fish function to invoke the ghjk CLI. + * This shim assumes it's running inside the ghjk embedded deno runtime. */ export function ghjk_fish( gcx: GhjkCtx, - denoDir: string, functionName = "__ghjk_shim", ) { return `function ${functionName} - GHJK_SHARE_DIR="${gcx.ghjkShareDir}" \\ - DENO_DIR="${denoDir}" \\ - DENO_NO_UPDATE_CHECK=1 \\ GHJK_DIR="${gcx.ghjkDir}" \\ - ${Deno.execPath()} run ${ - unstableFlags.join(" ") - } -A --lock ${gcx.ghjkDir}/deno.lock ${ - import.meta.resolve("../main.ts") - } $argv + ${Deno.execPath()} $argv end`; } diff --git a/main.ts b/main.ts deleted file mode 100755 index 35a2f835..00000000 --- a/main.ts +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env -S deno run --unstable-worker-options -A - -import "./setup_logger.ts"; -import { cli } from "./host/mod.ts"; -import { std_path } from "./deps/common.ts"; -import logger from "./utils/logger.ts"; -import { dirs, findEntryRecursive } from "./utils/mod.ts"; - -if (import.meta.main) { - // look for ghjkdir - let ghjkdir = Deno.env.get("GHJK_DIR") ?? - await findEntryRecursive(Deno.cwd(), ".ghjk"); - const ghjkfile = ghjkdir - ? await findEntryRecursive(std_path.dirname(ghjkdir), "ghjk.ts") - : await findEntryRecursive(Deno.cwd(), "ghjk.ts"); - if (!ghjkdir && !ghjkfile) { - logger().warn( - "ghjk could not find any ghjkfiles or ghjkdirs, try creating a `ghjk.ts` script.", - ); - // Deno.exit(2); - } - if (ghjkfile && !ghjkdir) { - ghjkdir = std_path.resolve(std_path.dirname(ghjkfile), ".ghjk"); - } - await cli({ - // FIXME: better - reFlagSet: !!Deno.env.get("GHJK_RE") && - !(["false", "", ""].includes(Deno.env.get("GHJK_RE")!)), - lockedFlagSet: !!Deno.env.get("GHJK_LOCKED") && - !(["false", "", ""].includes(Deno.env.get("GHJK_LOCKED")!)), - - ghjkShareDir: Deno.env.get("GHJK_SHARE_DIR") ?? - dirs().shareDir.resolve("ghjk").toString(), - ghjkfilePath: ghjkfile ? std_path.resolve(Deno.cwd(), ghjkfile) : undefined, - ghjkDirPath: ghjkdir ? std_path.resolve(Deno.cwd(), ghjkdir) : undefined, - }); -} else { - throw new Error( - `unexpected context: this module is an entrypoint. If you want to programmatically invoke the ghjk cli, import \`cli\` from ${ - import.meta.resolve("./host/mod.ts") - }`, - ); -} diff --git a/modules/envs/mod.ts b/modules/envs/mod.ts index 516173b3..996970ad 100644 --- a/modules/envs/mod.ts +++ b/modules/envs/mod.ts @@ -1,6 +1,6 @@ export * from "./types.ts"; -import { cliffy_cmd, zod } from "../../deps/cli.ts"; +import { zod } from "../../deps/cli.ts"; import { $, detectShellPath, Json, unwrapZodRes } from "../../utils/mod.ts"; import validators from "./types.ts"; import type { @@ -20,6 +20,7 @@ import type { import { buildInstallGraph, syncCtxFromGhjk } from "../ports/sync.ts"; import { getEnvsCtx } from "./inter.ts"; import { getTasksCtx } from "../tasks/inter.ts"; +import { CliCommand } from "../../src/deno_systems/types.ts"; export type EnvsCtx = { activeEnv: string; @@ -33,9 +34,8 @@ const lockValidator = zod.object({ type EnvsLockEnt = zod.infer; -export class EnvsModule extends ModuleBase { - processManifest( - gcx: GhjkCtx, +export class EnvsModule extends ModuleBase { + override loadConfig( manifest: ModuleManifest, _bb: Blackboard, _lockEnt: EnvsLockEnt | undefined, @@ -52,20 +52,18 @@ export class EnvsModule extends ModuleBase { const setEnv = Deno.env.get("GHJK_ENV"); const activeEnv = setEnv && setEnv != "" ? setEnv : config.defaultEnv; - const envsCtx = getEnvsCtx(gcx); - envsCtx.activeEnv = activeEnv; - envsCtx.config = config; + const ecx = getEnvsCtx(this.gcx); + ecx.activeEnv = activeEnv; + ecx.config = config; for (const [name, key] of Object.entries(config.envsNamed)) { - envsCtx.keyToName[key] = [name, ...(envsCtx.keyToName[key] ?? [])]; + ecx.keyToName[key] = [name, ...(ecx.keyToName[key] ?? [])]; } - - return Promise.resolve(envsCtx); } - commands( - gcx: GhjkCtx, - ecx: EnvsCtx, - ) { + override commands(): CliCommand[] { + const gcx = this.gcx; + const ecx = getEnvsCtx(this.gcx); + function envKeyArgs( args: { taskKeyMaybe?: string; @@ -92,20 +90,32 @@ export class EnvsModule extends ModuleBase { : { envKey: envKeyMaybe ?? ecx.activeEnv }; } - return { - envs: new cliffy_cmd - .Command() - .description("Envs module, reproducable posix shells environments.") - .alias("e") - // .alias("env") - .action(function () { - this.showHelp(); - }) - .command( - "ls", - new cliffy_cmd.Command() - .description("List environments defined in the ghjkfile.") - .action(() => { + const commonFlags: CliCommand["flags"] = { + taskEnv: { + short: "t", + long: "task-env", + value_name: "TASK NAME", + help: "Activate the environment used by the named task", + exclusive: true, + }, + }; + + const commonArgs: CliCommand["args"] = { + envKey: { + value_name: "ENV KEY", + }, + }; + + return [ + { + name: "envs", + visible_aliases: ["e"], + about: "Envs module, reproducable posix shells environments.", + sub_commands: [ + { + name: "ls", + about: "List environments defined in the ghjkfile.", + action: () => { // deno-lint-ignore no-console console.log( Object.entries(ecx.config.envsNamed) @@ -118,66 +128,84 @@ export class EnvsModule extends ModuleBase { }) .join("\n"), ); - }), - ) - .command( - "activate", - new cliffy_cmd.Command() - .description(`Activate an environment. - -- If no [envName] is specified and no env is currently active, this activates the configured default env [${ecx.config.defaultEnv}].`) - .arguments("[envName:string]") - .option( - "-t, --task-env ", - "Synchronize to the environment used by the named task", - { standalone: true }, - ) - .action(async function ({ taskEnv }, envKeyMaybe) { + }, + }, + { + name: "activate", + about: `Activate an environment.`, + before_long_help: + `- If no ENV KEY is specified and no env is currently active, this activates the configured default env [${ecx.config.defaultEnv}].`, + flags: { + ...commonFlags, + }, + args: { + ...commonArgs, + }, + action: async function ( + { + flags: { taskEnv: taskKeyMaybe }, + args: { envKey: envKeyMaybe }, + }, + ) { const { envKey } = envKeyArgs({ - taskKeyMaybe: taskEnv, - envKeyMaybe, + taskKeyMaybe: taskKeyMaybe as string, + envKeyMaybe: (Array.isArray(envKeyMaybe) + ? envKeyMaybe[0] + : envKeyMaybe) as string, }); await activateEnv(envKey); - }), - ) - .command( - "cook", - new cliffy_cmd.Command() - .description(`Cooks the environment to a posix shell. - -- If no [envName] is specified, this will cook the active env [${ecx.activeEnv}]`) - .arguments("[envName:string]") - .option( - "-t, --task-env ", - "Synchronize to the environment used by the named task", - { standalone: true }, - ) - .action(async function ({ taskEnv }, envKeyMaybe) { + }, + }, + { + name: "cook", + about: `Cooks the environment to a posix shell.`, + before_long_help: + `- If no ENV KEY is specified, this will cook the active env [${ecx.activeEnv}]`, + flags: { + ...commonFlags, + }, + args: { + ...commonArgs, + }, + action: async function ( + { + flags: { taskEnv: taskKeyMaybe }, + args: { envKey: envKeyMaybe }, + }, + ) { const { envKey, envName } = envKeyArgs({ - taskKeyMaybe: taskEnv, - envKeyMaybe, + taskKeyMaybe: taskKeyMaybe as string, + envKeyMaybe: (Array.isArray(envKeyMaybe) + ? envKeyMaybe[0] + : envKeyMaybe) as string, }); await reduceAndCookEnv(gcx, ecx, envKey, envName ?? envKey); - }), - ) - .command( - "show", - new cliffy_cmd.Command() - .description(`Show details about an environment. + }, + }, + { + name: "show", + about: `Cooks the environment to a posix shell.`, + before_long_help: `Show details about an environment. -- If no [envName] is specified, this shows details of the active env [${ecx.activeEnv}]. -- If no [envName] is specified and no env is active, this shows details of the default env [${ecx.config.defaultEnv}]. - `) - .arguments("[envName:string]") - .option( - "-t, --task-env ", - "Synchronize to the environment used by the named task", - { standalone: true }, - ) - .action(async function ({ taskEnv }, envKeyMaybe) { +- If no ENV KEY is specified, this shows details of the active env [${ecx.activeEnv}]. +- If no ENV KEY is specified and no env is active, this shows details of the default env [${ecx.config.defaultEnv}].`, + flags: { + ...commonFlags, + }, + args: { + ...commonArgs, + }, + action: async function ( + { + flags: { taskEnv: taskKeyMaybe }, + args: { envKey: envKeyMaybe }, + }, + ) { const { envKey } = envKeyArgs({ - taskKeyMaybe: taskEnv, - envKeyMaybe, + taskKeyMaybe: taskKeyMaybe as string, + envKeyMaybe: (Array.isArray(envKeyMaybe) + ? envKeyMaybe[0] + : envKeyMaybe) as string, }); const env = ecx.config.envs[envKey]; if (!env) { @@ -185,24 +213,30 @@ export class EnvsModule extends ModuleBase { } // deno-lint-ignore no-console console.log($.inspect(await showableEnv(gcx, env, envKey))); - }), - ), - sync: new cliffy_cmd.Command() - .description(`Synchronize your shell to what's in your config. - -Cooks and activates an environment. -- If no [envName] is specified and no env is currently active, this syncs the configured default env [${ecx.config.defaultEnv}]. -- If the environment is already active, this doesn't launch a new shell.`) - .arguments("[envName:string]") - .option( - "-t, --task-env ", - "Synchronize to the environment used by the named task", - { standalone: true }, - ) - .action(async function ({ taskEnv }, envKeyMaybe) { + }, + }, + ], + }, + { + name: "sync", + about: "Synchronize your shell to what's in your config.", + before_long_help: `Cooks and activates an environment. +- If no ENV KEY is specified and no env is currently active, this syncs the configured default env [${ecx.config.defaultEnv}]. +- If the environment is already active, this doesn't launch a new shell.`, + flags: { + ...commonFlags, + }, + args: { + ...commonArgs, + }, + action: async function ( + { flags: { taskEnv: taskKeyMaybe }, args: { envKey: envKeyMaybe } }, + ) { const { envKey, envName } = envKeyArgs({ - taskKeyMaybe: taskEnv, - envKeyMaybe, + taskKeyMaybe: taskKeyMaybe as string, + envKeyMaybe: (Array.isArray(envKeyMaybe) + ? envKeyMaybe[0] + : envKeyMaybe) as string, }); await reduceAndCookEnv( gcx, @@ -211,14 +245,12 @@ Cooks and activates an environment. envName ?? envKey, ); await activateEnv(envKey); - }), - }; + }, + }, + ]; } - loadLockEntry( - _gcx: GhjkCtx, - raw: Json, - ) { + loadLockEntry(raw: Json) { const entry = lockValidator.parse(raw); if (entry.version != "0") { @@ -227,10 +259,7 @@ Cooks and activates an environment. return entry; } - genLockEntry( - _gcx: GhjkCtx, - _tcx: EnvsCtx, - ) { + genLockEntry() { return { version: "0", }; diff --git a/modules/envs/posix.ts b/modules/envs/posix.ts index 73f479e8..323fa055 100644 --- a/modules/envs/posix.ts +++ b/modules/envs/posix.ts @@ -202,7 +202,7 @@ async function writeActivators( onExitHooks: [string, string[]][], ) { const ghjkDirVar = "_ghjk_dir"; - const shareDirVar = "_ghjk_share_dir"; + const dataDirVar = "_ghjk_data_dir"; pathVars = { ...Object.fromEntries( Object.entries(pathVars).map(( @@ -211,7 +211,7 @@ async function writeActivators( key, val .replace(gcx.ghjkDir.toString(), "$" + ghjkDirVar) - .replace(gcx.ghjkShareDir.toString(), "$" + shareDirVar), + .replace(gcx.ghjkDataDir.toString(), "$" + dataDirVar), ]), ), }; @@ -227,9 +227,6 @@ async function writeActivators( .join(" ").replaceAll("'", "'\\''") ); - // ghjk.sh sets the DENO_DIR so we can usually - // assume it's set - const denoDir = Deno.env.get("DENO_DIR") ?? ""; const scripts = { // // posix shell version @@ -252,7 +249,7 @@ async function writeActivators( ``, `# the following variables are used to make the script more human readable`, `${ghjkDirVar}="${gcx.ghjkDir.toString()}"`, - `${shareDirVar}="${gcx.ghjkShareDir.toString()}"`, + `${dataDirVar}="${gcx.ghjkDataDir.toString()}"`, ``, `export GHJK_CLEANUP_POSIX="";`, `# env vars`, @@ -305,11 +302,8 @@ async function writeActivators( }), ``, `# hooks that want to invoke ghjk are made to rely`, - `# on this shim instead to improve latency`, - // the ghjk executable is itself a shell script - // which execs deno, we remove the middleman here - // also, the ghjk executable is optional - ghjk_sh(gcx, denoDir, ghjkShimName), + `# on this shim to improve reliablity`, + ghjk_sh(gcx, ghjkShimName), ``, `# only run the hooks in interactive mode`, `case "$-" in`, @@ -346,7 +340,7 @@ async function writeActivators( ``, `# the following variables are used to make the script more human readable`, `set ${ghjkDirVar} "${gcx.ghjkDir.toString()}"`, - `set ${shareDirVar} "${gcx.ghjkShareDir.toString()}"`, + `set ${dataDirVar} "${gcx.ghjkDataDir.toString()}"`, ``, `# env vars`, `# we keep track of old values before this script is run`, @@ -376,8 +370,8 @@ async function writeActivators( }), ``, `# hooks that want to invoke ghjk are made to rely`, - `# on this shim to improve latency`, - ghjk_fish(gcx, denoDir, ghjkShimName), + `# on this shim to improve to improve reliablity`, + ghjk_fish(gcx, ghjkShimName), ``, `# only run the hooks in interactive mode`, `if status is-interactive;`, diff --git a/modules/mod.ts b/modules/mod.ts index daa35fa1..210079ab 100644 --- a/modules/mod.ts +++ b/modules/mod.ts @@ -1,29 +1,22 @@ -import { cliffy_cmd } from "../deps/cli.ts"; import { Blackboard } from "../host/types.ts"; +import { CliCommand } from "../src/deno_systems/types.ts"; import type { Json } from "../utils/mod.ts"; import type { GhjkCtx, ModuleManifest } from "./types.ts"; -export abstract class ModuleBase { +export abstract class ModuleBase { + constructor(protected gcx: GhjkCtx) {} /* init( _gcx: GhjkCtx, ): Promise | void {} */ - abstract processManifest( - gcx: GhjkCtx, + abstract loadConfig( manifest: ModuleManifest, bb: Blackboard, lockEnt: LockEnt | undefined, - ): Promise | Ctx; + ): Promise | void; // returns undefined if previous lock entry is no longer valid abstract loadLockEntry( - gcx: GhjkCtx, raw: Json, ): Promise | LockEnt | undefined; - abstract genLockEntry( - gcx: GhjkCtx, - mcx: Ctx, - ): Promise | Json; - abstract commands( - gcx: GhjkCtx, - mcx: Ctx, - ): Record>; + abstract genLockEntry(): Promise | Json; + abstract commands(): CliCommand[]; } diff --git a/modules/ports/mod.ts b/modules/ports/mod.ts index 1dcad40d..98f9b7b2 100644 --- a/modules/ports/mod.ts +++ b/modules/ports/mod.ts @@ -1,6 +1,6 @@ export * from "./types.ts"; -import { cliffy_cmd, Table, zod } from "../../deps/cli.ts"; +import { Table, zod } from "../../deps/cli.ts"; import { $, Json, unwrapZodRes } from "../../utils/mod.ts"; import logger from "../../utils/logger.ts"; import validators, { @@ -35,6 +35,7 @@ import type { Provision, ProvisionReducer } from "../envs/types.ts"; import { getPortsCtx } from "./inter.ts"; import { updateInstall } from "./utils.ts"; import { getEnvsCtx } from "../envs/inter.ts"; +import { CliCommand } from "../../src/deno_systems/types.ts"; export type PortsCtx = { config: PortsModuleConfigX; @@ -49,9 +50,8 @@ const lockValidator = zod.object({ }); type PortsLockEnt = zod.infer; -export class PortsModule extends ModuleBase { - processManifest( - gcx: GhjkCtx, +export class PortsModule extends ModuleBase { + loadConfig( manifest: ModuleManifest, bb: Blackboard, _lockEnt: PortsLockEnt | undefined, @@ -67,7 +67,8 @@ export class PortsModule extends ModuleBase { validators.portsModuleConfigHashed.safeParse(manifest.config), ); - const pcx: PortsCtx = getPortsCtx(gcx); + const gcx = this.gcx; + const pcx = getPortsCtx(gcx); // pre-process the install sets found in the config for (const [id, hashedSet] of Object.entries(hashedModConf.sets)) { @@ -108,176 +109,70 @@ export class PortsModule extends ModuleBase { installSetProvisionTy, installSetReducer(gcx) as ProvisionReducer, ); - return pcx; } - commands( - gcx: GhjkCtx, - pcx: PortsCtx, - ) { - return { - ports: new cliffy_cmd.Command() - .alias("p") - .action(function () { - this.showHelp(); - }) - .description("Ports module, install programs into your env.") - .command( - "resolve", - new cliffy_cmd.Command() - .description(`Resolve all installs declared in config. - -- Useful to pre-resolve and add all install configs to the lockfile.`) - .action(async function () { - // scx contains a reference counted db connection - // somewhere deep in there - // so we need to use `using` - await using scx = await syncCtxFromGhjk(gcx); - for (const [_id, set] of Object.entries(pcx.config.sets)) { - void await buildInstallGraph(scx, set); - } - }), - ) - .command( - "outdated", - new cliffy_cmd.Command() - .description("Show a version table for installs.") - .option( - "-u, --update-install ", - "Update specific install", - ) - .option("-n, --update-all", "Update all installs") - .action(async (opts) => { - const envsCtx = getEnvsCtx(gcx); - const envName = envsCtx.activeEnv; - - const installSets = pcx.config.sets; - - let currInstallSetId; - { - const activeEnvName = envsCtx.activeEnv; - const activeEnv = envsCtx.config - .envs[ - envsCtx.config.envsNamed[activeEnvName] ?? activeEnvName - ]; - if (!activeEnv) { - throw new Error( - `No env found under given name "${activeEnvName}"`, - ); - } - - const instSetRef = activeEnv.provides.filter((prov) => - prov.ty === installSetRefProvisionTy - )[0] as InstallSetRefProvision; - - currInstallSetId = instSetRef.setId; - } - const currInstallSet = installSets[currInstallSetId]; - const allowedDeps = currInstallSet.allowedBuildDeps; - - const rows = []; - const { - installedPortsVersions: installed, - latestPortsVersions: latest, - installConfigs, - } = await getOldNewVersionComparison( - gcx, - envName, - allowedDeps, - ); - for (let [installId, installedVersion] of installed.entries()) { - let latestVersion = latest.get(installId); - if (!latestVersion) { - throw new Error( - `Couldn't find the latest version for install id: ${installId}`, - ); - } - - if (latestVersion[0] === "v") { - latestVersion = latestVersion.slice(1); - } - if (installedVersion[0] === "v") { - installedVersion = installedVersion.slice(1); - } - - const config = installConfigs.get(installId); - - if (!config) { - throw new Error( - `Config not found for install id: ${installId}`, - ); - } - - if (config["specifiedVersion"]) { - latestVersion = "=" + latestVersion; - } - - const presentableConfig = { ...config }; - ["buildDepConfigs", "version", "specifiedVersion"].map( - (key) => { - delete presentableConfig[key]; - }, - ); - const row = [ - $.inspect(presentableConfig), - installedVersion, - latestVersion, - ]; - rows.push(row); - } - - if (opts.updateInstall) { - const installName = opts.updateInstall; - // TODO: convert from install name to install id, after port module refactor - let installId!: string; - const newVersion = latest.get(installId); - if (!newVersion) { - logger().info( - `Error while fetching the latest version for: ${installName}`, - ); - return; - } - await updateInstall(gcx, installId, newVersion, allowedDeps); - return; - } - - if (opts.updateAll) { - for (const [installId, newVersion] of latest.entries()) { - await updateInstall(gcx, installId, newVersion, allowedDeps); - } - return; - } - - const _versionTable = new Table() - .header(["Install Config", "Old Version", "New Version"]) - .body(rows) - .border() - .padding(1) - .indent(2) - .maxColWidth(30) - .render(); - }), - ) - .command( - "cleanup", - new cliffy_cmd.Command() - .description("TODO") - .action(function () { - throw new Error("TODO"); - }), - ), - }; + override commands() { + const gcx = this.gcx; + const pcx = getPortsCtx(gcx); + + const out: CliCommand[] = [{ + name: "ports", + visible_aliases: ["p"], + about: "Ports module, install programs into your env.", + sub_commands: [ + { + name: "resolve", + about: "Resolve all installs declared in config.", + before_long_help: + `- Useful to pre-resolve and add all install configs to the lockfile.`, + action: async function () { + // scx contains a reference counted db connection + // somewhere deep in there + // so we need to use `using` + await using scx = await syncCtxFromGhjk(gcx); + for (const [_id, set] of Object.entries(pcx.config.sets)) { + void await buildInstallGraph(scx, set); + } + }, + }, + { + name: "outdated", + about: "Show a version table for installs.", + flags: { + updateInstall: { + short: "u", + long: "update-install", + value_name: "INSTALL ID", + }, + updateAll: { + short: "a", + long: "update-all", + action: "SetTrue", + }, + }, + action: async function ( + { flags: { updateInstall, updateAll } }, + ) { + await outdatedCommand( + gcx, + pcx, + updateInstall as string | undefined, + updateAll as boolean | undefined, + ); + }, + }, + ], + }]; + return out; } - loadLockEntry( - gcx: GhjkCtx, - raw: Json, - ) { + + loadLockEntry(raw: Json) { const entry = lockValidator.parse(raw); if (entry.version != "0") { throw new Error(`unexepected version tag deserializing lockEntry`); } - const memoStore = getResolutionMemo(gcx); + const memoStore = getResolutionMemo(this.gcx); for (const [hash, config] of Object.entries(entry.configResolutions)) { logger().debug( "restoring resolution from lockfile", @@ -290,11 +185,8 @@ export class PortsModule extends ModuleBase { return entry; } - async genLockEntry( - gcx: GhjkCtx, - _pcx: PortsCtx, - ) { - const memo = getResolutionMemo(gcx); + async genLockEntry() { + const memo = getResolutionMemo(this.gcx); const configResolutions = Object.fromEntries( await Array.fromAsync( [...memo.entries()].map(async ([key, prom]) => [key, await prom]), @@ -307,6 +199,120 @@ export class PortsModule extends ModuleBase { } } +async function outdatedCommand( + gcx: GhjkCtx, + pcx: PortsCtx, + updateInstallFlag?: string, + updateAllFlag?: boolean, +) { + const envsCtx = getEnvsCtx(gcx); + const envName = envsCtx.activeEnv; + + const installSets = pcx.config.sets; + + let currInstallSetId; + { + const activeEnvName = envsCtx.activeEnv; + const activeEnv = envsCtx.config + .envs[ + envsCtx.config.envsNamed[activeEnvName] ?? activeEnvName + ]; + if (!activeEnv) { + throw new Error( + `No env found under given name "${activeEnvName}"`, + ); + } + + const instSetRef = activeEnv.provides.filter((prov) => + prov.ty === installSetRefProvisionTy + )[0] as InstallSetRefProvision; + + currInstallSetId = instSetRef.setId; + } + const currInstallSet = installSets[currInstallSetId]; + const allowedDeps = currInstallSet.allowedBuildDeps; + + const rows = []; + const { + installedPortsVersions: installed, + latestPortsVersions: latest, + installConfigs, + } = await getOldNewVersionComparison( + gcx, + envName, + allowedDeps, + ); + for (let [installId, installedVersion] of installed.entries()) { + let latestVersion = latest.get(installId); + if (!latestVersion) { + throw new Error( + `Couldn't find the latest version for install id: ${installId}`, + ); + } + + if (latestVersion[0] === "v") { + latestVersion = latestVersion.slice(1); + } + if (installedVersion[0] === "v") { + installedVersion = installedVersion.slice(1); + } + + const config = installConfigs.get(installId); + + if (!config) { + throw new Error( + `Config not found for install id: ${installId}`, + ); + } + + if (config["specifiedVersion"]) { + latestVersion = "=" + latestVersion; + } + + const presentableConfig = { ...config }; + ["buildDepConfigs", "version", "specifiedVersion"].map( + (key) => { + delete presentableConfig[key]; + }, + ); + const row = [ + $.inspect(presentableConfig), + installedVersion, + latestVersion, + ]; + rows.push(row); + } + + if (updateInstallFlag) { + const installId = updateInstallFlag; + const newVersion = latest.get(installId); + if (!newVersion) { + logger().info( + `Error while fetching the latest version for: ${installId}`, + ); + return; + } + await updateInstall(gcx, installId, newVersion, allowedDeps); + return; + } + + if (updateAllFlag) { + for (const [installId, newVersion] of latest.entries()) { + await updateInstall(gcx, installId, newVersion, allowedDeps); + } + return; + } + + const _versionTable = new Table() + .header(["Install Config", "Old Version", "New Version"]) + .body(rows) + .border() + .padding(1) + .indent(2) + .maxColWidth(30) + .render(); +} + async function getOldNewVersionComparison( gcx: GhjkCtx, envName: string, diff --git a/modules/ports/sync.ts b/modules/ports/sync.ts index c39e6593..becd443c 100644 --- a/modules/ports/sync.ts +++ b/modules/ports/sync.ts @@ -53,7 +53,7 @@ export type SyncCtx = Awaited>; export async function syncCtxFromGhjk( gcx: GhjkCtx, ) { - const portsPath = await $.path(gcx.ghjkShareDir).resolve("ports") + const portsPath = await $.path(gcx.ghjkDataDir).resolve("ports") .ensureDir(); const [installsPath, downloadsPath, tmpPath] = ( await Promise.all([ @@ -518,9 +518,14 @@ function resolveConfig( version.match(new RegExp(`^v?${config.version}$`)) ); if (!match) { - throw new Error(`error resolving verison: not found`, { - cause: { config, manifest, allVersions }, - }); + throw new Error( + `error resolving verison ${config.version}: not found, available versions: [${ + allVersions.join(", ") + }]`, + { + cause: { config, manifest, allVersions }, + }, + ); } version = match; } else { diff --git a/modules/ports/worker.ts b/modules/ports/worker.ts index de2a21c8..97bf2d52 100644 --- a/modules/ports/worker.ts +++ b/modules/ports/worker.ts @@ -164,6 +164,9 @@ export class DenoWorkerPort extends PortBase { const worker = new Worker(import.meta.url, { name: `${this.manifest.name}@${this.manifest.version}`, type: "module", + // FIXME: catch worker errors or they bring down the whole + // program (no lockfile generated) + // TODO: proper permissions }); // promise that resolves when worker replies const promise = new Promise((resolve, reject) => { diff --git a/modules/tasks/mod.ts b/modules/tasks/mod.ts index 222bda79..c5349c24 100644 --- a/modules/tasks/mod.ts +++ b/modules/tasks/mod.ts @@ -1,16 +1,17 @@ export * from "./types.ts"; -import { cliffy_cmd, zod } from "../../deps/cli.ts"; +import { zod } from "../../deps/cli.ts"; import { Json, unwrapZodRes } from "../../utils/mod.ts"; import validators from "./types.ts"; import type { TasksModuleConfigX } from "./types.ts"; -import { type GhjkCtx, type ModuleManifest } from "../types.ts"; +import { type ModuleManifest } from "../types.ts"; import { ModuleBase } from "../mod.ts"; import { buildTaskGraph, execTask, type TaskGraph } from "./exec.ts"; import { Blackboard } from "../../host/types.ts"; import { getTasksCtx } from "./inter.ts"; +import { CliCommand } from "../../src/deno_systems/types.ts"; export type TasksCtx = { config: TasksModuleConfigX; @@ -21,9 +22,8 @@ const lockValidator = zod.object({ }); type TasksLockEnt = zod.infer; -export class TasksModule extends ModuleBase { - processManifest( - gcx: GhjkCtx, +export class TasksModule extends ModuleBase { + loadConfig( manifest: ModuleManifest, bb: Blackboard, _lockEnt: TasksLockEnt | undefined, @@ -40,78 +40,69 @@ export class TasksModule extends ModuleBase { validators.tasksModuleConfig.safeParse(manifest.config), ); - const taskGraph = buildTaskGraph(gcx, config); + const taskGraph = buildTaskGraph(this.gcx, config); - const tasksCtx = getTasksCtx(gcx); - tasksCtx.config = config; - tasksCtx.taskGraph = taskGraph; - - return tasksCtx; + const tcx = getTasksCtx(this.gcx); + tcx.config = config; + tcx.taskGraph = taskGraph; } - commands( - gcx: GhjkCtx, - tcx: TasksCtx, - ) { - const namedSet = new Set(tcx.config.tasksNamed); - const commands = Object.keys(tcx.config.tasks) - .sort() - .map( - (key) => { - const def = tcx.config.tasks[key]; - const cmd = new cliffy_cmd.Command() - .name(key) - .useRawArgs() - .action(async (_, ...args) => { - await execTask( - gcx, - tcx.config, - tcx.taskGraph, - key, - args, - ); - }); - if (def.desc) { - cmd.description(def.desc); - } - if (!namedSet.has(key)) { - cmd.hidden(); - } - return cmd; - }, - ); - const root = new cliffy_cmd.Command() - .alias("x") - .action(function () { - this.showHelp(); - }) - .description(`Tasks module. + override commands() { + const gcx = this.gcx; + const tcx = getTasksCtx(this.gcx); -The named tasks in your ghjkfile will be listed here.`); - for (const cmd of commands) { - root.command(cmd.getName(), cmd); - } - return { - tasks: root, - }; + const namedSet = new Set(tcx.config.tasksNamed); + const out: CliCommand[] = [{ + name: "tasks", + visible_aliases: ["x"], + about: "Tasks module, execute your task programs.", + before_long_help: "The named tasks in your ghjkfile will be listed here.", + disable_help_subcommand: true, + sub_commands: [ + ...Object.keys(tcx.config.tasks) + .sort() + .map( + (key) => { + const def = tcx.config.tasks[key]; + return { + name: key, + about: def.desc, + hide: !namedSet.has(key), + args: { + raw: { + value_name: "TASK ARGS", + trailing_var_arg: true, + allow_hyphen_values: true, + action: "Append", + }, + }, + action: async ({ args: { raw } }) => { + await execTask( + gcx, + tcx.config, + tcx.taskGraph, + key, + (raw as string[]) ?? [], + ); + }, + } as CliCommand; + }, + ), + ], + }]; + return out; } - loadLockEntry( - _gcx: GhjkCtx, - raw: Json, - ) { + loadLockEntry(raw: Json) { const entry = lockValidator.parse(raw); if (entry.version != "0") { - throw new Error(`unexepected version tag deserializing lockEntry`); + throw new Error(`unexpected version tag deserializing lockEntry`); } return entry; } - genLockEntry( - _gcx: GhjkCtx, - _tcx: TasksCtx, - ) { + genLockEntry() { return { version: "0", }; diff --git a/modules/types.ts b/modules/types.ts index f1c23ced..561fa2b8 100644 --- a/modules/types.ts +++ b/modules/types.ts @@ -16,7 +16,7 @@ export type ModuleManifest = zod.infer; export type GhjkCtx = { ghjkfilePath?: Path; ghjkDir: Path; - ghjkShareDir: Path; + ghjkDataDir: Path; blackboard: Map; }; diff --git a/ports/asdf.ts b/ports/asdf.ts index c0bfd14e..dff7a474 100644 --- a/ports/asdf.ts +++ b/ports/asdf.ts @@ -124,6 +124,7 @@ export class Port extends PortBase { return; } const conf = confValidator.parse(args.config); + await $.path(args.downloadPath).ensureDir(); await $`${binPath}` .env({ ...pathsWithDepArts(args.depArts, args.platform.os), @@ -136,6 +137,7 @@ export class Port extends PortBase { } override async install(args: InstallArgs) { const conf = confValidator.parse(args.config); + await $.path(args.installPath).ensureDir(); await $`${ depExecShimPath(std_ports.asdf_plugin_git, "install", args.depArts) }` diff --git a/ports/cmake.ts b/ports/cmake.ts deleted file mode 100644 index 979bc722..00000000 --- a/ports/cmake.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { InstallConfigFat, InstallConfigSimple } from "../port.ts"; -import { AsdfInstallConf } from "./asdf.ts"; -import { PipiInstallConf } from "./pipi.ts"; -import * as ports from "./mod.ts"; - -/** - * Port to install cmake - * - * For macOS users, you need to add python as allowed build dependencies - * as cmake is downladed via pip install. - * - * For other platforms, the `asdf_plugin_git` build dependency is required. - * - * Set the `enableRuntimes` flag to setup both cases. - * - * ```typescript - * ghjk.config({ - * enableRuntimes: true, - * }); - * - * ghjk.install(ports.cmake()); - * ``` - */ -export default function conf( - config: InstallConfigSimple = {}, -): InstallConfigFat[] { - /* - The universal macOS cmake build downloaded by asdf crashes - due to security restrictions in macOS, so it's installed using pipi port instead, which runs with no problems. - */ - if (Deno.build.os === "darwin") { - const pipiConfig: PipiInstallConf = { - packageName: "cmake", - version: config.version, - }; - return ports.pipi(pipiConfig); - } - const asdfConfig: AsdfInstallConf = { - ...config, - pluginRepo: "https://github.com/asdf-community/asdf-cmake", - installType: "version", - version: config.version, - }; - - return [ports.asdf(asdfConfig)]; -} diff --git a/ports/infisical.ts b/ports/infisical.ts index 917df6b6..f44bda5f 100644 --- a/ports/infisical.ts +++ b/ports/infisical.ts @@ -39,7 +39,7 @@ export class Port extends GithubReleasePort { repoOwner = "Infisical"; repoName = "infisical"; - async listAll(args: ListAllArgs) { + override async listAll(args: ListAllArgs) { const all = await super.listAll(args); return all.map((str) => str.replace(/^infisical-cli\/v/, "")); } diff --git a/ports/mod.ts b/ports/mod.ts index 4b23bed8..b9782418 100644 --- a/ports/mod.ts +++ b/ports/mod.ts @@ -3,7 +3,6 @@ export { default as asdf } from "./asdf.ts"; export { default as asdf_plugin_git } from "./asdf_plugin_git.ts"; export { default as cargo_binstall } from "./cargo-binstall.ts"; export { default as cargobi } from "./cargobi.ts"; -export { default as cmake } from "./cmake.ts"; export { default as cpy_bs } from "./cpy_bs.ts"; export { default as curl } from "./curl.ts"; export { default as deno_ghrel } from "./deno_ghrel.ts"; diff --git a/ports/poetry.ts b/ports/poetry.ts index b28de019..653605cd 100644 --- a/ports/poetry.ts +++ b/ports/poetry.ts @@ -49,7 +49,7 @@ const toPipiConfig = (config: InstallConfigLiteX) => ({ }); export class Port extends PipiPort { - listAll(args: ListAllArgs) { + override listAll(args: ListAllArgs) { return super.listAll({ ...args, config: toPipiConfig(args.config) }); } @@ -64,7 +64,7 @@ export class Port extends PipiPort { return super.download({ ...args, config: toPipiConfig(args.config) }); } - install(args: InstallArgs) { + override install(args: InstallArgs) { return super.install({ ...args, config: toPipiConfig(args.config) }); } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..762d4cf1 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +# NOTE: to change this, change the const RUST_VERSION in ghjk.ts and +# then use the lock-sed task +channel = "1.82.0" +components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown", "wasm32-wasi"] diff --git a/scripts/check.ts b/scripts/check.ts deleted file mode 100755 index dcc56fea..00000000 --- a/scripts/check.ts +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/env -S ghjk deno run --allow-env --allow-run --allow-read --allow-write=. - -import "../setup_logger.ts"; -import { $ } from "../utils/mod.ts"; - -const files = (await Array.fromAsync( - $.path(import.meta.url).parentOrThrow().expandGlob("**/*.ts", { - exclude: [ - ".git", - ".dev", - "play.ts", - ".ghjk/**", - ".deno-dir/**", - "vendor/**", - ".git/**", // was throwing an error without this - ], - }), -)).map((ref) => ref.path.toString()); - -await $`${Deno.env.get("DENO_EXEC_PATH") ?? "deno"} check ${files}`; diff --git a/src/deno_systems/bindings.ts b/src/deno_systems/bindings.ts new file mode 100644 index 00000000..d1f58b70 --- /dev/null +++ b/src/deno_systems/bindings.ts @@ -0,0 +1,176 @@ +// NOTE: this mechanism is currently offline for deno systems +// we just +// +// we catch all rejections and explicityly dispatch them to the host +// to avoid shutting down the event loop on uncaught errors +globalThis.addEventListener("unhandledrejection", (evt) => { + let reason = evt.reason; + if (reason instanceof Error) { + reason = reason.stack; + } + if (Ghjk.dispatchException(reason)) { + evt.preventDefault(); + } +}); + +// start an interval to prevent the event loop exiting +// after loading systems +setInterval(() => {/* beat */}, 1000); + +// import "../../src/ghjk/js/mock.sfx.ts"; +import { zod } from "../../deps/common.ts"; +import { $, unwrapZodRes } from "../../utils/mod.ts"; +import type { GhjkCtx, ModuleManifest } from "../../modules/types.ts"; +import type { ModuleBase } from "../../modules/mod.ts"; +import type { Blackboard } from "../../host/types.ts"; +import { Ghjk, Json } from "../ghjk/js/runtime.js"; + +import type { + CliCommand, + CliCommandBindedX, + DenoSystemsRoot, +} from "./types.ts"; +import bindingTypes from "./types.ts"; + +// FIXME: better means of exit detection, keep alive as long +// as callbacks are registered? +// globalThis.onbeforeunload = (evt) => { +// evt.preventDefault(); +// }; + +const prepareArgs = zod.object({ + uri: zod.string(), + config: zod.object({ + ghjkfile: zod.string().optional(), + ghjkdir: zod.string(), + data_dir: zod.string(), + deno_lockfile: zod.string().optional(), + repo_root: zod.string(), + deno_dir: zod.string(), + }), +}); + +const args = prepareArgs.parse(Ghjk.blackboard.get("args")); +await prepareSystems(args); + +async function prepareSystems(args: zod.infer) { + const gcx = { + ghjkDir: $.path(args.config.ghjkdir), + ghjkDataDir: $.path(args.config.data_dir), + ghjkfilePath: args.config.ghjkfile + ? $.path(args.config.ghjkfile) + : undefined, + blackboard: new Map(), + } satisfies GhjkCtx; + + const { default: mod } = await import(args.uri); + const { systems } = unwrapZodRes( + bindingTypes.denoSystemsRoot.safeParse(mod), + ) as DenoSystemsRoot; + + const manifests = [] as ManifestDesc[]; + + for (const [id, ctorFn] of Object.entries(systems)) { + manifests.push({ + id, + ctor_cb_key: Ghjk.callbacks.set( + `sys_ctor_${id}_${crypto.randomUUID()}`, + () => { + const instance = ctorFn(gcx); + return instanceBinding(gcx, id, instance); + }, + ), + }); + } + await Ghjk.hostcall("register_systems", manifests); +} + +type ManifestDesc = { + id: string; + ctor_cb_key: string; +}; + +type InstanceDesc = { + load_lock_entry_cb_key: string; + gen_lock_entry_cb_key: string; + load_config_cb_key: string; + cli_commands_cb_key: string; +}; + +function instanceBinding( + gcx: GhjkCtx, + sys_id: string, + instance: ModuleBase, +) { + const instanceId = crypto.randomUUID(); + type State = { + stateKey: string; + }; + return { + load_config_cb_key: Ghjk.callbacks.set( + `sys_load_config_${instanceId}`, + async (args: Json) => { + const { config, bb, state: stateRaw } = args as { + config: ModuleManifest; + bb: Blackboard; + state?: State; + }; + const state = stateRaw?.stateKey + ? gcx.blackboard.get(stateRaw?.stateKey) + : undefined; + await instance.loadConfig({ id: sys_id, config }, bb, state); + return null; + }, + ), + load_lock_entry_cb_key: Ghjk.callbacks.set( + `sys_load_lock_entry_${instanceId}`, + async (args: Json) => { + const { raw } = args as any; + const state = await instance.loadLockEntry(raw); + const stateKey = `sys_state_${instanceId}`; + gcx.blackboard.set(stateKey, state); + return { + stateKey, + } satisfies State; + }, + ), + gen_lock_entry_cb_key: Ghjk.callbacks.set( + `sys_gen_lock_entry_${instanceId}`, + () => { + return instance.genLockEntry(); + }, + ), + cli_commands_cb_key: Ghjk.callbacks.set( + `sys_cli_commands_${instanceId}`, + (_) => { + const commandsRaw = instance.commands(); + return commandsRaw.map((cmd) => + commandBinding(cmd) as CliCommandBindedX + ); + }, + ), + } satisfies InstanceDesc; +} + +function commandBinding(commandRaw: CliCommand): CliCommandBindedX { + const { action, sub_commands, ...command } = bindingTypes.cliCommand.parse( + commandRaw, + ); + const actionId = crypto.randomUUID(); + return { + ...command, + sub_commands: sub_commands + ? sub_commands.map((cmd) => commandBinding(cmd)) + : undefined, + action_cb_key: action + ? Ghjk.callbacks.set( + `sys_cli_command_action_${command.name}_${actionId}`, + async (args) => { + const actionArgs = bindingTypes.cliActionArgs.parse(args); + await action(actionArgs); + return {}; + }, + ) + : undefined, + } satisfies CliCommandBindedX; +} diff --git a/src/deno_systems/mod.ts b/src/deno_systems/mod.ts new file mode 100644 index 00000000..92e45319 --- /dev/null +++ b/src/deno_systems/mod.ts @@ -0,0 +1,10 @@ +import { map } from "../../modules/std.ts"; +import type { DenoSystemsRoot } from "./types.ts"; + +export default { + systems: Object.fromEntries( + Object.entries(map).map( + ([id, sys]) => [id, (gcx) => new sys.ctor(gcx)], + ), + ), +} satisfies DenoSystemsRoot; diff --git a/src/deno_systems/types.ts b/src/deno_systems/types.ts new file mode 100644 index 00000000..85b0e178 --- /dev/null +++ b/src/deno_systems/types.ts @@ -0,0 +1,145 @@ +import { zod } from "../../deps/common.ts"; +import type { GhjkCtx } from "../../modules/types.ts"; +import type { ModuleBase } from "../../modules/mod.ts"; + +const denoSystemsRoot = zod.object({ + systems: zod.record(zod.function()), +}); + +const charSchema = zod.string().length(1); + +const cliArg = zod.object({ + value_name: zod.string().optional(), + value_hint: zod.enum([ + "Unknown", + "Other", + "AnyPath", + "FilePath", + "DirPath", + "ExecutablePath", + "CommandName", + "CommandString", + // "CommandWithArguments", + "Username", + "Hostname", + "Url", + "EmailAddress", + ]).optional(), + + action: zod.enum([ + "Set", + "Append", + "SetTrue", + "SetFalse", + "Count", + "Help", + "HelpShort", + "HelpLong", + "Version", + ]).optional(), + + required: zod.boolean().optional(), + global: zod.boolean().optional(), + hide: zod.boolean().optional(), + exclusive: zod.boolean().optional(), + trailing_var_arg: zod.boolean().optional(), + + env: zod.string().optional(), + + help: zod.string().optional(), + long_help: zod.string().optional(), +}); + +const cliFlag = cliArg.extend({ + long: zod.string().optional(), + long_aliases: zod.string().array().optional(), + visible_long_aliases: zod.string().array().optional(), + + short: charSchema.optional(), + short_aliases: charSchema.array().optional(), + visible_short_aliases: charSchema.array().optional(), +}); + +const cliCommandBase = zod.object({ + name: zod.string(), + + aliases: zod.string().array().optional(), + visible_aliases: zod.string().array().optional(), + + hide: zod.boolean().optional(), + disable_help_subcommand: zod.boolean().optional(), + + about: zod.string().optional(), + before_help: zod.string().optional(), + before_long_help: zod.string().optional(), + + args: zod.record(cliArg).optional(), + flags: zod.record(cliFlag).optional(), +}); + +const flagsAndArgs = zod.record( + zod.union([ + zod.string(), + zod.string().array(), + zod.number(), + zod.boolean(), + ]).optional(), +); + +const cliActionArgs = zod.object({ + flags: flagsAndArgs, + args: flagsAndArgs, +}); + +const cliCommandActionBase = cliCommandBase.extend({ + action: zod.function() + .args(cliActionArgs) + .returns(zod.union([zod.promise(zod.void()), zod.void()])).optional(), +}); + +const cliCommandBindedBase = cliCommandBase.extend({ + action_cb_key: zod.string().optional(), +}); + +const cliCommand: zod.ZodType = cliCommandActionBase.extend({ + sub_commands: zod.lazy(() => zod.array(cliCommand).optional()), +}); + +const cliCommandBinded: zod.ZodType = cliCommandBindedBase + .extend({ + sub_commands: zod.lazy(() => zod.array(cliCommandBinded).optional()), + }); + +type DenoSystemCtor = (gcx: GhjkCtx) => ModuleBase; + +export type DenoSystemsRoot = { + systems: Record; +}; + +export type CliCommand = zod.input & { + sub_commands?: CliCommand[]; +}; +export type CliCommandX = zod.infer & { + sub_commands?: CliCommandX[]; +}; + +export type CliCommandBinded = zod.input & { + sub_commands?: CliCommandBinded[]; +}; +export type CliCommandBindedX = zod.infer & { + sub_commands?: CliCommandBindedX[]; +}; + +export type CliFlag = zod.input; +export type CliFlagX = zod.infer; + +export type CliArg = zod.input; +export type CliArgX = zod.infer; + +export default { + denoSystemsRoot, + cliFlag, + cliArg, + cliCommand, + cliActionArgs, +}; diff --git a/src/denort/Cargo.toml b/src/denort/Cargo.toml new file mode 100644 index 00000000..54c4a0cd --- /dev/null +++ b/src/denort/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "denort" +version.workspace = true +edition.workspace = true + +[lib] +path = "lib.rs" + +[dependencies] +tracing-unwrap.workspace = true + +educe.workspace = true + +color-eyre.workspace = true +anyhow.workspace = true + +tracing.workspace = true +tracing-subscriber.workspace = true + +deno.workspace = true + +tokio.workspace = true diff --git a/src/denort/lib.rs b/src/denort/lib.rs new file mode 100644 index 00000000..3706ef1f --- /dev/null +++ b/src/denort/lib.rs @@ -0,0 +1,327 @@ +#![allow(clippy::let_and_return)] + +pub use deno; + +pub mod macros; +pub mod promises; +pub mod unsync; +pub mod worker; + +#[allow(unused)] +mod interlude { + pub use std::future::Future; + pub use std::path::{Path, PathBuf}; + pub use std::sync::Arc; + + pub use color_eyre::eyre; + pub use deno::deno_runtime::{ + self, + deno_core::{self, v8}, + }; + pub use eyre::{format_err as ferr, Context, Result as Res, WrapErr}; + pub use tracing::{debug, error, info, trace, warn, Instrument}; + pub use tracing_unwrap::*; +} +use crate::interlude::*; + +use deno::deno_runtime::{ + deno_core::{futures::FutureExt, unsync::JoinHandle, ModuleSpecifier}, + deno_permissions, + tokio_util::create_and_run_current_thread_with_maybe_metrics, +}; + +#[rustfmt::skip] +use deno_runtime::deno_core as deno_core; // necessary for re-exported macros to work + +const DEFAULT_UNSTABLE_FLAGS: &[&str] = &["worker-options", "kv" /* "net", "http" */]; + +/// This must be called on the main thread as early as possible +/// or one will encounter stack overflows and segmentation faults +pub fn init() { + deno::util::v8::init_v8_flags(&[], &[], deno::util::v8::get_v8_flags_from_env()); + // The stack will blow on debug builds unless we increase the size + if cfg!(debug_assertions) { + // We must do this early before any new threads are started + // since std::thread might cache RUST_MIN_STACK once it's read this env + if std::env::var("RUST_MIN_STACK").is_err() { + std::env::set_var("RUST_MIN_STACK", "8388608"); + } + }; +} + +/// Ensure that the subcommand runs in a task, rather than being directly executed. Since some of these +/// futures are very large, this prevents the stack from getting blown out from passing them by value up +/// the callchain (especially in debug mode when Rust doesn't have a chance to elide copies!). +#[inline(always)] +fn spawn_subcommand + 'static>(f: F) -> JoinHandle<()> { + // the boxed_local() is important in order to get windows to not blow the stack in debug + deno_core::unsync::spawn(f.boxed_local()) +} +pub fn run_sync( + main_mod: ModuleSpecifier, + config_file: Option, + permissions: deno::args::PermissionFlags, + custom_extensions: Arc, +) { + new_thread_builder() + .spawn(|| { + create_and_run_current_thread_with_maybe_metrics(async move { + spawn_subcommand(async move { + run(main_mod, config_file, permissions, custom_extensions) + .await + .unwrap() + }) + .await + .unwrap() + }) + }) + .unwrap() + .join() + .unwrap(); +} + +pub async fn run( + main_module: ModuleSpecifier, + config_file: Option, + permissions: deno::args::PermissionFlags, + custom_extensions: Arc, +) -> anyhow::Result<()> { + // NOTE: avoid using the Run subcommand + // as it breaks our custom_extensions patch for some reason + let flags = deno::args::Flags { + permissions, + unstable_config: deno::args::UnstableConfig { + features: DEFAULT_UNSTABLE_FLAGS + .iter() + .copied() + .map(String::from) + .collect(), + ..Default::default() + }, + config_flag: if let Some(config_file) = config_file { + deno::args::ConfigFlag::Path(config_file) + } else { + Default::default() + }, + ..Default::default() + }; + + let flags = Arc::new(flags); + + let cli_factory = + deno::factory::CliFactory::from_flags(flags).with_custom_ext_cb(custom_extensions); + + let worker_factory = cli_factory.create_cli_main_worker_factory().await?; + + let mut worker = worker_factory + .create_main_worker(deno_runtime::WorkerExecutionMode::Run, main_module) + .await?; + tracing::info!("running worker"); + let exit_code = worker.run().await?; + println!("exit_code: {exit_code}"); + + Ok(()) +} + +pub fn test_sync( + files: deno::deno_config::glob::FilePatterns, + config_file: PathBuf, + permissions: deno::args::PermissionFlags, + coverage_dir: Option, + filter: Option, + custom_extensions: Arc, + argv: Vec, +) { + new_thread_builder() + .spawn(|| { + create_and_run_current_thread_with_maybe_metrics(async move { + spawn_subcommand(async move { + test( + files, + config_file, + permissions, + coverage_dir, + filter, + custom_extensions, + argv, + ) + .await + .unwrap() + }) + .await + .unwrap() + }) + }) + .unwrap() + .join() + .unwrap(); +} + +pub async fn test( + files: deno::deno_config::glob::FilePatterns, + config_file: PathBuf, + permissions: deno::args::PermissionFlags, + coverage_dir: Option, + filter: Option, + custom_extensions: Arc, + argv: Vec, +) -> anyhow::Result<()> { + use deno::tools::test::*; + + deno_permissions::set_prompt_callbacks( + Box::new(deno::util::draw_thread::DrawThread::hide), + Box::new(deno::util::draw_thread::DrawThread::show), + ); + let pattern_to_str = |pattern| match pattern { + deno::deno_config::glob::PathOrPattern::Path(path) => path.to_string_lossy().to_string(), + deno::deno_config::glob::PathOrPattern::Pattern(pattern) => pattern.as_str().to_string(), + deno::deno_config::glob::PathOrPattern::RemoteUrl(url) => url.as_str().to_owned(), + deno::deno_config::glob::PathOrPattern::NegatedPath(path) => { + path.to_string_lossy().to_string() + } + }; + + let test_flags = deno::args::TestFlags { + files: deno::args::FileFlags { + include: files + .include + .clone() + .map(|set| set.into_path_or_patterns().into_iter()) + .unwrap_or_default() + .map(pattern_to_str) + .collect(), + ignore: files + .exclude + .clone() + .into_path_or_patterns() + .into_iter() + .map(pattern_to_str) + .collect(), + }, + doc: true, + trace_leaks: true, + coverage_dir, + filter, + concurrent_jobs: std::thread::available_parallelism().ok(), + ..Default::default() + }; + let flags = deno::args::Flags { + permissions, + unstable_config: deno::args::UnstableConfig { + features: DEFAULT_UNSTABLE_FLAGS + .iter() + .copied() + .map(String::from) + .collect(), + ..Default::default() + }, + type_check_mode: deno::args::TypeCheckMode::Local, + config_flag: deno::args::ConfigFlag::Path(config_file.to_string_lossy().into()), + argv, + subcommand: deno::args::DenoSubcommand::Test(test_flags.clone()), + ..Default::default() + }; + + let flags = Arc::new(flags); + + let cli_factory = + deno::factory::CliFactory::from_flags(flags).with_custom_ext_cb(custom_extensions); + + let options = cli_factory.cli_options()?.clone(); + + let test_options = deno::args::WorkspaceTestOptions { + // files, + ..options.resolve_workspace_test_options(&test_flags) + }; + let members_with_test_opts = options.resolve_test_options_for_members(&test_flags)?; + let file_fetcher = cli_factory.file_fetcher()?; + + let specifiers_with_mode = fetch_specifiers_with_test_mode( + options.as_ref(), + file_fetcher, + members_with_test_opts + .into_iter() + .map(|(_, opts)| opts.files), + &test_options.doc, + ) + .await?; + + if !test_options.permit_no_files && specifiers_with_mode.is_empty() { + return Err(deno_core::error::generic_error("No test modules found")); + } + let doc_tests = get_doc_tests(&specifiers_with_mode, file_fetcher).await?; + let specifiers_for_typecheck_and_test = get_target_specifiers(specifiers_with_mode, &doc_tests); + for doc_test in doc_tests { + file_fetcher.insert_memory_files(doc_test); + } + + let main_graph_container = cli_factory.main_module_graph_container().await?; + + // type check + main_graph_container + .check_specifiers( + &specifiers_for_typecheck_and_test, + options.ext_flag().as_ref(), + ) + .await?; + + if test_options.no_run { + return Ok(()); + } + + let worker_factory = cli_factory.create_cli_main_worker_factory().await?; + let worker_factory = Arc::new(worker_factory); + + // Various test files should not share the same permissions in terms of + // `PermissionsContainer` - otherwise granting/revoking permissions in one + // file would have impact on other files, which is undesirable. + let desc_parser = &cli_factory.permission_desc_parser()?; + let permissions = deno_permissions::Permissions::from_options( + desc_parser.as_ref(), + &options.permissions_options(), + )?; + + // run tests + test_specifiers( + worker_factory, + &permissions, + desc_parser, + specifiers_for_typecheck_and_test, + TestSpecifiersOptions { + cwd: deno_core::url::Url::from_directory_path(options.initial_cwd()).map_err(|_| { + anyhow::anyhow!( + "Unable to construct URL from the path of cwd: {}", + options.initial_cwd().to_string_lossy(), + ) + })?, + concurrent_jobs: test_options.concurrent_jobs, + fail_fast: test_options.fail_fast, + log_level: options.log_level(), + filter: test_options.filter.is_some(), + reporter: test_options.reporter, + junit_path: test_options.junit_path, + specifier: TestSpecifierOptions { + filter: TestFilter::from_flag(&test_options.filter), + shuffle: test_options.shuffle, + trace_leaks: test_options.trace_leaks, + }, + hide_stacktraces: true, + }, + ) + .await?; + + Ok(()) +} + +pub fn new_thread_builder() -> std::thread::Builder { + let builder = std::thread::Builder::new(); + let builder = if cfg!(debug_assertions) { + // deno & swc need 8 MiB with dev profile (release is ok) + // https://github.com/swc-project/swc/blob/main/CONTRIBUTING.md + builder.stack_size(8 * 1024 * 1024) + } else { + // leave default: https://doc.rust-lang.org/std/thread/#stack-size + builder + }; + builder +} diff --git a/src/denort/macros.rs b/src/denort/macros.rs new file mode 100644 index 00000000..a798aa4e --- /dev/null +++ b/src/denort/macros.rs @@ -0,0 +1,16 @@ +// Conversion that preserves source chain +// but not backtraces. +// This can be made a funciton but we have to +// depend on anyhow directly to be able to refer +// to it's Error type. +// https://github.com/eyre-rs/eyre/issues/31 +#[macro_export] +macro_rules! anyhow_to_eyre { + () => { + |err| { + eyre::format_err!(Box::::from( + err + )) + } + }; +} diff --git a/src/denort/promises.rs b/src/denort/promises.rs new file mode 100644 index 00000000..ade0ae45 --- /dev/null +++ b/src/denort/promises.rs @@ -0,0 +1,71 @@ +use crate::interlude::*; + +// Lifted from deno_core 0.318.0 +/* +MIT License + +Copyright 2018-2024 the Deno authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +/// Wrap a promise with `then` handlers allowing us to watch the resolution progress from a Rust closure. +/// This has a side-effect of preventing unhandled rejection handlers from triggering. If that is +/// desired, the final handler may choose to rethrow the exception. +pub fn watch_promise<'s, F>( + scope: &mut v8::HandleScope<'s>, + promise: v8::Local<'s, v8::Promise>, + f: F, +) -> Option> +where + F: FnOnce( + &mut v8::HandleScope, + v8::ReturnValue, + Result, v8::Local>, + ) + 'static, +{ + let external = v8::External::new(scope, Box::into_raw(Box::new(Some(f))) as _); + + fn get_handler(external: v8::Local) -> F { + unsafe { Box::>::from_raw(external.value() as _) } + .take() + .unwrap() + } + let on_fulfilled = + |scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, rv: v8::ReturnValue| { + let data = v8::Local::::try_from(args.data()).unwrap(); + let f = get_handler::(data); + f(scope, rv, Ok(args.get(0))); + }; + let on_fulfilled = v8::Function::builder(on_fulfilled) + .data(external.into()) + .build(scope); + + let on_rejected = + |scope: &mut v8::HandleScope, args: v8::FunctionCallbackArguments, rv: v8::ReturnValue| { + let data = v8::Local::::try_from(args.data()).unwrap(); + let f = get_handler::(data); + f(scope, rv, Err(args.get(0))); + }; + let on_rejected = v8::Function::builder(on_rejected) + .data(external.into()) + .build(scope); + // function builders will return None if the runtime is shutting down + let (Some(on_fulfilled), Some(on_rejected)) = (on_fulfilled, on_rejected) else { + _ = get_handler::(external); + return None; + }; + + // then2 will return None if the runtime is shutting down + let Some(promise) = promise.then2(scope, on_fulfilled, on_rejected) else { + _ = get_handler::(external); + return None; + }; + + Some(promise) +} diff --git a/src/denort/unsync.rs b/src/denort/unsync.rs new file mode 100644 index 00000000..0a3acacf --- /dev/null +++ b/src/denort/unsync.rs @@ -0,0 +1,280 @@ +// Modified from https://github.com/denoland/deno_unsync/blob/503a3fcb82235a591a98b497c8d26be5772c6dc9/src/tokio/task.rs +// Copyright 2018-2024 the Deno authors. MIT license. + +use core::pin::Pin; +use core::task::Context; +use core::task::Poll; +use std::future::Future; +use std::marker::PhantomData; +use tokio::runtime::Handle; +use tokio::runtime::RuntimeFlavor; + +/// Equivalent to [`tokio::task::JoinHandle`]. +#[repr(transparent)] +pub struct JoinHandle { + handle: tokio::task::JoinHandle>, + _r: PhantomData, +} + +impl JoinHandle { + /// Equivalent to [`tokio::task::JoinHandle::abort`]. + pub fn abort(&self) { + self.handle.abort() + } + + pub fn abort_handle(&self) -> tokio::task::AbortHandle { + self.handle.abort_handle() + } +} + +impl Future for JoinHandle { + type Output = Result; + + fn poll( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + // SAFETY: We are sure that handle is valid here + unsafe { + let me: &mut Self = Pin::into_inner_unchecked(self); + let handle = Pin::new_unchecked(&mut me.handle); + match handle.poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(Ok(r)) => Poll::Ready(Ok(r.into_inner())), + Poll::Ready(Err(e)) => Poll::Ready(Err(e)), + } + } + } +} + +/// Equivalent to [`tokio::task::spawn`], but does not require the future to be [`Send`]. Must only be +/// used on a [`RuntimeFlavor::CurrentThread`] executor, though this is only checked when running with +/// debug assertions. +#[inline(always)] +pub fn spawn + 'static, R: 'static>(name: &str, f: F) -> JoinHandle { + debug_assert!(Handle::current().runtime_flavor() == RuntimeFlavor::CurrentThread); + // SAFETY: we know this is a current-thread executor + let future = unsafe { MaskFutureAsSend::new(f) }; + JoinHandle { + handle: tokio::task::Builder::new() + .name(name) + .spawn(future) + .expect("tokio error"), + _r: Default::default(), + } +} + +/// Equivalent to [`tokio::task::spawn_blocking`]. Currently a thin wrapper around the tokio API, but this +/// may change in the future. +#[inline(always)] +pub fn spawn_blocking R) + Send + 'static, R: Send + 'static>( + name: &str, + f: F, +) -> JoinHandle { + let handle = tokio::task::Builder::new() + .name(name) + .spawn_blocking(|| MaskResultAsSend { result: f() }) + .expect("tokio error"); + JoinHandle { + handle, + _r: Default::default(), + } +} + +#[repr(transparent)] +#[doc(hidden)] +pub struct MaskResultAsSend { + result: R, +} + +/// SAFETY: We ensure that Send bounds are only faked when tokio is running on a current-thread executor +unsafe impl Send for MaskResultAsSend {} + +impl MaskResultAsSend { + #[inline(always)] + pub fn into_inner(self) -> R { + self.result + } +} + +#[repr(transparent)] +pub struct MaskFutureAsSend { + future: F, +} + +impl MaskFutureAsSend { + /// Mark a non-`Send` future as `Send`. This is a trick to be able to use + /// `tokio::spawn()` (which requires `Send` futures) in a current thread + /// runtime. + /// + /// # Safety + /// + /// You must ensure that the future is actually used on the same + /// thread, ie. always use current thread runtime flavor from Tokio. + #[inline(always)] + pub unsafe fn new(future: F) -> Self { + Self { future } + } +} + +// SAFETY: we are cheating here - this struct is NOT really Send, +// but we need to mark it Send so that we can use `spawn()` in Tokio. +unsafe impl Send for MaskFutureAsSend {} + +impl Future for MaskFutureAsSend { + type Output = MaskResultAsSend; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + // SAFETY: We are sure that future is valid here + unsafe { + let me: &mut MaskFutureAsSend = Pin::into_inner_unchecked(self); + let future = Pin::new_unchecked(&mut me.future); + match future.poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(result) => Poll::Ready(MaskResultAsSend { result }), + } + } + } +} + +// Copied from https://github.com/denoland/deno_unsync/blob/503a3fcb82235a591a98b497c8d26be5772c6dc9/src/tokio/joinset.rs +// Copyright 2018-2024 the Deno authors. MIT license. +// Some code and comments under MIT license where adapted from Tokio code +// Copyright (c) 2023 Tokio Contributors + +use std::task::Waker; +use tokio::task::AbortHandle; +use tokio::task::JoinError; + +/// Wraps the tokio [`JoinSet`] to make it !Send-friendly and to make it easier and safer for us to +/// poll while empty. +pub struct JoinSet { + joinset: tokio::task::JoinSet>, + /// If join_next returns Ready(None), we stash the waker + waker: Option, +} + +impl Default for JoinSet { + fn default() -> Self { + Self { + joinset: Default::default(), + waker: None, + } + } +} + +impl JoinSet { + /// Spawn the provided task on the `JoinSet`, returning an [`AbortHandle`] + /// that can be used to remotely cancel the task. + /// + /// The provided future will start running in the background immediately + /// when this method is called, even if you don't await anything on this + /// `JoinSet`. + /// + /// # Panics + /// + /// This method panics if called outside of a Tokio runtime. + /// + /// [`AbortHandle`]: tokio::task::AbortHandle + #[track_caller] + pub fn spawn(&mut self, task: F) -> AbortHandle + where + F: Future, + F: 'static, + T: 'static, + { + // SAFETY: We only use this with the single-thread executor + let handle = self.joinset.spawn(unsafe { MaskFutureAsSend::new(task) }); + + // If someone had called poll_join_next while we were empty, ask them to poll again + // so we can properly register the waker with the underlying JoinSet. + if let Some(waker) = self.waker.take() { + waker.wake(); + } + handle + } + + #[track_caller] + pub fn spawn_named(&mut self, name: &str, task: F) -> AbortHandle + where + F: Future, + F: 'static, + T: 'static, + { + // SAFETY: We only use this with the single-thread executor + let handle = self + .joinset + .build_task() + .name(name) + .spawn(unsafe { MaskFutureAsSend::new(task) }) + .expect("tokio error"); + + // If someone had called poll_join_next while we were empty, ask them to poll again + // so we can properly register the waker with the underlying JoinSet. + if let Some(waker) = self.waker.take() { + waker.wake(); + } + handle + } + + /// Returns the number of tasks currently in the `JoinSet`. + pub fn len(&self) -> usize { + self.joinset.len() + } + + /// Returns whether the `JoinSet` is empty. + pub fn is_empty(&self) -> bool { + self.joinset.is_empty() + } + + /// Waits until one of the tasks in the set completes and returns its output. + /// + /// # Cancel Safety + /// + /// This method is cancel safe. If `join_next` is used as the event in a `tokio::select!` + /// statement and some other branch completes first, it is guaranteed that no tasks were + /// removed from this `JoinSet`. + pub fn poll_join_next(&mut self, cx: &mut Context) -> Poll> { + match self.joinset.poll_join_next(cx) { + Poll::Ready(Some(res)) => Poll::Ready(res.map(|res| res.into_inner())), + Poll::Ready(None) => { + // Stash waker + self.waker = Some(cx.waker().clone()); + Poll::Pending + } + Poll::Pending => Poll::Pending, + } + } + + /// Waits until one of the tasks in the set completes and returns its output. + /// + /// Returns `None` if the set is empty. + /// + /// # Cancel Safety + /// + /// This method is cancel safe. If `join_next` is used as the event in a `tokio::select!` + /// statement and some other branch completes first, it is guaranteed that no tasks were + /// removed from this `JoinSet`. + pub async fn join_next(&mut self) -> Option> { + self.joinset + .join_next() + .await + .map(|result| result.map(|res| res.into_inner())) + } + + /// Aborts all tasks on this `JoinSet`. + /// + /// This does not remove the tasks from the `JoinSet`. To wait for the tasks to complete + /// cancellation, you should call `join_next` in a loop until the `JoinSet` is empty. + pub fn abort_all(&mut self) { + self.joinset.abort_all(); + } + + /// Removes all tasks from this `JoinSet` without aborting them. + /// + /// The tasks removed by this call will continue to run in the background even if the `JoinSet` + /// is dropped. + pub fn detach_all(&mut self) { + self.joinset.detach_all(); + } +} diff --git a/src/denort/worker.rs b/src/denort/worker.rs new file mode 100644 index 00000000..c58fa855 --- /dev/null +++ b/src/denort/worker.rs @@ -0,0 +1,566 @@ +use crate::interlude::*; +use deno::{ + deno_runtime::{ + deno_core::{futures::FutureExt, ModuleSpecifier}, + deno_permissions, + }, + *, +}; + +// thread tag used for basic sanity checks +pub const WORKER_THREAD_NAME: &str = "denort-worker-thread"; + +/// This starts a new task to run all the work +/// that'll need to touch deno internals. +/// Deno is single threaded and this expects to run on single threaded runtimes. +/// +/// The returned handle will use channels internally to communicate to this worker. +pub async fn worker( + flags: deno::args::Flags, + custom_extensions_cb: Option>, +) -> Res { + let cx = WorkerContext::from_config(flags, custom_extensions_cb).await?; + + let (msg_tx, mut msg_rx) = tokio::sync::mpsc::channel::(32); + + let (term_signal_tx, term_signal_rx) = tokio::sync::watch::channel(false); + + let mut term_signal_rx2 = term_signal_rx.clone(); + let join_handle = crate::unsync::spawn( + "deno-worker", + async move { + let mut task_set = crate::unsync::JoinSet::default(); + trace!("starting deno worker"); + loop { + let msg = tokio::select! { + Some(msg) = msg_rx.recv() => { + msg + } + _ = term_signal_rx2.changed() => break, + else => break + }; + trace!(?msg, "deno worker msg"); + match msg { + DenoWorkerMsg::PrepareModule { + response_channel, + inner, + } => { + response_channel + .send( + module_worker(&cx, term_signal_rx2.clone(), inner, &mut task_set) + .await, + ) + .expect_or_log("channel error"); + } + } + } + // std::mem::forget(cx); + trace!("deno worker done"); + } + .instrument(tracing::trace_span!("deno-worker")), + ); + // let term_signal_tx = Arc::new(term_signal_tx); + let join_handle = Arc::new(std::sync::Mutex::new(Some(join_handle))); + Ok(DenoWorkerHandle { + sender: msg_tx, + term_signal_tx, + term_signal_rx, + join_handle, + }) +} + +type TermSignal = tokio::sync::watch::Receiver; + +async fn module_worker( + cx: &WorkerContext, + global_term_signal: TermSignal, + msg: PrepareModuleMsg, + task_set: &mut crate::unsync::JoinSet<()>, +) -> Res { + let mut module_cx = cx + .prepare_module( + msg.main_module.clone(), + &msg.permissions, + msg.mode, + msg.stdio, + msg.custom_extensions_cb, + ) + .await?; + + let (module_tx, mut module_rx) = tokio::sync::mpsc::channel::(1); + task_set.spawn_named( + &format!("deno-module-worker-{}", msg.main_module), + async move { + trace!("starting module worker"); + while let Some(msg) = module_rx.recv().await { + trace!(?msg, "module worker msg"); + match msg { + ModuleWorkerReq::Run { response_channel } => response_channel + .send(module_cx.run(global_term_signal.clone()).await) + .expect_or_log("channel error"), + ModuleWorkerReq::DriveTillExit { + term_signal, + response_channel, + } => response_channel + .send( + module_cx + .drive_till_exit(global_term_signal.clone(), term_signal) + .await + .map_err(crate::anyhow_to_eyre!()), + ) + .expect_or_log("channel error"), + ModuleWorkerReq::Execute { response_channel } => response_channel + .send( + module_cx + .execute_main_module() + .await + .map_err(crate::anyhow_to_eyre!()), + ) + .expect_or_log("channel error"), + ModuleWorkerReq::GetLoadedModules { response_channel } => response_channel + .send(module_cx.get_loaded_modules()) + .expect_or_log("channel error"), + } + } + // std::mem::forget(module_cx); + trace!("module worker done"); + } + .instrument(tracing::trace_span!( + "deno-module-worker", + main_module = %msg.main_module + )), + ); + Ok(ModuleWorkerHandle { sender: module_tx }) +} + +#[derive(educe::Educe)] +#[educe(Debug)] +struct WorkerContext { + #[educe(Debug(ignore))] + cli_factory: deno::factory::CliFactory, + #[educe(Debug(ignore))] + worker_factory: deno::worker::CliMainWorkerFactory, + #[educe(Debug(ignore))] + graph: Arc, +} + +impl WorkerContext { + async fn from_config( + flags: deno::args::Flags, + root_custom_extensions_cb: Option>, + ) -> Res { + deno_permissions::set_prompt_callbacks( + Box::new(util::draw_thread::DrawThread::hide), + Box::new(util::draw_thread::DrawThread::show), + ); + + let flags = args::Flags { ..flags }; + let flags = Arc::new(flags); + let cli_factory = factory::CliFactory::from_flags(flags); + let cli_factory = if let Some(custom_extensions_cb) = &root_custom_extensions_cb { + cli_factory.with_custom_ext_cb(custom_extensions_cb.clone()) + } else { + cli_factory + }; + let worker_factory = cli_factory + .create_cli_main_worker_factory() + .await + .map_err(|err| ferr!(Box::new(err)))?; + + let graph = cli_factory + .main_module_graph_container() + .await + .map_err(crate::anyhow_to_eyre!())? + .clone(); + Ok(Self { + cli_factory, + worker_factory, + graph, + }) + } + + async fn prepare_module( + &self, + main_module: ModuleSpecifier, + permissions: &deno_permissions::PermissionsOptions, + mode: deno_runtime::WorkerExecutionMode, + stdio: deno_runtime::deno_io::Stdio, + custom_extensions_cb: Option>, + ) -> Res { + let desc_parser = self + .cli_factory + .permission_desc_parser() + .map_err(crate::anyhow_to_eyre!())? + .clone(); + let permissions = + deno_permissions::Permissions::from_options(desc_parser.as_ref(), permissions)?; + let permissions = deno_permissions::PermissionsContainer::new(desc_parser, permissions); + let mut worker = self + .worker_factory + .create_custom_worker( + mode, + main_module.clone(), + permissions, + custom_extensions_cb, + stdio, + ) + .await + .map_err(crate::anyhow_to_eyre!())?; + let maybe_coverage_collector = worker + .maybe_setup_coverage_collector() + .await + .map_err(crate::anyhow_to_eyre!())?; + + // TODO: hot module support, expose shared worker contet from deno/cli/worker + // let maybe_hmr_runner = worker + // .maybe_setup_hmr_runner() + // .await + // .map_err(|err| ferr!(Box::new(err)))?; + + let worker = worker.into_main_worker(); + + Ok(ModuleWorkerContext { + main_module, + worker, + graph: self.graph.clone(), + maybe_coverage_collector, + // maybe_hmr_runner, + }) + } +} + +#[derive(educe::Educe)] +#[educe(Debug)] +struct PrepareModuleMsg { + main_module: ModuleSpecifier, + permissions: deno_permissions::PermissionsOptions, + #[educe(Debug(ignore))] + mode: deno_runtime::WorkerExecutionMode, + #[educe(Debug(ignore))] + stdio: deno_runtime::deno_io::Stdio, + #[educe(Debug(ignore))] + custom_extensions_cb: Option>, +} + +#[derive(educe::Educe)] +#[educe(Debug)] +enum DenoWorkerMsg { + PrepareModule { + #[educe(Debug(ignore))] + response_channel: tokio::sync::oneshot::Sender>, + inner: PrepareModuleMsg, + }, +} + +#[derive(Clone, educe::Educe)] +#[educe(Debug)] +pub struct DenoWorkerHandle { + sender: tokio::sync::mpsc::Sender, + term_signal_tx: tokio::sync::watch::Sender, + #[educe(Debug(ignore))] + join_handle: Arc>>>, + term_signal_rx: tokio::sync::watch::Receiver, +} + +impl DenoWorkerHandle { + pub fn term_signal_watcher(&self) -> tokio::sync::watch::Receiver { + self.term_signal_rx.clone() + } + + pub async fn terminate(self) -> Res<()> { + let join_handle = { + let mut opt = self.join_handle.lock().expect_or_log("mutex error"); + opt.take() + }; + let Some(join_handle) = join_handle else { + return Ok(()); + }; + self.term_signal_tx.send(true)?; + let abort_handle = join_handle.abort_handle(); + match tokio::time::timeout(std::time::Duration::from_millis(100), join_handle).await { + Ok(val) => val.wrap_err("tokio error"), + Err(_) => { + trace!("timeout waiting for deno worker termination, aborting"); + abort_handle.abort(); + Ok(()) + } + } + //join_handle.await.wrap_err("tokio error") + } +} + +impl DenoWorkerHandle { + pub async fn prepare_module( + &self, + main_module: ModuleSpecifier, + permissions: deno_permissions::PermissionsOptions, + mode: deno_runtime::WorkerExecutionMode, + stdio: deno_runtime::deno_io::Stdio, + custom_extensions_cb: Option>, + ) -> Res { + let (tx, rx) = tokio::sync::oneshot::channel(); + self.sender + .send(DenoWorkerMsg::PrepareModule { + response_channel: tx, + inner: PrepareModuleMsg { + main_module, + permissions, + mode, + stdio, + custom_extensions_cb, + }, + }) + .await + .expect_or_log("channel error"); + rx.await.expect_or_log("channel error") + } +} + +#[derive(educe::Educe)] +#[educe(Debug)] +struct ModuleWorkerContext { + main_module: deno_core::ModuleSpecifier, + #[educe(Debug(ignore))] + worker: deno_runtime::worker::MainWorker, + #[educe(Debug(ignore))] + graph: Arc, + #[educe(Debug(ignore))] + maybe_coverage_collector: Option>, + // maybe_hmr_runner: Option>, +} + +impl ModuleWorkerContext { + fn get_loaded_modules(&self) -> Vec { + use deno::graph_container::*; + self.graph + .graph() + .modules() + .map(|module| match module { + deno_graph::Module::Js(js_module) => js_module.specifier.clone(), + deno_graph::Module::Json(json_module) => json_module.specifier.clone(), + deno_graph::Module::Wasm(wasm_module) => wasm_module.specifier.clone(), + deno_graph::Module::Npm(npm_module) => npm_module.specifier.clone(), + deno_graph::Module::Node(built_in_node_module) => { + built_in_node_module.specifier.clone() + } + deno_graph::Module::External(external_module) => external_module.specifier.clone(), + }) + .collect() + } + + async fn run(&mut self, global_term_signal: TermSignal) -> Res { + debug!("main_module {}", self.main_module); + self.execute_main_module() + .await + .map_err(crate::anyhow_to_eyre!())?; + + let (_term_signal_tx, term_signal_rx) = tokio::sync::watch::channel(false); + let exit_code = self + .drive_till_exit(global_term_signal, term_signal_rx) + .await + .map_err(crate::anyhow_to_eyre!())?; + + Ok(exit_code) + } + + async fn drive_till_exit( + &mut self, + mut global_term_signal: TermSignal, + mut term_signal: TermSignal, + ) -> anyhow::Result { + self.worker.dispatch_load_event()?; + loop { + /* if let Some(hmr_runner) = self.maybe_hmr_runner.as_mut() { + let watcher_communicator = + self.shared.maybe_file_watcher_communicator.clone().unwrap(); + + let hmr_future = hmr_runner.run().boxed_local(); + let event_loop_future = self.worker.run_event_loop(false).boxed_local(); + + let result; + tokio::select! { + hmr_result = hmr_future => { + result = hmr_result; + }, + event_loop_result = event_loop_future => { + result = event_loop_result; + } + } + if let Err(e) = result { + watcher_communicator.change_restart_mode(WatcherRestartMode::Automatic); + return Err(e); + } + } else { + self.worker + .run_event_loop(self.maybe_coverage_collector.is_none()) + .await?; + } */ + + let event_loop_future = self + .worker + .run_event_loop(self.maybe_coverage_collector.is_none()) + .boxed_local(); + + trace!("running event loop"); + tokio::select! { + _ = global_term_signal.wait_for(|sig| *sig) => { + trace!("global term signal lit, shutting down event loop"); + break + }, + _ = term_signal.wait_for(|sig| *sig) => { + trace!("worker term signal lit, shutting down event loop"); + break + }, + event_loop_result = event_loop_future => { + anyhow::Context::context(event_loop_result, "event loop error")?; + } + } + + let web_continue = self.worker.dispatch_beforeunload_event()?; + if !web_continue { + let node_continue = self.worker.dispatch_process_beforeexit_event()?; + if !node_continue { + trace!("beforeunload and beforeexit success, shutting down loop"); + break; + } + } + } + self.worker.dispatch_unload_event()?; + self.worker.dispatch_process_exit_event()?; + if let Some(coverage_collector) = self.maybe_coverage_collector.as_mut() { + self.worker + .js_runtime + .with_event_loop_future( + coverage_collector.stop_collecting().boxed_local(), + deno_core::PollEventLoopOptions::default(), + ) + .await?; + } + /* if let Some(hmr_runner) = self.maybe_hmr_runner.as_mut() { + self.worker + .js_runtime + .with_event_loop_future( + hmr_runner.stop().boxed_local(), + deno_core::PollEventLoopOptions::default(), + ) + .await?; + } */ + Ok(self.worker.exit_code()) + } + + async fn execute_main_module(&mut self) -> anyhow::Result<()> { + let id = self.worker.preload_main_module(&self.main_module).await?; + self.worker.evaluate_module(id).await + } +} + +#[derive(educe::Educe)] +#[educe(Debug)] +enum ModuleWorkerReq { + Run { + #[educe(Debug(ignore))] + response_channel: tokio::sync::oneshot::Sender>, + }, + DriveTillExit { + term_signal: TermSignal, + #[educe(Debug(ignore))] + response_channel: tokio::sync::oneshot::Sender>, + }, + Execute { + #[educe(Debug(ignore))] + response_channel: tokio::sync::oneshot::Sender>, + }, + GetLoadedModules { + #[educe(Debug(ignore))] + response_channel: tokio::sync::oneshot::Sender>, + }, +} + +#[derive(Clone, Debug)] +pub struct ModuleWorkerHandle { + sender: tokio::sync::mpsc::Sender, +} + +#[derive(Clone, Debug)] +pub struct FinishedWorkerHandle { + sender: tokio::sync::mpsc::Sender, +} + +#[derive(Debug)] +pub struct ActiveWorkerHandle { + pub exit_code_rx: tokio::sync::oneshot::Receiver>, + pub term_signal_tx: tokio::sync::watch::Sender, + pub finished: FinishedWorkerHandle, +} + +impl ModuleWorkerHandle { + /// Load and execute the main module + /// and drive the main loop until the program + /// exits. + pub async fn run(self) -> Res<(i32, FinishedWorkerHandle)> { + let (result_tx, result_rx) = tokio::sync::oneshot::channel(); + self.sender + .send(ModuleWorkerReq::Run { + response_channel: result_tx, + }) + .await + .expect_or_log("channel error"); + Ok(( + result_rx.await.expect_or_log("channel error")?, + FinishedWorkerHandle { + sender: self.sender, + }, + )) + } + + /// Load and execute the main module + /// but doesn't progress the main event + /// loop. + pub async fn execute(&mut self) -> Res<()> { + let (tx, rx) = tokio::sync::oneshot::channel(); + self.sender + .send(ModuleWorkerReq::Execute { + response_channel: tx, + }) + .await + .expect_or_log("channel error"); + rx.await.expect_or_log("channel error") + } + + /// Drive the event loop until exit and return + /// result in returned channel or the term signal + /// is lit. + /// Expects that [`execute`] was called first on the worker. + pub async fn drive_till_exit(self) -> Res { + let (term_signal_tx, term_signal_rx) = tokio::sync::watch::channel(false); + let (exit_code_tx, exit_code_rx) = tokio::sync::oneshot::channel(); + self.sender + .send(ModuleWorkerReq::DriveTillExit { + term_signal: term_signal_rx, + response_channel: exit_code_tx, + }) + .await + .expect_or_log("channel error"); + Ok(ActiveWorkerHandle { + exit_code_rx, + term_signal_tx, + finished: FinishedWorkerHandle { + sender: self.sender, + }, + }) + } +} + +impl FinishedWorkerHandle { + pub async fn get_loaded_modules(&mut self) -> Vec { + let (tx, rx) = tokio::sync::oneshot::channel(); + self.sender + .send(ModuleWorkerReq::GetLoadedModules { + response_channel: tx, + }) + .await + .expect_or_log("channel error"); + // FIXME: can use sync oneshot here? + rx.await.expect_or_log("channel error") + } +} diff --git a/src/ghjk/Cargo.toml b/src/ghjk/Cargo.toml new file mode 100644 index 00000000..c6b652ee --- /dev/null +++ b/src/ghjk/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "ghjk" +description = "Program your development environments." +version.workspace = true +edition.workspace = true + +[[bin]] +name = "ghjk" +path = "main.rs" + +[dependencies] +denort.workspace = true +deno_core.workspace = true + +serde = "1" +serde_json = "1" + +ahash = { version = "0.8", features = ["serde"] } +indexmap = { version = "2.6.0", features = ["serde"] } +# serde_repr = { version = "0.1" } + +regex = "1.10" + +rand = "0.8" +time = { version = "0.3", features = ["serde"] } +nix = { version = "0.29.0", features = ["signal"] } + +once_cell = "1.19" +parking_lot = "0.12" +bitflags = "2.6" +itertools = "0.13" + +smallvec = { version = "1", features = [ + "serde", + "const_generics", + "const_new", + "union", +] } +smartstring = { version = "1", features = ["serde"] } + +educe.workspace = true + +thiserror = "1" +tracing-error = "0.2" +tracing-unwrap.workspace = true + +color-eyre.workspace = true +anyhow.workspace = true + +tracing.workspace = true +tracing-subscriber.workspace = true +tracing-appender = "0.2" +tracing-futures = "0.2" + +async-trait = "0.1.83" +futures = { version = "=0.3.30", default-features = false, features = ["std", "async-await"] } +tokio = { workspace = true, features = ["full", "parking_lot", "tracing"] } +tokio-stream = "0.1" + +dashmap = { version = "5.5", features = ["serde"]} + +clap = { workspace = true, features = ["derive", "env"] } +clap_complete = "=4.5.24" +shadow-rs.workspace = true +# TODO: support more config formats +config = { version = "0.14.1", default-features = false, features = ["async", "json5", "json"] } + +multihash = "0.19.2" +json-canon = "0.1.3" +data-encoding = "2.6.0" +sha2 = "0.10.8" + +pathdiff = "0.2.2" +directories = "5.0.1" +dialoguer = "0.11.0" +console = "0.15.8" +console-subscriber = { version = "0.4.1", optional = true } + +[build-dependencies] +shadow-rs.workspace = true diff --git a/src/ghjk/build.rs b/src/ghjk/build.rs new file mode 100644 index 00000000..4a0dfc45 --- /dev/null +++ b/src/ghjk/build.rs @@ -0,0 +1,3 @@ +fn main() -> shadow_rs::SdResult<()> { + shadow_rs::new() +} diff --git a/src/ghjk/cli.rs b/src/ghjk/cli.rs new file mode 100644 index 00000000..75692e17 --- /dev/null +++ b/src/ghjk/cli.rs @@ -0,0 +1,442 @@ +use std::process::ExitCode; + +use clap::builder::styling::AnsiColor; + +use crate::config::Config; +use crate::interlude::*; + +use crate::systems::{CliCommandAction, SystemCliCommand}; +use crate::{host, systems}; + +const DENO_UNSTABLE_FLAGS: &[&str] = &["worker-options", "kv"]; + +pub async fn cli() -> Res { + /* tokio::spawn({ + async { + loop { + println!("{:?}: thread is not blocked", std::thread::current().id()); + tokio::time::sleep(std::time::Duration::from_secs(2)).await; + } + } + }); */ + + let cwd = std::env::current_dir()?; + + let config = Config::source().await?; + + debug!("config sourced: {config:?}"); + + let Some(quick_err) = try_quick_cli(&config).await? else { + return Ok(ExitCode::SUCCESS); + }; + + let Some(ghjkdir_path) = config.ghjkdir.clone() else { + quick_err.exit(); + }; + + let deno_cx = { + // TODO: DENO_FLAGS param simlar to V8_FLAGS + let flags = denort::deno::args::Flags { + unstable_config: denort::deno::args::UnstableConfig { + features: DENO_UNSTABLE_FLAGS + .iter() + .copied() + .map(String::from) + .collect(), + ..default() + }, + no_lock: config.deno_lockfile.is_none(), + lock: config + .deno_lockfile + .as_ref() + .map(|path| path.to_string_lossy().into()), + internal: deno::args::InternalFlags { + cache_path: Some(config.deno_dir.clone()), + ..default() + }, + ..default() + }; + denort::worker::worker(flags, Some(Arc::new(Vec::new))).await? + }; + + let gcx = GhjkCtx { + config, + deno: deno_cx.clone(), + }; + let gcx = Arc::new(gcx); + + let (systems_deno, deno_sys_cx) = systems::deno::systems_from_deno( + &gcx, + &gcx.config + .repo_root + .join("src/deno_systems/mod.ts") + .wrap_err("repo url error")?, + &ghjkdir_path, + ) + .await?; + + let hcx = host::HostCtx::new( + gcx.clone(), + host::Config { + env_vars: std::env::vars().collect(), + cwd, + // TODO: env vars, flags and tests for the following + re_resolve: false, + locked: false, + re_serialize: false, + }, + systems_deno, + ); + + let hcx = Arc::new(hcx); + + let Some(mut systems) = host::systems_from_ghjkfile(hcx, &ghjkdir_path).await? else { + warn!("no ghjkfile found"); + quick_err.exit() + }; + + // let conf_json = serde_json::to_string_pretty(&systems.config)?; + // info!(%conf_json); + + use clap::*; + + let mut root_cmd = Cli::command(); + + debug!("collecting system commands"); + + let (sys_cmds, sys_actions) = match commands_from_systems(&systems).await { + Ok(val) => val, + Err(err) => { + systems.write_lockfile_or_log().await; + return Err(err); + } + }; + + for cmd in sys_cmds { + root_cmd = root_cmd.subcommand(cmd); + } + + debug!("checking argv matches"); + + let matches = match root_cmd.try_get_matches() { + Ok(val) => val, + Err(err) => { + systems.write_lockfile_or_log().await; + err.exit(); + } + }; + + match QuickComands::from_arg_matches(&matches) { + Ok(QuickComands::Print { commands }) => { + _ = commands.action(&gcx.config, Some(&systems.config))?; + return Ok(ExitCode::SUCCESS); + } + Ok(QuickComands::Deno { .. }) => { + unreachable!("deno quick cli will prevent this") + } + Err(err) => { + let kind = err.kind(); + use clap::error::ErrorKind; + if !(kind == ErrorKind::InvalidSubcommand + || kind == ErrorKind::InvalidValue + || kind == ErrorKind::DisplayHelp + || kind == ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand) + { + systems.write_lockfile_or_log().await; + err.exit(); + } + } + } + + let (cmd_path, mut action, action_matches) = match action_for_match(sys_actions, &matches).await + { + Ok(val) => val, + Err(err) => { + systems.write_lockfile_or_log().await; + return Err(err); + } + }; + + debug!(?cmd_path, "system command found"); + let Some(action) = action.action else { + systems.write_lockfile_or_log().await; + action.clap.print_long_help()?; + return Ok(std::process::ExitCode::FAILURE); + }; + + let res = action(action_matches.clone()) + .await + .wrap_err_with(|| format!("error on system command at path {cmd_path:?}")); + + systems.write_lockfile_or_log().await; + + deno_sys_cx.terminate().await?; + deno_cx.terminate().await?; + + res.map(|()| ExitCode::SUCCESS) +} + +/// Sections of the CLI do not require loading a ghjkfile. +pub async fn try_quick_cli(config: &Config) -> Res> { + use clap::*; + + let cli = match Cli::try_parse() { + Ok(val) => val, + Err(err) => { + let kind = err.kind(); + use clap::error::ErrorKind; + if kind == ErrorKind::InvalidSubcommand + || kind == ErrorKind::InvalidValue + || kind == ErrorKind::DisplayHelp + || kind == ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand + { + return Ok(Some(err)); + } + err.exit(); + } + }; + + match cli.quick_commands { + QuickComands::Print { commands } => { + if !commands.action(config, None)? { + return Ok(Some(clap::error::Error::new( + clap::error::ErrorKind::DisplayHelp, + ))); + } + } + QuickComands::Deno { .. } => unreachable!("deno quick cli will have prevented this"), + } + + Ok(None) +} + +const CLAP_STYLE: clap::builder::Styles = clap::builder::Styles::styled() + .header(AnsiColor::Yellow.on_default()) + .usage(AnsiColor::BrightBlue.on_default()) + .literal(AnsiColor::BrightBlue.on_default()) + .placeholder(AnsiColor::BrightBlue.on_default()); + +#[derive(Debug, clap::Parser)] +#[clap( + version, + about, + styles = CLAP_STYLE +)] +struct Cli { + #[command(subcommand)] + quick_commands: QuickComands, +} + +#[derive(clap::Subcommand, Debug)] +enum QuickComands { + /// Print different discovored or built values to stdout. + Print { + #[command(subcommand)] + commands: PrintCommands, + }, + /// Access the deno cli + Deno { + #[arg(raw(true))] + args: String, + }, +} + +#[derive(clap::Subcommand, Debug)] +enum PrintCommands { + /// Print the path to the data dir used by ghjk. + DataDirPath, + /// Print the path to the dir of the currently active ghjk context. + GhjkdirPath, + /// Print the path of the ghjkfile used. + GhjkfilePath, + /// Print the extracted and serialized config from the ghjkfile. + Config { + /// Use json format when printing config. + #[arg(long)] + json: bool, + }, +} + +impl PrintCommands { + /// The return value specifies weather or not the CLI is done or + /// weather it should continue on with serialization if this + /// action was invoked as part of the quick cli + fn action( + self, + cli_config: &Config, + serialized_config: Option<&host::SerializedConfig>, + ) -> Res { + Ok(match self { + PrintCommands::DataDirPath => { + println!("{}", cli_config.data_dir.display()); + true + } + // TODO: rename GHJK_DIR to GHJKDIR + PrintCommands::GhjkdirPath => { + if let Some(path) = &cli_config.ghjkdir { + // TODO: graceful termination on SIGPIPE + println!("{}", path.display()); + true + } else { + eyre::bail!("no ghjkdir found."); + } + } + PrintCommands::GhjkfilePath => { + if let Some(path) = &cli_config.ghjkdir { + println!("{}", path.display()); + true + } else { + eyre::bail!("no ghjkfile found."); + } + } + PrintCommands::Config { .. } => match serialized_config { + Some(config) => { + let conf_json = serde_json::to_string_pretty(&config)?; + println!("{conf_json}"); + true + } + None => false, + }, + }) + } +} + +type SysCmdActions = IndexMap; +struct SysCmdAction { + name: CHeapStr, + clap: clap::Command, + action: Option, + sub_commands: SysCmdActions, +} + +async fn commands_from_systems( + systems: &host::GhjkfileSystems, +) -> Res<(Vec, SysCmdActions)> { + fn inner(cmd: SystemCliCommand) -> (SysCmdAction, clap::Command) { + // apply styles here due to propagation + // breaking for these dynamic subcommands for some reason + let mut clap_cmd = cmd.clap.styles(CLAP_STYLE); + let mut sub_commands = IndexMap::new(); + for (id, cmd) in cmd.sub_commands { + let (sub_sys_cmd, sub_cmd) = inner(cmd); + clap_cmd = clap_cmd.subcommand(sub_cmd); + sub_commands.insert(id, sub_sys_cmd); + } + ( + SysCmdAction { + clap: clap_cmd.clone(), + name: cmd.name, + action: cmd.action, + sub_commands, + }, + clap_cmd, + ) + } + let mut commands = vec![]; + let mut conflict_tracker = HashMap::new(); + let mut actions = SysCmdActions::new(); + for (id, sys_inst) in &systems.sys_instances { + let cmds = sys_inst + .commands() + .await + .wrap_err_with(|| format!("error getting commands for system: {id}"))?; + for cmd in cmds { + let (sys_cmd, clap_cmd) = inner(cmd); + + if let Some(conflict) = conflict_tracker.insert(sys_cmd.name.clone(), id) { + eyre::bail!( + "system commannd conflict under name {:?} for modules {conflict:?} and {id:?}", + sys_cmd.name.clone(), + ); + } + actions.insert(sys_cmd.name.clone(), sys_cmd); + commands.push(clap_cmd); + } + } + Ok((commands, actions)) +} + +async fn action_for_match( + mut actions: SysCmdActions, + matches: &clap::ArgMatches, +) -> Res<(Vec, SysCmdAction, &clap::ArgMatches)> { + fn inner<'a>( + mut current: SysCmdAction, + matches: &'a clap::ArgMatches, + cmd_path: &mut Vec, + ) -> Res<(SysCmdAction, &'a clap::ArgMatches)> { + match matches.subcommand() { + Some((cmd_name, matches)) => { + cmd_path.push(cmd_name.into()); + match current.sub_commands.swap_remove(cmd_name) { + Some(action) => inner(action, matches, cmd_path), + None => { + eyre::bail!("no match found for cmd {cmd_path:?}") + } + } + } + None => Ok((current, matches)), + } + } + let mut cmd_path = vec![]; + let Some((cmd_name, matches)) = matches.subcommand() else { + unreachable!("clap prevents this branch") + }; + cmd_path.push(cmd_name.into()); + let Some(action) = actions.swap_remove(cmd_name) else { + eyre::bail!("no match found for cmd {cmd_path:?}"); + }; + let (action, matches) = inner(action, matches, &mut cmd_path)?; + Ok((cmd_path, action, matches)) +} + +/// TODO: keep more of this in deno next time it's updated +pub fn deno_quick_cli() -> Option<()> { + let argv = std::env::args_os().skip(1).collect::>(); + let first = argv.first()?; + if first != "deno" { + return None; + } + deno::util::unix::raise_fd_limit(); + deno::util::windows::ensure_stdio_open(); + deno_runtime::deno_permissions::set_prompt_callbacks( + Box::new(deno::util::draw_thread::DrawThread::hide), + Box::new(deno::util::draw_thread::DrawThread::show), + ); + + let future = async move { + // NOTE(lucacasonato): due to new PKU feature introduced in V8 11.6 we need to + // initialize the V8 platform on a parent thread of all threads that will spawn + // V8 isolates. + let flags = deno::resolve_flags_and_init(argv)?; + deno::run_subcommand(Arc::new(flags)).await + }; + + let result = deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics(future); + + match result { + Ok(exit_code) => deno_runtime::exit(exit_code), + Err(err) => exit_for_error(err), + } +} + +fn exit_with_message(message: &str, code: i32) -> ! { + tracing::error!("error: {}", message.trim_start_matches("error: ")); + deno_runtime::exit(code); +} + +fn exit_for_error(error: anyhow::Error) -> ! { + let mut error_string = format!("{error:?}"); + let error_code = 1; + + if let Some(e) = error.downcast_ref::() { + error_string = deno_runtime::fmt_errors::format_js_error(e); + } /* else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) = + error.downcast_ref::() + { + error_string = e.to_string(); + error_code = 10; + } */ + + exit_with_message(&error_string, error_code); +} diff --git a/src/ghjk/config.rs b/src/ghjk/config.rs new file mode 100644 index 00000000..5157c901 --- /dev/null +++ b/src/ghjk/config.rs @@ -0,0 +1,286 @@ +use crate::interlude::*; + +#[derive(Debug)] +pub struct Config { + pub ghjkfile: Option, + pub ghjkdir: Option, + pub data_dir: PathBuf, + pub deno_dir: PathBuf, + pub deno_lockfile: Option, + pub repo_root: url::Url, +} + +#[derive(Deserialize)] +struct GlobalConfigFile { + data_dir: Option, + deno_dir: Option, + repo_root: Option, +} + +#[derive(Deserialize)] +struct LocalConfigFile { + #[serde(flatten)] + global: GlobalConfigFile, + deno_lockfile: Option, +} + +impl Config { + pub async fn source() -> Res { + let cwd = std::env::current_dir()?; + let xdg_dirs = directories::ProjectDirs::from("", "", "ghjk") + .expect_or_log("unable to resolve home dir"); + + let ghjkdir_path = match path_from_env(&cwd, "GHJK_DIR")? { + Some(val) => Some(val), + None => crate::utils::find_entry_recursive(&cwd, ".ghjk") + .await + .wrap_err("error trying to locate a .ghjk dir")?, + }; + + let ghjkfile_path = match path_from_env(&cwd, "GHJKFILE")? { + Some(val) => Some(val), + None => { + // NOTE: look for typescript ghjkfile + let ghjkfile_name = "ghjk.ts"; + match &ghjkdir_path { + Some(ghjkfile_path) => { + crate::utils::find_entry_recursive( + ghjkfile_path + .parent() + .expect_or_log("invalid GHJK_DIR path"), + ghjkfile_name, + ) + .await? + } + None => crate::utils::find_entry_recursive(&cwd, ghjkfile_name) + .await + .wrap_err_with(|| { + format!("error trying to locate a ghjkfile of kind \"{ghjkfile_name}\"") + })?, + } + } + }; + + // if ghjkfile var is set, set the GHJK_DIR overriding + // any set by the user + let (ghjkfile_path, ghjkdir_path) = if let Some(path) = ghjkfile_path { + let file_path = tokio::fs::canonicalize(&path) + .await + .wrap_err_with(|| format!("error canonicalizing ghjkfile path at {path:?}"))?; + let dir_path = file_path.parent().unwrap().join(".ghjk"); + (Some(file_path), Some(dir_path)) + } else { + (None, ghjkdir_path) + }; + + if ghjkdir_path.is_none() && ghjkfile_path.is_none() { + warn!( + "ghjk could not find any ghjkfiles or ghjkdirs, try creating a `ghjk.ts` script.", + ); + } + + let mut config = Config { + ghjkfile: ghjkfile_path, + ghjkdir: ghjkdir_path.clone(), + data_dir: xdg_dirs.data_dir().to_owned(), + deno_dir: xdg_dirs.data_dir().join("deno"), + deno_lockfile: ghjkdir_path.as_ref().map(|path| path.join("deno.lock")), + repo_root: { + if cfg!(debug_assertions) { + url::Url::from_file_path(&cwd) + .expect_or_log("cwd error") + .join(&format!("{}/", cwd.file_name().unwrap().to_string_lossy())) + .wrap_err("repo url error")? + } else { + const BASE_URL: &str = + "https://raw.githubusercontent.com/metatypedev/metatype/"; + // repo root url must end in slash due to + // how Url::join works + let url = BASE_URL.to_owned() + crate::shadow::COMMIT_HASH + "/"; + url::Url::parse(&url).expect("repo url error") + } + }, + }; + + let global_config_path = match path_from_env(&cwd, "GHJK_CONFIG_DIR")? { + Some(val) => val, + None => xdg_dirs.config_dir().join("config"), + }; + + // we use builtin config-rs File implementation + // which relies on sync std + let config = tokio::task::spawn_blocking(move || { + { + config + .source_global_config(&global_config_path) + .wrap_err_with(|| { + format!("error sourcing global config from {global_config_path:?}") + })?; + } + + if let Some(ghjkdir_path) = &ghjkdir_path { + let file_path = ghjkdir_path.join("config"); + config + .source_local_config(&file_path) + .wrap_err_with(|| format!("error sourcing local config from {file_path:?}"))?; + }; + + config + .source_env_config(&cwd) + .wrap_err("error sourcing config from environment variables")?; + + if !config.repo_root.path().ends_with("/") { + config + .repo_root + .set_path(&format!("{}/", config.repo_root.path())); + } + + eyre::Ok(config) + }) + .await + .expect_or_log("tokio error")?; + + if let Some(path) = &config.ghjkdir { + let ignore_path = path.join(".gitignore"); + if !matches!(tokio::fs::try_exists(&ignore_path).await, Ok(true)) { + tokio::fs::create_dir_all(path) + .await + .wrap_err_with(|| format!("error creating ghjkdir at {path:?}"))?; + tokio::fs::write( + &ignore_path, + "envs +hash.json", + ) + .await + .wrap_err_with(|| format!("error writing ignore file at {ignore_path:?}"))?; + } + } + Ok(config) + } + + fn source_global_config(&mut self, file_path: &Path) -> Res<()> { + let GlobalConfigFile { + deno_dir, + data_dir, + repo_root, + } = config::Config::builder() + .add_source(config::File::with_name(&file_path.to_string_lossy()[..]).required(false)) + .build() + .wrap_err("error reading config file")? + .try_deserialize() + .wrap_err("error deserializing config file")?; + if let Some(path) = data_dir { + self.data_dir = + resolve_config_path(&path, file_path).wrap_err("error resolving data_dir")?; + } + if let Some(path) = deno_dir { + self.deno_dir = + resolve_config_path(&path, file_path).wrap_err("error resolving deno_dir")?; + } + if let Some(path) = repo_root { + self.repo_root = deno_core::resolve_url_or_path(&path, file_path) + .map_err(|err| ferr!(Box::new(err))) + .wrap_err("error resolving repo_root")?; + } + Ok(()) + } + + fn source_local_config(&mut self, file_path: &Path) -> Res<()> { + let LocalConfigFile { + global: + GlobalConfigFile { + data_dir, + deno_dir, + repo_root, + }, + deno_lockfile, + } = config::Config::builder() + .add_source(config::File::with_name(&file_path.to_string_lossy()).required(false)) + .build() + .wrap_err("error reading config file")? + .try_deserialize() + .wrap_err("error deserializing config file")?; + + if let Some(path) = data_dir { + self.data_dir = + resolve_config_path(&path, file_path).wrap_err("error resolving data_dir")?; + } + if let Some(path) = deno_dir { + self.deno_dir = + resolve_config_path(&path, file_path).wrap_err("error resolving deno_dir")?; + } + if let Some(path) = deno_lockfile { + self.deno_lockfile = Some( + resolve_config_path(&path, file_path).wrap_err("error resolving deno_lockfile")?, + ); + } + if let Some(path) = repo_root { + self.repo_root = deno_core::resolve_url_or_path(&path, file_path) + .map_err(|err| ferr!(Box::new(err))) + .wrap_err("error resolving repo_root")?; + } + Ok(()) + } + + fn source_env_config(&mut self, cwd: &Path) -> Res<()> { + let LocalConfigFile { + global: + GlobalConfigFile { + data_dir, + deno_dir, + repo_root, + }, + deno_lockfile, + } = config::Config::builder() + .add_source(config::Environment::with_prefix("GHJK")) + .build() + .wrap_err("error reading config file")? + .try_deserialize() + .wrap_err("error deserializing config file")?; + + if let Some(path) = data_dir { + self.data_dir = resolve_config_path(&path, cwd).wrap_err("error resolving data_dir")?; + } + if let Some(path) = deno_dir { + self.deno_dir = resolve_config_path(&path, cwd).wrap_err("error resolving deno_dir")?; + } + if let Some(path) = deno_lockfile { + self.deno_lockfile = if path != "off" { + Some(resolve_config_path(&path, cwd).wrap_err("error resolving deno_lockfile")?) + } else { + None + }; + } + if let Some(path) = repo_root { + self.repo_root = deno_core::resolve_url_or_path(&path, cwd) + .map_err(|err| ferr!(Box::new(err))) + .wrap_err("error resolving repo_root")?; + } + Ok(()) + } +} + +fn resolve_config_path(path: impl AsRef, config_path: &Path) -> Res { + let path = config_path.join(&path); + let path = std::path::absolute(&path) + .wrap_err_with(|| format!("error absolutizing path at {path:?}"))?; + Ok(path) +} + +fn path_from_env(cwd: &Path, env_name: &str) -> Res> { + let path = match std::env::var(env_name) { + Ok(path) => Some(PathBuf::from(path)), + Err(std::env::VarError::NotUnicode(os_str)) => Some(PathBuf::from(os_str)), + Err(std::env::VarError::NotPresent) => None, + }; + + if let Some(path) = path { + let path = cwd.join(&path); + + Ok(Some(std::path::absolute(&path).wrap_err_with(|| { + format!("error absolutizing path {path:?} from env ${env_name}") + })?)) + } else { + Ok(None) + } +} diff --git a/src/ghjk/ext.rs b/src/ghjk/ext.rs new file mode 100644 index 00000000..6f79729d --- /dev/null +++ b/src/ghjk/ext.rs @@ -0,0 +1,161 @@ +use crate::interlude::*; + +use std::{cell::RefCell, rc::Rc}; + +use deno_core::v8; +use deno_core::OpState; +use tokio::sync::mpsc; +#[rustfmt::skip] +use deno_core as deno_core; // necessary for re-exported macros to work + +mod callbacks; +pub use callbacks::CallbacksHandle; + +/// This extension assumes that deno was launched on top of a tokio::LocalSet +pub fn extensions(config: ExtConfig) -> Arc { + // let atom = std::sync::atomic::AtomicBool::new(false); + Arc::new(move || { + // if atom.load(std::sync::atomic::Ordering::SeqCst) { + // return vec![]; + // } + // atom.store(true, std::sync::atomic::Ordering::SeqCst); + vec![ghjk_deno_ext::init_ops_and_esm(config.clone())] + }) +} +// This is used to populate the deno_core::OpState with dependencies +// used by the different ops +#[derive(Clone, Default)] +pub struct ExtConfig { + pub blackboard: Arc>, + callbacks_rx: Arc>, + exception_tx: Option>, + pub hostcalls: Hostcalls, +} + +impl ExtConfig { + pub fn new() -> Self { + Self::default() + } + + pub fn callbacks_handle( + &mut self, + dworker: &denort::worker::DenoWorkerHandle, + ) -> callbacks::CallbacksHandle { + let (line, handle) = callbacks::CallbackLine::new(dworker); + self.callbacks_rx = Arc::new(std::sync::Mutex::new(line)); + + handle + } + + pub fn exceptions_rx(&mut self) -> mpsc::UnboundedReceiver { + let (tx, rx) = mpsc::unbounded_channel(); + self.exception_tx = Some(tx); + rx + } + + fn inject(self, state: &mut deno_core::OpState) { + let callbacks = callbacks::worker(&self); + let ctx = ExtContext { + config: self, + callbacks, + }; + state.put(ctx); + } +} + +deno_core::extension!( + ghjk_deno_ext, + ops = [ + op_blackboard_get, + op_blackboard_set, + callbacks::op_callbacks_set, + op_hostcall, + op_dispatch_exception2 + ], + options = { config: ExtConfig }, + state = |state, opt| { + opt.config.inject(state); + }, + customizer = customizer, + docs = "Kitchen sink extension for all ghjk needs.", +); + +fn customizer(ext: &mut deno_core::Extension) { + ext.esm_files + .to_mut() + .push(deno_core::ExtensionFileSource::new( + "ext:ghjk_deno_ext/00_runtime.js", + deno_core::ascii_str_include!("js/00_runtime.js"), + )); + ext.esm_entry_point = Some("ext:ghjk_deno_ext/00_runtime.js"); +} + +#[derive(Clone)] +struct ExtContext { + callbacks: Option, + config: ExtConfig, +} + +#[deno_core::op2] +#[serde] +pub fn op_blackboard_get( + #[state] ctx: &ExtContext, + #[string] key: &str, +) -> Option { + ctx.config.blackboard.get(key).map(|val| val.clone()) +} + +#[deno_core::op2] +#[serde] +pub fn op_blackboard_set( + #[state] ctx: &ExtContext, + #[string] key: String, + #[serde] val: serde_json::Value, +) -> Option { + ctx.config.blackboard.insert(key.into(), val) +} + +#[derive(Clone, Default)] +pub struct Hostcalls { + pub funcs: Arc>, +} + +pub type HostcallFn = Box< + dyn Fn(serde_json::Value) -> BoxFuture<'static, Res> + 'static + Send + Sync, +>; + +#[deno_core::op2(async)] +#[serde] +pub async fn op_hostcall( + state: Rc>, + #[string] name: String, + #[serde] args: serde_json::Value, +) -> anyhow::Result { + let ctx = { + let state = state.borrow(); + let ctx = state.borrow::(); + ctx.clone() + }; + let Some(func) = ctx.config.hostcalls.funcs.get(&name[..]) else { + anyhow::bail!("no hostcall found under {name}"); + }; + func(args).await.map_err(|err| anyhow::anyhow!(err)) +} + +#[deno_core::op2(fast)] +pub fn op_dispatch_exception2( + scope: &mut v8::HandleScope, + #[state] ctx: &ExtContext, + exception: v8::Local, +) -> bool { + if let Some(tx) = &ctx.config.exception_tx { + tx.send(ferr!( + "unhandledrejection: {}", + exception.to_rust_string_lossy(scope) + )) + .expect_or_log("channel error"); + true + } else { + false + } +} diff --git a/src/ghjk/ext/callbacks.rs b/src/ghjk/ext/callbacks.rs new file mode 100644 index 00000000..804a28e0 --- /dev/null +++ b/src/ghjk/ext/callbacks.rs @@ -0,0 +1,388 @@ +use std::{cell::RefCell, rc::Rc}; + +use crate::interlude::*; + +use deno_core::serde_v8; +use deno_core::v8; +use deno_core::OpState; +// necessary for re-exported macros to work +#[rustfmt::skip] +use deno_core as deno_core; +use tokio::sync::{mpsc, oneshot}; + +use super::ExtConfig; +use super::ExtContext; + +#[derive(Debug, thiserror::Error)] +pub enum CallbackError { + #[error("no callback found under {key}")] + NotFound { key: String }, + #[error("callback protocol error")] + ProtocolError(#[source] eyre::Report), + #[error("error executing callback")] + JsError(#[source] eyre::Report), + #[error("v8 error")] + V8Error(#[source] eyre::Report), +} + +struct CallbackCtx { + msg_rx: mpsc::Receiver, + term_signal: tokio::sync::watch::Receiver, +} + +/// Line used by the callback_worker to receive +/// invocations. +#[derive(Default)] +pub struct CallbackLine { + /// This would be None if the callback line was already + /// taken or if the callback line was not initially set + cx: Option, + /// Indicates weather the callback line was initially set + was_set: bool, +} + +impl CallbackLine { + pub fn new(dworker: &denort::worker::DenoWorkerHandle) -> (Self, CallbacksHandle) { + let (msg_tx, msg_rx) = mpsc::channel(1); + ( + Self { + was_set: true, + cx: Some(CallbackCtx { + msg_rx, + term_signal: dworker.term_signal_watcher(), + }), + }, + CallbacksHandle { msg_tx }, + ) + } + + fn take(&mut self) -> Option { + if !self.was_set { + // debug!("callback line was not set, worker callbacks will noop"); + return None; + } + // debug!("realm with callbacks just had a child, it won't inherit callback feature"); + self.cx.take() + } +} + +/// Line used to invoke callbacks registered by js code. +#[derive(Clone)] +pub struct CallbacksHandle { + msg_tx: mpsc::Sender, +} + +impl CallbacksHandle { + pub async fn exec( + &self, + key: CHeapStr, + args: serde_json::Value, + ) -> Result { + let (tx, rx) = tokio::sync::oneshot::channel(); + self.msg_tx + .send(CallbacksMsg::Exec { + response_channel: tx, + key, + args, + }) + .await + .expect_or_log("channel error"); + rx.await.expect_or_log("channel error") + } +} + +/// Internal used to communicate between callback worker +#[derive(educe::Educe)] +#[educe(Debug)] +enum CallbacksMsg { + Exec { + #[educe(Debug(ignore))] + response_channel: oneshot::Sender>, + key: CHeapStr, + #[educe(Debug(ignore))] + args: serde_json::Value, + }, +} + +#[derive(Clone, Default)] +pub struct Callbacks { + store: Arc>, +} + +/// Start a worker task to execute callbacks on. +/// +/// Stored callbacks are not Sync so this expects to be started +/// on the same thread as deno. +/// This will return none if the callback line was set or +/// the callback line was already taken. This happens +/// with child WebWorkers for example which don't currently +/// support callbacks. +pub fn worker(config: &ExtConfig) -> Option { + let CallbackCtx { + msg_rx: mut rx, + term_signal, + } = { + let mut line = config.callbacks_rx.lock().expect_or_log("mutex err"); + line.take()? + }; + + let callbacks = Callbacks::default(); + let callbacks_2go = callbacks.clone(); + denort::unsync::spawn( + "callback-worker", + async move { + trace!("callback worker starting"); + while let Some(msg) = rx.recv().await { + trace!(?msg, "msg"); + match msg { + CallbacksMsg::Exec { + key: name, + args, + response_channel, + } => response_channel + .send( + callbacks_2go + .exec_callback(name, args, term_signal.clone()) + .await, + ) + .expect_or_log("channel error"), + } + } + trace!("callback worker done"); + } + .instrument(tracing::trace_span!("callback-worker")), + ); + Some(callbacks) +} + +impl Callbacks { + #[tracing::instrument(skip(self, args))] + pub async fn exec_callback( + &self, + key: CHeapStr, + args: serde_json::Value, + mut term_signal: tokio::sync::watch::Receiver, + ) -> Result { + let Some(cb) = self.store.get(&key[..]).map(|cb| cb.clone()) else { + return Err(CallbackError::NotFound { + key: key.to_string(), + }); + }; + + if *term_signal.borrow_and_update() { + trace!("callback invoked on terminated runtime"); + return Err(CallbackError::V8Error(ferr!("deno is shutting down"))); + } + + let (tx, rx) = oneshot::channel::>(); + + // we use the sender to spawn work on the v8 thread + let join_handle = tokio::task::spawn_blocking(move || { + cb.async_work_sender.spawn_blocking(move |scope| { + let args = serde_v8::to_v8(scope, args).map_err(|err| { + CallbackError::V8Error(ferr!(err).wrap_err("error serializaing args to v8")) + })?; + + let recv = v8::undefined(scope); + + let res = { + let tc_scope = &mut v8::TryCatch::new(scope); + // FIXME(@yohe): the original pointer was made from a global + // and yet we're transmuting it to a Local here. + // This is observed from the deno codebase + // and I can't explain it + // SAFETY: cargo culted from deno codebase + let func = unsafe { + std::mem::transmute::, v8::Local>( + cb.js_fn, + ) + }; + + let res = func + .call(tc_scope, recv.into(), &[args]) + // FIXME: under what circumstances can this be None? + .expect_or_log("got None from callback call"); + if tc_scope.has_caught() { + let exception = tc_scope.exception().unwrap(); + return Err(CallbackError::JsError( + ferr!(js_error_message(tc_scope, exception)) + .wrap_err("callback exception"), + )); + } + res + }; + if !res.is_promise() { + let res = serde_v8::from_v8(scope, res).map_err(|err| { + CallbackError::ProtocolError( + ferr!(err).wrap_err("error deserializaing result from v8"), + ) + })?; + return Ok(Some(res)); + } + let promise = v8::Local::::try_from(res).unwrap(); + let deno_shutting_down = + denort::promises::watch_promise(scope, promise, move |scope, _rf, res| { + let res = match res { + Ok(val) => serde_v8::from_v8(scope, val).map_err(|err| { + CallbackError::ProtocolError( + ferr!(err) + .wrap_err("error deserializaing promise result from v8"), + ) + }), + // FIXME: this is a bit of a mess and a bunch of workaround + // for private deno_core functionality as discussed at + // https://github.com/denoland/deno/discussions/27504 + Err(err) => Err(CallbackError::JsError( + ferr!(js_error_message(scope, err)) + .wrap_err("callback promise rejection"), + )), + }; + if let Err(res) = tx.send(res) { + debug!(?res, "callback response after abortion"); + } + }) + .is_none(); + if deno_shutting_down { + return Err(CallbackError::V8Error(ferr!("js runtime is shutting down"))); + }; + Ok(None) + }) + }); + + // if the callback is not async, we recieve the value right away + if let Some(res) = join_handle.await.expect_or_log("tokio error")? { + return Ok(res); + }; + + let res = tokio::select! { + _ = term_signal.wait_for(|signal| *signal) => { + trace!("callback worker recieved term signal"); + return Err(CallbackError::V8Error(ferr!("deno terminated waiting on callback"))); + }, + res = rx => { + res.expect_or_log("channel error")? + } + }; + + Ok(res) + } +} + +fn js_error_message(scope: &mut v8::HandleScope, err: v8::Local) -> String { + let Some(obj) = err.to_object(scope) else { + return err.to_rust_string_lossy(scope); + }; + let evt_err_class = { + let name = v8::String::new(scope, "ErrorEvent") + .expect_or_log("v8 error") + .into(); + scope + .get_current_context() + // classes are stored on the global obj + .global(scope) + .get(scope, name) + .expect_or_log("v8 error") + .to_object(scope) + .expect_or_log("v8 error") + }; + if !obj + .instance_of(scope, evt_err_class) + .expect_or_log("v8 error") + { + for key in &["stack", "message"] { + let key = v8::String::new(scope, key).expect_or_log("v8 error"); + if let Some(inner) = obj.get(scope, key.into()) { + if inner.boolean_value(scope) { + return inner.to_rust_string_lossy(scope); + } + } + } + return err.to_rust_string_lossy(scope); + } + // ErrorEvents are recieved here for some reason + // https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent + { + // if it has an error value attached, prefer that + let key = v8::String::new(scope, "error") + .expect_or_log("v8 error") + .into(); + if let Some(inner) = obj.get(scope, key) { + // check if it's not null or undefined + if inner.boolean_value(scope) { + // stack messages are preferred if it has one + let Some(inner) = inner.to_object(scope) else { + return inner.to_rust_string_lossy(scope); + }; + let key = v8::String::new(scope, "stack").expect_or_log("v8 error"); + if let Some(stack) = inner.get(scope, key.into()) { + if stack.boolean_value(scope) { + return stack.to_rust_string_lossy(scope); + } + } + return inner.to_rust_string_lossy(scope); + } + } + } + #[derive(Deserialize)] + struct ErrorEvt { + lineno: i64, + colno: i64, + filename: String, + message: String, + } + let evt: ErrorEvt = serde_v8::from_v8(scope, err).unwrap(); + format!( + "{} ({}:{}:{})", + evt.message, evt.filename, evt.lineno, evt.colno + ) +} + +struct Callback { + js_fn: SendPtr, + async_work_sender: deno_core::V8CrossThreadTaskSpawner, +} + +impl Clone for Callback { + fn clone(&self) -> Self { + Self { + js_fn: SendPtr(self.js_fn.0), + async_work_sender: self.async_work_sender.clone(), + } + } +} + +#[derive(Clone, Copy)] +#[repr(transparent)] +struct SendPtr(std::ptr::NonNull); +// SAFETY: we only ever access this value from within the same thread +// as deno +unsafe impl Send for SendPtr {} + +#[tracing::instrument(skip(state, cb))] +#[deno_core::op2] +pub fn op_callbacks_set( + state: Rc>, + #[string] name: String, + #[global] cb: v8::Global, +) -> anyhow::Result<()> { + let (ctx, async_work_sender) = { + let state = state.borrow(); + let ctx = state.borrow::(); + let sender = state.borrow::(); + + (ctx.clone(), sender.clone()) + }; + let Some(callbacks) = ctx.callbacks else { + warn!("callback set but callback feature is not enabled"); + anyhow::bail!("callbacks feature is not enabled"); + }; + debug!(%name, "registering callback"); + callbacks.store.insert( + name.into(), + Callback { + js_fn: SendPtr(cb.into_raw()), + async_work_sender, + }, + ); + Ok(()) +} diff --git a/src/ghjk/host.rs b/src/ghjk/host.rs new file mode 100644 index 00000000..4cbcb10e --- /dev/null +++ b/src/ghjk/host.rs @@ -0,0 +1,378 @@ +use std::io::IsTerminal; + +use crate::interlude::*; + +use crate::systems::*; + +mod deno; +mod hashfile; + +use hashfile::HashObj; + +#[derive(Debug)] +pub struct Config { + /// Discard serialization cache. + pub re_serialize: bool, + /// Discard any resolved values in lockfile. + #[allow(unused)] + pub re_resolve: bool, + /// Force use serialization cache. + pub locked: bool, + pub env_vars: IndexMap, + pub cwd: PathBuf, +} + +#[derive(educe::Educe)] +#[educe(Debug)] +pub struct HostCtx { + pub gcx: Arc, + pub config: Config, + #[educe(Debug(ignore))] + pub systems: HashMap, + // NOTE: only use this for hashfile usage which is invalidated and generated + // anew around the serialization process which is expected to take a reasonably + // short amount of time. Any code, like system impls, afterwards might take + // an unkown amount of time possibly making the hashes in this memo stale + pub file_hash_memo: DHashMap, +} + +impl HostCtx { + pub fn new( + gcx: Arc, + config: Config, + systems: HashMap, + ) -> Self { + Self { + gcx, + config, + systems, + file_hash_memo: default(), + } + } +} + +#[tracing::instrument(skip(hcx))] +pub async fn systems_from_ghjkfile( + hcx: Arc, + ghjkdir_path: &Path, +) -> Res> { + let (hashfile_path, lockfile_path) = ( + ghjkdir_path.join("hash.json"), + ghjkdir_path.join("lock.json"), + ); + + // read both files concurrently + let (hash_obj, lock_obj) = futures::join!( + HashObj::from_file(&hashfile_path), + LockObj::from_file(&lockfile_path), + ); + + // discard corrupt files if needed + let (mut hash_obj, mut lock_obj) = ( + match hash_obj { + Ok(val) => val, + Err(hashfile::HashfileError::Serialization(_)) => { + error!("hashfile is corrupt, discarding"); + None + } + Err(hashfile::HashfileError::Other(err)) => return Err(err), + }, + match lock_obj { + Ok(val) => val, + Err(LockfileError::Serialization(err)) => { + // interactive discard of lockfile if in an interactive shell + if std::io::stderr().is_terminal() + && tokio::task::spawn_blocking(|| { + dialoguer::Confirm::new() + .with_prompt("lockfile is corrupt, discard?") + .default(false) + .interact() + }) + .await + .expect_or_log("tokio error") + .wrap_err("prompt error")? + { + None + } else { + return Err(ferr!(err).wrap_err("corrupt lockfile")); + } + } + Err(LockfileError::Other(err)) => return Err(err), + }, + ); + + if hcx.config.locked { + if hash_obj.is_none() { + eyre::bail!("locked flag is set but no hashfile found"); + } + if lock_obj.is_none() { + eyre::bail!("locked flag is set but no lockfile found"); + } + } + + let (ghjkfile_exists, ghjkfile_hash) = if let Some(path) = &hcx.gcx.config.ghjkfile { + ( + matches!(tokio::fs::try_exists(path).await, Ok(true)), + Some( + hashfile::file_digest_hash(hcx.as_ref(), path) + .await? + .unwrap(), + ), + ) + } else { + (false, None) + }; + + // check if we need to discard the hashfile + if let Some(obj) = &mut hash_obj { + // NOTE: version migrator would go here + if obj.version != "0" { + eyre::bail!("unsupported hashfile version: {:?}", obj.version); + } + if !hcx.config.locked + && (hcx.config.re_serialize + // no need for expensive staleness checks if the ghjkfile + // no longer exists + || ghjkfile_hash.is_none() + || obj + .is_stale(hcx.as_ref()) + .await + .inspect(|is_stale| { + if *is_stale { + debug!("stale hashfile, discarding") + } + })?) + { + hash_obj = None; + } + } + // check if we need to discard the lockfile + if let Some(obj) = &mut lock_obj { + // TODO: version migrator + if obj.version != "0" { + eyre::bail!("unsupported hashfile version: {:?}", obj.version); + } + } + // TODO: + // if hcx.re_resolve {} + + let mut lock_entries = HashMap::new(); + + if let Some(lock_obj) = &mut lock_obj { + debug!(?lockfile_path, "loading lockfile"); + for sys_conf in &lock_obj.config.modules { + let Some(sys_man) = hcx.systems.get(&sys_conf.id) else { + eyre::bail!( + "unrecognized system found in lockfile config: {:?}", + sys_conf.id + ); + }; + let Some(sys_lock) = lock_obj.sys_entries.swap_remove(&sys_conf.id) else { + eyre::bail!( + "no lock entry found for system specified by lockfile config: {:?}", + sys_conf.id + ); + }; + let sys_inst = sys_man.init().await?; + lock_entries.insert( + sys_conf.id.clone(), + sys_inst.load_lock_entry(sys_lock).await?, + ); + } + } + + let mut fresh_serialized = false; + + let (config, hash_obj) = if let (Some(lock_obj), Some(hash_obj)) = (&lock_obj, hash_obj) { + // Only recover the old config if the hash_obj and lock_obj haven't + // been discarded by the cache invalidation checks above. + // Assumes that a hashfile tags the specific serialized version of the ghjkfile + // and it's context put in the lockfile + (lock_obj.config.clone(), hash_obj) + } else if let Some(ghjkfile_path) = &hcx.gcx.config.ghjkfile { + if !ghjkfile_exists { + eyre::bail!("no file found at ghjkfile path {ghjkfile_path:?}"); + } + if hcx.config.locked { + unreachable!("code should have early exited"); + } + info!(?ghjkfile_path, "serializing ghjkfile"); + fresh_serialized = true; + // TODO: configurable timeout on serialization + serialize_ghjkfile(hcx.as_ref(), ghjkfile_path) + .await + .wrap_err("error serializing ghjkfile")? + } else { + if hcx.config.locked { + unreachable!("code should have early exited"); + } + return Ok(None); + }; + + debug!("initializing ghjkfile systems"); + let sys_instances = { + let mut sys_instances = IndexMap::new(); + for sys_conf in &config.modules { + let Some(sys_man) = hcx.systems.get(&sys_conf.id) else { + eyre::bail!( + "unrecognized system specified by ghjkfile: {:?}", + sys_conf.id + ); + }; + let sys_inst = sys_man.init().await?; + sys_inst + .load_config( + sys_conf.config.clone(), + config.blackboard.clone(), + lock_entries.remove(&sys_conf.id), + ) + .await + .wrap_err_with(|| format!("error loading system config: {:?}", sys_conf.id))?; + sys_instances.insert(sys_conf.id.clone(), sys_inst); + } + sys_instances + }; + + Ok(Some(GhjkfileSystems { + hcx, + config, + sys_instances, + hash_obj, + old_lock_obj: lock_obj, + lockfile_path, + hashfile_path, + fresh_serialized, + hashfile_written: false, + })) +} + +pub struct GhjkfileSystems { + hcx: Arc, + pub config: Arc, + hash_obj: HashObj, + pub sys_instances: IndexMap, + old_lock_obj: Option, + lockfile_path: PathBuf, + hashfile_path: PathBuf, + fresh_serialized: bool, + hashfile_written: bool, +} + +impl GhjkfileSystems { + pub async fn write_lockfile_or_log(&mut self) { + if let Err(err) = self.write_lockfile().await { + error!("error writing lockfile: {err}"); + } + } + + #[tracing::instrument(skip(self))] + pub async fn write_lockfile(&mut self) -> Res<()> { + let mut lock_obj = LockObj { + version: "0".into(), + config: self.config.clone(), + sys_entries: default(), + }; + // generate the lock entries after *all* the systems + // are done processing their config to allow + // any shared stores to be properly populated + // e.g. the resolution memo store + for (sys_id, sys_inst) in &mut self.sys_instances { + let lock_entry = sys_inst.gen_lock_entry().await.wrap_err_with(|| { + format!("error generating lock entry for system: {:?}", sys_id) + })?; + lock_obj.sys_entries.insert(sys_id.clone(), lock_entry); + } + + if self.old_lock_obj.is_none() + || matches!(self.old_lock_obj.as_ref(), Some(old) if !old.eq(&lock_obj)) + { + if self.hcx.config.locked { + warn!("locked flag set, changes to lockfile discarded"); + } else { + trace!(lockfile_path = ?self.lockfile_path, /* ?lock_obj, */ "writing lock.json"); + tokio::fs::write( + &self.lockfile_path, + serde_json::to_vec_pretty(&lock_obj).expect_or_log("error jsonifying lockfile"), + ) + .await + .wrap_err("error writing to lockfile")?; + self.old_lock_obj.replace(lock_obj); + } + } + + // Only write out hashfile when a fresh serialization + // result was saved in the lock file. + if self.fresh_serialized && !self.hashfile_written { + if self.hcx.config.locked { + unreachable!("code should have early exited"); + } + trace!(hashfile_path = ?self.hashfile_path, /* hash_obj= ?self.hash_obj, */ "writing hash.json"); + tokio::fs::write( + &self.hashfile_path, + serde_json::to_vec_pretty(&self.hash_obj) + .expect_or_log("error jsonifying hashfile"), + ) + .await + .wrap_err("error writing to lockfile")?; + self.hashfile_written = true; + } + Ok(()) + } +} + +async fn serialize_ghjkfile(hcx: &HostCtx, path: &Path) -> Res<(Arc, HashObj)> { + let ext = path.extension(); + let res = if ext.map(|ext| ext == "ts" || ext == "js") == Some(true) { + deno::serialize_deno_ghjkfile(hcx, path).await? + } else { + eyre::bail!("unrecognized ghjkfile extension: {path:?}") + }; + debug!("ghjkfile serialized"); + let hash_obj = HashObj::from_result(hcx, path, &res) + .await + .wrap_err("error building hash obj")?; + Ok((Arc::new(res.config), hash_obj)) +} + +#[derive(Debug)] +struct SerializationResult { + config: SerializedConfig, + accessed_env_keys: Vec, + read_file_paths: Vec, + listed_file_paths: Vec, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct SerializedConfig { + modules: Vec, + blackboard: ConfigBlackboard, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct LockObj { + pub version: String, + pub sys_entries: indexmap::IndexMap, + pub config: Arc, +} + +#[derive(Debug, thiserror::Error)] +pub enum LockfileError { + #[error("error parsing lockfile:{0}")] + Serialization(serde_json::Error), + #[error(transparent)] + Other(#[from] eyre::Report), +} + +impl LockObj { + /// The lock.json file stores the serialized config and some entries + /// from systems. It's primary purpose is as a memo store to avoid + /// re-serialization on each CLI invocation. + pub async fn from_file(path: &Path) -> Result, LockfileError> { + let raw = match tokio::fs::read(path).await { + Ok(val) => val, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None), + Err(err) => return Err(LockfileError::Other(ferr!("error reading hashfile: {err}"))), + }; + serde_json::from_slice(&raw).map_err(LockfileError::Serialization) + } +} diff --git a/src/ghjk/host/deno.rs b/src/ghjk/host/deno.rs new file mode 100644 index 00000000..35bbdbd2 --- /dev/null +++ b/src/ghjk/host/deno.rs @@ -0,0 +1,92 @@ +use crate::interlude::*; + +use denort::deno::deno_runtime; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct InternalSerializationResult { + config: super::SerializedConfig, + accessed_env_keys: Vec, + read_file_paths: Vec, + listed_file_paths: Vec, +} + +#[tracing::instrument(skip(hcx))] +pub async fn serialize_deno_ghjkfile( + hcx: &super::HostCtx, + path: &Path, +) -> Res { + let main_module = hcx + .gcx + .config + .repo_root + .join("files/deno/bindings.ts") + .wrap_err("repo url error")?; + + let mut ext_conf = crate::ext::ExtConfig::new(); + + ext_conf.blackboard = [ + // blackboard is used as communication means + // with the deno side of the code + ( + "args".into(), + json!({ + "uri": url::Url::from_file_path(path).unwrap_or_log(), + }), + ), + ] + .into_iter() + .collect::>() + .into(); + + let bb = ext_conf.blackboard.clone(); + + let worker = hcx + .gcx + .deno + .prepare_module( + main_module.clone(), + deno_runtime::deno_permissions::PermissionsOptions { + allow_env: Some(vec![]), + allow_import: Some(vec![]), + allow_read: Some(vec![]), + allow_net: Some(vec![]), + ..default() + }, + deno_runtime::WorkerExecutionMode::Run, + default(), + Some(crate::ext::extensions(ext_conf)), + ) + .await?; + + let (exit_code, mut worker) = worker.run().await?; + if exit_code != 0 { + eyre::bail!("non-zero exit code running deno module"); + } + let loaded_modules = worker.get_loaded_modules().await; + + let (_, resp) = bb.remove("resp").expect_or_log("resp missing"); + let resp: InternalSerializationResult = + serde_json::from_value(resp).expect_or_log("error deserializing resp"); + + let mut loaded_modules = loaded_modules + .into_iter() + .filter(|url| url.scheme() == "file") + .map(|url| { + url.to_file_path() + .map_err(|()| ferr!("url to path error: {url}")) + }) + .collect::>>()?; + + let mut read_file_paths = resp.read_file_paths; + read_file_paths.append(&mut loaded_modules); + + debug!("ghjk.ts serialized"); + + Ok(super::SerializationResult { + config: resp.config, + accessed_env_keys: resp.accessed_env_keys, + listed_file_paths: resp.listed_file_paths, + read_file_paths, + }) +} diff --git a/src/ghjk/host/hashfile.rs b/src/ghjk/host/hashfile.rs new file mode 100644 index 00000000..5ec14e02 --- /dev/null +++ b/src/ghjk/host/hashfile.rs @@ -0,0 +1,271 @@ +use crate::interlude::*; + +use super::HostCtx; + +#[derive(Debug, Serialize, Deserialize)] +pub struct HashObj { + pub version: String, + /// Hashes of all env vars that were read. + pub env_var_hashes: indexmap::IndexMap>, + /// Hashes of all files that were read. + pub read_file_hashes: indexmap::IndexMap>, + /// File paths that were observed from the fs but not necessarily + /// read. + pub listed_files: Vec, +} + +#[derive(Debug, thiserror::Error)] +pub enum HashfileError { + #[error("error parsing hashfile: {0}")] + Serialization(serde_json::Error), + #[error("{0}")] + Other(#[source] eyre::Report), +} + +impl HashObj { + #[tracing::instrument(skip(hcx, res))] + pub async fn from_result( + hcx: &super::HostCtx, + ghjkfile_path: &Path, + res: &super::SerializationResult, + ) -> Res { + Ok(HashObj { + version: "0".into(), + env_var_hashes: env_var_digests( + &hcx.config.env_vars, + res.accessed_env_keys.iter().map(|key| key.as_ref()), + ), + listed_files: res + .listed_file_paths + .iter() + .map(|path| { + pathdiff::diff_paths( + std::path::absolute(path).expect_or_log("error absolutizing path"), + &hcx.config.cwd, + ) + .unwrap_or_log() + }) + .collect(), + read_file_hashes: file_digests( + hcx, + res.read_file_paths + .iter() + .map(|path| path.as_ref()) + .collect(), + ) + .await?, + }) + } + + /// The hash.json file stores the digests of all external accesses + /// of a ghjkfile during serialization. The primary purpose is to + /// do "cache invalidation" on ghjkfiles, re-serializing them if + /// any of the digests change. + pub async fn from_file(path: &Path) -> Result, HashfileError> { + let raw = match tokio::fs::read(path).await { + Ok(val) => val, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None), + Err(err) => return Err(HashfileError::Other(ferr!("error reading hashfile: {err}"))), + }; + serde_json::from_slice(&raw).map_err(HashfileError::Serialization) + } + + #[tracing::instrument(skip(hcx))] + pub async fn is_stale(&self, hcx: &HostCtx) -> Res { + { + let new_digest = env_var_digests( + &hcx.config.env_vars, + self.env_var_hashes.keys().map(|key| &key[..]), + ); + if self.env_var_hashes != new_digest { + trace!("stale env var digests"); + return Ok(true); + } + } + { + for path in &self.listed_files { + if !matches!(tokio::fs::try_exists(path).await, Ok(true)) { + trace!("stale listed files"); + return Ok(true); + } + } + } + { + if self.read_file_hashes + != file_digests( + hcx, + self.read_file_hashes + .keys() + .map(|path| path.as_ref()) + .collect(), + ) + .await? + { + trace!("stale read files digest"); + return Ok(true); + } + } + Ok(false) + } +} + +fn env_var_digests<'a>( + all: &IndexMap, + accessed: impl Iterator, +) -> IndexMap> { + accessed + .map(|key| { + ( + key.to_owned(), + all.get(key).map(|val| crate::utils::hash_str(val)), + ) + }) + .collect() +} + +async fn file_digests( + hcx: &HostCtx, + read_files: Vec<&Path>, +) -> Res>> { + use futures::StreamExt; + let mut map = futures::stream::iter(read_files.into_iter().map(|path| { + async move { + let path = std::path::absolute(path)?; + let hash = file_digest_hash(hcx, &path).await?; + let relative_path = pathdiff::diff_paths(path, &hcx.config.cwd).unwrap(); + Ok((relative_path, hash)) + } + .boxed() + })) + .buffer_unordered(16) + .collect::>() + .await + .into_iter() + .collect::>>()?; + map.sort_unstable_keys(); + Ok(map) +} + +#[tracing::instrument(skip(hcx))] +pub async fn file_digest_hash(hcx: &HostCtx, path: &Path) -> Res> { + let path = match tokio::fs::canonicalize(path).await { + Ok(val) => val, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + return Ok(None); + } + Err(err) => return Err(err).wrap_err("error resolving realpath"), + }; + match tokio::fs::metadata(&path).await { + Ok(stat) => { + const LARGE_FILE_THRESHOLD: u64 = 100 * 1024 * 1024; // 100MB + + let content_hash = if stat.file_type().is_file() || stat.file_type().is_symlink() { + if stat.len() > LARGE_FILE_THRESHOLD { + warn!( + len = stat.len(), + "large file detected, skippin content hash" + ); + None + } else { + Some( + file_content_digest_hash(hcx, &path) + .await? + .await + .map_err(|err| ferr!(err))?, + ) + } + } else { + None + }; + + let stat = StatMeta { + // we're not going to invalidate on access + accessed: None, + ..StatMeta::from(stat) + }; + let json = json!({ + "content_hash": content_hash, + "stat": stat + }); + Ok(Some(crate::utils::hash_obj(&json))) + } + Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(None), + Err(err) => Err(err).wrap_err("error on file stat"), + } +} + +pub type SharedFileContentDigestFuture = + futures::future::Shared>>; + +async fn file_content_digest_hash( + hcx: &HostCtx, + path: &Path, +) -> Res { + let path = path.to_owned(); + use dashmap::mapref::entry::*; + match hcx.file_hash_memo.entry(path.clone()) { + Entry::Occupied(occupied_entry) => Ok(occupied_entry.get().clone()), + Entry::Vacant(vacant_entry) => { + let shared = vacant_entry + .insert( + async { + let file = tokio::fs::File::open(path) + .await + .map_err(|err| format!("error opening file: {err}"))?; + let hash: CHeapStr = crate::utils::hash_reader(file) + .await + .map_err(|err| format!("error hashing file reader {err}"))? + .into(); + Ok(hash) + } + .boxed() + .shared(), + ) + .value() + .clone(); + Ok(shared) + } + } +} + +#[derive(Serialize)] +struct StatMeta { + accessed: Option, + created: Option, + modified: Option, + is_file: bool, + is_dir: bool, + is_symlink: bool, + size: u64, + #[cfg(unix)] + mode: u32, +} + +impl From for StatMeta { + fn from(value: std::fs::Metadata) -> Self { + fn unwrap_opt_sys_time(inp: std::io::Result) -> Option { + inp.map_err(|_| ()) + .and_then(|ts| { + ts.duration_since(std::time::SystemTime::UNIX_EPOCH) + .map_err(|_| ()) + }) + .map(|dur| dur.as_secs()) + .ok() + } + #[cfg(unix)] + use std::os::unix::fs::PermissionsExt; + + Self { + // file_type: match value.file_type() {}, + accessed: unwrap_opt_sys_time(value.accessed()), + created: unwrap_opt_sys_time(value.created()), + modified: unwrap_opt_sys_time(value.modified()), + is_file: value.is_file(), + is_symlink: value.is_symlink(), + is_dir: value.is_dir(), + size: value.len(), + #[cfg(unix)] + mode: value.permissions().mode(), + } + } +} diff --git a/src/ghjk/js/00_runtime.js b/src/ghjk/js/00_runtime.js new file mode 100644 index 00000000..2870e5d2 --- /dev/null +++ b/src/ghjk/js/00_runtime.js @@ -0,0 +1,44 @@ +// const { core } = Deno[Deno.internal]; +const { core } = Deno; +const { ops } = core; +// const fastops = core.ensureFastOps(); // TODO: investigate + +// NOTE: use the following import if ever switching to snaphsots +// import * as ops from "ext:core/ops"; + +function getOp(name) { + // Note: always get the op right away. + // the core.ops object is a proxy + // that retrieves the named op + // when requested i.e. not a + // hashmap prepopulated by the ops. + // If we don't get the op now, the + // proxy behvior won't be avail later at runtime + const op = ops[name]; + if (!op) { + throw Error(`op: ${name} not found`); + } + return op; +} + +const op_callbacks_set = getOp("op_callbacks_set"); + +/** + * @type {import('./runtime.d.ts').GhjkNs} + */ +const ____GhjkHost = { + blackboard: { + get: getOp("op_blackboard_get"), + set: getOp("op_blackboard_set"), + }, + callbacks: { + set: (key, fn) => { + op_callbacks_set(key, fn); + return key; + }, + }, + hostcall: getOp("op_hostcall"), + dispatchException: getOp("op_dispatch_exception2"), +}; + +globalThis.____GhjkHost = ____GhjkHost; diff --git a/src/ghjk/js/mock.sfx.ts b/src/ghjk/js/mock.sfx.ts new file mode 100644 index 00000000..76de8147 --- /dev/null +++ b/src/ghjk/js/mock.sfx.ts @@ -0,0 +1,20 @@ +//! Import this as a side effect for a mock the Ghjk object. +//! Useful to sanity check code that relies on the Ghjk extension. + +import { Ghjk } from "./runtime.js"; + +const bb = new Map(); +Object.assign(Ghjk, { + callbacks: { + set: (key: string) => key, + }, + hostcall: () => Promise.resolve({}), + blackboard: { + set: (key: string, value: any) => { + const old = bb.get(key); + bb.set(key, value); + return old; + }, + get: (key: string) => bb.get(key), + }, +}); diff --git a/src/ghjk/js/runtime.d.ts b/src/ghjk/js/runtime.d.ts new file mode 100644 index 00000000..d0bc53ec --- /dev/null +++ b/src/ghjk/js/runtime.d.ts @@ -0,0 +1,17 @@ +export type JsonLiteral = string | number | boolean | null; +export type JsonObject = { [key: string]: Json }; +export type JsonArray = Json[]; +export type Json = JsonLiteral | JsonObject | JsonArray; + +type GhjkNs = { + blackboard: { + get: (key: string) => Json | undefined; + set: (key: string, value: Json) => Json | undefined; + }; + callbacks: { + set: (key: string, fn: (arg: Json) => Json | Promise) => string; + }; + hostcall: (key: string, args: Json) => Promise; + dispatchException: (exception: any) => boolean; +}; +export const Ghjk: GhjkNs; diff --git a/src/ghjk/js/runtime.js b/src/ghjk/js/runtime.js new file mode 100644 index 00000000..2931f835 --- /dev/null +++ b/src/ghjk/js/runtime.js @@ -0,0 +1,10 @@ +/// + +//! This file provides the import point for types and values defined in: +// - ./00_runtime.js: which is preloaded by the custom deno runtime +// - ./runtime.d.ts: which types the objects from the preload + +/** + * @type {import('./runtime.d.ts').GhjkNs} + */ +export const Ghjk = globalThis.____GhjkHost; diff --git a/src/ghjk/log.rs b/src/ghjk/log.rs new file mode 100644 index 00000000..5aba03c9 --- /dev/null +++ b/src/ghjk/log.rs @@ -0,0 +1,100 @@ +use crate::interlude::*; + +pub fn init() { + static INIT: std::sync::Once = std::sync::Once::new(); + INIT.call_once(|| { + let eyre_panic_hook = color_eyre::config::HookBuilder::default().display_location_section( + std::env::var("RUST_ERR_LOCATION") + .map(|var| var != "0") + .unwrap_or(true), + ); + + #[cfg(not(debug_assertions))] + let eyre_panic_hook = eyre_panic_hook.panic_section(format!( + r#"Ghjk has panicked. This is a bug, please report this +at https://github.com/metatypedev/ghjk/issues/new. +If you can reliably reproduce this panic, try to include the +following items in your report: +- Reproduction steps +- Output of meta-cli doctor and +- A panic backtrace. Set the following environment variables as shown to enable full backtraces. + - RUST_BACKTRACE=1 + - RUST_LIB_BACKTRACE=full + - RUST_SPANTRACE=1 +Platform: {platform} +Version: {version} +Args: {args:?} +"#, + platform = crate::shadow::BUILD_TARGET, + // TODO: include commit sha + version = crate::shadow::PKG_VERSION, + args = std::env::args().collect::>() + )); + + let (eyre_panic_hook, _eyre_hook) = eyre_panic_hook.try_into_hooks().unwrap(); + let eyre_panic_hook = eyre_panic_hook.into_panic_hook(); + + std::panic::set_hook(Box::new(move |panic_info| { + if let Some(msg) = panic_info + .payload() + .downcast_ref::() + .map(|val| val.as_str()) + .or_else(|| panic_info.payload().downcast_ref::<&str>().cloned()) + { + if msg.contains("A Tokio 1.x context was found, but it is being shutdown.") { + warn!("improper shutdown, make sure to terminate all workers first"); + return; + } + } + eyre_panic_hook(panic_info); + // - Tokio does not exit the process when a task panics, so we define a custom + // panic hook to implement this behaviour. + // std::process::exit(1); + })); + + _eyre_hook.install().unwrap(); + + if std::env::var("RUST_LOG").is_err() { + std::env::set_var("RUST_LOG", "info"); + } + #[cfg(not(debug_assertions))] + if std::env::var("RUST_SPANTRACE").is_err() { + std::env::set_var("RUST_SPANTRACE", "0"); + } + + use tracing_subscriber::prelude::*; + + let fmt = tracing_subscriber::fmt::layer() + .without_time() + .with_writer(std::io::stderr) + // .pretty() + // .with_file(true) + // .with_line_number(true) + .with_target(false); + + #[cfg(test)] + let fmt = fmt.with_test_writer(); + + #[cfg(debug_assertions)] + let fmt = fmt.with_target(true); + + let filter = tracing_subscriber::EnvFilter::from_default_env(); + + let registry = tracing_subscriber::registry(); + + #[cfg(feature = "console-subscriber")] + // FIXME: this isn't being picked up by tokio-console + let registry = registry.with(console_subscriber::spawn()); + + let registry = registry + // filter on values from RUST_LOG + .with(filter) + // subscriber that emits to stderr + .with(fmt) + // instrument errors with SpanTraces, used by color-eyre + .with(tracing_error::ErrorLayer::default()); + + registry.init(); + // console_subscriber::init(); + }); +} diff --git a/src/ghjk/main.rs b/src/ghjk/main.rs new file mode 100644 index 00000000..95c41ad8 --- /dev/null +++ b/src/ghjk/main.rs @@ -0,0 +1,72 @@ +#[allow(unused)] +mod interlude { + pub use crate::utils::{default, CHeapStr, DHashMap}; + + pub use std::collections::HashMap; + pub use std::path::{Path, PathBuf}; + pub use std::sync::Arc; + + pub use crate::GhjkCtx; + + pub use color_eyre::eyre; + pub use denort::deno::{ + self, + deno_runtime::{ + self, + deno_core::{self, url}, + }, + }; + pub use eyre::{format_err as ferr, Context, Result as Res, WrapErr}; + pub use futures::{future::BoxFuture, FutureExt}; + pub use indexmap::IndexMap; + pub use serde::{Deserialize, Serialize}; + pub use serde_json::json; + pub use smallvec::smallvec as svec; + pub use smallvec::SmallVec as Svec; + pub use tracing::{debug, error, info, trace, warn, Instrument}; + pub use tracing_unwrap::*; +} + +mod host; + +mod cli; +mod config; +mod ext; +mod log; +mod systems; +mod utils; + +use crate::interlude::*; + +fn main() -> Res { + let None = cli::deno_quick_cli() else { + unreachable!(); + }; + + // FIXME: change signal handler for children + // FIXME: use unix_sigpipe once https://github.com/rust-lang/rust/issues/97889 lands + unsafe { + use nix::sys::signal::*; + signal(Signal::SIGPIPE, SigHandler::SigDfl)?; + } + std::env::set_var("DENO_NO_UPDATE_CHECK", "1"); + + log::init(); + denort::init(); + + debug!(version = shadow::PKG_VERSION, "ghjk CLI"); + + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()? + .block_on(cli::cli()) +} + +use shadow_rs::shadow; +shadow!(shadow); + +#[derive(Debug)] +pub struct GhjkCtx { + deno: denort::worker::DenoWorkerHandle, + config: config::Config, +} diff --git a/src/ghjk/systems.rs b/src/ghjk/systems.rs new file mode 100644 index 00000000..c0b34f14 --- /dev/null +++ b/src/ghjk/systems.rs @@ -0,0 +1,149 @@ +//! Systems (formerly modules) are units of implementation that bundle together +//! related functionality. + +use std::any::Any; + +use crate::interlude::*; + +pub mod deno; + +pub enum SystemManifest { + Deno(deno::DenoSystemManifest), +} + +impl SystemManifest { + pub async fn init(&self) -> Res { + match self { + SystemManifest::Deno(man) => Ok(ErasedSystemInstance::new(Arc::new(man.ctor().await?))), + } + } +} + +#[async_trait::async_trait] +pub trait SystemInstance { + type LockState; + + async fn load_config( + &self, + config: serde_json::Value, + bb: ConfigBlackboard, + state: Option, + ) -> Res<()>; + + async fn load_lock_entry(&self, raw: serde_json::Value) -> Res; + + async fn gen_lock_entry(&self) -> Res; + + async fn commands(&self) -> Res>; +} + +type BoxAny = Box; + +#[allow(clippy::type_complexity)] +pub struct ErasedSystemInstance { + load_lock_entry_fn: Box BoxFuture<'static, Res>>, + gen_lock_entry_fn: Box BoxFuture<'static, Res>>, + load_config_fn: Box< + dyn Fn(serde_json::Value, ConfigBlackboard, Option) -> BoxFuture<'static, Res<()>>, + >, + commands_fn: Box BoxFuture<'static, Res>>>, +} + +impl ErasedSystemInstance { + pub fn new(instance: Arc) -> Self + where + S: SystemInstance + Send + Sync + 'static, + L: std::any::Any + Send + Sync, + { + Self { + load_lock_entry_fn: { + let instance = instance.clone(); + Box::new(move |raw| { + let instance = instance.clone(); + async move { + let res: BoxAny = Box::new(instance.load_lock_entry(raw).await?); + Ok(res) + } + .boxed() + }) + }, + gen_lock_entry_fn: { + let instance = instance.clone(); + Box::new(move || { + let instance = instance.clone(); + async move { instance.gen_lock_entry().await }.boxed() + }) + }, + load_config_fn: { + let instance = instance.clone(); + Box::new(move |config, bb, state| { + let instance = instance.clone(); + async move { + let state: Option> = + state.map(|st| st.downcast().expect_or_log("downcast error")); + instance.load_config(config, bb, state.map(|bx| *bx)).await + } + .boxed() + }) + }, + commands_fn: { + let instance = instance.clone(); + Box::new(move || { + let instance = instance.clone(); + async move { instance.commands().await }.boxed() + }) + }, + } + } + + pub async fn load_config( + &self, + config: serde_json::Value, + bb: ConfigBlackboard, + state: Option, + ) -> Res<()> { + (self.load_config_fn)(config, bb, state).await + } + + pub async fn load_lock_entry(&self, raw: serde_json::Value) -> Res { + (self.load_lock_entry_fn)(raw).await + } + + pub async fn gen_lock_entry(&self) -> Res { + (self.gen_lock_entry_fn)().await + } + + pub async fn commands(&self) -> Res> { + (self.commands_fn)().await + } +} + +pub type SystemId = CHeapStr; + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub struct SystemConfig { + pub id: SystemId, + pub config: serde_json::Value, +} + +pub type CliCommandAction = + Box BoxFuture<'static, Res<()>> + Send + Sync>; + +pub struct SystemCliCommand { + pub name: CHeapStr, + pub clap: clap::Command, + pub sub_commands: IndexMap, + pub action: Option, +} + +impl std::fmt::Debug for SystemCliCommand { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SystemCliCommand") + .field("name", &self.name) + .field("sub_commands", &self.sub_commands) + .field("actions", &self.action.is_some()) + .finish() + } +} + +pub type ConfigBlackboard = Arc>; diff --git a/src/ghjk/systems/deno.rs b/src/ghjk/systems/deno.rs new file mode 100644 index 00000000..bee5aa85 --- /dev/null +++ b/src/ghjk/systems/deno.rs @@ -0,0 +1,321 @@ +//! This module implements support for systems written in typescript +//! running on top of deno. + +use crate::interlude::*; + +use super::{SystemCliCommand, SystemId, SystemInstance, SystemManifest}; + +mod cli; + +#[derive(Clone)] +pub struct DenoSystemsContext { + callbacks: crate::ext::CallbacksHandle, + exit_code_channel: Arc>>>>, + term_signal: tokio::sync::watch::Sender, + #[allow(unused)] + hostcalls: crate::ext::Hostcalls, +} + +impl DenoSystemsContext { + #[allow(unused)] + pub async fn terminate(mut self) -> Res<()> { + let channel = { + let mut opt = self.exit_code_channel.lock().expect_or_log("mutex error"); + opt.take() + }; + let Some(channel) = channel else { + eyre::bail!("already terminated") + }; + self.term_signal.send(true).expect_or_log("channel error"); + channel.await.expect_or_log("channel error") + } +} + +#[tracing::instrument(skip(gcx))] +pub async fn systems_from_deno( + gcx: &GhjkCtx, + source_uri: &url::Url, + ghjkdir_path: &Path, +) -> Res<(HashMap, DenoSystemsContext)> { + let main_module = gcx + .config + .repo_root + .join("src/deno_systems/bindings.ts") + .wrap_err("repo url error")?; + + let mut ext_conf = crate::ext::ExtConfig::new(); + + let bb = ext_conf.blackboard.clone(); + bb.insert("args".into(), { + #[derive(Serialize)] + struct ConfigRef<'a> { + pub ghjkfile: Option<&'a Path>, + pub ghjkdir: &'a Path, + pub data_dir: &'a Path, + pub deno_dir: &'a Path, + pub deno_lockfile: Option<&'a Path>, + pub repo_root: &'a url::Url, + } + + #[derive(Serialize)] + struct BindingArgs<'a> { + uri: url::Url, + config: ConfigRef<'a>, + } + let crate::config::Config { + repo_root, + ghjkdir: _, + data_dir, + deno_lockfile, + ghjkfile, + deno_dir, + } = &gcx.config; + + json!(BindingArgs { + uri: source_uri.clone(), + config: ConfigRef { + ghjkfile: ghjkfile.as_ref().map(|path| path.as_path()), + ghjkdir: ghjkdir_path, + data_dir, + deno_lockfile: deno_lockfile.as_ref().map(|path| path.as_path()), + deno_dir, + repo_root + }, + }) + }); + let hostcalls = ext_conf.hostcalls.clone(); + + let (manifests_tx, mut manifests_rx) = tokio::sync::mpsc::channel(1); + hostcalls.funcs.insert( + "register_systems".into(), + Box::new(move |args| { + let tx = manifests_tx.clone(); + async move { + tx.send(args).await.expect_or_log("channel error"); + Ok(serde_json::Value::Null) + } + .boxed() + }), + ); + let cb_line = ext_conf.callbacks_handle(&gcx.deno); + let mut exception_line = ext_conf.exceptions_rx(); + + let mut worker = gcx + .deno + .prepare_module( + main_module, + deno_runtime::deno_permissions::PermissionsOptions { + allow_env: Some(vec![]), + allow_import: Some(vec![]), + allow_read: Some(vec![]), + allow_net: Some(vec![]), + allow_ffi: Some(vec![]), + allow_run: Some(vec![]), + allow_sys: Some(vec![]), + allow_write: Some(vec![]), + allow_all: true, + prompt: false, + ..default() + }, + deno_runtime::WorkerExecutionMode::Run, + default(), + Some(crate::ext::extensions(ext_conf)), + ) + .await?; + worker.execute().await?; + let mut active_worker = worker.drive_till_exit().await?; + + let manifests = tokio::select! { + res = &mut active_worker.exit_code_rx => { + let exit_code = res + .expect_or_log("channel error") + .wrap_err("deno systems error building manifests")?; + eyre::bail!("premature exit of deno systems before manifests were sent: exit code = {exit_code}"); + }, + manifests = manifests_rx.recv() => { + manifests.expect_or_log("channel error") + } + }; + + let manifests: Vec = + serde_json::from_value(manifests).wrap_err("protocol error")?; + + let term_signal = active_worker.term_signal_tx.clone(); + let join_exit_code_watcher = { + let dcx = gcx.deno.clone(); + tokio::spawn(async move { + let res; + loop { + res = tokio::select! { + res = &mut active_worker.exit_code_rx => { + match res { + Ok(res) => res.wrap_err("error on deno worker for deno systems"), + Err(_) => Err(ferr!("deno systems unexpected shutdown")) + } + } + Some(err) = exception_line.recv() => { + // NOTE: we only log the error here + // this assumes that the systems are processing + // a callback and that they will recieve an EventError + // when the event loop continues + // mostly relevant for Worker errors + error!("event loop error caught: {err}"); + continue; + } + }; + break; + } + let err = match res { + Ok(0) => return Ok(()), + Ok(exit_code) => { + ferr!("deno systems died with non-zero exit code: {exit_code}") + } + Err(err) => err, + }; + error!("deno systems error: {err:?}"); + dcx.terminate() + .await + .expect_or_log("error terminating deno worker"); + Err(err) + }) + }; + + let exit_code_channel = Arc::new(std::sync::Mutex::new(Some(join_exit_code_watcher))); + + let scx = DenoSystemsContext { + callbacks: cb_line, + hostcalls, + term_signal, + exit_code_channel, + }; + + let manifests = manifests + .into_iter() + .map(|desc| { + ( + desc.id.clone(), + SystemManifest::Deno(DenoSystemManifest { + desc, + scx: scx.clone(), + }), + ) + }) + .collect(); + + Ok((manifests, scx)) +} + +#[derive(Debug, Deserialize)] +struct ManifestDesc { + id: SystemId, + ctor_cb_key: CHeapStr, +} + +#[derive(educe::Educe)] +#[educe(Debug)] +pub struct DenoSystemManifest { + desc: ManifestDesc, + #[educe(Debug(ignore))] + scx: DenoSystemsContext, +} + +impl DenoSystemManifest { + #[tracing::instrument] + pub async fn ctor(&self) -> Res { + trace!("initializing deno system"); + let desc = self + .scx + .callbacks + .exec(self.desc.ctor_cb_key.clone(), serde_json::Value::Null) + .await?; + + let desc = serde_json::from_value(desc).wrap_err("protocol error")?; + + trace!("deno system initialized"); + + Ok(DenoSystemInstance { + desc, + scx: self.scx.clone(), + }) + } +} + +#[derive(Debug, Deserialize)] +/// This is the description sent from the typescript side for a registered manifest. +struct InstanceDesc { + load_lock_entry_cb_key: CHeapStr, + gen_lock_entry_cb_key: CHeapStr, + load_config_cb_key: CHeapStr, + cli_commands_cb_key: CHeapStr, +} + +pub struct DenoSystemInstance { + desc: InstanceDesc, + scx: DenoSystemsContext, +} + +#[async_trait::async_trait] +impl SystemInstance for DenoSystemInstance { + type LockState = serde_json::Value; + + async fn load_config( + &self, + config: serde_json::Value, + bb: Arc>, + state: Option, + ) -> Res<()> { + self.scx + .callbacks + .exec( + self.desc.load_config_cb_key.clone(), + json!({ + "config": config, + "bb": bb, + "state": state + }), + ) + .await + .wrap_err("callback error")?; + Ok(()) + } + + async fn load_lock_entry(&self, raw: serde_json::Value) -> Res { + self.scx + .callbacks + .exec( + self.desc.load_lock_entry_cb_key.clone(), + json!({ + "raw": raw + }), + ) + .await + .wrap_err("callback error") + } + + async fn gen_lock_entry(&self) -> Res { + self.scx + .callbacks + .exec(self.desc.gen_lock_entry_cb_key.clone(), json!({})) + .await + .wrap_err("callback error") + } + + async fn commands(&self) -> Res> { + let cmds = self + .scx + .callbacks + .exec(self.desc.cli_commands_cb_key.clone(), json!({})) + .await + .wrap_err("callback error")?; + + let cmds: Vec = + serde_json::from_value(cmds).wrap_err("protocol error")?; + + let cmds = cmds + .into_iter() + .map(|cmd| cmd.convert(self.scx.clone())) + .collect(); + + Ok(cmds) + } +} diff --git a/src/ghjk/systems/deno/cli.rs b/src/ghjk/systems/deno/cli.rs new file mode 100644 index 00000000..668d47d1 --- /dev/null +++ b/src/ghjk/systems/deno/cli.rs @@ -0,0 +1,400 @@ +//! Types and conversions for runtime specified CLI commands +//! from deno systems + +use crate::{interlude::*, systems::CliCommandAction}; + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct CliCommandDesc { + pub name: String, + + pub hide: Option, + + pub aliases: Option>, + pub visible_aliases: Option>, + + pub about: Option, + pub before_help: Option, + pub before_long_help: Option, + + pub args: Option>, + pub flags: Option>, + pub sub_commands: Option>, + + pub disable_help_subcommand: Option, + + pub action_cb_key: Option, +} + +impl CliCommandDesc { + #[tracing::instrument(skip(scx))] + pub fn convert(self, scx: super::DenoSystemsContext) -> crate::systems::SystemCliCommand { + let name = self.name; + let mut cmd = clap::Command::new(name.clone()).name(name.clone()); + + if let Some(val) = self.hide { + cmd = cmd.hide(val) + } + if let Some(val) = self.aliases { + cmd = cmd.aliases(val) + } + if let Some(val) = self.visible_aliases { + cmd = cmd.visible_aliases(val) + } + if let Some(val) = &self.about { + cmd = cmd.about(val) + } + if let Some(val) = self.before_help { + cmd = cmd.before_help(val) + } + if let Some(val) = self.before_long_help { + cmd = cmd.before_long_help(val) + } + if let Some(val) = self.disable_help_subcommand { + cmd = cmd.disable_help_subcommand(val) + } + let flag_ids = if let Some(val) = &self.flags { + let mut ids = ahash::HashSet::default(); + for (id, desc) in val { + ids.insert(id.clone()); + let arg = desc.convert(id); + cmd = cmd.arg(arg); + } + ids + } else { + default() + }; + + if let Some(val) = &self.args { + for (id, desc) in val { + if flag_ids.contains(id) { + panic!("flag and arg id clash at {id}"); + } + let arg = desc.convert(id); + cmd = cmd.arg(arg); + } + } + let sub_commands = if let Some(val) = self.sub_commands { + let mut subcommands = IndexMap::new(); + for desc in val { + let id = desc.name.clone(); + let scmd = desc.convert(scx.clone()); + subcommands.insert(id.into(), scmd); + } + subcommands + } else { + default() + }; + + let action: Option = if let Some(val) = self.action_cb_key { + let cb_key = CHeapStr::from(val); + let flags = self.flags.unwrap_or_default(); + let flags = Arc::new(flags); + let args = self.args.unwrap_or_default(); + let args = Arc::new(args); + Some(Box::new(move |matches| { + let scx = scx.clone(); + let cb_key = cb_key.clone(); + let flags = flags.clone(); + let args = args.clone(); + deno_cb_action(matches, scx.clone(), cb_key, flags, args).boxed() + })) + } else { + /* if sub_commands.is_empty() { + error!("a system command has no action or subcommands attached"); + } */ + None + }; + + crate::systems::SystemCliCommand { + name: name.into(), + clap: cmd, + sub_commands, + action, + } + } +} + +async fn deno_cb_action( + mut matches: clap::ArgMatches, + scx: super::DenoSystemsContext, + cb_key: CHeapStr, + flag_descs: Arc>, + args_descs: Arc>, +) -> Res<()> { + let mut flags = IndexMap::new(); + let mut args = IndexMap::new(); + + let match_ids = matches + .ids() + .map(|id| id.as_str().to_owned()) + .collect::>() + .into_iter(); + for id in match_ids { + let Some(desc) = flag_descs + .get(&id) + .map(|flag| &flag.arg) + .or_else(|| args_descs.get(&id)) + else { + unreachable!("unspecified arg id found: {id}"); + }; + let value = match desc.action.unwrap_or(ArgActionSerde::Set) { + ArgActionSerde::Set => matches + .try_remove_one::(id.as_str()) + .wrap_err_with(|| format!("error extracting match string for {id}"))? + .map(|val| json!(val)), + ArgActionSerde::Append => matches + .try_remove_many::(id.as_str()) + .wrap_err_with(|| format!("error extracting match bool for {id}"))? + .map(|vals| vals.collect::>()) + .map(|val| json!(val)), + ArgActionSerde::SetTrue | ArgActionSerde::SetFalse => matches + .try_remove_one::(id.as_str()) + .wrap_err_with(|| format!("error extracting match bool for {id}"))? + .map(|val| json!(val)), + ArgActionSerde::Count => matches + .try_remove_one::(id.as_str()) + .wrap_err_with(|| format!("error extracting match count for {id}"))? + .map(|val| json!(val)), + ArgActionSerde::Help + | ArgActionSerde::HelpShort + | ArgActionSerde::HelpLong + | ArgActionSerde::Version => unreachable!(), + }; + let Some(value) = value else { + continue; + }; + + let bucket = if flag_descs.contains_key(id.as_str()) { + &mut flags + } else { + &mut args + }; + + bucket.insert(id.as_str().to_owned(), value); + } + let response = scx + .callbacks + .exec( + cb_key.clone(), + json!({ + "flags": flags, + "args": args + }), + ) + .await + .wrap_err("callback error")?; + debug!(?response, "system command action response"); + Ok(()) +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct CliArgDesc { + pub required: Option, + pub global: Option, + pub hide: Option, + pub exclusive: Option, + pub trailing_var_arg: Option, + pub allow_hyphen_values: Option, + + pub action: Option, + + pub value_name: Option, + pub value_hint: Option, + + pub long: Option, + pub long_aliases: Option>, + pub visible_long_aliases: Option>, + + pub short: Option, + pub short_aliases: Option>, + pub visible_short_aliases: Option>, + + pub env: Option, + + pub help: Option, + pub long_help: Option, +} + +impl CliArgDesc { + pub fn convert(&self, id: &str) -> clap::Arg { + let mut arg = clap::Arg::new(id.to_owned()); + + if let Some(val) = self.required { + arg = arg.required(val) + } + if let Some(val) = self.global { + arg = arg.global(val) + } + if let Some(val) = self.hide { + arg = arg.hide(val) + } + if let Some(val) = self.exclusive { + arg = arg.exclusive(val) + } + if let Some(val) = self.trailing_var_arg { + arg = arg.num_args(..).trailing_var_arg(val) + } + if let Some(val) = self.allow_hyphen_values { + arg = arg.allow_hyphen_values(val) + } + + if let Some(val) = self.action { + arg = arg.action(clap::ArgAction::from(val)) + } + + if let Some(val) = &self.value_name { + arg = arg.value_name(val) + } + + if let Some(val) = self.value_hint { + arg = arg.value_hint(clap::ValueHint::from(val)) + } + + if let Some(val) = &self.long { + arg = arg.long(val) + } + if let Some(val) = &self.long_aliases { + arg = arg.aliases(val) + }; + if let Some(val) = &self.visible_long_aliases { + arg = arg.visible_aliases(val) + }; + + if let Some(val) = self.short { + arg = arg.short(val) + }; + if let Some(val) = &self.short_aliases { + arg = arg.short_aliases(val.clone()) + }; + if let Some(val) = &self.visible_short_aliases { + arg = arg.short_aliases(val.clone()) + }; + + if let Some(val) = &self.env { + arg = arg.env(val) + }; + + if let Some(val) = &self.help { + arg = arg.help(val) + }; + + if let Some(val) = &self.long_help { + arg = arg.long_help(val) + }; + + arg + } +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct CliFlagDesc { + #[serde(flatten)] + pub arg: CliArgDesc, + + pub long: Option, + pub long_aliases: Option>, + pub visible_long_aliases: Option>, + + pub short: Option, + pub short_aliases: Option>, + pub visible_short_aliases: Option>, +} + +impl CliFlagDesc { + pub fn convert(&self, id: &str) -> clap::Arg { + let mut arg = self.arg.convert(id); + + if let Some(val) = &self.long { + arg = arg.long(val) + } + if let Some(val) = &self.long_aliases { + arg = arg.aliases(val) + }; + if let Some(val) = &self.visible_long_aliases { + arg = arg.visible_aliases(val) + }; + + if let Some(val) = self.short { + arg = arg.short(val) + }; + if let Some(val) = &self.short_aliases { + arg = arg.short_aliases(val.clone()) + }; + if let Some(val) = &self.visible_short_aliases { + arg = arg.short_aliases(val.clone()) + }; + + arg + } +} + +#[derive(Deserialize, Debug, Clone, Copy)] +pub enum ValueHintSerde { + Unknown, + Other, + AnyPath, + FilePath, + DirPath, + ExecutablePath, + CommandName, + CommandString, + CommandWithArguments, + Username, + Hostname, + Url, + EmailAddress, +} + +impl From for clap::ValueHint { + fn from(val: ValueHintSerde) -> Self { + use ValueHintSerde::*; + match val { + Unknown => clap::ValueHint::Unknown, + Other => clap::ValueHint::Other, + AnyPath => clap::ValueHint::AnyPath, + FilePath => clap::ValueHint::FilePath, + DirPath => clap::ValueHint::DirPath, + ExecutablePath => clap::ValueHint::ExecutablePath, + CommandName => clap::ValueHint::CommandName, + CommandString => clap::ValueHint::CommandString, + CommandWithArguments => clap::ValueHint::CommandWithArguments, + Username => clap::ValueHint::Username, + Hostname => clap::ValueHint::Hostname, + Url => clap::ValueHint::Url, + EmailAddress => clap::ValueHint::EmailAddress, + } + } +} + +#[derive(Deserialize, Debug, Clone, Copy)] +pub enum ArgActionSerde { + Set, + Append, + SetTrue, + SetFalse, + Count, + Help, + HelpShort, + HelpLong, + Version, +} + +impl From for clap::ArgAction { + fn from(val: ArgActionSerde) -> Self { + use ArgActionSerde::*; + match val { + Set => clap::ArgAction::Set, + Append => clap::ArgAction::Append, + SetTrue => clap::ArgAction::SetTrue, + SetFalse => clap::ArgAction::SetFalse, + Count => clap::ArgAction::Count, + Help => clap::ArgAction::Help, + HelpShort => clap::ArgAction::HelpShort, + HelpLong => clap::ArgAction::HelpLong, + Version => clap::ArgAction::Version, + } + } +} diff --git a/src/ghjk/utils.rs b/src/ghjk/utils.rs new file mode 100644 index 00000000..f3d7422c --- /dev/null +++ b/src/ghjk/utils.rs @@ -0,0 +1,261 @@ +use crate::interlude::*; + +use std::io::Write; + +#[inline] +pub fn default() -> T { + T::default() +} + +pub type DHashMap = dashmap::DashMap; +pub use cheapstr::CHeapStr; + +mod cheapstr { + use crate::interlude::*; + + use std::{ + borrow::Cow, + hash::{Hash, Hasher}, + }; + // lifted from github.com/bevyengine/bevy 's bevy_core/Name struct + // MIT/APACHE2 licence + #[derive(Clone, Serialize, Deserialize)] + #[serde(crate = "serde", from = "String", into = "String")] + pub struct CHeapStr { + hash: u64, + string: Cow<'static, str>, + } + + impl CHeapStr { + /// Creates a new [`IdUnique`] from any string-like type. + pub fn new(string: impl Into>) -> Self { + let string = string.into(); + let mut id = Self { string, hash: 0 }; + id.update_hash(); + id + } + + /// Gets the name of the entity as a `&str`. + #[inline] + pub fn as_str(&self) -> &str { + &self.string + } + + fn update_hash(&mut self) { + let mut hasher = ahash::AHasher::default(); + self.string.hash(&mut hasher); + self.hash = hasher.finish(); + } + } + + impl From for CHeapStr + where + T: Into>, + { + #[inline(always)] + fn from(string: T) -> Self { + Self::new(string) + } + } + + impl Hash for CHeapStr { + fn hash(&self, state: &mut H) { + self.string.hash(state); + } + } + + impl PartialEq for CHeapStr { + fn eq(&self, other: &Self) -> bool { + if self.hash != other.hash { + // Makes the common case of two strings not been equal very fast + return false; + } + + self.string.eq(&other.string) + } + } + + impl Eq for CHeapStr {} + + impl PartialOrd for CHeapStr { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl Ord for CHeapStr { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.string.cmp(&other.string) + } + } + + impl std::ops::Deref for CHeapStr { + type Target = Cow<'static, str>; + + fn deref(&self) -> &Self::Target { + &self.string + } + } + + impl std::borrow::Borrow for CHeapStr { + fn borrow(&self) -> &str { + &self[..] + } + } + + impl From for String { + fn from(value: CHeapStr) -> String { + // FIXME: optmize this + /* let string = if let Some(s) = Arc::get_mut(&mut self.0) { + unsafe { + String::from_raw_parts( + s as *mut str as *mut u8, + s.len(), + s.len() + ) + } + } else { + (&self.0[..]).to_string() + }; + std::mem::forget(self.0); + string */ + value.string.into_owned() + } + } + + impl std::fmt::Display for CHeapStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.string.fmt(f) + } + } + + impl std::fmt::Debug for CHeapStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.string.fmt(f) + } + } +} + +const SHA2_256: u64 = 0x12; + +pub fn hash_obj(obj: &T) -> String { + use sha2::Digest; + let mut hash = sha2::Sha256::new(); + json_canon::to_writer(&mut hash, obj).expect_or_log("error serializing manifest"); + let hash = hash.finalize(); + + let hash = + multihash::Multihash::<32>::wrap(SHA2_256, &hash[..]).expect_or_log("error multihashing"); + encode_base32_multibase(hash.digest()) +} + +pub fn hash_str(string: &str) -> String { + hash_bytes(string.as_bytes()) +} + +pub fn hash_bytes(bytes: &[u8]) -> String { + use sha2::Digest; + let mut hash = sha2::Sha256::new(); + hash.write(bytes).expect_or_log("error writing to hasher"); + let hash = hash.finalize(); + + let hash = + multihash::Multihash::<32>::wrap(SHA2_256, &hash[..]).expect_or_log("error multihashing"); + encode_base32_multibase(hash.digest()) +} + +pub async fn hash_reader(reader: T) -> Res { + use sha2::Digest; + use tokio::io::*; + let mut hash = sha2::Sha256::new(); + let mut buf = vec![0u8; 65536]; + + let reader = tokio::io::BufReader::new(reader); + + let mut reader = std::pin::pin!(reader); + + loop { + // Read a chunk of data + let bytes_read = reader.read(&mut buf).await?; + + // Break the loop if we reached EOF + if bytes_read == 0 { + break; + } + hash.write(&buf[..bytes_read]) + .expect_or_log("error writing to hasher"); + } + let hash = hash.finalize(); + + let hash = + multihash::Multihash::<32>::wrap(SHA2_256, &hash[..]).expect_or_log("error multihashing"); + let hash = encode_base32_multibase(hash.digest()); + Ok(hash) +} + +pub fn encode_base32_multibase>(source: T) -> String { + format!( + "b{}", + data_encoding::BASE32_NOPAD + .encode(source.as_ref()) + .to_lowercase() + ) +} + +#[allow(unused)] +// Consider z-base32 https://en.wikipedia.org/wiki/Base32#z-base-32 +pub fn decode_base32_multibase(source: &str) -> eyre::Result> { + match ( + &source[0..1], + data_encoding::BASE32_NOPAD.decode(source[1..].as_bytes()), + ) { + ("b", Ok(bytes)) => Ok(bytes), + (prefix, Ok(_)) => Err(eyre::format_err!( + "unexpected multibase prefix for base32 multibase: {prefix}" + )), + (_, Err(err)) => Err(eyre::format_err!("error decoding base32: {err}")), + } +} + +#[allow(unused)] +pub fn encode_hex_multibase>(source: T) -> String { + format!( + "f{}", + data_encoding::HEXLOWER_PERMISSIVE.encode(source.as_ref()) + ) +} + +#[allow(unused)] +pub fn decode_hex_multibase(source: &str) -> eyre::Result> { + match ( + &source[0..1], + data_encoding::HEXLOWER_PERMISSIVE.decode(source[1..].as_bytes()), + ) { + ("f", Ok(bytes)) => Ok(bytes), + (prefix, Ok(_)) => Err(eyre::format_err!( + "unexpected multibase prefix for hex multibase: {prefix}" + )), + (_, Err(err)) => Err(eyre::format_err!("error decoding hex: {err}")), + } +} + +pub async fn find_entry_recursive(from: &Path, name: &str) -> Res> { + let mut cur = from; + loop { + let location = cur.join(name); + match tokio::fs::try_exists(&location).await { + Ok(true) => { + return Ok(Some(location)); + } + Err(err) if err.kind() != std::io::ErrorKind::NotFound => { + return Err(err).wrap_err("error on file stat"); + } + _ => { + let Some(next_cur) = cur.parent() else { + return Ok(None); + }; + cur = next_cur; + } + } + } +} diff --git a/src/play/Cargo.toml b/src/play/Cargo.toml new file mode 100644 index 00000000..f12e33aa --- /dev/null +++ b/src/play/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "play" +version.workspace = true +edition.workspace = true + +[[bin]] +name = "play" +path = "main.rs" + +[dependencies] + +tracing-unwrap.workspace = true + +color-eyre.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +once_cell.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +tokio = { workspace = true, features = ["full", "parking_lot"] } +data-encoding = "2.6.0" +sha2 = "0.10.8" +futures-concurrency = "7.6.2" diff --git a/src/play/main.rs b/src/play/main.rs new file mode 100644 index 00000000..6994e430 --- /dev/null +++ b/src/play/main.rs @@ -0,0 +1,20 @@ +#![allow(unused)] + +use futures_concurrency::prelude::*; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +type BoxErr = Box; +type Res = Result; + +fn main() { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(async { + // playground + }); +} diff --git a/src/xtask/Cargo.toml b/src/xtask/Cargo.toml new file mode 100644 index 00000000..8bda8e04 --- /dev/null +++ b/src/xtask/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "xtask" +version.workspace = true +edition.workspace = true + +[[bin]] +name = "xtask" +path = "main.rs" + +[dependencies] +denort.workspace = true + +tracing-unwrap.workspace = true + +color-eyre.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +once_cell.workspace = true +clap = { workspace = true, features = ["derive", "env"] } diff --git a/src/xtask/main.rs b/src/xtask/main.rs new file mode 100644 index 00000000..a1841abd --- /dev/null +++ b/src/xtask/main.rs @@ -0,0 +1,99 @@ +#[allow(unused)] +mod interlude { + pub use std::future::Future; + pub use std::path::{Path, PathBuf}; + pub use std::sync::Arc; + + pub use color_eyre::eyre; + pub use eyre::{format_err as ferr, Context, Result as Res, WrapErr}; + pub use tracing::{debug, error, info, trace, warn}; + pub use tracing_unwrap::*; +} +use clap::builder::styling::AnsiColor; + +use crate::interlude::*; + +mod utils; + +fn main() -> Res<()> { + utils::setup_tracing()?; + let cwd = std::env::current_dir()?; + + use clap::Parser; + let args = Args::parse(); + match args.command { + Commands::Test { files, filter } => { + use denort::deno::deno_config; + denort::test_sync( + deno_config::glob::FilePatterns { + include: if let Some(vec) = files { + Some(deno_config::glob::PathOrPatternSet::new( + vec.into_iter() + .map(|path| { + deno_config::glob::PathOrPattern::from_relative(&cwd, &path) + }) + .collect::, _>>()?, + )) + } else { + None + }, + exclude: deno_config::glob::PathOrPatternSet::new(vec![]), + base: cwd, + }, + "deno.jsonc".into(), + denort::deno::args::PermissionFlags { + allow_all: true, + ..Default::default() + }, + None, + filter, + Arc::new(std::vec::Vec::new), + vec![], + ) + } /* Commands::Run { argv } => denort::run_sync( + denort::deno::deno_runtime::deno_core::resolve_url_or_path("ghjk.ts", &cwd).unwrap(), + Some("deno.jsonc".into()), + denort::deno::args::PermissionFlags { + allow_all: true, + ..Default::default() + }, + Arc::new(std::vec::Vec::new), + ), */ + } + + Ok(()) +} + +const CLAP_STYLE: clap::builder::Styles = clap::builder::Styles::styled() + .header(AnsiColor::Yellow.on_default()) + .usage(AnsiColor::Green.on_default()) + .literal(AnsiColor::Green.on_default()) + .placeholder(AnsiColor::Green.on_default()); + +#[derive(Debug, clap::Parser)] +#[clap( + version, + about, + styles = CLAP_STYLE +)] +struct Args { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Debug, clap::Subcommand)] +enum Commands { + /* #[clap(visible_alias = "r")] + Run { + /// Script arg + argv: Vec, + }, */ + #[clap(visible_alias = "t")] + Test { + /// Files to test + files: Option>, + /// Tests to include + #[arg(long)] + filter: Option, + }, +} diff --git a/src/xtask/utils.rs b/src/xtask/utils.rs new file mode 100644 index 00000000..32026b1c --- /dev/null +++ b/src/xtask/utils.rs @@ -0,0 +1,29 @@ +use crate::interlude::*; + +// Ensure that the `tracing` stack is only initialised once using `once_cell` +// isn't required in cargo-nextest since each test runs in a new process +#[cfg(test)] +pub fn _setup_tracing_once() { + use once_cell::sync::Lazy; + static TRACING: Lazy<()> = Lazy::new(|| { + setup_tracing().expect("failed to init tracing"); + }); + Lazy::force(&TRACING); +} + +pub fn setup_tracing() -> eyre::Result<()> { + color_eyre::install()?; + if std::env::var("RUST_LOG").is_err() { + std::env::set_var("RUST_LOG", "info"); + } + + // tracing_log::LogTracer::init()?; + tracing_subscriber::fmt() + .compact() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .with_timer(tracing_subscriber::fmt::time::uptime()) + .try_init() + .map_err(|err| eyre::eyre!(err))?; + + Ok(()) +} diff --git a/std/sedLock.ts b/std/sedLock.ts index c94961be..a32af009 100644 --- a/std/sedLock.ts +++ b/std/sedLock.ts @@ -1,3 +1,7 @@ +/** + * TODO: show diff on replacement. + */ + import { $, Path, unwrapZodRes } from "../utils/mod.ts"; import { std_fs, zod } from "../deps/common.ts"; diff --git a/tests/envHooks.ts b/tests/envHooks.ts index 963ea072..f62ac73f 100644 --- a/tests/envHooks.ts +++ b/tests/envHooks.ts @@ -49,7 +49,7 @@ const fishInteractiveScript = [ ] .join("\n"); -type CustomE2eTestCase = Omit & { +type CustomE2eTestCase = Omit & { ePoint: string; stdin: string; }; @@ -60,9 +60,7 @@ const cases: CustomE2eTestCase[] = [ // -s: read from stdin // -l: login mode // -i: make it interactive - ePoint: Deno.env.get("GHJK_TEST_E2E_TYPE") == "local" - ? `bash --rcfile $BASH_ENV -si` // we don't want to use the system rcfile - : `bash -sil`, + ePoint: `bash --rcfile $BASH_ENV -si`, // we don't want to use the system rcfile stdin: posixInteractiveScript, }, { @@ -80,7 +78,8 @@ const cases: CustomE2eTestCase[] = [ harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: ` + fs: { + "ghjk.ts": ` export { sophon } from "$ghjk/hack.ts"; import { task, env } from "$ghjk/hack.ts"; @@ -88,6 +87,7 @@ env("main") .onEnter(task($ => $\`/bin/sh -c 'echo remark > marker'\`)) .onExit(task($ => $\`/bin/sh -c 'rm marker'\`)) `, + }, ePoints: [{ cmd: testCase.ePoint, stdin: testCase.stdin }], name: `envHooks/${testCase.name}`, }))); diff --git a/tests/envs.ts b/tests/envs.ts index 05106a7b..b7f19007 100644 --- a/tests/envs.ts +++ b/tests/envs.ts @@ -9,7 +9,7 @@ import dummy from "../ports/dummy.ts"; import type { FileArgs } from "../mod.ts"; type CustomE2eTestCase = - & Omit + & Omit & { ePoint: string; stdin: string; @@ -47,6 +47,7 @@ const envVarTestEnvs: EnvDefArgs[] = [ ]; const envVarTestsPosix = ` set -ex +env # by default, we should be in main [ "$SONG" = "ditto" ] || exit 1010 [ "$GHJK_ENV" = "main" ] || exit 1011 @@ -57,6 +58,7 @@ ghjk_deactivate [ "$GHJK_ENV" = "main" ] && exit 1022 ghjk envs cook sss +echo $? . .ghjk/envs/sss/activate.sh # by default, envs should be based on main # so they should inherit it's env vars @@ -333,14 +335,16 @@ test (dummy) = "e1"; or exit 105 harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: "ghjkTs" in testCase ? testCase.ghjkTs : genTsGhjkFile( - { - secureConf: { - ...testCase.secureConfig, - envs: [...testCase.envs, ...(testCase.secureConfig?.envs ?? [])], + fs: { + "ghjk.ts": "ghjkTs" in testCase ? testCase.ghjkTs : genTsGhjkFile( + { + secureConf: { + ...testCase.secureConfig, + envs: [...testCase.envs, ...(testCase.secureConfig?.envs ?? [])], + }, }, - }, - ), + ), + }, ePoints: [{ cmd: testCase.ePoint, stdin: testCase.stdin }], name: `envs/${testCase.name}`, }))); diff --git a/tests/hashfile.ts b/tests/hashfile.ts new file mode 100644 index 00000000..a7227379 --- /dev/null +++ b/tests/hashfile.ts @@ -0,0 +1,75 @@ +import "../setup_logger.ts"; +import { E2eTestCase, harness } from "./utils.ts"; + +type CustomE2eTestCase = Omit & { + stdin: string; +}; + +const cases: CustomE2eTestCase[] = [ + { + name: "invalidated_control", + stdin: ` +__ghjk_get_mtime_ts .ghjk/hash.json > tstamp +ghjk sync +test (cat tstamp) = (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +ghjk sync +test (cat tstamp) = (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +`, + }, + { + name: "invalidated_ghjk_modified", + stdin: ` +__ghjk_get_mtime_ts .ghjk/hash.json > tstamp +echo '// hey' >> ghjk.ts +ghjk sync +test (cat tstamp) -lt (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +`, + }, + { + name: "invalidated_dep_script_modified", + stdin: ` +__ghjk_get_mtime_ts .ghjk/hash.json > tstamp +echo '// hey' >> extra.ts +ghjk sync +test (cat tstamp) -lt (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +`, + }, + { + name: "invalidated_env_modified", + stdin: ` +__ghjk_get_mtime_ts .ghjk/hash.json > tstamp +MY_ENV=changed ghjk sync +test (cat tstamp) -lt (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +`, + }, + { + name: "invalidated_listed_file_removed", + stdin: ` +__ghjk_get_mtime_ts .ghjk/hash.json > tstamp +rm dir/one +ghjk sync +test (cat tstamp) -lt (__ghjk_get_mtime_ts .ghjk/hash.json); or exit 101 +`, + }, +]; + +harness(cases.map((testCase) => ({ + ...testCase, + fs: { + "ghjk.ts": ` +export { sophon } from "$ghjk/hack.ts"; +import { task, env } from "$ghjk/hack.ts"; +import {stuff} from "./extra.ts" + +await Array.fromAsync(Deno.readDir("dir")) + +env("main") + .vars({ hello: Deno.env.get("MY_ENV") ?? "world" }) +`, + "extra.ts": `export const stuff = "hello"`, + "dir/one": "1", + "dir/two": "2", + }, + ePoints: [{ cmd: "fish", stdin: testCase.stdin }], + name: `hashfile/${testCase.name}`, +}))); diff --git a/tests/ports.ts b/tests/ports.ts index 2d8b0a96..8487bba2 100644 --- a/tests/ports.ts +++ b/tests/ports.ts @@ -6,7 +6,7 @@ import dummy from "../ports/dummy.ts"; import type { InstallConfigFat } from "../modules/ports/types.ts"; import { testTargetPlatform } from "./utils.ts"; -type CustomE2eTestCase = Omit & { +type CustomE2eTestCase = Omit & { ePoint: string; installConf: InstallConfigFat | InstallConfigFat[]; secureConf?: FileArgs; @@ -28,6 +28,17 @@ const cases: CustomE2eTestCase[] = [ installConf: ports.jq_ghrel(), ePoint: `jq --version`, }, + { + name: "asdf-jq", + ePoint: `jq --version`, + installConf: ports.asdf({ + pluginRepo: "https://github.com/lsanwick/asdf-jq", + installType: "version", + }), + secureConf: { + enableRuntimes: true, + }, + }, // 3 megs { name: "protoc", @@ -150,14 +161,7 @@ const cases: CustomE2eTestCase[] = [ ports.meta_cli_ghrel({ full: true }), ports.wasmedge(), ], - ePoint: Deno.env.get("GHJK_TEST_E2E_TYPE") != "local" - // meta cli runs into segmentation error in the alpine - // image - // https://github.com/metatypedev/metatype/issues/584 - // just check that the shell's able to find the - // executrable - ? `which meta && wasmedge --version` - : `meta --version && wasmedge --version`, + ePoint: `which meta && wasmedge --version`, ignore: testTargetPlatform == "linux/aarch64", }, // 80 meg @@ -166,15 +170,6 @@ const cases: CustomE2eTestCase[] = [ installConf: ports.cpy_bs(), ePoint: `python3 --version`, }, - // 77 meg +, depends on "cpy_bs" on darwin/macos - { - name: "cmake", - installConf: ports.cmake({}), - ePoint: `cmake --version`, - secureConf: { - enableRuntimes: true, - }, - }, // 80 meg + { name: "pipi-poetry", @@ -227,16 +222,18 @@ const cases: CustomE2eTestCase[] = [ harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: genTsGhjkFile( - { - secureConf: { - ...testCase.secureConf, - installs: Array.isArray(testCase.installConf) - ? testCase.installConf - : [testCase.installConf], + fs: { + "ghjk.ts": genTsGhjkFile( + { + secureConf: { + ...testCase.secureConf, + installs: Array.isArray(testCase.installConf) + ? testCase.installConf + : [testCase.installConf], + }, }, - }, - ), + ), + }, ePoints: [ ...["bash -c", "fish -c", "zsh -c"].map((sh) => ({ cmd: [...`env ${sh}`.split(" "), `"${testCase.ePoint}"`], diff --git a/tests/portsOutdated.ts b/tests/portsOutdated.ts index 2519ccd6..4e4b0139 100644 --- a/tests/portsOutdated.ts +++ b/tests/portsOutdated.ts @@ -4,7 +4,7 @@ import * as ports from "../ports/mod.ts"; import type { InstallConfigFat } from "../modules/ports/types.ts"; import { FileArgs } from "../mod.ts"; -type CustomE2eTestCase = Omit & { +type CustomE2eTestCase = Omit & { ePoint: string; installConf: InstallConfigFat | InstallConfigFat[]; secureConf?: FileArgs; @@ -37,16 +37,18 @@ const cases: CustomE2eTestCase[] = [ harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: genTsGhjkFile( - { - secureConf: { - ...testCase.secureConf, - installs: Array.isArray(testCase.installConf) - ? testCase.installConf - : [testCase.installConf], + fs: { + "ghjk.ts": genTsGhjkFile( + { + secureConf: { + ...testCase.secureConf, + installs: Array.isArray(testCase.installConf) + ? testCase.installConf + : [testCase.installConf], + }, }, - }, - ), + ), + }, ePoints: [ ...["bash -c", "fish -c", "zsh -c"].map((sh) => ({ cmd: [...`env ${sh}`.split(" "), `"${testCase.ePoint}"`], diff --git a/tests/reloadHooks.ts b/tests/reloadHooks.ts index fda62982..a29fa5db 100644 --- a/tests/reloadHooks.ts +++ b/tests/reloadHooks.ts @@ -199,7 +199,7 @@ test "$GHJK_ENV" = "test"; or exit 112 ]) .join("\n"); -type CustomE2eTestCase = Omit & { +type CustomE2eTestCase = Omit & { installConf?: InstallConfigFat[]; ePoint: string; stdin: string; @@ -208,9 +208,8 @@ type CustomE2eTestCase = Omit & { // -s: read from stdin // -l: login mode // -i: interactive mode -const bashInteractiveEpoint = Deno.env.get("GHJK_TEST_E2E_TYPE") == "local" - ? `bash --rcfile $BASH_ENV -si` // we don't want to use the system rcfile - : `bash -sil`; +// we don't want to use the system rcfile +const bashInteractiveEpoint = `bash --rcfile $BASH_ENV -si`; const cases: CustomE2eTestCase[] = [ { @@ -297,21 +296,23 @@ const cases: CustomE2eTestCase[] = [ harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: genTsGhjkFile( - { - secureConf: { - envs: [ - { - name: "main", - installs: testCase.installConf ? testCase.installConf : [dummy()], - }, - { - name: "test", - }, - ], + fs: { + "ghjk.ts": genTsGhjkFile( + { + secureConf: { + envs: [ + { + name: "main", + installs: testCase.installConf ? testCase.installConf : [dummy()], + }, + { + name: "test", + }, + ], + }, }, - }, - ), + ), + }, ePoints: [{ cmd: testCase.ePoint, stdin: testCase.stdin }], name: `reloadHooks/${testCase.name}`, }))); diff --git a/tests/tasks.ts b/tests/tasks.ts index d7040949..00b19eaf 100644 --- a/tests/tasks.ts +++ b/tests/tasks.ts @@ -4,7 +4,7 @@ import * as ghjk from "../mod.ts"; import * as ports from "../ports/mod.ts"; type CustomE2eTestCase = - & Omit + & Omit & { ePoint: string; stdin: string; @@ -171,16 +171,18 @@ test (cat output.txt) = 'A#STATIC, B#DYNAMIC' harness(cases.map((testCase) => ({ ...testCase, - tsGhjkfileStr: "ghjkTs" in testCase ? testCase.ghjkTs : genTsGhjkFile( - { - secureConf: { - tasks: Object.fromEntries( - testCase.tasks.map((def) => [def.name!, def]), - ), - enableRuntimes: testCase.enableRuntimesOnMasterPDAL, + fs: { + "ghjk.ts": "ghjkTs" in testCase ? testCase.ghjkTs : genTsGhjkFile( + { + secureConf: { + tasks: Object.fromEntries( + testCase.tasks.map((def) => [def.name!, def]), + ), + enableRuntimes: testCase.enableRuntimesOnMasterPDAL, + }, }, - }, - ), + ), + }, ePoints: [{ cmd: testCase.ePoint, stdin: testCase.stdin }], name: `tasks/${testCase.name}`, }))); diff --git a/tests/test-alpine.Dockerfile b/tests/test-alpine.Dockerfile deleted file mode 100644 index e9655187..00000000 --- a/tests/test-alpine.Dockerfile +++ /dev/null @@ -1,80 +0,0 @@ -ARG DENO_V=1.42.1 - -FROM docker.io/denoland/deno:alpine-${DENO_V} - -ARG BASH_V=5.2.21-r0 -ARG FISH_V=3.6.3-r0 -ARG ZSH_V=5.9-r2 -ARG GIT_V=2.43.0-r0 -ARG CURL_V=8.5.0-r0 -ARG XZ_V=5.4.5-r0 -ARG GTAR_V=1.35-r2 -ARG UNZIP_V=6.0-r14 -ARG ZSTD_V=1.5.5-r8 -ARG GCOMPAT_V=1.1.0-r4 -ARG BUILD_BASE_V=0.5-r3 - -RUN set -eux; \ - apk update; \ - apk add \ - # ambient deps \ - zstd=$ZSTD_V \ - tar=$GTAR_V \ - # test deps \ - bash=$BASH_V \ - fish=$FISH_V \ - zsh=$ZSH_V \ - # asdf deps \ - git=$GIT_V \ - curl=$CURL_V \ - xz=$XZ_V \ - unzip=$UNZIP_V \ - build-base=$BUILD_BASE_V \ - # gcompat=$GCOMPAT_V \ - ca-certificates \ - ; - -WORKDIR /ghjk - -COPY deno.lock deno.jsonc ./ -COPY deps/* ./deps/ -RUN deno task cache - -COPY . ./ - -RUN ln -s ./main.ts /bin/ghjk - -WORKDIR /app - -ENV GHJK_LOG=info -ENV GHJK_INSTALL_EXE_DIR=/usr/bin -ENV GHJK_INSTALL_HOOK_SHELLS=fish,bash,zsh -# share the module cache of the image -ENV GHJK_INSTALL_DENO_DIR=$DENO_DIR -RUN deno run -A /ghjk/install.ts - -ARG GITHUB_TOKEN -ENV GITHUB_TOKEN=$GITHUB_TOKEN - -# avoid variable expansion in the contents of the -# here-document by quoting the tag -COPY <<"EOT" /app/ghjk.ts -#{{CMD_ADD_CONFIG}} -EOT - -RUN <; - ePoints: { cmd: string | string[]; stdin?: string }[]; - timeout_ms?: number; - ignore?: boolean; - only?: boolean; -}; export const testTargetPlatform = Deno.env.get("DOCKER_PLATFORM") ?? (Deno.build.os + "/" + Deno.build.arch); @@ -28,128 +16,83 @@ if ( throw new Error(`unsupported test platform: ${testTargetPlatform}`); } -const dockerPlatform = `--platform=${ - testTargetPlatform - .replace("x86_64", "amd64") - .replace("aarch64", "arm64") -}`; - -const dockerCmd = (Deno.env.get("DOCKER_CMD") ?? "docker").split(/\s/); - -const dFileTemplate = await importRaw(import.meta.resolve("./test.Dockerfile")); -const templateStrings = { - addConfig: `#{{CMD_ADD_CONFIG}}`, +export type E2eTestCase = { + name: string; + fs: Record; + envVars?: Record; + ePoints: { cmd: string | string[]; stdin?: string }[]; + timeout_ms?: number; + ignore?: boolean; + only?: boolean; }; -const noRmi = Deno.env.get("DOCKER_NO_RMI"); - -export async function dockerE2eTest(testCase: E2eTestCase) { - const { name, envVars: testEnvs, ePoints, tsGhjkfileStr } = testCase; - const tag = `ghjk_e2e_${name}`.toLowerCase(); - const env = { - ...testEnvs, - }; - if (Deno.env.get("GITHUB_TOKEN")) { - env.GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN")!; - } - const devGhjkPath = import.meta.resolve("../"); - - const configFile = tsGhjkfileStr - // replace all file urls that point to the ghjk - // repo in the host fs to point to the copy of the - // repo in the image - .replaceAll(devGhjkPath, "file://$ghjk/") - .replaceAll("$ghjk", "/ghjk"); - - const dFile = dbg(dFileTemplate - .replace( - templateStrings.addConfig, - configFile - // escape all dollars - .replaceAll("$", "$$$$"), - )); - - await $ - .raw`${dockerCmd} buildx build ${dockerPlatform} ${ - Object.entries(env).map(([key, val]) => ["--build-arg", `${key}=${val}`]) - } --tag '${tag}' --network=host --output type=docker -f- .` - .env(env) - .stdinText(dFile); - - for (const ePoint of ePoints) { - let cmd = $.raw`${dockerCmd} run ${dockerPlatform} --rm ${[ - /* we want to enable interactivity when piping in */ - ePoint.stdin ? "-i " : "", - ...Object.entries(env).map(([key, val]) => ["-e", `${key}=${val}`]) - .flat(), - tag, - ]} ${ePoint.cmd}` - .env(env); - if (ePoint.stdin) { - cmd = cmd.stdinText(ePoint.stdin!); - } - try { - await cmd; - } catch (err) { - logger(import.meta).error(err); - throw err; - } - } - if (!noRmi) { - await $ - .raw`${dockerCmd} rmi '${tag}'` - .env(env); - } -} export async function localE2eTest(testCase: E2eTestCase) { - const { envVars: testEnvs, ePoints, tsGhjkfileStr } = testCase; + const { envVars: testEnvs, ePoints, fs } = testCase; const tmpDir = $.path( await Deno.makeTempDir({ prefix: "ghjk_le2e_", }), ); - const ghjkShareDir = await tmpDir.join("ghjk").ensureDir(); - - await tmpDir.join("ghjk.ts").writeText( - tsGhjkfileStr.replaceAll( - "$ghjk", - std_url.dirname(import.meta.resolve("../mod.ts")).href, - ), + const ghjkDataDir = await tmpDir.join("ghjk").ensureDir(); + + await $.co( + Object.entries(fs) + .map( + ([path, content]) => + tmpDir.join(path) + .writeText( + content.replaceAll( + "$ghjk", + std_url.dirname(import.meta.resolve("../mod.ts")).href, + ), + ), + ), ); - const env: Record = { + const ghjkExePath = $.path(import.meta.resolve("../target/debug/ghjk")); + const ghjkShimPath = await ghjkDataDir + .join("ghjk") + .writeText( + `#!/bin/sh +exec ${ghjkExePath.resolve().toString()} "$@"`, + { mode: 0o700 }, + ); + + const env: Record = { GHJK_AUTO_HOOK: "true", - BASH_ENV: `${ghjkShareDir.toString()}/env.bash`, - ZDOTDIR: ghjkShareDir.toString(), - GHJK_SHARE_DIR: ghjkShareDir.toString(), - PATH: `${ghjkShareDir.toString()}:${Deno.env.get("PATH")}`, + BASH_ENV: `${ghjkDataDir.toString()}/env.bash`, + ZDOTDIR: ghjkDataDir.toString(), + GHJK_DATA_DIR: ghjkDataDir.toString(), + PATH: `${ghjkShimPath.parentOrThrow().toString()}:${Deno.env.get("PATH")}`, HOME: tmpDir.toString(), + GHJK_REPO_ROOT: import.meta.resolve("../"), + // share the system's deno cache + GHJK_DENO_DIR: Deno.env.get("DENO_DIR") + ? $.path(Deno.env.get("DENO_DIR")!).resolve().toString() + : $.path(Deno.env.get("HOME")!).resolve(".cache", "deno").toString(), + RUST_LOG: Deno.env.get("RUST_LOG"), + GHJK_LOG: Deno.env.get("GHJK_LOG"), ...testEnvs, }; // install ghjk await install({ ...defaultInstallArgs, - skipExecInstall: false, - ghjkExecInstallDir: ghjkShareDir.toString(), - // share the system's deno cache - ghjkDenoCacheDir: Deno.env.get("DENO_DIR") ?? - $.path(Deno.env.get("HOME")!).join(".cache", "deno").toString(), - ghjkShareDir: ghjkShareDir.toString(), + ghjkDataDir: ghjkDataDir.toString(), // don't modify system shell configs shellsToHook: [], }); - await $`${ghjkShareDir.join("ghjk").toString()} print config` + /* await $`ghjk print config` .cwd(tmpDir.toString()) .clearEnv() - .env(env); - await $`${ghjkShareDir.join("ghjk").toString()} envs cook` + .env(env); */ + await $`ghjk envs cook` .cwd(tmpDir.toString()) .clearEnv() .env(env); /* // print the contents of the ghjk dir for debugging purposes const ghjkDirLen = ghjkDir.toString().length; - dbg((await Array.fromAsync(ghjkShareDir.walk())).map((entry) => [ + dbg((await Array.fromAsync(ghjkDataDir.walk())).map((entry) => [ entry.isDirectory ? "dir " : entry.isSymlink ? "ln " : "file", entry.path.toString().slice(ghjkDirLen), ])); @@ -158,7 +101,7 @@ export async function localE2eTest(testCase: E2eTestCase) { const confHome = await tmpDir.join(".config").ensureDir(); const fishConfDir = await confHome.join("fish").ensureDir(); await fishConfDir.join("config.fish").symlinkTo( - ghjkShareDir.join("env.fish").toString(), + ghjkDataDir.join("env.fish").toString(), ); env["XDG_CONFIG_HOME"] = confHome.toString(); } @@ -233,17 +176,11 @@ export function harness( cases: E2eTestCase[], ) { const e2eType = Deno.env.get("GHJK_TEST_E2E_TYPE"); - let runners = [[dockerE2eTest, "e2eDocker" as string] as const]; - if (e2eType == "both") { - runners.push([localE2eTest, "e2eLocal"]); - } else if (e2eType == "local") { - runners = [[localE2eTest, "e2eLocal"]]; - } else if ( - e2eType && e2eType != "docker" - ) { - throw new Error( - `unexpected GHJK_TEST_E2E_TYPE: ${e2eType}`, - ); + const runners = [ + [localE2eTest, "e2eLocal"] as const, + ]; + if (e2eType && e2eType != "local") { + throw new Error("docker test runner has been removed"); } for (const [runner, group] of runners) { for (const testCase of cases) { diff --git a/tools/check.ts b/tools/check.ts new file mode 100755 index 00000000..1231afcb --- /dev/null +++ b/tools/check.ts @@ -0,0 +1,24 @@ +#!/bin/env -S ghjk deno run --allow-env --allow-run --allow-read --allow-write=. + +import "../setup_logger.ts"; +import { $ } from "../utils/mod.ts"; + +const files = (await Array.fromAsync( + $.path(import.meta.url).parentOrThrow().parentOrThrow().expandGlob( + "**/*.ts", + { + exclude: [ + ".git", + ".dev", + "play.ts", + ".ghjk/**", + ".deno-dir/**", + "vendor/**", + ".git/**", // was throwing an error without this + "target/", + ], + }, + ), +)).map((ref) => ref.path.toString()); + +await $`${Deno.env.get("DENO_EXEC_PATH") ?? "deno"} check ${files}`; diff --git a/scripts/dev.ts b/tools/dev.ts similarity index 50% rename from scripts/dev.ts rename to tools/dev.ts index 0209dbac..d6e737c5 100755 --- a/scripts/dev.ts +++ b/tools/dev.ts @@ -14,53 +14,59 @@ const devDir = $.path( // }), ).join("../.dev"); -const ghjkShareDir = await devDir.join("ghjk").ensureDir(); +const ghjkDataDir = await devDir.join("ghjk").ensureDir(); await (await $.removeIfExists(devDir.join("ghjk.ts"))) .symlinkTo(import.meta.resolve("../ghjk.ts")); +const ghjkExePath = $.path(import.meta.resolve("../target/debug/ghjk")); +await ghjkDataDir + .join("ghjk") + .writeText( + `#!/bin/sh +exec ${ghjkExePath.resolve().toString()} "$@"`, + { mode: 0o700 }, + ); + const env: Record = { - BASH_ENV: `${ghjkShareDir.toString()}/env.bash`, - ZDOTDIR: ghjkShareDir.toString(), - GHJK_SHARE_DIR: ghjkShareDir.toString(), - PATH: `${ghjkShareDir.toString()}:${Deno.env.get("PATH")}`, - HOME: devDir.toString(), + BASH_ENV: `${ghjkDataDir.toString()}/env.bash`, + ZDOTDIR: ghjkDataDir.toString(), + GHJK_DATA_DIR: ghjkDataDir.toString(), + PATH: `${ghjkDataDir.toString()}:${Deno.env.get("PATH")}`, + GHJK_CONFIG_DIR: devDir.toString(), + // HOME: devDir.toString(), }; -{ - const confHome = await ghjkShareDir.join(".config").ensureDir(); - const fishConfDir = await confHome.join("fish").ensureDir(); - await (await $.removeIfExists(fishConfDir.join("config.fish"))) - .symlinkTo(ghjkShareDir.join("env.fish").toString()); - env["XDG_CONFIG_HOME"] = confHome.toString(); -} +await devDir.join("config.json").writeJsonPretty({ + "data_dir": ghjkDataDir.toString(), +}); // install ghjk await install({ ...defaultInstallArgs, - skipExecInstall: false, - ghjkExecInstallDir: ghjkShareDir.toString(), - // share the system's deno cache - ghjkDenoCacheDir: Deno.env.get("DENO_DIR") ?? - $.path(Deno.env.get("HOME")!).join(".cache", "deno").toString(), - ghjkShareDir: ghjkShareDir.toString(), + ghjkDataDir: ghjkDataDir.toString(), // don't modify system shell configs shellsToHook: [], }); -// await $`${ghjkShareDir.join("ghjk").toString()} print config` +// await $`${ghjkDataDir.join("ghjk").toString()} print config` // .cwd(devDir.toString()) // .clearEnv() // .env(env); // -// await $`${ghjkShareDir.join("ghjk").toString()} envs cook` +// await $`${ghjkDataDir.join("ghjk").toString()} envs cook` // .cwd(devDir.toString()) // .clearEnv() // .env(env); let cmd; if (Deno.args.length) { - if (Deno.args[0] == "bash") { + if (Deno.args[0] == "bash" && Deno.args.length == 1) { cmd = $`bash --rcfile ${env.BASH_ENV}`; + } else if (Deno.args[0] == "fish" && Deno.args.length == 1) { + // cmd = $`fish --no-config --init-command 'source ${ + cmd = $`fish --init-command 'source ${ + ghjkDataDir.join("env.fish").toString() + }'`; } else { cmd = $`${Deno.args}`; } diff --git a/utils/logger.ts b/utils/logger.ts index 10834e61..6415647f 100644 --- a/utils/logger.ts +++ b/utils/logger.ts @@ -107,7 +107,7 @@ export class TestConsoleErrHandler extends ConsoleErrHandler { super(levelName, options); } - handle(lr: std_log.LogRecord): void { + override handle(lr: std_log.LogRecord): void { if (lr.level >= this.throwLevel) { throw new Error(`detected ${lr.levelName} log record:`, { cause: lr }); } @@ -142,6 +142,7 @@ export default function logger( logger = new std_log.Logger(name, level, { handlers: [consoleHandler], }); + loggers.set(name, logger); } return logger; } diff --git a/utils/mod.ts b/utils/mod.ts index 04688421..464a43df 100644 --- a/utils/mod.ts +++ b/utils/mod.ts @@ -43,7 +43,7 @@ export const jsonSchema: zod.ZodType = zod.lazy(() => ); export function dbg(val: T, ...more: unknown[]) { - logger().debug(() => val, ...more, "DBG"); + logger().debug("DBG", val, ...more); return val; } @@ -250,11 +250,12 @@ export const $ = dax.build$( depth: 10, }); }, - co( + co: ((values: any[]) => Promise.all(values)) as typeof Promise.all, + /* co( values: T, ): Promise<{ -readonly [P in keyof T]: Awaited }> { return Promise.all(values); - }, + }, */ // coIter( // items: Iterable, // fn: (item:T) => PromiseLike, @@ -281,6 +282,7 @@ export const $ = dax.build$( } return pathRef; }, + dbg, }, }, ); @@ -305,29 +307,6 @@ export async function findEntryRecursive(path: string | Path, name: string) { } } -export function homeDir() { - switch (Deno.build.os) { - case "linux": - case "darwin": - return Deno.env.get("HOME") ?? null; - case "windows": - return Deno.env.get("USERPROFILE") ?? null; - default: - return null; - } -} - -export function dirs() { - const home = homeDir(); - if (!home) { - throw new Error("cannot find home dir"); - } - return { - homeDir: home, - shareDir: $.path(home).resolve(".local", "share"), - }; -} - export const AVAIL_CONCURRENCY = Number.parseInt( Deno.env.get("DENO_JOBS") ?? "1", ); @@ -409,6 +388,7 @@ export type DownloadFileArgs = { export async function downloadFile( args: DownloadFileArgs, ) { + logger().debug("downloading", args); const { name, mode, url, downloadPath, tmpDirPath, headers } = { name: $.path(args.url).basename(), mode: 0o666, @@ -542,33 +522,37 @@ export function thinInstallConfig(fat: InstallConfigFat) { export type OrRetOf = T extends () => infer Inner ? Inner : T; +/** + * This tries to emulate a rust `match` statement but in a typesafe + * way. This is a WIP function. + * ```ts + * const pick: 2 = switchMap( + * "hello", + * { + * hey: () => 1, + * hello: () => 2, + * hi: 3, + * holla: 4, + * }, + * ); + * ``` + */ export function switchMap< K extends string | number | symbol, All extends { - [Key in K]: All[K]; + [Key in K]?: All[K]; }, ->( +> // D = undefined, +( val: K, branches: All, - // def?: D, + // def?: (val: K) => D, ): K extends keyof All ? OrRetOf - : /* All[keyof All] | */ undefined { - // return branches[val]; + : OrRetOf | undefined { const branch = branches[val]; return typeof branch == "function" ? branch() : branch; } -switchMap( - "holla" as string, - { - hey: () => 1, - hello: () => 2, - hi: 3, - holla: 4, - } as const, - // () =>5 -); - export async function expandGlobsAndAbsolutize( path: string, wd: string, @@ -597,13 +581,12 @@ export function unwrapZodRes( const zodErr = zod_val_err.fromZodError(res.error, { includePath: true, maxIssuesInMessage: 3, + prefix: errMessage, }); - throw new Error(`${errMessage}: ${zodErr}`, { - cause: { - issues: res.error.issues, - ...cause, - }, - }); + zodErr.cause = { + ...cause, + }; + throw zodErr; } return res.data; } diff --git a/utils/unarchive.ts b/utils/unarchive.ts index 4ff3b3fb..cbc2b5bc 100644 --- a/utils/unarchive.ts +++ b/utils/unarchive.ts @@ -4,7 +4,6 @@ import { std_fs, std_io, std_path, - std_streams, std_untar, } from "../deps/ports.ts"; @@ -45,7 +44,7 @@ export async function untgz( await Foras.initBundledOnce(); const tgzFile = await Deno.open(path, { read: true }); const gzDec = new Foras.GzDecoder(); - await std_streams.copy(tgzFile, { + await std_io.copy(tgzFile, { write(buf) { const mem = new Foras.Memory(buf); gzDec.write(mem); @@ -77,7 +76,7 @@ export async function untar( * This does not close the reader. */ export async function untarReader( - reader: Deno.Reader, + reader: std_io.Reader, dest = "./", ) { for await (const entry of new std_untar.Untar(reader)) { @@ -93,7 +92,7 @@ export async function untarReader( write: true, mode: entry.fileMode, }); - await std_streams.copy(entry, file); + await std_io.copy(entry, file); file.close(); } }