From d3cbc15450404333eb158ad54161426fbcb821c1 Mon Sep 17 00:00:00 2001 From: SikongJueluo <1822250894@qq.com> Date: Tue, 7 Oct 2025 22:15:41 +0800 Subject: [PATCH] finish basic autocraft for create store --- .gitignore | 5 + .justfile | 9 + eslint.config.mjs | 38 + package.json | 25 + pnpm-lock.yaml | 1147 +++++++++++++++++++++++ src/autocraft/main.ts | 120 +++ src/lib/CraftManager.ts | 203 ++++ src/lib/PeripheralManager.ts | 97 ++ src/lib/ccLog.ts | 67 ++ src/lib/event.ts | 374 ++++++++ tsconfig.autocraft.json | 9 + tsconfig.json | 32 + types/advanced-peripherals/index.d.ts | 14 + types/advanced-peripherals/package.json | 11 + types/cc/audio/dfpwm.d.ts | 8 + types/cc/completion.d.ts | 9 + types/cc/expect.d.ts | 11 + types/cc/image/nft.d.ts | 8 + types/cc/index.d.ts | 8 + types/cc/package.json | 9 + types/cc/pretty.d.ts | 18 + types/cc/require.d.ts | 5 + types/cc/shell/completion.d.ts | 16 + types/cc/strings.d.ts | 7 + types/craftos/index.d.ts | 1125 ++++++++++++++++++++++ types/craftos/package.json | 11 + 26 files changed, 3386 insertions(+) create mode 100644 .gitignore create mode 100644 .justfile create mode 100644 eslint.config.mjs create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 src/autocraft/main.ts create mode 100644 src/lib/CraftManager.ts create mode 100644 src/lib/PeripheralManager.ts create mode 100644 src/lib/ccLog.ts create mode 100644 src/lib/event.ts create mode 100644 tsconfig.autocraft.json create mode 100644 tsconfig.json create mode 100644 types/advanced-peripherals/index.d.ts create mode 100644 types/advanced-peripherals/package.json create mode 100644 types/cc/audio/dfpwm.d.ts create mode 100644 types/cc/completion.d.ts create mode 100644 types/cc/expect.d.ts create mode 100644 types/cc/image/nft.d.ts create mode 100644 types/cc/index.d.ts create mode 100644 types/cc/package.json create mode 100644 types/cc/pretty.d.ts create mode 100644 types/cc/require.d.ts create mode 100644 types/cc/shell/completion.d.ts create mode 100644 types/cc/strings.d.ts create mode 100644 types/craftos/index.d.ts create mode 100644 types/craftos/package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1bf3c29 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +*.lua +.DS_Store +event/ +build/ diff --git a/.justfile b/.justfile new file mode 100644 index 0000000..54a679b --- /dev/null +++ b/.justfile @@ -0,0 +1,9 @@ +set windows-shell := ["powershell.exe", "-NoLogo", "-Command"] + +build: build-autocraft sync + +build-autocraft: + pnpm build-autocraft + +sync: + cp -r "./build/*" "C:\\Users\\sikongjueluo\\AppData\\Roaming\\CraftOS-PC\\computer\\0\\user\\" diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..29078e0 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,38 @@ +// @ts-check + +import eslint from "@eslint/js"; +import { defineConfig } from "eslint/config"; +import tseslint from "typescript-eslint"; + +export default defineConfig( + eslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + ...tseslint.configs.stylisticTypeChecked, + { + languageOptions: { + parserOptions: { + project: ["./tsconfig.json", "./tsconfig.autocraft.json"], + }, + }, + rules: { + "@typescript-eslint/strict-boolean-expressions": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + }, + }, + { + files: ["**/*.js", "**/*.mjs"], + ...tseslint.configs.disableTypeChecked, + }, +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..11bd692 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "cc-utils", + "version": "1.0.0", + "description": "Template project for ComputerCraft programs written in TypeScript.", + "main": "main.ts", + "scripts": { + "build": "tstl", + "build-autocraft": "tstl -p ./tsconfig.autocraft.json", + "sync": "cp -r \"./build/*\" \"C:\\Users\\sikongjueluo\\AppData\\Roaming\\CraftOS-PC\\computer\\0\\user\"" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@sikongjueluo/advanced-peripherals-types": "file:types/advanced-peripherals", + "@jackmacwindows/cc-types": "file:types/cc", + "@jackmacwindows/craftos-types": "file:types/craftos", + "@jackmacwindows/lua-types": "^2.13.2", + "@jackmacwindows/typescript-to-lua": "^1.28.1", + "@typescript-to-lua/language-extensions": "^1.19.0", + "eslint": "^9.36.0", + "typescript": "^5.7.2", + "typescript-eslint": "^8.45.0" + }, + "author": "sikongjueluo", + "license": "MIT" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..799e3ac --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1147 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@eslint/js': + specifier: ^9.36.0 + version: 9.36.0 + '@jackmacwindows/cc-types': + specifier: file:types/cc + version: file:types/cc + '@jackmacwindows/craftos-types': + specifier: file:types/craftos + version: file:types/craftos + '@jackmacwindows/lua-types': + specifier: ^2.13.2 + version: 2.13.2 + '@jackmacwindows/typescript-to-lua': + specifier: ^1.28.1 + version: 1.28.1(typescript@5.9.3) + '@sikongjueluo/advanced-peripherals-types': + specifier: file:types/advanced-peripherals + version: file:types/advanced-peripherals + '@typescript-to-lua/language-extensions': + specifier: ^1.19.0 + version: 1.19.0 + eslint: + specifier: ^9.36.0 + version: 9.36.0 + typescript: + specifier: ^5.7.2 + version: 5.9.3 + typescript-eslint: + specifier: ^8.45.0 + version: 8.45.0(eslint@9.36.0)(typescript@5.9.3) + +packages: + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.3.1': + resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.15.2': + resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.36.0': + resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.5': + resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jackmacwindows/cc-types@file:types/cc': + resolution: {directory: types/cc, type: directory} + + '@jackmacwindows/craftos-types@file:types/craftos': + resolution: {directory: types/craftos, type: directory} + + '@jackmacwindows/lua-types@2.13.2': + resolution: {integrity: sha512-XoqHmgtG1SLWzmMx8wQc0sJtPmrzjCFbiwNiBIZE7HOEXWdJi7NDKVlE1nl9A5745Yb5jIkfz2deOzMtHiHVcQ==} + + '@jackmacwindows/typescript-to-lua@1.28.1': + resolution: {integrity: sha512-cUPug8Je8pRK8jSbAMY5LA2XWShJHyLc/gIDp/B6F8fcXTXOJbCXqrFFPsp81NRRuORCQEchaRHybOG/mj0W3A==} + engines: {node: '>=16.10.0'} + hasBin: true + peerDependencies: + typescript: 5.7.2 + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@sikongjueluo/advanced-peripherals-types@file:types/advanced-peripherals': + resolution: {directory: types/advanced-peripherals, type: directory} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@typescript-eslint/eslint-plugin@8.45.0': + resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.45.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.45.0': + resolution: {integrity: sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.45.0': + resolution: {integrity: sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.45.0': + resolution: {integrity: sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.45.0': + resolution: {integrity: sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.45.0': + resolution: {integrity: sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.45.0': + resolution: {integrity: sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.45.0': + resolution: {integrity: sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.45.0': + resolution: {integrity: sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.45.0': + resolution: {integrity: sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-to-lua/language-extensions@1.19.0': + resolution: {integrity: sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + enhanced-resolve@5.8.2: + resolution: {integrity: sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==} + engines: {node: '>=10.13.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.36.0: + resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tapable@2.2.3: + resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} + engines: {node: '>=6'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.45.0: + resolution: {integrity: sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0)': + dependencies: + eslint: 9.36.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.3.1': {} + + '@eslint/core@0.15.2': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.36.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.5': + dependencies: + '@eslint/core': 0.15.2 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jackmacwindows/cc-types@file:types/cc': {} + + '@jackmacwindows/craftos-types@file:types/craftos': {} + + '@jackmacwindows/lua-types@2.13.2': {} + + '@jackmacwindows/typescript-to-lua@1.28.1(typescript@5.9.3)': + dependencies: + '@typescript-to-lua/language-extensions': 1.19.0 + enhanced-resolve: 5.8.2 + picomatch: 2.3.1 + resolve: 1.22.10 + source-map: 0.7.6 + typescript: 5.9.3 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@sikongjueluo/advanced-peripherals-types@file:types/advanced-peripherals': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@typescript-eslint/eslint-plugin@8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0)(typescript@5.9.3))(eslint@9.36.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.45.0 + '@typescript-eslint/type-utils': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.45.0 + eslint: 9.36.0 + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.45.0(eslint@9.36.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.45.0 + '@typescript-eslint/types': 8.45.0 + '@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.45.0 + debug: 4.4.3 + eslint: 9.36.0 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.45.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.45.0(typescript@5.9.3) + '@typescript-eslint/types': 8.45.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.45.0': + dependencies: + '@typescript-eslint/types': 8.45.0 + '@typescript-eslint/visitor-keys': 8.45.0 + + '@typescript-eslint/tsconfig-utils@8.45.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.45.0(eslint@9.36.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.45.0 + '@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.36.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.45.0': {} + + '@typescript-eslint/typescript-estree@8.45.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.45.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.45.0(typescript@5.9.3) + '@typescript-eslint/types': 8.45.0 + '@typescript-eslint/visitor-keys': 8.45.0 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.45.0(eslint@9.36.0)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@typescript-eslint/scope-manager': 8.45.0 + '@typescript-eslint/types': 8.45.0 + '@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3) + eslint: 9.36.0 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.45.0': + dependencies: + '@typescript-eslint/types': 8.45.0 + eslint-visitor-keys: 4.2.1 + + '@typescript-to-lua/language-extensions@1.19.0': {} + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + enhanced-resolve@5.8.2: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.3 + + escape-string-regexp@4.0.0: {} + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.36.0: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.1 + '@eslint/core': 0.15.2 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.36.0 + '@eslint/plugin-kit': 0.3.5 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + function-bind@1.1.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picomatch@2.3.1: {} + + prelude-ls@1.2.1: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + resolve-from@4.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@7.7.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + source-map@0.7.6: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tapable@2.2.3: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.45.0(eslint@9.36.0)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.36.0)(typescript@5.9.3))(eslint@9.36.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.45.0(eslint@9.36.0)(typescript@5.9.3) + eslint: 9.36.0 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} diff --git a/src/autocraft/main.ts b/src/autocraft/main.ts new file mode 100644 index 0000000..bc49c97 --- /dev/null +++ b/src/autocraft/main.ts @@ -0,0 +1,120 @@ +import { CraftManager } from "@/lib/CraftManager"; +import * as peripheralManager from "../lib/PeripheralManager"; +import { CCLog } from "@/lib/ccLog"; + +const log = new CCLog("autocraft.log"); + +const peripheralsRelativeSides = { + packagesContainer: "minecraft:chest_10", + itemsContainer: "minecraft:chest_9", + packageExtractor: "create:packager_1", + blockReader: "front", + wiredModem: "back", +}; + +function main() { + const packagesContainer = peripheralManager.findByNameRequired( + "inventory", + peripheralsRelativeSides.packagesContainer, + ); + + const itemsContainer = peripheralManager.findByNameRequired( + "inventory", + peripheralsRelativeSides.itemsContainer, + ); + + const packageExtractor = peripheralManager.findByNameRequired( + "inventory", + peripheralsRelativeSides.packageExtractor, + ); + + const blockReader = peripheralManager.findByNameRequired( + "blockReader", + peripheralsRelativeSides.blockReader, + ); + + const wiredModem = peripheralManager.findByNameRequired( + "wiredModem", + peripheralsRelativeSides.wiredModem, + ); + const turtleLocalName = wiredModem.getNameLocal(); + + const craftManager = new CraftManager(turtleLocalName); + + let hasPackage = redstone.getInput("front"); + while (true) { + if (!hasPackage) os.pullEvent("redstone"); + hasPackage = redstone.getInput("front"); + if (!hasPackage) { + continue; + } + log.info(`Package detected`); + + const itemsInfo = packagesContainer.list(); + for (const key in itemsInfo) { + const slot = parseInt(key); + const item = itemsInfo[slot]; + log.info(`${item.count}x ${item.name} in slot ${key}`); + + // Get package NBT + packagesContainer.pushItems(turtleLocalName, slot); + const packageInfo = blockReader.getBlockData().Items[1]; + // log.info(textutils.serialise(packageInfo)); + + // Get recipe + const packageRecipes = CraftManager.getPackageRecipe(packageInfo); + + // No recipe, just extract package + if (packageRecipes == undefined) { + packageExtractor.pullItems(turtleLocalName, 1); + log.info(`No recipe, just pass`); + continue; + } + + // Extract package + // log.info(`Get recipe ${textutils.serialise(recipe)}`); + packageExtractor.pullItems(turtleLocalName, 1); + + // Pull and craft multi recipe + for (const recipe of packageRecipes) { + let craftOutputItem: BlockItemDetailData | undefined = undefined; + let restCraftCnt = recipe.Count; + + do { + // Clear workbench + craftManager.pushAll(itemsContainer); + + log.info(`Pull items according to a recipe`); + const craftCnt = craftManager.pullItems( + recipe, + itemsContainer, + restCraftCnt, + ); + if (craftCnt == 0) break; + craftManager.craft(); + log.info(`Craft ${craftCnt} times`); + restCraftCnt -= craftCnt; + + // Get output item + craftOutputItem ??= blockReader.getBlockData().Items[1]; + } while (restCraftCnt > 0); + + // Finally output + if (restCraftCnt > 0) { + log.warn(`Only craft ${recipe.Count - restCraftCnt} times`); + } else { + log.info(`Finish craft ${recipe.Count}x ${craftOutputItem?.id}`); + } + craftManager.pushAll(itemsContainer); + } + } + } +} + +try { + main(); +} catch (error: unknown) { + log.error(textutils.serialise(error as object)); +} finally { + log.close(); +} diff --git a/src/lib/CraftManager.ts b/src/lib/CraftManager.ts new file mode 100644 index 0000000..99666d3 --- /dev/null +++ b/src/lib/CraftManager.ts @@ -0,0 +1,203 @@ +import { CCLog } from "./ccLog"; + +const log = new CCLog("CraftManager.log"); + +// ComputerCraft Turtle inventory layout: +// 1, 2, 3, 4 +// 5, 6, 7, 8 +// 9, 10, 11, 12 +// 13, 14, 15, 16 + +const TURTLE_SIZE = 16; +// const CRAFT_SLOT_CNT = 9; +const CRAFT_SLOT_TABLE: number[] = [1, 2, 3, 5, 6, 7, 9, 10, 11]; +// const REST_SLOT_CNT = 7; +// const REST_SLOT_TABLE: number[] = [4, 8, 12, 13, 14, 15, 16]; + +interface CreatePackageTag { + Items: { + Items: { + id: string; + Count: number; + Slot: number; + }[]; + Size: number; + }; + Fragment: { + Index: number; + OrderContext: { + OrderedCrafts: { + Pattern: { + Entries: { + Item: { + id: string; + Count: number; + tag?: object; + }; + Amount: number; + }[]; + }; + Count: number; + }[]; + OrderedStacks: { + Entries: { + Item: { + id: string; + Count: number; + }; + Amount: number; + }[]; + }; + }; + IsFinal: number; + OrderId: number; + LinkIndex: number; + IsFinalLink: number; + }; + Address: string; +} + +interface CraftRecipeItem { + Item: { + id: string; + Count: number; + }; + Amount: number; +} + +interface CraftRecipe { + PatternEntries: Record; + Count: number; +} + +type CraftMode = "keep" | "keepProduct" | "keepIngredient"; + +class CraftManager { + private localName: string; + + constructor(modem: WiredModemPeripheral | string) { + if (turtle == undefined) { + throw new Error("Script must be run in a turtle computer"); + } + + if (modem == undefined) { + throw new Error("Please provide a valid modem"); + } + + let name = ""; + if (typeof modem === "string") { + name = modem; + } else { + if (peripheral.getType(modem) !== "modem") { + throw new Error("Please provide a valid modem"); + } + + name = modem.getNameLocal(); + if (name === null) { + throw new Error("Please provide a valid modem"); + } + } + this.localName = name; + // log.info(`Get turtle name : ${name}`); + } + + public pushAll(outputInventory: InventoryPeripheral): void { + for (let i = 1; i <= TURTLE_SIZE; i++) { + outputInventory.pullItems(this.localName, i); + } + } + + public craft(dstInventory?: InventoryPeripheral, limit?: number): void { + turtle.craft(limit); + + if (dstInventory != undefined) { + dstInventory.pullItems(this.localName, 1, limit); + } + } + + public static getPackageRecipe( + item: BlockItemDetailData, + ): CraftRecipe[] | undefined { + if ( + !item.id.includes("create:cardboard_package") || + (item.tag as CreatePackageTag)?.Fragment?.OrderContext + ?.OrderedCrafts?.[0] == undefined + ) { + return undefined; + } + + const orderedCraft = (item.tag as CreatePackageTag).Fragment.OrderContext + .OrderedCrafts; + return orderedCraft.map((value, _) => ({ + PatternEntries: value.Pattern.Entries, + Count: value.Count, + })); + } + + public pullItems( + recipe: CraftRecipe, + inventory: InventoryPeripheral, + limit: number, + ): number { + let maxCraftCount = limit; + + for (const index in recipe.PatternEntries) { + const entry = recipe.PatternEntries[index]; + if (entry.Item.Count == 0 || entry.Item.id == "minecraft:air") { + continue; + } + + const ingredientList = inventory.list(); + let restCount = maxCraftCount; + for (const key in ingredientList) { + // Get item detail and check max count + const slot = parseInt(key); + const ingredient = inventory.getItemDetail(slot)!; + if (entry.Item.id != ingredient.name) { + continue; + } + + const ingredientMaxCount = ingredient.maxCount; + if (maxCraftCount > ingredientMaxCount) { + maxCraftCount = ingredientMaxCount; + restCount = maxCraftCount; + } + log.info( + `Slot ${slot} ${ingredient.name} max count: ${ingredientMaxCount}`, + ); + + // TODO: Process multi count entry item + if (ingredient.count >= restCount) { + inventory.pushItems( + this.localName, + slot, + restCount, + CRAFT_SLOT_TABLE[parseInt(index) - 1], + ); + restCount = 0; + break; + } else { + inventory.pushItems( + this.localName, + slot, + ingredient.count, + CRAFT_SLOT_TABLE[parseInt(index) - 1], + ); + restCount -= ingredient.count; + } + } + + if (restCount > 0) return 0; + } + + return maxCraftCount; + } +} + +export { + CraftManager, + CraftRecipe, + CraftMode, + CraftRecipeItem, + CreatePackageTag, +}; diff --git a/src/lib/PeripheralManager.ts b/src/lib/PeripheralManager.ts new file mode 100644 index 0000000..152f1e2 --- /dev/null +++ b/src/lib/PeripheralManager.ts @@ -0,0 +1,97 @@ +type PeripheralType = "inventory" | "modem" | "wiredModem" | "blockReader"; +type BlockSide = "top" | "bottom" | "left" | "right" | "front" | "back"; + +// Declare the function signature for findBySide +function findByName( + devType: "inventory", + devName: string, +): InventoryPeripheral | undefined; +function findByName( + devType: "modem", + devName: string, +): ModemPeripheral | undefined; +function findByName( + devType: "wiredModem", + devName: string, +): WiredModemPeripheral | undefined; +function findByName( + devType: "blockReader", + devName: string, +): BlockReaderPeripheral | undefined; +function findByName( + devType: PeripheralType, + side: BlockSide, +): IPeripheral | undefined; +function findByName( + devType: PeripheralType, + devName: string, +): IPeripheral | undefined; + +// Implement the function signature for findBySide +function findByName( + devType: PeripheralType, + devName: string, +): IPeripheral | undefined { + const dev = peripheral.find( + devType == "wiredModem" ? "modem" : devType, + (name: string, _) => { + return name == devName; + }, + )[0]; + + // Seperate Modem and wiredModem + if ( + devType == "modem" && + ((dev as ModemPeripheral).isWireless == undefined || + (dev as ModemPeripheral).isWireless() == false) + ) + return undefined; + + if ( + devType == "wiredModem" && + (dev as ModemPeripheral).isWireless != undefined && + (dev as ModemPeripheral).isWireless() == true + ) + return undefined; + + return dev; +} + +// Declare the function signature for findBySideRequired +function findByNameRequired( + devType: "inventory", + devName: string, +): InventoryPeripheral; +function findByNameRequired(devType: "modem", devName: string): ModemPeripheral; +function findByNameRequired( + devType: "wiredModem", + devName: string, +): WiredModemPeripheral; +function findByNameRequired( + devType: "blockReader", + devName: string, +): BlockReaderPeripheral; +function findByNameRequired( + devType: PeripheralType, + side: BlockSide, +): T; +function findByNameRequired( + devType: PeripheralType, + devName: string, +): T; + +// Implement the function signature for findBySideRequired +function findByNameRequired( + devType: PeripheralType, + side: string, +): T { + const dev = findByName(devType, side); + if (!dev) { + throw new Error( + `Required peripheral of type '${devType}' not found on side '${side}'`, + ); + } + return dev as T; +} + +export { PeripheralType, BlockSide, findByName, findByNameRequired }; diff --git a/src/lib/ccLog.ts b/src/lib/ccLog.ts new file mode 100644 index 0000000..03c74cd --- /dev/null +++ b/src/lib/ccLog.ts @@ -0,0 +1,67 @@ +enum LogLevel { + Info = 0, + Warn = 1, + Error = 2, +} + +export class CCLog { + private fp: LuaFile | undefined; + constructor(filename?: string) { + term.clear(); + term.setCursorPos(1, 1); + if (filename != undefined && filename.length != 0) { + const filepath = shell.dir() + "/" + filename; + const [file, error] = io.open(filepath, fs.exists(filepath) ? "a" : "w+"); + if (file != undefined) { + this.fp = file; + } else { + throw Error(error); + } + } + } + + private getFormatMsg(msg: string, level: LogLevel): string { + const date = os.date("*t"); + return `[ ${date.year}/${date.month}/${date.day} -- ${date.hour}:${date.min}:${date.sec} ${LogLevel[level]} ] : ${msg}\r\n`; + } + + public writeLine(msg: string, color?: Color) { + let originalColor: Color = 0; + if (color != undefined) { + originalColor = term.getTextColor(); + term.setTextColor(color); + } + + // Log + term.write(msg); + if (this.fp != undefined) { + this.fp.write(msg); + } + + if (color != undefined) { + term.setTextColor(originalColor); + } + + // Next line + term.setCursorPos(1, term.getCursorPos()[1] + 1); + } + + public info(msg: string) { + this.writeLine(this.getFormatMsg(msg, LogLevel.Info), colors.green); + } + + public warn(msg: string) { + this.writeLine(this.getFormatMsg(msg, LogLevel.Warn), colors.orange); + } + + public error(msg: string) { + this.writeLine(this.getFormatMsg(msg, LogLevel.Error), colors.red); + } + + public close() { + if (this.fp !== undefined) { + this.fp.close(); + this.fp = undefined; + } + } +} diff --git a/src/lib/event.ts b/src/lib/event.ts new file mode 100644 index 0000000..4bc170b --- /dev/null +++ b/src/lib/event.ts @@ -0,0 +1,374 @@ +// You may comment out any events you don't need to save space. Make sure to +// delete them from eventInitializers as well. + +export interface IEvent { + get_name(): string; + get_args(): any[]; +} + +export class CharEvent implements IEvent { + public character: string = ""; + public get_name() {return "char";} + public get_args() {return [this.character];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "char") return null; + let ev = new CharEvent(); + ev.character = (args[1] as string); + return ev; + } +} + +export class KeyEvent implements IEvent { + public key: Key = 0; + public isHeld: boolean = false; + public isUp: boolean = false; + public get_name() {return this.isUp ? "key_up" : "key";} + public get_args() {return [this.key, (this.isUp ? null : this.isHeld)];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "key" && (args[0] as string) != "key_up")) return null; + let ev = new KeyEvent(); + ev.key = (args[1] as number); + ev.isUp = (args[0] as string) == "key_up"; + ev.isHeld = ev.isUp ? false : (args[2] as boolean); + return ev; + } +} + +export class PasteEvent implements IEvent { + public text: string = ""; + public get_name() {return "paste";} + public get_args() {return [(this.text as any)];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "paste") return null; + let ev = new PasteEvent(); + ev.text = (args[1] as string); + return ev; + } +} + +export class TimerEvent implements IEvent { + public id: number = 0; + public isAlarm: boolean = false; + public get_name() {return this.isAlarm ? "alarm" : "timer";} + public get_args() {return [this.id];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "timer" && (args[0] as string) != "alarm")) return null; + let ev = new TimerEvent(); + ev.id = (args[1] as number); + ev.isAlarm = (args[0] as string) == "alarm"; + return ev; + } +} + +export class TaskCompleteEvent implements IEvent { + public id: number = 0; + public success: boolean = false; + public error: string | null = null; + public params: any[] = []; + public get_name() {return "task_complete";} + public get_args() { + if (this.success) return [this.id, this.success].concat(this.params); + else return [this.id, this.success, this.error]; + } + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "task_complete") return null; + let ev = new TaskCompleteEvent(); + ev.id = (args[1] as number); + ev.success = (args[2] as boolean); + if (ev.success) { + ev.error = null; + ev.params = args.slice(3); + } else { + ev.error = (args[3] as string); + ev.params = []; + } + return ev; + } +} + +export class RedstoneEvent implements IEvent { + public get_name() {return "redstone";} + public get_args() {return [];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "redstone") return null; + let ev = new RedstoneEvent(); + return ev; + } +} + +export class TerminateEvent implements IEvent { + public get_name() {return "terminate";} + public get_args() {return [];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "terminate") return null; + let ev = new TerminateEvent(); + return ev; + } +} + +export class DiskEvent implements IEvent { + public side: string = ""; + public eject: boolean = false; + public get_name() {return this.eject ? "disk_eject" : "disk";} + public get_args() {return [this.side];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "disk" && (args[0] as string) != "disk_eject")) return null; + let ev = new DiskEvent(); + ev.side = (args[1] as string); + ev.eject = (args[0] as string) == "disk_eject"; + return ev; + } +} + +export class PeripheralEvent implements IEvent { + public side: string = ""; + public detach: boolean = false; + public get_name() {return this.detach ? "peripheral_detach" : "peripheral";} + public get_args() {return [this.side];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "peripheral" && (args[0] as string) != "peripheral_detach")) return null; + let ev = new PeripheralEvent(); + ev.side = (args[1] as string); + ev.detach = (args[0] as string) == "peripheral_detach"; + return ev; + } +} + +export class RednetMessageEvent implements IEvent { + public sender: number = 0; + public message: any; + public protocol: string | null = null; + public get_name() {return "rednet_message";} + public get_args() {return [this.sender, this.message, this.protocol];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "rednet_message") return null; + let ev = new RednetMessageEvent(); + ev.sender = (args[1] as number); + ev.message = args[2]; + ev.protocol = (args[3] as string); + return ev; + } +} + +export class ModemMessageEvent implements IEvent { + public side: string = ""; + public channel: number = 0; + public replyChannel: number = 0; + public message: any; + public distance: number = 0; + public get_name() {return "modem_message";} + public get_args() {return [this.side, this.channel, this.replyChannel, this.message, this.distance];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "modem_message") return null; + let ev = new ModemMessageEvent(); + ev.side = (args[1] as string); + ev.channel = (args[2] as number); + ev.replyChannel = (args[3] as number); + ev.message = args[4]; + ev.distance = (args[5] as number); + return ev; + } +} + +export class HTTPEvent implements IEvent { + public url: string = ""; + public handle: HTTPResponse | null = null; + public error: string | null = null; + public get_name() {return this.error == null ? "http_success" : "http_failure";} + public get_args() {return [this.url, (this.error == null ? this.handle : this.error), (this.error != null ? this.handle : null)];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "http_success" && (args[0] as string) != "http_failure")) return null; + let ev = new HTTPEvent(); + ev.url = (args[1] as string); + if ((args[0] as string) == "http_success") { + ev.error = null; + ev.handle = (args[2] as HTTPResponse); + } else { + ev.error = (args[2] as string); + if (ev.error == null) ev.error = ""; + ev.handle = (args[3] as HTTPResponse); + } + return ev; + } +} + +export class WebSocketEvent implements IEvent { + public handle: WebSocket | null = null; + public error: string | null = null; + public get_name() {return this.error == null ? "websocket_success" : "websocket_failure";} + public get_args() {return [this.handle == null ? this.error : this.handle];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "websocket_success" && (args[0] as string) != "websocket_failure")) return null; + let ev = new WebSocketEvent(); + if ((args[0] as string) == "websocket_success") { + ev.handle = (args[1] as WebSocket); + ev.error = null; + } else { + ev.error = (args[1] as string); + ev.handle = null; + } + return ev; + } +} + +export enum MouseEventType { + Click, + Up, + Scroll, + Drag, + Touch, + Move, +} + +export class MouseEvent implements IEvent { + public button: number = 0; + public x: number = 0; + public y: number = 0; + public side: string | null = null; + public type: MouseEventType = MouseEventType.Click; + public get_name() { + return { + [MouseEventType.Click]: "mouse_click", + [MouseEventType.Up]: "mouse_up", + [MouseEventType.Scroll]: "mouse_scroll", + [MouseEventType.Drag]: "mouse_drag", + [MouseEventType.Touch]: "monitor_touch", + [MouseEventType.Move]: "mouse_move" + }[this.type]; + } + public get_args() {return [(this.type == MouseEventType.Touch ? this.side : this.button), this.x, this.y];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string")) return null; + let ev = new MouseEvent(); + const type = args[0] as string; + if (type == "mouse_click") {ev.type = MouseEventType.Click; ev.button = (args[1] as number); ev.side = null;} + else if (type == "mouse_up") {ev.type = MouseEventType.Up; ev.button = (args[1] as number); ev.side = null;} + else if (type == "mouse_scroll") {ev.type = MouseEventType.Scroll; ev.button = (args[1] as number); ev.side = null;} + else if (type == "mouse_drag") {ev.type = MouseEventType.Drag; ev.button = (args[1] as number); ev.side = null;} + else if (type == "monitor_touch") {ev.type = MouseEventType.Touch; ev.button = 0; ev.side = (args[1] as string);} + else if (type == "mouse_move") {ev.type = MouseEventType.Move; ev.button = (args[1] as number); ev.side = null;} + else return null; + ev.x = (args[2] as number); + ev.y = (args[3] as number); + return ev; + } +} + +export class ResizeEvent implements IEvent { + public side: string | null = null; + public get_name() {return this.side == null ? "term_resize" : "monitor_resize";} + public get_args() {return [this.side];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || ((args[0] as string) != "term_resize" && (args[0] as string) != "monitor_resize")) return null; + let ev = new ResizeEvent(); + if ((args[0] as string) == "monitor_resize") ev.side = (args[1] as string); + else ev.side = null; + return ev; + } +} + +export class TurtleInventoryEvent implements IEvent { + public get_name() {return "turtle_inventory";} + public get_args() {return [];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "turtle_inventory") return null; + let ev = new TurtleInventoryEvent(); + return ev; + } +} + +class SpeakerAudioEmptyEvent implements IEvent { + public side: string = ""; + public get_name() {return "speaker_audio_empty";} + public get_args() {return [this.side];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "speaker_audio_empty") return null; + let ev: SpeakerAudioEmptyEvent; + ev.side = args[1] as string; + return ev; + } +} + +class ComputerCommandEvent implements IEvent { + public args: string[] = []; + public get_name() {return "computer_command";} + public get_args() {return this.args;} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "computer_command") return null; + let ev: ComputerCommandEvent; + ev.args = args.slice(1); + return ev; + } +} + +/* +class Event implements IEvent { + + public get_name() {return "";} + public get_args() {return [(: any)];} + public static init(args: any[]): IEvent | null { + if (!(typeof args[0] === "string") || (args[0] as string) != "") return null; + let ev: Event; + + return ev; + } +} +*/ + +export class GenericEvent implements IEvent { + public args: any[] = []; + public get_name() {return (this.args[0] as string);} + public get_args() {return this.args.slice(1);} + public static init(args: any[]): IEvent | null { + let ev = new GenericEvent(); + ev.args = args; + return ev; + } +} + +let eventInitializers: ((args: any[]) => IEvent | null)[] = [ + CharEvent.init, + KeyEvent.init, + PasteEvent.init, + TimerEvent.init, + TaskCompleteEvent.init, + RedstoneEvent.init, + TerminateEvent.init, + DiskEvent.init, + PeripheralEvent.init, + RednetMessageEvent.init, + ModemMessageEvent.init, + HTTPEvent.init, + WebSocketEvent.init, + MouseEvent.init, + ResizeEvent.init, + TurtleInventoryEvent.init, + SpeakerAudioEmptyEvent.init, + ComputerCommandEvent.init, + GenericEvent.init +]; + +type Constructor = new (...args: any[]) => T; +export function pullEventRaw(filter: string | null = null): IEvent | null { + let args = table.pack(...coroutine.yield(filter)); + for (let init of eventInitializers) { + let ev = init(args); + if (ev != null) return ev; + } + return GenericEvent.init(args); +} +export function pullEvent(filter: string | null = null): IEvent | null { + let ev = pullEventRaw(filter); + if (ev instanceof TerminateEvent) throw "Terminated"; + return ev; +} +export function pullEventRawAs(type: Constructor, filter: string | null = null): T | null { + let ev = pullEventRaw(filter); + if ((ev instanceof type)) return ev as T; + else return null; +} +export function pullEventAs(type: Constructor, filter: string | null = null): T | null { + let ev = pullEvent(filter); + if ((ev instanceof type)) return ev as T; + else return null; +} diff --git a/tsconfig.autocraft.json b/tsconfig.autocraft.json new file mode 100644 index 0000000..5b45209 --- /dev/null +++ b/tsconfig.autocraft.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://raw.githubusercontent.com/MCJack123/TypeScriptToLua/master/tsconfig-schema.json", + "extends": "./tsconfig.json", + "tstl": { + "luaBundle": "build/autocraft.lua", + "luaBundleEntry": "src/autocraft/main.ts" + }, + "include": ["src/autocraft/*.ts"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1a8cdc7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://raw.githubusercontent.com/MCJack123/TypeScriptToLua/master/tsconfig-schema.json", + "compilerOptions": { + "target": "ESNext", + "lib": ["ESNext"], + "baseUrl": ".", + "moduleResolution": "node", + "strict": true, + "types": [ + "@sikongjueluo/advanced-peripherals-types", + "@jackmacwindows/lua-types/cc", + "@jackmacwindows/craftos-types", + "@jackmacwindows/cc-types", + "@typescript-to-lua/language-extensions" + ], + "paths": { + "@/*": ["./src/*"], + "@jackmacwindows/craftos-types": ["./types/craftos"], + "@jackmacwindows/lua-types/cc": ["./types/cc"], + "@sikongjueluo/advanced-peripherals-types": [ + "./types/advanced-peripherals" + ] + } + }, + "tstl": { + "luaTarget": "CC", + "luaLibImport": "require-minimal", + "tstlVerbose": true, + "noImplicitSelf": true + }, + "include": ["./*.ts", "./src/**/*.ts", "./types/**/*.ts"] +} diff --git a/types/advanced-peripherals/index.d.ts b/types/advanced-peripherals/index.d.ts new file mode 100644 index 0000000..8e35763 --- /dev/null +++ b/types/advanced-peripherals/index.d.ts @@ -0,0 +1,14 @@ +declare interface BlockItemDetailData { + id: string; + tag: object; + Count: number; + Slot: number; +} + +declare interface BlockDetailData { + Items: Record; +} + +declare class BlockReaderPeripheral { + getBlockData(): BlockDetailData; +} diff --git a/types/advanced-peripherals/package.json b/types/advanced-peripherals/package.json new file mode 100644 index 0000000..d885fcb --- /dev/null +++ b/types/advanced-peripherals/package.json @@ -0,0 +1,11 @@ +{ + "name": "@sikongjueluo/advanced-peripherals-types", + "version": "1.0.0", + "description": "TypeScript type definitions for base Advanced Peripherals APIs.", + "types": "./index.d.ts", + "files": [ + "./index.d.ts" + ], + "author": "SikongJueluo", + "license": "MIT" +} diff --git a/types/cc/audio/dfpwm.d.ts b/types/cc/audio/dfpwm.d.ts new file mode 100644 index 0000000..872cd06 --- /dev/null +++ b/types/cc/audio/dfpwm.d.ts @@ -0,0 +1,8 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.audio.dfpwm" { + export function make_encoder(): (pcm: number[]) => string; + export function encode(pcm: number[]): string; + export function make_decoder(): (dfpwm: string) => number[]; + export function decode(dfpwm: string): number[]; +} \ No newline at end of file diff --git a/types/cc/completion.d.ts b/types/cc/completion.d.ts new file mode 100644 index 0000000..d98b0d5 --- /dev/null +++ b/types/cc/completion.d.ts @@ -0,0 +1,9 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.completion" { + export function choice(text: string, choices: string[], add_space?: boolean): string[]; + export function peripheral(text: string, add_space?: boolean): string[]; + export function side(text: string, add_space?: boolean): string[]; + export function setting(text: string, add_space?: boolean): string[]; + export function command(text: string, add_space?: boolean): string[]; +} \ No newline at end of file diff --git a/types/cc/expect.d.ts b/types/cc/expect.d.ts new file mode 100644 index 0000000..3cef89b --- /dev/null +++ b/types/cc/expect.d.ts @@ -0,0 +1,11 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc/expect" { + namespace expect { + function expect(index: number, value: any, ...types: string[]): any; + function field(tbl: Object|LuaTable, index: string, ...types: string[]): any; + function range(num: number, min?: number, max?: number): number; + } + function expect(index: number, value: any, ...types: string[]): any; + export = expect; +} \ No newline at end of file diff --git a/types/cc/image/nft.d.ts b/types/cc/image/nft.d.ts new file mode 100644 index 0000000..d42ab5f --- /dev/null +++ b/types/cc/image/nft.d.ts @@ -0,0 +1,8 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.image.nft" { + type Image = {text: string, foreground: string, background: string}[]; + export function parse(image: string): Image; + export function load(path: string): Image; + export function draw(image: Image, xPos: number, yPos: number, target?: ITerminal): void; +} \ No newline at end of file diff --git a/types/cc/index.d.ts b/types/cc/index.d.ts new file mode 100644 index 0000000..11d4a95 --- /dev/null +++ b/types/cc/index.d.ts @@ -0,0 +1,8 @@ +import "audio/dfpwm.d.ts"; +import "completion.d.ts"; +import "expect.d.ts"; +import "image.nft.d.ts"; +import "pretty.d.ts"; +import "require.d.ts"; +import "shell/completion.d.ts"; +import "strings.d.ts"; diff --git a/types/cc/package.json b/types/cc/package.json new file mode 100644 index 0000000..5c5d432 --- /dev/null +++ b/types/cc/package.json @@ -0,0 +1,9 @@ +{ + "name": "@jackmacwindows/cc-types", + "version": "1.0.1", + "description": "TypeScript type definitions for CraftOS modules.", + "types": "index.d.ts", + "files": ["./*.d.ts", "./audio", "./image", "./shell"], + "author": "JackMacWindows", + "license": "MIT" +} \ No newline at end of file diff --git a/types/cc/pretty.d.ts b/types/cc/pretty.d.ts new file mode 100644 index 0000000..787aa05 --- /dev/null +++ b/types/cc/pretty.d.ts @@ -0,0 +1,18 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.pretty" { + type Doc = {}; + export const empty: Doc; + export const space: Doc; + export const line: Doc; + export const space_line: Doc; + export function text(text: string, color?: number): Doc; + export function concat(...args: (Doc|string)[]): Doc; + export function nest(depth: number, doc: Doc): Doc; + export function group(doc: Doc): Doc; + export function write(doc: Doc, ribbon_frac?: number): void; + export function print(doc: Doc, ribbon_frac?: number): void; + export function render(doc: Doc, width?: number, ribbon_frac?: number): string; + export function pretty(obj: any, options?: {function_args?: boolean, function_source: boolean}): Doc; + export function pretty_print(obj: any, options?: {function_args?: boolean, function_source: boolean}, ribbon_frac?: number): void; +} \ No newline at end of file diff --git a/types/cc/require.d.ts b/types/cc/require.d.ts new file mode 100644 index 0000000..29f65ff --- /dev/null +++ b/types/cc/require.d.ts @@ -0,0 +1,5 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.require" { + export function make(env: Object|LuaTable, dir: string): LuaMultiReturn<[(name: string) => any, Object|LuaTable]>; +} \ No newline at end of file diff --git a/types/cc/shell/completion.d.ts b/types/cc/shell/completion.d.ts new file mode 100644 index 0000000..b4bc279 --- /dev/null +++ b/types/cc/shell/completion.d.ts @@ -0,0 +1,16 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.shell.completion" { + export function file(shell: Object|LuaTable, text: string): string[]; + export function dir(shell: Object|LuaTable, text: string): string[]; + export function dirOrFile(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[]; + export function program(shell: Object|LuaTable, text: string): string[]; + export function programWithArgs(shell: Object|LuaTable, text: string, previous: string[], starting: number): string[]; + export function help(shell: Object|LuaTable, text: string, previous: string[]): string[]; + export function choice(shell: Object|LuaTable, text: string, previous: string[], choices: string[], add_space?: boolean): string[]; + export function peripheral(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[]; + export function side(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[]; + export function setting(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[]; + export function command(shell: Object|LuaTable, text: string, previous: string[], add_space?: boolean): string[]; + export function build(...args: (null | ((text: string, previous: string[]) => string[]) | [(text: string, previous: string[], ...args: any[]) => string[], ...any[]])[]): (index: number, arg: string, previous: string[]) => string[]; +} \ No newline at end of file diff --git a/types/cc/strings.d.ts b/types/cc/strings.d.ts new file mode 100644 index 0000000..3086ab5 --- /dev/null +++ b/types/cc/strings.d.ts @@ -0,0 +1,7 @@ +/** @noSelfInFile **/ +/** @noResolution **/ +declare module "cc.strings" { + export function wrap(text: string, width?: number): string[]; + export function ensure_width(text: string, width?: number): string; + export function split(str: string, deliminator: string, plain?: boolean, limit?: number): string[]; +} diff --git a/types/craftos/index.d.ts b/types/craftos/index.d.ts new file mode 100644 index 0000000..80bd1c8 --- /dev/null +++ b/types/craftos/index.d.ts @@ -0,0 +1,1125 @@ +/** @noSelfInFile **/ + +// Latest CC version: 1.109.3 +/* eslint-disable @typescript-eslint/no-wrapper-object-types */ + +type Color = number; +type Colour = Color; + +/** @noSelf **/ +declare namespace colors { + let white: Color; + let orange: Color; + let magenta: Color; + let lightBlue: Color; + let yellow: Color; + let lime: Color; + let pink: Color; + let gray: Color; + let lightGray: Color; + let cyan: Color; + let purple: Color; + let blue: Color; + let brown: Color; + let green: Color; + let red: Color; + let black: Color; + function combine(c1: Color, ...c2: Color[]): Color; + function subtract(c1: Color, ...c2: Color[]): Color; + function test(colors: Color, color: Color): boolean; + function packRGB(r: number, g: number, b: number): number; + function unpackRGB(rgb: number): LuaMultiReturn<[number, number, number]>; + function toBlit(color: Color): string; + function fromBlit(color: string): Color | undefined; +} + +/** @noSelf **/ +declare namespace colours { + let white: Colour; + let orange: Colour; + let magenta: Colour; + let lightBlue: Colour; + let yellow: Colour; + let lime: Colour; + let pink: Colour; + let grey: Colour; + let lightGrey: Colour; + let cyan: Colour; + let purple: Colour; + let blue: Colour; + let brown: Colour; + let green: Colour; + let red: Colour; + let black: Colour; + function combine(c1: Colour, ...c2: Colour[]): Colour; + function subtract(c1: Colour, ...c2: Colour[]): Colour; + function test(colors: Colour, color: Colour): boolean; + function packRGB(r: number, g: number, b: number): number; + function unpackRGB(rgb: number): LuaMultiReturn<[number, number, number]>; + function toBlit(color: Colour): string; +} +/** @noSelf **/ +declare namespace commands { + function exec( + command: string, + ): LuaMultiReturn<[boolean, string[], number | undefined]>; + function execAsync(command: string): number; + function list(command: string): string[]; + function getBlockPosition(): LuaMultiReturn<[number, number, number]>; + function getBlockInfo( + x: number, + y: number, + z: number, + dimension?: string, + ): LuaTable | Object; + function getBlockInfos( + x1: number, + y1: number, + z1: number, + x2: number, + y2: number, + z2: number, + dimension?: string, + ): (LuaTable | Object)[]; +} +/** @noSelf **/ +declare namespace disk { + function isPresent(name: string): boolean; + function getLabel(name: string): string | undefined; + function setLabel(name: string, label?: string): void; + function hasData(name: string): boolean; + function getMountPath(name: string): string | undefined; + function hasAudio(name: string): boolean; + function getAudioTitle(name: string): string | undefined; + function playAudio(name: string): void; + function stopAudio(name: string): void; + function eject(name: string): void; + function getID(name: string): number; +} +/** @noSelf */ +declare class ReadFileHandle { + public close(): void; + public seek(whence?: "cur" | "set" | "end", offset?: number): number; + public read(count?: number): string | number; + public readLine(withTrailing?: boolean): string; + public readAll(): string; +} + +/** @noSelf */ +declare class WriteFileHandle { + public close(): void; + public seek(whence?: "cur" | "set" | "end", offset?: number): number; + public write(value: string): void; + public writeLine(value: string): void; + public flush(): void; +} + +interface FileAttributes { + size: number; + isDir: boolean; + isReadOnly: boolean; + created: number; + modified: number; +} + +declare const fs: { + list(this: void, path: string): string[]; + exists(this: void, path: string): boolean; + isDir(this: void, path: string): boolean; + isReadOnly(this: void, path: string): boolean; + getName(this: void, path: string): string; + getDrive(this: void, path: string): string; + getSize(this: void, path: string): number; + getFreeSpace(this: void, path: string): number; + makeDir(this: void, path: string): void; + move(this: void, from: string, to: string): void; + copy(this: void, from: string, to: string): void; + "delete"(this: void, path: string): void; + combine(this: void, base: string, ...local: string[]): string; + open( + this: void, + path: string, + mode: "r" | "rb", + ): LuaMultiReturn<[ReadFileHandle] | [undefined, string]>; + open( + this: void, + path: string, + mode: "w" | "wb" | "a" | "ab", + ): LuaMultiReturn<[WriteFileHandle] | [undefined, string]>; + open( + this: void, + path: string, + mode: "r+" | "rb+" | "w+" | "wb+" | "a+" | "ab+", + ): LuaMultiReturn<[ReadFileHandle & WriteFileHandle] | [undefined, string]>; + find(this: void, wildcard: string): string[]; + getDir(this: void, path: string): string; + complete( + this: void, + partial: string, + path: string, + includeFiles?: boolean, + includeSlashes?: boolean, + ): string[]; + complete( + this: void, + partial: string, + path: string, + options: { + include_dirs?: boolean; + include_files?: boolean; + include_hidden?: boolean; + }, + ): string[]; + getCapacity(this: void, path: string): number; + attributes(this: void, path: string): FileAttributes; + isDriveRoot(this: void, path: string): boolean; +}; +declare function sleep(time: number): void; +declare function write(str: string): number; +declare function print(...str: unknown[]): number; +declare function printError(...str: unknown[]): void; +declare function read( + replaceChar?: string, + history?: string[], + completeFn?: (partial: string) => string[], + defaultValue?: string, +): string; +declare let _CC_DEFAULT_SETTINGS: string; +declare let _CC_DISABLE_LUA51_FEATURES: boolean; +declare let _HOST: string; +/** @noSelf **/ +declare namespace gps { + let CHANNEL_GPS: number; + function locate( + timeout?: number, + debug?: boolean, + ): LuaMultiReturn<[number, number, number]>; +} +/** @noSelf **/ +declare namespace help { + function path(): string; + function setPath(path: string): void; + function lookup(topic: string): string | undefined; + function topics(): string[]; + function completeTopic(prefix: string): string[]; +} +interface RequestOptions { + url: string; + body?: string; + headers?: LuaMap; + binary?: boolean; + method?: string; + redirect?: boolean; + timeout?: number; +} +interface WebSocketOptions { + url: string; + headers?: LuaMap; + timeout?: number; +} + +/** @noSelf */ +declare class HTTPResponse { + public getResponseCode(): number; + public getResponseHeaders(): LuaMap; + public read(count?: number): string | number | undefined; + public readLine(withTrailing: boolean): string | undefined; + public readAll(): string | undefined; + public close(): void; +} + +/** @noSelf */ +declare class WebSocket { + public receive(timeout?: number): string | undefined; + public send(message: string, binary?: boolean): void; + public close(): void; +} + +/** @noSelf **/ +declare namespace http { + function request( + url: string, + body?: string, + headers?: LuaMap, + binary?: boolean, + ): void; + function request(options: RequestOptions): void; + function get( + url: string, + headers?: LuaMap, + binary?: boolean, + ): LuaMultiReturn<[HTTPResponse] | [undefined, string, HTTPResponse?]>; + function get( + options: RequestOptions, + ): LuaMultiReturn<[HTTPResponse] | [undefined, string, HTTPResponse?]>; + function post( + url: string, + body?: string, + headers?: LuaMap, + binary?: boolean, + ): LuaMultiReturn<[HTTPResponse] | [undefined, string, HTTPResponse?]>; + function post( + options: RequestOptions, + ): LuaMultiReturn<[HTTPResponse] | [undefined, string, HTTPResponse?]>; + function checkURLAsync(url: string): void; + function checkURL(url: string): boolean; + function websocket( + url: string, + headers?: LuaMap, + ): LuaMultiReturn<[WebSocket] | [false, string]>; + function websocket( + options: WebSocketOptions, + ): LuaMultiReturn<[WebSocket] | [false, string]>; + function websocketAsync(url: string, headers?: LuaMap): void; + function websocketAsync(options: WebSocketOptions): void; +} +type Key = number; + +declare const keys: { + a: Key; + apostrophe: Key; + at: Key; + ax: Key; + b: Key; + backslash: Key; + backspace: Key; + c: Key; + capsLock: Key; + cimcumflex: Key; + colon: Key; + comma: Key; + convert: Key; + d: Key; + delete: Key; + down: Key; + e: Key; + eight: Key; + end: Key; + enter: Key; + equals: Key; + f: Key; + f1: Key; + f10: Key; + f11: Key; + f12: Key; + f13: Key; + f14: Key; + f15: Key; + f2: Key; + f3: Key; + f4: Key; + f5: Key; + f6: Key; + f7: Key; + f8: Key; + f9: Key; + five: Key; + four: Key; + g: Key; + grave: Key; + h: Key; + home: Key; + i: Key; + insert: Key; + j: Key; + k: Key; + kana: Key; + kanji: Key; + l: Key; + left: Key; + leftAlt: Key; + leftBracket: Key; + leftCtrl: Key; + leftShift: Key; + m: Key; + minus: Key; + multiply: Key; + n: Key; + nine: Key; + noconvert: Key; + numLock: Key; + numPad0: Key; + numPad1: Key; + numPad2: Key; + numPad3: Key; + numPad4: Key; + numPad5: Key; + numPad6: Key; + numPad7: Key; + numPad8: Key; + numPad9: Key; + numPadAdd: Key; + numPadComma: Key; + numPadDecimal: Key; + numPadDivide: Key; + numPadEnter: Key; + numPadEquals: Key; + numPadSubtract: Key; + o: Key; + one: Key; + p: Key; + pageDown: Key; + pageUp: Key; + pause: Key; + period: Key; + q: Key; + r: Key; + returnKey: Key; + right: Key; + rightAlt: Key; + rightBracket: Key; + rightCtrl: Key; + rightShift: Key; + s: Key; + scollLock: Key; + semiColon: Key; + seven: Key; + six: Key; + slash: Key; + space: Key; + stop: Key; + t: Key; + tab: Key; + three: Key; + two: Key; + u: Key; + underscore: Key; + up: Key; + v: Key; + w: Key; + x: Key; + y: Key; + yen: Key; + z: Key; + zero: Key; + getName(this: void, k: Key): string; +}; +/** @noSelf **/ +declare namespace multishell { + function getFocus(): number; + function setFocus(n: number): boolean; + function getTitle(n: number): string | undefined; + function setTitle(n: number, title: string): void; + function getCurrent(): number; + function launch(env: LuaTable, path: string, ...args: string[]): number; + function getCount(): number; +} +declare interface LuaDate { + year: number; + month: number; + day: number; + hour: number; + min: number; + sec: number; + wday: number; + yday: number; + isdst: boolean; +} +/** @noSelf **/ +declare namespace os { + function version(): string; + function getComputerID(): number; + function computerID(): number; + function getComputerLabel(): string | undefined; + function computerLabel(): string | undefined; + function setComputerLabel(label?: string): void; + function run(env: LuaTable, path: string, ...args: string[]): boolean; + function queueEvent(type: string, ...param: unknown[]): void; + function clock(): number; + function startTimer(timeout: number): number; + function cancelTimer(id: number): void; + function time(mode?: string): number; + function sleep(timeout: number): void; + function day(mode?: string): number; + function setAlarm(time: number): number; + function cancelAlarm(id: number): void; + function shutdown(): void; + function reboot(): void; + function epoch(mode?: string): number; + function date(format?: string, time?: number): string | LuaDate; + function pullEvent(filter?: string): LuaMultiReturn<[string, ...unknown[]]>; + function pullEventRaw( + filter?: string, + ): LuaMultiReturn<[string, ...unknown[]]>; +} +/** @noSelf **/ +declare namespace paintutils { + function parseImage(image: string): number[][] | undefined; + function loadImage(path: string): number[][] | undefined; + function drawPixel(x: number, y: number, color?: Color): void; + function drawLine( + startX: number, + startY: number, + endX: number, + endY: number, + color?: Color, + ): void; + function drawBox( + startX: number, + startY: number, + endX: number, + endY: number, + color?: Color, + ): void; + function drawFilledBox( + startX: number, + startY: number, + endX: number, + endY: number, + color?: Color, + ): void; + function drawImage(image: number[][], x: number, y: number): void; +} +/** @noSelf **/ +declare namespace parallel { + function waitForunknown(...args: (() => void)[]): void; + function waitForAll(...args: (() => void)[]): void; +} +/** @noSelf */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +interface IPeripheral {} + +/** @noSelf */ +declare class CommandPeripheral implements IPeripheral { + getCommand(): string; + setCommand(command: string): void; + runCommand(): LuaMultiReturn<[boolean, string | undefined]>; +} + +/** @noSelf */ +declare class ComputerPeripheral implements IPeripheral { + turnOn(): void; + shutdown(): void; + reboot(): void; + getID(): number; + isOn(): boolean; + getLabel(): string; +} + +/** @noSelf */ +declare class DrivePeripheral implements IPeripheral { + isDiskPresent(): boolean; + getDiskLabel(): string; + setDiskLabel(label?: string): void; + hasData(): boolean; + getMountPath(): string; + hasAudio(): boolean; + getAudioTitle(): string; + playAudio(): void; + stopAudio(): void; + ejectDisk(): void; + getDiskID(): number; +} + +/** @noSelf */ +declare class ModemPeripheral implements IPeripheral { + open(channel: number): void; + isOpen(channel: number): boolean; + close(channel: number): void; + closeAll(): void; + transmit( + channel: number, + replyChannel: number, + payload: object | number | boolean | string, + ): void; + isWireless(): boolean; +} + +/** @noSelf */ +declare class WiredModemPeripheral extends ModemPeripheral { + getNamesRemote(): string[]; + isPresentRemote(name: string): boolean; + getTypeRemote(name: string): string; + getMethodsRemote(name: string): string[]; + callRemote( + name: string, + method: string, + ...args: string[] + ): LuaMultiReturn<[...unknown[]]>; + getNameLocal(): string; +} + +/** @noSelf */ +declare class MonitorPeripheral implements IPeripheral, ITerminal { + write(text: string): void; + blit(text: string, textColors: string, backgroundColors: string): void; + clear(): void; + clearLine(): void; + getCursorPos(): LuaMultiReturn<[number, number]>; + setCursorPos(x: number, y: number): void; + getCursorBlink(): boolean; + setCursorBlink(blink: boolean): void; + isColor(): boolean; + isColour(): boolean; + getSize(mode?: boolean | number): LuaMultiReturn<[number, number]>; + scroll(n: number): void; + getTextColor(): Color; + getTextColour(): Colour; + setTextColor(color: Color): void; + setTextColour(color: Colour): void; + getBackgroundColor(): Color; + getBackgroundColour(): Colour; + setBackgroundColor(color: Color): void; + setBackgroundColour(color: Colour): void; + getPaletteColor(color: Color): LuaMultiReturn<[Color, Color, Color]>; + getPaletteColour(color: Colour): LuaMultiReturn<[Colour, Colour, Colour]>; + setPaletteColor(color: Color, rgb: number): void; + setPaletteColor(color: Color, r: number, g: number, b: number): void; + setPaletteColour(color: Colour, rgb: number): void; + setPaletteColour(color: Colour, r: number, g: number, b: number): void; + getGraphicsMode(): boolean | number; + setGraphicsMode(mode: boolean | number): void; + getPixel(x: number, y: number): number; + setPixel(x: number, y: number, color: Color): void; + getPixels( + x: number, + y: number, + width: number, + height: number, + asString?: boolean, + ): (string | Color[])[]; + setPixels(x: number, y: number, data: Color | (string | Color[])[]): void; + getFrozen(): boolean; + setFrozen(frozen: boolean): void; + setTextScale(scale: number): void; +} + +/** @noSelf */ +declare class PrinterPeripheral implements IPeripheral { + write(...args: (string | number)[]): void; + getCursorPos(): LuaMultiReturn<[number, number]>; + setCursorPos(x: number, y: number): void; + getPageSize(): LuaMultiReturn<[number, number]>; + newPage(): void; + endPage(): void; + setPageTitle(title?: string): void; + getInkLevel(): number; + getPaperLevel(): number; +} + +/** @noSelf */ +declare class SpeakerPeripheral implements IPeripheral { + playSound(name: string, volume?: number, pitch?: number): void; + playNote(name: string, volume?: number, pitch?: number): void; + playAudio(data: number[], volume?: number): boolean; + stop(): void; +} + +/** @noSelf */ +declare class EnergyStoragePeripheral implements IPeripheral { + getEnergy(): number; + getEnergyCapacity(): number; +} + +/** @noSelf */ +declare class FluidStoragePeripheral implements IPeripheral { + tanks(): Record; + pushFluid(to: string, limit?: number, name?: string): number; + pullFluid(from: string, limit?: number, name?: string): number; +} + +declare interface SlotDetail { + name: string; + count: number; + nbt?: string; +} + +declare type ItemDetail = SlotDetail & { + displayName: string; + maxCount: number; + damage?: number; + maxDamage?: number; + durability?: number; + tags: string[]; + lore?: string[]; //? + enchantments?: { name: string; level: number; displayName: string }[]; + unbreakable?: boolean; +}; + +/** @noSelf */ +declare class InventoryPeripheral implements IPeripheral { + size(): number; + list(): Record; + getItemDetail(slot: number): ItemDetail | undefined; + getItemLimit(slot: number): number; + pushItems( + toName: string, + fromSlot: number, + limit?: number, + toSlot?: number, + ): number; + pullItems( + fromName: string, + fromSlot: number, + limit?: number, + toSlot?: number, + ): number; +} +/** @noSelf **/ +declare namespace peripheral { + function getNames(): string[]; + function isPresent(name: string): boolean; + function getType(peripheral: string): LuaMultiReturn<[...string[]]>; + function getType(peripheral: IPeripheral): string; + function hasType( + peripheral: IPeripheral | string, + type: string, + ): boolean | undefined; + function getMethods(name: string): string[] | undefined; + function getName(peripheral: IPeripheral): string; + function call( + side: string, + method: string, + ...args: unknown[] + ): LuaMultiReturn<[...unknown[]]>; + function wrap(name: string): IPeripheral | undefined; + function find( + type: string, + filter?: (name: string, peripheral: IPeripheral) => boolean, + ): LuaMultiReturn<[...IPeripheral[]]>; +} +/** @noSelf **/ +declare namespace pocket { + function equipBack(): LuaMultiReturn<[boolean, string | undefined]>; + function unequipBack(): LuaMultiReturn<[boolean, string | undefined]>; +} +/** @noSelf **/ +declare namespace rednet { + let CHANNEL_BROADCAST: number; + let CHANNEL_REPEAT: number; + let MAX_ID_CHANNELS: number; + function open(modem: string): void; + function close(modem?: string): void; + function isOpen(modem?: string): boolean; + function send( + recipient: number, + message: object | number | boolean | string, + protocol?: string, + ): boolean; + function broadcast( + message: object | number | boolean | string, + protocol?: string, + ): void; + function receive( + filter?: string, + timeout?: number, + ): LuaMultiReturn<[number, unknown, string | undefined] | [undefined]>; + function host(protocol: string, hostname: string): void; + function unhost(protocol: string): void; + function lookup( + protocol: string, + hostname?: string, + ): LuaMultiReturn<[...number[]]>; + function run(): void; +} +/** @noSelf **/ +declare namespace redstone { + function getSides(): string[]; + function setOutput(side: string, on: boolean): void; + function getOutput(side: string): boolean; + function getInput(side: string): boolean; + function setAnalogOutput(side: string, value: number): void; + function getAnalogOutput(side: string): number; + function getAnalogInput(side: string): number; + function setAnalogueOutput(side: string, value: number): void; + function getAnalogueOutput(side: string): number; + function getAnalogueInput(side: string): number; + function setBundledOutput(side: string, value: Color): void; + function getBundledOutput(side: string): Color; + function getBundledInput(side: string): Color; + function testBundledInput(side: string, mask: number): boolean; +} +interface SettingOptions { + description?: string; + default?: object; + type?: "number" | "boolean" | "string" | "table"; +} +/** @noSelf **/ +declare namespace settings { + function define(name: string, options?: SettingOptions): void; + function undefine(name: string): void; + function set(name: string, value: object): void; + function get(name: string, defaultValue?: object): unknown; + function getDetails(name: string): SettingOptions; + function unset(name: string): void; + function clear(): void; + function getNames(): string[]; + function load(path?: string): boolean; + function save(path?: string): boolean; +} +/** @noSelf **/ +declare namespace shell { + function exit(): void; + function dir(): string; + function setDir(path: string): void; + function path(): string; + function setPath(path: string): void; + function resolve(path: string): string; + function resolveProgram(name: string): string; + function aliases(): Record; + function setAlias(name: string, program: string): void; + function clearAlias(name: string): void; + function programs(showHidden?: boolean): string[]; + function getRunningProgram(): string; + function run(command: string, ...args: string[]): boolean; + function execute(command: string, ...args: string[]): boolean; + function openTab(command: string, ...args: string[]): number; + function switchTab(id: number): void; + function complete(prefix: string): string[]; + function completeProgram(prefix: string): string[]; + function setCompletionFunction( + path: string, + completion: ( + shell: LuaTable | Object, + index: number, + partial: string, + previous: string[], + ) => string[], + ): void; + function getCompletionInfo(): { + fnComplete: ( + shell: LuaTable | Object, + index: number, + partial: string, + previous: string[], + ) => string[]; + }[]; +} +/** @noSelf */ +interface ITerminal { + write(text: string): void; + blit(text: string, textColors: string, backgroundColors: string): void; + clear(): void; + clearLine(): void; + getCursorPos(): LuaMultiReturn<[number, number]>; + setCursorPos(x: number, y: number): void; + getCursorBlink(): boolean; + setCursorBlink(blink: boolean): void; + isColor(): boolean; + isColour(): boolean; + getSize(mode?: boolean | number): LuaMultiReturn<[number, number]>; + scroll(n: number): void; + getTextColor(): Color; + getTextColour(): Colour; + setTextColor(color: Color): void; + setTextColour(color: Colour): void; + getBackgroundColor(): Color; + getBackgroundColour(): Colour; + setBackgroundColor(color: Color): void; + setBackgroundColour(color: Colour): void; + getPaletteColor(color: Color): LuaMultiReturn<[number, number, number]>; + getPaletteColour(color: Colour): LuaMultiReturn<[number, number, number]>; + setPaletteColor(color: Color, rgb: number): void; + setPaletteColor(color: Color, r: number, g: number, b: number): void; + setPaletteColour(color: Colour, rgb: number): void; + setPaletteColour(color: Colour, r: number, g: number, b: number): void; + getGraphicsMode(): boolean | number; + setGraphicsMode(mode: boolean | number): void; + getPixel(x: number, y: number): number; + setPixel(x: number, y: number, color: Color): void; + getPixels( + x: number, + y: number, + width: number, + height: number, + asString?: boolean, + ): (string | Color[])[]; + setPixels(x: number, y: number, data: Color | (string | Color[])[]): void; + getFrozen(): boolean; + setFrozen(frozen: boolean): void; +} +/** @noSelf **/ +declare namespace term { + function redirect(term: ITerminal): ITerminal; + function current(): ITerminal; + function native(): ITerminal; + function screenshot(): void; + function showMouse(mouse: boolean): void; + function write(text: string): void; + function blit( + text: string, + textColors: string, + backgroundColors: string, + ): void; + function clear(): void; + function clearLine(): void; + function getCursorPos(): LuaMultiReturn<[number, number]>; + function setCursorPos(x: number, y: number): void; + function getCursorBlink(): boolean; + function setCursorBlink(blink: boolean): void; + function isColor(): boolean; + function isColour(): boolean; + function getSize(mode?: boolean | number): LuaMultiReturn<[number, number]>; + function scroll(n: number): void; + function getTextColor(): Color; + function getTextColour(): Colour; + function setTextColor(color: Color): void; + function setTextColour(color: Colour): void; + function getBackgroundColor(): Color; + function getBackgroundColour(): Colour; + function setBackgroundColor(color: Color): void; + function setBackgroundColour(color: Colour): void; + function nativePaletteColor( + color: number, + ): LuaMultiReturn<[number, number, number]>; + function nativePaletteColour( + colour: number, + ): LuaMultiReturn<[number, number, number]>; + function getPaletteColor( + color: Color, + ): LuaMultiReturn<[number, number, number]>; + function getPaletteColour( + color: Colour, + ): LuaMultiReturn<[number, number, number]>; + function setPaletteColor(color: Color, rgb: number): void; + function setPaletteColor(color: Color, r: number, g: number, b: number): void; + function setPaletteColour(color: Colour, rgb: number): void; + function setPaletteColour( + color: Colour, + r: number, + g: number, + b: number, + ): void; + function getGraphicsMode(): boolean | number; + function setGraphicsMode(mode: boolean | number): void; + function getPixel(x: number, y: number): number; + function setPixel(x: number, y: number, color: Color): void; + function getPixels( + x: number, + y: number, + width: number, + height: number, + asString?: boolean, + ): (string | Color[])[]; + function setPixels( + x: number, + y: number, + data: Color | (string | Color[])[], + ): void; + function getFrozen(): boolean; + function setFrozen(frozen: boolean): void; +} +interface UnserializeJSONOptions { + nbt_style?: boolean; + parse_null?: boolean; + parse_empty_array?: boolean; +} +interface SerializeOptions { + compact?: boolean; + allow_repetitions?: boolean; +} +interface SerializeJSONOptions { + nbtStyle?: boolean; + allow_repetitions?: boolean; + unicode_strings?: boolean; +} +/** @noSelf **/ +declare namespace textutils { + let empty_json_array: Object; + let json_null: Object; + function slowWrite(text: string, rate?: number): void; + function slowPrint(text: string, rate?: number): void; + function formatTime(time: number, hour24?: boolean): string; + function pagedPrint(text: string, freeLines?: number): number; + function tabulate(...args: (LuaTable | Object | Color)[]): void; + function pagedTabulate(...args: (LuaTable | Object | Color)[]): void; + function serialize(tab: object, options?: SerializeOptions): string; + function serialise(tab: object, options?: SerializeOptions): string; + function serializeJSON(tab: object, nbtStyle?: boolean): string; + function serializeJSON(tab: object, options: SerializeJSONOptions): string; + function serialiseJSON(tab: object, nbtStyle?: boolean): string; + function serialiseJSON(tab: object, options: SerializeJSONOptions): string; + function unserialize(str: string): unknown; + function unserialise(str: string): unknown; + function unserializeJSON( + str: string, + options?: UnserializeJSONOptions, + ): unknown; + function unserialiseJSON( + str: string, + options?: UnserializeJSONOptions, + ): unknown; + function urlEncode(url: string): string; + function complete(searchText: string, searchTable?: object): string[]; +} +/** @noSelf **/ +declare namespace turtle { + function craft( + quantity?: number, + ): LuaMultiReturn<[true, undefined] | [false, string]>; + function forward(): LuaMultiReturn<[boolean, string | undefined]>; + function back(): LuaMultiReturn<[boolean, string | undefined]>; + function up(): LuaMultiReturn<[boolean, string | undefined]>; + function down(): LuaMultiReturn<[boolean, string | undefined]>; + function turnLeft(): LuaMultiReturn<[boolean, string | undefined]>; + function turnRight(): LuaMultiReturn<[boolean, string | undefined]>; + function select(slotNum: number): true; + function getSelectedSlot(): number; + + function getItemCount(slotNum?: number): number; + + function getItemSpace(slotNum?: number): number; + + function getItemDetail( + slotNum?: number, + detailed?: boolean, + ): LuaTable | Object | undefined; + + function equipLeft(): LuaMultiReturn<[true, undefined] | [false, string]>; + function equipRight(): LuaMultiReturn<[true, undefined] | [false, string]>; + + function attack( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + function attackUp( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + function attackDown( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + + function dig( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + function digUp( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + function digDown( + toolSide?: "left" | "right", + ): LuaMultiReturn<[boolean, string | undefined]>; + + function place(text?: string): LuaMultiReturn<[boolean, string | undefined]>; + function placeUp( + text?: string, + ): LuaMultiReturn<[boolean, string | undefined]>; + function placeDown( + text?: string, + ): LuaMultiReturn<[boolean, string | undefined]>; + + function detect(): boolean; + function detectUp(): boolean; + function detectDown(): boolean; + + function inspect(): LuaMultiReturn<[boolean, LuaTable | Object | string]>; + function inspectUp(): LuaMultiReturn<[boolean, LuaTable | Object | string]>; + function inspectDown(): LuaMultiReturn<[boolean, LuaTable | Object | string]>; + + function compare(): boolean; + function compareUp(): boolean; + function compareDown(): boolean; + + function drop(count?: number): LuaMultiReturn<[boolean, string | undefined]>; + function dropUp( + count?: number, + ): LuaMultiReturn<[boolean, string | undefined]>; + function dropDown( + count?: number, + ): LuaMultiReturn<[boolean, string | undefined]>; + + function suck(count?: number): LuaMultiReturn<[boolean, string | undefined]>; + function suckUp( + count?: number, + ): LuaMultiReturn<[boolean, string | undefined]>; + function suckDown( + count?: number, + ): LuaMultiReturn<[boolean, string | undefined]>; + + function refuel( + count?: number, + ): LuaMultiReturn<[true, undefined] | [false, string]>; + function getFuelLevel(): number | "unlimited"; + function getFuelLimit(): number | "unlimited"; + + function transferTo(slotNum: number, quantity?: number): boolean; +} +/** @customConstructor vector.new */ +declare class Vector { + constructor(x: number, y: number, z: number); + public x: number; + public y: number; + public z: number; + public add(this: Vector, o: Vector): Vector; + public sub(this: Vector, o: Vector): Vector; + public mul(this: Vector, o: number): Vector; + public div(this: Vector, o: number): Vector; + public unm(this: Vector): Vector; + public dot(this: Vector, o: Vector): number; + public cross(this: Vector, o: Vector): Vector; + public length(this: Vector): number; + public normalize(this: Vector): Vector; + public round(this: Vector, tolerance?: number): Vector; + public tostring(this: Vector): string; + public equals(this: Vector, o: Vector): boolean; +} +/** + * @customConstructor window.create + * @noSelf */ +declare class Window implements ITerminal { + constructor( + parent: ITerminal, + x: number, + y: number, + width: number, + height: number, + visible?: boolean, + ); + public write(text: string): void; + public blit(text: string, textColors: string, backgroundColors: string): void; + public clear(): void; + public clearLine(): void; + public getCursorPos(): LuaMultiReturn<[number, number]>; + public setCursorPos(x: number, y: number): void; + public getCursorBlink(): boolean; + public setCursorBlink(blink: boolean): void; + public isColor(): boolean; + public isColour(): boolean; + public getSize(mode?: boolean | number): LuaMultiReturn<[number, number]>; + public scroll(n: number): void; + public getTextColor(): Color; + public getTextColour(): Colour; + public setTextColor(color: Color): void; + public setTextColour(color: Colour): void; + public getBackgroundColor(): Color; + public getBackgroundColour(): Colour; + public setBackgroundColor(color: Color): void; + public setBackgroundColour(color: Colour): void; + public getPaletteColor( + color: Color, + ): LuaMultiReturn<[number, number, number]>; + public getPaletteColour( + color: Colour, + ): LuaMultiReturn<[number, number, number]>; + public setPaletteColor(color: Color, rgb: number): void; + public setPaletteColor(color: Color, r: number, g: number, b: number): void; + public setPaletteColour(color: Colour, rgb: number): void; + public setPaletteColour(color: Colour, r: number, g: number, b: number): void; + public getGraphicsMode(): boolean | number; + public setGraphicsMode(mode: boolean | number): void; + public getPixel(x: number, y: number): number; + public setPixel(x: number, y: number, color: Color): void; + public getPixels( + x: number, + y: number, + width: number, + height: number, + asString?: boolean, + ): (string | Color[])[]; + public setPixels( + x: number, + y: number, + data: Color | (string | Color[])[], + ): void; + public getFrozen(): boolean; + public setFrozen(frozen: boolean): void; + public getVisible(): boolean; + public setVisible(visible: boolean): void; + public redraw(): void; + public restoreCursor(): void; + public getPosition(): LuaMultiReturn<[number, number]>; + public reposition( + x: number, + y: number, + width?: number, + height?: number, + ): void; +} diff --git a/types/craftos/package.json b/types/craftos/package.json new file mode 100644 index 0000000..befc854 --- /dev/null +++ b/types/craftos/package.json @@ -0,0 +1,11 @@ +{ + "name": "@jackmacwindows/craftos-types", + "version": "1.1.3", + "description": "TypeScript type definitions for base CraftOS APIs.", + "types": "./index.d.ts", + "files": [ + "./index.d.ts" + ], + "author": "JackMacWindows", + "license": "MIT" +}