diff --git a/.github/workflows/ci-as-build.yml b/.github/workflows/ci-as-build.yml new file mode 100644 index 00000000..5a778e57 --- /dev/null +++ b/.github/workflows/ci-as-build.yml @@ -0,0 +1,52 @@ +name: ci-as-build +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review +jobs: + get-dirs: + name: Get Directories + runs-on: ubuntu-latest + outputs: + dirs: ${{ steps.get-dirs.outputs.dirs }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Get subdirectories + id: get-dirs + # we need to build all the examples + run: echo "dirs=$(ls -d examples/*/ | jq -Rsc 'split("\n")[:-1]' )" >> ${GITHUB_OUTPUT} + + as-build: + needs: get-dirs + if: github.event_name == 'pull_request' + name: Build + runs-on: ubuntu-latest + strategy: + matrix: + dir: ${{ fromJson(needs.get-dirs.outputs.dirs) }} + defaults: + run: + working-directory: ${{ matrix.dir }} + steps: + - name: Checkout Source + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ">=20" + - name: Install dependencies + working-directory: src/ + run: npm install + - name: Establish link + working-directory: src/ + run: npm link + - name: Install additional dependencies + run: npm install + - name: Use linked source + run: npm link @hypermode/functions-as + - name: Build project + run: npm run build diff --git a/.github/workflows/ci-as-lint.yml b/.github/workflows/ci-as-lint.yml index 9951f4e6..7dbf691b 100644 --- a/.github/workflows/ci-as-lint.yml +++ b/.github/workflows/ci-as-lint.yml @@ -32,17 +32,25 @@ jobs: run: working-directory: ${{ matrix.dir }} steps: - - uses: actions/checkout@v4 + - name: Checkout Source + uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: ">=20" - - name: Check Node and NPM versions - run: | - node --version - npm --version - name: Install dependencies + working-directory: src/ + run: npm install + - name: Establish link + if: ${{ matrix.dir != 'src/' }} + working-directory: src/ + run: npm link + - name: Install additional dependencies + if: ${{ matrix.dir != 'src/' }} run: npm install + - name: Use linked source + if: ${{ matrix.dir != 'src/' }} + run: npm link @hypermode/functions-as - name: Validate code is formatted run: npm run pretty:check - name: Valid code is linted diff --git a/.github/workflows/ci-as-tests.yml b/.github/workflows/ci-as-tests.yml index c8c42289..a2d1d5e0 100644 --- a/.github/workflows/ci-as-tests.yml +++ b/.github/workflows/ci-as-tests.yml @@ -20,10 +20,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: ">=20" - - name: Check Node and NPM versions - run: | - node --version - npm --version - name: Install dependencies run: npm install - name: Run Unit Tests diff --git a/examples/hmplugin1/package-lock.json b/examples/hmplugin1/package-lock.json index dd24c969..5f30bc69 100644 --- a/examples/hmplugin1/package-lock.json +++ b/examples/hmplugin1/package-lock.json @@ -14,9 +14,9 @@ }, "devDependencies": { "@assemblyscript/wasi-shim": "^0.1.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "assemblyscript": "^0.27.25", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", + "assemblyscript": "^0.27.26", "assemblyscript-prettier": "^3.0.1", "eslint": "^8.57.0", "prettier": "^3.2.5", @@ -171,9 +171,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@hypermode/functions-as": { @@ -243,16 +243,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", - "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz", + "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/type-utils": "7.4.0", - "@typescript-eslint/utils": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/type-utils": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -278,15 +278,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", - "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz", + "integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4" }, "engines": { @@ -306,13 +306,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz", + "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -323,13 +323,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", - "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz", + "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/utils": "7.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -350,9 +350,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz", + "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -363,13 +363,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz", + "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -391,17 +391,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", "semver": "^7.5.4" }, "engines": { @@ -416,12 +416,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz", + "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/types": "7.5.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -530,9 +530,9 @@ "integrity": "sha512-R1nR7TT0KcROL/TxSXmiX2Q+7CgUMrjT/y9IP07StStqWs32KT2mpadJNF//yHWRaIJWe6atqTqO0JzsdhkPcQ==" }, "node_modules/assemblyscript": { - "version": "0.27.25", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.25.tgz", - "integrity": "sha512-hkx6Vz+EFVA2hqFfnTWfO14892scFIkJzdXyqfXUoBS76cLbar0PFJQ7yZuL9m/i5xpjFk9Bz2094uHLh7W5UA==", + "version": "0.27.26", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.26.tgz", + "integrity": "sha512-1Fn3r45s+F0zgOSTp2Hbw8+XTot/aNdzRToY+9peuWHAcQXRzlZZborBXcqkypYYvNvEa1etNxhlkqQ2oWZhNg==", "dev": true, "dependencies": { "binaryen": "116.0.0-nightly.20240114", @@ -933,9 +933,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -996,9 +996,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/fs.realpath": { @@ -1112,9 +1112,9 @@ } }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -1698,9 +1698,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { "node": ">=16" @@ -1710,9 +1710,9 @@ } }, "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", "dev": true }, "node_modules/type-check": { @@ -1740,9 +1740,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "peer": true, "bin": { diff --git a/examples/hmplugin1/package.json b/examples/hmplugin1/package.json index 363a0e31..a8667222 100644 --- a/examples/hmplugin1/package.json +++ b/examples/hmplugin1/package.json @@ -21,9 +21,9 @@ }, "devDependencies": { "@assemblyscript/wasi-shim": "^0.1.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "assemblyscript": "^0.27.25", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", + "assemblyscript": "^0.27.26", "assemblyscript-prettier": "^3.0.1", "eslint": "^8.57.0", "prettier": "^3.2.5", diff --git a/src/.eslintrc.json b/src/.eslintrc.json index dcee4cdc..2024a700 100644 --- a/src/.eslintrc.json +++ b/src/.eslintrc.json @@ -14,6 +14,12 @@ { "files": ["./assembly/**/*.ts"], "parser": "./eslintParser.cjs" + }, + { + "files": ["./transform/**"], + "env": { + "node": true + } } ] } diff --git a/src/.prettierignore b/src/.prettierignore new file mode 100644 index 00000000..5935aaad --- /dev/null +++ b/src/.prettierignore @@ -0,0 +1 @@ +transform/lib/ diff --git a/src/asconfig.json b/src/asconfig.json index 16266ab0..9cf3c10d 100644 --- a/src/asconfig.json +++ b/src/asconfig.json @@ -1,5 +1,5 @@ { "options": { - "transform": ["./transform", "json-as/transform"] + "transform": ["json-as/transform"] } } diff --git a/src/package-lock.json b/src/package-lock.json index c3b6b4e4..3d89caec 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -14,9 +14,10 @@ "xid-ts": "^1.1.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^7.3.1", - "@typescript-eslint/parser": "^7.3.1", - "assemblyscript": "^0.27.25", + "@types/node": "^20.12.3", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", + "assemblyscript": "^0.27.26", "assemblyscript-prettier": "^3.0.1", "eslint": "^8.57.0", "prettier": "^3.2.5", @@ -160,9 +161,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@nodelib/fs.scandir": { @@ -206,6 +207,15 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/node": { + "version": "20.12.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.3.tgz", + "integrity": "sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -213,16 +223,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", - "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz", + "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/type-utils": "7.4.0", - "@typescript-eslint/utils": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/type-utils": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -248,15 +258,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", - "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz", + "integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4" }, "engines": { @@ -276,13 +286,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz", + "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -293,13 +303,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", - "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz", + "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/utils": "7.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -320,9 +330,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz", + "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -333,13 +343,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz", + "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -361,17 +371,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", "semver": "^7.5.4" }, "engines": { @@ -386,12 +396,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz", + "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/types": "7.5.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -500,9 +510,9 @@ "integrity": "sha512-R1nR7TT0KcROL/TxSXmiX2Q+7CgUMrjT/y9IP07StStqWs32KT2mpadJNF//yHWRaIJWe6atqTqO0JzsdhkPcQ==" }, "node_modules/assemblyscript": { - "version": "0.27.25", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.25.tgz", - "integrity": "sha512-hkx6Vz+EFVA2hqFfnTWfO14892scFIkJzdXyqfXUoBS76cLbar0PFJQ7yZuL9m/i5xpjFk9Bz2094uHLh7W5UA==", + "version": "0.27.26", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.27.26.tgz", + "integrity": "sha512-1Fn3r45s+F0zgOSTp2Hbw8+XTot/aNdzRToY+9peuWHAcQXRzlZZborBXcqkypYYvNvEa1etNxhlkqQ2oWZhNg==", "dev": true, "dependencies": { "binaryen": "116.0.0-nightly.20240114", @@ -903,9 +913,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -966,9 +976,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/fs.realpath": { @@ -1082,9 +1092,9 @@ } }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -1658,9 +1668,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { "node": ">=16" @@ -1670,9 +1680,9 @@ } }, "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", "dev": true }, "node_modules/type-check": { @@ -1700,9 +1710,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "peer": true, "bin": { @@ -1713,6 +1723,12 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/src/package.json b/src/package.json index 703af4be..fd929f6d 100644 --- a/src/package.json +++ b/src/package.json @@ -6,6 +6,8 @@ "license": "MIT", "type": "module", "scripts": { + "build:transform": "tsc -p ./transform", + "prepare": "$npm_execpath run build:transform", "pretest": "$npm_execpath list @as-pect/cli || $npm_execpath install --no-save --no-audit @as-pect/cli", "test": "asp --verbose", "pretty": "prettier --write .", @@ -19,9 +21,10 @@ "xid-ts": "^1.1.0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^7.3.1", - "@typescript-eslint/parser": "^7.3.1", - "assemblyscript": "^0.27.25", + "@types/node": "^20.12.3", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", + "assemblyscript": "^0.27.26", "assemblyscript-prettier": "^3.0.1", "eslint": "^8.57.0", "prettier": "^3.2.5", @@ -29,5 +32,8 @@ }, "overrides": { "assemblyscript": "$assemblyscript" + }, + "exports": { + "./transform": "./transform/lib/index.js" } } diff --git a/src/transform.js b/src/transform.js deleted file mode 100644 index ca1ba8a3..00000000 --- a/src/transform.js +++ /dev/null @@ -1,82 +0,0 @@ -import { Transform } from "assemblyscript/transform"; -import { TextEncoder } from "util"; -import { readFileSync } from "fs"; -import { fileURLToPath } from "url"; -import { dirname, join } from "path"; -import { execSync } from "child_process"; -import { Xid } from "xid-ts"; -import process from "process"; - -// This transform adds metadata to the compiled wasm file, as custom sections. - -export default class HypermodeTransform extends Transform { - afterCompile(module) { - // Setup for adding UTF-8 strings in wasm custom sections. - const encoder = new TextEncoder(); - const addInfo = (name, data) => { - module.addCustomSection(name, encoder.encode(data)); - }; - - // Add metadata. - addInfo("build_id", getBuildId()); - addInfo("build_ts", getBuildTimestamp()); - addInfo("hypermode_library", getHypermodeInfo()); - addInfo("hypermode_plugin", getPluginInfo()); - - // Add git metadata if available. - if (isGitRepo()) { - addInfo("git_repo", getGitRepo()); - addInfo("git_commit", getGitCommit()); - } - } -} - -function getBuildId() { - return new Xid().toString(); -} - -function getBuildTimestamp() { - return new Date().toISOString(); -} - -function getHypermodeInfo() { - const path = join(dirname(fileURLToPath(import.meta.url)), "package.json"); - const lib = JSON.parse(readFileSync(path)); - return `${lib.name}@${lib.version}`; -} - -function getPluginInfo() { - const pluginName = process.env.npm_package_name; - const pluginVersion = process.env.npm_package_version; - return `${pluginName}@${pluginVersion}`; -} - -function isGitRepo() { - try { - // This will throw if not in a git repo, or if git is not installed. - execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" }); - return true; - } catch (e) { - return false; - } -} - -function getGitRepo() { - let url = execSync("git remote get-url origin").toString().trim(); - - // Convert ssh to https - if (url.startsWith("git@")) { - url = url.replace(":", "/").replace("git@", "https://"); - } - - // Remove the .git suffix - if (url.endsWith(".git")) { - url = url.slice(0, -4); - } - - return url; -} - -function getGitCommit() { - return execSync("git rev-parse HEAD").toString().trim(); -} diff --git a/src/transform/.gitignore b/src/transform/.gitignore new file mode 100644 index 00000000..c3af8579 --- /dev/null +++ b/src/transform/.gitignore @@ -0,0 +1 @@ +lib/ diff --git a/src/transform/src/extractor.ts b/src/transform/src/extractor.ts new file mode 100644 index 00000000..d2d334bf --- /dev/null +++ b/src/transform/src/extractor.ts @@ -0,0 +1,79 @@ +import { Program } from "assemblyscript/dist/assemblyscript.js"; +import { Transform } from "assemblyscript/dist/transform.js"; +import binaryen from "assemblyscript/lib/binaryen.js"; +import { FunctionSignature } from "./types.js"; + +export class Extractor { + binaryen: typeof binaryen; + module: binaryen.Module; + program: Program; + + constructor(transform: Transform, module: binaryen.Module) { + this.program = transform.program; + this.binaryen = transform.binaryen; + this.module = module; + } + + async getExportedFunctions(): Promise { + const functions = await this.getAllFunctions(); + const paths = this.getExportedFunctionPaths(); + + const results = paths + .map((path) => functions.get(path)) + .filter((f) => f !== undefined) + .sort((a, b) => a.name.localeCompare(b.name)); + + return results; + } + + private async getAllFunctions(): Promise> { + ignoreCompilerMismatchWarning(); + const { HypermodeVisitor } = await import("./visitor.js"); + const visitor = new HypermodeVisitor(); + this.program.parser.sources.forEach((source) => visitor.visit(source)); + return visitor.functions; + } + + private getExportedFunctionPaths(): string[] { + const paths = []; + + const funcs = new Map(); + for (let i = 0; i < this.module.getNumFunctions(); ++i) { + const ref = this.module.getFunctionByIndex(i); + const info = this.binaryen.getFunctionInfo(ref); + funcs.set(info.name, info); + } + + for (let i = 0; i < this.module.getNumExports(); ++i) { + const ref = this.module.getExportByIndex(i); + const info = this.binaryen.getExportInfo(ref); + + if (info.kind !== binaryen.ExternalFunction) { + continue; + } + + if (info.name.startsWith("_")) { + continue; + } + + const f = funcs.get(info.value); + if (f === undefined) { + continue; + } + + paths.push(info.value.replace(/^export:/, "")); + } + + return paths; + } +} + +const cw = console.warn; +function ignoreCompilerMismatchWarning() { + console.warn = (message?: unknown, ...optionalParams: unknown[]): void => { + if (message === "compiler mismatch: std/portable included twice") { + return; + } + cw(message, ...optionalParams); + }; +} diff --git a/src/transform/src/index.ts b/src/transform/src/index.ts new file mode 100644 index 00000000..953e8878 --- /dev/null +++ b/src/transform/src/index.ts @@ -0,0 +1,18 @@ +import { Transform } from "assemblyscript/dist/transform.js"; +import { HypermodeMetadata } from "./metadata.js"; +import { Extractor } from "./extractor.js"; +import writeLogo from "./logo.js"; + +export default class HypermodeTransform extends Transform { + async afterCompile(module) { + const extractor = new Extractor(this, module); + const functions = await extractor.getExportedFunctions(); + + const m = HypermodeMetadata.generate(); + m.addFunctions(functions); + m.writeToModule(module); + + writeLogo(process.stdout); + m.logToStream(process.stdout); + } +} diff --git a/src/transform/src/logo.ts b/src/transform/src/logo.ts new file mode 100644 index 00000000..e83a2e95 --- /dev/null +++ b/src/transform/src/logo.ts @@ -0,0 +1,16 @@ +import { Colors } from "assemblyscript/util/terminal.js"; +import { WriteStream } from "tty"; + +export default (stream: WriteStream) => { + const colors = new Colors(stream); + stream.write( + colors.blue(String.raw` + __ __ __ + / // /_ _____ ___ ______ _ ___ ___/ /__ + / _ / // / _ \/ -_) __/ ' \/ _ \/ _ / -_) + /_//_/\_, / .__/\__/_/ /_/_/_/\___/\_,_/\__/ + /___/_/ +`), + ); + stream.write("\n"); +}; diff --git a/src/transform/src/metadata.ts b/src/transform/src/metadata.ts new file mode 100644 index 00000000..12645ca0 --- /dev/null +++ b/src/transform/src/metadata.ts @@ -0,0 +1,113 @@ +import { readFileSync } from "fs"; +import { fileURLToPath } from "url"; +import { execSync } from "child_process"; +import * as path from "path"; +import { Xid } from "xid-ts"; +import binaryen from "assemblyscript/lib/binaryen.js"; +import { Colors } from "assemblyscript/util/terminal.js"; +import { FunctionSignature } from "./types.js"; +import { WriteStream } from "tty"; + +export class HypermodeMetadata { + buildId: string; + buildTs: string; + plugin: string; + library: string; + gitRepo?: string; + gitCommit?: string; + functions: FunctionSignature[] = []; + + static generate(): HypermodeMetadata { + const m = new HypermodeMetadata(); + + m.buildId = new Xid().toString(); + m.buildTs = new Date().toISOString(); + m.plugin = getPluginInfo(); + m.library = getHypermodeInfo(); + + if (isGitRepo()) { + m.gitRepo = getGitRepo(); + m.gitCommit = getGitCommit(); + } + + return m; + } + + addFunctions(functions: FunctionSignature[]) { + this.functions.push(...functions); + } + + writeToModule(module: binaryen.Module) { + const encoder = new TextEncoder(); + const json = JSON.stringify(this); + module.addCustomSection("hypermode_meta", encoder.encode(json)); + } + + logToStream(stream: WriteStream) { + const colors = new Colors(stream); + const write = (text: string) => stream.write(colors.cyan(text) + "\n"); + + write("Plugin Metadata:"); + write(` Plugin Name: ${this.plugin}`); + write(` Library: ${this.library}`); + write(` Build ID: ${this.buildId}`); + write(` Build Timestamp: ${this.buildTs}`); + if (this.gitRepo) { + write(` Git Repo: ${this.gitRepo}`); + write(` Git Commit: ${this.gitCommit}`); + } + write(""); + + write("Hypermode Functions:"); + this.functions.forEach((f) => write(` ${f.toString()}`)); + write(""); + } +} + +function getHypermodeInfo(): string { + const filePath = path.join( + path.dirname(fileURLToPath(import.meta.url)), + "..", + "..", + "package.json", + ); + const json = readFileSync(filePath).toString(); + const lib = JSON.parse(json); + return `${lib.name}@${lib.version}`; +} + +function getPluginInfo(): string { + const pluginName = process.env.npm_package_name; + const pluginVersion = process.env.npm_package_version; + return `${pluginName}@${pluginVersion}`; +} + +function isGitRepo(): boolean { + try { + // This will throw if not in a git repo, or if git is not installed. + execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" }); + return true; + } catch (e) { + return false; + } +} + +function getGitRepo(): string { + let url = execSync("git remote get-url origin").toString().trim(); + + // Convert ssh to https + if (url.startsWith("git@")) { + url = url.replace(":", "/").replace("git@", "https://"); + } + + // Remove the .git suffix + if (url.endsWith(".git")) { + url = url.slice(0, -4); + } + + return url; +} + +function getGitCommit(): string { + return execSync("git rev-parse HEAD").toString().trim(); +} diff --git a/src/transform/src/types.ts b/src/transform/src/types.ts new file mode 100644 index 00000000..25962280 --- /dev/null +++ b/src/transform/src/types.ts @@ -0,0 +1,19 @@ +export class FunctionSignature { + constructor( + public name: string, + public parameters: Parameter[], + public returnType: string, + ) {} + + toString() { + const params = this.parameters + .map((p) => `${p.name}: ${p.type}`) + .join(", "); + return `${this.name}(${params}): ${this.returnType}`; + } +} + +interface Parameter { + name: string; + type: string; +} diff --git a/src/transform/src/visitor.ts b/src/transform/src/visitor.ts new file mode 100644 index 00000000..4f0cddf0 --- /dev/null +++ b/src/transform/src/visitor.ts @@ -0,0 +1,34 @@ +import { FunctionSignature } from "./types.js"; +import { BaseVisitor } from "visitor-as"; +import { + FunctionDeclaration, + NamedTypeNode, +} from "assemblyscript/dist/assemblyscript.js"; + +export class HypermodeVisitor extends BaseVisitor { + functions = new Map(); + + visitFunctionDeclaration(node: FunctionDeclaration): void { + const internalPath = node.range.source.internalPath; + + // skip library functions + if (internalPath.startsWith("~")) { + return; + } + + const name = node.name.text; + const path = `${internalPath}/${name}`; + + const signature = node.signature; + const parameters = signature.parameters.map((p) => ({ + name: p.name.text, + type: (p.type as NamedTypeNode).name.identifier.text, + })); + + const returnTypeNode = signature.returnType as NamedTypeNode; + const returnType = returnTypeNode.name.identifier.text; + + const f = new FunctionSignature(name, parameters, returnType); + this.functions.set(path, f); + } +} diff --git a/src/transform/tsconfig.json b/src/transform/tsconfig.json new file mode 100644 index 00000000..50c6bdf9 --- /dev/null +++ b/src/transform/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2020", + "moduleResolution": "Node", + "removeComments": true, + "outDir": "./lib", + "sourceMap": true + } +}