diff --git a/.github/auto-merge.yml b/.github/auto-merge.yml new file mode 100644 index 0000000..9a6f2f8 --- /dev/null +++ b/.github/auto-merge.yml @@ -0,0 +1,3 @@ +- match: + dependency_type: all + update_type: all \ No newline at end of file diff --git a/.github/labeler.yml b/.github/labeler.yml index 31e04bd..3eb730c 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,13 +1,35 @@ -# Add 'branding' to any file changes within 'noip' folder -branding: noip/* +# Add 'branding' label to any changes within 'docs' folder or any subfolders +branding: +- changed-files: + - any-glob-to-any-file: branding/** -# Add 'enhancement' label to any change to index.js file +# Add 'docs' label to any change to .md files within the entire repository +docs: +- changed-files: + - any-glob-to-any-file: '**/*.md' + +# Add 'enhancement' label to any change to src files within the source dir EXCEPT for the docs sub-folder enhancement: - - src/* - - package.json - - pakcage-lock.json - - config.schema.json +- all: + - changed-files: + - any-glob-to-any-file: 'src/**/*' + - any-glob-to-any-file: 'package.json' + - any-glob-to-any-file: 'package-lock.json' + - any-glob-to-any-file: 'config.schema.json' + +# Add 'beta' label to any PR that is opened against the `beta` branch +beta: +- base-branch: 'beta*' + +# Add 'alpha' label to any PR that is opened against the `alpha` branch +alpha: +- base-branch: 'alpha*' + +# Add 'latest' label to any PR that is opened against the `latest` branch +latest: +- base-branch: 'latest' # Add 'workflow' to any changes within 'workflow' folder or any subfolders workflow: - - .github/workflows/* +- changed-files: + - any-glob-to-any-file: .github/** \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..839d6f9 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,30 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' + +categories: + - title: 'Workflow Changes' + labels: + - 'workflow' + - title: 'Enhancements' + labels: + - 'enhancement' + - title: 'Documentation' + labels: + - 'docs' + +change-template: '- $TITLE @$AUTHOR [#$NUMBER]' +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Changes + + $CHANGES \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 6aa5d49..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ latest, beta* ] - pull_request: - branches: [ latest, beta* ] - schedule: - - cron: '17 9 * * 2' - -jobs: - analyze: - uses: donavanbecker/.github/.github/workflows/codeql-analysis.yml@latest diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml index 36f19d8..86083a1 100644 --- a/.github/workflows/dependabot.yml +++ b/.github/workflows/dependabot.yml @@ -2,16 +2,17 @@ name: AutoDependabot on: pull_request: + branches: + - beta + - latest + pull_request_target: push: branches: - beta + - latest jobs: - automerge: - name: Auto-merge dependabot updates - runs-on: ubuntu-latest - steps: - - uses: mitto98/dependabot-automerge-action@master - with: - token: ${{ github.token }} - merge: true + label: + uses: donavanbecker/.github/.github/workflows/dependabot.yml@latest + secrets: + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index de43b12..7c630a4 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -2,13 +2,11 @@ name: Release Drafter on: push: - branches: [latest] - pull_request: # required for autolabeler - types: [opened, reopened, synchronize] - workflow_dispatch: + branches: + - latest jobs: - stale: + release-drafter: uses: donavanbecker/.github/.github/workflows/release-drafter.yml@latest secrets: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 7073c14..cd33edb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "vscode.typescript-language-features" }, "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -24,5 +24,8 @@ ], "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0259703..9883906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/) +## [Version 3.0.0](https://github.com/donavanbecker/homebridge-noip/releases/tag/v3.0.0) (2023-12-23) + +### What's Changes +- Moved from CommonJS to ES Module +- Housekeeping and updated dependencies. + +**Full Changelog**: https://github.com/donavanbecker/homebridge-noip/compare/v2.0.4...v3.0.0 + ## [Version 2.0.4](https://github.com/donavanbecker/homebridge-noip/releases/tag/v2.0.4) (2023-12-15) ### What's Changes diff --git a/LICENSE b/LICENSE index b09cd78..a3774e0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,14 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +ISC License (ISC) +Copyright (c) 2023 donavanbecker + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e2b144a..1183c4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "homebridge-noip", - "version": "2.0.4", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "homebridge-noip", - "version": "2.0.4", + "version": "3.0.0", "funding": [ { "type": "Paypal", @@ -17,18 +17,18 @@ "url": "https://github.com/sponsors/donavanbecker" } ], - "license": "Apache-2.0", + "license": "ISC", "dependencies": { "@homebridge/plugin-ui-utils": "^1.0.0", "rxjs": "^7.8.1", "super-stringify": "^1.0.0", - "undici": "^6.0.1" + "undici": "^6.2.1" }, "devDependencies": { - "@types/node": "^20.10.4", - "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", - "eslint": "^8.55.0", + "@types/node": "^20.10.5", + "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/parser": "^6.15.0", + "eslint": "^8.56.0", "homebridge": "^1.7.0", "nodemon": "^3.0.2", "npm-check-updates": "^16.14.12", @@ -120,9 +120,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -769,9 +769,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -784,16 +784,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.14.0.tgz", - "integrity": "sha512-1ZJBykBCXaSHG94vMMKmiHoL0MhNHKSVlcHVYZNw+BKxufhqQVTOawNpwwI1P5nIFZ/4jLVop0mcY6mJJDFNaw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.15.0.tgz", + "integrity": "sha512-j5qoikQqPccq9QoBAupOP+CBu8BaJ8BLjaXSioDISeTZkVO3ig7oSIKh3H+rEpee7xCXtWwSB4KIL5l6hWZzpg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/type-utils": "6.14.0", - "@typescript-eslint/utils": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/type-utils": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -819,15 +819,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.14.0.tgz", - "integrity": "sha512-QjToC14CKacd4Pa7JK4GeB/vHmWFJckec49FR4hmIRf97+KXole0T97xxu9IFiPxVQ1DBWrQ5wreLwAGwWAVQA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.15.0.tgz", + "integrity": "sha512-MkgKNnsjC6QwcMdlNAel24jjkEO/0hQaMDLqP4S9zq5HBAUJNQB6y+3DwLjX7b3l2b37eNAxMPLwb3/kh8VKdA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4" }, "engines": { @@ -847,13 +847,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz", - "integrity": "sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.15.0.tgz", + "integrity": "sha512-+BdvxYBltqrmgCNu4Li+fGDIkW9n//NrruzG9X1vBzaNK+ExVXPoGB71kneaVw/Jp+4rH/vaMAGC6JfMbHstVg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0" + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -864,13 +864,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz", - "integrity": "sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.15.0.tgz", + "integrity": "sha512-CnmHKTfX6450Bo49hPg2OkIm/D/TVYV7jO1MCfPYGwf6x3GO0VU8YMO5AYMn+u3X05lRRxA4fWCz87GFQV6yVQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.14.0", - "@typescript-eslint/utils": "6.14.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/utils": "6.15.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -891,9 +891,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.14.0.tgz", - "integrity": "sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.15.0.tgz", + "integrity": "sha512-yXjbt//E4T/ee8Ia1b5mGlbNj9fB9lJP4jqLbZualwpP2BCQ5is6BcWwxpIsY4XKAhmdv3hrW92GdtJbatC6dQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -904,13 +904,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz", - "integrity": "sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.15.0.tgz", + "integrity": "sha512-7mVZJN7Hd15OmGuWrp2T9UvqR2Ecg+1j/Bp1jXUEY2GZKV6FXlOIoqVDmLpBiEiq3katvj/2n2mR0SDwtloCew==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/visitor-keys": "6.14.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -931,17 +931,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.14.0.tgz", - "integrity": "sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-eF82p0Wrrlt8fQSRL0bGXzK5nWPRV2dYQZdajcfzOD9+cQz9O7ugifrJxclB+xVOvWvagXfqS4Es7vpLP4augw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.14.0", - "@typescript-eslint/types": "6.14.0", - "@typescript-eslint/typescript-estree": "6.14.0", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", "semver": "^7.5.4" }, "engines": { @@ -956,12 +956,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz", - "integrity": "sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.15.0.tgz", + "integrity": "sha512-1zvtdC1a9h5Tb5jU9x3ADNXO9yjP8rXlaoChu0DQX40vf5ACVpYIVIZhIMZ6d5sDXH7vq4dsZBT1fEGj8D2n2w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.14.0", + "@typescript-eslint/types": "6.15.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1969,15 +1969,15 @@ } }, "node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", + "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -2193,9 +2193,9 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -5954,9 +5954,9 @@ "dev": true }, "node_modules/undici": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.0.1.tgz", - "integrity": "sha512-eZFYQLeS9BiXpsU0cuFhCwfeda2MnC48EVmmOz/eCjsTgmyTdaHdVsPSC/kwC2GtW2e0uH0HIPbadf3/bRWSxw==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.2.1.tgz", + "integrity": "sha512-7Wa9thEM6/LMnnKtxJHlc8SrTlDmxqJecgz1iy8KlsN0/iskQXOQCuPkrZLXbElPaSw5slFFyKIKXyJ3UtbApw==", "dependencies": { "@fastify/busboy": "^2.0.0" }, diff --git a/package.json b/package.json index a765247..71f6edf 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,14 @@ { "displayName": "No-IP", "name": "homebridge-noip", - "version": "2.0.4", + "version": "3.0.0", "description": "The No-IP plugin allows you to update your No-IP hostname(s) for your homebridge instance.", - "author": "donavanbecker", - "license": "Apache-2.0", + "author": { + "name": "donavanbecker", + "url": "https://github.com/donavanbecker" + }, + "type": "module", + "license": "ISC", "icon": "https://raw.githubusercontent.com/donavanbecker/homebridge-noip/beta-2.0.3/branding/icon.png", "repository": { "type": "git", @@ -23,6 +27,7 @@ "update": "ncu -u && npm update && npm install", "update dependencies": "npm run check && npm run update", "lint": "eslint src/**.ts", + "jlint": "eslint homebridge-ui/public/**.mjs", "watch": "npm run build && npm link && nodemon", "build": "rimraf ./dist && tsc", "prepublishOnly": "npm run lint && npm run build", @@ -47,15 +52,15 @@ ], "dependencies": { "@homebridge/plugin-ui-utils": "^1.0.0", - "undici": "^6.0.1", + "undici": "^6.2.1", "rxjs": "^7.8.1", "super-stringify": "^1.0.0" }, "devDependencies": { - "@types/node": "^20.10.4", - "@typescript-eslint/eslint-plugin": "^6.14.0", - "@typescript-eslint/parser": "^6.14.0", - "eslint": "^8.55.0", + "@types/node": "^20.10.5", + "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/parser": "^6.15.0", + "eslint": "^8.56.0", "nodemon": "^3.0.2", "homebridge": "^1.7.0", "npm-check-updates": "^16.14.12", diff --git a/src/devices/contactsensor.ts b/src/devices/contactsensor.ts index e31eee8..b8c2524 100644 --- a/src/devices/contactsensor.ts +++ b/src/devices/contactsensor.ts @@ -1,5 +1,5 @@ /* eslint-disable max-len */ -import { Service, PlatformAccessory, CharacteristicValue, IPv4Address } from 'homebridge'; +import { Service, PlatformAccessory, CharacteristicValue, IPv4Address, API, HAP } from 'homebridge'; import { NoIPPlatform } from '../platform'; import { interval, throwError } from 'rxjs'; import { skipWhile, timeout } from 'rxjs/operators'; @@ -15,6 +15,10 @@ export class ContactSensor { // Services private service: Service; + + public readonly api: API; + protected readonly hap: HAP; + // Characteristic Values ContactSensorState!: CharacteristicValue; @@ -30,25 +34,28 @@ export class ContactSensor { response!: string; constructor(private readonly platform: NoIPPlatform, private accessory: PlatformAccessory, public device) { + + this.api = this.platform.api; + this.hap = this.api.hap; // default placeholders - this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED; + this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED; // this is subject we use to track when we need to POST changes to the NoIP API this.SensorUpdateInProgress = false; // set accessory information accessory - .getService(this.platform.Service.AccessoryInformation)! - .setCharacteristic(this.platform.Characteristic.Manufacturer, 'No-IP') - .setCharacteristic(this.platform.Characteristic.Model, accessory.context.model) - .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.serialNumber) - .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device)) - .getCharacteristic(this.platform.Characteristic.FirmwareRevision) + .getService(this.hap.Service.AccessoryInformation)! + .setCharacteristic(this.hap.Characteristic.Manufacturer, 'No-IP') + .setCharacteristic(this.hap.Characteristic.Model, accessory.context.model) + .setCharacteristic(this.hap.Characteristic.SerialNumber, accessory.context.serialNumber) + .setCharacteristic(this.hap.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device)) + .getCharacteristic(this.hap.Characteristic.FirmwareRevision) .updateValue(this.FirmwareRevision(accessory, device)); // get the LightBulb service if it exists, otherwise create a new LightBulb service // you can create multiple services for each accessory - (this.service = this.accessory.getService(this.platform.Service.ContactSensor) || this.accessory.addService(this.platform.Service.ContactSensor)), + (this.service = this.accessory.getService(this.hap.Service.ContactSensor) || this.accessory.addService(this.hap.Service.ContactSensor)), device.hostname; // To avoid "Cannot add a Service with the same UUID another Service without aCSo defining a unique 'subtype' property." error, @@ -57,7 +64,7 @@ export class ContactSensor { // set the service name, this is what is displayed as the default name on the Home app // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method. - this.service.setCharacteristic(this.platform.Characteristic.Name, device.hostname); + this.service.setCharacteristic(this.hap.Characteristic.Name, device.hostname); // each service must implement at-minimum the "required characteristics" for the given service type // see https://developers.homebridge.io/#/service/ @@ -79,9 +86,9 @@ export class ContactSensor { */ parseStatus() { if (this.response.includes('nochg')) { - this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED; + this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_DETECTED; } else { - this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED; + this.ContactSensorState = this.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED; } this.platform.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`); } @@ -192,13 +199,13 @@ export class ContactSensor { if (this.ContactSensorState === undefined) { this.platform.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`); } else { - this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, this.ContactSensorState); + this.service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, this.ContactSensorState); this.platform.debugLog(`Contact Sensor: ${this.accessory.displayName} updateCharacteristic ContactSensorState: ${this.ContactSensorState}`); } } public apiError(e: any) { - this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e); + this.service.updateCharacteristic(this.hap.Characteristic.ContactSensorState, e); } FirmwareRevision(accessory: PlatformAccessory, device: { firmware: string }): CharacteristicValue { diff --git a/src/index.ts b/src/index.ts index 1318b2e..44fdea9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,13 @@ +/* Copyright(C) 2017-2023, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * index.ts: homebridge-cloudflared-tunnel plugin registration. + */ +import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'; import { API } from 'homebridge'; -import { PLATFORM_NAME } from './settings'; -import { NoIPPlatform } from './platform'; +import { NoIPPlatform } from './platform.js'; -/** - * This method registers the platform with Homebridge - */ -export = (api: API): void => { - api.registerPlatform(PLATFORM_NAME, NoIPPlatform); +// Register our platform with homebridge. +export default (api: API): void => { + + api.registerPlatform(PLUGIN_NAME, PLATFORM_NAME, NoIPPlatform); }; diff --git a/src/platform.ts b/src/platform.ts index f4084bf..99bde54 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -1,7 +1,11 @@ +/* Copyright(C) 2017-2023, donavanbecker (https://github.com/donavanbecker). All rights reserved. + * + * protect-platform.ts: homebridge-cloudflared-tunnel platform class. + */ +import { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge'; +import { PLATFORM_NAME, PLUGIN_NAME, NoIPPlatformConfig, DevicesConfig } from './settings.js'; +import { ContactSensor } from './devices/contactsensor.js'; import { request } from 'undici'; -import { ContactSensor } from './devices/contactsensor'; -import { PLATFORM_NAME, PLUGIN_NAME, NoIPPlatformConfig } from './settings'; -import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, Service, Characteristic } from 'homebridge'; /** * HomebridgePlatform @@ -9,25 +13,35 @@ import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, Service, Charact * parse the user config and discover/register accessories with Homebridge. */ export class NoIPPlatform implements DynamicPlatformPlugin { - public readonly Service: typeof Service = this.api.hap.Service; - public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic; - - // this is used to track restored cached accessories - public readonly accessories: PlatformAccessory[] = []; + public accessories: PlatformAccessory[]; + public readonly api: API; + public readonly log: Logging; - version = process.env.npm_package_version || '1.6.0'; + version = process.env.npm_package_version || '1.0.0'; Logging?: string; debugMode!: boolean; platformLogging?: string; + config!: NoIPPlatformConfig; - constructor(public readonly log: Logger, public readonly config: NoIPPlatformConfig, public readonly api: API) { - this.logs(); - this.debugLog(`Finished initializing platform: ${this.config.name}`); + constructor(log: Logging, config: NoIPPlatformConfig, api: API) { + this.accessories = []; + this.api = api; + this.log = log; // only load if configured - if (!this.config) { + if (!config) { return; } + // Plugin options into our config variables. + this.config = { + platform: 'NoIPPlatform', + devices: config.devices as Array, + refreshRate: config.refreshRate as number, + logging: config.logging as string, + }; + this.logs(); + this.debugLog(`Finished initializing platform: ${config.name}`); + // verify the config try { this.verifyConfig(); @@ -73,7 +87,7 @@ export class NoIPPlatform implements DynamicPlatformPlugin { * Hidden Device Discovery Option * This will disable adding any device and will just output info. */ - this.config.debug; + this.config.logging = this.config.logging || 'standard'; if (this.config.refreshRate! < 1800) { throw new Error('Refresh Rate must be above 1800 (30 minutes).'); @@ -225,8 +239,8 @@ export class NoIPPlatform implements DynamicPlatformPlugin { logs() { this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug'); - if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') { - this.platformLogging = this.config.options!.logging; + if (this.config.logging === 'debug' || this.config.logging === 'standard' || this.config?.logging === 'none') { + this.platformLogging = this.config!.logging; this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`); } else if (this.debugMode) { this.platformLogging = 'debugMode'; diff --git a/tsconfig.json b/tsconfig.json index 2dff9c8..b5ad9a3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,27 @@ { "compilerOptions": { - "target": "ES2021", - "module": "commonjs", - "lib": ["es2015", "es2016", "es2017", "es2018", "es2019", "es2020", "ES2021"], + "target": "ES2022", + "module": "ES2022", + "lib": [ + "DOM", + "ES2022" + ], "declaration": true, "declarationMap": true, "sourceMap": true, - "outDir": "./dist", - "rootDir": "./src", + "outDir": "dist", + "rootDir": "src", "strict": true, "esModuleInterop": true, - "noImplicitAny": false + "noImplicitAny": false, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", }, - "include": ["src/"], - "exclude": ["**/*.spec.ts"] -} + "include": [ + "src" + ], + "exclude": [ + "**/*.spec.ts" + ] +} \ No newline at end of file