diff --git a/.create-adapter.json b/.create-adapter.json new file mode 100644 index 0000000..702fe08 --- /dev/null +++ b/.create-adapter.json @@ -0,0 +1,35 @@ +{ + "cli": true, + "target": "directory", + "adapterName": "frigate", + "title": "Frigate", + "description": "Adapter for Frigate", + "keywords": ["frigate", "ki", "detection"], + "contributors": ["Bettman66"], + "expert": "yes", + "features": ["adapter"], + "adminFeatures": [], + "type": "alarm", + "startMode": "daemon", + "connectionType": "local", + "dataSource": "push", + "connectionIndicator": "yes", + "language": "JavaScript", + "nodeVersion": "18", + "adminUi": "json", + "tools": ["ESLint", "type checking", "Prettier"], + "releaseScript": "yes", + "devServer": "no", + "indentation": "Space (4)", + "quotes": "single", + "es6class": "yes", + "authorName": "TA2k", + "authorGithub": "iobroker-community-adapters", + "authorEmail": "tombox2020@gmail.com", + "gitRemoteProtocol": "HTTPS", + "gitCommit": "no", + "defaultBranch": "main", + "license": "MIT License", + "dependabot": "yes", + "creatorVersion": "2.6.1" +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c66d2fc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +.prettierrc.js +**/.eslintrc.js +admin/words.js \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 4d91303..f8e2c2e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,35 +1,42 @@ { - "env": { - "es6": true, - "node": true, - "mocha": true - }, - "extends": "eslint:recommended", - "rules": { - "indent": [ - "error", - "spaces", - { - "SwitchCase": 1 - } - ], - "no-console": "off", - "no-var": "error", - "prefer-const": "error", - "quotes": [ - "error", - "double", - { - "avoidEscape": true, - "allowTemplateLiterals": true - } - ], - "semi": [ - "error", - "always" - ] - }, - "parserOptions": { - "ecmaVersion": 2018 - } -} \ No newline at end of file + "root": true, + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "extends": ["eslint:recommended"], + "plugins": [], + "rules": { + "indent": [ + "error", + 2, + { + "SwitchCase": 1 + } + ], + "no-console": "off", + "no-unused-vars": [ + "error", + { + "ignoreRestSiblings": true, + "argsIgnorePattern": "^_" + } + ], + "no-var": "error", + "no-trailing-spaces": "error", + "prefer-const": "error", + "quotes": [ + "error", + "single", + { + "avoidEscape": true, + "allowTemplateLiterals": true + } + ], + "semi": ["error", "always"] + }, + "parserOptions": { + "ecmaVersion": "latest" + } +} diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index 7d2f11e..1603e7d 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -5,7 +5,7 @@ name: Test and Release on: push: branches: - - '*' + - 'main' tags: # normal versions - 'v[0-9]+.[0-9]+.[0-9]+' @@ -13,6 +13,11 @@ on: - 'v[0-9]+.[0-9]+.[0-9]+-**' pull_request: {} +# Cancel previous PR/branch runs when a new commit is pushed +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + jobs: # Performs quick checks before the expensive test runs check-and-lint: @@ -20,135 +25,67 @@ jobs: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: ioBroker/testing-action-check@v1 with: - node-version: ${{ matrix.node-version }} - - - name: Install Dependencies - run: npm install - - - name: Lint source code - run: npm run lint - - name: Test package files - run: npm run test:package + node-version: '18.x' + # Uncomment the following line if your adapter cannot be installed using 'npm ci' + # install-command: 'npm install' + lint: true # Runs adapter tests on all supported node versions and OSes adapter-tests: if: contains(github.event.head_commit.message, '[skip ci]') == false - needs: [check-and-lint] - runs-on: ${{ matrix.os }} strategy: matrix: - node-version: [18.x, 20.x, 16.x] + node-version: [18.x, 20.x, 21.x] os: [ubuntu-latest, windows-latest, macos-latest] steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + - uses: ioBroker/testing-action-adapter@v1 with: node-version: ${{ matrix.node-version }} + os: ${{ matrix.os }} + # Uncomment the following line if your adapter cannot be installed using 'npm ci' + # install-command: 'npm install' - - name: Install Dependencies - run: npm install + # TODO: To enable automatic npm releases, create a token on npmjs.org + # Enter this token as a GitHub secret (with name NPM_TOKEN) in the repository options + # Then uncomment the following block: - - name: Run unit tests - run: npm run test:unit + # Deploys the final package to NPM + deploy: + needs: [check-and-lint, adapter-tests] - - name: Run integration tests (unix only) - if: startsWith(runner.OS, 'windows') == false - run: DEBUG=testing:* npm run test:integration + # Trigger this step only when a commit on any branch is tagged with a version number + if: | + contains(github.event.head_commit.message, '[skip ci]') == false && + github.event_name == 'push' && + startsWith(github.ref, 'refs/tags/v') - - name: Run integration tests (windows only) - if: startsWith(runner.OS, 'windows') - run: set DEBUG=testing:* & npm run test:integration -# TODO: To enable automatic npm releases, create a token on npmjs.org -# Enter this token as a GitHub secret (with name NPM_TOKEN) in the repository options -# Then uncomment the following block: + runs-on: ubuntu-latest -# # Deploys the final package to NPM -# deploy: -# needs: [adapter-tests] -# -# # Trigger this step only when a commit on any branch is tagged with a version number -# if: | -# contains(github.event.head_commit.message, '[skip ci]') == false && -# github.event_name == 'push' && -# startsWith(github.ref, 'refs/tags/v') -# -# runs-on: ubuntu-latest -# strategy: -# matrix: -# node-version: [14.x] -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v2 -# -# - name: Use Node.js ${{ matrix.node-version }} -# uses: actions/setup-node@v1 -# with: -# node-version: ${{ matrix.node-version }} -# -# - name: Extract the version and commit body from the tag -# id: extract_release -# # The body may be multiline, therefore newlines and % need to be escaped -# run: | -# VERSION="${{ github.ref }}" -# VERSION=${VERSION##*/v} -# echo "::set-output name=VERSION::$VERSION" -# BODY=$(git show -s --format=%b) -# BODY="${BODY//'%'/'%25'}" -# BODY="${BODY//$'\n'/'%0A'}" -# BODY="${BODY//$'\r'/'%0D'}" -# echo "::set-output name=BODY::$BODY" -# -# - name: Publish package to npm -# run: | -# npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }} -# npm whoami -# npm publish -# -# - name: Create Github Release -# uses: actions/create-release@v1 -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# with: -# tag_name: ${{ github.ref }} -# release_name: Release v${{ steps.extract_release.outputs.VERSION }} -# draft: false -# # Prerelease versions create prereleases on Github -# prerelease: ${{ contains(steps.extract_release.outputs.VERSION, '-') }} -# body: ${{ steps.extract_release.outputs.BODY }} -# -# # When using Sentry for error reporting, Sentry could be informed about new releases -# # To enable create a API-Token in Sentry (User settings, API keys) -# # Enter this token as a GitHub secret (with name SENTRY_AUTH_TOKEN) in the repository options -# # Then uncomment and customize the following block: -# #- name: Notify Sentry.io about the release -# # run: | -# # npm i -g @sentry/cli -# # export SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} -# # export SENTRY_URL=https://sentry.iobroker.net -# # export SENTRY_ORG=iobroker -# # export SENTRY_PROJECT=iobroker-volvo -# # export SENTRY_VERSION=iobroker.volvo@${{ steps.extract_release.outputs.VERSION }} -# # sentry-cli releases new $SENTRY_VERSION -# # sentry-cli releases finalize $SENTRY_VERSION -# # # Add the following line BEFORE finalize if repositories are connected in Sentry -# # #sentry-cli releases set-commits $SENTRY_VERSION --auto -# # # Add the following line BEFORE finalize if sourcemap uploads are needed -# # #sentry-cli releases files $SENTRY_VERSION upload-sourcemaps build/ + # Write permissions are required to create Github releases + permissions: + contents: write + + steps: + - uses: ioBroker/testing-action-deploy@v1 + with: + node-version: '18.x' + # Uncomment the following line if your adapter cannot be installed using 'npm ci' + # install-command: 'npm install' + npm-token: ${{ secrets.NPM_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} +# # When using Sentry for error reporting, Sentry can be informed about new releases +# # To enable create a API-Token in Sentry (User settings, API keys) +# # Enter this token as a GitHub secret (with name SENTRY_AUTH_TOKEN) in the repository options +# # Then uncomment and customize the following block: +# sentry: true +# sentry-token: ${{ secrets.SENTRY_AUTH_TOKEN }} +# sentry-project: "iobroker-volvo" +# sentry-version-prefix: "iobroker.volvo" +# # If your sentry project is linked to a GitHub repository, you can enable the following option +# # sentry-github-integration: true diff --git a/.gitignore b/.gitignore index dc5f07f..3bf582b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ -.git -.idea +# No dot-directories except github/vscode +.*/ +!.vscode/ +!.github/ + *.code-workspace node_modules nbproject @@ -11,5 +14,4 @@ Thumbs.db # i18n intermediate files admin/i18n/flat.txt -admin/i18n/*/flat.txt -.DS_Store +admin/i18n/*/flat.txt \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..515bcd4 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +package.json +package-lock.json \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..697b637 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,9 @@ +module.exports = { + semi: true, + trailingComma: 'all', + singleQuote: true, + printWidth: 140, + useTabs: false, + tabWidth: 2, + endOfLine: 'lf', +}; diff --git a/.releaseconfig.json b/.releaseconfig.json new file mode 100644 index 0000000..e7d09e2 --- /dev/null +++ b/.releaseconfig.json @@ -0,0 +1,3 @@ +{ + "plugins": ["iobroker", "license", "manual-review"] +} diff --git a/LICENSE b/LICENSE index 3fcb368..d3b61c1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 TA2k +Copyright (c) 2020-2030 TA2k Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 6fcf820..d4eda50 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ [![NPM](https://nodei.co/npm/iobroker.volvo.png?downloads=true)](https://nodei.co/npm/iobroker.volvo/) **Tests:** ![Test and Release](https://github.com/TA2k/ioBroker.volvo/workflows/Test%20and%20Release/badge.svg) + ## volvo adapter for ioBroker Volvo On Call and new Electric API for Android Automotive Cars Adapter @@ -20,10 +21,9 @@ Volvo On Call and new Electric API for Android Automotive Cars Adapter Non Eletric car can login via username and password. - ## Eletric Android Automotive Cars need a VCC API Key -Register/Login into +Register/Login into You need a Google or Github Account this is not related to you APP Credentials @@ -39,45 +39,47 @@ Paste the API Key in the Instance settings Enter Volvoe App Username and password. ## Controling Eletric Android -Controlling Eletric Android with the volvo.0.id.remote is not possible at the moment. The commands are send succeful to the API and are accepted but it looks like the API is not complete to control the car. +Controlling Eletric Android with the volvo.0.id.remote is not possible at the moment. The commands are send succeful to the API and are accepted but it looks like the API is not complete to control the car. ## Getting started Use objects under remote to control the vehicle - - ## Changelog +### 0.1.2-beta.0 (2024-04-30) + +- add v2 support ### 0.1.0 -* (TA2k) add new api for electric cars +- (TA2k) add new api for electric cars + ### 0.0.6 -* (TA2k) fix trip object naming - +- (TA2k) fix trip object naming + ### 0.0.5 -* (TA2k) fix receiving data +- (TA2k) fix receiving data ### 0.0.4 -* (TA2k) fix jscontroller - +- (TA2k) fix jscontroller + ### 0.0.3 -* (TA2k) fix preclimate +- (TA2k) fix preclimate ### 0.0.2 -* (TA2k) initial release +- (TA2k) initial release ## License MIT License -Copyright (c) 2020 TA2k +Copyright (c) 2020-2030 TA2k Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/io-package.json b/io-package.json index 2cb5dcd..0aecc5b 100644 --- a/io-package.json +++ b/io-package.json @@ -1,8 +1,21 @@ { "common": { "name": "volvo", - "version": "0.1.1", + "version": "0.1.2-beta.0", "news": { + "0.1.2-beta.0": { + "en": "add v2 support", + "de": "v2 unterstützung hinzugefügt", + "ru": "поддержка v2", + "pt": "adicionar suporte v2", + "nl": "v2 ondersteuning toevoegen", + "fr": "ajouter le support v2", + "it": "aggiungere v2 supporto", + "es": "add v2 support", + "pl": "dodaj obsługę v2", + "uk": "підтримка v2", + "zh-cn": "添加 v2 支持" + }, "0.1.1": { "en": "add location API for electric cars" }, @@ -20,18 +33,6 @@ }, "0.0.3": { "en": "fix preclimate" - }, - "0.0.2": { - "en": "initial release", - "de": "Erstveröffentlichung", - "ru": "Начальная версия", - "pt": "lançamento inicial", - "nl": "Eerste uitgave", - "fr": "Première version", - "it": "Versione iniziale", - "es": "Versión inicial", - "pl": "Pierwsze wydanie", - "zh-cn": "首次出版" } }, "title": "Volvo On Call", diff --git a/lib/extractKeys.js b/lib/extractKeys.js index 3a6e921..ef152c8 100644 --- a/lib/extractKeys.js +++ b/lib/extractKeys.js @@ -1,171 +1,171 @@ //v2.7 async function extractKeys(adapter, path, element, preferedArrayName, forceIndex) { - try { - if (element === null || element === undefined) { - adapter.log.debug("Cannot extract empty: " + path); - return; - } - const objectKeys = Object.keys(element); - const write = false; - if (Array.isArray(element)) { - extractArray(adapter, element, "", path, write, preferedArrayName, forceIndex); - return; - } - - if (typeof element === "string" || typeof element === "number") { - let name = element; - if (typeof element === "number") { - name = element.toString(); - } - adapter - .setObjectNotExistsAsync(path, { - type: "state", - common: { - name: name, - role: "indicator", - type: typeof element, - write: write, - read: true, - }, - native: {}, - }) - .then(() => { - adapter.setState(path, element, true); - }) - .catch((error) => { - adapter.log.error(error); - }); - return; - } - - objectKeys.forEach((key) => { - if (isJsonString(element[key])) { - element[key] = JSON.parse(element[key]); - } + try { + if (element === null || element === undefined) { + adapter.log.debug('Cannot extract empty: ' + path); + return; + } + const objectKeys = Object.keys(element); + const write = false; + if (Array.isArray(element)) { + extractArray(adapter, element, '', path, write, preferedArrayName, forceIndex); + return; + } - if (Array.isArray(element[key])) { - extractArray(adapter, element, key, path, write, preferedArrayName, forceIndex); - } else if (element[key] !== null && typeof element[key] === "object") { - extractKeys(adapter, path + "." + key, element[key], preferedArrayName, forceIndex); - } else { - adapter - .setObjectNotExistsAsync(path + "." + key, { - type: "state", - common: { - name: key, - role: "indicator", - type: typeof element[key], - write: write, - read: true, - }, - native: {}, - }) - .then(() => { - adapter.setState(path + "." + key, element[key], true); - }) - .catch((error) => { - adapter.log.error(error); - }); - } + if (typeof element === 'string' || typeof element === 'number') { + let name = element; + if (typeof element === 'number') { + name = element.toString(); + } + adapter + .setObjectNotExistsAsync(path, { + type: 'state', + common: { + name: name, + role: 'indicator', + type: typeof element, + write: write, + read: true, + }, + native: {}, + }) + .then(() => { + adapter.setState(path, element, true); + }) + .catch((error) => { + adapter.log.error(error); }); - } catch (error) { - adapter.log.error("Error extract keys: " + path + " " + JSON.stringify(element)); - adapter.log.error(error); + return; } + + objectKeys.forEach((key) => { + if (isJsonString(element[key])) { + element[key] = JSON.parse(element[key]); + } + + if (Array.isArray(element[key])) { + extractArray(adapter, element, key, path, write, preferedArrayName, forceIndex); + } else if (element[key] !== null && typeof element[key] === 'object') { + extractKeys(adapter, path + '.' + key, element[key], preferedArrayName, forceIndex); + } else { + adapter + .setObjectNotExistsAsync(path + '.' + key, { + type: 'state', + common: { + name: key, + role: 'indicator', + type: typeof element[key], + write: write, + read: true, + }, + native: {}, + }) + .then(() => { + adapter.setState(path + '.' + key, element[key], true); + }) + .catch((error) => { + adapter.log.error(error); + }); + } + }); + } catch (error) { + adapter.log.error('Error extract keys: ' + path + ' ' + JSON.stringify(element)); + adapter.log.error(error); + } } function extractArray(adapter, element, key, path, write, preferedArrayName, forceIndex) { - try { - if (key) { - element = element[key]; - } - element.forEach(async (arrayElement, index) => { - index = index + 1; - if (index < 10) { - index = "0" + index; - } - let arrayPath = key + index; + try { + if (key) { + element = element[key]; + } + element.forEach(async (arrayElement, index) => { + index = index + 1; + if (index < 10) { + index = '0' + index; + } + let arrayPath = key + index; - if (typeof arrayElement[Object.keys(arrayElement)[0]] === "string") { - arrayPath = arrayElement[Object.keys(arrayElement)[0]]; - } - Object.keys(arrayElement).forEach((keyName) => { - if (keyName.endsWith("Id")) { - if (arrayElement[keyName].replace) { - arrayPath = arrayElement[keyName].replace(/\./g, ""); - } else { - arrayPath = arrayElement[keyName]; - } - } - }); - Object.keys(arrayElement).forEach((keyName) => { - if (keyName.endsWith("Name")) { - arrayPath = arrayElement[keyName]; - } - }); + if (typeof arrayElement[Object.keys(arrayElement)[0]] === 'string') { + arrayPath = arrayElement[Object.keys(arrayElement)[0]]; + } + Object.keys(arrayElement).forEach((keyName) => { + if (keyName.endsWith('Id')) { + if (arrayElement[keyName].replace) { + arrayPath = arrayElement[keyName].replace(/\./g, ''); + } else { + arrayPath = arrayElement[keyName]; + } + } + }); + Object.keys(arrayElement).forEach((keyName) => { + if (keyName.endsWith('Name')) { + arrayPath = arrayElement[keyName]; + } + }); - if (arrayElement.id) { - if (arrayElement.id.replace) { - arrayPath = arrayElement.id.replace(/\./g, ""); - } else { - arrayPath = arrayElement.id; - } - } - if (arrayElement.name) { - arrayPath = arrayElement.name.replace(/\./g, ""); - } - if (arrayElement.start_date_time) { - arrayPath = arrayElement.start_date_time.replace(/\./g, ""); - } - if (preferedArrayName && arrayElement[preferedArrayName]) { - arrayPath = arrayElement[preferedArrayName].replace(/\./g, ""); - } + if (arrayElement.id) { + if (arrayElement.id.replace) { + arrayPath = arrayElement.id.replace(/\./g, ''); + } else { + arrayPath = arrayElement.id; + } + } + if (arrayElement.name) { + arrayPath = arrayElement.name.replace(/\./g, ''); + } + if (arrayElement.start_date_time) { + arrayPath = arrayElement.start_date_time.replace(/\./g, ''); + } + if (preferedArrayName && arrayElement[preferedArrayName]) { + arrayPath = arrayElement[preferedArrayName].replace(/\./g, ''); + } - if (forceIndex) { - arrayPath = key + index; - } - //special case array with 2 string objects - if ( - Object.keys(arrayElement).length === 2 && - typeof Object.keys(arrayElement)[0] === "string" && - typeof Object.keys(arrayElement)[1] === "string" && - typeof arrayElement[Object.keys(arrayElement)[0]] !== "object" && - typeof arrayElement[Object.keys(arrayElement)[1]] !== "object" - ) { - let subKey = arrayElement[Object.keys(arrayElement)[0]]; - const subValue = arrayElement[Object.keys(arrayElement)[1]]; - const subName = Object.keys(arrayElement)[0] + " " + Object.keys(arrayElement)[1]; - if (key) { - subKey = key + "." + subKey; - } - await adapter.setObjectNotExistsAsync(path + "." + subKey, { - type: "state", - common: { - name: subName, - role: "indicator", - type: typeof subValue, - write: write, - read: true, - }, - native: {}, - }); - adapter.setState(path + "." + subKey, subValue, true); - return; - } - extractKeys(adapter, path + "." + arrayPath, arrayElement); + if (forceIndex) { + arrayPath = key + index; + } + //special case array with 2 string objects + if ( + Object.keys(arrayElement).length === 2 && + typeof Object.keys(arrayElement)[0] === 'string' && + typeof Object.keys(arrayElement)[1] === 'string' && + typeof arrayElement[Object.keys(arrayElement)[0]] !== 'object' && + typeof arrayElement[Object.keys(arrayElement)[1]] !== 'object' + ) { + let subKey = arrayElement[Object.keys(arrayElement)[0]]; + const subValue = arrayElement[Object.keys(arrayElement)[1]]; + const subName = Object.keys(arrayElement)[0] + ' ' + Object.keys(arrayElement)[1]; + if (key) { + subKey = key + '.' + subKey; + } + await adapter.setObjectNotExistsAsync(path + '.' + subKey, { + type: 'state', + common: { + name: subName, + role: 'indicator', + type: typeof subValue, + write: write, + read: true, + }, + native: {}, }); - } catch (error) { - adapter.log.error("Cannot extract array " + path); - adapter.log.error(error); - } + adapter.setState(path + '.' + subKey, subValue, true); + return; + } + extractKeys(adapter, path + '.' + arrayPath, arrayElement); + }); + } catch (error) { + adapter.log.error('Cannot extract array ' + path); + adapter.log.error(error); + } } function isJsonString(str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; } module.exports = { - extractKeys, + extractKeys, }; diff --git a/lib/json2iob.js b/lib/json2iob.js deleted file mode 100644 index 6f63e24..0000000 --- a/lib/json2iob.js +++ /dev/null @@ -1,294 +0,0 @@ -//v1.9 -/* -options: -write //set common write variable to true -forceIndex //instead of trying to find names for array entries, use the index as the name -channelName //set name of the root channel -preferedArrayName //set key to use this as an array entry name -preferedArrayDec //set key to use this as an array entry description -autoCast (true false) // make JSON.parse to parse numbers correctly -descriptions: Object of names for state keys -*/ -const JSONbig = require("json-bigint")({ storeAsString: true }); -module.exports = class Json2iob { - constructor(adapter) { - this.adapter = adapter; - this.alreadyCreatedObjects = {}; - } - - async parse(path, element, options) { - try { - if (element === null || element === undefined) { - this.adapter.log.debug("Cannot extract empty: " + path); - return; - } - - const objectKeys = Object.keys(element); - - if (!options || !options.write) { - if (!options) { - options = { write: false }; - } else { - options["write"] = false; - } - } - - if (typeof element === "string" || typeof element === "number") { - const lastPathElement = path.split(".").pop(); - - if (!this.alreadyCreatedObjects[path]) { - await this.adapter - .setObjectNotExistsAsync(path, { - type: "state", - common: { - name: lastPathElement, - role: this.getRole(element, options.write), - type: element !== null ? typeof element : "mixed", - write: options.write, - read: true, - }, - native: {}, - }) - .then(() => { - this.alreadyCreatedObjects[path] = true; - }) - .catch((error) => { - this.adapter.log.error(error); - }); - } - await this.adapter.setStateAsync(path, element, true); - - return; - } - if (!this.alreadyCreatedObjects[path]) { - let name = options.channelName || ""; - if (options.preferedArrayDesc && element[options.preferedArrayDesc]) { - name = element[options.preferedArrayDesc]; - } - await this.adapter - .setObjectNotExistsAsync(path, { - type: "channel", - common: { - name: name, - write: false, - read: true, - }, - native: {}, - }) - .then(() => { - this.alreadyCreatedObjects[path] = true; - options.channelName = undefined; - }) - .catch((error) => { - this.adapter.log.error(error); - }); - } - if (Array.isArray(element)) { - await this.extractArray(element, "", path, options); - return; - } - - for (const key of objectKeys) { - if (this.isJsonString(element[key]) && options.autoCast) { - element[key] = JSONbig.parse(element[key]); - } - - if (Array.isArray(element[key])) { - await this.extractArray(element, key, path, options); - } else if (element[key] !== null && typeof element[key] === "object") { - await this.parse(path + "." + key, element[key], options); - } else { - const pathKey = key.replace(/\./g, "_"); - if (!this.alreadyCreatedObjects[path + "." + pathKey]) { - let objectName = key; - if (options.descriptions && options.descriptions[key]) { - objectName = options.descriptions[key]; - } - const type = element[key] !== null ? typeof element[key] : "mixed"; - const common = { - name: objectName, - role: this.getRole(element[key], options.write), - type: type, - write: options.write, - read: true, - }; - - await this.adapter - .setObjectNotExistsAsync(path + "." + pathKey, { - type: "state", - common: common, - native: {}, - }) - .then(() => { - this.alreadyCreatedObjects[path + "." + pathKey] = true; - }) - .catch((error) => { - this.adapter.log.error(error); - }); - } - await this.adapter.setStateAsync(path + "." + pathKey, element[key], true); - } - } - } catch (error) { - this.adapter.log.error("Error extract keys: " + path + " " + JSON.stringify(element)); - this.adapter.log.error(error); - } - } - async extractArray(element, key, path, options) { - try { - if (key) { - element = element[key]; - } - for (let index in element) { - const arrayElement = element[index]; - index = parseInt(index) + 1; - if (index < 10) { - index = "0" + index; - } - let arrayPath = key + index; - if (typeof arrayElement === "string" && key !== "") { - await this.parse(path + "." + key + "." + arrayElement, arrayElement, options); - continue; - } - if (typeof arrayElement[Object.keys(arrayElement)[0]] === "string") { - arrayPath = arrayElement[Object.keys(arrayElement)[0]]; - } - for (const keyName of Object.keys(arrayElement)) { - if (keyName.endsWith("Id") && arrayElement[keyName] !== null) { - if (arrayElement[keyName] && arrayElement[keyName].replace) { - arrayPath = arrayElement[keyName].replace(/\./g, ""); - } else { - arrayPath = arrayElement[keyName]; - } - } - } - for (const keyName in Object.keys(arrayElement)) { - if (keyName.endsWith("Name")) { - if (arrayElement[keyName] && arrayElement[keyName].replace) { - arrayPath = arrayElement[keyName].replace(/\./g, ""); - } else { - arrayPath = arrayElement[keyName]; - } - } - } - - if (arrayElement.id) { - if (arrayElement.id.replace) { - arrayPath = arrayElement.id.replace(/\./g, ""); - } else { - arrayPath = arrayElement.id; - } - } - if (arrayElement.name) { - arrayPath = arrayElement.name.replace(/\./g, ""); - } - if (arrayElement.label) { - arrayPath = arrayElement.label.replace(/\./g, ""); - } - if (arrayElement.labelText) { - arrayPath = arrayElement.labelText.replace(/\./g, ""); - } - if (arrayElement.start_date_time) { - arrayPath = arrayElement.start_date_time.replace(/\./g, ""); - } - if (options.preferedArrayName && options.preferedArrayName.indexOf("+") !== -1) { - const preferedArrayNameArray = options.preferedArrayName.split("+"); - if (arrayElement[preferedArrayNameArray[0]]) { - const element0 = arrayElement[preferedArrayNameArray[0]].replace(/\./g, "").replace(/ /g, ""); - let element1 = ""; - if (preferedArrayNameArray[1].indexOf("/") !== -1) { - const subArray = preferedArrayNameArray[1].split("/"); - const subElement = arrayElement[subArray[0]]; - if (subElement && subElement[subArray[1]] !== undefined) { - element1 = subElement[subArray[1]]; - } else if (arrayElement[subArray[1]] !== undefined) { - element1 = arrayElement[subArray[1]]; - } - } else { - element1 = arrayElement[preferedArrayNameArray[1]].replace(/\./g, "").replace(/ /g, ""); - } - arrayPath = element0 + "-" + element1; - } - } else if (options.preferedArrayName && options.preferedArrayName.indexOf("/") !== -1) { - const preferedArrayNameArray = options.preferedArrayName.split("/"); - const subElement = arrayElement[preferedArrayNameArray[0]]; - if (subElement) { - arrayPath = subElement[preferedArrayNameArray[1]].replace(/\./g, "").replace(/ /g, ""); - } - } else if (options.preferedArrayName && arrayElement[options.preferedArrayName]) { - arrayPath = arrayElement[options.preferedArrayName].toString().replace(/\./g, ""); - } - - if (options.forceIndex) { - arrayPath = key + index; - } - //special case array with 2 string objects - if ( - !options.forceIndex && - Object.keys(arrayElement).length === 2 && - typeof Object.keys(arrayElement)[0] === "string" && - typeof Object.keys(arrayElement)[1] === "string" && - typeof arrayElement[Object.keys(arrayElement)[0]] !== "object" && - typeof arrayElement[Object.keys(arrayElement)[1]] !== "object" && - arrayElement[Object.keys(arrayElement)[0]] !== "null" - ) { - let subKey = arrayElement[Object.keys(arrayElement)[0]]; - const subValue = arrayElement[Object.keys(arrayElement)[1]]; - const subName = Object.keys(arrayElement)[0] + " " + Object.keys(arrayElement)[1]; - if (key) { - subKey = key + "." + subKey; - } - if (!this.alreadyCreatedObjects[path + "." + subKey]) { - await this.adapter - .setObjectNotExistsAsync(path + "." + subKey, { - type: "state", - common: { - name: subName, - role: this.getRole(subValue, options.write), - type: subValue !== null ? typeof subValue : "mixed", - write: options.write, - read: true, - }, - native: {}, - }) - .then(() => { - this.alreadyCreatedObjects[path + "." + subKey] = true; - }); - } - await this.adapter.setStateAsync(path + "." + subKey, subValue, true); - continue; - } - await this.parse(path + "." + arrayPath, arrayElement, options); - } - } catch (error) { - this.adapter.log.error("Cannot extract array " + path); - this.adapter.log.error(error); - } - } - isJsonString(str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - } - getRole(element, write) { - if (typeof element === "boolean" && !write) { - return "indicator"; - } - if (typeof element === "boolean" && write) { - return "switch"; - } - if (typeof element === "number" && !write) { - return "value"; - } - if (typeof element === "number" && write) { - return "level"; - } - if (typeof element === "string") { - return "text"; - } - return "state"; - } -}; diff --git a/lib/tools.js b/lib/tools.js index 8df5213..b5d0fac 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -1,4 +1,4 @@ -const axios = require("axios"); +const axios = require('axios'); /** * Tests whether the given variable is a real object and not an Array @@ -6,11 +6,11 @@ const axios = require("axios"); * @returns {it is Record} */ function isObject(it) { - // This is necessary because: - // typeof null === 'object' - // typeof [] === 'object' - // [] instanceof Object === true - return Object.prototype.toString.call(it) === "[object Object]"; + // This is necessary because: + // typeof null === 'object' + // typeof [] === 'object' + // [] instanceof Object === true + return Object.prototype.toString.call(it) === '[object Object]'; } /** @@ -19,8 +19,8 @@ function isObject(it) { * @returns {it is any[]} */ function isArray(it) { - if (typeof Array.isArray === "function") return Array.isArray(it); - return Object.prototype.toString.call(it) === "[object Array]"; + if (typeof Array.isArray === 'function') return Array.isArray(it); + return Object.prototype.toString.call(it) === '[object Array]'; } /** @@ -31,14 +31,14 @@ function isArray(it) { * @returns {Promise} */ async function translateText(text, targetLang, yandexApiKey) { - if (targetLang === "en") { - return text; - } - if (yandexApiKey) { - return await translateYandex(text, targetLang, yandexApiKey); - } else { - return await translateGoogle(text, targetLang); - } + if (targetLang === 'en') { + return text; + } + if (yandexApiKey) { + return await translateYandex(text, targetLang, yandexApiKey); + } else { + return await translateGoogle(text, targetLang); + } } /** @@ -49,19 +49,19 @@ async function translateText(text, targetLang, yandexApiKey) { * @returns {Promise} */ async function translateYandex(text, targetLang, apiKey) { - if (targetLang === "zh-cn") { - targetLang = "zh"; - } - try { - const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`; - const response = await axios({url, timeout: 15000}); - if (response.data && response.data["text"]) { - return response.data["text"][0]; - } - throw new Error("Invalid response for translate request"); - } catch (e) { - throw new Error(`Could not translate to "${targetLang}": ${e}`); - } + if (targetLang === 'zh-cn') { + targetLang = 'zh'; + } + try { + const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`; + const response = await axios({url, timeout: 15000}); + if (response.data && response.data['text']) { + return response.data['text'][0]; + } + throw new Error('Invalid response for translate request'); + } catch (e) { + throw new Error(`Could not translate to "${targetLang}": ${e}`); + } } /** @@ -71,21 +71,21 @@ async function translateYandex(text, targetLang, apiKey) { * @returns {Promise} */ async function translateGoogle(text, targetLang) { - try { - const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`; - const response = await axios({url, timeout: 15000}); - if (isArray(response.data)) { - // we got a valid response - return response.data[0][0][0]; - } - throw new Error("Invalid response for translate request"); - } catch (e) { - throw new Error(`Could not translate to "${targetLang}": ${e}`); - } + try { + const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`; + const response = await axios({url, timeout: 15000}); + if (isArray(response.data)) { + // we got a valid response + return response.data[0][0][0]; + } + throw new Error('Invalid response for translate request'); + } catch (e) { + throw new Error(`Could not translate to "${targetLang}": ${e}`); + } } module.exports = { - isArray, - isObject, - translateText + isArray, + isObject, + translateText }; diff --git a/main.js b/main.js index 76d2e8e..ea5a925 100644 --- a/main.js +++ b/main.js @@ -11,7 +11,7 @@ const { v4: uuidv4 } = require('uuid'); const request = require('request'); const axios = require('axios').default; const qs = require('qs'); -const Json2iob = require('./lib/json2iob'); +const Json2iob = require('json2iob'); const { extractKeys } = require('./lib/extractKeys'); // Load your modules here, e.g.: // const fs = require("fs"); @@ -90,7 +90,12 @@ class Volvo extends utils.Adapter { this.setState('info.connection', true, true); this.vinArray.forEach((vin) => { - this.getMethod(vin, 'https://vocapi.wirelesscar.net/customerapi/rest/vehicles/$vin/attributes', 'VehicleAttributes', 'attributes') + this.getMethod( + vin, + 'https://vocapi.wirelesscar.net/customerapi/rest/vehicles/$vin/attributes', + 'VehicleAttributes', + 'attributes', + ) .then(() => {}) .catch(() => {}); this.getMethod(vin, 'https://vocapi.wirelesscar.net/customerapi/rest/vehicles/$vin/status', 'VehicleStatus', 'status') @@ -103,7 +108,7 @@ class Volvo extends utils.Adapter { vin, 'https://vocapi.wirelesscar.net/customerapi/rest/vehicles/$vin/position?client_longitude=0.000000&client_precision=0.000000&client_latitude=0.000000 ', 'Position', - 'position' + 'position', ) .then(() => {}) .catch(() => {}); @@ -120,7 +125,7 @@ class Volvo extends utils.Adapter { vin, 'https://vocapi.wirelesscar.net/customerapi/rest/vehicles/$vin/position?client_longitude=0.000000&client_precision=0.000000&client_latitude=0.000000 ', 'Position', - 'position' + 'position', ) .then(() => {}) .catch(() => {}); @@ -187,7 +192,7 @@ class Volvo extends utils.Adapter { await this.setObjectNotExistsAsync(id, { type: 'device', common: { - name: id, + name: id + name, }, native: {}, }); @@ -216,10 +221,10 @@ class Volvo extends utils.Adapter { }); // end - let remoteArray = [{ command: 'Refresh', name: 'True = Refresh' }]; + const remoteArray = [{ command: 'Refresh', name: 'True = Refresh' }]; await this.requestClient({ method: 'get', - url: 'https://api.volvocars.com/connected-vehicle/v1/vehicles/' + id + '/commands', + url: 'https://api.volvocars.com/connected-vehicle/v2/vehicles/' + id + '/commands', headers: { accept: 'application/vnd.volvocars.api.connected-vehicle.commandlist.v1+json', 'vcc-api-key': this.config.vccapikey, @@ -298,7 +303,7 @@ class Volvo extends utils.Adapter { for (const endpoint of endpoints) { await this.requestClient({ method: 'get', - url: 'https://api.volvocars.com/connected-vehicle/v1/vehicles/' + vin + '/' + endpoint, + url: 'https://api.volvocars.com/connected-vehicle/v2/vehicles/' + vin + '/' + endpoint, headers: { accept: 'application/json, */*', 'vcc-api-key': this.config.vccapikey, @@ -467,7 +472,7 @@ class Volvo extends utils.Adapter { this.log.error(error.stack); reject(); } - } + }, ); }); } @@ -509,11 +514,12 @@ class Volvo extends utils.Adapter { this.log.error(error.stack); reject(); } - } + }, ); }); } async setMethod(vin, service, position) { + // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { this.baseHeader['X-Request-Id'] = uuidv4(); this.baseHeader['Accept'] = 'application/vnd.wirelesscar.com.voc.Service.v4+json; charset=utf-8'; @@ -559,7 +565,7 @@ class Volvo extends utils.Adapter { this.log.error(error.stack); reject(); } - } + }, ); }); } @@ -595,7 +601,6 @@ class Volvo extends utils.Adapter { const vin = id.split('.')[2]; const command = id.split('.')[4]; let body = ''; - let contentType = ''; if (this.config.newApi) { body = null; if (command === 'unlock') { @@ -605,7 +610,7 @@ class Volvo extends utils.Adapter { } const response = await this.requestClient({ method: 'post', - url: 'https://api.volvocars.com/connected-vehicle/v1/vehicles/' + vin + '/commands/' + command, + url: 'https://api.volvocars.com/connected-vehicle/v2/vehicles/' + vin + '/commands/' + command, headers: { 'content-type': 'application/vnd.volvocars.api.connected-vehicle.' + command.replace('-', '') + '.v1+json', 'vcc-api-key': this.config.vccapikey, diff --git a/main.test.js b/main.test.js index 307b4c6..1b0f6a9 100644 --- a/main.test.js +++ b/main.test.js @@ -1,4 +1,4 @@ -"use strict"; +'use strict'; /** * This is a dummy TypeScript test file using chai and mocha @@ -9,21 +9,21 @@ // tslint:disable:no-unused-expression -const { expect } = require("chai"); +const { expect } = require('chai'); // import { functionToTest } from "./moduleToTest"; -describe("module to test => function to test", () => { - // initializing logic - const expected = 5; +describe('module to test => function to test', () => { + // initializing logic + const expected = 5; - it(`should return ${expected}`, () => { - const result = 5; - // assign result a value from functionToTest - expect(result).to.equal(expected); - // or using the should() syntax - result.should.equal(expected); - }); - // ... more tests => it + it(`should return ${expected}`, () => { + const result = 5; + // assign result a value from functionToTest + expect(result).to.equal(expected); + // or using the should() syntax + result.should.equal(expected); + }); + // ... more tests => it }); diff --git a/package-lock.json b/package-lock.json index 49b45af..2771216 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,29 @@ { "name": "iobroker.volvo", - "version": "0.1.1", + "version": "0.1.2-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "iobroker.volvo", - "version": "0.1.1", + "version": "0.1.2-beta.0", "license": "MIT", "dependencies": { - "@iobroker/adapter-core": "^3.0.4", - "axios": "^1.6.7", + "@iobroker/adapter-core": "^3.1.4", + "axios": "^1.6.8", "json-bigint": "^1.0.0", - "qs": "^6.12.0", + "json2iob": "^2.6.11", + "qs": "^6.12.1", "request": "^2.88.0", "uuid": "^9.0.1" }, "devDependencies": { - "@iobroker/testing": "^4.1.1", - "@types/node": "^20.11.25", + "@alcalzone/release-script": "^3.7.0", + "@alcalzone/release-script-plugin-iobroker": "^3.7.0", + "@alcalzone/release-script-plugin-license": "^3.7.0", + "@alcalzone/release-script-plugin-manual-review": "^3.7.0", + "@iobroker/testing": "^4.1.3", + "@types/node": "^20.12.7", "eslint": "^8.57.0" } }, @@ -31,6 +36,237 @@ "node": ">=0.10.0" } }, + "node_modules/@alcalzone/pak": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@alcalzone/pak/-/pak-0.10.2.tgz", + "integrity": "sha512-v+kM7HlfIVNLDlGBcbZvrG3yVK3rPLH5kIoGRJbCcoHwpUqQbfEMzXAy1ZrfP+zbI5phHw2PhgrXZr3z6nh7Ow==", + "dev": true, + "dependencies": { + "axios": "^1.6.2", + "execa": "~5.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.3.7", + "tiny-glob": "^0.2.9" + } + }, + "node_modules/@alcalzone/pak/node_modules/execa": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.1.tgz", + "integrity": "sha512-4hFTjFbFzQa3aCLobpbPJR/U+VoL1wdV5ozOWjeet0AWDeYr9UFGM1eUFWHX+VtOWFq4p0xXUXfW1YxUaP4fpw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@alcalzone/release-script": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script/-/release-script-3.7.0.tgz", + "integrity": "sha512-+aDCbmDLxySKxKEoG/qnwLThj1uZWU1vRkNFeCKtNdf6DLOAevzwMcNGl/6a+CTih4M5CBSoi20orYrjHqsmLg==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "@alcalzone/release-script-plugin-changelog": "3.7.0", + "@alcalzone/release-script-plugin-exec": "3.7.0", + "@alcalzone/release-script-plugin-git": "3.7.0", + "@alcalzone/release-script-plugin-package": "3.7.0", + "@alcalzone/release-script-plugin-version": "3.7.0", + "alcalzone-shared": "^4.0.1", + "axios": "^1.6.2", + "enquirer": "^2.3.6", + "fs-extra": "^10.1.0", + "picocolors": "1.0.0", + "semver": "^7.5.2", + "source-map-support": "^0.5.21", + "yargs": "^17.4.1" + }, + "bin": { + "release-script": "bin/release.js" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-core": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-core/-/release-script-core-3.7.0.tgz", + "integrity": "sha512-4np4dBziwX/aNRhS/gpK8bwa0wpLe7oomzJ7YTUXf5bUtV/UTpN2a9tm5Bp7ElnisKj6N3AqHl4lVXRo4L9hYg==", + "dev": true, + "dependencies": { + "execa": "^5.1.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-changelog": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-changelog/-/release-script-plugin-changelog-3.7.0.tgz", + "integrity": "sha512-AlLOIjIPP42uBmvcdYkfijYDzolyY6JmfbTmdxQDBLyrgYXnuUr2GaKxbpeWSbvcAuUhNvHCAyI6LI90X3OTEg==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-exec": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-exec/-/release-script-plugin-exec-3.7.0.tgz", + "integrity": "sha512-ZhlKGhxa71mLyYB1/ojzik2RKcSAeIjuwKzlWRd6oUvKoZPe7eAjLYneXx5viQC6tvDJE4dvN1NlkFGWsSlZYA==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-git": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-git/-/release-script-plugin-git-3.7.0.tgz", + "integrity": "sha512-4wA1XNnU7uyNnzXaLe4eBd1pfyk6VhVBuTzQ5EKraLNEXZ+JWWxeYMdcJGI6QdA1qAtld91gLRfLI1Ewye9ecQ==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-iobroker": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-iobroker/-/release-script-plugin-iobroker-3.7.0.tgz", + "integrity": "sha512-6nkLIDZ4qvZ21f3ozjPJ//x+hqkaiTfkDcYnyw6SWOIUbCa5v7Xj0cAZY7INguSfjv18UOTlU1J8xdzqHxtREg==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "axios": "^1.6.2", + "fs-extra": "^10.1.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-license": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-license/-/release-script-plugin-license-3.7.0.tgz", + "integrity": "sha512-HLnKHr3pc6NJJ7zAa8S/SdC305oEurnkRa9XNP5F6rgrixsxUiynBVh0tpPsVsOTdndm7fNIBRfR66IGnw0cag==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "fs-extra": "^10.1.0", + "tiny-glob": "^0.2.9" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-manual-review": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-manual-review/-/release-script-plugin-manual-review-3.7.0.tgz", + "integrity": "sha512-lU/KJHQpYhdDcYPxiR3X5BsP9O+bNYfyP8VPE5dF9fwLgTFklbGMOhF9VjdQMiZ8Cyr7fCH7ptw+oHw+UuQutQ==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-package": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-package/-/release-script-plugin-package-3.7.0.tgz", + "integrity": "sha512-eZSzE+Hbt6otxleIGBSkXUwspKTlYdKrV8Bp9jDm0ZwSTZ/0jt6zPjL/HfCeX2hd5JtjGc/YEzuHuDVv1fHi8A==", + "dev": true, + "dependencies": { + "@alcalzone/pak": "^0.10.1", + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script-plugin-version": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-version/-/release-script-plugin-version-3.7.0.tgz", + "integrity": "sha512-030NGQeB+mglVz/58cx0WO4QiFChaSd/pz35mnOrUc9PbKWRpzisTVOt4IhCV/++YiAVibJO31NMNzvipPdx4Q==", + "dev": true, + "dependencies": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.5.2", + "tiny-glob": "^0.2.9" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/@alcalzone/release-script/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@alcalzone/release-script/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@alcalzone/release-script/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -121,9 +357,9 @@ "dev": true }, "node_modules/@iobroker/adapter-core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.4.tgz", - "integrity": "sha512-QsSeIkOa+zEVdIQ0kc0GcfsnQC+pTWWkixotdG4naKuaLUwMWK7xP0UyUEUiaHfPG3KqyZxwIxQR9HMENvvIYQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.1.4.tgz", + "integrity": "sha512-RYDGB8Vk/MEKvMMwo4fLgxY8kjHrCeQmqROo/JxQYiLBEA4/gwFCTpxdD6s7RQ+dh4yZoH16/yTWqdgyR6NAxQ==", "engines": { "npm": ">=7.0.0" }, @@ -132,9 +368,9 @@ } }, "node_modules/@iobroker/testing": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@iobroker/testing/-/testing-4.1.1.tgz", - "integrity": "sha512-TGl0o+ejiSUuJiyv6bYgOCkv3w/bOo0eEThAgl3sG3nyiWDBLuXCbtE18UlRLbFyYLOWZ1KETp1f0x7kHMKLxA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@iobroker/testing/-/testing-4.1.3.tgz", + "integrity": "sha512-PTfvlXQBXDJVX35bkJxzgjuMX6bEjUmB4Dy8+bWLqbOgyq1JQVrRn+ah5IB7hEf+4lP8wD0MpAjXFJTv3zfTvA==", "dev": true, "dependencies": { "alcalzone-shared": "~4.0.3", @@ -226,10 +462,15 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "node_modules/@types/json-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.4.tgz", + "integrity": "sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==" + }, "node_modules/@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -385,11 +626,11 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -453,6 +694,12 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -762,6 +1009,19 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -956,6 +1216,29 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1063,9 +1346,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -1180,6 +1463,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1235,6 +1530,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1355,6 +1662,15 @@ "npm": ">=1.3.7" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -1474,6 +1790,18 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1554,6 +1882,18 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, + "node_modules/json2iob": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/json2iob/-/json2iob-2.6.11.tgz", + "integrity": "sha512-62YeIptyCgp1vH9jugWgiCtAqsV5Tp8w9ukyceVt73Lr6NfRL/LyhRh2TJgxQMDo3dL25MRhlzGDbEajUnhb8A==", + "dependencies": { + "@types/json-bigint": "^1.0.4", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1651,6 +1991,24 @@ "get-func-name": "^2.0.0" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -1670,6 +2028,15 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1810,6 +2177,18 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -1835,6 +2214,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -1944,6 +2338,12 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1984,9 +2384,9 @@ } }, "node_modules/qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "dependencies": { "side-channel": "^1.0.6" }, @@ -2189,6 +2589,21 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -2252,6 +2667,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/sinon": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", @@ -2280,6 +2701,25 @@ "sinon": ">=4.0.0" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -2330,6 +2770,15 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2360,6 +2809,16 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2534,6 +2993,12 @@ "node": ">=10" } }, + "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 + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -2596,6 +3061,193 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, + "@alcalzone/pak": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@alcalzone/pak/-/pak-0.10.2.tgz", + "integrity": "sha512-v+kM7HlfIVNLDlGBcbZvrG3yVK3rPLH5kIoGRJbCcoHwpUqQbfEMzXAy1ZrfP+zbI5phHw2PhgrXZr3z6nh7Ow==", + "dev": true, + "requires": { + "axios": "^1.6.2", + "execa": "~5.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.3.7", + "tiny-glob": "^0.2.9" + }, + "dependencies": { + "execa": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.1.tgz", + "integrity": "sha512-4hFTjFbFzQa3aCLobpbPJR/U+VoL1wdV5ozOWjeet0AWDeYr9UFGM1eUFWHX+VtOWFq4p0xXUXfW1YxUaP4fpw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + } + } + }, + "@alcalzone/release-script": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script/-/release-script-3.7.0.tgz", + "integrity": "sha512-+aDCbmDLxySKxKEoG/qnwLThj1uZWU1vRkNFeCKtNdf6DLOAevzwMcNGl/6a+CTih4M5CBSoi20orYrjHqsmLg==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "@alcalzone/release-script-plugin-changelog": "3.7.0", + "@alcalzone/release-script-plugin-exec": "3.7.0", + "@alcalzone/release-script-plugin-git": "3.7.0", + "@alcalzone/release-script-plugin-package": "3.7.0", + "@alcalzone/release-script-plugin-version": "3.7.0", + "alcalzone-shared": "^4.0.1", + "axios": "^1.6.2", + "enquirer": "^2.3.6", + "fs-extra": "^10.1.0", + "picocolors": "1.0.0", + "semver": "^7.5.2", + "source-map-support": "^0.5.21", + "yargs": "^17.4.1" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "@alcalzone/release-script-core": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-core/-/release-script-core-3.7.0.tgz", + "integrity": "sha512-4np4dBziwX/aNRhS/gpK8bwa0wpLe7oomzJ7YTUXf5bUtV/UTpN2a9tm5Bp7ElnisKj6N3AqHl4lVXRo4L9hYg==", + "dev": true, + "requires": { + "execa": "^5.1.1" + } + }, + "@alcalzone/release-script-plugin-changelog": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-changelog/-/release-script-plugin-changelog-3.7.0.tgz", + "integrity": "sha512-AlLOIjIPP42uBmvcdYkfijYDzolyY6JmfbTmdxQDBLyrgYXnuUr2GaKxbpeWSbvcAuUhNvHCAyI6LI90X3OTEg==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0" + } + }, + "@alcalzone/release-script-plugin-exec": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-exec/-/release-script-plugin-exec-3.7.0.tgz", + "integrity": "sha512-ZhlKGhxa71mLyYB1/ojzik2RKcSAeIjuwKzlWRd6oUvKoZPe7eAjLYneXx5viQC6tvDJE4dvN1NlkFGWsSlZYA==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1" + } + }, + "@alcalzone/release-script-plugin-git": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-git/-/release-script-plugin-git-3.7.0.tgz", + "integrity": "sha512-4wA1XNnU7uyNnzXaLe4eBd1pfyk6VhVBuTzQ5EKraLNEXZ+JWWxeYMdcJGI6QdA1qAtld91gLRfLI1Ewye9ecQ==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "fs-extra": "^10.1.0" + } + }, + "@alcalzone/release-script-plugin-iobroker": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-iobroker/-/release-script-plugin-iobroker-3.7.0.tgz", + "integrity": "sha512-6nkLIDZ4qvZ21f3ozjPJ//x+hqkaiTfkDcYnyw6SWOIUbCa5v7Xj0cAZY7INguSfjv18UOTlU1J8xdzqHxtREg==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "axios": "^1.6.2", + "fs-extra": "^10.1.0", + "semver": "^7.5.2" + } + }, + "@alcalzone/release-script-plugin-license": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-license/-/release-script-plugin-license-3.7.0.tgz", + "integrity": "sha512-HLnKHr3pc6NJJ7zAa8S/SdC305oEurnkRa9XNP5F6rgrixsxUiynBVh0tpPsVsOTdndm7fNIBRfR66IGnw0cag==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "fs-extra": "^10.1.0", + "tiny-glob": "^0.2.9" + } + }, + "@alcalzone/release-script-plugin-manual-review": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-manual-review/-/release-script-plugin-manual-review-3.7.0.tgz", + "integrity": "sha512-lU/KJHQpYhdDcYPxiR3X5BsP9O+bNYfyP8VPE5dF9fwLgTFklbGMOhF9VjdQMiZ8Cyr7fCH7ptw+oHw+UuQutQ==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0" + } + }, + "@alcalzone/release-script-plugin-package": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-package/-/release-script-plugin-package-3.7.0.tgz", + "integrity": "sha512-eZSzE+Hbt6otxleIGBSkXUwspKTlYdKrV8Bp9jDm0ZwSTZ/0jt6zPjL/HfCeX2hd5JtjGc/YEzuHuDVv1fHi8A==", + "dev": true, + "requires": { + "@alcalzone/pak": "^0.10.1", + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.5.2" + } + }, + "@alcalzone/release-script-plugin-version": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@alcalzone/release-script-plugin-version/-/release-script-plugin-version-3.7.0.tgz", + "integrity": "sha512-030NGQeB+mglVz/58cx0WO4QiFChaSd/pz35mnOrUc9PbKWRpzisTVOt4IhCV/++YiAVibJO31NMNzvipPdx4Q==", + "dev": true, + "requires": { + "@alcalzone/release-script-core": "3.7.0", + "alcalzone-shared": "^4.0.1", + "fs-extra": "^10.1.0", + "semver": "^7.5.2", + "tiny-glob": "^0.2.9" + } + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2658,15 +3310,15 @@ "dev": true }, "@iobroker/adapter-core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.4.tgz", - "integrity": "sha512-QsSeIkOa+zEVdIQ0kc0GcfsnQC+pTWWkixotdG4naKuaLUwMWK7xP0UyUEUiaHfPG3KqyZxwIxQR9HMENvvIYQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.1.4.tgz", + "integrity": "sha512-RYDGB8Vk/MEKvMMwo4fLgxY8kjHrCeQmqROo/JxQYiLBEA4/gwFCTpxdD6s7RQ+dh4yZoH16/yTWqdgyR6NAxQ==", "requires": {} }, "@iobroker/testing": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@iobroker/testing/-/testing-4.1.1.tgz", - "integrity": "sha512-TGl0o+ejiSUuJiyv6bYgOCkv3w/bOo0eEThAgl3sG3nyiWDBLuXCbtE18UlRLbFyYLOWZ1KETp1f0x7kHMKLxA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@iobroker/testing/-/testing-4.1.3.tgz", + "integrity": "sha512-PTfvlXQBXDJVX35bkJxzgjuMX6bEjUmB4Dy8+bWLqbOgyq1JQVrRn+ah5IB7hEf+4lP8wD0MpAjXFJTv3zfTvA==", "dev": true, "requires": { "alcalzone-shared": "~4.0.3", @@ -2746,10 +3398,15 @@ "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, + "@types/json-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.4.tgz", + "integrity": "sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==" + }, "@types/node": { - "version": "20.11.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", - "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "dev": true, "requires": { "undici-types": "~5.26.4" @@ -2866,11 +3523,11 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "requires": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -2925,6 +3582,12 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3149,6 +3812,16 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + } + }, "es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -3288,6 +3961,23 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3374,9 +4064,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "forever-agent": { "version": "0.6.1", @@ -3446,6 +4136,12 @@ "hasown": "^2.0.0" } }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3486,6 +4182,18 @@ "type-fest": "^0.20.2" } }, + "globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -3568,6 +4276,12 @@ "sshpk": "^1.7.0" } }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -3654,6 +4368,12 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3725,6 +4445,15 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, + "json2iob": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/json2iob/-/json2iob-2.6.11.tgz", + "integrity": "sha512-62YeIptyCgp1vH9jugWgiCtAqsV5Tp8w9ukyceVt73Lr6NfRL/LyhRh2TJgxQMDo3dL25MRhlzGDbEajUnhb8A==", + "requires": { + "@types/json-bigint": "^1.0.4", + "json-bigint": "^1.0.0" + } + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -3802,6 +4531,21 @@ "get-func-name": "^2.0.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -3815,6 +4559,12 @@ "mime-db": "1.52.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3925,6 +4675,15 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -3944,6 +4703,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -4023,6 +4791,12 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -4051,9 +4825,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "requires": { "side-channel": "^1.0.6" } @@ -4177,6 +4951,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -4225,6 +5008,12 @@ "object-inspect": "^1.13.1" } }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "sinon": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", @@ -4246,6 +5035,22 @@ "dev": true, "requires": {} }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "sshpk": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", @@ -4282,6 +5087,12 @@ "ansi-regex": "^5.0.1" } }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4303,6 +5114,16 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "requires": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4428,6 +5249,12 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/package.json b/package.json index ea524ed..87b6dea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iobroker.volvo", - "version": "0.1.1", + "version": "0.1.2-beta.0", "description": "Volvo On Call Adapter", "author": { "name": "TA2k", @@ -17,16 +17,21 @@ "url": "https://github.com/TA2k/ioBroker.volvo" }, "dependencies": { - "@iobroker/adapter-core": "^3.0.4", - "axios": "^1.6.7", + "@iobroker/adapter-core": "^3.1.4", + "axios": "^1.6.8", "json-bigint": "^1.0.0", - "qs": "^6.12.0", + "json2iob": "^2.6.11", + "qs": "^6.12.1", "request": "^2.88.0", "uuid": "^9.0.1" }, "devDependencies": { - "@iobroker/testing": "^4.1.1", - "@types/node": "^20.11.25", + "@alcalzone/release-script": "^3.7.0", + "@alcalzone/release-script-plugin-iobroker": "^3.7.0", + "@alcalzone/release-script-plugin-license": "^3.7.0", + "@alcalzone/release-script-plugin-manual-review": "^3.7.0", + "@iobroker/testing": "^4.1.3", + "@types/node": "^20.12.7", "eslint": "^8.57.0" }, "main": "main.js", @@ -36,7 +41,8 @@ "test:unit": "mocha test/unit --exit", "test:integration": "mocha test/integration --exit", "test": "npm run test:js && npm run test:package", - "lint": "eslint" + "lint": "eslint .", + "release": "release-script --all" }, "bugs": { "url": "https://github.com/TA2k/ioBroker.volvo/issues" diff --git a/test/integration.js b/test/integration.js index 01b6e7d..1b3453e 100644 --- a/test/integration.js +++ b/test/integration.js @@ -1,5 +1,5 @@ -const path = require("path"); -const { tests } = require("@iobroker/testing"); +const path = require('path'); +const { tests } = require('@iobroker/testing'); // Run integration tests - See https://github.com/ioBroker/testing for a detailed explanation and further options -tests.integration(path.join(__dirname, "..")); +tests.integration(path.join(__dirname, '..')); diff --git a/test/mocha.setup.js b/test/mocha.setup.js index b3b9631..f3c44a8 100644 --- a/test/mocha.setup.js +++ b/test/mocha.setup.js @@ -1,13 +1,13 @@ // Don't silently swallow unhandled rejections -process.on("unhandledRejection", (e) => { - throw e; +process.on('unhandledRejection', (e) => { + throw e; }); // enable the should interface with sinon // and load chai-as-promised and sinon-chai by default -const sinonChai = require("sinon-chai"); -const chaiAsPromised = require("chai-as-promised"); -const { should, use } = require("chai"); +const sinonChai = require('sinon-chai'); +const chaiAsPromised = require('chai-as-promised'); +const { should, use } = require('chai'); should(); use(sinonChai); diff --git a/test/package.js b/test/package.js index 3a48e04..38eacc8 100644 --- a/test/package.js +++ b/test/package.js @@ -1,5 +1,5 @@ -const path = require("path"); -const { tests } = require("@iobroker/testing"); +const path = require('path'); +const { tests } = require('@iobroker/testing'); // Validate the package files -tests.packageFiles(path.join(__dirname, "..")); +tests.packageFiles(path.join(__dirname, '..')); diff --git a/test/unit.js b/test/unit.js index 2fd84c2..8e27b3a 100644 --- a/test/unit.js +++ b/test/unit.js @@ -1,5 +1,5 @@ -const path = require("path"); -const { tests } = require("@iobroker/testing"); +const path = require('path'); +const { tests } = require('@iobroker/testing'); // Run unit tests - See https://github.com/ioBroker/testing for a detailed explanation and further options -tests.unit(path.join(__dirname, "..")); +tests.unit(path.join(__dirname, '..'));