├── .cargo └── config.toml ├── .editorconfig ├── .eslintrc.yml ├── .gitattributes ├── .github └── workflows │ ├── CI.yml │ └── lint.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .prettierignore ├── .yarn └── releases │ └── yarn-3.4.1.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── __test__ ├── fa-brands-400-v6.2.woff2 ├── fa-regular-400-v5.15.4.woff2 └── index.spec.ts ├── benchmark └── bench.mjs ├── build.rs ├── example └── index.mjs ├── index.d.ts ├── index.js ├── npm ├── android-arm-eabi │ ├── README.md │ └── package.json ├── android-arm64 │ ├── README.md │ └── package.json ├── darwin-arm64 │ ├── README.md │ └── package.json ├── darwin-x64 │ ├── README.md │ └── package.json ├── freebsd-x64 │ ├── README.md │ └── package.json ├── linux-arm-gnueabihf │ ├── README.md │ └── package.json ├── linux-arm64-gnu │ ├── README.md │ └── package.json ├── linux-arm64-musl │ ├── README.md │ └── package.json ├── linux-x64-gnu │ ├── README.md │ └── package.json ├── linux-x64-musl │ ├── README.md │ └── package.json ├── win32-arm64-msvc │ ├── README.md │ └── package.json ├── win32-ia32-msvc │ ├── README.md │ └── package.json └── win32-x64-msvc │ ├── README.md │ └── package.json ├── package.json ├── rustfmt.toml ├── simple-test.js ├── src └── lib.rs ├── tsconfig.json └── yarn.lock /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.x86_64-unknown-linux-musl] 2 | rustflags = [ 3 | "-C", 4 | "target-feature=-crt-static", 5 | ] 6 | 7 | [target.aarch64-unknown-linux-musl] 8 | linker = "aarch64-linux-musl-gcc" 9 | rustflags = ["-C", "target-feature=-crt-static"] 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors or IDEs 3 | # http://editorconfig.org 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | parser: '@typescript-eslint/parser' 2 | 3 | parserOptions: 4 | ecmaFeatures: 5 | jsx: true 6 | ecmaVersion: latest 7 | sourceType: module 8 | project: ./tsconfig.json 9 | 10 | env: 11 | browser: true 12 | es6: true 13 | node: true 14 | jest: true 15 | 16 | plugins: 17 | - import 18 | - '@typescript-eslint' 19 | 20 | extends: 21 | - eslint:recommended 22 | - plugin:prettier/recommended 23 | 24 | rules: 25 | # 0 = off, 1 = warn, 2 = error 26 | 'no-empty': 0 27 | 'space-before-function-paren': 0 28 | 'no-useless-constructor': 0 29 | 'no-undef': 2 30 | 'no-console': [2, { allow: ['error', 'warn', 'info', 'assert'] }] 31 | 'comma-dangle': ['error', 'only-multiline'] 32 | 'no-unused-vars': 0 33 | 'no-var': 2 34 | 'one-var-declaration-per-line': 2 35 | 'prefer-const': 2 36 | 'no-const-assign': 2 37 | 'no-duplicate-imports': 2 38 | 'no-use-before-define': [2, { 'functions': false, 'classes': false }] 39 | 'eqeqeq': [2, 'always', { 'null': 'ignore' }] 40 | 'no-case-declarations': 0 41 | 'no-restricted-syntax': 42 | [ 43 | 2, 44 | { 45 | 'selector': 'BinaryExpression[operator=/(==|===|!=|!==)/][left.raw=true], BinaryExpression[operator=/(==|===|!=|!==)/][right.raw=true]', 46 | 'message': Don't compare for equality against boolean literals, 47 | }, 48 | ] 49 | 50 | # https://github.com/benmosher/eslint-plugin-import/pull/334 51 | 'import/no-duplicates': 2 52 | 'import/first': 2 53 | 'import/newline-after-import': 2 54 | 'import/order': 55 | [ 56 | 2, 57 | { 58 | 'newlines-between': 'always', 59 | 'alphabetize': { 'order': 'asc' }, 60 | 'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], 61 | }, 62 | ] 63 | 64 | overrides: 65 | - files: 66 | - ./**/*{.ts,.tsx} 67 | rules: 68 | 'no-unused-vars': [2, { varsIgnorePattern: '^_', argsIgnorePattern: '^_', ignoreRestSiblings: true }] 69 | 'no-undef': 0 70 | # TypeScript declare merge 71 | 'no-redeclare': 0 72 | 'no-useless-constructor': 0 73 | 'no-dupe-class-members': 0 74 | 'no-case-declarations': 0 75 | 'no-duplicate-imports': 0 76 | # TypeScript Interface and Type 77 | 'no-use-before-define': 0 78 | 79 | '@typescript-eslint/adjacent-overload-signatures': 2 80 | '@typescript-eslint/await-thenable': 2 81 | '@typescript-eslint/consistent-type-assertions': 2 82 | '@typescript-eslint/ban-types': 83 | [ 84 | 'error', 85 | { 86 | 'types': 87 | { 88 | 'String': { 'message': 'Use string instead', 'fixWith': 'string' }, 89 | 'Number': { 'message': 'Use number instead', 'fixWith': 'number' }, 90 | 'Boolean': { 'message': 'Use boolean instead', 'fixWith': 'boolean' }, 91 | 'Function': { 'message': 'Use explicit type instead' }, 92 | }, 93 | }, 94 | ] 95 | '@typescript-eslint/explicit-member-accessibility': 96 | [ 97 | 'error', 98 | { 99 | accessibility: 'explicit', 100 | overrides: 101 | { 102 | accessors: 'no-public', 103 | constructors: 'no-public', 104 | methods: 'no-public', 105 | properties: 'no-public', 106 | parameterProperties: 'explicit', 107 | }, 108 | }, 109 | ] 110 | '@typescript-eslint/method-signature-style': 2 111 | '@typescript-eslint/no-floating-promises': 2 112 | '@typescript-eslint/no-implied-eval': 2 113 | '@typescript-eslint/no-for-in-array': 2 114 | '@typescript-eslint/no-inferrable-types': 2 115 | '@typescript-eslint/no-invalid-void-type': 2 116 | '@typescript-eslint/no-misused-new': 2 117 | '@typescript-eslint/no-misused-promises': 2 118 | '@typescript-eslint/no-namespace': 2 119 | '@typescript-eslint/no-non-null-asserted-optional-chain': 2 120 | '@typescript-eslint/no-throw-literal': 2 121 | '@typescript-eslint/no-unnecessary-boolean-literal-compare': 2 122 | '@typescript-eslint/prefer-for-of': 2 123 | '@typescript-eslint/prefer-nullish-coalescing': 2 124 | '@typescript-eslint/switch-exhaustiveness-check': 2 125 | '@typescript-eslint/prefer-optional-chain': 2 126 | '@typescript-eslint/prefer-readonly': 2 127 | '@typescript-eslint/prefer-string-starts-ends-with': 0 128 | '@typescript-eslint/no-array-constructor': 2 129 | '@typescript-eslint/require-await': 2 130 | '@typescript-eslint/return-await': 2 131 | '@typescript-eslint/ban-ts-comment': 132 | [2, { 'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': true, 'ts-check': false }] 133 | '@typescript-eslint/naming-convention': 134 | [ 135 | 2, 136 | { 137 | selector: 'memberLike', 138 | format: ['camelCase', 'PascalCase'], 139 | modifiers: ['private'], 140 | leadingUnderscore: 'forbid', 141 | }, 142 | ] 143 | '@typescript-eslint/no-unused-vars': 144 | [2, { varsIgnorePattern: '^_', argsIgnorePattern: '^_', ignoreRestSiblings: true }] 145 | '@typescript-eslint/member-ordering': 146 | [ 147 | 2, 148 | { 149 | default: 150 | [ 151 | 'public-static-field', 152 | 'protected-static-field', 153 | 'private-static-field', 154 | 'public-static-method', 155 | 'protected-static-method', 156 | 'private-static-method', 157 | 'public-instance-field', 158 | 'protected-instance-field', 159 | 'private-instance-field', 160 | 'public-constructor', 161 | 'protected-constructor', 162 | 'private-constructor', 163 | 'public-instance-method', 164 | 'protected-instance-method', 165 | 'private-instance-method', 166 | ], 167 | }, 168 | ] 169 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | 5 | *.ts text eol=lf merge=union 6 | *.tsx text eol=lf merge=union 7 | *.rs text eol=lf merge=union 8 | *.js text eol=lf merge=union 9 | *.json text eol=lf merge=union 10 | *.debug text eol=lf merge=union 11 | 12 | # Generated codes 13 | index.js linguist-detectable=false 14 | index.d.ts linguist-detectable=false -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | env: 3 | DEBUG: napi:* 4 | APP_NAME: woff2-rs 5 | MACOSX_DEPLOYMENT_TARGET: '10.13' 6 | 'on': 7 | push: 8 | branches: 9 | - main 10 | tags-ignore: 11 | - '**' 12 | paths-ignore: 13 | # - '**/*.md' 14 | - LICENSE 15 | - '**/*.gitignore' 16 | - .editorconfig 17 | - docs/** 18 | pull_request: null 19 | jobs: 20 | build: 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | settings: 25 | - host: macos-latest 26 | target: x86_64-apple-darwin 27 | build: | 28 | yarn build 29 | strip -x *.node 30 | - host: windows-latest 31 | build: yarn build 32 | target: x86_64-pc-windows-msvc 33 | - host: windows-latest 34 | build: | 35 | yarn build --target i686-pc-windows-msvc 36 | yarn test 37 | target: i686-pc-windows-msvc 38 | - host: ubuntu-latest 39 | target: x86_64-unknown-linux-gnu 40 | docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian 41 | build: |- 42 | set -e && 43 | yarn build --target x86_64-unknown-linux-gnu && 44 | strip *.node 45 | - host: ubuntu-latest 46 | target: x86_64-unknown-linux-musl 47 | docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine 48 | build: set -e && yarn build && strip *.node 49 | - host: macos-latest 50 | target: aarch64-apple-darwin 51 | build: | 52 | sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*; 53 | export CC=$(xcrun -f clang); 54 | export CXX=$(xcrun -f clang++); 55 | SYSROOT=$(xcrun --sdk macosx --show-sdk-path); 56 | export CFLAGS="-isysroot $SYSROOT -isystem $SYSROOT"; 57 | yarn build --target aarch64-apple-darwin 58 | strip -x *.node 59 | - host: ubuntu-latest 60 | target: aarch64-unknown-linux-gnu 61 | docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64 62 | build: |- 63 | set -e && 64 | yarn build --target aarch64-unknown-linux-gnu && 65 | aarch64-unknown-linux-gnu-strip *.node 66 | - host: ubuntu-latest 67 | target: armv7-unknown-linux-gnueabihf 68 | setup: | 69 | sudo apt-get update 70 | sudo apt-get install gcc-arm-linux-gnueabihf -y 71 | build: | 72 | yarn build --target armv7-unknown-linux-gnueabihf 73 | arm-linux-gnueabihf-strip *.node 74 | - host: ubuntu-latest 75 | target: aarch64-linux-android 76 | build: | 77 | yarn build --target aarch64-linux-android 78 | ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node 79 | - host: ubuntu-latest 80 | target: armv7-linux-androideabi 81 | build: | 82 | yarn build --target armv7-linux-androideabi 83 | ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node 84 | - host: ubuntu-latest 85 | target: aarch64-unknown-linux-musl 86 | docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine 87 | build: |- 88 | set -e && 89 | rustup target add aarch64-unknown-linux-musl && 90 | yarn build --target aarch64-unknown-linux-musl && 91 | /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node 92 | - host: windows-latest 93 | target: aarch64-pc-windows-msvc 94 | build: yarn build --target aarch64-pc-windows-msvc 95 | name: stable - ${{ matrix.settings.target }} - node@18 96 | runs-on: ${{ matrix.settings.host }} 97 | steps: 98 | - uses: actions/checkout@v3 99 | - name: Setup node 100 | uses: actions/setup-node@v3 101 | if: ${{ !matrix.settings.docker }} 102 | with: 103 | node-version: 18 104 | check-latest: true 105 | cache: yarn 106 | - name: Install 107 | uses: dtolnay/rust-toolchain@stable 108 | if: ${{ !matrix.settings.docker }} 109 | with: 110 | toolchain: stable 111 | targets: ${{ matrix.settings.target }} 112 | - name: Cache cargo 113 | uses: actions/cache@v3 114 | with: 115 | path: | 116 | ~/.cargo/registry/index/ 117 | ~/.cargo/registry/cache/ 118 | ~/.cargo/git/db/ 119 | .cargo-cache 120 | target/ 121 | key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} 122 | - uses: goto-bus-stop/setup-zig@v2 123 | if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' }} 124 | with: 125 | version: 0.10.1 126 | - name: Setup toolchain 127 | run: ${{ matrix.settings.setup }} 128 | if: ${{ matrix.settings.setup }} 129 | shell: bash 130 | - name: Setup node x86 131 | if: matrix.settings.target == 'i686-pc-windows-msvc' 132 | run: yarn config set supportedArchitectures.cpu "ia32" 133 | shell: bash 134 | - name: Install dependencies 135 | run: yarn install 136 | - name: Setup node x86 137 | uses: actions/setup-node@v3 138 | if: matrix.settings.target == 'i686-pc-windows-msvc' 139 | with: 140 | node-version: 18 141 | check-latest: true 142 | cache: yarn 143 | architecture: x86 144 | - name: Build in docker 145 | uses: addnab/docker-run-action@v3 146 | if: ${{ matrix.settings.docker }} 147 | with: 148 | image: ${{ matrix.settings.docker }} 149 | options: '--user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build' 150 | run: ${{ matrix.settings.build }} 151 | - name: Build 152 | run: ${{ matrix.settings.build }} 153 | if: ${{ !matrix.settings.docker }} 154 | shell: bash 155 | - name: Upload artifact 156 | uses: actions/upload-artifact@v3 157 | with: 158 | name: bindings-${{ matrix.settings.target }} 159 | path: ${{ env.APP_NAME }}.*.node 160 | if-no-files-found: error 161 | build-freebsd: 162 | runs-on: macos-12 163 | name: Build FreeBSD 164 | steps: 165 | - uses: actions/checkout@v3 166 | - name: Build 167 | id: build 168 | uses: vmactions/freebsd-vm@v0 169 | env: 170 | DEBUG: napi:* 171 | RUSTUP_HOME: /usr/local/rustup 172 | CARGO_HOME: /usr/local/cargo 173 | RUSTUP_IO_THREADS: 1 174 | with: 175 | envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS 176 | usesh: true 177 | mem: 3000 178 | prepare: | 179 | pkg install -y -f curl node libnghttp2 180 | curl -qL https://www.npmjs.com/install.sh | sh 181 | npm install --location=global --ignore-scripts yarn 182 | curl https://sh.rustup.rs -sSf --output rustup.sh 183 | sh rustup.sh -y --profile minimal --default-toolchain beta 184 | export PATH="/usr/local/cargo/bin:$PATH" 185 | echo "~~~~ rustc --version ~~~~" 186 | rustc --version 187 | echo "~~~~ node -v ~~~~" 188 | node -v 189 | echo "~~~~ yarn --version ~~~~" 190 | yarn --version 191 | run: | 192 | export PATH="/usr/local/cargo/bin:$PATH" 193 | pwd 194 | ls -lah 195 | whoami 196 | env 197 | freebsd-version 198 | yarn install 199 | yarn build 200 | strip -x *.node 201 | yarn test 202 | rm -rf node_modules 203 | rm -rf target 204 | rm -rf .yarn/cache 205 | - name: Upload artifact 206 | uses: actions/upload-artifact@v3 207 | with: 208 | name: bindings-freebsd 209 | path: ${{ env.APP_NAME }}.*.node 210 | if-no-files-found: error 211 | test-macOS-windows-binding: 212 | name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} 213 | needs: 214 | - build 215 | strategy: 216 | fail-fast: false 217 | matrix: 218 | settings: 219 | - host: windows-latest 220 | target: x86_64-pc-windows-msvc 221 | node: 222 | - '14' 223 | - '16' 224 | - '18' 225 | runs-on: ${{ matrix.settings.host }} 226 | steps: 227 | - uses: actions/checkout@v3 228 | - name: Setup node 229 | uses: actions/setup-node@v3 230 | with: 231 | node-version: ${{ matrix.node }} 232 | check-latest: true 233 | cache: yarn 234 | - name: Install dependencies 235 | run: yarn install 236 | - name: Download artifacts 237 | uses: actions/download-artifact@v3 238 | with: 239 | name: bindings-${{ matrix.settings.target }} 240 | path: . 241 | - name: List packages 242 | run: ls -R . 243 | shell: bash 244 | - name: Test bindings 245 | run: yarn test 246 | test-linux-x64-gnu-binding: 247 | name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }} 248 | needs: 249 | - build 250 | strategy: 251 | fail-fast: false 252 | matrix: 253 | node: 254 | - '14' 255 | - '16' 256 | - '18' 257 | runs-on: ubuntu-latest 258 | steps: 259 | - uses: actions/checkout@v3 260 | - name: Setup node 261 | uses: actions/setup-node@v3 262 | with: 263 | node-version: ${{ matrix.node }} 264 | check-latest: true 265 | cache: yarn 266 | - name: Install dependencies 267 | run: yarn install 268 | - name: Download artifacts 269 | uses: actions/download-artifact@v3 270 | with: 271 | name: bindings-x86_64-unknown-linux-gnu 272 | path: . 273 | - name: List packages 274 | run: ls -R . 275 | shell: bash 276 | - name: Test bindings 277 | run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-slim yarn test 278 | test-linux-x64-musl-binding: 279 | name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }} 280 | needs: 281 | - build 282 | strategy: 283 | fail-fast: false 284 | matrix: 285 | node: 286 | - '14' 287 | - '16' 288 | - '18' 289 | runs-on: ubuntu-latest 290 | steps: 291 | - uses: actions/checkout@v3 292 | - name: Setup node 293 | uses: actions/setup-node@v3 294 | with: 295 | node-version: ${{ matrix.node }} 296 | check-latest: true 297 | cache: yarn 298 | - name: Install dependencies 299 | run: | 300 | yarn config set supportedArchitectures.libc "musl" 301 | yarn install 302 | - name: Download artifacts 303 | uses: actions/download-artifact@v3 304 | with: 305 | name: bindings-x86_64-unknown-linux-musl 306 | path: . 307 | - name: List packages 308 | run: ls -R . 309 | shell: bash 310 | - name: Test bindings 311 | run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-alpine yarn test 312 | test-linux-aarch64-gnu-binding: 313 | name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }} 314 | needs: 315 | - build 316 | strategy: 317 | fail-fast: false 318 | matrix: 319 | node: 320 | - '14' 321 | - '16' 322 | - '18' 323 | runs-on: ubuntu-latest 324 | steps: 325 | - uses: actions/checkout@v3 326 | - name: Download artifacts 327 | uses: actions/download-artifact@v3 328 | with: 329 | name: bindings-aarch64-unknown-linux-gnu 330 | path: . 331 | - name: List packages 332 | run: ls -R . 333 | shell: bash 334 | - name: Install dependencies 335 | run: | 336 | yarn config set supportedArchitectures.cpu "arm64" 337 | yarn config set supportedArchitectures.libc "glibc" 338 | yarn install 339 | - name: Set up QEMU 340 | uses: docker/setup-qemu-action@v2 341 | with: 342 | platforms: arm64 343 | - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 344 | - name: Setup and run tests 345 | uses: addnab/docker-run-action@v3 346 | with: 347 | image: node:${{ matrix.node }}-slim 348 | options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build' 349 | run: | 350 | set -e 351 | yarn test 352 | ls -la 353 | test-linux-aarch64-musl-binding: 354 | name: Test bindings on aarch64-unknown-linux-musl - node@${{ matrix.node }} 355 | needs: 356 | - build 357 | runs-on: ubuntu-latest 358 | steps: 359 | - uses: actions/checkout@v3 360 | - name: Download artifacts 361 | uses: actions/download-artifact@v3 362 | with: 363 | name: bindings-aarch64-unknown-linux-musl 364 | path: . 365 | - name: List packages 366 | run: ls -R . 367 | shell: bash 368 | - name: Install dependencies 369 | run: | 370 | yarn config set supportedArchitectures.cpu "arm64" 371 | yarn config set supportedArchitectures.libc "musl" 372 | yarn install 373 | - name: Set up QEMU 374 | uses: docker/setup-qemu-action@v2 375 | with: 376 | platforms: arm64 377 | - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 378 | - name: Setup and run tests 379 | uses: addnab/docker-run-action@v3 380 | with: 381 | image: node:lts-alpine 382 | options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build' 383 | run: | 384 | set -e 385 | yarn test 386 | test-linux-arm-gnueabihf-binding: 387 | name: Test bindings on armv7-unknown-linux-gnueabihf - node@${{ matrix.node }} 388 | needs: 389 | - build 390 | strategy: 391 | fail-fast: false 392 | matrix: 393 | node: 394 | - '14' 395 | - '16' 396 | - '18' 397 | runs-on: ubuntu-latest 398 | steps: 399 | - uses: actions/checkout@v3 400 | - name: Download artifacts 401 | uses: actions/download-artifact@v3 402 | with: 403 | name: bindings-armv7-unknown-linux-gnueabihf 404 | path: . 405 | - name: List packages 406 | run: ls -R . 407 | shell: bash 408 | - name: Install dependencies 409 | run: | 410 | yarn config set supportedArchitectures.cpu "arm" 411 | yarn install 412 | - name: Set up QEMU 413 | uses: docker/setup-qemu-action@v2 414 | with: 415 | platforms: arm 416 | - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 417 | - name: Setup and run tests 418 | uses: addnab/docker-run-action@v3 419 | with: 420 | image: node:${{ matrix.node }}-bullseye-slim 421 | options: '--platform linux/arm/v7 -v ${{ github.workspace }}:/build -w /build' 422 | run: | 423 | set -e 424 | yarn test 425 | ls -la 426 | publish: 427 | name: Publish 428 | runs-on: ubuntu-latest 429 | needs: 430 | - build-freebsd 431 | - test-macOS-windows-binding 432 | - test-linux-x64-gnu-binding 433 | - test-linux-x64-musl-binding 434 | - test-linux-aarch64-gnu-binding 435 | - test-linux-aarch64-musl-binding 436 | - test-linux-arm-gnueabihf-binding 437 | steps: 438 | - uses: actions/checkout@v3 439 | - name: Setup node 440 | uses: actions/setup-node@v3 441 | with: 442 | node-version: 18 443 | check-latest: true 444 | cache: yarn 445 | - name: Install dependencies 446 | run: yarn install 447 | - name: Download all artifacts 448 | uses: actions/download-artifact@v3 449 | with: 450 | path: artifacts 451 | - name: Move artifacts 452 | run: yarn artifacts 453 | - name: List packages 454 | run: ls -R ./npm 455 | shell: bash 456 | - name: Publish 457 | run: | 458 | if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$"; 459 | then 460 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc 461 | npm publish --access public 462 | elif git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+"; 463 | then 464 | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc 465 | npm publish --tag next --access public 466 | else 467 | echo "Not a release, skipping publish" 468 | fi 469 | env: 470 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 471 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 472 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags-ignore: 8 | - '**' 9 | pull_request: 10 | 11 | jobs: 12 | lint: 13 | name: Lint 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | 18 | - name: Setup node 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: 16 22 | cache: 'yarn' 23 | check-latest: true 24 | 25 | - name: Install 26 | uses: dtolnay/rust-toolchain@stable 27 | with: 28 | components: clippy, rustfmt 29 | 30 | - name: Cache NPM dependencies 31 | uses: actions/cache@v3 32 | with: 33 | path: node_modules 34 | key: npm-cache-lint-node@16 35 | 36 | - name: Install dependencies 37 | run: yarn install --immutable --network-timeout 300000 38 | 39 | - name: ESLint 40 | run: yarn lint 41 | 42 | - name: Cargo fmt 43 | run: cargo fmt -- --check 44 | 45 | - name: Clippy 46 | run: cargo clippy 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variables file 76 | .env 77 | .env.test 78 | 79 | # parcel-bundler cache (https://parceljs.org/) 80 | .cache 81 | 82 | # Next.js build output 83 | .next 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and not Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Stores VSCode versions used for testing VSCode extensions 111 | .vscode-test 112 | 113 | # End of https://www.toptal.com/developers/gitignore/api/node 114 | 115 | # Created by https://www.toptal.com/developers/gitignore/api/macos 116 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos 117 | 118 | ### macOS ### 119 | # General 120 | .DS_Store 121 | .AppleDouble 122 | .LSOverride 123 | 124 | # Icon must end with two 125 | Icon 126 | 127 | 128 | # Thumbnails 129 | ._* 130 | 131 | # Files that might appear in the root of a volume 132 | .DocumentRevisions-V100 133 | .fseventsd 134 | .Spotlight-V100 135 | .TemporaryItems 136 | .Trashes 137 | .VolumeIcon.icns 138 | .com.apple.timemachine.donotpresent 139 | 140 | # Directories potentially created on remote AFP share 141 | .AppleDB 142 | .AppleDesktop 143 | Network Trash Folder 144 | Temporary Items 145 | .apdisk 146 | 147 | ### macOS Patch ### 148 | # iCloud generated files 149 | *.icloud 150 | 151 | # End of https://www.toptal.com/developers/gitignore/api/macos 152 | 153 | # Created by https://www.toptal.com/developers/gitignore/api/windows 154 | # Edit at https://www.toptal.com/developers/gitignore?templates=windows 155 | 156 | ### Windows ### 157 | # Windows thumbnail cache files 158 | Thumbs.db 159 | Thumbs.db:encryptable 160 | ehthumbs.db 161 | ehthumbs_vista.db 162 | 163 | # Dump file 164 | *.stackdump 165 | 166 | # Folder config file 167 | [Dd]esktop.ini 168 | 169 | # Recycle Bin used on file shares 170 | $RECYCLE.BIN/ 171 | 172 | # Windows Installer files 173 | *.cab 174 | *.msi 175 | *.msix 176 | *.msm 177 | *.msp 178 | 179 | # Windows shortcuts 180 | *.lnk 181 | 182 | # End of https://www.toptal.com/developers/gitignore/api/windows 183 | 184 | #Added by cargo 185 | 186 | /target 187 | Cargo.lock 188 | 189 | .pnp.* 190 | .yarn/* 191 | !.yarn/patches 192 | !.yarn/plugins 193 | !.yarn/releases 194 | !.yarn/sdks 195 | !.yarn/versions 196 | 197 | *.node 198 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | target 2 | .yarn -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | npmAuditRegistry: "https://registry.npmjs.org" 4 | 5 | yarnPath: .yarn/releases/yarn-3.4.1.cjs 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | This changelog also contains important changes in dependencies. 9 | 10 | ## [Unreleased] 11 | 12 | ## [1.0.1] - 2023-05-10 13 | 14 | fix: missing `@woff2/` prefix in the package name in require 15 | 16 | ## [1.0.0] - 2023-02-05 17 | 18 | The first official version. 19 | 20 | - Support converts WOFF2 to TTF or OTF. 21 | 22 | [unreleased]: https://github.com/yisibl/resvg-js/compare/v1.0.1...HEAD 23 | [1.0.1]: https://github.com/yisibl/resvg-js/releases/tag/v1.0.1 24 | [1.0.0]: https://github.com/yisibl/resvg-js/releases/tag/v1.0.0 25 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["yisibl "] 3 | edition = "2021" 4 | name = "woff2-rs" 5 | version = "1.0.0" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [lib] 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | napi = "2" 14 | napi-derive = "2" 15 | woff2 = "0.3.0" 16 | 17 | [build-dependencies] 18 | napi-build = "2" 19 | 20 | [profile.release] 21 | lto = true # Enable Link Time Optimization 22 | # opt-level = 3 23 | # Setting this to 1 may improve the performance of generated code, but may be slower to compile. 24 | # https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units 25 | codegen-units = 1 26 | 27 | [patch.crates-io] 28 | woff2 = { git = "https://github.com/yisibl/woff2-rs", branch = "fix-total-compressed-size" } 29 | # woff2 = { git = "https://github.com/yisibl/woff2-rs", rev = "65c0a0f0" } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 N-API for Rust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node `woff2-rs` 2 | 3 | GitHub CI Status 4 | @woff2/woff2-rs npm version 5 | @woff2/woff2-rs npm downloads 6 | 7 | A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based [woff2-rs](https://github.com/Cimpress-MCP/woff2-rs) and [napi-rs](https://github.com/napi-rs/napi-rs). 8 | 9 | ## Features 10 | 11 | - Converts WOFF2 to TTF or OTF. 12 | - Quick to install, no need for node-gyp and postinstall. 13 | - Cross-platform support, including [Apple M Chips](https://www.apple.com/newsroom/2020/11/apple-unleashes-m1/). 14 | - Support for running as native addons in Deno. 15 | 16 | ## Installation 17 | 18 | ``` 19 | npm i @woff2/woff2-rs 20 | yarn add @woff2/woff2-rs 21 | ``` 22 | 23 | ## Usage 24 | 25 | ```js 26 | import { promises as fs } from 'fs' 27 | import path, { join } from 'path' 28 | import { fileURLToPath } from 'url' 29 | import woff2Rs from '@woff2/woff2-rs' 30 | 31 | const __filename = fileURLToPath(import.meta.url) 32 | const __dirname = path.resolve(path.dirname(__filename)) 33 | async function toTTF() { 34 | const font = await fs.readFile(join(__dirname, '../__test__/fa-regular-400-v5.15.4.woff2')) 35 | const outputBuffer = woff2Rs.decode(font) // output TTF buffer 36 | await fs.writeFile(join(__dirname, 'fa-regular-400.ttf'), outputBuffer) 37 | } 38 | toTTF() 39 | ``` 40 | 41 | ## Benchmark 42 | 43 | ```bash 44 | npm run bench 45 | 46 | Running "WOFF2 to TTF (Use Font Awesome)" suite... 47 | Progress: 50% 48 | Progress: 100% 49 | 50 | woff2-next(node-gyp binding): 51 | 2 990 ops/s, ±0.30% | fastest 52 | 53 | @napi-rs/ttf2woff2(Rust binding): 54 | 2 396 ops/s, ±0.66% | 19.87% slower 55 | 56 | @woff2/woff2-rs(Pure Rust): 57 | 1 934 ops/s, ±0.30% | 35.32% slower 58 | 59 | wawoff(Wasm): 60 | 1 501 ops/s, ±0.75% | slowest, 49.8% slower 61 | ``` 62 | 63 | ## Support matrix 64 | 65 | | | Node.js 12 | Node.js 14 | Node.js 16 | Node.js 18 | npm | 66 | | ---------------- | ---------- | ---------- | ---------- | ---------- | --- | 67 | | Windows x64 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-win32-x64-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-win32-x64-msvc) | 68 | | Windows x32 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-win32-ia32-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-win32-ia32-msvc) | 69 | | Windows arm64 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-win32-arm64-msvc.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-win32-arm64-msvc) | 70 | | macOS x64 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-darwin-x64.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-darwin-x64) | 71 | | macOS arm64(M1) | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-darwin-arm64.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-darwin-arm64) | 72 | | Linux x64 gnu | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-linux-x64-gnu.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-linux-x64-gnu) | 73 | | Linux x64 musl | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-linux-x64-musl.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-linux-x64-musl) | 74 | | Linux arm gnu | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-linux-arm-gnueabihf.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-linux-arm-gnueabihf) | 75 | | Linux arm64 gnu | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-linux-arm64-gnu.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-linux-arm64-gnu) | 76 | | Linux arm64 musl | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-linux-arm64-musl.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-linux-arm64-musl) | 77 | | Android arm64 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-android-arm64.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-android-arm64) | 78 | | Android armv7 | ✓ | ✓ | ✓ | ✓ |[![npm version](https://img.shields.io/npm/v/@woff2/woff2-rs-android-arm-eabi.svg?sanitize=true)](https://www.npmjs.com/package/@woff2/woff2-rs-android-arm-eabi) | 79 | 80 | ### Build 81 | 82 | After `yarn build/npm run build` command, you can see `package-template.[darwin|win32|linux].node` file in project root. This is the native addon built from [lib.rs](./src/lib.rs). 83 | 84 | ### Test 85 | 86 | With [ava](https://github.com/avajs/ava), run `yarn test/npm run test` to testing native addon. You can also switch to another testing framework if you want. 87 | 88 | ## Develop requirements 89 | 90 | - Install the latest `Rust` 91 | - Install `Node.js@10+` which fully supported `Node-API` 92 | - Install `yarn@1.x` 93 | 94 | ## Test in local 95 | 96 | - yarn 97 | - yarn build 98 | - yarn test 99 | 100 | ## Release package 101 | 102 | Ensure you have set your **NPM_TOKEN** in the `GitHub` project setting. 103 | 104 | In `Settings -> Secrets`, add **NPM_TOKEN** into it. 105 | 106 | When you want to release the package: 107 | 108 | `npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=] | from-git]` 109 | 110 | ``` 111 | # 1.0.0 => 1.0.1 112 | npm version patch 113 | 114 | # or 1.0.0 => 1.1.0 115 | npm version minor 116 | 117 | git push 118 | ``` 119 | -------------------------------------------------------------------------------- /__test__/fa-brands-400-v6.2.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yisibl/node-woff2-rs/ed4b46358b02e6ac9a2852c025ba8149f4e6c1e0/__test__/fa-brands-400-v6.2.woff2 -------------------------------------------------------------------------------- /__test__/fa-regular-400-v5.15.4.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yisibl/node-woff2-rs/ed4b46358b02e6ac9a2852c025ba8149f4e6c1e0/__test__/fa-regular-400-v5.15.4.woff2 -------------------------------------------------------------------------------- /__test__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from 'fs/promises' 2 | import { join } from 'path' 3 | 4 | import * as fontkit from '@yisibl/fontkit' 5 | import test from 'ava' 6 | 7 | import { decode } from '../index' 8 | 9 | test('should be converting WOFF2 to TTF', async (t) => { 10 | const font = await readFile(join(__dirname, './fa-brands-400-v6.2.woff2')) 11 | const output = decode(font) 12 | const fontkitOut = fontkit.openSync(output) 13 | 14 | t.is(fontkitOut.type, 'TTF') // font type 15 | }) 16 | 17 | test('should be a TTF font converted by fontkit check', async (t) => { 18 | const font = await readFile(join(__dirname, './fa-regular-400-v5.15.4.woff2')) 19 | const output = decode(font) 20 | const fontkitOut = fontkit.openSync(output) 21 | 22 | t.is(fontkitOut.type, 'TTF') 23 | t.is(fontkitOut.directory.numTables, 13) // table count 24 | t.is(fontkitOut.directory.tables.glyf.length, 28076) // glyf table size 25 | t.is(fontkitOut.directory.tables.loca.length, 310) // glyf table size 26 | }) 27 | -------------------------------------------------------------------------------- /benchmark/bench.mjs: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs' 2 | import path, { join } from 'path' 3 | import { fileURLToPath } from 'url' 4 | 5 | import { convertWOFF2ToTTF } from '@napi-rs/ttf2woff2' 6 | import b from 'benny' 7 | import wawoff from 'wawoff2' 8 | import woff2Next from 'woff2-next' 9 | 10 | import woff2Rs from '../index.js' 11 | 12 | const __filename = fileURLToPath(import.meta.url) 13 | const __dirname = path.resolve(path.dirname(__filename)) 14 | 15 | async function run() { 16 | // const font1 = await fs.readFile(join(__dirname, '../__test__/fa-brands-400-v6.2.woff2')) 17 | const font1 = await fs.readFile(join(__dirname, '../__test__/fa-regular-400-v5.15.4.woff2')) 18 | 19 | await b.suite( 20 | 'WOFF2 to TTF (Use Font Awesome)', 21 | 22 | b.add('woff2-next(node-gyp binding)', () => { 23 | woff2Next.decode(font1) 24 | }), 25 | 26 | b.add('@napi-rs/ttf2woff2(Rust binding)', () => { 27 | convertWOFF2ToTTF(font1) 28 | }), 29 | 30 | b.add('@woff2/woff2-rs(Pure Rust)', () => { 31 | woff2Rs.decode(font1) 32 | }), 33 | 34 | b.add('wawoff(Wasm)', async () => { 35 | await wawoff.decompress(font1) 36 | }), 37 | 38 | b.cycle(), 39 | b.complete(), 40 | ) 41 | } 42 | 43 | run().catch((e) => { 44 | console.error(e) 45 | }) 46 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | extern crate napi_build; 2 | 3 | fn main() { 4 | napi_build::setup(); 5 | } 6 | -------------------------------------------------------------------------------- /example/index.mjs: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs' 2 | import path, { join } from 'path' 3 | import { fileURLToPath } from 'url' 4 | 5 | import woff2Rs from '../index.js' 6 | 7 | const __filename = fileURLToPath(import.meta.url) 8 | const __dirname = path.resolve(path.dirname(__filename)) 9 | async function toTTF() { 10 | const font = await fs.readFile(join(__dirname, '../__test__/fa-regular-400-v5.15.4.woff2')) 11 | const outputBuffer = woff2Rs.decode(font) // output TTF buffer 12 | 13 | await fs.writeFile(join(__dirname, 'fa-regular-400.ttf'), outputBuffer) 14 | } 15 | toTTF() 16 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | 4 | /* auto-generated by NAPI-RS */ 5 | 6 | export function decode(input: Buffer): Buffer 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { existsSync, readFileSync } = require('fs') 2 | const { join } = require('path') 3 | 4 | const { platform, arch } = process 5 | 6 | let nativeBinding = null 7 | let localFileExisted = false 8 | let loadError = null 9 | 10 | function isMusl() { 11 | // For Node 10 12 | if (!process.report || typeof process.report.getReport !== 'function') { 13 | try { 14 | const lddPath = require('child_process').execSync('which ldd').toString().trim() 15 | return readFileSync(lddPath, 'utf8').includes('musl') 16 | } catch (e) { 17 | return true 18 | } 19 | } else { 20 | const { glibcVersionRuntime } = process.report.getReport().header 21 | return !glibcVersionRuntime 22 | } 23 | } 24 | 25 | switch (platform) { 26 | case 'android': 27 | switch (arch) { 28 | case 'arm64': 29 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.android-arm64.node')) 30 | try { 31 | if (localFileExisted) { 32 | nativeBinding = require('./woff2-rs.android-arm64.node') 33 | } else { 34 | nativeBinding = require('@woff2/woff2-rs-android-arm64') 35 | } 36 | } catch (e) { 37 | loadError = e 38 | } 39 | break 40 | case 'arm': 41 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.android-arm-eabi.node')) 42 | try { 43 | if (localFileExisted) { 44 | nativeBinding = require('./woff2-rs.android-arm-eabi.node') 45 | } else { 46 | nativeBinding = require('@woff2/woff2-rs-android-arm-eabi') 47 | } 48 | } catch (e) { 49 | loadError = e 50 | } 51 | break 52 | default: 53 | throw new Error(`Unsupported architecture on Android ${arch}`) 54 | } 55 | break 56 | case 'win32': 57 | switch (arch) { 58 | case 'x64': 59 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.win32-x64-msvc.node')) 60 | try { 61 | if (localFileExisted) { 62 | nativeBinding = require('./woff2-rs.win32-x64-msvc.node') 63 | } else { 64 | nativeBinding = require('@woff2/woff2-rs-win32-x64-msvc') 65 | } 66 | } catch (e) { 67 | loadError = e 68 | } 69 | break 70 | case 'ia32': 71 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.win32-ia32-msvc.node')) 72 | try { 73 | if (localFileExisted) { 74 | nativeBinding = require('./woff2-rs.win32-ia32-msvc.node') 75 | } else { 76 | nativeBinding = require('@woff2/woff2-rs-win32-ia32-msvc') 77 | } 78 | } catch (e) { 79 | loadError = e 80 | } 81 | break 82 | case 'arm64': 83 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.win32-arm64-msvc.node')) 84 | try { 85 | if (localFileExisted) { 86 | nativeBinding = require('./woff2-rs.win32-arm64-msvc.node') 87 | } else { 88 | nativeBinding = require('@woff2/woff2-rs-win32-arm64-msvc') 89 | } 90 | } catch (e) { 91 | loadError = e 92 | } 93 | break 94 | default: 95 | throw new Error(`Unsupported architecture on Windows: ${arch}`) 96 | } 97 | break 98 | case 'darwin': 99 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.darwin-universal.node')) 100 | try { 101 | if (localFileExisted) { 102 | nativeBinding = require('./woff2-rs.darwin-universal.node') 103 | } else { 104 | nativeBinding = require('@woff2/woff2-rs-darwin-universal') 105 | } 106 | break 107 | } catch {} 108 | switch (arch) { 109 | case 'x64': 110 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.darwin-x64.node')) 111 | try { 112 | if (localFileExisted) { 113 | nativeBinding = require('./woff2-rs.darwin-x64.node') 114 | } else { 115 | nativeBinding = require('@woff2/woff2-rs-darwin-x64') 116 | } 117 | } catch (e) { 118 | loadError = e 119 | } 120 | break 121 | case 'arm64': 122 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.darwin-arm64.node')) 123 | try { 124 | if (localFileExisted) { 125 | nativeBinding = require('./woff2-rs.darwin-arm64.node') 126 | } else { 127 | nativeBinding = require('@woff2/woff2-rs-darwin-arm64') 128 | } 129 | } catch (e) { 130 | loadError = e 131 | } 132 | break 133 | default: 134 | throw new Error(`Unsupported architecture on macOS: ${arch}`) 135 | } 136 | break 137 | case 'freebsd': 138 | if (arch !== 'x64') { 139 | throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) 140 | } 141 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.freebsd-x64.node')) 142 | try { 143 | if (localFileExisted) { 144 | nativeBinding = require('./woff2-rs.freebsd-x64.node') 145 | } else { 146 | nativeBinding = require('@woff2/woff2-rs-freebsd-x64') 147 | } 148 | } catch (e) { 149 | loadError = e 150 | } 151 | break 152 | case 'linux': 153 | switch (arch) { 154 | case 'x64': 155 | if (isMusl()) { 156 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.linux-x64-musl.node')) 157 | try { 158 | if (localFileExisted) { 159 | nativeBinding = require('./woff2-rs.linux-x64-musl.node') 160 | } else { 161 | nativeBinding = require('@woff2/woff2-rs-linux-x64-musl') 162 | } 163 | } catch (e) { 164 | loadError = e 165 | } 166 | } else { 167 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.linux-x64-gnu.node')) 168 | try { 169 | if (localFileExisted) { 170 | nativeBinding = require('./woff2-rs.linux-x64-gnu.node') 171 | } else { 172 | nativeBinding = require('@woff2/woff2-rs-linux-x64-gnu') 173 | } 174 | } catch (e) { 175 | loadError = e 176 | } 177 | } 178 | break 179 | case 'arm64': 180 | if (isMusl()) { 181 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.linux-arm64-musl.node')) 182 | try { 183 | if (localFileExisted) { 184 | nativeBinding = require('./woff2-rs.linux-arm64-musl.node') 185 | } else { 186 | nativeBinding = require('@woff2/woff2-rs-linux-arm64-musl') 187 | } 188 | } catch (e) { 189 | loadError = e 190 | } 191 | } else { 192 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.linux-arm64-gnu.node')) 193 | try { 194 | if (localFileExisted) { 195 | nativeBinding = require('./woff2-rs.linux-arm64-gnu.node') 196 | } else { 197 | nativeBinding = require('@woff2/woff2-rs-linux-arm64-gnu') 198 | } 199 | } catch (e) { 200 | loadError = e 201 | } 202 | } 203 | break 204 | case 'arm': 205 | localFileExisted = existsSync(join(__dirname, 'woff2-rs.linux-arm-gnueabihf.node')) 206 | try { 207 | if (localFileExisted) { 208 | nativeBinding = require('./woff2-rs.linux-arm-gnueabihf.node') 209 | } else { 210 | nativeBinding = require('@woff2/woff2-rs-linux-arm-gnueabihf') 211 | } 212 | } catch (e) { 213 | loadError = e 214 | } 215 | break 216 | default: 217 | throw new Error(`Unsupported architecture on Linux: ${arch}`) 218 | } 219 | break 220 | default: 221 | throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) 222 | } 223 | 224 | if (!nativeBinding) { 225 | if (loadError) { 226 | throw loadError 227 | } 228 | throw new Error(`Failed to load native binding`) 229 | } 230 | 231 | const { decode } = nativeBinding 232 | 233 | module.exports.decode = decode 234 | -------------------------------------------------------------------------------- /npm/android-arm-eabi/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-android-arm-eabi` 2 | 3 | This is the **armv7-linux-androideabi** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/android-arm-eabi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-android-arm-eabi", 3 | "version": "1.0.1", 4 | "os": [ 5 | "android" 6 | ], 7 | "cpu": [ 8 | "arm" 9 | ], 10 | "main": "woff2-rs.android-arm-eabi.node", 11 | "files": [ 12 | "woff2-rs.android-arm-eabi.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/android-arm64/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-android-arm64` 2 | 3 | This is the **aarch64-linux-android** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/android-arm64/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-android-arm64", 3 | "version": "1.0.1", 4 | "os": [ 5 | "android" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "woff2-rs.android-arm64.node", 11 | "files": [ 12 | "woff2-rs.android-arm64.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/darwin-arm64/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-darwin-arm64` 2 | 3 | This is the **aarch64-apple-darwin** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/darwin-arm64/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-darwin-arm64", 3 | "version": "1.0.1", 4 | "os": [ 5 | "darwin" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "woff2-rs.darwin-arm64.node", 11 | "files": [ 12 | "woff2-rs.darwin-arm64.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/darwin-x64/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-darwin-x64` 2 | 3 | This is the **x86_64-apple-darwin** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/darwin-x64/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-darwin-x64", 3 | "version": "1.0.1", 4 | "os": [ 5 | "darwin" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "woff2-rs.darwin-x64.node", 11 | "files": [ 12 | "woff2-rs.darwin-x64.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/freebsd-x64/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-freebsd-x64` 2 | 3 | This is the **x86_64-unknown-freebsd** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/freebsd-x64/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-freebsd-x64", 3 | "version": "1.0.1", 4 | "os": [ 5 | "freebsd" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "woff2-rs.freebsd-x64.node", 11 | "files": [ 12 | "woff2-rs.freebsd-x64.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/linux-arm-gnueabihf/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-linux-arm-gnueabihf` 2 | 3 | This is the **armv7-unknown-linux-gnueabihf** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/linux-arm-gnueabihf/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-linux-arm-gnueabihf", 3 | "version": "1.0.1", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "arm" 9 | ], 10 | "main": "woff2-rs.linux-arm-gnueabihf.node", 11 | "files": [ 12 | "woff2-rs.linux-arm-gnueabihf.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/linux-arm64-gnu/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-linux-arm64-gnu` 2 | 3 | This is the **aarch64-unknown-linux-gnu** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/linux-arm64-gnu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-linux-arm64-gnu", 3 | "version": "1.0.1", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "woff2-rs.linux-arm64-gnu.node", 11 | "files": [ 12 | "woff2-rs.linux-arm64-gnu.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git", 36 | "libc": [ 37 | "glibc" 38 | ] 39 | } -------------------------------------------------------------------------------- /npm/linux-arm64-musl/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-linux-arm64-musl` 2 | 3 | This is the **aarch64-unknown-linux-musl** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/linux-arm64-musl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-linux-arm64-musl", 3 | "version": "1.0.1", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "woff2-rs.linux-arm64-musl.node", 11 | "files": [ 12 | "woff2-rs.linux-arm64-musl.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git", 36 | "libc": [ 37 | "musl" 38 | ] 39 | } -------------------------------------------------------------------------------- /npm/linux-x64-gnu/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-linux-x64-gnu` 2 | 3 | This is the **x86_64-unknown-linux-gnu** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/linux-x64-gnu/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-linux-x64-gnu", 3 | "version": "1.0.1", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "woff2-rs.linux-x64-gnu.node", 11 | "files": [ 12 | "woff2-rs.linux-x64-gnu.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git", 36 | "libc": [ 37 | "glibc" 38 | ] 39 | } -------------------------------------------------------------------------------- /npm/linux-x64-musl/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-linux-x64-musl` 2 | 3 | This is the **x86_64-unknown-linux-musl** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/linux-x64-musl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-linux-x64-musl", 3 | "version": "1.0.1", 4 | "os": [ 5 | "linux" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "woff2-rs.linux-x64-musl.node", 11 | "files": [ 12 | "woff2-rs.linux-x64-musl.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git", 36 | "libc": [ 37 | "musl" 38 | ] 39 | } -------------------------------------------------------------------------------- /npm/win32-arm64-msvc/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-win32-arm64-msvc` 2 | 3 | This is the **aarch64-pc-windows-msvc** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/win32-arm64-msvc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-win32-arm64-msvc", 3 | "version": "1.0.1", 4 | "os": [ 5 | "win32" 6 | ], 7 | "cpu": [ 8 | "arm64" 9 | ], 10 | "main": "woff2-rs.win32-arm64-msvc.node", 11 | "files": [ 12 | "woff2-rs.win32-arm64-msvc.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/win32-ia32-msvc/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-win32-ia32-msvc` 2 | 3 | This is the **i686-pc-windows-msvc** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/win32-ia32-msvc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-win32-ia32-msvc", 3 | "version": "1.0.1", 4 | "os": [ 5 | "win32" 6 | ], 7 | "cpu": [ 8 | "ia32" 9 | ], 10 | "main": "woff2-rs.win32-ia32-msvc.node", 11 | "files": [ 12 | "woff2-rs.win32-ia32-msvc.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /npm/win32-x64-msvc/README.md: -------------------------------------------------------------------------------- 1 | # `@woff2/woff2-rs-win32-x64-msvc` 2 | 3 | This is the **x86_64-pc-windows-msvc** binary for `@woff2/woff2-rs` 4 | -------------------------------------------------------------------------------- /npm/win32-x64-msvc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs-win32-x64-msvc", 3 | "version": "1.0.1", 4 | "os": [ 5 | "win32" 6 | ], 7 | "cpu": [ 8 | "x64" 9 | ], 10 | "main": "woff2-rs.win32-x64-msvc.node", 11 | "files": [ 12 | "woff2-rs.win32-x64-msvc.node" 13 | ], 14 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 15 | "keywords": [ 16 | "woff2", 17 | "woff", 18 | "ttf2woff2", 19 | "woff2 to ttf", 20 | "woff2 converter", 21 | "converter", 22 | "ttf", 23 | "font", 24 | "fonts", 25 | "rust" 26 | ], 27 | "license": "MIT", 28 | "engines": { 29 | "node": ">= 10" 30 | }, 31 | "publishConfig": { 32 | "registry": "https://registry.npmjs.org/", 33 | "access": "public" 34 | }, 35 | "repository": "git@github.com:yisibl/node-woff2-rs.git" 36 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@woff2/woff2-rs", 3 | "version": "1.0.1", 4 | "description": "A WOFF2 decompressor converts WOFF2 to TTF or OTF, powered by Rust based woff2-rs and napi-rs.", 5 | "main": "index.js", 6 | "repository": "git@github.com:yisibl/node-woff2-rs.git", 7 | "license": "MIT", 8 | "keywords": [ 9 | "woff2", 10 | "woff", 11 | "ttf2woff2", 12 | "woff2 to ttf", 13 | "woff2 converter", 14 | "converter", 15 | "ttf", 16 | "font", 17 | "fonts", 18 | "rust" 19 | ], 20 | "files": [ 21 | "index.d.ts", 22 | "index.js" 23 | ], 24 | "napi": { 25 | "name": "woff2-rs", 26 | "triples": { 27 | "defaults": true, 28 | "additional": [ 29 | "x86_64-unknown-linux-musl", 30 | "aarch64-unknown-linux-gnu", 31 | "i686-pc-windows-msvc", 32 | "armv7-unknown-linux-gnueabihf", 33 | "aarch64-apple-darwin", 34 | "aarch64-linux-android", 35 | "x86_64-unknown-freebsd", 36 | "aarch64-unknown-linux-musl", 37 | "aarch64-pc-windows-msvc", 38 | "armv7-linux-androideabi" 39 | ] 40 | } 41 | }, 42 | "engines": { 43 | "node": ">= 10" 44 | }, 45 | "publishConfig": { 46 | "registry": "https://registry.npmjs.org/", 47 | "access": "public" 48 | }, 49 | "scripts": { 50 | "artifacts": "napi artifacts", 51 | "bench": "node benchmark/bench.mjs", 52 | "build": "napi build --platform --release --pipe \"prettier -w\"", 53 | "build:debug": "napi build --platform --pipe \"prettier -w\"", 54 | "format": "run-p format:prettier format:rs", 55 | "format:prettier": "prettier . -w", 56 | "format:rs": "cargo fmt", 57 | "lint": "eslint . -c ./.eslintrc.yml", 58 | "prepublishOnly": "napi prepublish -t npm", 59 | "test": "ava", 60 | "version": "napi version" 61 | }, 62 | "devDependencies": { 63 | "@napi-rs/cli": "^2.14.6", 64 | "@napi-rs/ttf2woff2": "^0.0.5", 65 | "@swc-node/register": "^1.5.5", 66 | "@swc/core": "^1.3.32", 67 | "@types/node": "^18.11.19", 68 | "@typescript-eslint/eslint-plugin": "^5.50.0", 69 | "@typescript-eslint/parser": "^5.50.0", 70 | "@yisibl/fontkit": "^2.0.2", 71 | "ava": "^5.1.1", 72 | "benny": "^3.7.1", 73 | "chalk": "^5.2.0", 74 | "eslint": "^8.33.0", 75 | "eslint-config-prettier": "^8.6.0", 76 | "eslint-plugin-import": "^2.27.5", 77 | "eslint-plugin-prettier": "^4.2.1", 78 | "husky": "^8.0.3", 79 | "lint-staged": "^13.1.0", 80 | "npm-run-all": "^4.1.5", 81 | "prettier": "^2.8.3", 82 | "typescript": "^4.9.5", 83 | "wawoff2": "^2.0.1", 84 | "woff2-next": "^0.0.2" 85 | }, 86 | "lint-staged": { 87 | "*.@(js|ts|tsx)": [ 88 | "eslint -c .eslintrc.yml --fix" 89 | ], 90 | "*.@(js|ts|tsx|yml|yaml|md|json)": [ 91 | "prettier --write" 92 | ] 93 | }, 94 | "ava": { 95 | "require": [ 96 | "@swc-node/register" 97 | ], 98 | "extensions": [ 99 | "ts" 100 | ], 101 | "timeout": "2m", 102 | "workerThreads": false, 103 | "environmentVariables": { 104 | "TS_NODE_PROJECT": "./tsconfig.json" 105 | } 106 | }, 107 | "prettier": { 108 | "printWidth": 120, 109 | "semi": false, 110 | "trailingComma": "all", 111 | "singleQuote": true, 112 | "arrowParens": "always" 113 | }, 114 | "packageManager": "yarn@3.4.1" 115 | } 116 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | tab_spaces = 2 2 | -------------------------------------------------------------------------------- /simple-test.js: -------------------------------------------------------------------------------- 1 | const { plus100 } = require('./index') 2 | 3 | console.assert(plus100(0) === 100, 'Simple test failed') 4 | 5 | console.info('Simple test passed') 6 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny(clippy::all)] 2 | 3 | use napi::bindgen_prelude::Buffer; 4 | use napi_derive::napi; 5 | 6 | use woff2::decode::convert_woff2_to_ttf; 7 | 8 | #[napi] 9 | pub fn decode(input: Buffer) -> Buffer { 10 | let output = convert_woff2_to_ttf(&mut std::io::Cursor::new(input)); 11 | 12 | Buffer::from(output.unwrap()) 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "strict": true, 5 | "moduleResolution": "node", 6 | "module": "CommonJS", 7 | "noUnusedLocals": true, 8 | "noUnusedParameters": true, 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true 11 | }, 12 | "include": ["."], 13 | "exclude": ["node_modules"] 14 | } 15 | --------------------------------------------------------------------------------