From fb888fd780e9cf950fa3159d461b0f051bfb9346 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 02:37:38 +0530 Subject: [PATCH 01/18] WIP --- .github/workflows/ci.yml | 86 + .github/workflows/prebuild-main.yml | 57 - .github/workflows/prebuild-pr.yml | 55 - Gruntfile.js | 80 - README.md | 9 +- binding.gyp | 14 +- binding.js | 264 +-- package-lock.json | 2828 +----------------------- package.json | 26 +- src/macros.hh | 7 +- src/node_printer.hpp | 6 +- src/node_printer_posix.cc | 251 +++ tools/buildElectronLinux.sh | 4 +- tools/buildElectronMac.sh | 21 + tools/buildElectronWindows.ps1 | 35 +- tools/generateReleaseBuildsLinux.sh | 71 +- tools/generateReleaseBuildsMac.sh | 54 + tools/generateReleaseBuildsWindows.ps1 | 73 +- types/index.d.ts | 19 +- 19 files changed, 723 insertions(+), 3237 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 Gruntfile.js create mode 100644 src/node_printer_posix.cc create mode 100644 tools/buildElectronMac.sh create mode 100644 tools/generateReleaseBuildsMac.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..691c86d7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,86 @@ +name: CI & Prebuilds + +on: + push: + branches: + - main + pull_request: + +jobs: + prebuild: + name: Prebuild on ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'npm' + + - name: Install Linux dependencies + if: runner.os == 'Linux' + run: | + sudo dpkg --add-architecture i386 + sudo apt-get update -y -qq + sudo apt-get install -y g++-multilib gcc-multilib libcups2-dev libcups2-dev:i386 libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 + + - name: Install dependencies + run: npm install + + - name: Build for Linux + if: runner.os == 'Linux' + run: | + npm run prebuild -- --strip --all --arch ia32 + npm run prebuild -- --strip --all --arch x64 + + - name: Build for macOS + if: runner.os == 'macOS' + run: | + npm run prebuild -- --strip --all --arch x64 + npm run prebuild -- --strip --all --arch arm64 + + - name: Build for Windows + if: runner.os == 'Windows' + run: | + npm run prebuild -- --strip --all --arch ia32 + npm run prebuild -- --strip --all --arch x64 + + - name: Upload prebuilds artifact + uses: actions/upload-artifact@v4 + with: + name: prebuilds-${{ matrix.os }} + path: prebuilds/ + + publish: + name: Publish Prebuilds + needs: prebuild + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + - name: Install dependencies + run: npm install + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: prebuilds/ + pattern: prebuilds-* + merge-multiple: true + - name: Publish to GitHub Releases + env: + NODE_PRE_GYP_GITHUB_TOKEN: ${{ secrets.PREBUILD_TOKEN }} + run: npm run release \ No newline at end of file diff --git a/.github/workflows/prebuild-main.yml b/.github/workflows/prebuild-main.yml index 9914ba80..e69de29b 100644 --- a/.github/workflows/prebuild-main.yml +++ b/.github/workflows/prebuild-main.yml @@ -1,57 +0,0 @@ -name: Prebuild Binaries and Publish - -on: - push: - branches: - - main - -jobs: - prebuild-linux: - name: Prebuild Binaries for Linux - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Setup Dependencies - run: | - sudo dpkg --add-architecture i386 - sudo apt-get update -y -qq - sudo apt-get install -y g++-multilib gcc-multilib libcups2-dev libcups2-dev:i386 libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch ia32 -u ${{ secrets.PREBUILD_TOKEN }} - npm run prebuild -- --strip --all --arch x64 -u ${{ secrets.PREBUILD_TOKEN }} - prebuild-macos: - name: Prebuild Binaries for macOS - runs-on: macos-latest - timeout-minutes: 30 - steps: - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch x64 -u ${{ secrets.PREBUILD_TOKEN }} - prebuild-windows: - name: Prebuild Binaries for Windows - runs-on: windows-latest - timeout-minutes: 30 - steps: - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch ia32 -u ${{ secrets.PREBUILD_TOKEN }} - npm run prebuild -- --strip --all --arch x64 -u ${{ secrets.PREBUILD_TOKEN }} diff --git a/.github/workflows/prebuild-pr.yml b/.github/workflows/prebuild-pr.yml index a4ab8bda..e69de29b 100644 --- a/.github/workflows/prebuild-pr.yml +++ b/.github/workflows/prebuild-pr.yml @@ -1,55 +0,0 @@ -name: Prebuild Binaries - -on: - pull_request: - -jobs: - prebuild-linux: - name: Prebuild Binaries for Linux - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Setup Dependencies - run: | - sudo dpkg --add-architecture i386 - sudo apt-get update -y -qq - sudo apt-get install -y g++-multilib gcc-multilib libcups2-dev libcups2-dev:i386 libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch ia32 - npm run prebuild -- --strip --all --arch x64 - prebuild-macos: - name: Prebuild Binaries for macOS - runs-on: macos-latest - timeout-minutes: 30 - steps: - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch x64 - prebuild-windows: - name: Prebuild Binaries for Windows - runs-on: windows-latest - timeout-minutes: 30 - steps: - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - uses: actions/checkout@v1 - - run: npm i - - name: Prebuild - run: | - npm run apply-patches - npm run prebuild -- --strip --all --arch ia32 - npm run prebuild -- --strip --all --arch x64 diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index cb927d99..00000000 --- a/Gruntfile.js +++ /dev/null @@ -1,80 +0,0 @@ -module.exports = function(grunt) { - grunt.initConfig({ - shell: { - 'node-pre-gyp-ia32': { - command: 'node-pre-gyp configure build package --target_arch=ia32' - }, - 'node-pre-gyp-x64': { - command: 'node-pre-gyp configure build package --target_arch=x64' - }, - 'node-gyp-ia32': { - command: 'node-gyp rebuild --arch=ia32' - }, - 'node-gyp-x64': { - command: 'node-gyp rebuild --arch=x64' - }, - 'upload-binaries': { - command: 'node-pre-gyp-github publish' - } - }, - copy: { - ia32: { - files: [ - {src: 'build/Release/electron-printer.node', dest: 'lib/electron-printer-' + process.platform + '-ia32.node'}, - {src: 'binding.js', dest: 'lib/binding.js'}, - {src: 'index.js', dest: 'lib/index.js'} - ] - }, - x64: { - files: [ - {src: 'build/Release/electron-printer.node', dest: 'lib/electron-printer-' + process.platform + '-x64.node'}, - {src: 'binding.js', dest: 'lib/binding.js'}, - {src: 'index.js', dest: 'lib/index.js'} - ] - } - } - }); - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-shell'); - grunt.loadNpmTasks('grunt-contrib-copy'); - - grunt.registerTask('build-pre-ia32', [ - 'shell:node-pre-gyp-ia32', - 'copy:ia32' - ]); - - grunt.registerTask('build-ia32', [ - 'shell:node-gyp-ia32', - 'copy:ia32' - ]); - - grunt.registerTask('build-x64', [ - 'shell:node-gyp-x64', - 'copy:x64' - ]); - - grunt.registerTask('build-pre-x64', [ - 'shell:node-pre-gyp-x64', - 'copy:x64' - ]); - - grunt.registerTask('build', [ - 'build-ia32', - 'build-x64' - ]); - - grunt.registerTask('build-pre', [ - 'build-pre-ia32', - 'build-pre-x64' - ]); - - grunt.registerTask('upload', [ - 'shell:upload-binaries' - ]); - - grunt.registerTask('release', [ - 'build-pre', - 'upload' - ]); -}; diff --git a/README.md b/README.md index b82a1deb..ffd35f71 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ -# @thesusheer/electron-printer +# @addble/electron-printer **No recompilation required when upgrading Node.js versions, thanks to N-API!** 🎉 Native bind printers on POSIX and Windows OS from Node.js, Electron, and node-webkit. -!npm version !Prebuild Binaries and Publish +[![npm version](https://badge.fury.io/js/%40addble%2Felectron-printer.svg)](https://badge.fury.io/js/%40addble%2Felectron-printer) +[![CI & Prebuilds](https://github.com/addble/electron-printer/actions/workflows/ci.yml/badge.svg)](https://github.com/addble/electron-printer/actions/workflows/ci.yml) > Supports Node.js versions from 8.0.0 onwards, including the latest versions, thanks to the transition to N-API. -> Prebuild and CI integration courtesy of @ekoeryanto in his FORK +> Prebuild and CI integration courtesy of @ekoeryanto in his [FORK](https://github.com/ekoeryanto/node-printer) -If you have a problem, ask a question on !Gitter or find/create a new Github issue +If you have a problem, please find or create a new [GitHub issue](https://github.com/addble/electron-printer/issues). ___ ### **Below is the original README** diff --git a/binding.gyp b/binding.gyp index f93f93f6..ff85a917 100644 --- a/binding.gyp +++ b/binding.gyp @@ -18,9 +18,17 @@ { 'target_name': '<(module_name)', 'sources': [ - # is like "ls -1 src/*.cc", but gyp does not support direct patterns on - # sources - '} A promise that resolves with the job ID. */ - function printDirect(parameters){ - var data = parameters - , printer - , docname - , type - , options - , success - , error; - - if(arguments.length==1){ - //TODO: check parameters type - //if (typeof parameters ) - data = parameters.data; - printer = parameters.printer; - docname = parameters.docname; - type = parameters.type; - options = parameters.options||{}; - success = parameters.success; - error = parameters.error; - }else{ - printer = arguments[1]; - type = arguments[2]; - docname = arguments[3]; - options = arguments[4]; - success = arguments[5]; - error = arguments[6]; - } - - if(!type){ - type = "RAW"; - } - - // Set default printer name - if(!printer) { - printer = addon.getDefaultPrinterName(); +async function printDirect(options) { + if (typeof options !== 'object' || options === null) { + throw new TypeError('An options object is required.'); } - type = type.toUpperCase(); + const { + data, + printer = addon.getDefaultPrinterName(), + docname = 'node print job', + type = 'RAW', + options: printerOptions = {} + } = options; - if(!docname){ - docname = "node print job"; + if (!data) { + throw new Error('A `data` field is required in the options object.'); } - if (!options){ - options = {}; + if (!printer) { + throw new Error('A `printer` name is required, or a default printer must be set.'); } - //TODO: check parameters type - if(addon.printDirect){// call C++ binding - try{ - var res = addon.printDirect(data, printer, docname, type, options); - if(res){ - success(res); - }else{ - error(Error("Something wrong in printDirect")); - } - }catch (e){ - error(e); + return new Promise((resolve, reject) => { + try { + const jobId = addon.printDirect(data, printer, docname, type.toUpperCase(), printerOptions); + resolve(jobId); + } catch (e) { + reject(e); } - }else{ - error("Not supported"); - } + }); } /** Get printer info with jobs @@ -128,38 +65,39 @@ module.exports.getSupportedPrintFormats = addon.getSupportedPrintFormats; * @return printer object info: * TODO: to enum all possible attributes */ - function getPrinter(printerName) - { - if(!printerName) { - printerName = addon.getDefaultPrinterName(); - } - var printer = addon.getPrinter(printerName); - correctPrinterinfo(printer); - return printer; - } +function getPrinter(printerName) { + const targetPrinterName = printerName || addon.getDefaultPrinterName(); + if (!targetPrinterName) { + return undefined; + } + + const printer = addon.getPrinter(targetPrinterName); + if (printer) { + correctPrinterinfo(printer); + } + return printer; +} function correctPrinterinfo(printer) { - if(printer.status || !printer.options || !printer.options['printer-state']){ + if (!printer || printer.status || !printer.options || !printer.options['printer-state']) { return; } var status = printer.options['printer-state']; // Add posix status - if(status == '3'){ + if (status == '3') { status = 'IDLE' - } - else if(status == '4'){ + } else if (status == '4') { status = 'PRINTING' - } - else if(status == '5'){ + } else if (status == '5') { status = 'STOPPED' } // correct date type var k; - for(k in printer.options) { - if(/time$/.test(k) && printer.options[k] && !(printer.options[k] instanceof Date)) { + for (k in printer.options) { + if (/time$/.test(k) && printer.options[k] && !(printer.options[k] instanceof Date)) { printer.options[k] = new Date(printer.options[k] * 1000); } } @@ -168,77 +106,45 @@ function correctPrinterinfo(printer) { } /** -parameters: - parameters - Object, parameters objects with the following structure: - filename - String, mandatory, data to printer - docname - String, optional, name of document showed in printer status - printer - String, optional, mane of the printer, if missed, will try to retrieve the default printer name - success - Function, optional, callback function - error - Function, optional, callback function if exists any error -*/ -function printFile(parameters){ - var filename, - docname, - printer, - options, - success, - error; - - if((arguments.length !== 1) || (typeof(parameters) !== 'object')){ - throw new Error('must provide arguments object'); - } - - filename = parameters.filename; - docname = parameters.docname; - printer = parameters.printer; - options = parameters.options || {}; - success = parameters.success; - error = parameters.error; - - if(!success){ - success = function(){}; + * Print a file to a printer. This function is asynchronous and returns a Promise. + * Note: This function is only supported on POSIX platforms (macOS, Linux). + * @param {object} options The print options. + * @param {string} options.filename The path to the file to be printed. + * @param {string} [options.printer] The name of the printer. If not provided, the default printer is used. + * @param {string} [options.docname] The name of the document. Defaults to the filename. + * @param {object} [options.options={}] CUPS-specific options. + * @returns {Promise} A promise that resolves with the job ID. + */ +async function printFile(options) { + if (typeof options !== 'object' || options === null) { + throw new TypeError('An options object is required.'); } - if(!error){ - error = function(err){ - throw err; - }; + if (!addon.printFile) { + throw new Error('`printFile` is not supported on this platform (Windows).'); } - if(!filename){ - var err = new Error('must provide at least a filename'); - return error(err); - } + const { + filename, + printer = addon.getDefaultPrinterName(), + docname = filename, + options: printerOptions = {} + } = options; - // try to define default printer name - if(!printer) { - printer = addon.getDefaultPrinterName(); + if (!filename) { + throw new Error('A `filename` is required in the options object.'); } - if(!printer) { - return error(new Error('Printer parameter of default printer is not defined')); + if (!printer) { + throw new Error('A `printer` name is required, or a default printer must be set.'); } - // set filename if docname is missing - if(!docname){ - docname = filename; - } - - //TODO: check parameters type - if(addon.printFile){// call C++ binding - try{ - // TODO: proper success/error callbacks from the extension - var res = addon.printFile(filename, docname, printer, options); - - if(!isNaN(parseInt(res))) { - success(res); - } else { - error(Error(res)); - } + return new Promise((resolve, reject) => { + try { + const jobId = addon.printFile(filename, docname, printer, printerOptions); + resolve(jobId); } catch (e) { - error(e); + reject(e); } - } else { - error("Not supported"); - } + }); } diff --git a/package-lock.json b/package-lock.json index bfbb6e46..a70f1cfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,93 +1,21 @@ { - "name": "@thesusheer/electron-printer", - "version": "2.0.3", + "name": "@addble/electron-printer", + "version": "2.0.4-addble.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@thesusheer/electron-printer", - "version": "2.0.3", + "name": "@addble/electron-printer", + "version": "2.0.4-addble.1", "hasInstallScript": true, "dependencies": { "node-addon-api": "^8.1.0" }, "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "grunt": "^1.6.1", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-jshint": "^3.2.0", - "grunt-node-gyp": "^5.0.0", - "grunt-shell": "^4.0.0", "node-pre-gyp-github": "github:Susheer/node-pre-gyp-github" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", @@ -168,34 +96,6 @@ "node": ">=18" } }, - "node_modules/@npmcli/agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", - "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", - "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/@octokit/auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", @@ -351,22 +251,6 @@ "@octokit/openapi-types": "^22.2.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "node_modules/agent-base": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", @@ -379,245 +263,12 @@ "node": ">= 14" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacache": { - "version": "18.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", - "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==", - "dev": true, - "dependencies": { - "exit": "0.1.2", - "glob": "^7.1.1" - }, - "engines": { - "node": ">=0.2.5" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha512-ENwblkFQpqqia6b++zLD/KUWafYlVY/UNnAp7oz7LY7E924wmpye416wBOmvv/HMWzl8gL1kJlfvId/1Dg176w==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/commander": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", @@ -627,12 +278,6 @@ "node": ">=18" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", @@ -642,65 +287,6 @@ "node": "^14.18.0 || >=16.10.0" } }, - "node_modules/console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha512-duS7VP5pvfsNLDvL1O4VOEbw37AI3A4ZUQYemvDlnpGrNu9tprR7BYWpDYwC0Xia0Zxz5ZupdiIrUp0GH1aXfg==", - "dev": true, - "dependencies": { - "date-now": "^0.1.4" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw==", - "dev": true - }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -724,15 +310,6 @@ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -742,2215 +319,180 @@ "node": ">=8" } }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", - "dev": true, - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.2" } }, - "node_modules/entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", - "dev": true - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, "engines": { - "node": ">=6" + "node": ">= 14" } }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==", - "dev": true - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/file-sync-cmp": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", - "integrity": "sha512-0k45oWBokCqh2MOexeYKpyqmGKG+8mQ2Wd8iawx+uWd/weWJQAZ6SoPybagdCI4xFisag8iAR77WPm4h3pTfxA==", - "dev": true - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getobject": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", - "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/grunt": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.6.1.tgz", - "integrity": "sha512-/ABUy3gYWu5iBmrUSRBP97JLpQUm0GgVveDCp6t3yRNIoltIYw7rEj3g5y1o2PGPR2vfTRGa7WC/LZHLTXnEzA==", - "dev": true, - "dependencies": { - "dateformat": "~4.6.2", - "eventemitter2": "~0.4.13", - "exit": "~0.1.2", - "findup-sync": "~5.0.0", - "glob": "~7.1.6", - "grunt-cli": "~1.4.3", - "grunt-known-options": "~2.0.0", - "grunt-legacy-log": "~3.0.0", - "grunt-legacy-util": "~2.0.1", - "iconv-lite": "~0.6.3", - "js-yaml": "~3.14.0", - "minimatch": "~3.0.4", - "nopt": "~3.0.6" - }, - "bin": { - "grunt": "bin/grunt" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/grunt-contrib-copy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz", - "integrity": "sha512-gFRFUB0ZbLcjKb67Magz1yOHGBkyU6uL29hiEW1tdQ9gQt72NuMKIy/kS6dsCbV0cZ0maNCb0s6y+uT1FKU7jA==", - "dev": true, - "dependencies": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-jshint": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz", - "integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==", - "dev": true, - "dependencies": { - "chalk": "~4.1.2", - "hooker": "^0.2.3", - "jshint": "~2.13.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-contrib-jshint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/grunt-contrib-jshint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/grunt-contrib-jshint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt-known-options": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", - "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-legacy-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", - "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", - "dev": true, - "dependencies": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.19" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/grunt-legacy-log-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", - "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", - "dev": true, - "dependencies": { - "chalk": "~4.1.0", - "lodash": "~4.17.19" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-legacy-log-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/grunt-legacy-log-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/grunt-legacy-log-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt-legacy-util": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", - "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", - "dev": true, - "dependencies": { - "async": "~3.2.0", - "exit": "~0.1.2", - "getobject": "~1.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.21", - "underscore.string": "~3.3.5", - "which": "~2.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-legacy-util/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/grunt-node-gyp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/grunt-node-gyp/-/grunt-node-gyp-5.0.0.tgz", - "integrity": "sha512-XAcBybBUbFKalssMwJtaLc3lnfS2RyklC4SNwdYtGeCfpSJFAjJ7FYMrmWSe7TmrcA6Sj+ZYk6h7DO0XYBNwXw==", - "dev": true, - "dependencies": { - "node-gyp": ">=3" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "grunt": "1" - } - }, - "node_modules/grunt-shell": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-4.0.0.tgz", - "integrity": "sha512-dHFy8VZDfWGYLTeNvIHze4PKXGvIlDWuN0UE7hUZstTQeiEyv1VmW1MaDYQ3X5tE3bCi3bEia1gGKH8z/f1czQ==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "npm-run-path": "^2.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "grunt": ">=1" - } - }, - "node_modules/grunt-shell/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt-shell/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/grunt-shell/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt-shell/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt-shell/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/grunt/node_modules/findup-sync": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", - "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.3", - "micromatch": "^4.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/grunt/node_modules/grunt-cli": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", - "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", - "dev": true, - "dependencies": { - "grunt-known-options": "~2.0.0", - "interpret": "~1.1.0", - "liftup": "~3.0.1", - "nopt": "~4.0.1", - "v8flags": "~3.2.0" - }, - "bin": { - "grunt": "bin/grunt" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt/node_modules/grunt-cli/node_modules/nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "dependencies": { - "abbrev": "1", - "osenv": "^0.1.4" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/grunt/node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/grunt/node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha512-t+UerCsQviSymAInD01Pw+Dn/usmz1sRO+3Zk1+lx8eg+WKpD2ulcwWqHHL0+aseRBr+3+vIhiG1K1JTwaIcTA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", - "dev": true, - "dependencies": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha512-CLM8SNMDu7C5psFCn6Wg/tgpj/bKAg7hc2gWqcuR9OD5Ft9PhBpIu8PLicPeis+xDd6YX2ncI8MCA64I9tftIA==", - "dev": true - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true - }, - "node_modules/jshint": { - "version": "2.13.6", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.6.tgz", - "integrity": "sha512-IVdB4G0NTTeQZrBoM8C5JFVLjV2KtZ9APgybDA1MK73xb09qFs0jCXyQLnCOp1cSZZZbvhq/6mfXHUTaDkffuQ==", - "dev": true, - "dependencies": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.21", - "minimatch": "~3.0.2", - "strip-json-comments": "1.0.x" - }, - "bin": { - "jshint": "bin/jshint" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/liftup": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", - "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", - "dev": true, - "dependencies": { - "extend": "^3.0.2", - "findup-sync": "^4.0.0", - "fined": "^1.2.0", - "flagged-respawn": "^1.0.1", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.1", - "rechoir": "^0.7.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/make-fetch-happen": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", - "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", - "dev": true, - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.1.tgz", - "integrity": "sha512-vmEOvxwiH8tlOcv4SyE8RH34rI5/nWVaigUeAUPawC6f0+HoDthwI0vkMu4tbtsZrXq6QXFfrkhjofzKEs5tpA==", - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", - "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/node-gyp/node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/node-gyp/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/node-gyp/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/node-gyp/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "dev": true, - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/node-gyp/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/node-pre-gyp-github": { - "version": "2.0.0", - "resolved": "git+ssh://git@github.com/Susheer/node-pre-gyp-github.git#5c8494d668c18738f8c9dee2f4061b9575dd945c", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/rest": "20.1.1", - "commander": "12.0.0" - }, - "bin": { - "node-pre-gyp-github": "bin/node-pre-gyp-github.js" - } - }, - "node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", - "dev": true, - "dependencies": { - "abbrev": "^3.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/nopt/node_modules/abbrev": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.0.tgz", - "integrity": "sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==", - "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "deprecated": "This package is no longer supported.", - "dev": true, - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true - }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "dependencies": { - "path-root-regex": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/proc-log": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", - "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, - "dependencies": { - "minipass": "^7.0.3" + "bin": { + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "node": ">=10" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "node_modules/node-addon-api": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.2.1.tgz", + "integrity": "sha512-vmEOvxwiH8tlOcv4SyE8RH34rI5/nWVaigUeAUPawC6f0+HoDthwI0vkMu4tbtsZrXq6QXFfrkhjofzKEs5tpA==", "engines": { - "node": ">=8" + "node": "^18 || ^20 || >= 21" } }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "dependencies": { - "ansi-regex": "^2.0.0" + "whatwg-url": "^5.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" + "node": "4.x || >=6.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha512-AOPG8EBc5wAikaG1/7uFCNFJwnKOuQwFTpYBdTW6OvWHeZBQBrAA/amefHGrEiOnCPcLFZK6FUPtWVKpQVIRgg==", - "dev": true, - "bin": { - "strip-json-comments": "cli.js" + "peerDependencies": { + "encoding": "^0.1.0" }, - "engines": { - "node": ">=0.8.0" + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node_modules/supports-color": { + "node_modules/node-pre-gyp-github": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "resolved": "git+ssh://git@github.com/Susheer/node-pre-gyp-github.git#5c8494d668c18738f8c9dee2f4061b9575dd945c", "dev": true, - "engines": { - "node": ">= 0.4" + "license": "MIT", + "dependencies": { + "@octokit/rest": "20.1.1", + "commander": "12.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "node-pre-gyp-github": "bin/node-pre-gyp-github.js" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", "dev": true, "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" }, "engines": { - "node": ">=10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/nopt/node_modules/abbrev": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.0.tgz", + "integrity": "sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==", "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" + "wrappy": "1" } }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { - "mkdirp": "bin/cmd.js" + "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dev": true, - "dependencies": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/underscore.string/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/universal-user-agent": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "dev": true }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2967,185 +509,11 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } } diff --git a/package.json b/package.json index eba3cf19..636ba674 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { - "name": "@thesusheer/electron-printer", + "name": "@addble/electron-printer", "description": "Node API (N-API) supported electron.s || node.js printer bindings", - "homepage": "https://github.com/Susheer/electron-printer", - "version": "2.0.4", + "homepage": "https://github.com/addble/electron-printer", + "version": "3.0.0", "main": "./lib/index.js", "types": "types/index.d.ts", "dependencies": { "node-addon-api": "^8.1.0" }, "scripts": { - "install": "prebuild-install || node-gyp rebuild", + "install": "node-pre-gyp install --fallback-to-build", "rebuild": "node-gyp rebuild", - "release": "node-pre-gyp-github publish --release --commitish main", - "electron-rebuild": "node-gyp rebuild --target_platform=win32 --target_arch=x64 --runtime=electron --target=32.2.0 --dist-url=https://electronjs.org/headers", + "prebuild": "node-pre-gyp prebuild --strip --all", + "release": "node-pre-gyp-github publish --release", "test": "node --test test/" }, @@ -28,27 +28,21 @@ ], "repository": { "type": "git", - "url": "https://github.com/Susheer/electron-printer.git" + "url": "https://github.com/addble/electron-printer.git" }, "binary": { "module_name": "electron-printer", "module_path": "./lib/", - "host": "https://github.com/Susheer/electron-printer/releases/download/", - "remote_path": "v{version}", - "tag_path": "https://github.com/Susheer/electron-printer/releases/tag/v{version}" + "host": "https://github.com/addble/electron-printer/releases/download/", + "remote_path": "v{version}" }, "licenses": [ { - "type": "BSD" + "type": "MIT" } ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "grunt": "^1.6.1", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-jshint": "^3.2.0", - "grunt-node-gyp": "^5.0.0", - "grunt-shell": "^4.0.0", "node-pre-gyp-github": "github:Susheer/node-pre-gyp-github" } } diff --git a/src/macros.hh b/src/macros.hh index c4f88d7e..04730b13 100644 --- a/src/macros.hh +++ b/src/macros.hh @@ -1,5 +1,5 @@ -#ifndef NODE_PRINTER_SRC_MACROS_H -#define NODE_PRINTER_SRC_MACROS_H +#ifndef ELECTRON_PRINTER_SRC_MACROS_H +#define ELECTRON_PRINTER_SRC_MACROS_H #include @@ -49,5 +49,4 @@ if ((job->key != NULL) && (*job->key != L'\0')) { \ std::wstring var = (args)[(i)].As().Utf16Value(); -#endif - +#endif // ELECTRON_PRINTER_SRC_MACROS_H diff --git a/src/node_printer.hpp b/src/node_printer.hpp index dbb32b05..33400ebf 100644 --- a/src/node_printer.hpp +++ b/src/node_printer.hpp @@ -1,5 +1,5 @@ -#ifndef NODE_PRINTER_HPP -#define NODE_PRINTER_HPP +#ifndef ELECTRON_PRINTER_HPP +#define ELECTRON_PRINTER_HPP #include "macros.hh" @@ -74,4 +74,4 @@ class MemValueBase bool getStringOrBufferFromNapiValue(const Napi::Value& value, std::string& oData); -#endif +#endif // ELECTRON_PRINTER_HPP diff --git a/src/node_printer_posix.cc b/src/node_printer_posix.cc new file mode 100644 index 00000000..c534c6a9 --- /dev/null +++ b/src/node_printer_posix.cc @@ -0,0 +1,251 @@ +#include "node_printer.hpp" +#include +#include +#include +#include +#include +#include + +// This file provides the implementation for POSIX-compliant systems (macOS, Linux) using CUPS. + +namespace { + +// Helper to convert Napi::Object to cups_option_t. +// The caller is responsible for freeing the returned cups_option_t array using cupsFreeOptions. +int napi_object_to_cups_options(Napi::Env env, Napi::Object napi_options, cups_option_t **cups_options) { + Napi::Array keys = napi_options.GetPropertyNames(); + uint32_t num_options = 0; + *cups_options = NULL; + + for (uint32_t i = 0; i < keys.Length(); i++) { + Napi::Value key_val = keys.Get(i); + std::string key = key_val.As().Utf8Value(); + Napi::Value value_val = napi_options.Get(key_val); + + std::string value; + if (value_val.IsString()) { + value = value_val.As().Utf8Value(); + } else if (value_val.IsNumber()) { + value = std::to_string(value_val.As().Int64Value()); + } else if (value_val.IsBoolean()) { + value = value_val.As().Value() ? "true" : "false"; + } else { + // Skip non-primitive types + continue; + } + + num_options = cupsAddOption(key.c_str(), value.c_str(), num_options, cups_options); + } + return num_options; +} + +} // anonymous namespace + +MY_NODE_MODULE_CALLBACK(getPrinters) +{ + MY_NODE_MODULE_HANDLESCOPE; + + cups_dest_t *dests; + int num_dests = cupsGetDests(&dests); + + if (num_dests <= 0) { + MY_NODE_MODULE_RETURN_VALUE(Napi::Array::New(env)); + } + + Napi::Array result = Napi::Array::New(env, num_dests); + + for (int i = 0; i < num_dests; i++) { + Napi::Object printer = Napi::Object::New(env); + printer.Set("name", Napi::String::New(env, dests[i].name)); + if (dests[i].instance) { + printer.Set("instance", Napi::String::New(env, dests[i].instance)); + } + printer.Set("is_default", Napi::Boolean::New(env, dests[i].is_default)); + + Napi::Object options = Napi::Object::New(env); + for (int j = 0; j < dests[i].num_options; j++) { + options.Set(dests[i].options[j].name, Napi::String::New(env, dests[i].options[j].value)); + } + printer.Set("options", options); + + const char* state_str = cupsGetOption("printer-state", dests[i].num_options, dests[i].options); + if (state_str) { + int state = atoi(state_str); + std::string status_string; + switch (state) { + case IPP_PRINTER_IDLE: status_string = "IDLE"; break; + case IPP_PRINTER_PROCESSING: status_string = "PRINTING"; break; + case IPP_PRINTER_STOPPED: status_string = "STOPPED"; break; + default: status_string = "UNKNOWN"; break; + } + printer.Set("status", Napi::String::New(env, status_string)); + } + + result.Set(i, printer); + } + + cupsFreeDests(num_dests, dests); + MY_NODE_MODULE_RETURN_VALUE(result); +} + +MY_NODE_MODULE_CALLBACK(getDefaultPrinterName) +{ + MY_NODE_MODULE_HANDLESCOPE; + const char* default_printer = cupsGetDefault2(NULL); + if (default_printer) { + MY_NODE_MODULE_RETURN_VALUE(Napi::String::New(env, default_printer)); + } + MY_NODE_MODULE_RETURN_VALUE(Napi::String::New(env, "")); +} + +MY_NODE_MODULE_CALLBACK(printDirect) +{ + MY_NODE_MODULE_HANDLESCOPE; + REQUIRE_ARGUMENTS(env, info, 5); + + std::string data; + if (!getStringOrBufferFromNapiValue(info[0], data)) { + RETURN_EXCEPTION(env, "Argument 0 must be a string or a Buffer."); + } + + ARG_CHECK_STRING(env, info, 1); // printer + ARG_CHECK_STRING(env, info, 2); // docname + ARG_CHECK_STRING(env, info, 3); // type + if (!info[4].IsObject()) { + RETURN_EXCEPTION(env, "Argument 4 must be an object."); + } + + std::string printer_name = info[1].As().Utf8Value(); + std::string doc_name = info[2].As().Utf8Value(); + std::string type = info[3].As().Utf8Value(); + Napi::Object js_options = info[4].As(); + + cups_option_t *options = NULL; + int num_options = napi_object_to_cups_options(env, js_options, &options); + + if (type == "RAW") { + num_options = cupsAddOption("raw", "true", num_options, &options); + } + + int job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer_name.c_str(), doc_name.c_str(), num_options, options); + + if (job_id > 0) { + const char* format = (type == "TEXT") ? "text/plain" : "application/octet-stream"; + http_t *http = httpConnect2(cupsServer(), ippPort(), NULL, 0, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL); + if (!http) { + cupsFreeOptions(num_options, options); + RETURN_EXCEPTION_STR(env, "Failed to connect to CUPS server"); + } + + if (cupsStartDocument(http, printer_name.c_str(), job_id, doc_name.c_str(), format, 1) == HTTP_STATUS_CONTINUE) { + cupsWriteRequestData(http, data.c_str(), data.length()); + ipp_status_t status = cupsFinishDocument(http, printer_name.c_str()); + if (status > IPP_STATUS_OK_CONFLICTING) { + std::string error_msg = "Failed to send document: "; + error_msg += cupsLastErrorString(); + httpClose(http); + cupsFreeOptions(num_options, options); + RETURN_EXCEPTION_STR(env, error_msg.c_str()); + } + } else { + std::string error_msg = "Failed to start document: "; + error_msg += cupsLastErrorString(); + httpClose(http); + cupsFreeOptions(num_options, options); + RETURN_EXCEPTION_STR(env, error_msg.c_str()); + } + httpClose(http); + } else { + std::string error_msg = "Failed to create CUPS job: "; + error_msg += cupsLastErrorString(); + cupsFreeOptions(num_options, options); + RETURN_EXCEPTION_STR(env, error_msg.c_str()); + } + + cupsFreeOptions(num_options, options); + MY_NODE_MODULE_RETURN_VALUE(Napi::Number::New(env, job_id)); +} + +MY_NODE_MODULE_CALLBACK(getPrinter) +{ + MY_NODE_MODULE_HANDLESCOPE; + REQUIRE_ARGUMENTS(env, info, 1); + ARG_CHECK_STRING(env, info, 0); + + std::string printer_name = info[0].As().Utf8Value(); + cups_dest_t *dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer_name.c_str(), NULL); + + if (!dest) { + MY_NODE_MODULE_RETURN_VALUE(env.Undefined()); + } + + Napi::Object printer = Napi::Object::New(env); + printer.Set("name", Napi::String::New(env, dest->name)); + if (dest->instance) { + printer.Set("instance", Napi::String::New(env, dest->instance)); + } + printer.Set("is_default", Napi::Boolean::New(env, dest->is_default)); + + Napi::Object options = Napi::Object::New(env); + for (int j = 0; j < dest->num_options; j++) { + options.Set(dest->options[j].name, Napi::String::New(env, dest->options[j].value)); + } + printer.Set("options", options); + + const char* state_str = cupsGetOption("printer-state", dest->num_options, dest->options); + if (state_str) { + int state = atoi(state_str); + std::string status_string; + switch (state) { + case IPP_PRINTER_IDLE: status_string = "IDLE"; break; + case IPP_PRINTER_PROCESSING: status_string = "PRINTING"; break; + case IPP_PRINTER_STOPPED: status_string = "STOPPED"; break; + default: status_string = "UNKNOWN"; break; + } + printer.Set("status", Napi::String::New(env, status_string)); + } + + cupsFreeDests(1, dest); + MY_NODE_MODULE_RETURN_VALUE(printer); +} + +MY_NODE_MODULE_CALLBACK(printFile) +{ + MY_NODE_MODULE_HANDLESCOPE; + REQUIRE_ARGUMENTS(env, info, 4); + ARG_CHECK_STRING(env, info, 0); // filename + ARG_CHECK_STRING(env, info, 1); // docname + ARG_CHECK_STRING(env, info, 2); // printer + if (!info[3].IsObject()) { + RETURN_EXCEPTION(env, "Argument 3 must be an object."); + } + + std::string filename = info[0].As().Utf8Value(); + std::string docname = info[1].As().Utf8Value(); + std::string printer_name = info[2].As().Utf8Value(); + Napi::Object js_options = info[3].As(); + + cups_option_t *options = NULL; + int num_options = napi_object_to_cups_options(env, js_options, &options); + + int job_id = cupsPrintFile(printer_name.c_str(), filename.c_str(), docname.c_str(), num_options, options); + + if (job_id == 0) { + std::string error_msg = "Failed to print file: "; + error_msg += cupsLastErrorString(); + cupsFreeOptions(num_options, options); + RETURN_EXCEPTION_STR(env, error_msg.c_str()); + } + + cupsFreeOptions(num_options, options); + MY_NODE_MODULE_RETURN_VALUE(Napi::Number::New(env, job_id)); +} + +MY_NODE_MODULE_CALLBACK(getSupportedPrintFormats) +{ + MY_NODE_MODULE_HANDLESCOPE; + Napi::Array result = Napi::Array::New(env); + result.Set(uint32_t(0), Napi::String::New(env, "RAW")); + result.Set(uint32_t(1), Napi::String::New(env, "TEXT")); + MY_NODE_MODULE_RETURN_VALUE(result); +} \ No newline at end of file diff --git a/tools/buildElectronLinux.sh b/tools/buildElectronLinux.sh index f6cf218b..ba8ba448 100755 --- a/tools/buildElectronLinux.sh +++ b/tools/buildElectronLinux.sh @@ -2,9 +2,9 @@ VERSION=$1 # # Build Electron Linux 64bit -node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=node_printer --module_path=../lib/ +node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=x64 --build-from-source # #Build Electron Linux 32bit -node-pre-gyp configure --target=$VERSION --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=node_printer --module_path=../lib/ +node-pre-gyp configure --target=$VERSION --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=ia32 --build-from-source diff --git a/tools/buildElectronMac.sh b/tools/buildElectronMac.sh new file mode 100644 index 00000000..90f9994d --- /dev/null +++ b/tools/buildElectronMac.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e + +VERSION=$1 + +if [ -z "$VERSION" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Build Electron macOS x64 +echo "Building for Electron $VERSION on macOS x64..." +node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=x64 --build-from-source + +# Build Electron macOS arm64 (for Apple Silicon) +echo "Building for Electron $VERSION on macOS arm64..." +node-pre-gyp configure --target=$VERSION --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm64 --build-from-source + +echo "Done." \ No newline at end of file diff --git a/tools/buildElectronWindows.ps1 b/tools/buildElectronWindows.ps1 index 23a105bd..6472fc9c 100644 --- a/tools/buildElectronWindows.ps1 +++ b/tools/buildElectronWindows.ps1 @@ -1,20 +1,27 @@ -# -# Usage: buildElectronWindows.ps1 -# +<# +.SYNOPSIS + Builds the native addon for a specific Electron version on Windows for x64 and ia32 architectures. +.PARAMETER Version + The target Electron version (e.g., "6.0.7"). +#> +param ( + [Parameter(Mandatory=$true, HelpMessage="The Electron version to build against.")] + [string]$Version +) -if ($args.Length -ne 1) { - echo "Must Supply only 1 argument - Version" - return -} +# Stop script on first error +$ErrorActionPreference = "Stop" -$version = $args[0] - -echo "Building Electron Version -> $version" +Write-Host "Building Electron Version -> $Version for x64 and ia32" # Build Electron Windows 64bit -../node_modules\.bin\node-pre-gyp.cmd configure --target=$version --arch=x64 --dist-url=https://electronjs.org/headers --module_name=node_printer -../node_modules\.bin\node-pre-gyp.cmd build package --runtime=electron --target=$version --target_arch=x64 --build-from-source +Write-Host "Building for x64..." +npx node-pre-gyp configure --target=$Version --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=x64 --build-from-source # Build Electron Windows 32bit -../node_modules\.bin\node-pre-gyp.cmd configure --target=$version --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=node_printer -../node_modules\.bin\node-pre-gyp.cmd build package --runtime=electron --target=$version --target_arch=ia32 --build-from-source \ No newline at end of file +Write-Host "Building for ia32..." +npx node-pre-gyp configure --target=$Version --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=ia32 --build-from-source + +Write-Host "Done." \ No newline at end of file diff --git a/tools/generateReleaseBuildsLinux.sh b/tools/generateReleaseBuildsLinux.sh index d9f78dcb..233612ce 100755 --- a/tools/generateReleaseBuildsLinux.sh +++ b/tools/generateReleaseBuildsLinux.sh @@ -1,59 +1,54 @@ #!/bin/bash +set -e # Exit immediately if a command exits with a non-zero status. + +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "e.g.: $0 2.0.5" + exit 1 +fi RELEASE_VERSION=$1 PACKAGE_VERSION=$(node -pe "require('./package.json').version") -SOURCE_PATH="${BASH_SOURCE%/*}/.." +SOURCE_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" +# Modern, relevant Node.js and Electron versions +# N-API provides forward compatibility, so we target major LTS versions. declare -a node_versions=( - "0.10.48" - "0.12.18" - "4.9.1" - "5.9.1" - "6.17.1" - "8.16.1" - "10.16.0" - "11.15.0" - "12.10.0" + "16.20.2" + "18.20.2" + "20.14.0" + "22.4.0" ) declare -a electron_versions=( - "1.2.8" - "1.3.8" - "1.4.6" - "1.7.12" - "2.0.18" - "3.1.13" - "4.2.10" - "5.0.10" - "6.0.7" + "28.3.3" + "29.4.0" + "30.1.0" + "31.2.1" ) # remove old build directory -rm -rf "$SOURCHE_PATH/build" > /dev/null +rm -rf "$SOURCE_PATH/build" # create release path -mkdir -p "$SOURCE_PATH/releases/$RELEASE_VERSION" > /dev/null - -for version in "${node_versions[@]}" -do - echo "Building for node version: $version..." - node-pre-gyp configure --target=$version --module_name=node_printer --silent - node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source --silent - node-pre-gyp configure --target=$version --module_name=node_printer --silent - node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source --silent - rsync -a -v "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files > /dev/null +mkdir -p "$SOURCE_PATH/releases/$RELEASE_VERSION" + +for version in "${node_versions[@]}"; do + echo "Building for Node.js version: $version..." + npx node-pre-gyp configure --target=$version --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source + rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files echo "Done" done -for version in "${electron_versions[@]}" -do +for version in "${electron_versions[@]}"; do echo "Building for electron version: $version..." - node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=node_printer --silent - node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source --silent - node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=node_printer --silent - node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source --silent - rsync -a -v "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files > /dev/null + npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source + rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files echo "Done" done -echo "Finished succesfully!" +echo "Finished successfully!" diff --git a/tools/generateReleaseBuildsMac.sh b/tools/generateReleaseBuildsMac.sh new file mode 100644 index 00000000..a1162f4f --- /dev/null +++ b/tools/generateReleaseBuildsMac.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -e # Exit immediately if a command exits with a non-zero status. + +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "e.g.: $0 2.0.5" + exit 1 +fi + +RELEASE_VERSION=$1 +PACKAGE_VERSION=$(node -pe "require('./package.json').version") +SOURCE_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" + +# Modern, relevant Node.js and Electron versions +# N-API provides forward compatibility, so we target major LTS versions. +declare -a node_versions=( + "16.20.2" + "18.20.2" + "20.14.0" + "22.4.0" +) + +declare -a electron_versions=( + "28.3.3" + "29.4.0" + "30.1.0" + "31.2.1" +) + +# Remove old build directory +rm -rf "$SOURCE_PATH/build" + +# Create release path +mkdir -p "$SOURCE_PATH/releases/$RELEASE_VERSION" + +for version in "${node_versions[@]}"; do + echo "Building for Node.js version: $version..." + npx node-pre-gyp configure --target=$version --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=arm64 --build-from-source + rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files + echo "Done" +done + +for version in "${electron_versions[@]}"; do + echo "Building for Electron version: $version..." + npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=arm64 --runtime=electron --build-from-source + rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files + echo "Done" +done + +echo "Finished successfully!" \ No newline at end of file diff --git a/tools/generateReleaseBuildsWindows.ps1 b/tools/generateReleaseBuildsWindows.ps1 index 6a33a03d..b80d421e 100644 --- a/tools/generateReleaseBuildsWindows.ps1 +++ b/tools/generateReleaseBuildsWindows.ps1 @@ -1,63 +1,60 @@ +<# +.SYNOPSIS + Builds pre-compiled binaries for a release. +.PARAMETER Release + The release version tag (e.g., "2.0.5"). +#> param ( - [Parameter(Mandatory=$true)][string]$release + [Parameter(Mandatory=$true)][string]$Release ) -$SOURCE_PATH = split-path -parent $MyInvocation.MyCommand.Definition -$RELEASE_VERSION = $release -$PACKAGE_VERSION = node -pe "require('./package.json').version" +# Stop script on first error +$ErrorActionPreference = "Stop" -echo $SOURCE_PATH +$SOURCE_PATH = Split-Path -Parent $MyInvocation.MyCommand.Definition +$RELEASE_VERSION = $Release +$PACKAGE_VERSION = node -pe "require('./package.json').version" +# Modern, relevant Node.js and Electron versions +# N-API provides forward compatibility, so we target major LTS versions. $node_versions = @( - "0.10.48", - "0.12.18", - "4.9.1", - "5.9.1", - "6.17.1", - "8.16.1", - "10.16.0", - "11.15.0", - "12.10.0" + "16.20.2", + "18.20.2", + "20.14.0", + "22.4.0" ) $electron_versions = @( - "1.2.8", - "1.3.8", - "1.4.6", - "1.7.12", - "2.0.18", - "3.1.13", - "4.2.10", - "5.0.10", - "6.0.7" + "28.3.3", + "29.4.0", + "30.1.0", + "31.2.1" ) # remove old build directory -Remove-Item -Recurse -Force $SOURCE_PATH'\..\build' -ErrorAction Ignore | Out-Null +Remove-Item -Recurse -Force "$SOURCE_PATH\..\build" -ErrorAction Ignore # create release path -New-Item $SOURCE_PATH'\..\releases\'$RELEASE_VERSION -ItemType Directory -ea 0 | Out-Null +New-Item "$SOURCE_PATH\..\releases\$RELEASE_VERSION" -ItemType Directory -ErrorAction SilentlyContinue | Out-Null foreach ($version in $node_versions) { Write-Output "Building for node version: $version..." - node-pre-gyp configure --target=$version --module_name=node_printer --silent | Out-Null - node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source --silent | Out-Null - node-pre-gyp configure --target=$version --module_name=node_printer --silent | Out-Null - node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source --silent | Out-Null - Copy-item -Force -Recurse $SOURCE_PATH'\..\build\stage\'$PACKAGE_VERSION\* -Destination $SOURCE_PATH'\..\releases\'$RELEASE_VERSION -ErrorAction Ignore | Out-Null - Remove-Item -Recurse -Force $SOURCE_PATH'\..\build\stage' | Out-Null + npx node-pre-gyp configure --target=$version --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source + Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" + Remove-Item -Recurse -Force "$SOURCE_PATH\..\build\stage" Write-Output "Done" } foreach ($version in $electron_versions) { Write-Output "Building for electron version: $version..." - node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=node_printer --silent | Out-Null - node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source --silent | Out-Null - node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=node_printer --silent | Out-Null - node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source --silent | Out-Null - Copy-item -Force -Recurse $SOURCE_PATH'\..\build\stage\'$PACKAGE_VERSION\* -Destination $SOURCE_PATH'\..\releases\'$RELEASE_VERSION -ErrorAction Ignore | Out-Null - Remove-Item -Recurse -Force $SOURCE_PATH'\..\build\stage' | Out-Null + npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source + npx node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source + Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" + Remove-Item -Recurse -Force "$SOURCE_PATH\..\build\stage" Write-Output "Done" } -Write-Output "Finished succesfully!" \ No newline at end of file +Write-Output "Finished successfully!" \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts index 1df34d1b..1a7180ca 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,34 +1,25 @@ export function getPrinters(): PrinterDetails[]; export function getPrinter(printerName: string): PrinterDetails; -export function getPrinterDriverOptions(printerName: string): PrinterDriverOptions; -export function getSelectedPaperSize(printerName: string): string; export function getDefaultPrinterName(): string | undefined; -export function printDirect(options: PrintDirectOptions): void; -export function printFile(options: PrintFileOptions): void; +export function printDirect(options: PrintDirectOptions): Promise; +export function printFile(options: PrintFileOptions): Promise; export function getSupportedPrintFormats(): string[]; -export function getJob(printerName: string, jobId: number): JobDetails; -export function setJob(printerName: string, jobId: number, command: 'CANCEL' | string): void; -export function getSupportedJobCommands(): string[]; export interface PrintDirectOptions { data: string | Buffer; printer?: string | undefined; + docname?: string | undefined; type?: 'RAW' | 'TEXT' | 'PDF' | 'JPEG' | 'POSTSCRIPT' | 'COMMAND' | 'AUTO' | undefined; options?: { [key: string]: string } | undefined; - success?: PrintOnSuccessFunction | undefined; - error?: PrintOnErrorFunction | undefined; } export interface PrintFileOptions { filename: string; printer?: string | undefined; - success?: PrintOnSuccessFunction | undefined; - error?: PrintOnErrorFunction | undefined; + docname?: string | undefined; + options?: { [key: string]: string } | undefined; } -export type PrintOnSuccessFunction = (jobId: string) => any; -export type PrintOnErrorFunction = (err: Error) => any; - export interface PrinterDetails { name: string; isDefault: boolean; From ee63384b4397555561805c7e98971919959f2d1f Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 02:40:02 +0530 Subject: [PATCH 02/18] WIP --- binding.js | 231 +++++++++++++++++++++++++++++++---------------- types/index.d.ts | 19 +++- 2 files changed, 168 insertions(+), 82 deletions(-) diff --git a/binding.js b/binding.js index 0d3f0862..5c4b5e34 100644 --- a/binding.js +++ b/binding.js @@ -20,44 +20,90 @@ module.exports.printFile = printFile; */ module.exports.getSupportedPrintFormats = addon.getSupportedPrintFormats; /* - * Print raw data to a printer. This function is asynchronous and returns a Promise. - * @param {object} options The print options. - * @param {Buffer|string} options.data The data to print. - * @param {string} [options.printer] The name of the printer. If not provided, the default printer is used. - * @param {string} [options.docname="node print job"] The name of the document as it appears in the print queue. - * @param {string} [options.type="RAW"] The data type (e.g., 'RAW', 'TEXT'). - * @param {object} [options.options={}] CUPS-specific options. - * @returns {Promise} A promise that resolves with the job ID. + print raw data. This function is intend to be asynchronous + + parameters: + parameters - Object, parameters objects with the following structure: + data - String, mandatory, data to printer + printer - String, optional, name of the printer, if missing, will try to print to default printer + docname - String, optional, name of document showed in printer status + type - String, optional, only for wind32, data type, one of the RAW, TEXT + options - JS object with CUPS options, optional + success - Function, optional, callback function + error - Function, optional, callback function if exists any error + + or + + data - String, mandatory, data to printer + printer - String, optional, name of the printer, if missing, will try to print to default printer + docname - String, optional, name of document showed in printer status + type - String, optional, data type, one of the RAW, TEXT + options - JS object with CUPS options, optional + success - Function, optional, callback function with first argument job_id + error - Function, optional, callback function if exists any error */ -async function printDirect(options) { - if (typeof options !== 'object' || options === null) { - throw new TypeError('An options object is required.'); + function printDirect(parameters){ + var data = parameters + , printer + , docname + , type + , options + , success + , error; + + if(arguments.length==1){ + //TODO: check parameters type + //if (typeof parameters ) + data = parameters.data; + printer = parameters.printer; + docname = parameters.docname; + type = parameters.type; + options = parameters.options||{}; + success = parameters.success; + error = parameters.error; + }else{ + printer = arguments[1]; + type = arguments[2]; + docname = arguments[3]; + options = arguments[4]; + success = arguments[5]; + error = arguments[6]; } - const { - data, - printer = addon.getDefaultPrinterName(), - docname = 'node print job', - type = 'RAW', - options: printerOptions = {} - } = options; + if(!type){ + type = "RAW"; + } - if (!data) { - throw new Error('A `data` field is required in the options object.'); + // Set default printer name + if(!printer) { + printer = addon.getDefaultPrinterName(); } - if (!printer) { - throw new Error('A `printer` name is required, or a default printer must be set.'); + type = type.toUpperCase(); + + if(!docname){ + docname = "node print job"; } - return new Promise((resolve, reject) => { - try { - const jobId = addon.printDirect(data, printer, docname, type.toUpperCase(), printerOptions); - resolve(jobId); - } catch (e) { - reject(e); + if (!options){ + options = {}; + } + + //TODO: check parameters type + if(addon.printDirect){// call C++ binding + try{ + var res = addon.printDirect(data, printer, docname, type, options); + if(res){ + success(res); + }else{ + error(Error("Something wrong in printDirect")); + } + }catch (e){ + error(e); } - }); + }else{ + error("Not supported"); + } } /** Get printer info with jobs @@ -65,39 +111,38 @@ async function printDirect(options) { * @return printer object info: * TODO: to enum all possible attributes */ -function getPrinter(printerName) { - const targetPrinterName = printerName || addon.getDefaultPrinterName(); - if (!targetPrinterName) { - return undefined; - } - - const printer = addon.getPrinter(targetPrinterName); - if (printer) { - correctPrinterinfo(printer); - } - return printer; -} + function getPrinter(printerName) + { + if(!printerName) { + printerName = addon.getDefaultPrinterName(); + } + var printer = addon.getPrinter(printerName); + correctPrinterinfo(printer); + return printer; + } function correctPrinterinfo(printer) { - if (!printer || printer.status || !printer.options || !printer.options['printer-state']) { + if(printer.status || !printer.options || !printer.options['printer-state']){ return; } var status = printer.options['printer-state']; // Add posix status - if (status == '3') { + if(status == '3'){ status = 'IDLE' - } else if (status == '4') { + } + else if(status == '4'){ status = 'PRINTING' - } else if (status == '5') { + } + else if(status == '5'){ status = 'STOPPED' } // correct date type var k; - for (k in printer.options) { - if (/time$/.test(k) && printer.options[k] && !(printer.options[k] instanceof Date)) { + for(k in printer.options) { + if(/time$/.test(k) && printer.options[k] && !(printer.options[k] instanceof Date)) { printer.options[k] = new Date(printer.options[k] * 1000); } } @@ -106,45 +151,77 @@ function correctPrinterinfo(printer) { } /** - * Print a file to a printer. This function is asynchronous and returns a Promise. - * Note: This function is only supported on POSIX platforms (macOS, Linux). - * @param {object} options The print options. - * @param {string} options.filename The path to the file to be printed. - * @param {string} [options.printer] The name of the printer. If not provided, the default printer is used. - * @param {string} [options.docname] The name of the document. Defaults to the filename. - * @param {object} [options.options={}] CUPS-specific options. - * @returns {Promise} A promise that resolves with the job ID. - */ -async function printFile(options) { - if (typeof options !== 'object' || options === null) { - throw new TypeError('An options object is required.'); +parameters: + parameters - Object, parameters objects with the following structure: + filename - String, mandatory, data to printer + docname - String, optional, name of document showed in printer status + printer - String, optional, mane of the printer, if missed, will try to retrieve the default printer name + success - Function, optional, callback function + error - Function, optional, callback function if exists any error +*/ +function printFile(parameters){ + var filename, + docname, + printer, + options, + success, + error; + + if((arguments.length !== 1) || (typeof(parameters) !== 'object')){ + throw new Error('must provide arguments object'); + } + + filename = parameters.filename; + docname = parameters.docname; + printer = parameters.printer; + options = parameters.options || {}; + success = parameters.success; + error = parameters.error; + + if(!success){ + success = function(){}; } - if (!addon.printFile) { - throw new Error('`printFile` is not supported on this platform (Windows).'); + if(!error){ + error = function(err){ + throw err; + }; } - const { - filename, - printer = addon.getDefaultPrinterName(), - docname = filename, - options: printerOptions = {} - } = options; + if(!filename){ + var err = new Error('must provide at least a filename'); + return error(err); + } - if (!filename) { - throw new Error('A `filename` is required in the options object.'); + // try to define default printer name + if(!printer) { + printer = addon.getDefaultPrinterName(); } - if (!printer) { - throw new Error('A `printer` name is required, or a default printer must be set.'); + if(!printer) { + return error(new Error('Printer parameter of default printer is not defined')); } - return new Promise((resolve, reject) => { - try { - const jobId = addon.printFile(filename, docname, printer, printerOptions); - resolve(jobId); + // set filename if docname is missing + if(!docname){ + docname = filename; + } + + //TODO: check parameters type + if(addon.printFile){// call C++ binding + try{ + // TODO: proper success/error callbacks from the extension + var res = addon.printFile(filename, docname, printer, options); + + if(!isNaN(parseInt(res))) { + success(res); + } else { + error(Error(res)); + } } catch (e) { - reject(e); + error(e); } - }); + } else { + error("Not supported"); + } } diff --git a/types/index.d.ts b/types/index.d.ts index 1a7180ca..1df34d1b 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,25 +1,34 @@ export function getPrinters(): PrinterDetails[]; export function getPrinter(printerName: string): PrinterDetails; +export function getPrinterDriverOptions(printerName: string): PrinterDriverOptions; +export function getSelectedPaperSize(printerName: string): string; export function getDefaultPrinterName(): string | undefined; -export function printDirect(options: PrintDirectOptions): Promise; -export function printFile(options: PrintFileOptions): Promise; +export function printDirect(options: PrintDirectOptions): void; +export function printFile(options: PrintFileOptions): void; export function getSupportedPrintFormats(): string[]; +export function getJob(printerName: string, jobId: number): JobDetails; +export function setJob(printerName: string, jobId: number, command: 'CANCEL' | string): void; +export function getSupportedJobCommands(): string[]; export interface PrintDirectOptions { data: string | Buffer; printer?: string | undefined; - docname?: string | undefined; type?: 'RAW' | 'TEXT' | 'PDF' | 'JPEG' | 'POSTSCRIPT' | 'COMMAND' | 'AUTO' | undefined; options?: { [key: string]: string } | undefined; + success?: PrintOnSuccessFunction | undefined; + error?: PrintOnErrorFunction | undefined; } export interface PrintFileOptions { filename: string; printer?: string | undefined; - docname?: string | undefined; - options?: { [key: string]: string } | undefined; + success?: PrintOnSuccessFunction | undefined; + error?: PrintOnErrorFunction | undefined; } +export type PrintOnSuccessFunction = (jobId: string) => any; +export type PrintOnErrorFunction = (err: Error) => any; + export interface PrinterDetails { name: string; isDefault: boolean; From 487f5bfb443e89f901182746440d4a1753e83324 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 04:38:25 +0530 Subject: [PATCH 03/18] WIP - Working for Mac --- .github/workflows/prebuild-pr.yml | 0 README.md | 24 +- binding.gyp | 6 +- binding.js | 227 ------------------ lib/index.js | 161 +++++++++++++ src/node_printer_posix.cc | 28 ++- test/detection.test.js | 57 +++++ test/printDirect.test.js | 75 +++--- .../printing.test.js | 0 types/index.d.ts | 19 +- 10 files changed, 319 insertions(+), 278 deletions(-) delete mode 100644 .github/workflows/prebuild-pr.yml create mode 100644 lib/index.js create mode 100644 test/detection.test.js rename .github/workflows/prebuild-main.yml => test/printing.test.js (100%) diff --git a/.github/workflows/prebuild-pr.yml b/.github/workflows/prebuild-pr.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/README.md b/README.md index ffd35f71..880aa441 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **No recompilation required when upgrading Node.js versions, thanks to N-API!** 🎉 -Native bind printers on POSIX and Windows OS from Node.js, Electron, and node-webkit. +Native bind printers on Windows OS, Nac OS and Linux from Node.js, Electron, and node-webkit. [![npm version](https://badge.fury.io/js/%40addble%2Felectron-printer.svg)](https://badge.fury.io/js/%40addble%2Felectron-printer) [![CI & Prebuilds](https://github.com/addble/electron-printer/actions/workflows/ci.yml/badge.svg)](https://github.com/addble/electron-printer/actions/workflows/ci.yml) @@ -13,6 +13,23 @@ Native bind printers on POSIX and Windows OS from Node.js, Electron, and node-we If you have a problem, please find or create a new [GitHub issue](https://github.com/addble/electron-printer/issues). +### Supported Features + +* No dependencies on NAN or V8; +* Native method wrappers for Windows and POSIX (which uses CUPS 1.4/MAC OS X 10.6) APIs; +* Compatible with Node.js versions that support N-API, ensuring long-term stability and compatibility; +* Compatible with Electron versions that support N-API, reducing the need for frequent recompilation; +* `getPrinters()` to enumerate all installed printers with current jobs and statuses; +* `getPrinter(printerName)` to get info for a specific printer; +* `getDefaultPrinterName()` returns the default printer name; +* `printDirect(options)` to send raw data to a printer. Returns a Promise. +* `printFile(options)` to print a file (POSIX only, e.g., macOS, Linux). Returns a Promise. +* `getSupportedPrintFormats()` to get supported data formats like 'RAW' and 'TEXT'. + +### How to install: +``` +npm install @addble/electron-printer + ___ ### **Below is the original README** ___ @@ -30,7 +47,6 @@ I was involved in a project where I needed to print from Node.js. This is the re * `getPrinter(printerName)` to get a specific/default printer info with current jobs and statuses; * `getPrinterDriverOptions(printerName)` (POSIX only) to get a specific/default printer driver options such as supported paper size and other info; * `getSelectedPaperSize(printerName)` (POSIX only) to get a specific/default printer default paper size from its driver options; -* `getDefaultPrinterName()` returns the default printer name; * `printDirect(options)` to send a job to a specific/default printer, now supports CUPS options passed in the form of a JS object (see `cancelJob.js` example). To print a PDF from Windows, it is possible by using node-pdfium module to convert a PDF format into EMF and then send it to the printer as EMF; * `printFile(options)` (POSIX only) to print a file; * `getSupportedPrintFormats()` to get all possible print formats for the `printDirect` method, which depends on the OS. `RAW` and `TEXT` are supported on all OSes; @@ -38,9 +54,7 @@ I was involved in a project where I needed to print from Node.js. This is the re * `setJob(printerName, jobId, command)` to send a command to a job (e.g., `'CANCEL'` to cancel the job); * `getSupportedJobCommands()` to get supported job commands for `setJob()`, depending on the OS. The `'CANCEL'` command is supported on all OSes. -### How to install: -``` -npm install @thesusheer/electron-printer + ``` ### How to use: diff --git a/binding.gyp b/binding.gyp index ff85a917..3038d940 100644 --- a/binding.gyp +++ b/binding.gyp @@ -25,10 +25,14 @@ ['OS=="win"', { 'sources': [ 'src/node_printer_win.cc' ], }], - ['OS=="mac" or OS=="linux"', { + ['OS=="mac"', { 'sources': [ 'src/node_printer_posix.cc' ], 'link_settings': { 'libraries': [ '-lcups' ] } }], + ['OS=="linux"', { + 'sources': [ 'src/node_printer_posix.cc' ], + 'link_settings': { 'libraries': [ '-lcups' ] } + }] ], 'include_dirs': ["} A promise that resolves with the job ID. + */ +async function printDirect(options) { + if (typeof options !== 'object' || options === null) { + throw new TypeError('An options object is required.'); + } + + // Explicitly extract and validate parameters to provide better error messages + // and prevent invalid types from reaching the C++ addon. + const data = options.data; + const printer = options.printer || addon.getDefaultPrinterName(); + const docname = options.docname || 'node print job'; + const type = options.type || 'RAW'; + const printerOptions = options.options || {}; + + if (!data) { + throw new Error('A `data` field is required in the options object.'); + } + + if (!printer || typeof printer !== 'string') { + throw new Error('A `printer` name is required, or a default printer must be set.'); + } + + if (typeof docname !== 'string') { + throw new TypeError('The `docname` option, if provided, must be a string.'); + } + + if (typeof type !== 'string') { + throw new TypeError('The `type` option, if provided, must be a string.'); + } + + return new Promise((resolve, reject) => { + try { + const jobId = addon.printDirect(data, printer, docname, type.toUpperCase(), printerOptions); + resolve(jobId); + } catch (e) { + reject(e); + } + }); +} + +/** Get printer info with jobs + * @param printerName printer name to extract the info + * @return printer object info: + * TODO: to enum all possible attributes + */ +function getPrinter(printerName) { + const targetPrinterName = printerName || addon.getDefaultPrinterName(); + if (!targetPrinterName) { + return undefined; + } + + const printer = addon.getPrinter(targetPrinterName); + if (printer) { + correctPrinterinfo(printer); + } + return printer; +} + + +function correctPrinterinfo(printer) { + if (!printer || printer.status || !printer.options || !printer.options['printer-state']) { + return; + } + + var status = printer.options['printer-state']; + // Add posix status + if (status == '3') { + status = 'IDLE' + } else if (status == '4') { + status = 'PRINTING' + } else if (status == '5') { + status = 'STOPPED' + } + + // correct date type + var k; + for (k in printer.options) { + if (/time$/.test(k) && printer.options[k] && !(printer.options[k] instanceof Date)) { + printer.options[k] = new Date(printer.options[k] * 1000); + } + } + + printer.status = status; +} + +/** + * Print a file to a printer. This function is asynchronous and returns a Promise. + * Note: This function is only supported on POSIX platforms (macOS, Linux). + * @param {object} options The print options. + * @param {string} options.filename The path to the file to be printed. + * @param {string} [options.printer] The name of the printer. If not provided, the default printer is used. + * @param {string} [options.docname] The name of the document. Defaults to the filename. + * @param {object} [options.options={}] CUPS-specific options. + * @returns {Promise} A promise that resolves with the job ID. + */ +async function printFile(options) { + if (typeof options !== 'object' || options === null) { + throw new TypeError('An options object is required.'); + } + + if (!addon.printFile) { + throw new Error('`printFile` is not supported on this platform (Windows).'); + } + + const filename = options.filename; + const printer = options.printer || addon.getDefaultPrinterName(); + // Default docname to filename if it's not provided or is null/empty + const docname = options.docname || filename; + const printerOptions = options.options || {}; + + if (!filename) { + throw new Error('A `filename` is required in the options object.'); + } + + if (!printer || typeof printer !== 'string') { + throw new Error('A `printer` name is required, or a default printer must be set.'); + } + + if (typeof docname !== 'string') { + throw new TypeError('The `docname` option, if provided, must be a string.'); + } + + return new Promise((resolve, reject) => { + try { + const jobId = addon.printFile(filename, docname, printer, printerOptions); + resolve(jobId); + } catch (e) { + reject(e); + } + }); +} \ No newline at end of file diff --git a/src/node_printer_posix.cc b/src/node_printer_posix.cc index c534c6a9..f55303a7 100644 --- a/src/node_printer_posix.cc +++ b/src/node_printer_posix.cc @@ -91,10 +91,32 @@ MY_NODE_MODULE_CALLBACK(getPrinters) MY_NODE_MODULE_CALLBACK(getDefaultPrinterName) { MY_NODE_MODULE_HANDLESCOPE; - const char* default_printer = cupsGetDefault2(NULL); - if (default_printer) { - MY_NODE_MODULE_RETURN_VALUE(Napi::String::New(env, default_printer)); + + // Using cupsGetDests is a more modern and reliable way to find the default printer, + // especially on newer versions of macOS where cupsGetDefault might be deprecated or behave differently. + cups_dest_t *dests; + int num_dests = cupsGetDests(&dests); + const char* default_printer_name = NULL; + + if (num_dests > 0) { + for (int i = 0; i < num_dests; i++) { + if (dests[i].is_default) { + default_printer_name = dests[i].name; + break; // Found it + } + } } + + if (default_printer_name) { + Napi::String result = Napi::String::New(env, default_printer_name); + cupsFreeDests(num_dests, dests); // Free the memory allocated by cupsGetDests + MY_NODE_MODULE_RETURN_VALUE(result); + } + + if (num_dests > 0) { + cupsFreeDests(num_dests, dests); + } + MY_NODE_MODULE_RETURN_VALUE(Napi::String::New(env, "")); } diff --git a/test/detection.test.js b/test/detection.test.js new file mode 100644 index 00000000..0d80b263 --- /dev/null +++ b/test/detection.test.js @@ -0,0 +1,57 @@ +const assert = require('assert/strict'); +const { test, describe, beforeEach } = require('node:test'); + +let printer; + +beforeEach(() => { + // This loads the actual native addon + printer = require('../lib'); +}); + +describe('Printer Detection Integration Tests', () => { + test('getPrinters should return an array of printers', (t) => { + const printers = printer.getPrinters(); + + assert.ok(Array.isArray(printers), 'getPrinters() should return an array.'); + console.log(`Found ${printers.length} printers.`); + + if (printers.length > 0) { + console.log('List of detected printers:'); + printers.forEach(p => { + console.log(`- ${p.name}`); + assert.strictEqual(typeof p.name, 'string', 'Each printer should have a name property of type string.'); + }); + } + }); + + test('getDefaultPrinterName should return a string or undefined', (t) => { + const defaultPrinterName = printer.getDefaultPrinterName(); + + assert.ok( + typeof defaultPrinterName === 'string' || typeof defaultPrinterName === 'undefined', + 'getDefaultPrinterName() should return a string or undefined.' + ); + + if (typeof defaultPrinterName === 'string' && defaultPrinterName.length > 0) { + console.log(`Default printer is: "${defaultPrinterName}"`); + } else { + console.log('No default printer is configured on this system.'); + } + }); + + test('getPrinter should return details for a specific printer', (t) => { + const printers = printer.getPrinters(); + if (printers.length === 0) { + t.skip('Skipping test: No printers are installed on this system.'); + return; + } + + const printerToTest = printers[0].name; + console.log(`Testing getPrinter with: "${printerToTest}"`); + const details = printer.getPrinter(printerToTest); + + assert.ok(details, 'getPrinter should return an object for an existing printer.'); + assert.strictEqual(typeof details, 'object', 'getPrinter should return an object.'); + assert.strictEqual(details.name, printerToTest, 'The returned printer details should have the correct name.'); + }); +}); \ No newline at end of file diff --git a/test/printDirect.test.js b/test/printDirect.test.js index 624e67fa..aadeb800 100644 --- a/test/printDirect.test.js +++ b/test/printDirect.test.js @@ -1,34 +1,53 @@ +const test = require('node:test'); const assert = require('assert/strict'); -const { test, beforeEach } = require('node:test'); +const path = require('node:path'); -let addon; -let template; -beforeEach(() => { - addon = require('../lib'); - template = "N\nS4\nD15\nq400\nR\nB20,10,0,1,2,30,173,B,\"barcode\"\nP0\n"; -}); +// This is the mock of our C++ addon. +// We can control its behavior for different test cases. +const mockAddon = { + printDirect: (data, printer, docname, type, options) => { + if (printer === 'FAIL') { + throw new Error('Printer not found'); + } + return 123; // Return a mock job ID on success + }, + getDefaultPrinterName: () => 'DefaultPrinter', + // Mock other addon functions as needed for more tests + getPrinters: () => [], + getPrinter: (name) => ({ name, isDefault: false }), + getSupportedPrintFormats: () => ['RAW', 'TEXT'], + printFile: () => 456, + SayMyName: () => 'Hello, From C++ !', +}; -test('Ensure printDirect function exists', (t) => { - assert.ok(addon.printDirect, 'printDirect function should exist'); - assert.strictEqual(typeof addon.printDirect, 'function', 'printDirect should be a function'); -}); +// This is the key part for mocking. We intercept Node's `require` mechanism. +// When `lib/index.js` tries to load the compiled `.node` file, we give it our mock object instead. +const addonPath1 = path.resolve(__dirname, '../lib/electron-printer.node'); +const addonPath2 = path.resolve(__dirname, '../build/Release/electron-printer.node'); +require('module')._cache[addonPath1] = { exports: mockAddon }; +require('module')._cache[addonPath2] = { exports: mockAddon }; -test('Ensure printDirect throws error when no arguments are passed', (t) => { - assert.throws(() => { - addon.printDirect(); - }, /Error/, 'printDirect should throw an error when no arguments are passed'); -}); +// Now that the mock is in place, we can safely require the main library file. +const printer = require('../lib'); -test('Ensure printDirect works properly', (t) => { - let barcode_text = "123"; - let printer_name = addon.getDefaultPrinterName(); - addon.printDirect({ - data:template.replace(/barcode/, barcode_text) - , printer:printer_name - , type: "RAW" - , success:function(){ - console.log("printed: "+barcode_text); - } - , error:function(err){console.log(err);} - }); +test.describe('Printing Tests with Mock', () => { + test('should print successfully with printDirect', async () => { + const jobId = await printer.printDirect({ data: 'test data' }); + assert.strictEqual(jobId, 123, 'The job ID should be the one returned by the mock addon'); + }); + + test('should reject with an error if the native call fails', async () => { + await assert.rejects( + () => printer.printDirect({ data: 'test data', printer: 'FAIL' }), + { message: 'Printer not found' }, + 'Should reject when the mock addon throws an error' + ); + }); + + test('should throw a TypeError if options are not provided', async () => { + await assert.rejects( + () => printer.printDirect(), + new TypeError('An options object is required.') + ); + }); }); \ No newline at end of file diff --git a/.github/workflows/prebuild-main.yml b/test/printing.test.js similarity index 100% rename from .github/workflows/prebuild-main.yml rename to test/printing.test.js diff --git a/types/index.d.ts b/types/index.d.ts index 1df34d1b..1a7180ca 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,34 +1,25 @@ export function getPrinters(): PrinterDetails[]; export function getPrinter(printerName: string): PrinterDetails; -export function getPrinterDriverOptions(printerName: string): PrinterDriverOptions; -export function getSelectedPaperSize(printerName: string): string; export function getDefaultPrinterName(): string | undefined; -export function printDirect(options: PrintDirectOptions): void; -export function printFile(options: PrintFileOptions): void; +export function printDirect(options: PrintDirectOptions): Promise; +export function printFile(options: PrintFileOptions): Promise; export function getSupportedPrintFormats(): string[]; -export function getJob(printerName: string, jobId: number): JobDetails; -export function setJob(printerName: string, jobId: number, command: 'CANCEL' | string): void; -export function getSupportedJobCommands(): string[]; export interface PrintDirectOptions { data: string | Buffer; printer?: string | undefined; + docname?: string | undefined; type?: 'RAW' | 'TEXT' | 'PDF' | 'JPEG' | 'POSTSCRIPT' | 'COMMAND' | 'AUTO' | undefined; options?: { [key: string]: string } | undefined; - success?: PrintOnSuccessFunction | undefined; - error?: PrintOnErrorFunction | undefined; } export interface PrintFileOptions { filename: string; printer?: string | undefined; - success?: PrintOnSuccessFunction | undefined; - error?: PrintOnErrorFunction | undefined; + docname?: string | undefined; + options?: { [key: string]: string } | undefined; } -export type PrintOnSuccessFunction = (jobId: string) => any; -export type PrintOnErrorFunction = (err: Error) => any; - export interface PrinterDetails { name: string; isDefault: boolean; From 66936b68bf792d697c741c44bea2f58382ad0055 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:01:28 +0530 Subject: [PATCH 04/18] Added support Mac, Windows ARM, and Linux. Code improvements and upgrades. --- .github/workflows/ci.yml | 9 +++++++++ README.md | 7 ++++++- binding.js | 0 package.json | 2 +- tools/buildElectronLinux.sh | 25 +++++++++++++++++++++-- tools/buildElectronWindows.ps1 | 6 +++++- tools/generateReleaseBuildsLinux.sh | 28 ++++++++++++++++---------- tools/generateReleaseBuildsWindows.ps1 | 26 +++++++++++++++--------- 8 files changed, 77 insertions(+), 26 deletions(-) delete mode 100644 binding.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 691c86d7..b131a437 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,12 @@ jobs: sudo apt-get update -y -qq sudo apt-get install -y g++-multilib gcc-multilib libcups2-dev libcups2-dev:i386 libc6-dev-i386 linux-libc-dev linux-libc-dev:i386 + - name: Set up QEMU for ARM builds + if: runner.os == 'Linux' + uses: docker/setup-qemu-action@v3 + with: + platforms: arm,arm64 + - name: Install dependencies run: npm install @@ -41,6 +47,8 @@ jobs: run: | npm run prebuild -- --strip --all --arch ia32 npm run prebuild -- --strip --all --arch x64 + npm run prebuild -- --strip --all --arch arm + npm run prebuild -- --strip --all --arch arm64 - name: Build for macOS if: runner.os == 'macOS' @@ -53,6 +61,7 @@ jobs: run: | npm run prebuild -- --strip --all --arch ia32 npm run prebuild -- --strip --all --arch x64 + npm run prebuild -- --strip --all --arch arm64 - name: Upload prebuilds artifact uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index 880aa441..9dff87fc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,12 @@ **No recompilation required when upgrading Node.js versions, thanks to N-API!** 🎉 -Native bind printers on Windows OS, Nac OS and Linux from Node.js, Electron, and node-webkit. +Native bind printers on Windows, Mac OS, and Linux from Node.js, Electron, and node-webkit. +Supports following architectures: +* Windows - ia32, x64, arm64 +* Mac - x64 & arm64 (Apple Silicon) +* Linux - ia32, x64, arm7l, arm64 + [![npm version](https://badge.fury.io/js/%40addble%2Felectron-printer.svg)](https://badge.fury.io/js/%40addble%2Felectron-printer) [![CI & Prebuilds](https://github.com/addble/electron-printer/actions/workflows/ci.yml/badge.svg)](https://github.com/addble/electron-printer/actions/workflows/ci.yml) diff --git a/binding.js b/binding.js deleted file mode 100644 index e69de29b..00000000 diff --git a/package.json b/package.json index 636ba674..69b2b372 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@addble/electron-printer", "description": "Node API (N-API) supported electron.s || node.js printer bindings", "homepage": "https://github.com/addble/electron-printer", - "version": "3.0.0", + "version": "3.0.0-RC1", "main": "./lib/index.js", "types": "types/index.d.ts", "dependencies": { diff --git a/tools/buildElectronLinux.sh b/tools/buildElectronLinux.sh index ba8ba448..06b1b0cb 100755 --- a/tools/buildElectronLinux.sh +++ b/tools/buildElectronLinux.sh @@ -1,10 +1,31 @@ #!/bin/bash +set -e + VERSION=$1 -# # Build Electron Linux 64bit +if [ -z "$VERSION" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Build Electron Linux 64bit (x64) +echo "Building for Electron $VERSION on Linux x64..." node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=x64 --build-from-source -# #Build Electron Linux 32bit +# Build Electron Linux 32bit (ia32) +echo "Building for Electron $VERSION on Linux ia32..." node-pre-gyp configure --target=$VERSION --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=ia32 --build-from-source + +# Build Electron Linux ARM 32bit (armv7l) for Raspberry Pi 2/3/4 (32-bit OS) +echo "Building for Electron $VERSION on Linux arm..." +node-pre-gyp configure --target=$VERSION --arch=arm --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm --build-from-source + +# Build Electron Linux ARM 64bit (arm64) for Raspberry Pi 3/4/5 (64-bit OS) +echo "Building for Electron $VERSION on Linux arm64..." +node-pre-gyp configure --target=$VERSION --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm64 --build-from-source + +echo "Done." diff --git a/tools/buildElectronWindows.ps1 b/tools/buildElectronWindows.ps1 index 6472fc9c..2874db9b 100644 --- a/tools/buildElectronWindows.ps1 +++ b/tools/buildElectronWindows.ps1 @@ -12,7 +12,7 @@ param ( # Stop script on first error $ErrorActionPreference = "Stop" -Write-Host "Building Electron Version -> $Version for x64 and ia32" +Write-Host "Building Electron Version -> $Version for x64, ia32, and arm64" # Build Electron Windows 64bit Write-Host "Building for x64..." @@ -24,4 +24,8 @@ Write-Host "Building for ia32..." npx node-pre-gyp configure --target=$Version --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=ia32 --build-from-source +Write-Host "Building for arm64..." +npx node-pre-gyp configure --target=$Version --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ +npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=arm64 --build-from-source + Write-Host "Done." \ No newline at end of file diff --git a/tools/generateReleaseBuildsLinux.sh b/tools/generateReleaseBuildsLinux.sh index 233612ce..013db589 100755 --- a/tools/generateReleaseBuildsLinux.sh +++ b/tools/generateReleaseBuildsLinux.sh @@ -3,7 +3,7 @@ set -e # Exit immediately if a command exits with a non-zero status. if [ -z "$1" ]; then echo "Usage: $0 " - echo "e.g.: $0 2.0.5" + echo "e.g.: $0 3.0.0" exit 1 fi @@ -27,6 +27,8 @@ declare -a electron_versions=( "31.2.1" ) +declare -a linux_archs=("x64" "ia32" "arm" "arm64") + # remove old build directory rm -rf "$SOURCE_PATH/build" @@ -34,21 +36,25 @@ rm -rf "$SOURCE_PATH/build" mkdir -p "$SOURCE_PATH/releases/$RELEASE_VERSION" for version in "${node_versions[@]}"; do - echo "Building for Node.js version: $version..." - npx node-pre-gyp configure --target=$version --module_name=electron-printer - npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source - npx node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source + echo "Building for Node.js version: $version" + for arch in "${linux_archs[@]}"; do + echo " Building for arch: $arch..." + npx node-pre-gyp configure --target=$version --arch=$arch --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=$arch --build-from-source + done rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files - echo "Done" + echo "Done building for Node.js $version" done for version in "${electron_versions[@]}"; do - echo "Building for electron version: $version..." - npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer - npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source - npx node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source + echo "Building for Electron version: $version" + for arch in "${linux_archs[@]}"; do + echo " Building for arch: $arch..." + npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=$arch --runtime=electron --build-from-source + done rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files - echo "Done" + echo "Done building for Electron $version" done echo "Finished successfully!" diff --git a/tools/generateReleaseBuildsWindows.ps1 b/tools/generateReleaseBuildsWindows.ps1 index b80d421e..8b54c39a 100644 --- a/tools/generateReleaseBuildsWindows.ps1 +++ b/tools/generateReleaseBuildsWindows.ps1 @@ -31,6 +31,8 @@ $electron_versions = @( "31.2.1" ) +$windows_archs = @("x64", "ia32", "arm64") + # remove old build directory Remove-Item -Recurse -Force "$SOURCE_PATH\..\build" -ErrorAction Ignore @@ -38,23 +40,27 @@ Remove-Item -Recurse -Force "$SOURCE_PATH\..\build" -ErrorAction Ignore New-Item "$SOURCE_PATH\..\releases\$RELEASE_VERSION" -ItemType Directory -ErrorAction SilentlyContinue | Out-Null foreach ($version in $node_versions) { - Write-Output "Building for node version: $version..." - npx node-pre-gyp configure --target=$version --module_name=electron-printer - npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source - npx node-pre-gyp build package --target=$version --target_arch=ia32 --build-from-source + Write-Output "Building for node version: $version" + foreach ($arch in $windows_archs) { + Write-Output " Building for arch: $arch..." + npx node-pre-gyp configure --target=$version --arch=$arch --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=$arch --build-from-source + } Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" Remove-Item -Recurse -Force "$SOURCE_PATH\..\build\stage" - Write-Output "Done" + Write-Output "Done building for Node.js $version" } foreach ($version in $electron_versions) { - Write-Output "Building for electron version: $version..." - npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer - npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source - npx node-pre-gyp build package --target=$version --target_arch=ia32 --runtime=electron --build-from-source + Write-Output "Building for Electron version: $version" + foreach ($arch in $windows_archs) { + Write-Output " Building for arch: $arch..." + npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp build package --target=$version --target_arch=$arch --runtime=electron --build-from-source + } Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" Remove-Item -Recurse -Force "$SOURCE_PATH\..\build\stage" - Write-Output "Done" + Write-Output "Done building for Electron $version" } Write-Output "Finished successfully!" \ No newline at end of file From 5670e12bfabada9e0b45994ceb440a8259313912 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:04:48 +0530 Subject: [PATCH 05/18] Updated readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9dff87fc..a94bcad4 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ See examples * Thiago Lugli, @thiagoelg * Eko Eryanto, @ekoeryanto * Sudheer Gupta, @susheer +* Yaikhomba Ningthemcha, @yaikhomba ### Project History: @@ -108,5 +109,8 @@ This project is licensed under the MIT License. * CUPS printer * print job * printer driver +* Mac OS printer +* Raspberry PI printer + --- \ No newline at end of file From 2c02f892a29e8be4f08372717837dc78213c3999 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:13:17 +0530 Subject: [PATCH 06/18] Updated nodejs version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b131a437..0dcf44b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '18.x' cache: 'npm' - name: Install Linux dependencies @@ -80,7 +80,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '18.x' - name: Install dependencies run: npm install - name: Download all artifacts From 65a8757cad496424096d8d61247c08ef5002f400 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:18:16 +0530 Subject: [PATCH 07/18] Added updates --- .github/workflows/ci.yml | 4 ++-- index.js | 1 - package.json | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0dcf44b1..b131a437 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18.x' + node-version: '20.x' cache: 'npm' - name: Install Linux dependencies @@ -80,7 +80,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18.x' + node-version: '20.x' - name: Install dependencies run: npm install - name: Download all artifacts diff --git a/index.js b/index.js index 8e1ce20d..e69de29b 100644 --- a/index.js +++ b/index.js @@ -1 +0,0 @@ -module.exports = require('./binding'); \ No newline at end of file diff --git a/package.json b/package.json index 69b2b372..0038673e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "install": "node-pre-gyp install --fallback-to-build", "rebuild": "node-gyp rebuild", - "prebuild": "node-pre-gyp prebuild --strip --all", + "prebuild": "node-pre-gyp prebuild", "release": "node-pre-gyp-github publish --release", "test": "node --test test/" }, @@ -43,6 +43,6 @@ ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "node-pre-gyp-github": "github:Susheer/node-pre-gyp-github" + "@mapbox/node-pre-gyp-github": "^1.5.0" } } From 56d1286cee4310f247967c41d7bcb2b85fab5f7d Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:18:51 +0530 Subject: [PATCH 08/18] Added updates --- index.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 index.js diff --git a/index.js b/index.js deleted file mode 100644 index e69de29b..00000000 From a98c41a8e2175bb37cdfa9befc3389290b0a0a30 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:22:01 +0530 Subject: [PATCH 09/18] Updated package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0038673e..58b1e106 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,6 @@ ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "@mapbox/node-pre-gyp-github": "^1.5.0" + "@prebuild/node-pre-gyp-github": "^2.0.0" } } From bdcf5642eb10869670a9037e764c1b3851bb003c Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:26:49 +0530 Subject: [PATCH 10/18] Updated dev dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58b1e106..20135a42 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,6 @@ ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "@prebuild/node-pre-gyp-github": "^2.0.0" + "node-pre-gyp-github": "^2.0.0" } } From a8464e28c1bc0007014be9bb99b75b7b0f00fbd8 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 05:30:37 +0530 Subject: [PATCH 11/18] Updated node verion for CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b131a437..0dcf44b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '18.x' cache: 'npm' - name: Install Linux dependencies @@ -80,7 +80,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '18.x' - name: Install dependencies run: npm install - name: Download all artifacts From 2ccaedd96c85cd4d4784e1175be361741b419ee0 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 15:23:42 +0530 Subject: [PATCH 12/18] Renamed package to node-printer --- README.md | 5 +++-- binding.gyp | 2 +- lib/index.js | 4 ++-- package.json | 6 +++--- tools/buildElectronLinux.sh | 24 ++++++------------------ tools/buildElectronMac.sh | 14 ++++++-------- tools/buildElectronWindows.ps1 | 20 +++++++------------- tools/generateReleaseBuildsLinux.sh | 4 ++-- tools/generateReleaseBuildsMac.sh | 4 ++-- tools/generateReleaseBuildsWindows.ps1 | 4 ++-- 10 files changed, 34 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index a94bcad4..23f5fdb9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# @addble/electron-printer +# @addble/node-printer **No recompilation required when upgrading Node.js versions, thanks to N-API!** 🎉 @@ -9,7 +9,7 @@ Supports following architectures: * Linux - ia32, x64, arm7l, arm64 -[![npm version](https://badge.fury.io/js/%40addble%2Felectron-printer.svg)](https://badge.fury.io/js/%40addble%2Felectron-printer) +[![npm version](https://badge.fury.io/js/%40addble%2Fnode-printer.svg)](https://badge.fury.io/js/%40addble%2Fnode-printer) [![CI & Prebuilds](https://github.com/addble/electron-printer/actions/workflows/ci.yml/badge.svg)](https://github.com/addble/electron-printer/actions/workflows/ci.yml) > Supports Node.js versions from 8.0.0 onwards, including the latest versions, thanks to the transition to N-API. @@ -101,6 +101,7 @@ This project is licensed under the MIT License. ### Keywords: * node-printer +* nodejs-printer * printer * electron-printer * node-addon-api diff --git a/binding.gyp b/binding.gyp index 3038d940..da6a663a 100644 --- a/binding.gyp +++ b/binding.gyp @@ -1,6 +1,6 @@ { 'variables': { - 'module_name%': 'electron-printer', + 'module_name%': 'node-printer', 'module_path%': 'lib' }, 'targets': [ diff --git a/lib/index.js b/lib/index.js index 4fd81b8d..9c58c436 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,10 +3,10 @@ let addon; try { // This will load the addon built by `node-gyp build` and copied by the `action_after_build` target in binding.gyp. - addon = require(path.join(__dirname, 'electron-printer.node')); + addon = require(path.join(__dirname, 'node-printer.node')); } catch (err) { // Fallback for development, e.g. when `action_after_build` hasn't run or when using prebuild-install which might place it elsewhere. - addon = require('../build/Release/electron-printer.node'); + addon = require('../build/Release/node-printer.node'); } module.exports.sayMyName = addon.SayMyName diff --git a/package.json b/package.json index 20135a42..a53ce15c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@addble/electron-printer", + "name": "@addble/node-printer", "description": "Node API (N-API) supported electron.s || node.js printer bindings", "homepage": "https://github.com/addble/electron-printer", "version": "3.0.0-RC1", @@ -31,7 +31,7 @@ "url": "https://github.com/addble/electron-printer.git" }, "binary": { - "module_name": "electron-printer", + "module_name": "node-printer", "module_path": "./lib/", "host": "https://github.com/addble/electron-printer/releases/download/", "remote_path": "v{version}" @@ -43,6 +43,6 @@ ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "node-pre-gyp-github": "^2.0.0" + "@prebuild/node-pre-gyp-github": "^2.0.0" } } diff --git a/tools/buildElectronLinux.sh b/tools/buildElectronLinux.sh index 06b1b0cb..dc4996d6 100755 --- a/tools/buildElectronLinux.sh +++ b/tools/buildElectronLinux.sh @@ -8,24 +8,12 @@ if [ -z "$VERSION" ]; then exit 1 fi -# Build Electron Linux 64bit (x64) -echo "Building for Electron $VERSION on Linux x64..." -node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=x64 --build-from-source +declare -a linux_archs=("x64" "ia32" "arm" "arm64") -# Build Electron Linux 32bit (ia32) -echo "Building for Electron $VERSION on Linux ia32..." -node-pre-gyp configure --target=$VERSION --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=ia32 --build-from-source - -# Build Electron Linux ARM 32bit (armv7l) for Raspberry Pi 2/3/4 (32-bit OS) -echo "Building for Electron $VERSION on Linux arm..." -node-pre-gyp configure --target=$VERSION --arch=arm --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm --build-from-source - -# Build Electron Linux ARM 64bit (arm64) for Raspberry Pi 3/4/5 (64-bit OS) -echo "Building for Electron $VERSION on Linux arm64..." -node-pre-gyp configure --target=$VERSION --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm64 --build-from-source +for arch in "${linux_archs[@]}"; do + echo "Building for Electron $VERSION on Linux $arch..." + npx node-pre-gyp configure --target=$VERSION --arch=$arch --dist-url=https://electronjs.org/headers --module_name=node-printer --module_path=../lib/ + npx node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=$arch --build-from-source +done echo "Done." diff --git a/tools/buildElectronMac.sh b/tools/buildElectronMac.sh index 90f9994d..60390742 100644 --- a/tools/buildElectronMac.sh +++ b/tools/buildElectronMac.sh @@ -8,14 +8,12 @@ if [ -z "$VERSION" ]; then exit 1 fi -# Build Electron macOS x64 -echo "Building for Electron $VERSION on macOS x64..." -node-pre-gyp configure --target=$VERSION --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=x64 --build-from-source +declare -a macos_archs=("x64" "arm64") -# Build Electron macOS arm64 (for Apple Silicon) -echo "Building for Electron $VERSION on macOS arm64..." -node-pre-gyp configure --target=$VERSION --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=arm64 --build-from-source +for arch in "${macos_archs[@]}"; do + echo "Building for Electron $VERSION on macOS $arch..." + npx node-pre-gyp configure --target=$VERSION --arch=$arch --dist-url=https://electronjs.org/headers --module_name=node-printer --module_path=../lib/ + npx node-pre-gyp build package --runtime=electron --target=$VERSION --target_arch=$arch --build-from-source +done echo "Done." \ No newline at end of file diff --git a/tools/buildElectronWindows.ps1 b/tools/buildElectronWindows.ps1 index 2874db9b..b97243fa 100644 --- a/tools/buildElectronWindows.ps1 +++ b/tools/buildElectronWindows.ps1 @@ -12,20 +12,14 @@ param ( # Stop script on first error $ErrorActionPreference = "Stop" -Write-Host "Building Electron Version -> $Version for x64, ia32, and arm64" +Write-Host "Building Electron Version -> $Version" -# Build Electron Windows 64bit -Write-Host "Building for x64..." -npx node-pre-gyp configure --target=$Version --arch=x64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=x64 --build-from-source +$windows_archs = @("x64", "ia32", "arm64") -# Build Electron Windows 32bit -Write-Host "Building for ia32..." -npx node-pre-gyp configure --target=$Version --arch=ia32 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=ia32 --build-from-source - -Write-Host "Building for arm64..." -npx node-pre-gyp configure --target=$Version --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=electron-printer --module_path=../lib/ -npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=arm64 --build-from-source +foreach ($arch in $windows_archs) { + Write-Host "Building for Windows $arch..." + npx node-pre-gyp configure --target=$Version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=node-printer --module_path=../lib/ + npx node-pre-gyp build package --runtime=electron --target=$Version --target_arch=$arch --build-from-source +} Write-Host "Done." \ No newline at end of file diff --git a/tools/generateReleaseBuildsLinux.sh b/tools/generateReleaseBuildsLinux.sh index 013db589..c6ae6e4e 100755 --- a/tools/generateReleaseBuildsLinux.sh +++ b/tools/generateReleaseBuildsLinux.sh @@ -39,7 +39,7 @@ for version in "${node_versions[@]}"; do echo "Building for Node.js version: $version" for arch in "${linux_archs[@]}"; do echo " Building for arch: $arch..." - npx node-pre-gyp configure --target=$version --arch=$arch --module_name=electron-printer + npx node-pre-gyp configure --target=$version --arch=$arch --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=$arch --build-from-source done rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files @@ -50,7 +50,7 @@ for version in "${electron_versions[@]}"; do echo "Building for Electron version: $version" for arch in "${linux_archs[@]}"; do echo " Building for arch: $arch..." - npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=$arch --runtime=electron --build-from-source done rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files diff --git a/tools/generateReleaseBuildsMac.sh b/tools/generateReleaseBuildsMac.sh index a1162f4f..fb655e4f 100644 --- a/tools/generateReleaseBuildsMac.sh +++ b/tools/generateReleaseBuildsMac.sh @@ -35,7 +35,7 @@ mkdir -p "$SOURCE_PATH/releases/$RELEASE_VERSION" for version in "${node_versions[@]}"; do echo "Building for Node.js version: $version..." - npx node-pre-gyp configure --target=$version --module_name=electron-printer + npx node-pre-gyp configure --target=$version --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=x64 --build-from-source npx node-pre-gyp build package --target=$version --target_arch=arm64 --build-from-source rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files @@ -44,7 +44,7 @@ done for version in "${electron_versions[@]}"; do echo "Building for Electron version: $version..." - npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp configure --target=$version --dist-url=https://electronjs.org/headers --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=x64 --runtime=electron --build-from-source npx node-pre-gyp build package --target=$version --target_arch=arm64 --runtime=electron --build-from-source rsync -av "$SOURCE_PATH/build/stage/$PACKAGE_VERSION/" "$SOURCE_PATH/releases/$RELEASE_VERSION/" --remove-source-files diff --git a/tools/generateReleaseBuildsWindows.ps1 b/tools/generateReleaseBuildsWindows.ps1 index 8b54c39a..dacb56b5 100644 --- a/tools/generateReleaseBuildsWindows.ps1 +++ b/tools/generateReleaseBuildsWindows.ps1 @@ -43,7 +43,7 @@ foreach ($version in $node_versions) { Write-Output "Building for node version: $version" foreach ($arch in $windows_archs) { Write-Output " Building for arch: $arch..." - npx node-pre-gyp configure --target=$version --arch=$arch --module_name=electron-printer + npx node-pre-gyp configure --target=$version --arch=$arch --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=$arch --build-from-source } Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" @@ -55,7 +55,7 @@ foreach ($version in $electron_versions) { Write-Output "Building for Electron version: $version" foreach ($arch in $windows_archs) { Write-Output " Building for arch: $arch..." - npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=electron-printer + npx node-pre-gyp configure --target=$version --arch=$arch --dist-url=https://electronjs.org/headers --module_name=node-printer npx node-pre-gyp build package --target=$version --target_arch=$arch --runtime=electron --build-from-source } Copy-Item -Force -Recurse "$SOURCE_PATH\..\build\stage\$PACKAGE_VERSION\*" -Destination "$SOURCE_PATH\..\releases\$RELEASE_VERSION" From 1eebb6cdc37395aff9482720dc368ed8db9e38cc Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Thu, 31 Jul 2025 15:49:02 +0530 Subject: [PATCH 13/18] Corrected devDependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a53ce15c..6fba9a1a 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,6 @@ ], "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "@prebuild/node-pre-gyp-github": "^2.0.0" + "node-pre-gyp-github": "^2.0.0" } } From 4a1723a54afdd676ea1637614c9a5aa4757bcefa Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Sat, 2 Aug 2025 11:37:34 +0530 Subject: [PATCH 14/18] Fixed CI file to skip PR builds --- .github/workflows/ci.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0dcf44b1..1784f034 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,23 +73,30 @@ jobs: name: Publish Prebuilds needs: prebuild runs-on: ubuntu-latest - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + # The job-level `if` is removed. The job will now run on pull requests, + # but the steps inside will be skipped. This allows the job to report a + # "success" status, which is useful if it's a required check for merging. steps: - name: Checkout code uses: actions/checkout@v4 + if: github.ref == 'refs/heads/main' - name: Setup Node.js uses: actions/setup-node@v4 + if: github.ref == 'refs/heads/main' with: node-version: '18.x' - name: Install dependencies + if: github.ref == 'refs/heads/main' run: npm install - name: Download all artifacts uses: actions/download-artifact@v4 + if: github.ref == 'refs/heads/main' with: path: prebuilds/ pattern: prebuilds-* merge-multiple: true - name: Publish to GitHub Releases + if: github.ref == 'refs/heads/main' env: NODE_PRE_GYP_GITHUB_TOKEN: ${{ secrets.PREBUILD_TOKEN }} run: npm run release \ No newline at end of file From 32cf6368b5d59729592d26651d4fb5af5ea07897 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Sat, 2 Aug 2025 13:18:21 +0530 Subject: [PATCH 15/18] Correcting dependencies --- lib/index.js | 9 +++++---- package-lock.json | 12 ++++++------ package.json | 12 ++++-------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/index.js b/lib/index.js index 9c58c436..1678e5f3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,11 +2,12 @@ const path = require('path'); let addon; try { - // This will load the addon built by `node-gyp build` and copied by the `action_after_build` target in binding.gyp. - addon = require(path.join(__dirname, 'node-printer.node')); + // When installed via node-pre-gyp, the binary is placed in ./lib/binding/ + addon = require(path.join(__dirname, 'binding', 'node-printer.node')); } catch (err) { - // Fallback for development, e.g. when `action_after_build` hasn't run or when using prebuild-install which might place it elsewhere. - addon = require('../build/Release/node-printer.node'); + // During development, the binary is in the standard build directory. + // The `action_after_build` step in binding.gyp is not strictly necessary with this setup. + addon = require(path.join(__dirname, '..', 'build', 'Release', 'node-printer.node')); } module.exports.sayMyName = addon.SayMyName diff --git a/package-lock.json b/package-lock.json index a70f1cfa..6e47ca72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { - "name": "@addble/electron-printer", - "version": "2.0.4-addble.1", + "name": "@addble/node-printer", + "version": "3.0.0-RC1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@addble/electron-printer", - "version": "2.0.4-addble.1", + "name": "@addble/node-printer", + "version": "3.0.0-RC1", "hasInstallScript": true, "dependencies": { - "node-addon-api": "^8.1.0" + "node-addon-api": "^8.2.1" }, "devDependencies": { "@mapbox/node-pre-gyp": "^2.0.0", - "node-pre-gyp-github": "github:Susheer/node-pre-gyp-github" + "node-pre-gyp-github": "^2.0.0" } }, "node_modules/@isaacs/fs-minipass": { diff --git a/package.json b/package.json index 6fba9a1a..ce621221 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "main": "./lib/index.js", "types": "types/index.d.ts", "dependencies": { - "node-addon-api": "^8.1.0" + "node-addon-api": "^8.2.1", + "@mapbox/node-pre-gyp": "^2.0.0" }, "scripts": { "install": "node-pre-gyp install --fallback-to-build", @@ -32,17 +33,12 @@ }, "binary": { "module_name": "node-printer", - "module_path": "./lib/", + "module_path": "./lib/binding/", "host": "https://github.com/addble/electron-printer/releases/download/", "remote_path": "v{version}" }, - "licenses": [ - { - "type": "MIT" - } - ], + "license": "MIT", "devDependencies": { - "@mapbox/node-pre-gyp": "^2.0.0", "node-pre-gyp-github": "^2.0.0" } } From 0892f0865bfc3338764b41546b5fb4a2c3faa7dc Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Sat, 2 Aug 2025 15:10:23 +0530 Subject: [PATCH 16/18] Updated CI --- .github/workflows/ci.yml | 36 +++++++++++++++++------------------- package.json | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1784f034..9c0bd0b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,29 +39,27 @@ jobs: with: platforms: arm,arm64 - - name: Install dependencies - run: npm install - - - name: Build for Linux - if: runner.os == 'Linux' + - name: Determine Architectures + id: archs + shell: bash run: | - npm run prebuild -- --strip --all --arch ia32 - npm run prebuild -- --strip --all --arch x64 - npm run prebuild -- --strip --all --arch arm - npm run prebuild -- --strip --all --arch arm64 + if [[ "${{ runner.os }}" == "Linux" ]]; then + echo "arch_list=ia32 x64 arm arm64" >> $GITHUB_OUTPUT + elif [[ "${{ runner.os }}" == "macOS" ]]; then + echo "arch_list=x64 arm64" >> $GITHUB_OUTPUT + elif [[ "${{ runner.os }}" == "Windows" ]]; then + echo "arch_list=ia32 x64 arm64" >> $GITHUB_OUTPUT + fi - - name: Build for macOS - if: runner.os == 'macOS' - run: | - npm run prebuild -- --strip --all --arch x64 - npm run prebuild -- --strip --all --arch arm64 + - name: Install dependencies + run: npm install - - name: Build for Windows - if: runner.os == 'Windows' + - name: Build Prebuilds run: | - npm run prebuild -- --strip --all --arch ia32 - npm run prebuild -- --strip --all --arch x64 - npm run prebuild -- --strip --all --arch arm64 + for arch in ${{ steps.archs.outputs.arch_list }}; do + npm run prebuild -- --strip --all --arch "$arch" + done + shell: bash - name: Upload prebuilds artifact uses: actions/upload-artifact@v4 diff --git a/package.json b/package.json index ce621221..cbc2ea1b 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "install": "node-pre-gyp install --fallback-to-build", "rebuild": "node-gyp rebuild", - "prebuild": "node-pre-gyp prebuild", + "prebuild": "node-pre-gyp-github", "release": "node-pre-gyp-github publish --release", "test": "node --test test/" }, From 85c738646ac442cd22870c1b2d6ca88995e19c4d Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Sat, 2 Aug 2025 16:08:56 +0530 Subject: [PATCH 17/18] Corrected errors --- .github/workflows/ci.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c0bd0b8..17d048f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: - name: Build Prebuilds run: | for arch in ${{ steps.archs.outputs.arch_list }}; do - npm run prebuild -- --strip --all --arch "$arch" + npm run prebuild -- --strip --arch "$arch" done shell: bash diff --git a/package.json b/package.json index cbc2ea1b..acf8d406 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "install": "node-pre-gyp install --fallback-to-build", "rebuild": "node-gyp rebuild", - "prebuild": "node-pre-gyp-github", + "prebuild": "node-pre-gyp build package", "release": "node-pre-gyp-github publish --release", "test": "node --test test/" }, From ba92eadb9f48110b89070f6d8d4a77fd6d3779c3 Mon Sep 17 00:00:00 2001 From: Yaikhomba Ningthemcha Date: Sat, 2 Aug 2025 16:59:48 +0530 Subject: [PATCH 18/18] Updated license and version details --- README.md | 14 +++++++++++--- package.json | 24 +++++++++++++++++------- tools/generateReleaseBuildsLinux.sh | 5 +++++ tools/generateReleaseBuildsMac.sh | 5 +++++ tools/generateReleaseBuildsWindows.ps1 | 5 +++++ 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 23f5fdb9..66367fc1 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,17 @@ If you have a problem, please find or create a new [GitHub issue](https://github * `printFile(options)` to print a file (POSIX only, e.g., macOS, Linux). Returns a Promise. * `getSupportedPrintFormats()` to get supported data formats like 'RAW' and 'TEXT'. +### Pre-compiled Binaries + +This package ships with pre-compiled binaries for a wide range of Node.js and Electron versions on Windows, macOS, and Linux for various architectures. + +While N-API provides forward compatibility (meaning a binary built for an older version may work on a newer one), we provide pre-builds for these major versions to ensure a smooth installation experience without requiring a local compiler toolchain: + +* **Node.js**: 16, 18, 20, 22 +* **Electron**: 15, 19, 22, 25, 27, 28, 29, 30, 31 + +If you are using a version not covered by our pre-compiled binaries, the installer will attempt to build the addon from source. This requires a proper C/C++ compiler toolchain to be installed on your system. + ### How to install: ``` npm install @addble/electron-printer @@ -60,8 +71,6 @@ I was involved in a project where I needed to print from Node.js. This is the re * `getSupportedJobCommands()` to get supported job commands for `setJob()`, depending on the OS. The `'CANCEL'` command is supported on all OSes. -``` - ### How to use: See examples @@ -75,7 +84,6 @@ See examples * Thiago Lugli, @thiagoelg * Eko Eryanto, @ekoeryanto * Sudheer Gupta, @susheer -* Yaikhomba Ningthemcha, @yaikhomba ### Project History: diff --git a/package.json b/package.json index acf8d406..56968e44 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,9 @@ "node-addon-api": "^8.2.1", "@mapbox/node-pre-gyp": "^2.0.0" }, + "devDependencies": { + "node-pre-gyp-github": "^2.0.0" + }, "scripts": { "install": "node-pre-gyp install --fallback-to-build", "rebuild": "node-gyp rebuild", @@ -18,14 +21,14 @@ }, "author": { - "name": "Ion Lupascu", - "url": "http://program-support.co.uk/", - "email": "ionlupascu@gmail.com" + "name": "Yaikhomba Ningthemcha", + "url": "https://github.com/yaikhomba" }, "contributors": [ "Sudheer Gupta ", "Thiago Lugli ", - "Eko Eryanto " + "Eko Eryanto ", + "Ion Lupascu " ], "repository": { "type": "git", @@ -38,7 +41,14 @@ "remote_path": "v{version}" }, "license": "MIT", - "devDependencies": { - "node-pre-gyp-github": "^2.0.0" - } + "licenses": [ + { + "type": "MIT", + "url": "https://opensource.org/licenses/MIT" + }, + { + "type":"BSD-3-Clause", + "url": "https://opensource.org/licenses/BSD-3-Clause" + } + ] } diff --git a/tools/generateReleaseBuildsLinux.sh b/tools/generateReleaseBuildsLinux.sh index c6ae6e4e..06dcf53c 100755 --- a/tools/generateReleaseBuildsLinux.sh +++ b/tools/generateReleaseBuildsLinux.sh @@ -21,6 +21,11 @@ declare -a node_versions=( ) declare -a electron_versions=( + "15.3.5" + "19.1.9" + "22.3.27" + "25.9.8" + "27.3.11" "28.3.3" "29.4.0" "30.1.0" diff --git a/tools/generateReleaseBuildsMac.sh b/tools/generateReleaseBuildsMac.sh index fb655e4f..3109144d 100644 --- a/tools/generateReleaseBuildsMac.sh +++ b/tools/generateReleaseBuildsMac.sh @@ -21,6 +21,11 @@ declare -a node_versions=( ) declare -a electron_versions=( + "15.3.5" + "19.1.9" + "22.3.27" + "25.9.8" + "27.3.11" "28.3.3" "29.4.0" "30.1.0" diff --git a/tools/generateReleaseBuildsWindows.ps1 b/tools/generateReleaseBuildsWindows.ps1 index dacb56b5..2a247be0 100644 --- a/tools/generateReleaseBuildsWindows.ps1 +++ b/tools/generateReleaseBuildsWindows.ps1 @@ -25,6 +25,11 @@ $node_versions = @( ) $electron_versions = @( + "15.3.5", + "19.1.9", + "22.3.27", + "25.9.8", + "27.3.11", "28.3.3", "29.4.0", "30.1.0",