From da7b4a713b9e58a86338ddc45f128a68811a995c Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 21 Jul 2025 16:33:05 -0700 Subject: [PATCH 01/34] Initial tracing code --- package-lock.json | 4266 +++++++++++++---- .../http/ts/package.json | 7 +- .../http/ts/src/main.ts | 236 +- .../http/ts/src/tracing.ts | 16 + 4 files changed, 3602 insertions(+), 923 deletions(-) create mode 100644 things/advanced-coffee-machine/http/ts/src/tracing.ts diff --git a/package-lock.json b/package-lock.json index fc96bd5..57713bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,11 +51,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.6", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } @@ -64,12 +63,15 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", "engines": { "node": ">=0.1.90" } }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "license": "MIT", "dependencies": { @@ -83,28 +85,67 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", + "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", + "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -113,6 +154,8 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -135,6 +178,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -149,7 +194,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -157,13 +204,27 @@ "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -175,6 +236,8 @@ }, "node_modules/@eslint/js": { "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, "license": "MIT", "engines": { @@ -183,6 +246,9 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -195,7 +261,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -205,6 +273,8 @@ }, "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -216,6 +286,8 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -228,11 +300,16 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -240,12 +317,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -255,15 +336,18 @@ }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "license": "MIT" }, "node_modules/@napi-rs/snappy-android-arm-eabi": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm-eabi/-/snappy-android-arm-eabi-7.2.2.tgz", - "integrity": "sha512-H7DuVkPCK5BlAr1NfSU8bDEN7gYs+R78pSHhDng83QxRnCLmVIZk33ymmIwurmoA1HrdTxbkbuNl+lMvNqnytw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm-eabi/-/snappy-android-arm-eabi-7.3.0.tgz", + "integrity": "sha512-KgD+8wNtS4/w7JqpiyONTwPAF74mhLnH7up+Ke4l5+jS9WFC1UexFsp+g62ugCIAmsdWfWKIpNTPpxkV7yrdYw==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -273,12 +357,13 @@ } }, "node_modules/@napi-rs/snappy-android-arm64": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm64/-/snappy-android-arm64-7.2.2.tgz", - "integrity": "sha512-2R/A3qok+nGtpVK8oUMcrIi5OMDckGYNoBLFyli3zp8w6IArPRfg1yOfVUcHvpUDTo9T7LOS1fXgMOoC796eQw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm64/-/snappy-android-arm64-7.3.0.tgz", + "integrity": "sha512-HUX9icvbWPgBDNwdxrFt1+lDfOmVsxAOMnJ+jzSYFDp2EclQjxAhPUV/rSRtS23xakHZgi6aBiJ+aY1p9Z/Fkg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -288,12 +373,13 @@ } }, "node_modules/@napi-rs/snappy-darwin-arm64": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.2.2.tgz", - "integrity": "sha512-USgArHbfrmdbuq33bD5ssbkPIoT7YCXCRLmZpDS6dMDrx+iM7eD2BecNbOOo7/v1eu6TRmQ0xOzeQ6I/9FIi5g==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.3.0.tgz", + "integrity": "sha512-shU1IOgMJRBLxqNvuqRvIr3lP8i2q/UJiwHfkipN05wzjlLN327ej0E98TarsfDgn8SDX92ovsc6zVfb4bhHbg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -303,12 +389,13 @@ } }, "node_modules/@napi-rs/snappy-darwin-x64": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-x64/-/snappy-darwin-x64-7.2.2.tgz", - "integrity": "sha512-0APDu8iO5iT0IJKblk2lH0VpWSl9zOZndZKnBYIc+ei1npw2L5QvuErFOTeTdHBtzvUHASB+9bvgaWnQo4PvTQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-x64/-/snappy-darwin-x64-7.3.0.tgz", + "integrity": "sha512-j/gaU69biRWyYq46DocHYBLjJezQhLNEjaWW3J7Y/dbil3P/+iCkvJkA0uHnIG2KXJk/QSyu2kzuy6YnMSk9Qw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -318,12 +405,13 @@ } }, "node_modules/@napi-rs/snappy-freebsd-x64": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-freebsd-x64/-/snappy-freebsd-x64-7.2.2.tgz", - "integrity": "sha512-mRTCJsuzy0o/B0Hnp9CwNB5V6cOJ4wedDTWEthsdKHSsQlO7WU9W1yP7H3Qv3Ccp/ZfMyrmG98Ad7u7lG58WXA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-freebsd-x64/-/snappy-freebsd-x64-7.3.0.tgz", + "integrity": "sha512-JnZDZDoWrUO2E8hmiU6oyrD34xazB8CVoZYCsHmkF5Yrl/5jvr/0BG3jd4SQ10wAdhQDHVwS8iaEB6GXdQxZGg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -333,12 +421,13 @@ } }, "node_modules/@napi-rs/snappy-linux-arm-gnueabihf": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm-gnueabihf/-/snappy-linux-arm-gnueabihf-7.2.2.tgz", - "integrity": "sha512-v1uzm8+6uYjasBPcFkv90VLZ+WhLzr/tnfkZ/iD9mHYiULqkqpRuC8zvc3FZaJy5wLQE9zTDkTJN1IvUcZ+Vcg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm-gnueabihf/-/snappy-linux-arm-gnueabihf-7.3.0.tgz", + "integrity": "sha512-qjEItUn91kuR6oLhXrLXSiUSB1LEz9L4lHCidmGmcIvvdM9FrceS0ny8seYuiU5fa6pZTwTO/6O3nQFQlgI+tg==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -348,12 +437,13 @@ } }, "node_modules/@napi-rs/snappy-linux-arm64-gnu": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-gnu/-/snappy-linux-arm64-gnu-7.2.2.tgz", - "integrity": "sha512-LrEMa5pBScs4GXWOn6ZYXfQ72IzoolZw5txqUHVGs8eK4g1HR9HTHhb2oY5ySNaKakG5sOgMsb1rwaEnjhChmQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-gnu/-/snappy-linux-arm64-gnu-7.3.0.tgz", + "integrity": "sha512-+v3IjUgphndbzRQ/PXoEDyORW3X4xfMPBAoQfziW1g+f+7nms+PCobWoAbGMneIGf6QP4KuLsv3clVa9+noW9g==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -363,12 +453,77 @@ } }, "node_modules/@napi-rs/snappy-linux-arm64-musl": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-musl/-/snappy-linux-arm64-musl-7.2.2.tgz", - "integrity": "sha512-3orWZo9hUpGQcB+3aTLW7UFDqNCQfbr0+MvV67x8nMNYj5eAeUtMmUE/HxLznHO4eZ1qSqiTwLbVx05/Socdlw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-musl/-/snappy-linux-arm64-musl-7.3.0.tgz", + "integrity": "sha512-8XFJIYXYrmesQ4m8xHX7jfon7HFdxY1n3eykfQaAWrKLpLMQL2x+caS6So7wpRFJI/2NyYWiY7FWYTAuMDbFVw==", "cpu": [ "arm64" ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm64-ohos": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-ohos/-/snappy-linux-arm64-ohos-7.3.0.tgz", + "integrity": "sha512-PlKHoHxeiNOQakbdMoQ0nF6GOKC52wHNCJ0Ii/JJHF8YfPIOv/BRZBEY32b8IidGj9RMq8vCa/ftBvNjIYdF5Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-ppc64-gnu": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-ppc64-gnu/-/snappy-linux-ppc64-gnu-7.3.0.tgz", + "integrity": "sha512-OJTssYn5nZC6UX9O85z4/Mtwr4ya09P0ebatb7IVNRN8GKcnkZbDOZX4HosSNNAllVQgn3n18gP45RSbtXzcGQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-riscv64-gnu": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-riscv64-gnu/-/snappy-linux-riscv64-gnu-7.3.0.tgz", + "integrity": "sha512-3O0QwzFtUm9sxDVBPjYgvAeHDw+omNJdtvamS60Yn87UZMk8V50vgDDr5NKcksmyfgdftdZfR/bFqDYCucTQuA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-s390x-gnu": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-s390x-gnu/-/snappy-linux-s390x-gnu-7.3.0.tgz", + "integrity": "sha512-hGgPn0M1tX4gUsJ/FieLsmKQgiI5p/TOlxh9WDqtIp52k9m965V9lRTEQrlUL//CndlEz3m6bk0PVgd4klNF8w==", + "cpu": [ + "s390x" + ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -378,12 +533,13 @@ } }, "node_modules/@napi-rs/snappy-linux-x64-gnu": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-gnu/-/snappy-linux-x64-gnu-7.2.2.tgz", - "integrity": "sha512-jZt8Jit/HHDcavt80zxEkDpH+R1Ic0ssiVCoueASzMXa7vwPJeF4ZxZyqUw4qeSy7n8UUExomu8G8ZbP6VKhgw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-gnu/-/snappy-linux-x64-gnu-7.3.0.tgz", + "integrity": "sha512-pBDHRUOJqC/6ZG7zy068pTItGeF4gJwO9zcZVgt951WXCvn7cIEjHhZSRim2ud8IoeH0Oumew1QYxZIxOFACJg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -393,12 +549,13 @@ } }, "node_modules/@napi-rs/snappy-linux-x64-musl": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-musl/-/snappy-linux-x64-musl-7.2.2.tgz", - "integrity": "sha512-Dh96IXgcZrV39a+Tej/owcd9vr5ihiZ3KRix11rr1v0MWtVb61+H1GXXlz6+Zcx9y8jM1NmOuiIuJwkV4vZ4WA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-musl/-/snappy-linux-x64-musl-7.3.0.tgz", + "integrity": "sha512-S+lWMBIvNYbTqGx1V2ndmcXyzIqsBTCBiU0cgtWxDNMTea5LCC749k+xxcCms/D0vwEe98qYkqAbs8IIEh1hKA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -407,13 +564,30 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/snappy-wasm32-wasi": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-wasm32-wasi/-/snappy-wasm32-wasi-7.3.0.tgz", + "integrity": "sha512-8K6OVGRzJ21BVXCYmbOa0wZrpalOWT8k/v8PbFHWcLLlghPEMJYGuGMlkzTd+VgKYjkjX1qBLaDA51+UMRWPug==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.12" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@napi-rs/snappy-win32-arm64-msvc": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-arm64-msvc/-/snappy-win32-arm64-msvc-7.2.2.tgz", - "integrity": "sha512-9No0b3xGbHSWv2wtLEn3MO76Yopn1U2TdemZpCaEgOGccz1V+a/1d16Piz3ofSmnA13HGFz3h9NwZH9EOaIgYA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-arm64-msvc/-/snappy-win32-arm64-msvc-7.3.0.tgz", + "integrity": "sha512-TzBl/dmHt+8JGZrv0eQ1j7dL6XuSor7K/1EZ2hwX1vxe/rdygZfIlMJlYbUuEqiK2ZJD1AVuc5WhqyQADu0t+A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -423,12 +597,13 @@ } }, "node_modules/@napi-rs/snappy-win32-ia32-msvc": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-ia32-msvc/-/snappy-win32-ia32-msvc-7.2.2.tgz", - "integrity": "sha512-QiGe+0G86J74Qz1JcHtBwM3OYdTni1hX1PFyLRo3HhQUSpmi13Bzc1En7APn+6Pvo7gkrcy81dObGLDSxFAkQQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-ia32-msvc/-/snappy-win32-ia32-msvc-7.3.0.tgz", + "integrity": "sha512-UVIIzEcxSo4TKNs8PGrfAjCHKlbxCljnQFjYPEwv8O9YaNpQoSy6pZU4SdO5aB4SRbqhSoqtkJlaKFBiHLa8Zw==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -438,12 +613,13 @@ } }, "node_modules/@napi-rs/snappy-win32-x64-msvc": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.2.2.tgz", - "integrity": "sha512-a43cyx1nK0daw6BZxVcvDEXxKMFLSBSDTAhsFD0VqSKcC7MGUBMaqyoWUcMiI7LBSz4bxUmxDWKfCYzpEmeb3w==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.3.0.tgz", + "integrity": "sha512-4vI5r2QY0NRIe0l/Vsgs+cqZDIFqtsqwSJVVBuCfcf1G39AXQ7g1bstdxnE4s6MHh/Xis7h2vsajYNnQh6xX4Q==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -452,8 +628,22 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@node-wot/binding-coap": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/binding-coap/-/binding-coap-0.8.16.tgz", + "integrity": "sha512-WJRLZSRd+YugQ+biSSsH5DM9Jr4H72HVTHqRaFWUg2lxSiGJGC28EQK/KSyfvxLepZwsNf/VqaHWvgQOCj1bGA==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@node-wot/core": "0.8.16", @@ -468,10 +658,29 @@ }, "node_modules/@node-wot/binding-coap/node_modules/@types/node": { "version": "16.18.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.35.tgz", + "integrity": "sha512-yqU2Rf94HFZqgHf6Tuyc/IqVD0l3U91KjvypSr1GtJKyrnl6L/kfnxVqN4QOwcF5Zx9tO/HKK+fozGr5AtqA+g==", "license": "MIT" }, + "node_modules/@node-wot/binding-coap/node_modules/wot-thing-description-types": { + "version": "1.1.0-09-November-2023", + "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", + "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", + "license": "W3C-20150513" + }, + "node_modules/@node-wot/binding-coap/node_modules/wot-typescript-definitions": { + "version": "0.8.0-SNAPSHOT.29", + "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", + "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", + "license": "W3C-20150513", + "dependencies": { + "wot-thing-description-types": "1.1.0-09-November-2023" + } + }, "node_modules/@node-wot/binding-http": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/binding-http/-/binding-http-0.8.16.tgz", + "integrity": "sha512-PqpjyEcJt1apjWpObtctPfQ+iK2FAf5IHrwESiMHL0fdGtbA1/tw0KZdC8/krZK7DtI+WvY+fnajdvS0MAqhvw==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@node-wot/core": "0.8.16", @@ -491,6 +700,7 @@ "version": "0.8.16", "resolved": "https://registry.npmjs.org/@node-wot/binding-modbus/-/binding-modbus-0.8.16.tgz", "integrity": "sha512-7OAX4SduuE8Sm/XrXdv7kaSyykJ/xtRpmg5+EcXl9YrAORHT3SdFZPsvoGz/UGsAE7R95VW55r19Yx9h3rOOOw==", + "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@node-wot/core": "0.8.16", "modbus-serial": "^8.0.17", @@ -498,8 +708,25 @@ "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" } }, + "node_modules/@node-wot/binding-modbus/node_modules/wot-thing-description-types": { + "version": "1.1.0-09-November-2023", + "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", + "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", + "license": "W3C-20150513" + }, + "node_modules/@node-wot/binding-modbus/node_modules/wot-typescript-definitions": { + "version": "0.8.0-SNAPSHOT.29", + "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", + "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", + "license": "W3C-20150513", + "dependencies": { + "wot-thing-description-types": "1.1.0-09-November-2023" + } + }, "node_modules/@node-wot/binding-mqtt": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/binding-mqtt/-/binding-mqtt-0.8.16.tgz", + "integrity": "sha512-GgEl5nbLjY96YaZClL/mCq0JL3ROH9cKE41UKM0ymKs8dvNlKmLeC7YLN1NCMKHcYVaxvJSrIaDVgEtadF8qEw==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@node-wot/core": "0.8.16", @@ -510,6 +737,8 @@ }, "node_modules/@node-wot/core": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/core/-/core-0.8.16.tgz", + "integrity": "sha512-viHaXIeIryx+sm0H8oBnR5mUSTFj9raWaJYCNa/BGphfOUhcOB5pajS5NOJcQUzSy76Z9XY3JMw3taRAuPTvsw==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@petamoriken/float16": "^3.1.1", @@ -528,6 +757,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { @@ -540,6 +771,8 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", "engines": { @@ -548,6 +781,8 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", "dependencies": { @@ -558,34 +793,187 @@ "node": ">= 8" } }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.9.0.tgz", + "integrity": "sha512-Ur+TgRmJgAEvg6VQuhkqzsWsqoOtr+QSZ8r8Yf6WrvlZpAl/sdRU+yUXWjA7r8JFS9VbBq7IEp7oMStFuJT2ow==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.9.0.tgz", + "integrity": "sha512-Koy1ApRUp5DB5KpOqhDk0JjO9x6QeEkmcePl8qQDsXZGF4MuHUBShXibd+J2tRNckTsvgEHi1uEuUckDgN+c/A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.9.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/exporter-jaeger": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-jaeger/-/exporter-jaeger-1.9.0.tgz", + "integrity": "sha512-XLsDLuTqQyw08s0n03zeqmz2ike/iQHiep819SJliJnJJKMbGta+JvaWWgrh/YUEYlbBLc/mQP1cndXtd8lbaA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.0", + "@opentelemetry/sdk-trace-base": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0", + "jaeger-client": "^3.15.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.9.0.tgz", + "integrity": "sha512-5M/NvJj7ZHZXEU8lkAFhrSrWaHmCCkFLstNbL8p16qpTn1AOZowuSjMOYRoJJBmL5PUobkZ3W8Gjov1UgldPBg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.9.0.tgz", + "integrity": "sha512-oo8RyuyzEbbXdIfeEG9iA5vmTH4Kld+dZMIZICd5G5SmeNcNes3sLrparpunIGms41wIP2mWiIlcOelDCmGceg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.9.0.tgz", + "integrity": "sha512-zCyien0p3XWarU6zv72c/JZ6QlG5QW/hc61Nh5TSR1K9ndnljzAGrH55x4nfyQdubfoh9QxLNh9FXH0fWK6vcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.9.0.tgz", + "integrity": "sha512-glNgtJjxAIrDku8DG5Xu3nBK25rT+hkyg7yuXh8RUurp/4BcsXjMyVqpyJvb2kg+lxAX73VJBhncRKGHn9t8QQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.9.0.tgz", + "integrity": "sha512-VTpjiqGQ4s8f0/szgZmVrtNSSmXFNoHwC4PNVwXyNeEqQcqyAygHvobpUG6m7qCiBFh6ZtrCuLdhhqWE04Objw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.9.0", + "@opentelemetry/core": "1.9.0", + "@opentelemetry/propagator-b3": "1.9.0", + "@opentelemetry/propagator-jaeger": "1.9.0", + "@opentelemetry/sdk-trace-base": "1.9.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.9.0.tgz", + "integrity": "sha512-po7penSfQ/Z8352lRVDpaBrd9znwA5mHGqXR7nDEiVnxkDFkBIhVf/tKeAJDIq/erFpcRowKFeCsr5eqqcSyFQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@petamoriken/float16": { - "version": "3.8.7", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz", + "integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==", "license": "MIT" }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -594,35 +982,44 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" }, "node_modules/@rtsao/scc": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true, "license": "MIT" }, "node_modules/@serialport/binding-mock": { "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", "license": "MIT", "dependencies": { "@serialport/bindings-interface": "^1.2.1", @@ -634,6 +1031,8 @@ }, "node_modules/@serialport/bindings-cpp": { "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-11.0.3.tgz", + "integrity": "sha512-xgNDJ7pHHZCJMoDsEH+D8q5CV+V3RGN4/jLEG9SQ7q6kh+o03axV0l/upPHZ0HW4tTXpGgqPIGbXOTrD4RGQQA==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -652,6 +1051,8 @@ }, "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -662,6 +1063,8 @@ }, "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "11.0.0" @@ -675,6 +1078,8 @@ }, "node_modules/@serialport/bindings-cpp/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -690,10 +1095,14 @@ }, "node_modules/@serialport/bindings-cpp/node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/@serialport/bindings-interface": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", + "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", "license": "MIT", "engines": { "node": "^12.22 || ^14.13 || >=16" @@ -701,6 +1110,8 @@ }, "node_modules/@serialport/parser-byte-length": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-11.0.1.tgz", + "integrity": "sha512-UsffR5b3NHwhjJzsWv5fZMkoq3wGNyUcRTA9jlu02w+2kMlBRJPzlPVB5szVX0VWUEqkCg+3VaU2XWuYr+uAUA==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -711,6 +1122,8 @@ }, "node_modules/@serialport/parser-cctalk": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-11.0.1.tgz", + "integrity": "sha512-klzVQfRcC1m0SVDV2Dy9hHfwweO2/mUMUyuXK04FRkKHy5/AdETmk9KTVVVVfpDCSysvHoyQPwiDFq8ddwX3cQ==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -721,6 +1134,8 @@ }, "node_modules/@serialport/parser-delimiter": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.1.tgz", + "integrity": "sha512-NAsYa3OFt2xEnj/+0BRkQP2qkRNbXBPEq6uFJEdNdzcTSF+BTRXkoIRrWBq3N6koovPqW6lnbxc/iJYe5AX/2Q==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -731,6 +1146,8 @@ }, "node_modules/@serialport/parser-inter-byte-timeout": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-11.0.1.tgz", + "integrity": "sha512-PEFV9dSpW+ptH1rLhdB9KgE+rbJ/FvQiZz0mx+4jkv/Po4g3PNsEEMXfMW0aQVSFVsmitvmE0jHlhGjLv8GQEg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -741,6 +1158,8 @@ }, "node_modules/@serialport/parser-packet-length": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-11.0.1.tgz", + "integrity": "sha512-KwPu8dsAI+eN4fnUS1vVmrOpUtBK4p9L9cHhwn5ZmfcvwvZMHp/J+IEu7xH0g5aM1/8QEoaql26BQP+sZ71NQQ==", "license": "MIT", "engines": { "node": ">=8.6.0" @@ -748,6 +1167,8 @@ }, "node_modules/@serialport/parser-readline": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.1.tgz", + "integrity": "sha512-wkJ3EI733+yhbi7eBWzs/qn8+cfIBcYQjfrILPNqslAy6VlgdKw+pHoblDFmg78GN0TqGUDSWlTJ65oLEPVp5Q==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "11.0.1" @@ -761,6 +1182,8 @@ }, "node_modules/@serialport/parser-ready": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-11.0.1.tgz", + "integrity": "sha512-v/bvlgKhrNt+SVLSqlfXCO1HEinfRRMGnzqbpdVCgu2SiWIEenCLjs51JisKVYQoQFcXdP/EHZnzm7NPXHDlAg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -771,6 +1194,8 @@ }, "node_modules/@serialport/parser-regex": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-11.0.1.tgz", + "integrity": "sha512-Lf3k7qibYqZ0+/wX3UA8fRng3WtQ+UyLpjQhG1COs6OBSq5/I5tYXczfhlrbA0gHo1qzgzr2V2t7m6FoBSc81Q==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -781,6 +1206,8 @@ }, "node_modules/@serialport/parser-slip-encoder": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-11.0.1.tgz", + "integrity": "sha512-l4mXsAGzpmPO7+uqKJqtPDW643irfnGEWbiy34FoYvuOs8n0SmiMtgQZFAtvlTNQCRWE2tykF/WG6K/McJthDw==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -791,6 +1218,8 @@ }, "node_modules/@serialport/parser-spacepacket": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-11.0.1.tgz", + "integrity": "sha512-Lq7fXoOsLOMo4XEt9HB31zV5LhrteXlsOy2o6r39TfRwU6x8Nou9jQMA9vW0a6yPra5zwsHIaNrA6tDOGj2Ozg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -801,6 +1230,8 @@ }, "node_modules/@serialport/stream": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-11.0.1.tgz", + "integrity": "sha512-6pjyKRg8MQuvhGfg36+PF7K5eGNQcEswCSiAg1UPilqqFS8X1QnaiSCn5UFp/hCN+pAtlFjkOi0ztvtmSI7n4g==", "license": "MIT", "dependencies": { "@serialport/bindings-interface": "1.2.2", @@ -815,6 +1246,8 @@ }, "node_modules/@serialport/stream/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -830,27 +1263,35 @@ }, "node_modules/@serialport/stream/node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/@servie/events": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@servie/events/-/events-1.0.0.tgz", + "integrity": "sha512-sBSO19KzdrJCM3gdx6eIxV8M9Gxfgg6iDQmH5TIAGaUu+X9VDdsINXJOnoiZ1Kx3TrHdH4bt5UVglkjsEGBcvw==", "license": "MIT" }, "node_modules/@thingweb/thing-model": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@thingweb/thing-model/-/thing-model-1.0.4.tgz", + "integrity": "sha512-09oa2VVG2yGTXCKbXco25t5bQ5n/BG+BPhKoR/IZrEKLJVPbml20Y9VZusscTTRNxYR2VBrFdON+WhomtIRrdg==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "ajv": "^8.11.0", "ajv-formats": "^3.0.1", "debug": "^4.3.4", "json-placeholder-replacer": "^2.0.4", - "wot-thing-description-types": "1.1.0-09-November-2023", - "wot-thing-model-types": "^1.1.0-09-November-2023", - "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" + "wot-thing-description-types": "^1.1.0-12-March-2025", + "wot-thing-model-types": "^1.1.0-12-March-2025", + "wot-typescript-definitions": "^0.8.0-SNAPSHOT.30" } }, "node_modules/@thingweb/thing-model/node_modules/ajv-formats": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -864,36 +1305,48 @@ } } }, - "node_modules/@thingweb/thing-model/node_modules/json-placeholder-replacer": { - "version": "2.0.5", - "license": "MIT", - "bin": { - "jpr": "dist/index.js", - "json-placeholder-replacer": "dist/index.js" - } - }, "node_modules/@tsconfig/node10": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/body-parser": { - "version": "1.19.5", + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -902,12 +1355,16 @@ } }, "node_modules/@types/chai": { - "version": "4.3.19", + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", "dev": true, "license": "MIT" }, "node_modules/@types/chai-as-promised": { "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", "dev": true, "license": "MIT", "dependencies": { @@ -916,6 +1373,8 @@ }, "node_modules/@types/connect": { "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", "dependencies": { @@ -924,6 +1383,8 @@ }, "node_modules/@types/debug": { "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, "license": "MIT", "dependencies": { @@ -932,10 +1393,14 @@ }, "node_modules/@types/eventsource": { "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@types/eventsource/-/eventsource-1.1.10.tgz", + "integrity": "sha512-rYzRmJSnm44Xb7FICRXEjwe/26ZiiS+VMGmuD17PevMP56cGgLEsaM955sYQW0S+K7h+mPOL70vGf1hi4WDjVA==", "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.21", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -946,7 +1411,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.5", + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", "dev": true, "license": "MIT", "dependencies": { @@ -957,39 +1424,53 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.4", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true, "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true, "license": "MIT" }, "node_modules/@types/mocha": { - "version": "10.0.8", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", "dev": true, "license": "MIT" }, "node_modules/@types/ms": { - "version": "0.7.34", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { - "version": "22.5.5", + "version": "22.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.5.tgz", + "integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==", "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.11", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", "dev": true, "license": "MIT", "dependencies": { @@ -998,25 +1479,32 @@ } }, "node_modules/@types/qs": { - "version": "6.9.16", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "dev": true, "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, "license": "MIT" }, "node_modules/@types/readable-stream": { - "version": "4.0.15", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz", + "integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==", "license": "MIT", "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" + "@types/node": "*" } }, "node_modules/@types/send": { - "version": "0.17.4", + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", "dev": true, "license": "MIT", "dependencies": { @@ -1025,7 +1513,9 @@ } }, "node_modules/@types/serve-static": { - "version": "1.15.7", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", "dev": true, "license": "MIT", "dependencies": { @@ -1036,34 +1526,41 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT" }, "node_modules/@types/triple-beam": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.12", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", + "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.6.0", - "@typescript-eslint/type-utils": "8.6.0", - "@typescript-eslint/utils": "8.6.0", - "@typescript-eslint/visitor-keys": "8.6.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/type-utils": "8.38.0", + "@typescript-eslint/utils": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1073,24 +1570,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.38.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", + "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.6.0", - "@typescript-eslint/types": "8.6.0", - "@typescript-eslint/typescript-estree": "8.6.0", - "@typescript-eslint/visitor-keys": "8.6.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", "debug": "^4.3.4" }, "engines": { @@ -1101,39 +1596,79 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.38.0", + "@typescript-eslint/types": "^8.38.0", + "debug": "^4.3.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.6.0", - "@typescript-eslint/visitor-keys": "8.6.0" + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", + "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.6.0", - "@typescript-eslint/utils": "8.6.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/utils": "8.38.0", "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1142,14 +1677,15 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", "dev": true, "license": "MIT", "engines": { @@ -1161,18 +1697,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.6.0", - "@typescript-eslint/visitor-keys": "8.6.0", + "@typescript-eslint/project-service": "8.38.0", + "@typescript-eslint/tsconfig-utils": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1181,35 +1721,21 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.6.0", - "@typescript-eslint/types": "8.6.0", - "@typescript-eslint/typescript-estree": "8.6.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1219,16 +1745,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.6.0", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.6.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.38.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1238,13 +1767,30 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -1255,10 +1801,14 @@ }, "node_modules/accept-language-parser": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==", "license": "MIT" }, "node_modules/accepts": { "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -1269,7 +1819,9 @@ } }, "node_modules/acorn": { - "version": "8.12.1", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -1281,6 +1833,8 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1289,6 +1843,8 @@ }, "node_modules/acorn-walk": { "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, "license": "MIT", "dependencies": { @@ -1304,6 +1860,8 @@ }, "node_modules/aedes": { "version": "0.46.3", + "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.46.3.tgz", + "integrity": "sha512-i3B+H74uNRhlqcs/JdrMp7e3daz4Cwls0x4yLcfjGXz2tIwnxhF6od4m86O6yyNdz/Gg3jfY3q0sc/Cz8qzg6g==", "license": "MIT", "dependencies": { "aedes-packet": "^2.3.1", @@ -1327,6 +1885,8 @@ }, "node_modules/aedes-packet": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-2.3.1.tgz", + "integrity": "sha512-LqBd57uc2rui2RbjycW17dylglejG26mM4ewVXGNDnVp/SUHFVEgm7d1HTmYrnSkSCNoHti042qgcTwv/F+BtQ==", "license": "MIT", "dependencies": { "mqtt-packet": "^6.3.0" @@ -1337,6 +1897,8 @@ }, "node_modules/aedes-packet/node_modules/bl": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -1346,6 +1908,8 @@ }, "node_modules/aedes-packet/node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -1368,6 +1932,8 @@ }, "node_modules/aedes-packet/node_modules/mqtt-packet": { "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", "license": "MIT", "dependencies": { "bl": "^4.0.2", @@ -1377,6 +1943,8 @@ }, "node_modules/aedes-persistence": { "version": "8.1.3", + "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-8.1.3.tgz", + "integrity": "sha512-VMCjEV+2g1TNJb/IlDEUy6SP9crT+QUhe2xc6UjyqrFNBNgTvHmOefXY7FxWrwmR2QA02vwg3+5p/JXkyg/Dkw==", "license": "MIT", "dependencies": { "aedes-packet": "^2.3.1", @@ -1389,6 +1957,8 @@ }, "node_modules/aedes/node_modules/uuid": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -1396,6 +1966,8 @@ }, "node_modules/ajv": { "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -1410,6 +1982,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -1423,8 +1997,18 @@ } } }, + "node_modules/ansi-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-color/-/ansi-color-0.2.1.tgz", + "integrity": "sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ==", + "engines": { + "node": "*" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "license": "MIT", "engines": { @@ -1433,7 +2017,9 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -1441,47 +2027,109 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "license": "ISC", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "optional": true, "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "optional": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "safe-buffer": "~5.1.0" } }, "node_modules/arg": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true, "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -1492,19 +2140,25 @@ }, "node_modules/array-flatten": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, "node_modules/array-includes": { - "version": "3.1.8", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1514,16 +2168,19 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1533,14 +2190,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1550,14 +2209,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1567,18 +2228,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -1589,6 +2251,8 @@ }, "node_modules/assertion-error": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, "license": "MIT", "engines": { @@ -1598,23 +2262,39 @@ "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" }, "node_modules/async-exit-hook": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/asynckit": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true, "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1629,10 +2309,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -1651,6 +2335,8 @@ }, "node_modules/basic-auth": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" @@ -1661,6 +2347,8 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "license": "MIT", "engines": { @@ -1670,8 +2358,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { - "version": "6.0.15", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.0.tgz", + "integrity": "sha512-ClDyJGQkc8ZtzdAAbAwBmhMSpwN/sC9HA8jxdYm6nVUbCfZbe2mgza4qh7AuEYyEPB/c4Kznf9s66bnsKMQDjw==", "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.0", @@ -1680,8 +2380,19 @@ "readable-stream": "^4.2.0" } }, + "node_modules/bl/node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/bl/node_modules/readable-stream": { - "version": "4.5.2", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -1696,6 +2407,8 @@ }, "node_modules/body-parser": { "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -1718,6 +2431,8 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -1725,10 +2440,14 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1737,6 +2456,8 @@ }, "node_modules/braces": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { @@ -1748,6 +2469,8 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true, "license": "ISC" }, @@ -1755,6 +2478,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "license": "(MIT OR Apache-2.0)", "bin": { "btoa": "bin/btoa.js" }, @@ -1764,6 +2488,8 @@ }, "node_modules/buffer": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -1786,31 +2512,28 @@ }, "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==", "license": "MIT" }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "peer": true, + "node_modules/bufrw": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/bufrw/-/bufrw-1.4.0.tgz", + "integrity": "sha512-sWm8iPbqvL9+5SiYxXH73UOkyEbGQg7kyHQmReF89WJHQJw2eV4P/yZ0E+b71cczJ4pPobVhXxgQcmfSTgGHxQ==", "dependencies": { - "semver": "^7.0.0" + "ansi-color": "^0.2.1", + "error": "^7.0.0", + "hexer": "^1.5.0", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.x" } }, "node_modules/bulk-write-stream": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", + "integrity": "sha512-XWOLjgHtpDasHfwM8oO4df1JoZwa7/OwTsXDzh4rUTo+9CowzeOFBZz43w+H14h1fyq+xl28tVIBrdjcjj4Gug==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -1819,24 +2542,59 @@ }, "node_modules/byte-length": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/byte-length/-/byte-length-1.0.2.tgz", + "integrity": "sha512-ovBpjmsgd/teRmgcPh23d4gJvxDoXtAzEL9xTfMU8Yc2kqCDb7L9jAG0XHl1nzuGl+h3ebCIF1i62UFyA9V/2Q==", "license": "MIT" }, "node_modules/bytes": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind": { - "version": "1.0.7", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -1847,6 +2605,8 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -1855,6 +2615,8 @@ }, "node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", "engines": { @@ -1866,10 +2628,14 @@ }, "node_modules/capitalize": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/capitalize/-/capitalize-2.0.4.tgz", + "integrity": "sha512-wcSyiFqXRYyCoqu0o0ekXzJAKCLMkqWS5QWGlgTJFJKwRmI6pzcN2hBl5VPq9RzLW5Uf4FF/V/lcFfjCtVak2w==", "license": "MIT" }, "node_modules/cbor": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "license": "MIT", "dependencies": { "nofilter": "^3.1.0" @@ -1880,6 +2646,8 @@ }, "node_modules/chai": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", "dependencies": { @@ -1897,6 +2665,8 @@ }, "node_modules/chai-as-promised": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "dev": true, "license": "WTFPL", "dependencies": { @@ -1908,6 +2678,8 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -1921,19 +2693,10 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/check-error": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, "license": "MIT", "dependencies": { @@ -1945,6 +2708,8 @@ }, "node_modules/chokidar": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -1966,8 +2731,30 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC", + "optional": true + }, "node_modules/client-oauth2": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/client-oauth2/-/client-oauth2-4.3.3.tgz", + "integrity": "sha512-k8AvUYJon0vv75ufoVo4nALYb/qwFFicO3I0+39C6xEdflqVtr+f9cy+0ZxAduoVSTfhP5DX2tY2XICAd5hy6Q==", "license": "Apache-2.0", "dependencies": { "popsicle": "^12.0.5", @@ -1979,6 +2766,8 @@ }, "node_modules/client-oauth2/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -1997,6 +2786,8 @@ }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "license": "ISC", "dependencies": { @@ -2005,29 +2796,10 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/coap": { - "version": "1.4.0", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/coap/-/coap-1.4.2.tgz", + "integrity": "sha512-kmlhZJTf6GgC7cs7bTj3oq2AOS9uFFw9AWbhVjuyMEiD3ByM8+3m/jSxaFM38aRfINJMxAD5tAwfNkIspX1Ccw==", "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.14", @@ -2036,7 +2808,7 @@ "coap-packet": "^1.1.1", "debug": "^4.3.5", "fastseries": "^2.0.0", - "lru-cache": "^10.2.2", + "lru-cache": "^11.0.2", "readable-stream": "^4.5.2" }, "engines": { @@ -2049,13 +2821,26 @@ }, "node_modules/coap-packet": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/coap-packet/-/coap-packet-1.1.1.tgz", + "integrity": "sha512-Bkz2ZKI/7hU2gm6nUuo5l+MBSkdFJx7My1ZgNEhKUC7K2yYfQYVbBPRa64BBYLcEcYgaSlau4A1Uw5xfM2I0zw==", "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/coap/node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/coap/node_modules/readable-stream": { - "version": "4.5.2", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -2068,10 +2853,21 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/color": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" @@ -2079,6 +2875,8 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2090,12 +2888,15 @@ }, "node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2105,6 +2906,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -2112,12 +2914,14 @@ "node_modules/color/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" }, "node_modules/colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", "dependencies": { "color": "^3.1.3", "text-hex": "1.0.x" @@ -2125,6 +2929,8 @@ }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "license": "MIT", "dependencies": { @@ -2136,14 +2942,20 @@ }, "node_modules/commist": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==", "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, "node_modules/concat-stream": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "engines": [ "node >= 6.0" ], @@ -2156,12 +2968,23 @@ } }, "node_modules/confbox": { - "version": "0.1.7", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", "dev": true, "license": "MIT" }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC", + "optional": true + }, "node_modules/content-disposition": { "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -2172,6 +2995,8 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -2190,13 +3015,17 @@ }, "node_modules/content-type": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.6.0", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -2204,14 +3033,20 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/crc": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz", + "integrity": "sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==", "license": "MIT", "engines": { "node": ">=12" @@ -2227,11 +3062,15 @@ }, "node_modules/create-require": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -2244,13 +3083,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2260,27 +3101,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -2292,7 +3137,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2308,6 +3155,8 @@ }, "node_modules/decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "license": "MIT", "engines": { @@ -2319,13 +3168,30 @@ }, "node_modules/decode-uri-component": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "license": "MIT", "engines": { "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/deep-eql": { "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "license": "MIT", "dependencies": { @@ -2335,13 +3201,28 @@ "node": ">=6" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/define-data-property": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -2357,6 +3238,8 @@ }, "node_modules/define-properties": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -2373,14 +3256,25 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT", + "optional": true + }, "node_modules/depd": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -2388,14 +3282,31 @@ }, "node_modules/destroy": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/diff": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -2404,6 +3315,8 @@ }, "node_modules/dns-packet": { "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -2414,6 +3327,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2424,7 +3339,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.5", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -2433,95 +3350,127 @@ "url": "https://dotenvx.com" } }, - "node_modules/duplexify": { - "version": "4.1.3", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/ee-first": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true, "license": "MIT" }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { - "version": "1.4.4", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "license": "MIT", "dependencies": { "once": "^1.4.0" } }, + "node_modules/error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==", + "dependencies": { + "string-template": "~0.2.1", + "xtend": "~4.0.0" + } + }, "node_modules/es-abstract": { - "version": "1.23.3", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", + "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -2531,25 +3480,27 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } }, "node_modules/es-errors": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "dev": true, + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2559,34 +3510,44 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -2597,6 +3558,8 @@ }, "node_modules/escalade": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -2605,10 +3568,14 @@ }, "node_modules/escape-html": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -2620,6 +3587,9 @@ }, "node_modules/eslint": { "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { @@ -2672,23 +3642,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-compat-utils": { - "version": "0.5.1", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "license": "MIT", "bin": { @@ -2700,6 +3657,8 @@ }, "node_modules/eslint-config-standard": { "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", + "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", "dev": true, "funding": [ { @@ -2728,6 +3687,8 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "license": "MIT", "dependencies": { @@ -2738,6 +3699,8 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2745,7 +3708,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.11.0", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -2762,6 +3727,8 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2770,6 +3737,8 @@ }, "node_modules/eslint-plugin-es": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2786,60 +3755,44 @@ "eslint": ">=4.19.1" } }, - "node_modules/eslint-plugin-es-x": { - "version": "7.8.0", - "dev": true, - "funding": [ - "https://github.com/sponsors/ota-meshi", - "https://opencollective.com/eslint" - ], - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.11.0", - "eslint-compat-utils": "^0.5.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, "node_modules/eslint-plugin-import": { - "version": "2.30.0", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.9.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2849,6 +3802,8 @@ }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2857,6 +3812,8 @@ }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2868,6 +3825,8 @@ }, "node_modules/eslint-plugin-import/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -2879,64 +3838,18 @@ }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-node": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", "dev": true, "license": "MIT", "dependencies": { @@ -2955,7 +3868,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2963,8 +3878,20 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint-plugin-node/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -2976,6 +3903,8 @@ }, "node_modules/eslint-plugin-node/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", "bin": { @@ -2984,6 +3913,8 @@ }, "node_modules/eslint-plugin-notice": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-notice/-/eslint-plugin-notice-1.0.0.tgz", + "integrity": "sha512-M3VLQMZzZpvfTZ/vy9FmClIKq5rLBbQpM0KgfLZPJPrVXpmJYeobmmb+lfJzHWdNm8PWwvw8KlafQWo2N9xx1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2995,23 +3926,10 @@ "eslint": ">=3.0.0" } }, - "node_modules/eslint-plugin-promise": { - "version": "6.6.0", - "dev": true, - "license": "ISC", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, "node_modules/eslint-plugin-unused-imports": { "version": "4.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", + "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3026,6 +3944,8 @@ }, "node_modules/eslint-plugin-workspaces": { "version": "0.10.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-workspaces/-/eslint-plugin-workspaces-0.10.1.tgz", + "integrity": "sha512-17p+ljQq2oYtN+cS6F52wRCV7xVh5fHiBOhQaYkSShRwRdiTvEkD6gvGysZjx08ckr9cozIFqI9SxdgTWDV9+g==", "dev": true, "license": "MIT", "dependencies": { @@ -3034,6 +3954,8 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3049,6 +3971,8 @@ }, "node_modules/eslint-utils": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "license": "MIT", "dependencies": { @@ -3063,6 +3987,8 @@ }, "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3071,6 +3997,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3082,6 +4010,8 @@ }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -3096,7 +4026,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3104,24 +4036,27 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, + "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">= 4" } }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -3133,6 +4068,8 @@ }, "node_modules/espree": { "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3149,6 +4086,8 @@ }, "node_modules/esquery": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -3160,6 +4099,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3171,6 +4112,8 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3179,6 +4122,8 @@ }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3187,6 +4132,8 @@ }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3194,6 +4141,8 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -3201,6 +4150,8 @@ }, "node_modules/events": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -3208,13 +4159,27 @@ }, "node_modules/eventsource": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", "license": "MIT", "engines": { "node": ">=12.0.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/express": { - "version": "4.21.0", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -3222,7 +4187,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -3236,7 +4201,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -3251,10 +4216,16 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -3262,10 +4233,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -3284,14 +4259,20 @@ }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -3299,24 +4280,43 @@ "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" } }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fast-querystring": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" @@ -3324,6 +4324,8 @@ }, "node_modules/fast-unique-numbers": { "version": "8.0.13", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", + "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.8", @@ -3334,11 +4336,25 @@ } }, "node_modules/fast-uri": { - "version": "3.0.1", - "license": "MIT" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastfall": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha512-KH6p+Z8AKPXnmA7+Iz2Lh8ARCMr+8WNPVludm1LGkZoD2MjY6LVnRMtTKhkdzI+jr0RzQWXKzKyBJm1zoHEL4Q==", "license": "MIT", "dependencies": { "reusify": "^1.0.0" @@ -3349,6 +4365,8 @@ }, "node_modules/fastparallel": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", "license": "ISC", "dependencies": { "reusify": "^1.0.4", @@ -3356,7 +4374,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -3365,15 +4385,20 @@ }, "node_modules/fastseries": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz", + "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", "license": "ISC" }, "node_modules/fecha": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" }, "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "license": "MIT", "dependencies": { @@ -3383,8 +4408,17 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT", + "optional": true + }, "node_modules/fill-range": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { @@ -3396,6 +4430,8 @@ }, "node_modules/filter-obj": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3403,6 +4439,8 @@ }, "node_modules/finalhandler": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -3419,6 +4457,8 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -3426,10 +4466,14 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/find-my-way": { "version": "7.7.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.7.0.tgz", + "integrity": "sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -3442,11 +4486,15 @@ }, "node_modules/find-root": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true, "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -3462,6 +4510,8 @@ }, "node_modules/find-workspaces": { "version": "0.3.1", + "resolved": "https://registry.npmjs.org/find-workspaces/-/find-workspaces-0.3.1.tgz", + "integrity": "sha512-UDkGILGJSA1LN5Aa7McxCid4sqW3/e+UYsVwyxki3dDT0F8+ym0rAfnCkEfkL0rO7M+8/mvkim4t/s3IPHmg+w==", "dev": true, "license": "MIT", "dependencies": { @@ -3472,6 +4522,8 @@ }, "node_modules/flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "license": "BSD-3-Clause", "bin": { @@ -3480,6 +4532,8 @@ }, "node_modules/flat-cache": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "license": "MIT", "dependencies": { @@ -3492,30 +4546,45 @@ } }, "node_modules/flatted": { - "version": "3.3.1", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" }, "node_modules/for-each": { - "version": "0.3.3", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/form-data": { - "version": "4.0.0", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -3524,6 +4593,8 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3531,6 +4602,8 @@ }, "node_modules/fresh": { "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3538,14 +4611,24 @@ }, "node_modules/from2": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "license": "MIT", "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, + "node_modules/from2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, "node_modules/from2/node_modules/readable-stream": { "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -3559,18 +4642,32 @@ }, "node_modules/from2/node_modules/string_decoder": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT", + "optional": true + }, "node_modules/fs.realpath": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -3582,20 +4679,26 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { - "version": "1.1.6", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -3606,14 +4709,87 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "license": "MIT", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "license": "ISC", "engines": { @@ -3622,6 +4798,8 @@ }, "node_modules/get-func-name": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "license": "MIT", "engines": { @@ -3629,14 +4807,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -3645,14 +4830,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-symbol-description": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -3661,20 +4861,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.8.1", - "dev": true, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT", - "peer": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } + "optional": true }, "node_modules/glob": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -3692,18 +4890,35 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, "node_modules/globals": { "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3718,6 +4933,8 @@ }, "node_modules/globalthis": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3732,10 +4949,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3743,19 +4962,28 @@ }, "node_modules/graphemer": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, "node_modules/has-bigints": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -3764,6 +4992,9 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -3773,8 +5004,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -3783,7 +5020,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -3794,6 +5033,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { @@ -3806,8 +5047,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC", + "optional": true + }, "node_modules/hasown": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3818,6 +5068,8 @@ }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "license": "MIT", "bin": { @@ -3826,8 +5078,27 @@ }, "node_modules/help-me": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", "license": "MIT" }, + "node_modules/hexer": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hexer/-/hexer-1.5.0.tgz", + "integrity": "sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==", + "dependencies": { + "ansi-color": "^0.2.1", + "minimist": "^1.1.0", + "process": "^0.10.0", + "xtend": "^4.0.0" + }, + "bin": { + "hexer": "cli.js" + }, + "engines": { + "node": ">= 0.10.x" + } + }, "node_modules/http-calculator": { "resolved": "things/calculator/http/express", "link": true @@ -3838,6 +5109,8 @@ }, "node_modules/http-errors": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -3852,6 +5125,8 @@ }, "node_modules/hyperid": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.3.0.tgz", + "integrity": "sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ==", "license": "MIT", "dependencies": { "buffer": "^5.2.1", @@ -3861,6 +5136,8 @@ }, "node_modules/hyperid/node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -3883,6 +5160,8 @@ }, "node_modules/hyperid/node_modules/uuid": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -3890,6 +5169,8 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -3900,6 +5181,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -3917,7 +5200,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.2", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -3925,7 +5210,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3941,6 +5228,8 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -3949,6 +5238,9 @@ }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -3957,23 +5249,49 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC", + "optional": true + }, "node_modules/internal-slot": { - "version": "1.0.7", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -3981,18 +5299,23 @@ }, "node_modules/is-absolute-url": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-array-buffer": { - "version": "3.0.4", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -4004,14 +5327,40 @@ "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-bigint": { - "version": "1.0.4", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4019,6 +5368,8 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { @@ -4029,12 +5380,14 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4043,23 +5396,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", "engines": { @@ -4070,7 +5410,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -4084,10 +5426,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -4098,11 +5444,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4113,14 +5462,63 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -4130,8 +5528,23 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "license": "MIT", "engines": { @@ -4143,6 +5556,8 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { @@ -4150,11 +5565,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4165,6 +5583,8 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "license": "MIT", "engines": { @@ -4173,6 +5593,8 @@ }, "node_modules/is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "license": "MIT", "engines": { @@ -4180,13 +5602,30 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4195,11 +5634,13 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -4212,6 +5653,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -4220,11 +5662,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4234,11 +5679,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4248,11 +5697,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -4263,6 +5714,8 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", "engines": { @@ -4272,28 +5725,95 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.2", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/isarray": { - "version": "1.0.0", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, + "node_modules/jaeger-client": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/jaeger-client/-/jaeger-client-3.19.0.tgz", + "integrity": "sha512-M0c7cKHmdyEUtjemnJyx/y9uX16XHocL46yQvyqDlPdvAcwPDbHrIbKjQdBqtiE4apQ/9dmr+ZLJYYPGnurgpw==", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0", + "opentracing": "^0.14.4", + "thriftrw": "^3.5.0", + "uuid": "^8.3.2", + "xorshift": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jaeger-client/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/js-sdsl": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "license": "MIT", "funding": { "type": "opencollective", @@ -4302,6 +5822,8 @@ }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { @@ -4311,13 +5833,23 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, "node_modules/json-buffer": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-placeholder-replacer": { - "version": "1.0.37", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/json-placeholder-replacer/-/json-placeholder-replacer-2.1.2.tgz", + "integrity": "sha512-C4/IPS34x4YKxhrvTBzDf6+Akn/vgRW3QKvzljWm3KLK2mQhBnNYYwXrin+knp7tF7mxmDW7NIMdSPVT33vN0g==", "license": "MIT", "bin": { "jpr": "dist/index.js", @@ -4326,15 +5858,21 @@ }, "node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/json5": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "license": "MIT", "dependencies": { @@ -4346,6 +5884,8 @@ }, "node_modules/keyv": { "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -4355,17 +5895,13 @@ "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/leven": { - "version": "2.1.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4378,6 +5914,8 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -4392,16 +5930,22 @@ }, "node_modules/lodash": { "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true, "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { @@ -4416,9 +5960,10 @@ } }, "node_modules/logform": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.1.tgz", - "integrity": "sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -4432,12 +5977,18 @@ } }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/long/-/long-2.4.0.tgz", + "integrity": "sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.6" + } }, "node_modules/loupe": { "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "license": "MIT", "dependencies": { @@ -4445,22 +5996,42 @@ } }, "node_modules/lru-cache": { - "version": "10.4.3", - "license": "ISC" + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } }, "node_modules/make-error": { "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "license": "ISC" }, "node_modules/make-error-cause": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-2.3.0.tgz", + "integrity": "sha512-etgt+n4LlOkGSJbBTV9VROHA5R7ekIPS4vfh+bCAoJgRrJWdqJCBbpS3osRJ/HrT7R68MzMiY3L3sDJ/Fd8aBg==", "license": "Apache-2.0", "dependencies": { "make-error": "^1.3.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4468,6 +6039,8 @@ }, "node_modules/merge-descriptors": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4475,6 +6048,8 @@ }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", "engines": { @@ -4483,6 +6058,8 @@ }, "node_modules/methods": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4490,11 +6067,15 @@ }, "node_modules/metric-lcs": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/metric-lcs/-/metric-lcs-0.1.2.tgz", + "integrity": "sha512-+TZ5dUDPKPJaU/rscTzxyN8ZkX7eAVLAiQU/e+YINleXPv03SCmJShaMT1If1liTH8OcmWXZs0CmzCBRBLcMpA==", "dev": true, "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -4507,6 +6088,8 @@ }, "node_modules/mime": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -4517,6 +6100,8 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -4524,6 +6109,8 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -4532,37 +6119,68 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { - "version": "5.1.6", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT", + "optional": true + }, "node_modules/mlly": { - "version": "1.7.1", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" } }, "node_modules/mocha": { - "version": "10.7.3", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "license": "MIT", "dependencies": { @@ -4595,8 +6213,39 @@ "node": ">= 14.0.0" } }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/modbus": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/modbus/-/modbus-1.1.3.tgz", + "integrity": "sha512-Y4NvKFNxOvp4KgsL/MXDEauvP3VtA7bAHlXXwv21/d+/o3ppIToweshm3sVhy5ivbSnA3nZ2hQZnlgvlpE4b1A==", "license": "MIT", "dependencies": { "crc": "^4.3.2", @@ -4608,7 +6257,9 @@ "link": true }, "node_modules/modbus-serial": { - "version": "8.0.17", + "version": "8.0.21", + "resolved": "https://registry.npmjs.org/modbus-serial/-/modbus-serial-8.0.21.tgz", + "integrity": "sha512-KBhDrMWNf00jf6v1wE/7c6A7ysgE2xx7PfQzSmQViHrGBb4soYEbtnSTf8agoymxwEt8FaDfQCgOLmAojDOOxA==", "license": "ISC", "dependencies": { "debug": "^4.3.1", @@ -4617,6 +6268,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/bindings-cpp": { "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", + "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -4635,6 +6288,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4645,6 +6300,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "11.0.0" @@ -4658,6 +6315,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-byte-length": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", + "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4668,6 +6327,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-cctalk": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", + "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4678,6 +6339,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-delimiter": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4688,6 +6351,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-inter-byte-timeout": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", + "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4698,6 +6363,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-packet-length": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", + "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", "license": "MIT", "engines": { "node": ">=8.6.0" @@ -4705,6 +6372,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-readline": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "12.0.0" @@ -4718,6 +6387,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-ready": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", + "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4728,6 +6399,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-regex": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", + "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4738,6 +6411,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-slip-encoder": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", + "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4748,6 +6423,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/parser-spacepacket": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", + "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4758,6 +6435,8 @@ }, "node_modules/modbus-serial/node_modules/@serialport/stream": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", + "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", "license": "MIT", "dependencies": { "@serialport/bindings-interface": "1.2.2", @@ -4772,6 +6451,8 @@ }, "node_modules/modbus-serial/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -4787,14 +6468,20 @@ }, "node_modules/modbus-serial/node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/modbus-serial/node_modules/node-addon-api": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==", "license": "MIT" }, "node_modules/modbus-serial/node_modules/serialport": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz", + "integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==", "license": "MIT", "dependencies": { "@serialport/binding-mock": "10.2.2", @@ -4821,6 +6508,8 @@ }, "node_modules/modbus/node_modules/@serialport/bindings-cpp": { "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", + "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -4839,6 +6528,8 @@ }, "node_modules/modbus/node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4849,6 +6540,8 @@ }, "node_modules/modbus/node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "11.0.0" @@ -4862,6 +6555,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-byte-length": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", + "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4872,6 +6567,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-cctalk": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", + "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4882,6 +6579,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-delimiter": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4892,6 +6591,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-inter-byte-timeout": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", + "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4902,6 +6603,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-packet-length": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", + "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", "license": "MIT", "engines": { "node": ">=8.6.0" @@ -4909,6 +6612,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-readline": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", "license": "MIT", "dependencies": { "@serialport/parser-delimiter": "12.0.0" @@ -4922,6 +6627,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-ready": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", + "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4932,6 +6639,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-regex": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", + "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4942,6 +6651,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-slip-encoder": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", + "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4952,6 +6663,8 @@ }, "node_modules/modbus/node_modules/@serialport/parser-spacepacket": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", + "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -4962,6 +6675,8 @@ }, "node_modules/modbus/node_modules/@serialport/stream": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", + "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", "license": "MIT", "dependencies": { "@serialport/bindings-interface": "1.2.2", @@ -4976,6 +6691,8 @@ }, "node_modules/modbus/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -4991,14 +6708,20 @@ }, "node_modules/modbus/node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/modbus/node_modules/node-addon-api": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==", "license": "MIT" }, "node_modules/modbus/node_modules/serialport": { "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz", + "integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==", "license": "MIT", "dependencies": { "@serialport/binding-mock": "10.2.2", @@ -5025,6 +6748,8 @@ }, "node_modules/mqemitter": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-4.5.0.tgz", + "integrity": "sha512-Mp/zytFeIv6piJQkEKnncHcP4R/ErJc5C7dfonkhkNUT2LA/nTayrfNxbipp3M5iCJUTQSUtzfQAQA3XVcKz6w==", "license": "ISC", "dependencies": { "fastparallel": "^2.3.0", @@ -5035,25 +6760,27 @@ } }, "node_modules/mqtt": { - "version": "5.10.1", + "version": "5.13.3", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.3.tgz", + "integrity": "sha512-91x03kh1+vBBA51OMNbEw2fymXfaUjpHkC0NcMckg9Vf6ee/GrM/HXfE8XeeziHQpJL8adr+9ThTbN5v/WmrRA==", "license": "MIT", "dependencies": { - "@types/readable-stream": "^4.0.5", - "@types/ws": "^8.5.9", + "@types/readable-stream": "^4.0.18", + "@types/ws": "^8.18.1", "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.3.4", + "debug": "^4.4.0", "help-me": "^5.0.0", - "lru-cache": "^10.0.1", + "lru-cache": "^10.4.3", "minimist": "^1.2.8", - "mqtt-packet": "^9.0.0", + "mqtt-packet": "^9.0.2", "number-allocator": "^1.0.14", - "readable-stream": "^4.4.2", - "reinterval": "^1.1.0", - "rfdc": "^1.3.0", + "readable-stream": "^4.7.0", + "rfdc": "^1.4.1", + "socks": "^2.8.3", "split2": "^4.2.0", - "worker-timers": "^7.1.4", - "ws": "^8.17.1" + "worker-timers": "^7.1.8", + "ws": "^8.18.0" }, "bin": { "mqtt": "build/bin/mqtt.js", @@ -5070,6 +6797,8 @@ }, "node_modules/mqtt-packet": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz", + "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==", "license": "MIT", "dependencies": { "bl": "^4.0.2", @@ -5079,6 +6808,8 @@ }, "node_modules/mqtt-packet/node_modules/bl": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -5088,6 +6819,8 @@ }, "node_modules/mqtt-packet/node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -5108,8 +6841,16 @@ "ieee754": "^1.1.13" } }, + "node_modules/mqtt/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/mqtt/node_modules/mqtt-packet": { - "version": "9.0.0", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.2.tgz", + "integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==", "license": "MIT", "dependencies": { "bl": "^6.0.8", @@ -5117,8 +6858,19 @@ "process-nextick-args": "^2.0.1" } }, + "node_modules/mqtt/node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/mqtt/node_modules/readable-stream": { - "version": "4.5.2", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -5133,10 +6885,14 @@ }, "node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", @@ -5146,24 +6902,82 @@ "multicast-dns": "cli.js" } }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "license": "MIT", + "optional": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/node-addon-api": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "license": "MIT" }, + "node_modules/node-aead-crypto": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/node-aead-crypto/-/node-aead-crypto-2.2.2.tgz", + "integrity": "sha512-EtCLL1FmVjj2GlBNcLRn75ea+y6yGuEdoTpqc9zIiRkIKk1ucTsOPoKaHYYxHfMAXWqHu2Dw8a44VSSKz45UTg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "2.14.x", + "prebuild-install": "^6.1.3" + }, + "engines": { + "node": ">4" + } + }, "node_modules/node-coap-client": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/node-coap-client/-/node-coap-client-1.0.8.tgz", + "integrity": "sha512-ADki3zyiITRkKVKKa33OsE6Kkr8lMRdURvNgz+ozAuBFPY867BAq8AAsKL5MqlIaFMfW3b2Dq27gaDiRFH4T6w==", "license": "MIT", "dependencies": { "debug": "^4.1.1", @@ -5175,6 +6989,8 @@ }, "node_modules/node-dtls-client": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/node-dtls-client/-/node-dtls-client-0.6.0.tgz", + "integrity": "sha512-TApzfBpbTkJOVouhgy9qJJB1Oui6sZz/1yNs1VNXTBWkF2ZgO594k58Y1moabAuTHzTUEc0XfwWmoz1yl8sx9Q==", "license": "MIT", "dependencies": { "debug": "^4.1.1", @@ -5189,6 +7005,8 @@ }, "node_modules/node-fetch": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -5207,6 +7025,8 @@ }, "node_modules/node-gyp-build": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "license": "MIT", "bin": { "node-gyp-build": "bin.js", @@ -5214,8 +7034,16 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, "node_modules/nofilter": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "license": "MIT", "engines": { "node": ">=12.19" @@ -5223,22 +7051,62 @@ }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "node_modules/number-allocator": { "version": "1.0.14", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", "license": "MIT", "dependencies": { "debug": "^4.3.1", "js-sdsl": "4.3.0" } }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { - "version": "1.13.2", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -5249,6 +7117,8 @@ }, "node_modules/object-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "engines": { @@ -5256,13 +7126,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -5274,6 +7148,8 @@ }, "node_modules/object.fromentries": { "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5291,6 +7167,8 @@ }, "node_modules/object.groupby": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5303,11 +7181,14 @@ } }, "node_modules/object.values": { - "version": "1.2.0", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -5320,6 +7201,8 @@ }, "node_modules/on-finished": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -5330,6 +7213,8 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -5339,12 +7224,24 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", "dependencies": { "fn.name": "1.x.x" } }, + "node_modules/opentracing": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, "node_modules/optionator": { "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -5359,8 +7256,28 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5375,6 +7292,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -5389,6 +7308,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -5400,6 +7321,8 @@ }, "node_modules/parseurl": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -5407,6 +7330,8 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -5415,6 +7340,8 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5422,6 +7349,8 @@ }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { @@ -5430,20 +7359,28 @@ }, "node_modules/path-parse": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.10", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/pathe": { - "version": "1.1.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, "node_modules/pathval": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, "license": "MIT", "engines": { @@ -5452,6 +7389,8 @@ }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -5462,17 +7401,21 @@ } }, "node_modules/pkg-types": { - "version": "1.2.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "dev": true, "license": "MIT", "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", - "pathe": "^1.1.2" + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" } }, "node_modules/popsicle": { "version": "12.1.2", + "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-12.1.2.tgz", + "integrity": "sha512-xE2vEUa15TiHvFhGmKTtdKk9aSLL5CHX8Vw5kHfVM3R0YHiaTon6Ybsamw0XYqMR+Ng2RijX88iYUKPBMpLBww==", "license": "MIT", "dependencies": { "popsicle-content-encoding": "^1.0.0", @@ -5490,6 +7433,8 @@ }, "node_modules/popsicle-content-encoding": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popsicle-content-encoding/-/popsicle-content-encoding-1.0.0.tgz", + "integrity": "sha512-4Df+vTfM8wCCJVTzPujiI6eOl3SiWQkcZg0AMrOkD1enMXsF3glIkFUZGvour1Sj7jOWCsNSEhBxpbbhclHhzw==", "license": "MIT", "peerDependencies": { "servie": "^4.0.0" @@ -5497,6 +7442,8 @@ }, "node_modules/popsicle-cookie-jar": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/popsicle-cookie-jar/-/popsicle-cookie-jar-1.0.1.tgz", + "integrity": "sha512-QVIZhADP8nDbXIQW6wq8GU9IOSE8INUACO/9KD9TFKQ7qq8r/y3qUDz59xIi6p6TH19lCJJyBAPSXP1liIoySw==", "license": "MIT", "dependencies": { "@types/tough-cookie": "^4.0.2", @@ -5511,6 +7458,8 @@ }, "node_modules/popsicle-redirects": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/popsicle-redirects/-/popsicle-redirects-1.1.1.tgz", + "integrity": "sha512-mC2HrKjdTAWDalOjGxlXw9j6Qxrz/Yd2ui6bPxpi2IQDYWpF4gUAMxbA8EpSWJhLi0PuWKDwTHHPrUPGutAoIA==", "license": "MIT", "peerDependencies": { "servie": "^4.1.0" @@ -5518,6 +7467,8 @@ }, "node_modules/popsicle-transport-http": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/popsicle-transport-http/-/popsicle-transport-http-1.2.1.tgz", + "integrity": "sha512-i5r3IGHkGiBDm1oPFvOfEeSGWR0lQJcsdTqwvvDjXqcTHYJJi4iSi3ecXIttDiTBoBtRAFAE9nF91fspQr63FQ==", "license": "MIT", "dependencies": { "make-error-cause": "^2.2.0" @@ -5528,6 +7479,8 @@ }, "node_modules/popsicle-transport-xhr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/popsicle-transport-xhr/-/popsicle-transport-xhr-2.0.0.tgz", + "integrity": "sha512-5Sbud4Widngf1dodJE5cjEYXkzEUIl8CzyYRYR57t6vpy9a9KPGQX6KBKdPjmBZlR5A06pOBXuJnVr23l27rtA==", "license": "MIT", "peerDependencies": { "servie": "^4.2.0" @@ -5535,21 +7488,55 @@ }, "node_modules/popsicle-user-agent": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popsicle-user-agent/-/popsicle-user-agent-1.0.0.tgz", + "integrity": "sha512-epKaq3TTfTzXcxBxjpoKYMcTTcAX8Rykus6QZu77XNhJuRHSRxMd+JJrbX/3PFI0opFGSN0BabbAYCbGxbu0mA==", "license": "MIT", "peerDependencies": { "servie": "^4.0.0" } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, + "node_modules/prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -5573,21 +7560,25 @@ } }, "node_modules/process": { - "version": "0.11.10", - "license": "MIT", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/process/-/process-0.10.1.tgz", + "integrity": "sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==", "engines": { "node": ">= 0.6.0" } }, "node_modules/process-nextick-args": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", + "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -5606,8 +7597,16 @@ "node": ">=12.0.0" } }, + "node_modules/protobufjs/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/proxy-addr": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -5618,11 +7617,21 @@ } }, "node_modules/psl": { - "version": "1.9.0", - "license": "MIT" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/pump": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -5631,6 +7640,8 @@ }, "node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" @@ -5638,6 +7649,8 @@ }, "node_modules/qlobber": { "version": "5.0.3", + "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz", + "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==", "license": "MIT", "engines": { "node": ">= 8" @@ -5645,6 +7658,8 @@ }, "node_modules/qs": { "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -5658,6 +7673,8 @@ }, "node_modules/query-string": { "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", "license": "MIT", "dependencies": { "decode-uri-component": "^0.2.2", @@ -5674,10 +7691,14 @@ }, "node_modules/querystringify": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -5697,6 +7718,8 @@ }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5705,6 +7728,8 @@ }, "node_modules/range-parser": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -5712,6 +7737,8 @@ }, "node_modules/raw-body": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -5723,8 +7750,36 @@ "node": ">= 0.8" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -5737,6 +7792,8 @@ }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { @@ -5746,19 +7803,42 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "license": "MIT" + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5769,6 +7849,8 @@ }, "node_modules/regexpp": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "license": "MIT", "engines": { @@ -5778,12 +7860,10 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/reinterval": { - "version": "1.1.0", - "license": "MIT" - }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { @@ -5792,6 +7872,8 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5799,43 +7881,45 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, "node_modules/resolve": { - "version": "1.22.8", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/ret": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", "license": "MIT", "engines": { "node": ">=4" @@ -5843,10 +7927,14 @@ }, "node_modules/retimer": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", "license": "MIT" }, "node_modules/reusify": { - "version": "1.0.4", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -5855,10 +7943,15 @@ }, "node_modules/rfdc": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -5872,7 +7965,9 @@ } }, "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5882,6 +7977,9 @@ }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -5901,6 +7999,8 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -5912,6 +8012,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -5934,6 +8036,8 @@ }, "node_modules/rxjs": { "version": "5.5.11", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", + "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", "license": "Apache-2.0", "dependencies": { "symbol-observable": "1.0.1" @@ -5943,13 +8047,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -5959,23 +8066,39 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "dev": true, - "license": "MIT" - }, "node_modules/safe-buffer": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex-test": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -5986,6 +8109,8 @@ }, "node_modules/safe-regex2": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", + "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", "license": "MIT", "dependencies": { "ret": "~0.2.0" @@ -5995,16 +8120,21 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/safer-buffer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/semver": { - "version": "7.6.3", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -6015,6 +8145,8 @@ }, "node_modules/send": { "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -6037,6 +8169,8 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -6044,10 +8178,14 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/send/node_modules/encodeurl": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6055,6 +8193,8 @@ }, "node_modules/serialize-javascript": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6063,6 +8203,8 @@ }, "node_modules/serialport": { "version": "11.0.1", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-11.0.1.tgz", + "integrity": "sha512-j/ntDuewAkqL6g5wKjwV2RTyLBL9cpob8aRd3yLAViYApTsJoYqRleyuzst0OboNTBjBsoxQ4YKYhuYHi1XViQ==", "license": "MIT", "dependencies": { "@serialport/binding-mock": "10.2.2", @@ -6089,6 +8231,8 @@ }, "node_modules/serialport/node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -6104,10 +8248,14 @@ }, "node_modules/serialport/node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "license": "MIT" }, "node_modules/serve-static": { "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", @@ -6121,6 +8269,8 @@ }, "node_modules/servie": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/servie/-/servie-4.3.3.tgz", + "integrity": "sha512-b0IrY3b1gVMsWvJppCf19g1p3JSnS0hQi6xu4Hi40CIhf0Lx8pQHcvBL+xunShpmOiQzg1NOia812NAWdSaShw==", "license": "Apache-2.0", "dependencies": { "@servie/events": "^1.0.0", @@ -6128,8 +8278,18 @@ "ts-expect": "^1.1.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC", + "optional": true + }, "node_modules/set-function-length": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -6145,6 +8305,8 @@ }, "node_modules/set-function-name": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6157,12 +8319,31 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -6174,6 +8355,8 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { @@ -6181,13 +8364,69 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -6196,29 +8435,83 @@ "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==", + "license": "ISC", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.3.1" } }, "node_modules/slugify": { "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", "license": "MIT", "engines": { "node": ">=8.0.0" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/smart-home": { "resolved": "mashups/smart-home", "link": true }, "node_modules/snappy": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.2.2.tgz", - "integrity": "sha512-iADMq1kY0v3vJmGTuKcFWSXt15qYUz7wFkArOrsSg0IFfI3nJqIJvK2/ZbEIndg7erIJLtAVX2nSOqPz7DcwbA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.3.0.tgz", + "integrity": "sha512-Qd1XxFO71HOOA6RxWkO5yHcYrQyBZOqGFKv99DD75bS34I3J6HEudlO4Lo617B6A6fJJ87YS5oYY9NZXxlXGkw==", + "license": "MIT", "optional": true, "engines": { "node": ">= 10" @@ -6227,24 +8520,45 @@ "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, - "optionalDependencies": { - "@napi-rs/snappy-android-arm-eabi": "7.2.2", - "@napi-rs/snappy-android-arm64": "7.2.2", - "@napi-rs/snappy-darwin-arm64": "7.2.2", - "@napi-rs/snappy-darwin-x64": "7.2.2", - "@napi-rs/snappy-freebsd-x64": "7.2.2", - "@napi-rs/snappy-linux-arm-gnueabihf": "7.2.2", - "@napi-rs/snappy-linux-arm64-gnu": "7.2.2", - "@napi-rs/snappy-linux-arm64-musl": "7.2.2", - "@napi-rs/snappy-linux-x64-gnu": "7.2.2", - "@napi-rs/snappy-linux-x64-musl": "7.2.2", - "@napi-rs/snappy-win32-arm64-msvc": "7.2.2", - "@napi-rs/snappy-win32-ia32-msvc": "7.2.2", - "@napi-rs/snappy-win32-x64-msvc": "7.2.2" + "optionalDependencies": { + "@napi-rs/snappy-android-arm-eabi": "7.3.0", + "@napi-rs/snappy-android-arm64": "7.3.0", + "@napi-rs/snappy-darwin-arm64": "7.3.0", + "@napi-rs/snappy-darwin-x64": "7.3.0", + "@napi-rs/snappy-freebsd-x64": "7.3.0", + "@napi-rs/snappy-linux-arm-gnueabihf": "7.3.0", + "@napi-rs/snappy-linux-arm64-gnu": "7.3.0", + "@napi-rs/snappy-linux-arm64-musl": "7.3.0", + "@napi-rs/snappy-linux-arm64-ohos": "7.3.0", + "@napi-rs/snappy-linux-ppc64-gnu": "7.3.0", + "@napi-rs/snappy-linux-riscv64-gnu": "7.3.0", + "@napi-rs/snappy-linux-s390x-gnu": "7.3.0", + "@napi-rs/snappy-linux-x64-gnu": "7.3.0", + "@napi-rs/snappy-linux-x64-musl": "7.3.0", + "@napi-rs/snappy-wasm32-wasi": "7.3.0", + "@napi-rs/snappy-win32-arm64-msvc": "7.3.0", + "@napi-rs/snappy-win32-ia32-msvc": "7.3.0", + "@napi-rs/snappy-win32-x64-msvc": "7.3.0" + } + }, + "node_modules/socks": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.6.tgz", + "integrity": "sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA==", + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, "node_modules/split-on-first": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", "license": "MIT", "engines": { "node": ">=6" @@ -6252,32 +8566,55 @@ }, "node_modules/split2": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "license": "ISC", "engines": { "node": ">= 10.x" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/statuses": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/stream-shift": { - "version": "1.0.3", - "license": "MIT" + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/strict-uri-encode": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", "license": "MIT", "engines": { "node": ">=4" @@ -6285,6 +8622,8 @@ }, "node_modules/string_decoder": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -6292,6 +8631,8 @@ }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -6308,15 +8649,40 @@ ], "license": "MIT" }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.trim": { - "version": "1.2.9", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6326,20 +8692,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "license": "MIT", "dependencies": { @@ -6356,7 +8730,9 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -6367,6 +8743,8 @@ }, "node_modules/strip-bom": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "license": "MIT", "engines": { @@ -6375,6 +8753,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -6385,21 +8765,22 @@ } }, "node_modules/supports-color": { - "version": "8.1.1", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", "engines": { @@ -6411,31 +8792,125 @@ }, "node_modules/symbol-observable": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, "license": "MIT" }, + "node_modules/thriftrw": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/thriftrw/-/thriftrw-3.11.4.tgz", + "integrity": "sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==", + "dependencies": { + "bufrw": "^1.2.1", + "error": "7.0.2", + "long": "^2.4.0" + }, + "bin": { + "thrift2json": "thrift2json.js" + }, + "engines": { + "node": ">= 0.10.x" + } + }, "node_modules/throwback": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throwback/-/throwback-4.1.0.tgz", + "integrity": "sha512-dLFe8bU8SeH0xeqeKL7BNo8XoPC/o91nz9/ooeplZPiso+DZukhoyZcSz9TFnUNScm+cA9qjU1m1853M6sPOng==", "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6447,6 +8922,8 @@ }, "node_modules/toidentifier": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -6454,6 +8931,8 @@ }, "node_modules/tough-cookie": { "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", @@ -6467,33 +8946,42 @@ }, "node_modules/tr46": { "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/ts-api-utils": { - "version": "1.3.0", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-expect": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", "license": "MIT" }, "node_modules/ts-node": { "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6536,6 +9024,8 @@ }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6544,6 +9034,8 @@ }, "node_modules/tsconfig-paths": { "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "license": "MIT", "dependencies": { @@ -6554,11 +9046,28 @@ } }, "node_modules/tslib": { - "version": "2.7.0", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -6570,6 +9079,8 @@ }, "node_modules/type-detect": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, "license": "MIT", "engines": { @@ -6578,6 +9089,8 @@ }, "node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -6589,6 +9102,8 @@ }, "node_modules/type-is": { "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -6599,28 +9114,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -6630,16 +9149,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -6649,16 +9171,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -6669,10 +9193,14 @@ }, "node_modules/typedarray": { "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, "node_modules/typescript": { "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6684,30 +9212,41 @@ } }, "node_modules/ufo": { - "version": "1.5.4", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", "dev": true, "license": "MIT" }, "node_modules/unbox-primitive": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/undici-types": { - "version": "6.19.8", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/universalify": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -6715,6 +9254,8 @@ }, "node_modules/unpipe": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6722,6 +9263,8 @@ }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6729,10 +9272,14 @@ } }, "node_modules/uritemplate": { - "version": "0.3.4" + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/uritemplate/-/uritemplate-0.3.4.tgz", + "integrity": "sha512-enADBvHfhjrwxFMTVWeIIYz51SZ91uC6o2MR/NQTVljJB6HTZ8eQL3Q7JBj3RxNISA14MOwJaU3vpf5R6dyxHA==" }, "node_modules/url-parse": { "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -6740,20 +9287,27 @@ } }, "node_modules/url-polyfill": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.12.tgz", - "integrity": "sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==" + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.13.tgz", + "integrity": "sha512-tXzkojrv2SujumYthZ/WjF7jaSfNhSXlYMpE5AYdL2I3D7DCeo+mch8KtW2rUuKjDg+3VXODXHVgipt8yGY/eQ==", + "license": "MIT" }, "node_modules/url-toolkit": { "version": "2.1.6", + "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz", + "integrity": "sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw==", "license": "Apache-2.0" }, "node_modules/util-deprecate": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -6761,6 +9315,8 @@ }, "node_modules/uuid": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -6768,15 +9324,21 @@ }, "node_modules/uuid-parse": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==", "license": "MIT" }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true, "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -6784,6 +9346,8 @@ }, "node_modules/web-streams-polyfill": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -6791,10 +9355,14 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -6803,6 +9371,8 @@ }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -6816,29 +9386,85 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-typed-array": { - "version": "1.1.15", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -6848,31 +9474,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/winston": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz", - "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.6.0", + "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "winston-transport": "^4.9.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-loki": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/winston-loki/-/winston-loki-6.1.2.tgz", - "integrity": "sha512-l1iqDDaEUt63Q8arDsiVCXIrK3jLjPOEc5UTs+WMVnWf8D+A8ZRErAAXKDOduT240aNGzpTbCwe5zfdqqLlzMg==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/winston-loki/-/winston-loki-6.1.3.tgz", + "integrity": "sha512-DjWtJ230xHyYQWr9mZJa93yhwHttn3JEtSYWP8vXZWJOahiQheUhf+88dSIidbGXB3u0oLweV6G1vkL/ouT62Q==", + "license": "MIT", "dependencies": { "async-exit-hook": "2.0.1", "btoa": "^1.2.1", @@ -6885,11 +9523,12 @@ } }, "node_modules/winston-transport": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.1.tgz", - "integrity": "sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", "dependencies": { - "logform": "^2.6.1", + "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, @@ -6899,6 +9538,8 @@ }, "node_modules/word-wrap": { "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { @@ -6907,6 +9548,8 @@ }, "node_modules/worker-timers": { "version": "7.1.8", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", + "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.24.5", @@ -6917,6 +9560,8 @@ }, "node_modules/worker-timers-broker": { "version": "6.1.8", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", + "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.24.5", @@ -6927,6 +9572,8 @@ }, "node_modules/worker-timers-worker": { "version": "7.0.71", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", + "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.24.5", @@ -6935,26 +9582,36 @@ }, "node_modules/workerpool": { "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, "license": "Apache-2.0" }, "node_modules/wot-thing-description-types": { - "version": "1.1.0-09-November-2023", + "version": "1.1.0-12-March-2025", + "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-12-March-2025.tgz", + "integrity": "sha512-BRRW4uBATljCPqCbpzNhgY2HFXz8Llh7mAJmjkVimxizOPq8bkmlm0Op/Yv8l7pNQ1GaoBtYwn2BQQjhcQCadA==", "license": "W3C-20150513" }, "node_modules/wot-thing-model-types": { - "version": "1.1.0-09-November-2023", + "version": "1.1.0-12-March-2025", + "resolved": "https://registry.npmjs.org/wot-thing-model-types/-/wot-thing-model-types-1.1.0-12-March-2025.tgz", + "integrity": "sha512-YqCLluIONdr9m8p8euVqSrVFlyROWVhrI2CVZHGuGJfpm56xU2jtT4yFiZHumrnjKKwp0QfErX0YLB1uxdPNGg==", "license": "W3C-20150513" }, "node_modules/wot-typescript-definitions": { - "version": "0.8.0-SNAPSHOT.29", + "version": "0.8.0-SNAPSHOT.31", + "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.31.tgz", + "integrity": "sha512-BBUWfJnNsSMb60FlUfQN+TWFP2W71LM4g7in83Y+vO6BjGvsyO0KY4jTbazjhLdxxTjbyftrExNkKNwtBIbxfA==", "license": "W3C-20150513", "dependencies": { - "wot-thing-description-types": "1.1.0-09-November-2023" + "wot-thing-description-types": "1.1.0-12-March-2025" } }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6969,33 +9626,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/ws": { - "version": "8.18.0", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -7013,8 +9653,16 @@ } } }, + "node_modules/xorshift": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xorshift/-/xorshift-1.2.0.tgz", + "integrity": "sha512-iYgNnGyeeJ4t6U11NpA/QiKy+PXn5Aa3Azg5qkwIFz1tBLllQrjjsk9yzD7IAK0naNU4JxdeDgqW9ov4u/hc4g==", + "license": "MIT" + }, "node_modules/xtend": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", "engines": { "node": ">=0.4" @@ -7022,29 +9670,31 @@ }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" - }, "node_modules/yaml": { - "version": "2.5.1", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "license": "MIT", "dependencies": { @@ -7062,6 +9712,8 @@ }, "node_modules/yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "engines": { @@ -7070,6 +9722,8 @@ }, "node_modules/yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "license": "MIT", "dependencies": { @@ -7082,29 +9736,10 @@ "node": ">=10" } }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, "license": "MIT", "engines": { @@ -7113,6 +9748,8 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { @@ -7129,6 +9766,11 @@ "dependencies": { "@node-wot/binding-http": "^0.8.14", "@node-wot/core": "^0.8.14", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/exporter-jaeger": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0", "dotenv": "^16.4.5", "json-placeholder-replacer": "^2.0.5", "wot-typescript-definitions": "^0.8.0-SNAPSHOT.29" @@ -7138,14 +9780,6 @@ "typescript": "^4.7.4" } }, - "things/advanced-coffee-machine/http/ts/node_modules/json-placeholder-replacer": { - "version": "2.0.5", - "license": "MIT", - "bin": { - "jpr": "dist/index.js", - "json-placeholder-replacer": "dist/index.js" - } - }, "things/calculator/coap/js": { "name": "coap-calculator", "version": "1.0.0", @@ -7203,6 +9837,14 @@ "node": ">=16" } }, + "things/calculator/http/express/node_modules/json-placeholder-replacer": { + "version": "1.0.37", + "license": "MIT", + "bin": { + "jpr": "dist/index.js", + "json-placeholder-replacer": "dist/index.js" + } + }, "things/calculator/mqtt/js": { "name": "mqtt-calculator", "version": "1.0.0", @@ -7400,14 +10042,6 @@ "typescript": "^4.7.4" } }, - "things/data-schema-thing/http/ts/node_modules/json-placeholder-replacer": { - "version": "2.0.5", - "license": "MIT", - "bin": { - "jpr": "dist/index.js", - "json-placeholder-replacer": "dist/index.js" - } - }, "things/elevator/modbus/js": { "name": "modbus-elevator", "version": "1.0.0", diff --git a/things/advanced-coffee-machine/http/ts/package.json b/things/advanced-coffee-machine/http/ts/package.json index 8dff49f..1fa97d1 100644 --- a/things/advanced-coffee-machine/http/ts/package.json +++ b/things/advanced-coffee-machine/http/ts/package.json @@ -24,7 +24,12 @@ "@node-wot/core": "^0.8.14", "dotenv": "^16.4.5", "json-placeholder-replacer": "^2.0.5", - "wot-typescript-definitions": "^0.8.0-SNAPSHOT.29" + "wot-typescript-definitions": "^0.8.0-SNAPSHOT.29", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", + "@opentelemetry/exporter-jaeger": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0" }, "devDependencies": { "@types/node": "^22.1.0", diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 7b8e275..128ce85 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,6 +25,8 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; +import "./tracing"; +import { trace, SpanStatusCode } from "@opentelemetry/api"; dotenv.config(); const hostname = process.env.HOSTNAME ?? "localhost"; @@ -166,123 +168,145 @@ servient throw Error("Please specify id variable as uriVariables."); }); + const tracer = trace.getTracer("advanced-coffee-machine"); // Set up a handler for makeDrink action thing.setActionHandler("makeDrink", async (_params, options) => { - // Default values - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + return await tracer.startActiveSpan("makeDrink", async (span) => { + try { + // Default values + let drinkId = "americano"; + let size = "m"; + let quantity = 1; + + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; - // Check if uriVariables are provided - if (options && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans - ); - - // Check if the amount of available resources is sufficient to make a drink - for (const resource in newResources) { - if (newResources[resource] <= 0) { - thing.emitEvent("outOfResource", `Low level of ${resource}: ${newResources[resource]}%`); + // Check if uriVariables are provided + if (options && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; + size = "size" in uriVariables ? (uriVariables.size as string) : size; + quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; + } + + // Calculate the new level of resources + const newResources = Object.assign({}, allAvailableResources); + newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); + newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); + newResources.chocolate -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + ); + + // Check if the amount of available resources is sufficient to make a drink + for (const resource in newResources) { + if (newResources[resource] <= 0) { + thing.emitEvent("outOfResource", `Low level of ${resource}: ${newResources[resource]}%`); + span.setStatus({ code: SpanStatusCode.ERROR, message: `${resource} level is not sufficient` }); + return { + result: false, + message: `${resource} level is not sufficient`, + }; + } + } + + // Now store the new level of allAvailableResources + allAvailableResources = newResources; + servedCounter = servedCounter + quantity; + + // Finally deliver the drink + span.setStatus({ code: SpanStatusCode.OK }); return { - result: false, - message: `${resource} level is not sufficient`, + result: true, + message: `Your ${drinkId} is in progress!`, }; + } catch (err) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) }); + throw err; + } finally { + span.end(); } - } - - // Now store the new level of allAvailableResources - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; - - // Finally deliver the drink - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; + }); }); // Set up a handler for setSchedule action thing.setActionHandler("setSchedule", async (params, options) => { - const paramsp = (await params.value()) as Record; // : any = await Helpers.parseInteractionOutput(params); - - // Check if uriVariables are provided - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { - // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - - // Now add a new schedule - schedules.push(paramsp); - - return { - result: true, - message: `Your schedule has been set!`, - }; - } - - return { - result: false, - message: `Please provide all the required parameters: time and mode.`, - }; + return await tracer.startActiveSpan("setSchedule", async (span) => { + try { + const paramsp = (await params.value()) as Record; // : any = await Helpers.parseInteractionOutput(params); + + // Check if uriVariables are provided + if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { + // Use default values if not provided + paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; + paramsp.size = "size" in paramsp ? paramsp.size : "m"; + paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; + + // Now add a new schedule + schedules.push(paramsp); + + span.setStatus({ code: SpanStatusCode.OK }); + return { + result: true, + message: `Your schedule has been set!`, + }; + } + span.setStatus({ code: SpanStatusCode.ERROR, message: `Missing required parameters: time and mode.` }); + return { + result: false, + message: `Please provide all the required parameters: time and mode.`, + }; + } catch (err) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) }); + throw err; + } finally { + span.end(); + } + }); }); // Finally expose the thing diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts new file mode 100644 index 0000000..a079265 --- /dev/null +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -0,0 +1,16 @@ +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; +import { JaegerExporter } from "@opentelemetry/exporter-jaeger"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { Resource } from "@opentelemetry/resources"; +import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; + +const provider = new NodeTracerProvider({ + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: "advanced-coffee-machine" + }), +}); +const exporter = new JaegerExporter({ + endpoint: process.env.JAEGER_ENDPOINT || "http://localhost:14268/api/traces" +}); +provider.addSpanProcessor(new BatchSpanProcessor(exporter)); +provider.register(); From 6093f1ebd8087c32bd854a95ac8b4b91f31f480d Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 21 Jul 2025 17:01:38 -0700 Subject: [PATCH 02/34] fix: ran npm run format --- .../http/ts/src/main.ts | 19 +++++++++++++++---- .../http/ts/src/tracing.ts | 8 ++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 128ce85..cc2d8c7 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -237,7 +237,9 @@ servient const newResources = Object.assign({}, allAvailableResources); newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate); + newResources.chocolate -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate + ); newResources.coffeeBeans -= Math.ceil( quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans ); @@ -245,8 +247,14 @@ servient // Check if the amount of available resources is sufficient to make a drink for (const resource in newResources) { if (newResources[resource] <= 0) { - thing.emitEvent("outOfResource", `Low level of ${resource}: ${newResources[resource]}%`); - span.setStatus({ code: SpanStatusCode.ERROR, message: `${resource} level is not sufficient` }); + thing.emitEvent( + "outOfResource", + `Low level of ${resource}: ${newResources[resource]}%` + ); + span.setStatus({ + code: SpanStatusCode.ERROR, + message: `${resource} level is not sufficient`, + }); return { result: false, message: `${resource} level is not sufficient`, @@ -295,7 +303,10 @@ servient message: `Your schedule has been set!`, }; } - span.setStatus({ code: SpanStatusCode.ERROR, message: `Missing required parameters: time and mode.` }); + span.setStatus({ + code: SpanStatusCode.ERROR, + message: `Missing required parameters: time and mode.`, + }); return { result: false, message: `Please provide all the required parameters: time and mode.`, diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 7d3388c..6a7fb0a 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -5,12 +5,12 @@ import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; const provider = new NodeTracerProvider({ - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: "advanced-coffee-machine" - }), + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: "advanced-coffee-machine", + }), }); const exporter = new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces" + endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", }); provider.addSpanProcessor(new BatchSpanProcessor(exporter)); provider.register(); From 8034db9db5e502c8aa119a1bddac81363b26451d Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Thu, 24 Jul 2025 15:20:54 -0700 Subject: [PATCH 03/34] Updated README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 286e1a1..b135c48 100644 --- a/README.md +++ b/README.md @@ -164,3 +164,7 @@ docker buildx build \ For running the things separately, using their `Dockerfile`'s, `docker build -t -f ./Dockerfile ../../` command must be used to give the context to be able to copy `tm.json` into the container. For Node.js-based devices, we use npm workspaces and running `npm install` at the root directory installs all the packages needed for every device. After packages are installed, running `node main.js` would run the thing. For port configuration, running either `node main.js -p 1000` or `node main.js --port 1000` would start the thing on port 1000. + +## Tracing + +Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:16686](http://localhost:16686) in your browser (Jaeger UI). From 4053ee703fc62123764a90838a6f4974a9c8b36f Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 29 Jul 2025 16:47:43 -0700 Subject: [PATCH 04/34] Modified tracing to include input values --- .../http/ts/src/main.ts | 263 ++++++++---------- .../http/ts/src/tracing.ts | 252 ++++++++++++++++- 2 files changed, 368 insertions(+), 147 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index cc2d8c7..7bccffe 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -26,7 +26,8 @@ import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; import "./tracing"; -import { trace, SpanStatusCode } from "@opentelemetry/api"; +import { tracedActionHandler, tracedPropertyWriteHandler, tracer } from "./tracing"; +import { SpanStatusCode } from "@opentelemetry/api"; dotenv.config(); const hostname = process.env.HOSTNAME ?? "localhost"; @@ -168,157 +169,129 @@ servient throw Error("Please specify id variable as uriVariables."); }); - const tracer = trace.getTracer("advanced-coffee-machine"); - // Set up a handler for makeDrink action - thing.setActionHandler("makeDrink", async (_params, options) => { - return await tracer.startActiveSpan("makeDrink", async (span) => { - try { - // Default values - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; + // Set up a handler for makeDrink action using traced wrapper + thing.setActionHandler("makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { + // Default values + let drinkId = "americano"; + let size = "m"; + let quantity = 1; + + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; + + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + // Check if uriVariables are provided + if (options && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; + size = "size" in uriVariables ? (uriVariables.size as string) : size; + quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; + } - // Check if uriVariables are provided - if (options && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } - - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate - ); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + // Calculate the new level of resources + const newResources = Object.assign({}, allAvailableResources); + newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); + newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); + newResources.chocolate -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate + ); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + ); + + // Check if the amount of available resources is sufficient to make a drink + for (const resource in newResources) { + if (newResources[resource] <= 0) { + thing.emitEvent( + "outOfResource", + `Low level of ${resource}: ${newResources[resource]}%` ); - - // Check if the amount of available resources is sufficient to make a drink - for (const resource in newResources) { - if (newResources[resource] <= 0) { - thing.emitEvent( - "outOfResource", - `Low level of ${resource}: ${newResources[resource]}%` - ); - span.setStatus({ - code: SpanStatusCode.ERROR, - message: `${resource} level is not sufficient`, - }); - return { - result: false, - message: `${resource} level is not sufficient`, - }; - } - } - - // Now store the new level of allAvailableResources - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; - - // Finally deliver the drink - span.setStatus({ code: SpanStatusCode.OK }); - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - } catch (err) { - span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) }); - throw err; - } finally { - span.end(); - } - }); - }); - - // Set up a handler for setSchedule action - thing.setActionHandler("setSchedule", async (params, options) => { - return await tracer.startActiveSpan("setSchedule", async (span) => { - try { - const paramsp = (await params.value()) as Record; // : any = await Helpers.parseInteractionOutput(params); - - // Check if uriVariables are provided - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { - // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - - // Now add a new schedule - schedules.push(paramsp); - - span.setStatus({ code: SpanStatusCode.OK }); - return { - result: true, - message: `Your schedule has been set!`, - }; - } - span.setStatus({ - code: SpanStatusCode.ERROR, - message: `Missing required parameters: time and mode.`, - }); return { result: false, - message: `Please provide all the required parameters: time and mode.`, + message: `${resource} level is not sufficient`, }; - } catch (err) { - span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) }); - throw err; - } finally { - span.end(); } - }); - }); + } + + // Now store the new level of allAvailableResources + allAvailableResources = newResources; + servedCounter = servedCounter + quantity; + + // Finally deliver the drink + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + })); + + // Set up a handler for setSchedule action using traced wrapper + thing.setActionHandler("setSchedule", tracedActionHandler("setSchedule", async (params, options) => { + const paramsp = params ? (await (params as any).value()) as Record : null; + + // Check if required parameters are provided + if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { + // Use default values if not provided + paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; + paramsp.size = "size" in paramsp ? paramsp.size : "m"; + paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; + + // Now add a new schedule + schedules.push(paramsp); + + return { + result: true, + message: `Your schedule has been set!`, + }; + } + + return { + result: false, + message: `Please provide all the required parameters: time and mode.`, + }; + })); // Finally expose the thing thing.expose().then(() => { diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 6a7fb0a..e30da8b 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -1,8 +1,9 @@ -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; +import { NodeTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace-node"; import { JaegerExporter } from "@opentelemetry/exporter-jaeger"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; +import { trace, SpanStatusCode, Span } from "@opentelemetry/api"; +import WoT from "wot-typescript-definitions"; const provider = new NodeTracerProvider({ resource: new Resource({ @@ -14,3 +15,250 @@ const exporter = new JaegerExporter({ }); provider.addSpanProcessor(new BatchSpanProcessor(exporter)); provider.register(); + +// Get tracer for early tracing +const tracer = trace.getTracer("advanced-coffee-machine"); + +/** + * Safely converts any value to a string for span tagging + */ +function safeStringify(value: any): string { + try { + if (value === null || value === undefined) return String(value); + if (typeof value === 'string') return value; + if (typeof value === 'number' || typeof value === 'boolean') return String(value); + return JSON.stringify(value); + } catch (error) { + return `[Unable to serialize: ${typeof value}]`; + } +} + +/** + * Adds comprehensive input parameter tags to a span + */ +function addInputTags(span: Span, params: any, options: any, actionName: string) { + // Basic span information + span.setAttributes({ + 'action.name': actionName, + 'wot.operation': 'invokeaction', + 'request.timestamp': new Date().toISOString(), + }); + + // Capture raw parameters + if (params !== undefined && params !== null) { + try { + // Try to get the actual value if it's a WoT InteractionInput + if (params && typeof params.value === 'function') { + params.value().then((actualValue: any) => { + span.setAttributes({ + 'input.params.raw': safeStringify(actualValue), + 'input.params.type': typeof actualValue, + 'input.params.present': true + }); + }).catch((error: any) => { + span.setAttributes({ + 'input.params.error': safeStringify(error), + 'input.params.present': false + }); + }); + } else { + span.setAttributes({ + 'input.params.raw': safeStringify(params), + 'input.params.type': typeof params, + 'input.params.present': true + }); + } + } catch (error) { + span.setAttributes({ + 'input.params.error': safeStringify(error), + 'input.params.present': false + }); + } + } else { + span.setAttributes({ + 'input.params.present': false + }); + } + + // Capture options and uriVariables + if (options && typeof options === 'object') { + try { + span.setAttributes({ + 'input.options.present': true, + 'input.options.raw': safeStringify(options) + }); + + // Specifically capture uriVariables + if ('uriVariables' in options && options.uriVariables) { + const uriVars = options.uriVariables as Record; + span.setAttributes({ + 'input.uriVariables.present': true, + 'input.uriVariables.raw': safeStringify(uriVars) + }); + + // Add individual uriVariable tags + Object.entries(uriVars).forEach(([key, value]) => { + span.setAttributes({ + [`input.uriVariables.${key}`]: safeStringify(value) + }); + }); + } + + // Capture any formIndex if present + if ('formIndex' in options) { + span.setAttributes({ + 'input.formIndex': String(options.formIndex) + }); + } + } catch (error) { + span.setAttributes({ + 'input.options.error': safeStringify(error), + 'input.options.present': false + }); + } + } else { + span.setAttributes({ + 'input.options.present': false + }); + } +} + +/** + * Creates a traced action handler that captures input parameters BEFORE TD validation + */ +export function tracedActionHandler( + actionName: string, + originalHandler: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise +): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { + return async (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { + // Start span IMMEDIATELY - before any TD validation or processing + return await tracer.startActiveSpan(`action.${actionName}`, async (span) => { + try { + // Capture ALL input parameters as tags FIRST + addInputTags(span, params, options, actionName); + + // Mark as processing + span.setAttributes({ + 'span.stage': 'processing', + 'td.validation': 'pending' + }); + + // Now call the original handler - TD validation happens inside node-wot + const result = await originalHandler(params, options); + + // If we get here, TD validation passed and handler succeeded + span.setAttributes({ + 'td.validation': 'passed', + 'handler.execution': 'success', + 'span.stage': 'completed', + 'output.present': result !== undefined + }); + + if (result !== undefined) { + span.setAttributes({ + 'output.value': safeStringify(result) + }); + } + + span.setStatus({ code: SpanStatusCode.OK }); + return result; + + } catch (error) { + // Capture error details - could be TD validation or handler error + const errorMessage = error instanceof Error ? error.message : String(error); + const errorName = error instanceof Error ? error.name : 'Unknown'; + + span.setAttributes({ + 'error.occurred': true, + 'error.message': errorMessage, + 'error.name': errorName, + 'error.type': typeof error, + 'span.stage': 'error' + }); + + // Try to determine if this is a TD validation error + if (errorMessage.includes('validation') || + errorMessage.includes('schema') || + errorMessage.includes('required') || + errorMessage.includes('type') || + errorName.includes('Validation')) { + span.setAttributes({ + 'td.validation': 'failed', + 'error.category': 'td_validation' + }); + } else { + span.setAttributes({ + 'td.validation': 'passed', + 'handler.execution': 'failed', + 'error.category': 'handler_execution' + }); + } + + span.setStatus({ + code: SpanStatusCode.ERROR, + message: errorMessage + }); + + throw error; + } finally { + span.end(); + } + }); + }; +} + +/** + * Creates a traced property write handler that captures input parameters BEFORE TD validation + */ +export function tracedPropertyWriteHandler( + propertyName: string, + originalHandler: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise +): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { + return async (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => { + return await tracer.startActiveSpan(`property.write.${propertyName}`, async (span) => { + try { + // Capture input parameters immediately + span.setAttributes({ + 'property.name': propertyName, + 'wot.operation': 'writeproperty', + 'request.timestamp': new Date().toISOString(), + 'span.stage': 'processing' + }); + + addInputTags(span, value, options, `write.${propertyName}`); + + // Call original handler + await originalHandler(value, options); + + span.setAttributes({ + 'td.validation': 'passed', + 'handler.execution': 'success', + 'span.stage': 'completed' + }); + + span.setStatus({ code: SpanStatusCode.OK }); + + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + + span.setAttributes({ + 'error.occurred': true, + 'error.message': errorMessage, + 'span.stage': 'error' + }); + + span.setStatus({ + code: SpanStatusCode.ERROR, + message: errorMessage + }); + + throw error; + } finally { + span.end(); + } + }); + }; +} + +// Export tracer for any manual span creation +export { tracer }; From 340ac8ce0fd556a7312824a4879f6a53df0f8492 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 29 Jul 2025 17:08:11 -0700 Subject: [PATCH 05/34] Refactored tracing.ts code --- .../http/ts/src/main.ts | 7 +- .../http/ts/src/tracing.ts | 273 +++++------------- 2 files changed, 76 insertions(+), 204 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 7bccffe..c398281 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,11 +25,12 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import "./tracing"; -import { tracedActionHandler, tracedPropertyWriteHandler, tracer } from "./tracing"; -import { SpanStatusCode } from "@opentelemetry/api"; +import { initTracing, tracedActionHandler, tracedPropertyWriteHandler } from "./tracing"; dotenv.config(); +// Initialize tracing +initTracing("advanced-coffee-machine"); + const hostname = process.env.HOSTNAME ?? "localhost"; let portNumber = process.env.PORT != null && process.env.PORT !== "" ? parseInt(process.env.PORT) : 3000; const thingName = "http-advanced-coffee-machine"; diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index e30da8b..46b597e 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -2,203 +2,100 @@ import { NodeTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace import { JaegerExporter } from "@opentelemetry/exporter-jaeger"; import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; -import { trace, SpanStatusCode, Span } from "@opentelemetry/api"; +import { trace, SpanStatusCode } from "@opentelemetry/api"; import WoT from "wot-typescript-definitions"; -const provider = new NodeTracerProvider({ - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: "advanced-coffee-machine", - }), -}); -const exporter = new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", -}); -provider.addSpanProcessor(new BatchSpanProcessor(exporter)); -provider.register(); +let tracer: any = null; -// Get tracer for early tracing -const tracer = trace.getTracer("advanced-coffee-machine"); - -/** - * Safely converts any value to a string for span tagging - */ function safeStringify(value: any): string { try { if (value === null || value === undefined) return String(value); if (typeof value === 'string') return value; if (typeof value === 'number' || typeof value === 'boolean') return String(value); return JSON.stringify(value); - } catch (error) { + } catch { return `[Unable to serialize: ${typeof value}]`; } } -/** - * Adds comprehensive input parameter tags to a span - */ -function addInputTags(span: Span, params: any, options: any, actionName: string) { - // Basic span information +async function captureInputs(span: any, params: any, options: any, operation: string): Promise { span.setAttributes({ - 'action.name': actionName, - 'wot.operation': 'invokeaction', - 'request.timestamp': new Date().toISOString(), + 'wot.operation': operation, + 'timestamp': new Date().toISOString(), }); - // Capture raw parameters + // Capture params without consuming the stream if (params !== undefined && params !== null) { try { - // Try to get the actual value if it's a WoT InteractionInput - if (params && typeof params.value === 'function') { - params.value().then((actualValue: any) => { - span.setAttributes({ - 'input.params.raw': safeStringify(actualValue), - 'input.params.type': typeof actualValue, - 'input.params.present': true - }); - }).catch((error: any) => { - span.setAttributes({ - 'input.params.error': safeStringify(error), - 'input.params.present': false - }); - }); - } else { - span.setAttributes({ - 'input.params.raw': safeStringify(params), - 'input.params.type': typeof params, - 'input.params.present': true - }); - } - } catch (error) { + // Don't call params.value() as it consumes the stream + // Just capture that params are present and their type span.setAttributes({ - 'input.params.error': safeStringify(error), - 'input.params.present': false + 'input.params.present': true, + 'input.params.type': typeof params }); + } catch (error) { + span.setAttributes({ 'input.params.error': safeStringify(error) }); } } else { - span.setAttributes({ - 'input.params.present': false - }); + span.setAttributes({ 'input.params.present': false }); } // Capture options and uriVariables if (options && typeof options === 'object') { - try { - span.setAttributes({ - 'input.options.present': true, - 'input.options.raw': safeStringify(options) - }); - - // Specifically capture uriVariables - if ('uriVariables' in options && options.uriVariables) { - const uriVars = options.uriVariables as Record; - span.setAttributes({ - 'input.uriVariables.present': true, - 'input.uriVariables.raw': safeStringify(uriVars) - }); - - // Add individual uriVariable tags - Object.entries(uriVars).forEach(([key, value]) => { - span.setAttributes({ - [`input.uriVariables.${key}`]: safeStringify(value) - }); - }); - } - - // Capture any formIndex if present - if ('formIndex' in options) { - span.setAttributes({ - 'input.formIndex': String(options.formIndex) - }); - } - } catch (error) { - span.setAttributes({ - 'input.options.error': safeStringify(error), - 'input.options.present': false + span.setAttributes({ 'input.options': safeStringify(options) }); + + if ('uriVariables' in options && options.uriVariables) { + const uriVars = options.uriVariables as Record; + span.setAttributes({ 'input.uriVariables': safeStringify(uriVars) }); + + // Add individual uriVariable tags + Object.entries(uriVars).forEach(([key, value]) => { + span.setAttributes({ [`input.uriVariables.${key}`]: safeStringify(value) }); }); } - } else { - span.setAttributes({ - 'input.options.present': false - }); } } -/** - * Creates a traced action handler that captures input parameters BEFORE TD validation - */ -export function tracedActionHandler( - actionName: string, - originalHandler: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise -): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { - return async (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { - // Start span IMMEDIATELY - before any TD validation or processing - return await tracer.startActiveSpan(`action.${actionName}`, async (span) => { - try { - // Capture ALL input parameters as tags FIRST - addInputTags(span, params, options, actionName); - - // Mark as processing - span.setAttributes({ - 'span.stage': 'processing', - 'td.validation': 'pending' - }); - - // Now call the original handler - TD validation happens inside node-wot - const result = await originalHandler(params, options); +export function initTracing(serviceName: string): void { + const provider = new NodeTracerProvider({ + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: serviceName, + }), + }); + + provider.addSpanProcessor(new BatchSpanProcessor(new JaegerExporter({ + endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", + }))); + + provider.register(); + tracer = trace.getTracer(serviceName); +} - // If we get here, TD validation passed and handler succeeded +export function traceAction( + name: string, + fn: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise +): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { + return async (params, options) => { + return tracer.startActiveSpan(`action.${name}`, async (span: any) => { + try { + span.setAttributes({ 'action.name': name }); + await captureInputs(span, params, options, 'invokeaction'); + + const result = await fn(params, options); + span.setAttributes({ - 'td.validation': 'passed', - 'handler.execution': 'success', - 'span.stage': 'completed', - 'output.present': result !== undefined + 'result.present': result !== undefined, + 'result.value': result !== undefined ? safeStringify(result) : 'undefined', + 'status': 'success' }); - - if (result !== undefined) { - span.setAttributes({ - 'output.value': safeStringify(result) - }); - } - span.setStatus({ code: SpanStatusCode.OK }); return result; - } catch (error) { - // Capture error details - could be TD validation or handler error - const errorMessage = error instanceof Error ? error.message : String(error); - const errorName = error instanceof Error ? error.name : 'Unknown'; - - span.setAttributes({ - 'error.occurred': true, - 'error.message': errorMessage, - 'error.name': errorName, - 'error.type': typeof error, - 'span.stage': 'error' + span.setAttributes({ + 'error.message': safeStringify(error), + 'status': 'error' }); - - // Try to determine if this is a TD validation error - if (errorMessage.includes('validation') || - errorMessage.includes('schema') || - errorMessage.includes('required') || - errorMessage.includes('type') || - errorName.includes('Validation')) { - span.setAttributes({ - 'td.validation': 'failed', - 'error.category': 'td_validation' - }); - } else { - span.setAttributes({ - 'td.validation': 'passed', - 'handler.execution': 'failed', - 'error.category': 'handler_execution' - }); - } - - span.setStatus({ - code: SpanStatusCode.ERROR, - message: errorMessage - }); - + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { span.end(); @@ -207,51 +104,24 @@ export function tracedActionHandler( }; } -/** - * Creates a traced property write handler that captures input parameters BEFORE TD validation - */ -export function tracedPropertyWriteHandler( - propertyName: string, - originalHandler: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise +export function traceProperty( + name: string, + fn: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise ): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { - return async (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => { - return await tracer.startActiveSpan(`property.write.${propertyName}`, async (span) => { + return async (value, options) => { + return tracer.startActiveSpan(`property.write.${name}`, async (span: any) => { try { - // Capture input parameters immediately - span.setAttributes({ - 'property.name': propertyName, - 'wot.operation': 'writeproperty', - 'request.timestamp': new Date().toISOString(), - 'span.stage': 'processing' - }); - - addInputTags(span, value, options, `write.${propertyName}`); - - // Call original handler - await originalHandler(value, options); - - span.setAttributes({ - 'td.validation': 'passed', - 'handler.execution': 'success', - 'span.stage': 'completed' - }); - + span.setAttributes({ 'property.name': name }); + await captureInputs(span, value, options, 'writeproperty'); + await fn(value, options); + span.setAttributes({ 'status': 'success' }); span.setStatus({ code: SpanStatusCode.OK }); - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error); - - span.setAttributes({ - 'error.occurred': true, - 'error.message': errorMessage, - 'span.stage': 'error' + span.setAttributes({ + 'error.message': safeStringify(error), + 'status': 'error' }); - - span.setStatus({ - code: SpanStatusCode.ERROR, - message: errorMessage - }); - + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { span.end(); @@ -260,5 +130,6 @@ export function tracedPropertyWriteHandler( }; } -// Export tracer for any manual span creation -export { tracer }; +// Legacy compatibility +export const tracedActionHandler = traceAction; +export const tracedPropertyWriteHandler = traceProperty; From b211687afd7a4a83400dc51af6b187ff7b8411ea Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 29 Jul 2025 17:18:44 -0700 Subject: [PATCH 06/34] Updated tracing code --- .../http/ts/src/tracing.ts | 113 +++++++++--------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 46b597e..65365a7 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -9,64 +9,83 @@ let tracer: any = null; function safeStringify(value: any): string { try { - if (value === null || value === undefined) return String(value); - if (typeof value === 'string') return value; - if (typeof value === 'number' || typeof value === 'boolean') return String(value); - return JSON.stringify(value); + return value === null || value === undefined ? String(value) : + typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : + JSON.stringify(value); } catch { return `[Unable to serialize: ${typeof value}]`; } } -async function captureInputs(span: any, params: any, options: any, operation: string): Promise { +function setSpanAttributes(span: any, name: string, operation: string, options: any, params?: any, error?: any, result?: any): void { + // Set basic attributes + const isAction = operation === 'invokeaction'; + const nameKey = isAction ? 'action.name' : 'property.name'; + span.setAttributes({ + [nameKey]: name, 'wot.operation': operation, - 'timestamp': new Date().toISOString(), + 'timestamp': new Date().toISOString() }); - // Capture params without consuming the stream - if (params !== undefined && params !== null) { - try { - // Don't call params.value() as it consumes the stream - // Just capture that params are present and their type - span.setAttributes({ - 'input.params.present': true, - 'input.params.type': typeof params - }); - } catch (error) { - span.setAttributes({ 'input.params.error': safeStringify(error) }); - } - } else { - span.setAttributes({ 'input.params.present': false }); - } - - // Capture options and uriVariables - if (options && typeof options === 'object') { + // Add input options if present + if (options) { span.setAttributes({ 'input.options': safeStringify(options) }); - if ('uriVariables' in options && options.uriVariables) { - const uriVars = options.uriVariables as Record; - span.setAttributes({ 'input.uriVariables': safeStringify(uriVars) }); + // Add URI variables if present + if (options.uriVariables) { + span.setAttributes({ 'input.uriVariables': safeStringify(options.uriVariables) }); - // Add individual uriVariable tags - Object.entries(uriVars).forEach(([key, value]) => { + // Add individual URI variables for easy filtering in Jaeger + for (const [key, value] of Object.entries(options.uriVariables)) { span.setAttributes({ [`input.uriVariables.${key}`]: safeStringify(value) }); - }); + } + } + } + + // Add input parameters if present + if (params !== undefined) { + span.setAttributes({ + 'input.params.present': true, + 'input.params.type': typeof params, + 'input.params.value': safeStringify(params) + }); + } + + // Add error or success information + if (error) { + const errorMessage = safeStringify(error); + const isValidationError = errorMessage.includes('validation') || + errorMessage.includes('schema') || + errorMessage.includes('required'); + + span.setAttributes({ + 'td.validation': isValidationError ? 'failed' : 'passed', + 'error.category': isValidationError ? 'td_validation' : 'handler_execution', + 'error.message': errorMessage, + 'status': 'error' + }); + } else { + span.setAttributes({ + 'td.validation': 'passed', + 'handler.execution': 'success', + 'status': 'success' + }); + + // Add result if present + if (result !== undefined) { + span.setAttributes({ 'result.value': safeStringify(result) }); } } } export function initTracing(serviceName: string): void { const provider = new NodeTracerProvider({ - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: serviceName, - }), + resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: serviceName }), }); - provider.addSpanProcessor(new BatchSpanProcessor(new JaegerExporter({ endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", }))); - provider.register(); tracer = trace.getTracer(serviceName); } @@ -78,23 +97,12 @@ export function traceAction( return async (params, options) => { return tracer.startActiveSpan(`action.${name}`, async (span: any) => { try { - span.setAttributes({ 'action.name': name }); - await captureInputs(span, params, options, 'invokeaction'); - const result = await fn(params, options); - - span.setAttributes({ - 'result.present': result !== undefined, - 'result.value': result !== undefined ? safeStringify(result) : 'undefined', - 'status': 'success' - }); + setSpanAttributes(span, name, 'invokeaction', options, params, null, result); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { - span.setAttributes({ - 'error.message': safeStringify(error), - 'status': 'error' - }); + setSpanAttributes(span, name, 'invokeaction', options, params, error); span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { @@ -111,16 +119,11 @@ export function traceProperty( return async (value, options) => { return tracer.startActiveSpan(`property.write.${name}`, async (span: any) => { try { - span.setAttributes({ 'property.name': name }); - await captureInputs(span, value, options, 'writeproperty'); await fn(value, options); - span.setAttributes({ 'status': 'success' }); + setSpanAttributes(span, name, 'writeproperty', options, value); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { - span.setAttributes({ - 'error.message': safeStringify(error), - 'status': 'error' - }); + setSpanAttributes(span, name, 'writeproperty', options, value, error); span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { From 24c09d85be26aeb0234887dbf5f6e147c88484f1 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 4 Aug 2025 16:17:36 -0700 Subject: [PATCH 07/34] fix: ran npm format --- .../http/ts/src/main.ts | 223 +++++++++--------- .../http/ts/src/tracing.ts | 85 ++++--- 2 files changed, 162 insertions(+), 146 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 08e693b..0b00a71 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -171,128 +171,131 @@ servient }); // Set up a handler for makeDrink action using traced wrapper - thing.setActionHandler("makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { - // Default values - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + thing.setActionHandler( + "makeDrink", + tracedActionHandler("makeDrink", async (_params, options) => { + // Default values + let drinkId = "americano"; + let size = "m"; + let quantity = 1; + + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate - ); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans - ); - - // Check if the amount of available resources is sufficient to make a drink - for (const resource in newResources) { - if (newResources[resource] <= 0) { - thing.emitEvent( - "outOfResource", - `Low level of ${resource}: ${newResources[resource]}%` - ); - return { - result: false, - message: `${resource} level is not sufficient`, - }; + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; + size = "size" in uriVariables ? (uriVariables.size as string) : size; + quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - } - // Now store the new level of allAvailableResources - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; + // Calculate the new level of resources + const newResources = Object.assign({}, allAvailableResources); + newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); + newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); + newResources.chocolate -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate + ); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + ); + + // Check if the amount of available resources is sufficient to make a drink + for (const resource in newResources) { + if (newResources[resource] <= 0) { + thing.emitEvent("outOfResource", `Low level of ${resource}: ${newResources[resource]}%`); + return { + result: false, + message: `${resource} level is not sufficient`, + }; + } + } + + // Now store the new level of allAvailableResources + allAvailableResources = newResources; + servedCounter = servedCounter + quantity; - // Finally deliver the drink - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - })); + // Finally deliver the drink + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + }) + ); // Set up a handler for setSchedule action using traced wrapper - thing.setActionHandler("setSchedule", tracedActionHandler("setSchedule", async (params, options) => { - const paramsp = params ? (await (params as any).value()) as Record : null; + thing.setActionHandler( + "setSchedule", + tracedActionHandler("setSchedule", async (params, options) => { + const paramsp = params ? ((await (params as any).value()) as Record) : null; - // Check if required parameters are provided - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { - // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; + // Check if required parameters are provided + if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { + // Use default values if not provided + paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; + paramsp.size = "size" in paramsp ? paramsp.size : "m"; + paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - // Now add a new schedule - schedules.push(paramsp); + // Now add a new schedule + schedules.push(paramsp); + + return { + result: true, + message: `Your schedule has been set!`, + }; + } return { - result: true, - message: `Your schedule has been set!`, + result: false, + message: `Please provide all the required parameters: time and mode.`, }; - } - - return { - result: false, - message: `Please provide all the required parameters: time and mode.`, - }; - })); + }) + ); // Finally expose the thing thing.expose().then(() => { diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 65365a7..4d6327f 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -9,33 +9,43 @@ let tracer: any = null; function safeStringify(value: any): string { try { - return value === null || value === undefined ? String(value) : - typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? String(value) : - JSON.stringify(value); + return value === null || value === undefined + ? String(value) + : typeof value === "string" || typeof value === "number" || typeof value === "boolean" + ? String(value) + : JSON.stringify(value); } catch { return `[Unable to serialize: ${typeof value}]`; } } -function setSpanAttributes(span: any, name: string, operation: string, options: any, params?: any, error?: any, result?: any): void { +function setSpanAttributes( + span: any, + name: string, + operation: string, + options: any, + params?: any, + error?: any, + result?: any +): void { // Set basic attributes - const isAction = operation === 'invokeaction'; - const nameKey = isAction ? 'action.name' : 'property.name'; - + const isAction = operation === "invokeaction"; + const nameKey = isAction ? "action.name" : "property.name"; + span.setAttributes({ [nameKey]: name, - 'wot.operation': operation, - 'timestamp': new Date().toISOString() + "wot.operation": operation, + timestamp: new Date().toISOString(), }); // Add input options if present if (options) { - span.setAttributes({ 'input.options': safeStringify(options) }); - + span.setAttributes({ "input.options": safeStringify(options) }); + // Add URI variables if present if (options.uriVariables) { - span.setAttributes({ 'input.uriVariables': safeStringify(options.uriVariables) }); - + span.setAttributes({ "input.uriVariables": safeStringify(options.uriVariables) }); + // Add individual URI variables for easy filtering in Jaeger for (const [key, value] of Object.entries(options.uriVariables)) { span.setAttributes({ [`input.uriVariables.${key}`]: safeStringify(value) }); @@ -46,35 +56,34 @@ function setSpanAttributes(span: any, name: string, operation: string, options: // Add input parameters if present if (params !== undefined) { span.setAttributes({ - 'input.params.present': true, - 'input.params.type': typeof params, - 'input.params.value': safeStringify(params) + "input.params.present": true, + "input.params.type": typeof params, + "input.params.value": safeStringify(params), }); } // Add error or success information if (error) { const errorMessage = safeStringify(error); - const isValidationError = errorMessage.includes('validation') || - errorMessage.includes('schema') || - errorMessage.includes('required'); - + const isValidationError = + errorMessage.includes("validation") || errorMessage.includes("schema") || errorMessage.includes("required"); + span.setAttributes({ - 'td.validation': isValidationError ? 'failed' : 'passed', - 'error.category': isValidationError ? 'td_validation' : 'handler_execution', - 'error.message': errorMessage, - 'status': 'error' + "td.validation": isValidationError ? "failed" : "passed", + "error.category": isValidationError ? "td_validation" : "handler_execution", + "error.message": errorMessage, + status: "error", }); } else { span.setAttributes({ - 'td.validation': 'passed', - 'handler.execution': 'success', - 'status': 'success' + "td.validation": "passed", + "handler.execution": "success", + status: "success", }); - + // Add result if present if (result !== undefined) { - span.setAttributes({ 'result.value': safeStringify(result) }); + span.setAttributes({ "result.value": safeStringify(result) }); } } } @@ -83,9 +92,13 @@ export function initTracing(serviceName: string): void { const provider = new NodeTracerProvider({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: serviceName }), }); - provider.addSpanProcessor(new BatchSpanProcessor(new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", - }))); + provider.addSpanProcessor( + new BatchSpanProcessor( + new JaegerExporter({ + endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", + }) + ) + ); provider.register(); tracer = trace.getTracer(serviceName); } @@ -98,11 +111,11 @@ export function traceAction( return tracer.startActiveSpan(`action.${name}`, async (span: any) => { try { const result = await fn(params, options); - setSpanAttributes(span, name, 'invokeaction', options, params, null, result); + setSpanAttributes(span, name, "invokeaction", options, params, null, result); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { - setSpanAttributes(span, name, 'invokeaction', options, params, error); + setSpanAttributes(span, name, "invokeaction", options, params, error); span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { @@ -120,10 +133,10 @@ export function traceProperty( return tracer.startActiveSpan(`property.write.${name}`, async (span: any) => { try { await fn(value, options); - setSpanAttributes(span, name, 'writeproperty', options, value); + setSpanAttributes(span, name, "writeproperty", options, value); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { - setSpanAttributes(span, name, 'writeproperty', options, value, error); + setSpanAttributes(span, name, "writeproperty", options, value, error); span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { From 6e57e3ded9f6ea73b3404a728b3d97fe1ef5e2ce Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 5 Aug 2025 15:29:59 -0700 Subject: [PATCH 08/34] Added spans for properties and events --- coffee-machine-test-commands.txt | 32 +++++ .../http/ts/src/main.ts | 124 ++++++++++++------ .../http/ts/src/tracing.ts | 64 ++++++++- 3 files changed, 176 insertions(+), 44 deletions(-) create mode 100644 coffee-machine-test-commands.txt diff --git a/coffee-machine-test-commands.txt b/coffee-machine-test-commands.txt new file mode 100644 index 0000000..cb38f7f --- /dev/null +++ b/coffee-machine-test-commands.txt @@ -0,0 +1,32 @@ +# Coffee Machine Tracing Test Commands + +# 1. Property Read Tests +curl -X GET http://localhost/http-advanced-coffee-machine/properties/allAvailableResources +curl -X GET http://localhost/http-advanced-coffee-machine/properties/possibleDrinks +curl -X GET http://localhost/http-advanced-coffee-machine/properties/maintenanceNeeded + +# 2. Property Write Tests +curl -X PUT http://localhost/http-advanced-coffee-machine/properties/servedCounter -H 'Content-Type: application/json' -d '1001' +curl -X PUT "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=water" -H 'Content-Type: application/json' -d '50' +curl -X PUT "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=coffeeBeans" -H 'Content-Type: application/json' -d '0' + +# 3. Property Read After Write Tests +curl -X GET http://localhost/http-advanced-coffee-machine/properties/maintenanceNeeded +curl -X GET "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=water" + +# 4. Action Tests +curl -X POST "http://localhost/http-advanced-coffee-machine/actions/makeDrink?drinkId=cappuccino&size=m&quantity=1" +curl -X POST http://localhost/http-advanced-coffee-machine/actions/setSchedule -H 'Content-Type: application/json' -d '{"time":"10:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' + +# 5. Property Read After Action Tests +curl -X GET http://localhost/http-advanced-coffee-machine/properties/schedules + +# 6. Event Trigger Tests (will trigger outOfResource event) +curl -X POST "http://localhost/http-advanced-coffee-machine/actions/makeDrink?drinkId=espresso&size=m&quantity=1" + +# Expected Results: +# - Property reads will show property.read.* traces +# - Property writes will show property.write.* traces +# - Actions will show action.* traces +# - Events will show event.* traces (maintenanceNeeded and outOfResource) +# - Check Jaeger at http://localhost:16686 to see all the new spans \ No newline at end of file diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 0b00a71..c497ab7 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,7 +25,13 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import { initTracing, tracedActionHandler, tracedPropertyWriteHandler } from "./tracing"; +import { + initTracing, + tracedActionHandler, + tracedPropertyReadHandler, + tracedPropertyWriteHandler, + tracedEventHandler, +} from "./tracing"; dotenv.config(); // Initialize tracing @@ -116,59 +122,88 @@ servient maintenanceNeeded = false; schedules = []; - thing.setPropertyReadHandler("allAvailableResources", async () => allAvailableResources); - thing.setPropertyReadHandler("possibleDrinks", async () => possibleDrinks); - thing.setPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded); - thing.setPropertyReadHandler("schedules", async () => schedules); + thing.setPropertyReadHandler( + "allAvailableResources", + tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) + ); + thing.setPropertyReadHandler( + "possibleDrinks", + tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) + ); + thing.setPropertyReadHandler( + "maintenanceNeeded", + tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded) + ); + thing.setPropertyReadHandler( + "schedules", + tracedPropertyReadHandler("schedules", async () => schedules) + ); // Override a write handler for servedCounter property, // raising maintenanceNeeded flag when the value exceeds 1000 drinks - thing.setPropertyWriteHandler("servedCounter", async (val) => { - servedCounter = (await val.value()) as number; - if (servedCounter > 1000) { - maintenanceNeeded = true; - thing.emitPropertyChange("maintenanceNeeded"); - - // Notify a "maintainer" when the value has changed - // (the notify function here simply logs a message to the console) - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - } - }); + thing.setPropertyWriteHandler( + "servedCounter", + tracedPropertyWriteHandler("servedCounter", async (val) => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + servedCounter = (await (val as any).value()) as number; + if (servedCounter > 1000) { + maintenanceNeeded = true; + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + + // Notify a "maintainer" when the value has changed + // (the notify function here simply logs a message to the console) + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + } + }) + ); // Now initialize the servedCounter property servedCounter = readFromSensor("servedCounter"); // Override a write handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyWriteHandler("availableResourceLevel", async (val, options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - allAvailableResources[id] = (await val.value()) as number; - return; + thing.setPropertyWriteHandler( + "availableResourceLevel", + tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + if (!val) { + throw new Error("No value provided for availableResourceLevel"); + } + allAvailableResources[id] = (await (val as any).value()) as number; + return; + } } - } - throw Error("Please specify id variable as uriVariables."); - }); + throw Error("Please specify id variable as uriVariables."); + }) + ); // Override a read handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyReadHandler("availableResourceLevel", async (options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - return allAvailableResources[id]; + thing.setPropertyReadHandler( + "availableResourceLevel", + tracedPropertyReadHandler("availableResourceLevel", async (options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + return allAvailableResources[id]; + } } - } - throw Error("Please specify id variable as uriVariables."); - }); + throw Error("Please specify id variable as uriVariables."); + }) + ); // Set up a handler for makeDrink action using traced wrapper thing.setActionHandler( @@ -234,6 +269,10 @@ servient quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } + if (drinkId === "americano") { + throw new Error("Americano is not available"); + } + // Calculate the new level of resources const newResources = Object.assign({}, allAvailableResources); newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); @@ -248,7 +287,10 @@ servient // Check if the amount of available resources is sufficient to make a drink for (const resource in newResources) { if (newResources[resource] <= 0) { - thing.emitEvent("outOfResource", `Low level of ${resource}: ${newResources[resource]}%`); + const eventData = `Low level of ${resource}: ${newResources[resource]}%`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( + eventData + ); return { result: false, message: `${resource} level is not sufficient`, diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 4d6327f..535dc72 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -30,7 +30,20 @@ function setSpanAttributes( ): void { // Set basic attributes const isAction = operation === "invokeaction"; - const nameKey = isAction ? "action.name" : "property.name"; + const isPropertyRead = operation === "readproperty"; + const isPropertyWrite = operation === "writeproperty"; + const isEvent = operation === "subscribeevent"; + + let nameKey: string; + if (isAction) { + nameKey = "action.name"; + } else if (isPropertyRead || isPropertyWrite) { + nameKey = "property.name"; + } else if (isEvent) { + nameKey = "event.name"; + } else { + nameKey = "interaction.name"; + } span.setAttributes({ [nameKey]: name, @@ -125,7 +138,29 @@ export function traceAction( }; } -export function traceProperty( +export function tracePropertyRead( + name: string, + fn: (options?: WoT.InteractionOptions) => Promise +): (options?: WoT.InteractionOptions) => Promise { + return async (options) => { + return tracer.startActiveSpan(`property.read.${name}`, async (span: any) => { + try { + const result = await fn(options); + setSpanAttributes(span, name, "readproperty", options, undefined, null, result); + span.setStatus({ code: SpanStatusCode.OK }); + return result; + } catch (error) { + setSpanAttributes(span, name, "readproperty", options, undefined, error); + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + throw error; + } finally { + span.end(); + } + }); + }; +} + +export function tracePropertyWrite( name: string, fn: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise ): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { @@ -146,6 +181,29 @@ export function traceProperty( }; } +export function traceEvent( + name: string, + fn: (data: any, options?: WoT.InteractionOptions) => void +): (data: any, options?: WoT.InteractionOptions) => void { + return (data, options) => { + tracer.startActiveSpan(`event.${name}`, async (span: any) => { + try { + fn(data, options); + setSpanAttributes(span, name, "subscribeevent", options, data); + span.setStatus({ code: SpanStatusCode.OK }); + } catch (error) { + setSpanAttributes(span, name, "subscribeevent", options, data, error); + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + throw error; + } finally { + span.end(); + } + }); + }; +} + // Legacy compatibility export const tracedActionHandler = traceAction; -export const tracedPropertyWriteHandler = traceProperty; +export const tracedPropertyReadHandler = tracePropertyRead; +export const tracedPropertyWriteHandler = tracePropertyWrite; +export const tracedEventHandler = traceEvent; From 72c077f194fdcb2395f52445d6b802ad2ed5d0b9 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 5 Aug 2025 15:30:25 -0700 Subject: [PATCH 09/34] fix: ran npm run format --- .../http/ts/src/main.ts | 130 +++++++----------- 1 file changed, 50 insertions(+), 80 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index c497ab7..edfbc71 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,13 +25,7 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import { - initTracing, - tracedActionHandler, - tracedPropertyReadHandler, - tracedPropertyWriteHandler, - tracedEventHandler, -} from "./tracing"; +import { initTracing, tracedActionHandler, tracedPropertyReadHandler, tracedPropertyWriteHandler, tracedEventHandler } from "./tracing"; dotenv.config(); // Initialize tracing @@ -122,88 +116,65 @@ servient maintenanceNeeded = false; schedules = []; - thing.setPropertyReadHandler( - "allAvailableResources", - tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) - ); - thing.setPropertyReadHandler( - "possibleDrinks", - tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) - ); - thing.setPropertyReadHandler( - "maintenanceNeeded", - tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded) - ); - thing.setPropertyReadHandler( - "schedules", - tracedPropertyReadHandler("schedules", async () => schedules) - ); + thing.setPropertyReadHandler("allAvailableResources", tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources)); + thing.setPropertyReadHandler("possibleDrinks", tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks)); + thing.setPropertyReadHandler("maintenanceNeeded", tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded)); + thing.setPropertyReadHandler("schedules", tracedPropertyReadHandler("schedules", async () => schedules)); // Override a write handler for servedCounter property, // raising maintenanceNeeded flag when the value exceeds 1000 drinks - thing.setPropertyWriteHandler( - "servedCounter", - tracedPropertyWriteHandler("servedCounter", async (val) => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - servedCounter = (await (val as any).value()) as number; - if (servedCounter > 1000) { - maintenanceNeeded = true; - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - - // Notify a "maintainer" when the value has changed - // (the notify function here simply logs a message to the console) - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - } - }) - ); + thing.setPropertyWriteHandler("servedCounter", tracedPropertyWriteHandler("servedCounter", async (val) => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + servedCounter = (await (val as any).value()) as number; + if (servedCounter > 1000) { + maintenanceNeeded = true; + tracedEventHandler("maintenanceNeeded", (data) => thing.emitPropertyChange("maintenanceNeeded"))(maintenanceNeeded); + + // Notify a "maintainer" when the value has changed + // (the notify function here simply logs a message to the console) + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + } + })); // Now initialize the servedCounter property servedCounter = readFromSensor("servedCounter"); // Override a write handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyWriteHandler( - "availableResourceLevel", - tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - if (!val) { - throw new Error("No value provided for availableResourceLevel"); - } - allAvailableResources[id] = (await (val as any).value()) as number; - return; + thing.setPropertyWriteHandler("availableResourceLevel", tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + if (!val) { + throw new Error("No value provided for availableResourceLevel"); } + allAvailableResources[id] = (await (val as any).value()) as number; + return; } - throw Error("Please specify id variable as uriVariables."); - }) - ); + } + throw Error("Please specify id variable as uriVariables."); + })); // Override a read handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyReadHandler( - "availableResourceLevel", - tracedPropertyReadHandler("availableResourceLevel", async (options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - return allAvailableResources[id]; - } + thing.setPropertyReadHandler("availableResourceLevel", tracedPropertyReadHandler("availableResourceLevel", async (options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + return allAvailableResources[id]; } - throw Error("Please specify id variable as uriVariables."); - }) - ); + } + throw Error("Please specify id variable as uriVariables."); + })); // Set up a handler for makeDrink action using traced wrapper thing.setActionHandler( @@ -269,9 +240,10 @@ servient quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - if (drinkId === "americano") { - throw new Error("Americano is not available"); - } + // Testing to see what happens when thing crashes + // if (drinkId === "americano") { + // throw new Error("Americano is not available"); + // } // Calculate the new level of resources const newResources = Object.assign({}, allAvailableResources); @@ -288,9 +260,7 @@ servient for (const resource in newResources) { if (newResources[resource] <= 0) { const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( - eventData - ); + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); return { result: false, message: `${resource} level is not sufficient`, From 0db157e301a6a3526d686b51db7b2356afb8d4dd Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Wed, 6 Aug 2025 15:26:15 -0700 Subject: [PATCH 10/34] fix: ran npm run format again --- things/advanced-coffee-machine/README.md | 2 +- .../http/ts/src/main.ts | 123 +++++++++++------- things/calculator/README.md | 12 +- things/counter-thing/README.md | 2 +- things/data-schema-thing/README.md | 2 +- things/elevator/README.md | 2 +- 6 files changed, 87 insertions(+), 56 deletions(-) diff --git a/things/advanced-coffee-machine/README.md b/things/advanced-coffee-machine/README.md index ba664f4..03aa08d 100644 --- a/things/advanced-coffee-machine/README.md +++ b/things/advanced-coffee-machine/README.md @@ -26,4 +26,4 @@ This advanced coffee machine simulates a device with resource management, drink ## Usage -The coffee machine exposes properties, actions, and events for managing drinks and resources. See the [Thing Description](http://plugfest.thingweb.io/http-advanced-coffee-machine) for details on endpoints and data formats. \ No newline at end of file +The coffee machine exposes properties, actions, and events for managing drinks and resources. See the [Thing Description](http://plugfest.thingweb.io/http-advanced-coffee-machine) for details on endpoints and data formats. diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index edfbc71..542a43e 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,7 +25,13 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import { initTracing, tracedActionHandler, tracedPropertyReadHandler, tracedPropertyWriteHandler, tracedEventHandler } from "./tracing"; +import { + initTracing, + tracedActionHandler, + tracedPropertyReadHandler, + tracedPropertyWriteHandler, + tracedEventHandler, +} from "./tracing"; dotenv.config(); // Initialize tracing @@ -116,65 +122,88 @@ servient maintenanceNeeded = false; schedules = []; - thing.setPropertyReadHandler("allAvailableResources", tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources)); - thing.setPropertyReadHandler("possibleDrinks", tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks)); - thing.setPropertyReadHandler("maintenanceNeeded", tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded)); - thing.setPropertyReadHandler("schedules", tracedPropertyReadHandler("schedules", async () => schedules)); + thing.setPropertyReadHandler( + "allAvailableResources", + tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) + ); + thing.setPropertyReadHandler( + "possibleDrinks", + tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) + ); + thing.setPropertyReadHandler( + "maintenanceNeeded", + tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded) + ); + thing.setPropertyReadHandler( + "schedules", + tracedPropertyReadHandler("schedules", async () => schedules) + ); // Override a write handler for servedCounter property, // raising maintenanceNeeded flag when the value exceeds 1000 drinks - thing.setPropertyWriteHandler("servedCounter", tracedPropertyWriteHandler("servedCounter", async (val) => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - servedCounter = (await (val as any).value()) as number; - if (servedCounter > 1000) { - maintenanceNeeded = true; - tracedEventHandler("maintenanceNeeded", (data) => thing.emitPropertyChange("maintenanceNeeded"))(maintenanceNeeded); - - // Notify a "maintainer" when the value has changed - // (the notify function here simply logs a message to the console) - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - } - })); + thing.setPropertyWriteHandler( + "servedCounter", + tracedPropertyWriteHandler("servedCounter", async (val) => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + servedCounter = (await (val as any).value()) as number; + if (servedCounter > 1000) { + maintenanceNeeded = true; + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + + // Notify a "maintainer" when the value has changed + // (the notify function here simply logs a message to the console) + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + } + }) + ); // Now initialize the servedCounter property servedCounter = readFromSensor("servedCounter"); // Override a write handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyWriteHandler("availableResourceLevel", tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - if (!val) { - throw new Error("No value provided for availableResourceLevel"); + thing.setPropertyWriteHandler( + "availableResourceLevel", + tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + if (!val) { + throw new Error("No value provided for availableResourceLevel"); + } + allAvailableResources[id] = (await (val as any).value()) as number; + return; } - allAvailableResources[id] = (await (val as any).value()) as number; - return; } - } - throw Error("Please specify id variable as uriVariables."); - })); + throw Error("Please specify id variable as uriVariables."); + }) + ); // Override a read handler for availableResourceLevel property, // utilizing the uriVariables properly - thing.setPropertyReadHandler("availableResourceLevel", tracedPropertyReadHandler("availableResourceLevel", async (options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - return allAvailableResources[id]; + thing.setPropertyReadHandler( + "availableResourceLevel", + tracedPropertyReadHandler("availableResourceLevel", async (options) => { + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { + const id = uriVariables.id; + return allAvailableResources[id]; + } } - } - throw Error("Please specify id variable as uriVariables."); - })); + throw Error("Please specify id variable as uriVariables."); + }) + ); // Set up a handler for makeDrink action using traced wrapper thing.setActionHandler( @@ -260,7 +289,9 @@ servient for (const resource in newResources) { if (newResources[resource] <= 0) { const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( + eventData + ); return { result: false, message: `${resource} level is not sufficient`, diff --git a/things/calculator/README.md b/things/calculator/README.md index beb7816..f74082d 100644 --- a/things/calculator/README.md +++ b/things/calculator/README.md @@ -30,9 +30,9 @@ The features are the same across all protocols - all implementations support the The calculator exposes basic arithmetic operations through multiple protocols. See the Thing Descriptions for details on endpoints and data formats: -- [HTTP Express Simple Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/http/express/http-simple-calculator-thing.td.jsonld) -- [HTTP Express Content Negotiation Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/http/express/http-content-negotiation-calculator-thing.td.jsonld) -- [HTTP Flask Calculator](http://plugfest.thingweb.io/http-flask-calculator) -- [CoAP Simple Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/coap/js/coap-simple-calculator-thing.td.jsonld) -- [CoAP Content Negotiation Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/coap/js/coap-content-negotiation-calculator-thing.td.jsonld) -- [MQTT Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/mqtt/js/mqtt-calculator.td.json) +- [HTTP Express Simple Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/http/express/http-simple-calculator-thing.td.jsonld) +- [HTTP Express Content Negotiation Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/http/express/http-content-negotiation-calculator-thing.td.jsonld) +- [HTTP Flask Calculator](http://plugfest.thingweb.io/http-flask-calculator) +- [CoAP Simple Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/coap/js/coap-simple-calculator-thing.td.jsonld) +- [CoAP Content Negotiation Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/coap/js/coap-content-negotiation-calculator-thing.td.jsonld) +- [MQTT Calculator](https://github.com/eclipse-thingweb/test-things/blob/main/things/calculator/mqtt/js/mqtt-calculator.td.json) diff --git a/things/counter-thing/README.md b/things/counter-thing/README.md index 99ebb27..9f24cf6 100644 --- a/things/counter-thing/README.md +++ b/things/counter-thing/README.md @@ -25,4 +25,4 @@ This counter thing provides increment, decrement, and reset operations, exposing ## Usage -The counter exposes properties and actions for interacting with the count value. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/counter-thing/counter-thing.td.json) for details on endpoints and data formats. \ No newline at end of file +The counter exposes properties and actions for interacting with the count value. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/counter-thing/counter-thing.td.json) for details on endpoints and data formats. diff --git a/things/data-schema-thing/README.md b/things/data-schema-thing/README.md index d4d08e8..e69e0a1 100644 --- a/things/data-schema-thing/README.md +++ b/things/data-schema-thing/README.md @@ -24,4 +24,4 @@ This thing provides a variety of properties and actions to test different data t ## Usage -The data schema thing exposes properties, actions, and events for testing schema compliance. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/data-schema-thing/http/ts/http-data-schema-thing.td.json) for details on endpoints and data formats. \ No newline at end of file +The data schema thing exposes properties, actions, and events for testing schema compliance. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/data-schema-thing/http/ts/http-data-schema-thing.td.json) for details on endpoints and data formats. diff --git a/things/elevator/README.md b/things/elevator/README.md index 38032d8..f5b0342 100644 --- a/things/elevator/README.md +++ b/things/elevator/README.md @@ -24,4 +24,4 @@ This elevator thing simulates an elevator with properties for light switch, floo ## Usage -The elevator exposes properties for floor number, movement, and light switch. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/elevator/modbus/js/modbus-elevator.td.json) for details on endpoints and data formats. \ No newline at end of file +The elevator exposes properties for floor number, movement, and light switch. See the [Thing Description](https://github.com/eclipse-thingweb/test-things/blob/main/things/elevator/modbus/js/modbus-elevator.td.json) for details on endpoints and data formats. From 97280dcc60270a4b42fdbff4e859360eec9d020f Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Thu, 7 Aug 2025 22:02:32 -0700 Subject: [PATCH 11/34] Enhanced OpenTelemetry tracing --- .../http/ts/src/main.ts | 593 ++++++++++++++---- .../http/ts/src/tracing.ts | 157 ++++- .../test-enhanced-tracing.sh | 185 ++++++ 3 files changed, 789 insertions(+), 146 deletions(-) create mode 100755 things/advanced-coffee-machine/test-enhanced-tracing.sh diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 542a43e..3a4bd58 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -31,6 +31,10 @@ import { tracedPropertyReadHandler, tracedPropertyWriteHandler, tracedEventHandler, + traceBusinessLogic, + traceValidation, + traceDatabaseOperation, + createChildSpan, } from "./tracing"; dotenv.config(); @@ -124,11 +128,75 @@ servient thing.setPropertyReadHandler( "allAvailableResources", - tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) + tracedPropertyReadHandler("allAvailableResources", async () => { + return await traceBusinessLogic("getAllResources", async () => { + // Validate resource data integrity + await traceValidation("resourceData", allAvailableResources, async () => { + const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; + for (const resource of requiredResources) { + if (!(resource in allAvailableResources)) { + throw new Error(`Missing required resource: ${resource}`); + } + if (typeof allAvailableResources[resource] !== "number") { + throw new Error(`Invalid resource level for ${resource}`); + } + } + }); + + // Read sensor data for real-time validation + const sensorData = await createChildSpan("sensors.readAll", async () => { + const readings: Record = {}; + for (const resource in allAvailableResources) { + readings[resource] = readFromSensor(resource); + } + return readings; + }, { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level" + }); + + // Compare and sync with database + return await traceDatabaseOperation("select", "resource_levels", async () => { + // In a real system, you might sync with actual sensor readings + // For demo, we'll just return the current state + return { ...allAvailableResources }; + }); + }); + }) ); thing.setPropertyReadHandler( "possibleDrinks", - tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) + tracedPropertyReadHandler("possibleDrinks", async () => { + return await traceBusinessLogic("getPossibleDrinks", async () => { + // Validate drink catalog integrity + await traceValidation("drinkCatalog", possibleDrinks, async () => { + if (!Array.isArray(possibleDrinks)) { + throw new Error("Drink catalog is corrupted"); + } + if (possibleDrinks.length === 0) { + throw new Error("No drinks available in catalog"); + } + }); + + // Load drink availability from database + const availabilityMap = await traceDatabaseOperation("select", "drink_availability", async () => { + // Simulate checking drink availability based on current resources + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; // For demo, all drinks are available + } + return availability; + }); + + // Filter available drinks based on current resources + return await createChildSpan("processing.filterAvailableDrinks", async () => { + return possibleDrinks.filter(drink => availabilityMap[drink] !== false); + }, { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability" + }); + }); + }) ); thing.setPropertyReadHandler( "maintenanceNeeded", @@ -136,7 +204,33 @@ servient ); thing.setPropertyReadHandler( "schedules", - tracedPropertyReadHandler("schedules", async () => schedules) + tracedPropertyReadHandler("schedules", async () => { + return await traceBusinessLogic("getSchedules", async () => { + // Validate system state + await traceValidation("systemState", { schedulesLength: schedules.length }, async () => { + if (!Array.isArray(schedules)) { + throw new Error("Schedules data structure is corrupted"); + } + }); + + // Load schedules from database + const result = await traceDatabaseOperation("select", "schedules", async () => { + return schedules; + }); + + // Process and filter active schedules + return await createChildSpan("processing.filterActiveSchedules", async () => { + const currentTime = new Date(); + return result.filter((schedule: any) => { + // For demo purposes, all schedules are considered active + return true; + }); + }, { + "schedules.count": schedules.length, + "query.time": new Date().toISOString() + }); + }); + }) ); // Override a write handler for servedCounter property, @@ -144,23 +238,66 @@ servient thing.setPropertyWriteHandler( "servedCounter", tracedPropertyWriteHandler("servedCounter", async (val) => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - servedCounter = (await (val as any).value()) as number; - if (servedCounter > 1000) { - maintenanceNeeded = true; - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - - // Notify a "maintainer" when the value has changed - // (the notify function here simply logs a message to the console) - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - } + return await traceBusinessLogic("updateServedCounter", async () => { + // Validate input + await traceValidation("counterInput", val, async () => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + }); + + // Parse and validate the new counter value + const newCounterValue = await createChildSpan("parsing.extractCounterValue", async () => { + const value = (await (val as any).value()) as number; + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); + } + return value; + }, { + "input.type": typeof val, + "parsing.operation": "counter_extraction" + }); + + // Update counter in database + await traceDatabaseOperation("update", "counters", async () => { + servedCounter = newCounterValue; + }); + + // Check maintenance threshold and trigger events if needed + await createChildSpan("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + + // Emit maintenance event + await createChildSpan("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); + + // Send notification to administrators + await createChildSpan("notification.sendAlert", async () => { + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + }, { + "notification.type": "maintenance_alert", + "notification.recipient": "admin@coffeeMachine.com", + "counter.value": servedCounter, + "maintenance.threshold": 1000 + }); + } + }, { + "counter.current": servedCounter, + "counter.previous": servedCounter - newCounterValue, + "maintenance.threshold": 1000, + "maintenance.needed": maintenanceNeeded + }); + }); }) ); @@ -172,19 +309,98 @@ servient thing.setPropertyWriteHandler( "availableResourceLevel", tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { + return await traceBusinessLogic("updateResourceLevel", async () => { + // Validate URI variables and extract resource ID + const resourceId = await traceValidation("uriVariables", options, async () => { + if (!Boolean(options) || typeof options !== "object" || !("uriVariables" in options)) { + throw new Error("URI variables are required"); + } + const uriVariables = options.uriVariables as Record; + if (!("id" in uriVariables)) { + throw new Error("Please specify id variable as uriVariables."); + } const id = uriVariables.id; + + // Validate resource ID + const validResources = ["water", "milk", "chocolate", "coffeeBeans"]; + if (!validResources.includes(id)) { + throw new Error(`Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}`); + } + return id; + }); + + // Validate and parse the new resource level + const newLevel = await createChildSpan("parsing.extractResourceLevel", async () => { if (!val) { throw new Error("No value provided for availableResourceLevel"); } - allAvailableResources[id] = (await (val as any).value()) as number; - return; - } - } - throw Error("Please specify id variable as uriVariables."); + const level = (await (val as any).value()) as number; + + // Validate resource level range + if (typeof level !== "number" || level < 0 || level > 100) { + throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); + } + return level; + }, { + "resource.id": resourceId, + "input.type": typeof val + }); + + // Check current level and calculate change + const levelChange = await createChildSpan("calculate.levelChange", async () => { + const currentLevel = allAvailableResources[resourceId]; + const change = newLevel - currentLevel; + return { + previous: currentLevel, + new: newLevel, + change: change, + changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change" + }; + }, { + "resource.id": resourceId, + "calculation.type": "level_change" + }); + + // Update resource level in database + await traceDatabaseOperation("update", "resource_levels", async () => { + allAvailableResources[resourceId] = newLevel; + }); + + // Check for low resource alerts + await createChildSpan("business.checkResourceThresholds", async () => { + if (newLevel <= 10) { + // Emit low resource event + await createChildSpan("event.lowResource", async () => { + const eventData = `Low level of ${resourceId}: ${newLevel}%`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); + }); + } + + if (newLevel === 0) { + // Update maintenance needed flag + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + } + }, { + "resource.id": resourceId, + "resource.level": newLevel, + "threshold.low": 10, + "threshold.empty": 0, + "maintenance.needed": maintenanceNeeded + }); + + // Log resource level change + await createChildSpan("logging.resourceUpdate", async () => { + console.log(`Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})`); + }, { + "resource.id": resourceId, + "level.previous": levelChange.previous, + "level.new": newLevel, + "change.type": levelChange.changeType, + "change.amount": levelChange.change + }); + }); }) ); @@ -209,59 +425,11 @@ servient thing.setActionHandler( "makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { - // Default values + // Parse input parameters first to use in metadata let drinkId = "americano"; let size = "m"; let quantity = 1; - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; - - // Check if uriVariables are provided if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { const uriVariables = options.uriVariables as Record; drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; @@ -269,45 +437,147 @@ servient quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - // Testing to see what happens when thing crashes - // if (drinkId === "americano") { - // throw new Error("Americano is not available"); - // } - - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate - ); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans - ); - - // Check if the amount of available resources is sufficient to make a drink - for (const resource in newResources) { - if (newResources[resource] <= 0) { - const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( - eventData - ); - return { - result: false, - message: `${resource} level is not sufficient`, + return await traceBusinessLogic("makeDrink", async () => { + // Validate input parameters + await traceValidation("input", options, async () => { + if (!drinkId || !size || !quantity) { + throw new Error("Invalid input parameters"); + } + }); + + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation("select", "recipes", async () => { + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, }; - } - } - // Now store the new level of allAvailableResources - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; + + return { drinkRecipes, sizeQuantifiers }; + }); - // Finally deliver the drink - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; + // Validate drink availability + await traceValidation("drinkAvailability", drinkId, async () => { + if (!drinkRecipes[drinkId]) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (!sizeQuantifiers[size]) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); + + // Get current resources from sensors + const currentResources = await traceDatabaseOperation("select", "resources", async () => { + return { ...allAvailableResources }; + }); + + // Calculate resource consumption + const newResources = await createChildSpan("calculate.resourceConsumption", async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + + return newResources; + }, { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption" + }); + + // Validate resource availability + await traceValidation("resourceAvailability", newResources, async () => { + for (const resource in newResources) { + if (newResources[resource] <= 0) { + const eventData = `Low level of ${resource}: ${newResources[resource]}%`; + await createChildSpan("event.outOfResource", async () => { + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); + }); + throw new Error(`${resource} level is not sufficient`); + } + } + }); + + // Update resources in database + await traceDatabaseOperation("update", "resources", async () => { + allAvailableResources = newResources; + }); + + // Update served counter + await traceDatabaseOperation("update", "counters", async () => { + servedCounter = servedCounter + quantity; + }); + + // Simulate drink preparation + await createChildSpan("hardware.prepareDrink", async () => { + // Simulate time for drink preparation + await new Promise(resolve => setTimeout(resolve, 100)); + }, { + "hardware.operation": "drink_preparation", + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity + }); + + // Return success response + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + }, { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity + }); }) ); @@ -315,28 +585,91 @@ servient thing.setActionHandler( "setSchedule", tracedActionHandler("setSchedule", async (params, options) => { + // Parse input parameters first for metadata const paramsp = params ? ((await (params as any).value()) as Record) : null; - - // Check if required parameters are provided - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { - // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - - // Now add a new schedule - schedules.push(paramsp); + + return await traceBusinessLogic("setSchedule", async () => { + // Always create initial validation span to show the process started + const validatedParams = await createChildSpan("initialization.parseInput", async () => { + // Validate input parameters + await traceValidation("input", params, async () => { + if (!paramsp) { + throw new Error("No parameters provided"); + } + }); + + // Validate required parameters + const scheduleData = await traceValidation("scheduleParameters", paramsp, async () => { + if (paramsp == null || typeof paramsp !== "object" || !("time" in paramsp) || !("mode" in paramsp)) { + throw new Error("Please provide all the required parameters: time and mode."); + } + + // Use default values if not provided + const data = { + time: paramsp.time, + mode: paramsp.mode, + drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", + size: "size" in paramsp ? paramsp.size : "m", + quantity: "quantity" in paramsp ? paramsp.quantity : 1, + }; + + return data; + }); + + // Validate time format + await traceValidation("timeFormat", scheduleData.time, async () => { + const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; + if (!timeRegex.test(String(scheduleData.time))) { + throw new Error("Invalid time format. Please use HH:MM format."); + } + }); + + return scheduleData; + }, { + "input.present": !!paramsp, + "input.type": typeof paramsp, + "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", + "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" + }); + + // Continue with business logic (this will only execute if validation passes) + await createChildSpan("business.scheduleProcessing", async () => { + // Check schedule conflicts + await createChildSpan("check.scheduleConflicts", async () => { + const existingSchedule = schedules.find(s => + typeof s === "object" && s !== null && "time" in s && s.time === validatedParams.time + ); + if (existingSchedule) { + throw new Error(`Schedule already exists for time ${validatedParams.time}`); + } + }, { + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode) + }); + + // Save schedule to database + await traceDatabaseOperation("insert", "schedules", async () => { + schedules.push(validatedParams); + }); + + // Log schedule creation + await createChildSpan("logging.scheduleCreated", async () => { + console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); + }); + }, { + "business.operation": "schedule_processing", + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode) + }); return { result: true, message: `Your schedule has been set!`, }; - } - - return { - result: false, - message: `Please provide all the required parameters: time and mode.`, - }; + }, { + "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", + "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" + }); }) ); diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 535dc72..6b9e1f9 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -2,7 +2,8 @@ import { NodeTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace import { JaegerExporter } from "@opentelemetry/exporter-jaeger"; import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; -import { trace, SpanStatusCode } from "@opentelemetry/api"; +import { trace, SpanStatusCode, SpanKind } from "@opentelemetry/api"; + import WoT from "wot-typescript-definitions"; let tracer: any = null; @@ -102,18 +103,40 @@ function setSpanAttributes( } export function initTracing(serviceName: string): void { - const provider = new NodeTracerProvider({ - resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: serviceName }), - }); - provider.addSpanProcessor( - new BatchSpanProcessor( - new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", - }) - ) - ); - provider.register(); - tracer = trace.getTracer(serviceName); + try { + const provider = new NodeTracerProvider({ + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: serviceName, + [SemanticResourceAttributes.SERVICE_VERSION]: "1.0.0", + [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: "development", + }), + }); + + provider.addSpanProcessor( + new BatchSpanProcessor( + new JaegerExporter({ + endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", + }) + ) + ); + + provider.register(); + tracer = trace.getTracer(serviceName); + + console.log(`OpenTelemetry tracing initialized for service: ${serviceName}`); + } catch (error) { + console.error("Failed to initialize OpenTelemetry tracing:", error); + // Create a no-op tracer as fallback + tracer = { + startActiveSpan: (name: string, fn: Function) => { + return fn({ + setAttributes: () => {}, + setStatus: () => {}, + end: () => {} + }); + } + }; + } } export function traceAction( @@ -121,18 +144,29 @@ export function traceAction( fn: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise ): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { return async (params, options) => { + if (!tracer || !tracer.startActiveSpan) { + // Fallback if tracer is not available + return fn(params, options); + } + return tracer.startActiveSpan(`action.${name}`, async (span: any) => { try { const result = await fn(params, options); setSpanAttributes(span, name, "invokeaction", options, params, null, result); - span.setStatus({ code: SpanStatusCode.OK }); + if (span.setStatus) { + span.setStatus({ code: SpanStatusCode.OK }); + } return result; } catch (error) { setSpanAttributes(span, name, "invokeaction", options, params, error); - span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + if (span.setStatus) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + } throw error; } finally { - span.end(); + if (span.end) { + span.end(); + } } }); }; @@ -202,6 +236,97 @@ export function traceEvent( }; } +// Helper function to create nested spans for operations +export function createChildSpan( + operationName: string, + operation: () => Promise | T, + attributes?: Record +): Promise { + if (!tracer || !tracer.startActiveSpan) { + // Fallback if tracer is not available + return Promise.resolve(operation()); + } + + return tracer.startActiveSpan(operationName, async (span: any) => { + try { + // Add custom attributes if provided + if (attributes && span.setAttributes) { + span.setAttributes(attributes); + } + + const result = await operation(); + if (span.setStatus) { + span.setStatus({ code: SpanStatusCode.OK }); + } + return result; + } catch (error) { + if (span.setStatus) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + } + if (span.setAttributes) { + span.setAttributes({ + "error.name": error instanceof Error ? error.name : "Error", + "error.message": String(error) + }); + } + throw error; + } finally { + if (span.end) { + span.end(); + } + } + }); +} + +// Helper function to simulate database operations +export function traceDatabaseOperation( + operation: string, + table: string, + operation_fn: () => Promise | T +): Promise { + if (!tracer) { + return Promise.resolve(operation_fn()); + } + return createChildSpan(`db.${operation}`, operation_fn, { + "db.operation": operation, + "db.table": table, + "db.system": "memory", // Since we're using in-memory storage + "span.kind": "internal" + }); +} + +// Helper function to trace validation operations +export function traceValidation( + validationType: string, + data: any, + validation_fn: () => Promise | T +): Promise { + if (!tracer) { + return Promise.resolve(validation_fn()); + } + return createChildSpan(`validation.${validationType}`, validation_fn, { + "validation.type": validationType, + "validation.input": safeStringify(data), + "span.kind": "internal" + }); +} + +// Helper function to trace business logic operations +export function traceBusinessLogic( + operationName: string, + operation_fn: () => Promise | T, + metadata?: Record +): Promise { + if (!tracer) { + return Promise.resolve(operation_fn()); + } + return createChildSpan(`business.${operationName}`, operation_fn, { + "business.operation": operationName, + "span.kind": "internal", + ...metadata + }); +} + // Legacy compatibility export const tracedActionHandler = traceAction; export const tracedPropertyReadHandler = tracePropertyRead; diff --git a/things/advanced-coffee-machine/test-enhanced-tracing.sh b/things/advanced-coffee-machine/test-enhanced-tracing.sh new file mode 100755 index 0000000..5dfbf01 --- /dev/null +++ b/things/advanced-coffee-machine/test-enhanced-tracing.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +# Test script for Enhanced OpenTelemetry Tracing +# This script demonstrates the full-stack tracing capabilities + +echo "🚀 Testing Enhanced OpenTelemetry Tracing for Advanced Coffee Machine" +echo "==================================================" + +# Configuration +COFFEE_MACHINE_URL="http://localhost/http-advanced-coffee-machine" +JAEGER_URL="http://localhost:16686" + +echo "📋 Prerequisites:" +echo " - Coffee machine should be running on port 80 (via Docker/proxy)" +echo " - Jaeger should be running on port 16686" +echo " - View traces at: $JAEGER_URL" +echo "" + +sleep 2 + +echo "🧪 Test 0: Reset Resources (prepare for testing)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=milk" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=chocolate" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 1: Make a Latte (should show full nested trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=latte&size=l&quantity=1" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 2: Make an Espresso (smaller trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=s&quantity=2" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 3: Set a Valid Schedule (should show full nested trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ + -H 'Content-Type: application/json' \ + -d '{"time":"08:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 4: Invalid Schedule (should show error trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ + -H 'Content-Type: application/json' \ + -d '{"time":"25:99","mode":"everyday"}' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 5: Check Resources (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/allAvailableResources" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 6: Check Possible Drinks (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/possibleDrinks" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 7: Update Resource Level (property write trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '50' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 8: Update Served Counter (property write trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ + -H 'Content-Type: application/json' \ + -d '1001' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 9: Check Schedules (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/schedules" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 10: Trigger Low Resource Event - Set Water to 5% (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '5' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 11: Trigger Out of Resource Event - Set Coffee Beans to 0% (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ + -H 'Content-Type: application/json' \ + -d '0' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 12: Try Making Drink with No Coffee Beans (should trigger outOfResource event)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=m&quantity=1" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 13: Set High Served Counter to Trigger Maintenance Event (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ + -H 'Content-Type: application/json' \ + -d '1500' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 14: Check Maintenance Status After High Counter (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/maintenanceNeeded" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +echo "✅ All tests completed!" +echo "" +echo "🔍 To view the enhanced traces:" +echo " 1. Open Jaeger UI: $JAEGER_URL" +echo " 2. Select service: 'advanced-coffee-machine'" +echo " 3. Click 'Find Traces'" +echo " 4. Click on any trace to see the nested span structure" +echo "" +echo "📊 You should see traces with:" +echo " • HTTP request spans (auto-instrumented)" +echo " • property.read.* spans for GET requests with nested business logic" +echo " • property.write.* spans for PUT requests with validation and events" +echo " • action.* spans for POST requests with complex workflows" +echo " • event.* spans for outOfResource and maintenanceNeeded events" +echo " • Nested business logic, validation, and calculation spans" +echo " • Database operation spans (db.select, db.update, db.insert)" +echo " • Hardware simulation spans (sensors, drink preparation)" +echo " • Rich metadata and contextual attributes" +echo " • Error details and validation failures" +echo "" +echo "🎯 Event Testing Scenarios:" +echo " • Low resource alerts (water at 5%)" +echo " • Out of resource events (coffee beans at 0%)" +echo " • Maintenance threshold events (served counter > 1000)" +echo " • Failed drink attempts triggering resource events" +echo "" +echo "🚀 This comprehensive test covers ALL WoT interaction types with full-stack tracing!" \ No newline at end of file From 40bd75d8905321664229dc9e3b368ae1c71e335c Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Thu, 7 Aug 2025 22:04:44 -0700 Subject: [PATCH 12/34] refactor: remove low-level complexity and simplify OpenTelemetry tracing implementation --- coffee-machine-test-commands.txt | 17 +- .../http/ts/src/main.ts | 593 ++++-------------- .../test-enhanced-tracing.sh | 185 ------ 3 files changed, 133 insertions(+), 662 deletions(-) delete mode 100755 things/advanced-coffee-machine/test-enhanced-tracing.sh diff --git a/coffee-machine-test-commands.txt b/coffee-machine-test-commands.txt index cb38f7f..9319da6 100644 --- a/coffee-machine-test-commands.txt +++ b/coffee-machine-test-commands.txt @@ -1,4 +1,4 @@ -# Coffee Machine Tracing Test Commands +# Coffee Machine Basic Test Commands # 1. Property Read Tests curl -X GET http://localhost/http-advanced-coffee-machine/properties/allAvailableResources @@ -8,25 +8,14 @@ curl -X GET http://localhost/http-advanced-coffee-machine/properties/maintenance # 2. Property Write Tests curl -X PUT http://localhost/http-advanced-coffee-machine/properties/servedCounter -H 'Content-Type: application/json' -d '1001' curl -X PUT "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=water" -H 'Content-Type: application/json' -d '50' -curl -X PUT "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=coffeeBeans" -H 'Content-Type: application/json' -d '0' -# 3. Property Read After Write Tests -curl -X GET http://localhost/http-advanced-coffee-machine/properties/maintenanceNeeded -curl -X GET "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=water" - -# 4. Action Tests +# 3. Action Tests curl -X POST "http://localhost/http-advanced-coffee-machine/actions/makeDrink?drinkId=cappuccino&size=m&quantity=1" curl -X POST http://localhost/http-advanced-coffee-machine/actions/setSchedule -H 'Content-Type: application/json' -d '{"time":"10:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' -# 5. Property Read After Action Tests -curl -X GET http://localhost/http-advanced-coffee-machine/properties/schedules - -# 6. Event Trigger Tests (will trigger outOfResource event) -curl -X POST "http://localhost/http-advanced-coffee-machine/actions/makeDrink?drinkId=espresso&size=m&quantity=1" - # Expected Results: # - Property reads will show property.read.* traces # - Property writes will show property.write.* traces # - Actions will show action.* traces # - Events will show event.* traces (maintenanceNeeded and outOfResource) -# - Check Jaeger at http://localhost:16686 to see all the new spans \ No newline at end of file +# - Check Jaeger at http://localhost:16686 to see the traces \ No newline at end of file diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 3a4bd58..542a43e 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -31,10 +31,6 @@ import { tracedPropertyReadHandler, tracedPropertyWriteHandler, tracedEventHandler, - traceBusinessLogic, - traceValidation, - traceDatabaseOperation, - createChildSpan, } from "./tracing"; dotenv.config(); @@ -128,75 +124,11 @@ servient thing.setPropertyReadHandler( "allAvailableResources", - tracedPropertyReadHandler("allAvailableResources", async () => { - return await traceBusinessLogic("getAllResources", async () => { - // Validate resource data integrity - await traceValidation("resourceData", allAvailableResources, async () => { - const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; - for (const resource of requiredResources) { - if (!(resource in allAvailableResources)) { - throw new Error(`Missing required resource: ${resource}`); - } - if (typeof allAvailableResources[resource] !== "number") { - throw new Error(`Invalid resource level for ${resource}`); - } - } - }); - - // Read sensor data for real-time validation - const sensorData = await createChildSpan("sensors.readAll", async () => { - const readings: Record = {}; - for (const resource in allAvailableResources) { - readings[resource] = readFromSensor(resource); - } - return readings; - }, { - "sensor.count": Object.keys(allAvailableResources).length, - "sensor.type": "resource_level" - }); - - // Compare and sync with database - return await traceDatabaseOperation("select", "resource_levels", async () => { - // In a real system, you might sync with actual sensor readings - // For demo, we'll just return the current state - return { ...allAvailableResources }; - }); - }); - }) + tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) ); thing.setPropertyReadHandler( "possibleDrinks", - tracedPropertyReadHandler("possibleDrinks", async () => { - return await traceBusinessLogic("getPossibleDrinks", async () => { - // Validate drink catalog integrity - await traceValidation("drinkCatalog", possibleDrinks, async () => { - if (!Array.isArray(possibleDrinks)) { - throw new Error("Drink catalog is corrupted"); - } - if (possibleDrinks.length === 0) { - throw new Error("No drinks available in catalog"); - } - }); - - // Load drink availability from database - const availabilityMap = await traceDatabaseOperation("select", "drink_availability", async () => { - // Simulate checking drink availability based on current resources - const availability: Record = {}; - for (const drink of possibleDrinks) { - availability[drink] = true; // For demo, all drinks are available - } - return availability; - }); - - // Filter available drinks based on current resources - return await createChildSpan("processing.filterAvailableDrinks", async () => { - return possibleDrinks.filter(drink => availabilityMap[drink] !== false); - }, { - "drinks.total": possibleDrinks.length, - "filtering.criteria": "resource_availability" - }); - }); - }) + tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) ); thing.setPropertyReadHandler( "maintenanceNeeded", @@ -204,33 +136,7 @@ servient ); thing.setPropertyReadHandler( "schedules", - tracedPropertyReadHandler("schedules", async () => { - return await traceBusinessLogic("getSchedules", async () => { - // Validate system state - await traceValidation("systemState", { schedulesLength: schedules.length }, async () => { - if (!Array.isArray(schedules)) { - throw new Error("Schedules data structure is corrupted"); - } - }); - - // Load schedules from database - const result = await traceDatabaseOperation("select", "schedules", async () => { - return schedules; - }); - - // Process and filter active schedules - return await createChildSpan("processing.filterActiveSchedules", async () => { - const currentTime = new Date(); - return result.filter((schedule: any) => { - // For demo purposes, all schedules are considered active - return true; - }); - }, { - "schedules.count": schedules.length, - "query.time": new Date().toISOString() - }); - }); - }) + tracedPropertyReadHandler("schedules", async () => schedules) ); // Override a write handler for servedCounter property, @@ -238,66 +144,23 @@ servient thing.setPropertyWriteHandler( "servedCounter", tracedPropertyWriteHandler("servedCounter", async (val) => { - return await traceBusinessLogic("updateServedCounter", async () => { - // Validate input - await traceValidation("counterInput", val, async () => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - }); - - // Parse and validate the new counter value - const newCounterValue = await createChildSpan("parsing.extractCounterValue", async () => { - const value = (await (val as any).value()) as number; - if (typeof value !== "number" || value < 0) { - throw new Error(`Invalid served counter value: ${value}`); - } - return value; - }, { - "input.type": typeof val, - "parsing.operation": "counter_extraction" - }); - - // Update counter in database - await traceDatabaseOperation("update", "counters", async () => { - servedCounter = newCounterValue; - }); - - // Check maintenance threshold and trigger events if needed - await createChildSpan("business.checkMaintenanceThreshold", async () => { - if (servedCounter > 1000) { - // Update maintenance status - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); - - // Emit maintenance event - await createChildSpan("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); - - // Send notification to administrators - await createChildSpan("notification.sendAlert", async () => { - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - }, { - "notification.type": "maintenance_alert", - "notification.recipient": "admin@coffeeMachine.com", - "counter.value": servedCounter, - "maintenance.threshold": 1000 - }); - } - }, { - "counter.current": servedCounter, - "counter.previous": servedCounter - newCounterValue, - "maintenance.threshold": 1000, - "maintenance.needed": maintenanceNeeded - }); - }); + if (!val) { + throw new Error("No value provided for servedCounter"); + } + servedCounter = (await (val as any).value()) as number; + if (servedCounter > 1000) { + maintenanceNeeded = true; + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + + // Notify a "maintainer" when the value has changed + // (the notify function here simply logs a message to the console) + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + } }) ); @@ -309,98 +172,19 @@ servient thing.setPropertyWriteHandler( "availableResourceLevel", tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - return await traceBusinessLogic("updateResourceLevel", async () => { - // Validate URI variables and extract resource ID - const resourceId = await traceValidation("uriVariables", options, async () => { - if (!Boolean(options) || typeof options !== "object" || !("uriVariables" in options)) { - throw new Error("URI variables are required"); - } - const uriVariables = options.uriVariables as Record; - if (!("id" in uriVariables)) { - throw new Error("Please specify id variable as uriVariables."); - } + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + if ("id" in uriVariables) { const id = uriVariables.id; - - // Validate resource ID - const validResources = ["water", "milk", "chocolate", "coffeeBeans"]; - if (!validResources.includes(id)) { - throw new Error(`Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}`); - } - return id; - }); - - // Validate and parse the new resource level - const newLevel = await createChildSpan("parsing.extractResourceLevel", async () => { if (!val) { throw new Error("No value provided for availableResourceLevel"); } - const level = (await (val as any).value()) as number; - - // Validate resource level range - if (typeof level !== "number" || level < 0 || level > 100) { - throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); - } - return level; - }, { - "resource.id": resourceId, - "input.type": typeof val - }); - - // Check current level and calculate change - const levelChange = await createChildSpan("calculate.levelChange", async () => { - const currentLevel = allAvailableResources[resourceId]; - const change = newLevel - currentLevel; - return { - previous: currentLevel, - new: newLevel, - change: change, - changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change" - }; - }, { - "resource.id": resourceId, - "calculation.type": "level_change" - }); - - // Update resource level in database - await traceDatabaseOperation("update", "resource_levels", async () => { - allAvailableResources[resourceId] = newLevel; - }); - - // Check for low resource alerts - await createChildSpan("business.checkResourceThresholds", async () => { - if (newLevel <= 10) { - // Emit low resource event - await createChildSpan("event.lowResource", async () => { - const eventData = `Low level of ${resourceId}: ${newLevel}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); - }); - } - - if (newLevel === 0) { - // Update maintenance needed flag - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); - } - }, { - "resource.id": resourceId, - "resource.level": newLevel, - "threshold.low": 10, - "threshold.empty": 0, - "maintenance.needed": maintenanceNeeded - }); - - // Log resource level change - await createChildSpan("logging.resourceUpdate", async () => { - console.log(`Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})`); - }, { - "resource.id": resourceId, - "level.previous": levelChange.previous, - "level.new": newLevel, - "change.type": levelChange.changeType, - "change.amount": levelChange.change - }); - }); + allAvailableResources[id] = (await (val as any).value()) as number; + return; + } + } + throw Error("Please specify id variable as uriVariables."); }) ); @@ -425,11 +209,59 @@ servient thing.setActionHandler( "makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { - // Parse input parameters first to use in metadata + // Default values let drinkId = "americano"; let size = "m"; let quantity = 1; + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; + + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; + + // Check if uriVariables are provided if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { const uriVariables = options.uriVariables as Record; drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; @@ -437,147 +269,45 @@ servient quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - return await traceBusinessLogic("makeDrink", async () => { - // Validate input parameters - await traceValidation("input", options, async () => { - if (!drinkId || !size || !quantity) { - throw new Error("Invalid input parameters"); - } - }); - - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation("select", "recipes", async () => { - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, + // Testing to see what happens when thing crashes + // if (drinkId === "americano") { + // throw new Error("Americano is not available"); + // } + + // Calculate the new level of resources + const newResources = Object.assign({}, allAvailableResources); + newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); + newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); + newResources.chocolate -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate + ); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + ); + + // Check if the amount of available resources is sufficient to make a drink + for (const resource in newResources) { + if (newResources[resource] <= 0) { + const eventData = `Low level of ${resource}: ${newResources[resource]}%`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( + eventData + ); + return { + result: false, + message: `${resource} level is not sufficient`, }; + } + } - return { drinkRecipes, sizeQuantifiers }; - }); + // Now store the new level of allAvailableResources + allAvailableResources = newResources; + servedCounter = servedCounter + quantity; - // Validate drink availability - await traceValidation("drinkAvailability", drinkId, async () => { - if (!drinkRecipes[drinkId]) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (!sizeQuantifiers[size]) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); - - // Get current resources from sensors - const currentResources = await traceDatabaseOperation("select", "resources", async () => { - return { ...allAvailableResources }; - }); - - // Calculate resource consumption - const newResources = await createChildSpan("calculate.resourceConsumption", async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; - - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); - - return newResources; - }, { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption" - }); - - // Validate resource availability - await traceValidation("resourceAvailability", newResources, async () => { - for (const resource in newResources) { - if (newResources[resource] <= 0) { - const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - await createChildSpan("event.outOfResource", async () => { - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); - }); - throw new Error(`${resource} level is not sufficient`); - } - } - }); - - // Update resources in database - await traceDatabaseOperation("update", "resources", async () => { - allAvailableResources = newResources; - }); - - // Update served counter - await traceDatabaseOperation("update", "counters", async () => { - servedCounter = servedCounter + quantity; - }); - - // Simulate drink preparation - await createChildSpan("hardware.prepareDrink", async () => { - // Simulate time for drink preparation - await new Promise(resolve => setTimeout(resolve, 100)); - }, { - "hardware.operation": "drink_preparation", - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity - }); - - // Return success response - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - }, { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity - }); + // Finally deliver the drink + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; }) ); @@ -585,91 +315,28 @@ servient thing.setActionHandler( "setSchedule", tracedActionHandler("setSchedule", async (params, options) => { - // Parse input parameters first for metadata const paramsp = params ? ((await (params as any).value()) as Record) : null; - - return await traceBusinessLogic("setSchedule", async () => { - // Always create initial validation span to show the process started - const validatedParams = await createChildSpan("initialization.parseInput", async () => { - // Validate input parameters - await traceValidation("input", params, async () => { - if (!paramsp) { - throw new Error("No parameters provided"); - } - }); - - // Validate required parameters - const scheduleData = await traceValidation("scheduleParameters", paramsp, async () => { - if (paramsp == null || typeof paramsp !== "object" || !("time" in paramsp) || !("mode" in paramsp)) { - throw new Error("Please provide all the required parameters: time and mode."); - } - - // Use default values if not provided - const data = { - time: paramsp.time, - mode: paramsp.mode, - drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", - size: "size" in paramsp ? paramsp.size : "m", - quantity: "quantity" in paramsp ? paramsp.quantity : 1, - }; - - return data; - }); - - // Validate time format - await traceValidation("timeFormat", scheduleData.time, async () => { - const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; - if (!timeRegex.test(String(scheduleData.time))) { - throw new Error("Invalid time format. Please use HH:MM format."); - } - }); - - return scheduleData; - }, { - "input.present": !!paramsp, - "input.type": typeof paramsp, - "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", - "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" - }); - - // Continue with business logic (this will only execute if validation passes) - await createChildSpan("business.scheduleProcessing", async () => { - // Check schedule conflicts - await createChildSpan("check.scheduleConflicts", async () => { - const existingSchedule = schedules.find(s => - typeof s === "object" && s !== null && "time" in s && s.time === validatedParams.time - ); - if (existingSchedule) { - throw new Error(`Schedule already exists for time ${validatedParams.time}`); - } - }, { - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode) - }); - - // Save schedule to database - await traceDatabaseOperation("insert", "schedules", async () => { - schedules.push(validatedParams); - }); - - // Log schedule creation - await createChildSpan("logging.scheduleCreated", async () => { - console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); - }); - }, { - "business.operation": "schedule_processing", - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode) - }); + + // Check if required parameters are provided + if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { + // Use default values if not provided + paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; + paramsp.size = "size" in paramsp ? paramsp.size : "m"; + paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; + + // Now add a new schedule + schedules.push(paramsp); return { result: true, message: `Your schedule has been set!`, }; - }, { - "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", - "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" - }); + } + + return { + result: false, + message: `Please provide all the required parameters: time and mode.`, + }; }) ); diff --git a/things/advanced-coffee-machine/test-enhanced-tracing.sh b/things/advanced-coffee-machine/test-enhanced-tracing.sh deleted file mode 100755 index 5dfbf01..0000000 --- a/things/advanced-coffee-machine/test-enhanced-tracing.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/bash - -# Test script for Enhanced OpenTelemetry Tracing -# This script demonstrates the full-stack tracing capabilities - -echo "🚀 Testing Enhanced OpenTelemetry Tracing for Advanced Coffee Machine" -echo "==================================================" - -# Configuration -COFFEE_MACHINE_URL="http://localhost/http-advanced-coffee-machine" -JAEGER_URL="http://localhost:16686" - -echo "📋 Prerequisites:" -echo " - Coffee machine should be running on port 80 (via Docker/proxy)" -echo " - Jaeger should be running on port 16686" -echo " - View traces at: $JAEGER_URL" -echo "" - -sleep 2 - -echo "🧪 Test 0: Reset Resources (prepare for testing)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ - -H 'Content-Type: application/json' \ - -d '100' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=milk" \ - -H 'Content-Type: application/json' \ - -d '100' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=chocolate" \ - -H 'Content-Type: application/json' \ - -d '100' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ - -H 'Content-Type: application/json' \ - -d '100' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 1: Make a Latte (should show full nested trace)" -echo "----------------------------------------" -curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=latte&size=l&quantity=1" \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 2: Make an Espresso (smaller trace)" -echo "----------------------------------------" -curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=s&quantity=2" \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 3: Set a Valid Schedule (should show full nested trace)" -echo "----------------------------------------" -curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ - -H 'Content-Type: application/json' \ - -d '{"time":"08:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 4: Invalid Schedule (should show error trace)" -echo "----------------------------------------" -curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ - -H 'Content-Type: application/json' \ - -d '{"time":"25:99","mode":"everyday"}' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 5: Check Resources (property read trace)" -echo "----------------------------------------" -curl -X GET "$COFFEE_MACHINE_URL/properties/allAvailableResources" \ - -H 'Accept: application/json' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 6: Check Possible Drinks (property read trace)" -echo "----------------------------------------" -curl -X GET "$COFFEE_MACHINE_URL/properties/possibleDrinks" \ - -H 'Accept: application/json' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 7: Update Resource Level (property write trace)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ - -H 'Content-Type: application/json' \ - -d '50' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 8: Update Served Counter (property write trace)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ - -H 'Content-Type: application/json' \ - -d '1001' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 9: Check Schedules (property read trace)" -echo "----------------------------------------" -curl -X GET "$COFFEE_MACHINE_URL/properties/schedules" \ - -H 'Accept: application/json' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 10: Trigger Low Resource Event - Set Water to 5% (event trace)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ - -H 'Content-Type: application/json' \ - -d '5' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 11: Trigger Out of Resource Event - Set Coffee Beans to 0% (event trace)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ - -H 'Content-Type: application/json' \ - -d '0' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 12: Try Making Drink with No Coffee Beans (should trigger outOfResource event)" -echo "----------------------------------------" -curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=m&quantity=1" \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 13: Set High Served Counter to Trigger Maintenance Event (event trace)" -echo "----------------------------------------" -curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ - -H 'Content-Type: application/json' \ - -d '1500' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -sleep 1 - -echo "🧪 Test 14: Check Maintenance Status After High Counter (property read trace)" -echo "----------------------------------------" -curl -X GET "$COFFEE_MACHINE_URL/properties/maintenanceNeeded" \ - -H 'Accept: application/json' \ - -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" - -echo "✅ All tests completed!" -echo "" -echo "🔍 To view the enhanced traces:" -echo " 1. Open Jaeger UI: $JAEGER_URL" -echo " 2. Select service: 'advanced-coffee-machine'" -echo " 3. Click 'Find Traces'" -echo " 4. Click on any trace to see the nested span structure" -echo "" -echo "📊 You should see traces with:" -echo " • HTTP request spans (auto-instrumented)" -echo " • property.read.* spans for GET requests with nested business logic" -echo " • property.write.* spans for PUT requests with validation and events" -echo " • action.* spans for POST requests with complex workflows" -echo " • event.* spans for outOfResource and maintenanceNeeded events" -echo " • Nested business logic, validation, and calculation spans" -echo " • Database operation spans (db.select, db.update, db.insert)" -echo " • Hardware simulation spans (sensors, drink preparation)" -echo " • Rich metadata and contextual attributes" -echo " • Error details and validation failures" -echo "" -echo "🎯 Event Testing Scenarios:" -echo " • Low resource alerts (water at 5%)" -echo " • Out of resource events (coffee beans at 0%)" -echo " • Maintenance threshold events (served counter > 1000)" -echo " • Failed drink attempts triggering resource events" -echo "" -echo "🚀 This comprehensive test covers ALL WoT interaction types with full-stack tracing!" \ No newline at end of file From 2e4284e297aaa32bc023eadfccc1e08e5482d836 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Thu, 7 Aug 2025 22:19:08 -0700 Subject: [PATCH 13/34] Added test file --- coffee-machine-test-commands.txt | 21 ---- tests/test-enhanced-tracing.sh | 185 +++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 21 deletions(-) delete mode 100644 coffee-machine-test-commands.txt create mode 100755 tests/test-enhanced-tracing.sh diff --git a/coffee-machine-test-commands.txt b/coffee-machine-test-commands.txt deleted file mode 100644 index 9319da6..0000000 --- a/coffee-machine-test-commands.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Coffee Machine Basic Test Commands - -# 1. Property Read Tests -curl -X GET http://localhost/http-advanced-coffee-machine/properties/allAvailableResources -curl -X GET http://localhost/http-advanced-coffee-machine/properties/possibleDrinks -curl -X GET http://localhost/http-advanced-coffee-machine/properties/maintenanceNeeded - -# 2. Property Write Tests -curl -X PUT http://localhost/http-advanced-coffee-machine/properties/servedCounter -H 'Content-Type: application/json' -d '1001' -curl -X PUT "http://localhost/http-advanced-coffee-machine/properties/availableResourceLevel?id=water" -H 'Content-Type: application/json' -d '50' - -# 3. Action Tests -curl -X POST "http://localhost/http-advanced-coffee-machine/actions/makeDrink?drinkId=cappuccino&size=m&quantity=1" -curl -X POST http://localhost/http-advanced-coffee-machine/actions/setSchedule -H 'Content-Type: application/json' -d '{"time":"10:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' - -# Expected Results: -# - Property reads will show property.read.* traces -# - Property writes will show property.write.* traces -# - Actions will show action.* traces -# - Events will show event.* traces (maintenanceNeeded and outOfResource) -# - Check Jaeger at http://localhost:16686 to see the traces \ No newline at end of file diff --git a/tests/test-enhanced-tracing.sh b/tests/test-enhanced-tracing.sh new file mode 100755 index 0000000..88edded --- /dev/null +++ b/tests/test-enhanced-tracing.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +# Test script for Enhanced OpenTelemetry Tracing +# This script demonstrates the full-stack tracing capabilities + +echo "🚀 Testing Enhanced OpenTelemetry Tracing for Advanced Coffee Machine" +echo "==================================================" + +# Configuration +COFFEE_MACHINE_URL="http://localhost/http-advanced-coffee-machine" +JAEGER_URL="http://localhost:16686" + +echo "📋 Prerequisites:" +echo " - Coffee machine should be running on port 80 (via Docker/proxy)" +echo " - Jaeger should be running on port 16686" +echo " - View traces at: $JAEGER_URL" +echo "" + +sleep 2 + +echo "🧪 Test 0: Reset Resources (prepare for testing)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=milk" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=chocolate" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ + -H 'Content-Type: application/json' \ + -d '100' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 1: Make a Latte (should show full nested trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=latte&size=l&quantity=1" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 2: Make an Espresso (smaller trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=s&quantity=2" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 3: Set a Valid Schedule (should show full nested trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ + -H 'Content-Type: application/json' \ + -d '{"time":"08:00","mode":"everyday","drinkId":"latte","size":"l","quantity":2}' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 4: Invalid Schedule (should show error trace)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/setSchedule" \ + -H 'Content-Type: application/json' \ + -d '{"time":"25:99","mode":"everyday"}' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 5: Check Resources (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/allAvailableResources" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 6: Check Possible Drinks (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/possibleDrinks" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 7: Update Resource Level (property write trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '50' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 8: Update Served Counter (property write trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ + -H 'Content-Type: application/json' \ + -d '1001' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 9: Check Schedules (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/schedules" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 10: Trigger Low Resource Event - Set Water to 5% (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=water" \ + -H 'Content-Type: application/json' \ + -d '5' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 11: Trigger Out of Resource Event - Set Coffee Beans to 0% (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/availableResourceLevel?id=coffeeBeans" \ + -H 'Content-Type: application/json' \ + -d '0' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 12: Try Making Drink with No Coffee Beans (should trigger outOfResource event)" +echo "----------------------------------------" +curl -X POST "$COFFEE_MACHINE_URL/actions/makeDrink?drinkId=espresso&size=m&quantity=1" \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 13: Set High Served Counter to Trigger Maintenance Event (event trace)" +echo "----------------------------------------" +curl -X PUT "$COFFEE_MACHINE_URL/properties/servedCounter" \ + -H 'Content-Type: application/json' \ + -d '1500' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +sleep 1 + +echo "🧪 Test 14: Check Maintenance Status After High Counter (property read trace)" +echo "----------------------------------------" +curl -X GET "$COFFEE_MACHINE_URL/properties/maintenanceNeeded" \ + -H 'Accept: application/json' \ + -w "\nStatus: %{http_code}\nTime: %{time_total}s\n\n" + +echo "✅ All tests completed!" +echo "" +echo "🔍 To view the enhanced traces:" +echo " 1. Open Jaeger UI: $JAEGER_URL" +echo " 2. Select service: 'advanced-coffee-machine'" +echo " 3. Click 'Find Traces'" +echo " 4. Click on any trace to see the nested span structure" +echo "" +echo "📊 You should see traces with:" +echo " • HTTP request spans (auto-instrumented)" +echo " • property.read.* spans for GET requests with nested business logic" +echo " • property.write.* spans for PUT requests with validation and events" +echo " • action.* spans for POST requests with complex workflows" +echo " • event.* spans for outOfResource and maintenanceNeeded events" +echo " • Nested business logic, validation, and calculation spans" +echo " • Database operation spans (db.select, db.update, db.insert)" +echo " • Hardware simulation spans (sensors, drink preparation)" +echo " • Rich metadata and contextual attributes" +echo " • Error details and validation failures" +echo "" +echo "🎯 Event Testing Scenarios:" +echo " • Low resource alerts (water at 5%)" +echo " • Out of resource events (coffee beans at 0%)" +echo " • Maintenance threshold events (served counter > 1000)" +echo " • Failed drink attempts triggering resource events" +echo "" +echo "🚀 This comprehensive test covers ALL WoT interaction types with full-stack tracing!" From d4ecd0ed17ceb83794e51a0d05abc3e7f1670c3c Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Thu, 7 Aug 2025 22:23:11 -0700 Subject: [PATCH 14/34] fix: ran npm run format --- .../http/ts/src/tracing.ts | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 6b9e1f9..460b90b 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -105,13 +105,13 @@ function setSpanAttributes( export function initTracing(serviceName: string): void { try { const provider = new NodeTracerProvider({ - resource: new Resource({ + resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: serviceName, [SemanticResourceAttributes.SERVICE_VERSION]: "1.0.0", [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: "development", }), }); - + provider.addSpanProcessor( new BatchSpanProcessor( new JaegerExporter({ @@ -119,10 +119,10 @@ export function initTracing(serviceName: string): void { }) ) ); - + provider.register(); tracer = trace.getTracer(serviceName); - + console.log(`OpenTelemetry tracing initialized for service: ${serviceName}`); } catch (error) { console.error("Failed to initialize OpenTelemetry tracing:", error); @@ -132,9 +132,9 @@ export function initTracing(serviceName: string): void { return fn({ setAttributes: () => {}, setStatus: () => {}, - end: () => {} + end: () => {}, }); - } + }, }; } } @@ -148,7 +148,7 @@ export function traceAction( // Fallback if tracer is not available return fn(params, options); } - + return tracer.startActiveSpan(`action.${name}`, async (span: any) => { try { const result = await fn(params, options); @@ -238,7 +238,7 @@ export function traceEvent( // Helper function to create nested spans for operations export function createChildSpan( - operationName: string, + operationName: string, operation: () => Promise | T, attributes?: Record ): Promise { @@ -246,14 +246,14 @@ export function createChildSpan( // Fallback if tracer is not available return Promise.resolve(operation()); } - + return tracer.startActiveSpan(operationName, async (span: any) => { try { // Add custom attributes if provided if (attributes && span.setAttributes) { span.setAttributes(attributes); } - + const result = await operation(); if (span.setStatus) { span.setStatus({ code: SpanStatusCode.OK }); @@ -264,9 +264,9 @@ export function createChildSpan( span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); } if (span.setAttributes) { - span.setAttributes({ + span.setAttributes({ "error.name": error instanceof Error ? error.name : "Error", - "error.message": String(error) + "error.message": String(error), }); } throw error; @@ -291,23 +291,19 @@ export function traceDatabaseOperation( "db.operation": operation, "db.table": table, "db.system": "memory", // Since we're using in-memory storage - "span.kind": "internal" + "span.kind": "internal", }); } // Helper function to trace validation operations -export function traceValidation( - validationType: string, - data: any, - validation_fn: () => Promise | T -): Promise { +export function traceValidation(validationType: string, data: any, validation_fn: () => Promise | T): Promise { if (!tracer) { return Promise.resolve(validation_fn()); } return createChildSpan(`validation.${validationType}`, validation_fn, { "validation.type": validationType, "validation.input": safeStringify(data), - "span.kind": "internal" + "span.kind": "internal", }); } @@ -323,7 +319,7 @@ export function traceBusinessLogic( return createChildSpan(`business.${operationName}`, operation_fn, { "business.operation": operationName, "span.kind": "internal", - ...metadata + ...metadata, }); } From 0ec0d838fc0127e764bbbffd4b9d2789f233fb33 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 11 Aug 2025 11:47:18 -0700 Subject: [PATCH 15/34] Fix Jaeger tracing configuration spans still not showing up --- README.md | 2 +- docker-compose-things-local.yml | 2 +- tests/test-enhanced-tracing.sh | 5 +- .../http/ts/src/main.ts | 252 ++++++++++-------- .../http/ts/src/tracing.ts | 15 +- 5 files changed, 153 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 99e4504..04b3200 100644 --- a/README.md +++ b/README.md @@ -181,4 +181,4 @@ For Node.js-based devices, we use npm workspaces and running `npm install` at th ## Tracing -Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:16686](http://localhost:16686) in your browser (Jaeger UI). +Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:8084](http://localhost:8084) in your browser (Jaeger UI). Traces are sent to the Jaeger collector on port 14268. diff --git a/docker-compose-things-local.yml b/docker-compose-things-local.yml index 5aac027..6bac58a 100644 --- a/docker-compose-things-local.yml +++ b/docker-compose-things-local.yml @@ -109,7 +109,7 @@ services: environment: - HOSTNAME=${STACK_HOSTNAME} - PORT=${WEB_PORT_OUT} - - JAEGER_ENDPOINT=http://host.docker.internal:14268/api/traces + - JAEGER_ENDPOINT=http://host.docker.internal:8085/api/traces networks: - things_network http-data-schema-thing: diff --git a/tests/test-enhanced-tracing.sh b/tests/test-enhanced-tracing.sh index 88edded..52b2acd 100755 --- a/tests/test-enhanced-tracing.sh +++ b/tests/test-enhanced-tracing.sh @@ -8,11 +8,12 @@ echo "==================================================" # Configuration COFFEE_MACHINE_URL="http://localhost/http-advanced-coffee-machine" -JAEGER_URL="http://localhost:16686" +JAEGER_URL="http://jaeger.localhost" + echo "📋 Prerequisites:" echo " - Coffee machine should be running on port 80 (via Docker/proxy)" -echo " - Jaeger should be running on port 16686" +echo " - Jaeger should be running on port 8084 (UI) and 14268 (collector)" echo " - View traces at: $JAEGER_URL" echo "" diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 542a43e..4272a9e 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -31,6 +31,10 @@ import { tracedPropertyReadHandler, tracedPropertyWriteHandler, tracedEventHandler, + traceBusinessLogic, + traceDatabaseOperation, + traceValidation, + createChildSpan, } from "./tracing"; dotenv.config(); @@ -124,7 +128,11 @@ servient thing.setPropertyReadHandler( "allAvailableResources", - tracedPropertyReadHandler("allAvailableResources", async () => allAvailableResources) + tracedPropertyReadHandler("allAvailableResources", async () => { + return traceDatabaseOperation("select", "resources", async () => { + return allAvailableResources; + }); + }) ); thing.setPropertyReadHandler( "possibleDrinks", @@ -209,105 +217,111 @@ servient thing.setActionHandler( "makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { - // Default values - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + return traceBusinessLogic("drinkPreparation", async () => { + // Default values + let drinkId = "americano"; + let size = "m"; + let quantity = 1; + + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; - // Testing to see what happens when thing crashes - // if (drinkId === "americano") { - // throw new Error("Americano is not available"); - // } - - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate - ); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans - ); - - // Check if the amount of available resources is sufficient to make a drink - for (const resource in newResources) { - if (newResources[resource] <= 0) { - const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( - eventData - ); - return { - result: false, - message: `${resource} level is not sufficient`, - }; + // Check if uriVariables are provided + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; + size = "size" in uriVariables ? (uriVariables.size as string) : size; + quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - } - // Now store the new level of allAvailableResources - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; + // Testing to see what happens when thing crashes + // if (drinkId === "americano") { + // throw new Error("Americano is not available"); + // } + + // Calculate the new level of resources + const newResources = Object.assign({}, allAvailableResources); + newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); + newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); + newResources.chocolate -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate + ); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans + ); - // Finally deliver the drink - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; + // Check if the amount of available resources is sufficient to make a drink + return traceValidation("resourceAvailability", newResources, async () => { + for (const resource in newResources) { + if (newResources[resource] <= 0) { + const eventData = `Low level of ${resource}: ${newResources[resource]}%`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( + eventData + ); + return { + result: false, + message: `${resource} level is not sufficient`, + }; + } + } + + // Now store the new level of allAvailableResources + return traceDatabaseOperation("update", "resources", async () => { + allAvailableResources = newResources; + servedCounter = servedCounter + quantity; + + // Finally deliver the drink + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + }); + }); + }); }) ); @@ -315,28 +329,34 @@ servient thing.setActionHandler( "setSchedule", tracedActionHandler("setSchedule", async (params, options) => { - const paramsp = params ? ((await (params as any).value()) as Record) : null; - - // Check if required parameters are provided - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { - // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - - // Now add a new schedule - schedules.push(paramsp); - - return { - result: true, - message: `Your schedule has been set!`, - }; - } + return traceBusinessLogic("scheduleManagement", async () => { + const paramsp = params ? ((await (params as any).value()) as Record) : null; + + // Check if required parameters are provided + return traceValidation("scheduleParameters", paramsp, async () => { + if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { + // Use default values if not provided + paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; + paramsp.size = "size" in paramsp ? paramsp.size : "m"; + paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; + + // Now add a new schedule + return traceDatabaseOperation("insert", "schedules", async () => { + schedules.push(paramsp); + + return { + result: true, + message: `Your schedule has been set!`, + }; + }); + } - return { - result: false, - message: `Please provide all the required parameters: time and mode.`, - }; + return { + result: false, + message: `Please provide all the required parameters: time and mode.`, + }; + }); + }); }) ); diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 6b9e1f9..784cdc5 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -115,8 +115,14 @@ export function initTracing(serviceName: string): void { provider.addSpanProcessor( new BatchSpanProcessor( new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:14268/api/traces", - }) + endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:8085/api/traces", + }), + { + // Ensure spans are processed quickly + scheduledDelayMillis: 100, + maxQueueSize: 1000, + maxExportBatchSize: 100, + } ) ); @@ -244,9 +250,11 @@ export function createChildSpan( ): Promise { if (!tracer || !tracer.startActiveSpan) { // Fallback if tracer is not available + console.log(`[TRACING] No tracer available for: ${operationName}`); return Promise.resolve(operation()); } - + + console.log(`[TRACING] Creating child span: ${operationName}`); return tracer.startActiveSpan(operationName, async (span: any) => { try { // Add custom attributes if provided @@ -258,6 +266,7 @@ export function createChildSpan( if (span.setStatus) { span.setStatus({ code: SpanStatusCode.OK }); } + console.log(`[TRACING] Child span completed: ${operationName}`); return result; } catch (error) { if (span.setStatus) { From a5e79966d0ca105c7c5498664e4c5dbdbb1c77d1 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 11 Aug 2025 12:15:06 -0700 Subject: [PATCH 16/34] Added more spans --- .../http/ts/src/main.ts | 607 +++++++++++++----- 1 file changed, 460 insertions(+), 147 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 4272a9e..3a4bd58 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -32,8 +32,8 @@ import { tracedPropertyWriteHandler, tracedEventHandler, traceBusinessLogic, - traceDatabaseOperation, traceValidation, + traceDatabaseOperation, createChildSpan, } from "./tracing"; dotenv.config(); @@ -129,14 +129,74 @@ servient thing.setPropertyReadHandler( "allAvailableResources", tracedPropertyReadHandler("allAvailableResources", async () => { - return traceDatabaseOperation("select", "resources", async () => { - return allAvailableResources; + return await traceBusinessLogic("getAllResources", async () => { + // Validate resource data integrity + await traceValidation("resourceData", allAvailableResources, async () => { + const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; + for (const resource of requiredResources) { + if (!(resource in allAvailableResources)) { + throw new Error(`Missing required resource: ${resource}`); + } + if (typeof allAvailableResources[resource] !== "number") { + throw new Error(`Invalid resource level for ${resource}`); + } + } + }); + + // Read sensor data for real-time validation + const sensorData = await createChildSpan("sensors.readAll", async () => { + const readings: Record = {}; + for (const resource in allAvailableResources) { + readings[resource] = readFromSensor(resource); + } + return readings; + }, { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level" + }); + + // Compare and sync with database + return await traceDatabaseOperation("select", "resource_levels", async () => { + // In a real system, you might sync with actual sensor readings + // For demo, we'll just return the current state + return { ...allAvailableResources }; + }); }); }) ); thing.setPropertyReadHandler( "possibleDrinks", - tracedPropertyReadHandler("possibleDrinks", async () => possibleDrinks) + tracedPropertyReadHandler("possibleDrinks", async () => { + return await traceBusinessLogic("getPossibleDrinks", async () => { + // Validate drink catalog integrity + await traceValidation("drinkCatalog", possibleDrinks, async () => { + if (!Array.isArray(possibleDrinks)) { + throw new Error("Drink catalog is corrupted"); + } + if (possibleDrinks.length === 0) { + throw new Error("No drinks available in catalog"); + } + }); + + // Load drink availability from database + const availabilityMap = await traceDatabaseOperation("select", "drink_availability", async () => { + // Simulate checking drink availability based on current resources + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; // For demo, all drinks are available + } + return availability; + }); + + // Filter available drinks based on current resources + return await createChildSpan("processing.filterAvailableDrinks", async () => { + return possibleDrinks.filter(drink => availabilityMap[drink] !== false); + }, { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability" + }); + }); + }) ); thing.setPropertyReadHandler( "maintenanceNeeded", @@ -144,7 +204,33 @@ servient ); thing.setPropertyReadHandler( "schedules", - tracedPropertyReadHandler("schedules", async () => schedules) + tracedPropertyReadHandler("schedules", async () => { + return await traceBusinessLogic("getSchedules", async () => { + // Validate system state + await traceValidation("systemState", { schedulesLength: schedules.length }, async () => { + if (!Array.isArray(schedules)) { + throw new Error("Schedules data structure is corrupted"); + } + }); + + // Load schedules from database + const result = await traceDatabaseOperation("select", "schedules", async () => { + return schedules; + }); + + // Process and filter active schedules + return await createChildSpan("processing.filterActiveSchedules", async () => { + const currentTime = new Date(); + return result.filter((schedule: any) => { + // For demo purposes, all schedules are considered active + return true; + }); + }, { + "schedules.count": schedules.length, + "query.time": new Date().toISOString() + }); + }); + }) ); // Override a write handler for servedCounter property, @@ -152,23 +238,66 @@ servient thing.setPropertyWriteHandler( "servedCounter", tracedPropertyWriteHandler("servedCounter", async (val) => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - servedCounter = (await (val as any).value()) as number; - if (servedCounter > 1000) { - maintenanceNeeded = true; - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - - // Notify a "maintainer" when the value has changed - // (the notify function here simply logs a message to the console) - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - } + return await traceBusinessLogic("updateServedCounter", async () => { + // Validate input + await traceValidation("counterInput", val, async () => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + }); + + // Parse and validate the new counter value + const newCounterValue = await createChildSpan("parsing.extractCounterValue", async () => { + const value = (await (val as any).value()) as number; + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); + } + return value; + }, { + "input.type": typeof val, + "parsing.operation": "counter_extraction" + }); + + // Update counter in database + await traceDatabaseOperation("update", "counters", async () => { + servedCounter = newCounterValue; + }); + + // Check maintenance threshold and trigger events if needed + await createChildSpan("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + + // Emit maintenance event + await createChildSpan("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); + + // Send notification to administrators + await createChildSpan("notification.sendAlert", async () => { + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + }, { + "notification.type": "maintenance_alert", + "notification.recipient": "admin@coffeeMachine.com", + "counter.value": servedCounter, + "maintenance.threshold": 1000 + }); + } + }, { + "counter.current": servedCounter, + "counter.previous": servedCounter - newCounterValue, + "maintenance.threshold": 1000, + "maintenance.needed": maintenanceNeeded + }); + }); }) ); @@ -180,19 +309,98 @@ servient thing.setPropertyWriteHandler( "availableResourceLevel", tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { + return await traceBusinessLogic("updateResourceLevel", async () => { + // Validate URI variables and extract resource ID + const resourceId = await traceValidation("uriVariables", options, async () => { + if (!Boolean(options) || typeof options !== "object" || !("uriVariables" in options)) { + throw new Error("URI variables are required"); + } + const uriVariables = options.uriVariables as Record; + if (!("id" in uriVariables)) { + throw new Error("Please specify id variable as uriVariables."); + } const id = uriVariables.id; + + // Validate resource ID + const validResources = ["water", "milk", "chocolate", "coffeeBeans"]; + if (!validResources.includes(id)) { + throw new Error(`Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}`); + } + return id; + }); + + // Validate and parse the new resource level + const newLevel = await createChildSpan("parsing.extractResourceLevel", async () => { if (!val) { throw new Error("No value provided for availableResourceLevel"); } - allAvailableResources[id] = (await (val as any).value()) as number; - return; - } - } - throw Error("Please specify id variable as uriVariables."); + const level = (await (val as any).value()) as number; + + // Validate resource level range + if (typeof level !== "number" || level < 0 || level > 100) { + throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); + } + return level; + }, { + "resource.id": resourceId, + "input.type": typeof val + }); + + // Check current level and calculate change + const levelChange = await createChildSpan("calculate.levelChange", async () => { + const currentLevel = allAvailableResources[resourceId]; + const change = newLevel - currentLevel; + return { + previous: currentLevel, + new: newLevel, + change: change, + changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change" + }; + }, { + "resource.id": resourceId, + "calculation.type": "level_change" + }); + + // Update resource level in database + await traceDatabaseOperation("update", "resource_levels", async () => { + allAvailableResources[resourceId] = newLevel; + }); + + // Check for low resource alerts + await createChildSpan("business.checkResourceThresholds", async () => { + if (newLevel <= 10) { + // Emit low resource event + await createChildSpan("event.lowResource", async () => { + const eventData = `Low level of ${resourceId}: ${newLevel}%`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); + }); + } + + if (newLevel === 0) { + // Update maintenance needed flag + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + } + }, { + "resource.id": resourceId, + "resource.level": newLevel, + "threshold.low": 10, + "threshold.empty": 0, + "maintenance.needed": maintenanceNeeded + }); + + // Log resource level change + await createChildSpan("logging.resourceUpdate", async () => { + console.log(`Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})`); + }, { + "resource.id": resourceId, + "level.previous": levelChange.previous, + "level.new": newLevel, + "change.type": levelChange.changeType, + "change.amount": levelChange.change + }); + }); }) ); @@ -217,110 +425,158 @@ servient thing.setActionHandler( "makeDrink", tracedActionHandler("makeDrink", async (_params, options) => { - return traceBusinessLogic("drinkPreparation", async () => { - // Default values - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; + // Parse input parameters first to use in metadata + let drinkId = "americano"; + let size = "m"; + let quantity = 1; - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { + const uriVariables = options.uriVariables as Record; + drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; + size = "size" in uriVariables ? (uriVariables.size as string) : size; + quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; + } - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } + return await traceBusinessLogic("makeDrink", async () => { + // Validate input parameters + await traceValidation("input", options, async () => { + if (!drinkId || !size || !quantity) { + throw new Error("Invalid input parameters"); + } + }); + + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation("select", "recipes", async () => { + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; + + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; + + return { drinkRecipes, sizeQuantifiers }; + }); + + // Validate drink availability + await traceValidation("drinkAvailability", drinkId, async () => { + if (!drinkRecipes[drinkId]) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (!sizeQuantifiers[size]) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); + + // Get current resources from sensors + const currentResources = await traceDatabaseOperation("select", "resources", async () => { + return { ...allAvailableResources }; + }); + + // Calculate resource consumption + const newResources = await createChildSpan("calculate.resourceConsumption", async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + + return newResources; + }, { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption" + }); - // Testing to see what happens when thing crashes - // if (drinkId === "americano") { - // throw new Error("Americano is not available"); - // } - - // Calculate the new level of resources - const newResources = Object.assign({}, allAvailableResources); - newResources.water -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].water); - newResources.milk -= Math.ceil(quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].milk); - newResources.chocolate -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].chocolate - ); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeQuantifiers[size] * drinkRecipes[drinkId].coffeeBeans - ); - - // Check if the amount of available resources is sufficient to make a drink - return traceValidation("resourceAvailability", newResources, async () => { + // Validate resource availability + await traceValidation("resourceAvailability", newResources, async () => { for (const resource in newResources) { if (newResources[resource] <= 0) { const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( - eventData - ); - return { - result: false, - message: `${resource} level is not sufficient`, - }; + await createChildSpan("event.outOfResource", async () => { + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); + }); + throw new Error(`${resource} level is not sufficient`); } } + }); - // Now store the new level of allAvailableResources - return traceDatabaseOperation("update", "resources", async () => { - allAvailableResources = newResources; - servedCounter = servedCounter + quantity; + // Update resources in database + await traceDatabaseOperation("update", "resources", async () => { + allAvailableResources = newResources; + }); - // Finally deliver the drink - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - }); + // Update served counter + await traceDatabaseOperation("update", "counters", async () => { + servedCounter = servedCounter + quantity; }); + + // Simulate drink preparation + await createChildSpan("hardware.prepareDrink", async () => { + // Simulate time for drink preparation + await new Promise(resolve => setTimeout(resolve, 100)); + }, { + "hardware.operation": "drink_preparation", + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity + }); + + // Return success response + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + }, { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity }); }) ); @@ -329,33 +585,90 @@ servient thing.setActionHandler( "setSchedule", tracedActionHandler("setSchedule", async (params, options) => { - return traceBusinessLogic("scheduleManagement", async () => { - const paramsp = params ? ((await (params as any).value()) as Record) : null; + // Parse input parameters first for metadata + const paramsp = params ? ((await (params as any).value()) as Record) : null; + + return await traceBusinessLogic("setSchedule", async () => { + // Always create initial validation span to show the process started + const validatedParams = await createChildSpan("initialization.parseInput", async () => { + // Validate input parameters + await traceValidation("input", params, async () => { + if (!paramsp) { + throw new Error("No parameters provided"); + } + }); + + // Validate required parameters + const scheduleData = await traceValidation("scheduleParameters", paramsp, async () => { + if (paramsp == null || typeof paramsp !== "object" || !("time" in paramsp) || !("mode" in paramsp)) { + throw new Error("Please provide all the required parameters: time and mode."); + } - // Check if required parameters are provided - return traceValidation("scheduleParameters", paramsp, async () => { - if (paramsp != null && typeof paramsp === "object" && "time" in paramsp && "mode" in paramsp) { // Use default values if not provided - paramsp.drinkId = "drinkId" in paramsp ? paramsp.drinkId : "americano"; - paramsp.size = "size" in paramsp ? paramsp.size : "m"; - paramsp.quantity = "quantity" in paramsp ? paramsp.quantity : 1; - - // Now add a new schedule - return traceDatabaseOperation("insert", "schedules", async () => { - schedules.push(paramsp); - - return { - result: true, - message: `Your schedule has been set!`, - }; - }); - } + const data = { + time: paramsp.time, + mode: paramsp.mode, + drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", + size: "size" in paramsp ? paramsp.size : "m", + quantity: "quantity" in paramsp ? paramsp.quantity : 1, + }; - return { - result: false, - message: `Please provide all the required parameters: time and mode.`, - }; + return data; + }); + + // Validate time format + await traceValidation("timeFormat", scheduleData.time, async () => { + const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; + if (!timeRegex.test(String(scheduleData.time))) { + throw new Error("Invalid time format. Please use HH:MM format."); + } + }); + + return scheduleData; + }, { + "input.present": !!paramsp, + "input.type": typeof paramsp, + "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", + "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" + }); + + // Continue with business logic (this will only execute if validation passes) + await createChildSpan("business.scheduleProcessing", async () => { + // Check schedule conflicts + await createChildSpan("check.scheduleConflicts", async () => { + const existingSchedule = schedules.find(s => + typeof s === "object" && s !== null && "time" in s && s.time === validatedParams.time + ); + if (existingSchedule) { + throw new Error(`Schedule already exists for time ${validatedParams.time}`); + } + }, { + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode) + }); + + // Save schedule to database + await traceDatabaseOperation("insert", "schedules", async () => { + schedules.push(validatedParams); + }); + + // Log schedule creation + await createChildSpan("logging.scheduleCreated", async () => { + console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); + }); + }, { + "business.operation": "schedule_processing", + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode) }); + + return { + result: true, + message: `Your schedule has been set!`, + }; + }, { + "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", + "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" }); }) ); From 740e6cdaa5b9767cef7f99583854d7bce987db23 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 11 Aug 2025 12:21:29 -0700 Subject: [PATCH 17/34] fix: ran npm run format --- .../http/ts/src/main.ts | 781 ++++++++++-------- 1 file changed, 448 insertions(+), 333 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 3a4bd58..952d865 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -144,16 +144,20 @@ servient }); // Read sensor data for real-time validation - const sensorData = await createChildSpan("sensors.readAll", async () => { - const readings: Record = {}; - for (const resource in allAvailableResources) { - readings[resource] = readFromSensor(resource); + const sensorData = await createChildSpan( + "sensors.readAll", + async () => { + const readings: Record = {}; + for (const resource in allAvailableResources) { + readings[resource] = readFromSensor(resource); + } + return readings; + }, + { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level", } - return readings; - }, { - "sensor.count": Object.keys(allAvailableResources).length, - "sensor.type": "resource_level" - }); + ); // Compare and sync with database return await traceDatabaseOperation("select", "resource_levels", async () => { @@ -179,22 +183,30 @@ servient }); // Load drink availability from database - const availabilityMap = await traceDatabaseOperation("select", "drink_availability", async () => { - // Simulate checking drink availability based on current resources - const availability: Record = {}; - for (const drink of possibleDrinks) { - availability[drink] = true; // For demo, all drinks are available + const availabilityMap = await traceDatabaseOperation( + "select", + "drink_availability", + async () => { + // Simulate checking drink availability based on current resources + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; // For demo, all drinks are available + } + return availability; } - return availability; - }); + ); // Filter available drinks based on current resources - return await createChildSpan("processing.filterAvailableDrinks", async () => { - return possibleDrinks.filter(drink => availabilityMap[drink] !== false); - }, { - "drinks.total": possibleDrinks.length, - "filtering.criteria": "resource_availability" - }); + return await createChildSpan( + "processing.filterAvailableDrinks", + async () => { + return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); + }, + { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability", + } + ); }); }) ); @@ -219,16 +231,20 @@ servient }); // Process and filter active schedules - return await createChildSpan("processing.filterActiveSchedules", async () => { - const currentTime = new Date(); - return result.filter((schedule: any) => { - // For demo purposes, all schedules are considered active - return true; - }); - }, { - "schedules.count": schedules.length, - "query.time": new Date().toISOString() - }); + return await createChildSpan( + "processing.filterActiveSchedules", + async () => { + const currentTime = new Date(); + return result.filter((schedule: any) => { + // For demo purposes, all schedules are considered active + return true; + }); + }, + { + "schedules.count": schedules.length, + "query.time": new Date().toISOString(), + } + ); }); }) ); @@ -247,16 +263,20 @@ servient }); // Parse and validate the new counter value - const newCounterValue = await createChildSpan("parsing.extractCounterValue", async () => { - const value = (await (val as any).value()) as number; - if (typeof value !== "number" || value < 0) { - throw new Error(`Invalid served counter value: ${value}`); + const newCounterValue = await createChildSpan( + "parsing.extractCounterValue", + async () => { + const value = (await (val as any).value()) as number; + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); + } + return value; + }, + { + "input.type": typeof val, + "parsing.operation": "counter_extraction", } - return value; - }, { - "input.type": typeof val, - "parsing.operation": "counter_extraction" - }); + ); // Update counter in database await traceDatabaseOperation("update", "counters", async () => { @@ -264,39 +284,47 @@ servient }); // Check maintenance threshold and trigger events if needed - await createChildSpan("business.checkMaintenanceThreshold", async () => { - if (servedCounter > 1000) { - // Update maintenance status - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); + await createChildSpan( + "business.checkMaintenanceThreshold", + async () => { + if (servedCounter > 1000) { + // Update maintenance status + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); - // Emit maintenance event - await createChildSpan("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); + // Emit maintenance event + await createChildSpan("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); - // Send notification to administrators - await createChildSpan("notification.sendAlert", async () => { - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + // Send notification to administrators + await createChildSpan( + "notification.sendAlert", + async () => { + notify( + "admin@coffeeMachine.com", + `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` + ); + }, + { + "notification.type": "maintenance_alert", + "notification.recipient": "admin@coffeeMachine.com", + "counter.value": servedCounter, + "maintenance.threshold": 1000, + } ); - }, { - "notification.type": "maintenance_alert", - "notification.recipient": "admin@coffeeMachine.com", - "counter.value": servedCounter, - "maintenance.threshold": 1000 - }); + } + }, + { + "counter.current": servedCounter, + "counter.previous": servedCounter - newCounterValue, + "maintenance.threshold": 1000, + "maintenance.needed": maintenanceNeeded, } - }, { - "counter.current": servedCounter, - "counter.previous": servedCounter - newCounterValue, - "maintenance.threshold": 1000, - "maintenance.needed": maintenanceNeeded - }); + ); }); }) ); @@ -320,46 +348,56 @@ servient throw new Error("Please specify id variable as uriVariables."); } const id = uriVariables.id; - + // Validate resource ID const validResources = ["water", "milk", "chocolate", "coffeeBeans"]; if (!validResources.includes(id)) { - throw new Error(`Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}`); + throw new Error( + `Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}` + ); } return id; }); // Validate and parse the new resource level - const newLevel = await createChildSpan("parsing.extractResourceLevel", async () => { - if (!val) { - throw new Error("No value provided for availableResourceLevel"); - } - const level = (await (val as any).value()) as number; - - // Validate resource level range - if (typeof level !== "number" || level < 0 || level > 100) { - throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); + const newLevel = await createChildSpan( + "parsing.extractResourceLevel", + async () => { + if (!val) { + throw new Error("No value provided for availableResourceLevel"); + } + const level = (await (val as any).value()) as number; + + // Validate resource level range + if (typeof level !== "number" || level < 0 || level > 100) { + throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); + } + return level; + }, + { + "resource.id": resourceId, + "input.type": typeof val, } - return level; - }, { - "resource.id": resourceId, - "input.type": typeof val - }); + ); // Check current level and calculate change - const levelChange = await createChildSpan("calculate.levelChange", async () => { - const currentLevel = allAvailableResources[resourceId]; - const change = newLevel - currentLevel; - return { - previous: currentLevel, - new: newLevel, - change: change, - changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change" - }; - }, { - "resource.id": resourceId, - "calculation.type": "level_change" - }); + const levelChange = await createChildSpan( + "calculate.levelChange", + async () => { + const currentLevel = allAvailableResources[resourceId]; + const change = newLevel - currentLevel; + return { + previous: currentLevel, + new: newLevel, + change: change, + changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change", + }; + }, + { + "resource.id": resourceId, + "calculation.type": "level_change", + } + ); // Update resource level in database await traceDatabaseOperation("update", "resource_levels", async () => { @@ -367,39 +405,51 @@ servient }); // Check for low resource alerts - await createChildSpan("business.checkResourceThresholds", async () => { - if (newLevel <= 10) { - // Emit low resource event - await createChildSpan("event.lowResource", async () => { - const eventData = `Low level of ${resourceId}: ${newLevel}%`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); - }); - } - - if (newLevel === 0) { - // Update maintenance needed flag - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); + await createChildSpan( + "business.checkResourceThresholds", + async () => { + if (newLevel <= 10) { + // Emit low resource event + await createChildSpan("event.lowResource", async () => { + const eventData = `Low level of ${resourceId}: ${newLevel}%`; + tracedEventHandler("outOfResource", (data) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + } + + if (newLevel === 0) { + // Update maintenance needed flag + await traceDatabaseOperation("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + } + }, + { + "resource.id": resourceId, + "resource.level": newLevel, + "threshold.low": 10, + "threshold.empty": 0, + "maintenance.needed": maintenanceNeeded, } - }, { - "resource.id": resourceId, - "resource.level": newLevel, - "threshold.low": 10, - "threshold.empty": 0, - "maintenance.needed": maintenanceNeeded - }); + ); // Log resource level change - await createChildSpan("logging.resourceUpdate", async () => { - console.log(`Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})`); - }, { - "resource.id": resourceId, - "level.previous": levelChange.previous, - "level.new": newLevel, - "change.type": levelChange.changeType, - "change.amount": levelChange.change - }); + await createChildSpan( + "logging.resourceUpdate", + async () => { + console.log( + `Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})` + ); + }, + { + "resource.id": resourceId, + "level.previous": levelChange.previous, + "level.new": newLevel, + "change.type": levelChange.changeType, + "change.amount": levelChange.change, + } + ); }); }) ); @@ -437,147 +487,167 @@ servient quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; } - return await traceBusinessLogic("makeDrink", async () => { - // Validate input parameters - await traceValidation("input", options, async () => { - if (!drinkId || !size || !quantity) { - throw new Error("Invalid input parameters"); - } - }); - - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation("select", "recipes", async () => { - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; + return await traceBusinessLogic( + "makeDrink", + async () => { + // Validate input parameters + await traceValidation("input", options, async () => { + if (!drinkId || !size || !quantity) { + throw new Error("Invalid input parameters"); + } + }); - return { drinkRecipes, sizeQuantifiers }; - }); + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation( + "select", + "recipes", + async () => { + // Size quantifiers + const sizeQuantifiers: Record = { + s: 0.1, + m: 0.2, + l: 0.3, + }; + + // Drink recipes showing the amount of a resource consumed for a particular drink + const drinkRecipes: Record> = { + espresso: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + americano: { + water: 2, + milk: 0, + chocolate: 0, + coffeeBeans: 2, + }, + cappuccino: { + water: 1, + milk: 1, + chocolate: 0, + coffeeBeans: 2, + }, + latte: { + water: 1, + milk: 2, + chocolate: 0, + coffeeBeans: 2, + }, + hotChocolate: { + water: 0, + milk: 0, + chocolate: 1, + coffeeBeans: 0, + }, + hotWater: { + water: 1, + milk: 0, + chocolate: 0, + coffeeBeans: 0, + }, + }; + + return { drinkRecipes, sizeQuantifiers }; + } + ); - // Validate drink availability - await traceValidation("drinkAvailability", drinkId, async () => { - if (!drinkRecipes[drinkId]) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (!sizeQuantifiers[size]) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); + // Validate drink availability + await traceValidation("drinkAvailability", drinkId, async () => { + if (!drinkRecipes[drinkId]) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (!sizeQuantifiers[size]) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); - // Get current resources from sensors - const currentResources = await traceDatabaseOperation("select", "resources", async () => { - return { ...allAvailableResources }; - }); + // Get current resources from sensors + const currentResources = await traceDatabaseOperation("select", "resources", async () => { + return { ...allAvailableResources }; + }); - // Calculate resource consumption - const newResources = await createChildSpan("calculate.resourceConsumption", async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; - - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); - - return newResources; - }, { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption" - }); + // Calculate resource consumption + const newResources = await createChildSpan( + "calculate.resourceConsumption", + async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil( + quantity * sizeMultiplier * recipe.coffeeBeans + ); - // Validate resource availability - await traceValidation("resourceAvailability", newResources, async () => { - for (const resource in newResources) { - if (newResources[resource] <= 0) { - const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - await createChildSpan("event.outOfResource", async () => { - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))(eventData); - }); - throw new Error(`${resource} level is not sufficient`); + return newResources; + }, + { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption", } - } - }); + ); + + // Validate resource availability + await traceValidation("resourceAvailability", newResources, async () => { + for (const resource in newResources) { + if (newResources[resource] <= 0) { + const eventData = `Low level of ${resource}: ${newResources[resource]}%`; + await createChildSpan("event.outOfResource", async () => { + tracedEventHandler("outOfResource", (data) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + throw new Error(`${resource} level is not sufficient`); + } + } + }); - // Update resources in database - await traceDatabaseOperation("update", "resources", async () => { - allAvailableResources = newResources; - }); + // Update resources in database + await traceDatabaseOperation("update", "resources", async () => { + allAvailableResources = newResources; + }); - // Update served counter - await traceDatabaseOperation("update", "counters", async () => { - servedCounter = servedCounter + quantity; - }); + // Update served counter + await traceDatabaseOperation("update", "counters", async () => { + servedCounter = servedCounter + quantity; + }); + + // Simulate drink preparation + await createChildSpan( + "hardware.prepareDrink", + async () => { + // Simulate time for drink preparation + await new Promise((resolve) => setTimeout(resolve, 100)); + }, + { + "hardware.operation": "drink_preparation", + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + } + ); - // Simulate drink preparation - await createChildSpan("hardware.prepareDrink", async () => { - // Simulate time for drink preparation - await new Promise(resolve => setTimeout(resolve, 100)); - }, { - "hardware.operation": "drink_preparation", + // Return success response + return { + result: true, + message: `Your ${drinkId} is in progress!`, + }; + }, + { "drink.id": drinkId, "drink.size": size, - "drink.quantity": quantity - }); - - // Return success response - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - }, { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity - }); + "drink.quantity": quantity, + } + ); }) ); @@ -587,89 +657,134 @@ servient tracedActionHandler("setSchedule", async (params, options) => { // Parse input parameters first for metadata const paramsp = params ? ((await (params as any).value()) as Record) : null; - - return await traceBusinessLogic("setSchedule", async () => { - // Always create initial validation span to show the process started - const validatedParams = await createChildSpan("initialization.parseInput", async () => { - // Validate input parameters - await traceValidation("input", params, async () => { - if (!paramsp) { - throw new Error("No parameters provided"); - } - }); - // Validate required parameters - const scheduleData = await traceValidation("scheduleParameters", paramsp, async () => { - if (paramsp == null || typeof paramsp !== "object" || !("time" in paramsp) || !("mode" in paramsp)) { - throw new Error("Please provide all the required parameters: time and mode."); - } + return await traceBusinessLogic( + "setSchedule", + async () => { + // Always create initial validation span to show the process started + const validatedParams = await createChildSpan( + "initialization.parseInput", + async () => { + // Validate input parameters + await traceValidation("input", params, async () => { + if (!paramsp) { + throw new Error("No parameters provided"); + } + }); - // Use default values if not provided - const data = { - time: paramsp.time, - mode: paramsp.mode, - drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", - size: "size" in paramsp ? paramsp.size : "m", - quantity: "quantity" in paramsp ? paramsp.quantity : 1, - }; + // Validate required parameters + const scheduleData = await traceValidation( + "scheduleParameters", + paramsp, + async () => { + if ( + paramsp == null || + typeof paramsp !== "object" || + !("time" in paramsp) || + !("mode" in paramsp) + ) { + throw new Error( + "Please provide all the required parameters: time and mode." + ); + } + + // Use default values if not provided + const data = { + time: paramsp.time, + mode: paramsp.mode, + drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", + size: "size" in paramsp ? paramsp.size : "m", + quantity: "quantity" in paramsp ? paramsp.quantity : 1, + }; + + return data; + } + ); - return data; - }); + // Validate time format + await traceValidation("timeFormat", scheduleData.time, async () => { + const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; + if (!timeRegex.test(String(scheduleData.time))) { + throw new Error("Invalid time format. Please use HH:MM format."); + } + }); - // Validate time format - await traceValidation("timeFormat", scheduleData.time, async () => { - const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; - if (!timeRegex.test(String(scheduleData.time))) { - throw new Error("Invalid time format. Please use HH:MM format."); + return scheduleData; + }, + { + "input.present": !!paramsp, + "input.type": typeof paramsp, + "schedule.time": + paramsp && typeof paramsp === "object" && "time" in paramsp + ? String(paramsp.time) + : "unknown", + "schedule.mode": + paramsp && typeof paramsp === "object" && "mode" in paramsp + ? String(paramsp.mode) + : "unknown", } - }); + ); + + // Continue with business logic (this will only execute if validation passes) + await createChildSpan( + "business.scheduleProcessing", + async () => { + // Check schedule conflicts + await createChildSpan( + "check.scheduleConflicts", + async () => { + const existingSchedule = schedules.find( + (s) => + typeof s === "object" && + s !== null && + "time" in s && + s.time === validatedParams.time + ); + if (existingSchedule) { + throw new Error( + `Schedule already exists for time ${validatedParams.time}` + ); + } + }, + { + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode), + } + ); - return scheduleData; - }, { - "input.present": !!paramsp, - "input.type": typeof paramsp, - "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", - "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" - }); + // Save schedule to database + await traceDatabaseOperation("insert", "schedules", async () => { + schedules.push(validatedParams); + }); - // Continue with business logic (this will only execute if validation passes) - await createChildSpan("business.scheduleProcessing", async () => { - // Check schedule conflicts - await createChildSpan("check.scheduleConflicts", async () => { - const existingSchedule = schedules.find(s => - typeof s === "object" && s !== null && "time" in s && s.time === validatedParams.time - ); - if (existingSchedule) { - throw new Error(`Schedule already exists for time ${validatedParams.time}`); + // Log schedule creation + await createChildSpan("logging.scheduleCreated", async () => { + console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); + }); + }, + { + "business.operation": "schedule_processing", + "schedule.time": String(validatedParams.time), + "schedule.mode": String(validatedParams.mode), } - }, { - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode) - }); - - // Save schedule to database - await traceDatabaseOperation("insert", "schedules", async () => { - schedules.push(validatedParams); - }); + ); - // Log schedule creation - await createChildSpan("logging.scheduleCreated", async () => { - console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); - }); - }, { - "business.operation": "schedule_processing", - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode) - }); - - return { - result: true, - message: `Your schedule has been set!`, - }; - }, { - "schedule.time": paramsp && typeof paramsp === "object" && "time" in paramsp ? String(paramsp.time) : "unknown", - "schedule.mode": paramsp && typeof paramsp === "object" && "mode" in paramsp ? String(paramsp.mode) : "unknown" - }); + return { + result: true, + message: `Your schedule has been set!`, + }; + }, + { + "schedule.time": + paramsp && typeof paramsp === "object" && "time" in paramsp + ? String(paramsp.time) + : "unknown", + "schedule.mode": + paramsp && typeof paramsp === "object" && "mode" in paramsp + ? String(paramsp.mode) + : "unknown", + } + ); }) ); From d404f88f69eef93caf091bcabe60f70f4044c17d Mon Sep 17 00:00:00 2001 From: Ege Korkan Date: Tue, 12 Aug 2025 17:45:45 +0200 Subject: [PATCH 18/34] update lock file --- package-lock.json | 191 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) diff --git a/package-lock.json b/package-lock.json index 36660cc..d7efb7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2106,6 +2106,31 @@ "node": ">= 0.10.x" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "semver": "^7.0.0" + } + }, "node_modules/bulk-write-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", @@ -3132,6 +3157,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, "node_modules/eslint-config-prettier": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", @@ -3245,6 +3287,29 @@ "eslint": ">=4.19.1" } }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, "node_modules/eslint-plugin-import": { "version": "2.32.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", @@ -3336,6 +3401,73 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -3416,6 +3548,23 @@ "eslint": ">=3.0.0" } }, + "node_modules/eslint-plugin-promise": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, "node_modules/eslint-plugin-unused-imports": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", @@ -4243,6 +4392,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -4751,6 +4914,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -7059,6 +7239,17 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/ret": { "version": "0.2.2", "license": "MIT", From f87982512ef99b9e5cac114a3967cd2326fae944 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 00:12:37 -0400 Subject: [PATCH 19/34] Decreased redundancy to help developers code things faster --- .../http/ts/src/auto-tracing.ts | 327 +++++++ .../http/ts/src/main.ts | 829 +++++++----------- .../http/ts/src/tracing.ts | 5 - 3 files changed, 649 insertions(+), 512 deletions(-) create mode 100644 things/advanced-coffee-machine/http/ts/src/auto-tracing.ts diff --git a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts new file mode 100644 index 0000000..6409082 --- /dev/null +++ b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts @@ -0,0 +1,327 @@ +/******************************************************************************** + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and + * Document License (2015-05-13) which is available at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. + * + * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 + ********************************************************************************/ + +import WoT from "wot-typescript-definitions"; +import { + tracedPropertyReadHandler, + tracedPropertyWriteHandler, + tracedActionHandler, + traceBusinessLogic, + traceValidation, + traceDatabaseOperation, + createChildSpan, +} from "./tracing"; + + +interface ValidationConfig { + type: string; + validator: (data: any) => Promise | void; +} + +interface DatabaseConfig { + operation: string; + table: string; +} + +interface ProcessingConfig { + name: string; + attributes?: Record; +} + +interface BusinessLogicConfig { + name: string; + validations?: ValidationConfig[]; + database?: DatabaseConfig[]; + processing?: ProcessingConfig[]; + metadata?: Record; +} + +// Auto-traced property handler +export function autoTracedPropertyRead( + propertyName: string, + config: BusinessLogicConfig, + businessLogic: (options?: any) => Promise | T +): (options?: WoT.InteractionOptions) => Promise { + return tracedPropertyReadHandler(propertyName, async (options) => { + return await traceBusinessLogic(config.name, async () => { + // Execute validations + if (config.validations) { + for (const validation of config.validations) { + await traceValidation(validation.type, null, async () => { + await validation.validator(null); + }); + } + } + + // Execute database operations + if (config.database) { + for (const db of config.database) { + await traceDatabaseOperation(db.operation, db.table, async () => {}); + } + } + + // Execute processing steps + if (config.processing) { + for (const proc of config.processing) { + await createChildSpan(proc.name, async () => {}, proc.attributes); + } + } + + // Execute main business logic + return await businessLogic(options); + }); + }); +} + +// Auto-traced property write handler +export function autoTracedPropertyWrite( + propertyName: string, + config: BusinessLogicConfig, + businessLogic: (value: any, options?: any) => Promise | void +): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { + return tracedPropertyWriteHandler(propertyName, async (value, options) => { + return await traceBusinessLogic(config.name, async () => { + // Execute validations with the input value + if (config.validations) { + for (const validation of config.validations) { + await traceValidation(validation.type, value, async () => { + await validation.validator(value); + }); + } + } + + // Execute processing steps + if (config.processing) { + for (const proc of config.processing) { + await createChildSpan(proc.name, async () => {}, proc.attributes); + } + } + + // Execute database operations + if (config.database) { + for (const db of config.database) { + await traceDatabaseOperation(db.operation, db.table, async () => {}); + } + } + + // Execute main business logic + await businessLogic(value, options); + }); + }); +} + +// Auto-traced action handler +export function autoTracedAction( + actionName: string, + config: BusinessLogicConfig, + businessLogic: (params?: any, options?: any) => Promise | T +): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { + return tracedActionHandler(actionName, async (params, options) => { + return await traceBusinessLogic(config.name, async () => { + // Execute validations + if (config.validations) { + for (const validation of config.validations) { + await traceValidation(validation.type, params, async () => { + await validation.validator(params); + }); + } + } + + // Execute processing steps + if (config.processing) { + for (const proc of config.processing) { + await createChildSpan(proc.name, async () => {}, proc.attributes); + } + } + + // Execute database operations + if (config.database) { + for (const db of config.database) { + await traceDatabaseOperation(db.operation, db.table, async () => {}); + } + } + + // Execute main business logic + return await businessLogic(params, options); + }); + }); +} + +// Smart wrapper that automatically creates spans based on function calls +export class TracedBusinessLogic { + constructor(private baseSpanName: string) {} + + async withValidation( + validationType: string, + data: any, + operation: () => Promise | T + ): Promise { + return await traceValidation(validationType, data, operation); + } + + async withDatabase( + operation: string, + table: string, + dbOperation: () => Promise | T + ): Promise { + return await traceDatabaseOperation(operation, table, dbOperation); + } + + async withProcessing( + operationName: string, + operation: () => Promise | T, + attributes?: Record + ): Promise { + return await createChildSpan(operationName, operation, attributes); + } + + async execute(operation: () => Promise | T): Promise { + return await traceBusinessLogic(this.baseSpanName, operation); + } +} + + +export function createTracedLogic(spanName: string): TracedBusinessLogic { + return new TracedBusinessLogic(spanName); +} + +export class TracingConfigBuilder { + private config: BusinessLogicConfig; + + constructor(businessLogicName: string) { + this.config = { name: businessLogicName }; + } + + addValidation(type: string, validator: (data: any) => Promise | void): TracingConfigBuilder { + if (!this.config.validations) this.config.validations = []; + this.config.validations.push({ type, validator }); + return this; + } + + addDatabase(operation: string, table: string): TracingConfigBuilder { + if (!this.config.database) this.config.database = []; + this.config.database.push({ operation, table }); + return this; + } + + addProcessing(name: string, attributes?: Record): TracingConfigBuilder { + if (!this.config.processing) this.config.processing = []; + this.config.processing.push({ name, attributes }); + return this; + } + + addMetadata(metadata: Record): TracingConfigBuilder { + this.config.metadata = { ...this.config.metadata, ...metadata }; + return this; + } + + build(): BusinessLogicConfig { + return this.config; + } +} + +export function tracingConfig(businessLogicName: string): TracingConfigBuilder { + return new TracingConfigBuilder(businessLogicName); +} + +export class AutoTracedThing { + constructor(private thing: WoT.ExposedThing) {} + + setPropertyReadHandler( + propertyName: string, + businessLogicName: string, + businessLogic: (options?: any) => Promise | T, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void { + let config = tracingConfig(businessLogicName); + if (configBuilder) { + config = configBuilder(config); + } + + this.thing.setPropertyReadHandler( + propertyName, + autoTracedPropertyRead(propertyName, config.build(), businessLogic) as any + ); + } + + setPropertyWriteHandler( + propertyName: string, + businessLogicName: string, + businessLogic: (value: any, options?: any) => Promise | void, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void { + let config = tracingConfig(businessLogicName); + if (configBuilder) { + config = configBuilder(config); + } + + this.thing.setPropertyWriteHandler( + propertyName, + autoTracedPropertyWrite(propertyName, config.build(), businessLogic) + ); + } + + setActionHandler( + actionName: string, + businessLogicName: string, + businessLogic: (params?: any, options?: any) => Promise | T, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void { + let config = tracingConfig(businessLogicName); + if (configBuilder) { + config = configBuilder(config); + } + + this.thing.setActionHandler( + actionName, + autoTracedAction(actionName, config.build(), businessLogic) as any + ); + } + + // Delegate other methods to the wrapped thing + writeProperty(propertyName: string, value: any): Promise { + return (this.thing as any).writeProperty(propertyName, value); + } + + readProperty(propertyName: string, options?: WoT.InteractionOptions): Promise { + return (this.thing as any).readProperty(propertyName, options); + } + + emitEvent(eventName: string, data?: any): void { + this.thing.emitEvent(eventName, data); + } + + emitPropertyChange(propertyName: string): void { + this.thing.emitPropertyChange(propertyName); + } + + expose(): Promise { + return this.thing.expose(); + } + + destroy(): Promise { + return this.thing.destroy(); + } + + // Get the underlying thing for direct access if needed + getUnderlyingThing(): WoT.ExposedThing { + return this.thing; + } +} + +// Factory function for creating auto-traced things +export function createAutoTracedThing(thing: WoT.ExposedThing): AutoTracedThing { + return new AutoTracedThing(thing); +} diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 952d865..7055530 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,17 +25,9 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import { - initTracing, - tracedActionHandler, - tracedPropertyReadHandler, - tracedPropertyWriteHandler, - tracedEventHandler, - traceBusinessLogic, - traceValidation, - traceDatabaseOperation, - createChildSpan, -} from "./tracing"; +import { initTracing, tracedEventHandler } from "./tracing"; +import { createAutoTracedThing, createTracedLogic } from "./auto-tracing"; + dotenv.config(); // Initialize tracing @@ -126,12 +118,19 @@ servient maintenanceNeeded = false; schedules = []; - thing.setPropertyReadHandler( + // Create auto-traced thing wrapper + const tracedThing = createAutoTracedThing(thing); + + // Property: allAvailableResources + tracedThing.setPropertyReadHandler( "allAvailableResources", - tracedPropertyReadHandler("allAvailableResources", async () => { - return await traceBusinessLogic("getAllResources", async () => { + "getAllResources", + async (options) => { + const logic = createTracedLogic("getAllResources"); + + return await logic.execute(async () => { // Validate resource data integrity - await traceValidation("resourceData", allAvailableResources, async () => { + await logic.withValidation("resourceData", allAvailableResources, async () => { const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; for (const resource of requiredResources) { if (!(resource in allAvailableResources)) { @@ -144,7 +143,7 @@ servient }); // Read sensor data for real-time validation - const sensorData = await createChildSpan( + const sensorData = await logic.withProcessing( "sensors.readAll", async () => { const readings: Record = {}; @@ -160,20 +159,23 @@ servient ); // Compare and sync with database - return await traceDatabaseOperation("select", "resource_levels", async () => { - // In a real system, you might sync with actual sensor readings - // For demo, we'll just return the current state + return await logic.withDatabase("select", "resource_levels", async () => { return { ...allAvailableResources }; }); }); - }) + } ); - thing.setPropertyReadHandler( + + // Property: possibleDrinks + tracedThing.setPropertyReadHandler( "possibleDrinks", - tracedPropertyReadHandler("possibleDrinks", async () => { - return await traceBusinessLogic("getPossibleDrinks", async () => { + "getPossibleDrinks", + async (options) => { + const logic = createTracedLogic("getPossibleDrinks"); + + return await logic.execute(async () => { // Validate drink catalog integrity - await traceValidation("drinkCatalog", possibleDrinks, async () => { + await logic.withValidation("drinkCatalog", possibleDrinks, async () => { if (!Array.isArray(possibleDrinks)) { throw new Error("Drink catalog is corrupted"); } @@ -183,21 +185,20 @@ servient }); // Load drink availability from database - const availabilityMap = await traceDatabaseOperation( + const availabilityMap = await logic.withDatabase( "select", "drink_availability", async () => { - // Simulate checking drink availability based on current resources const availability: Record = {}; for (const drink of possibleDrinks) { - availability[drink] = true; // For demo, all drinks are available + availability[drink] = true; } return availability; } ); // Filter available drinks based on current resources - return await createChildSpan( + return await logic.withProcessing( "processing.filterAvailableDrinks", async () => { return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); @@ -208,37 +209,73 @@ servient } ); }); - }) + } ); - thing.setPropertyReadHandler( + + // Property: maintenanceNeeded (simple read) + tracedThing.setPropertyReadHandler( "maintenanceNeeded", - tracedPropertyReadHandler("maintenanceNeeded", async () => maintenanceNeeded) + "getMaintenanceStatus", + async (options) => maintenanceNeeded ); - thing.setPropertyReadHandler( + + // Property Read: availableResourceLevel (with URI variables) + tracedThing.setPropertyReadHandler( + "availableResourceLevel", + "getResourceLevel", + async (options) => { + const logic = createTracedLogic("getResourceLevel"); + + return await logic.execute(async () => { + // Parse resource ID from URI variables + const resourceId = await logic.withProcessing( + "parsing.extractResourceId", + async () => { + const resourceId = options?.uriVariables?.id as string; + if (!resourceId || !(resourceId in allAvailableResources)) { + throw new Error(`Invalid resource ID: ${resourceId}`); + } + return resourceId; + }, + { + "resource.id": options?.uriVariables?.id || "unknown", + "parsing.operation": "resource_id_extraction", + } + ); + + // Get resource level from database + return await logic.withDatabase("select", "resource_levels", async () => { + return allAvailableResources[resourceId]; + }); + }); + } + ); + + // Property: schedules + tracedThing.setPropertyReadHandler( "schedules", - tracedPropertyReadHandler("schedules", async () => { - return await traceBusinessLogic("getSchedules", async () => { + "getSchedules", + async (options) => { + const logic = createTracedLogic("getSchedules"); + + return await logic.execute(async () => { // Validate system state - await traceValidation("systemState", { schedulesLength: schedules.length }, async () => { + await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { if (!Array.isArray(schedules)) { throw new Error("Schedules data structure is corrupted"); } }); // Load schedules from database - const result = await traceDatabaseOperation("select", "schedules", async () => { + const result = await logic.withDatabase("select", "schedules", async () => { return schedules; }); // Process and filter active schedules - return await createChildSpan( + return await logic.withProcessing( "processing.filterActiveSchedules", async () => { - const currentTime = new Date(); - return result.filter((schedule: any) => { - // For demo purposes, all schedules are considered active - return true; - }); + return result.filter((schedule: any) => true); // For demo, all schedules are active }, { "schedules.count": schedules.length, @@ -246,24 +283,26 @@ servient } ); }); - }) + } ); - // Override a write handler for servedCounter property, - // raising maintenanceNeeded flag when the value exceeds 1000 drinks - thing.setPropertyWriteHandler( + // Property Write: servedCounter + tracedThing.setPropertyWriteHandler( "servedCounter", - tracedPropertyWriteHandler("servedCounter", async (val) => { - return await traceBusinessLogic("updateServedCounter", async () => { + "updateServedCounter", + async (val) => { + const logic = createTracedLogic("updateServedCounter"); + + await logic.execute(async () => { // Validate input - await traceValidation("counterInput", val, async () => { + await logic.withValidation("counterInput", val, async () => { if (!val) { throw new Error("No value provided for servedCounter"); } }); // Parse and validate the new counter value - const newCounterValue = await createChildSpan( + const newCounterValue = await logic.withProcessing( "parsing.extractCounterValue", async () => { const value = (await (val as any).value()) as number; @@ -279,109 +318,62 @@ servient ); // Update counter in database - await traceDatabaseOperation("update", "counters", async () => { + await logic.withDatabase("update", "counters", async () => { servedCounter = newCounterValue; }); // Check maintenance threshold and trigger events if needed - await createChildSpan( - "business.checkMaintenanceThreshold", - async () => { - if (servedCounter > 1000) { - // Update maintenance status - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); - - // Emit maintenance event - await createChildSpan("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); - - // Send notification to administrators - await createChildSpan( - "notification.sendAlert", - async () => { - notify( - "admin@coffeeMachine.com", - `maintenanceNeeded property has changed, new value is: ${maintenanceNeeded}` - ); - }, - { - "notification.type": "maintenance_alert", - "notification.recipient": "admin@coffeeMachine.com", - "counter.value": servedCounter, - "maintenance.threshold": 1000, - } - ); - } - }, - { - "counter.current": servedCounter, - "counter.previous": servedCounter - newCounterValue, - "maintenance.threshold": 1000, - "maintenance.needed": maintenanceNeeded, - } - ); - }); - }) - ); - - // Now initialize the servedCounter property - servedCounter = readFromSensor("servedCounter"); + await logic.withProcessing("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await logic.withDatabase("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); - // Override a write handler for availableResourceLevel property, - // utilizing the uriVariables properly - thing.setPropertyWriteHandler( - "availableResourceLevel", - tracedPropertyWriteHandler("availableResourceLevel", async (val, options) => { - return await traceBusinessLogic("updateResourceLevel", async () => { - // Validate URI variables and extract resource ID - const resourceId = await traceValidation("uriVariables", options, async () => { - if (!Boolean(options) || typeof options !== "object" || !("uriVariables" in options)) { - throw new Error("URI variables are required"); - } - const uriVariables = options.uriVariables as Record; - if (!("id" in uriVariables)) { - throw new Error("Please specify id variable as uriVariables."); - } - const id = uriVariables.id; - - // Validate resource ID - const validResources = ["water", "milk", "chocolate", "coffeeBeans"]; - if (!validResources.includes(id)) { - throw new Error( - `Invalid resource ID: ${id}. Valid options: ${validResources.join(", ")}` - ); + // Emit maintenance event + await logic.withProcessing("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); } - return id; }); + }); + } + ); - // Validate and parse the new resource level - const newLevel = await createChildSpan( - "parsing.extractResourceLevel", + // Property Write: availableResourceLevel + tracedThing.setPropertyWriteHandler( + "availableResourceLevel", + "updateResourceLevel", + async (val, options) => { + const logic = createTracedLogic("updateResourceLevel"); + + await logic.execute(async () => { + // Parse and validate resource data + const { resourceId, newLevel } = await logic.withProcessing( + "parsing.extractResourceData", async () => { - if (!val) { - throw new Error("No value provided for availableResourceLevel"); + const resourceId = options?.uriVariables?.id as string; + const newLevel = (await (val as any).value()) as number; + + if (!resourceId || !(resourceId in allAvailableResources)) { + throw new Error(`Invalid resource ID: ${resourceId}`); } - const level = (await (val as any).value()) as number; - - // Validate resource level range - if (typeof level !== "number" || level < 0 || level > 100) { - throw new Error(`Invalid resource level: ${level}. Must be between 0 and 100.`); + if (typeof newLevel !== "number" || newLevel < 0 || newLevel > 100) { + throw new Error(`Invalid level for ${resourceId}: ${newLevel}`); } - return level; + + return { resourceId, newLevel }; }, { - "resource.id": resourceId, - "input.type": typeof val, + "resource.id": "dynamic", + "parsing.operation": "resource_extraction", } ); - // Check current level and calculate change - const levelChange = await createChildSpan( + // Calculate level change + const change = await logic.withProcessing( "calculate.levelChange", async () => { const currentLevel = allAvailableResources[resourceId]; @@ -400,402 +392,225 @@ servient ); // Update resource level in database - await traceDatabaseOperation("update", "resource_levels", async () => { + await logic.withDatabase("update", "resource_levels", async () => { allAvailableResources[resourceId] = newLevel; }); // Check for low resource alerts - await createChildSpan( - "business.checkResourceThresholds", + await logic.withProcessing("business.checkResourceThresholds", async () => { + if (newLevel <= 10) { + // Emit low resource event + await logic.withProcessing("event.lowResource", async () => { + const eventData = `Low level of ${resourceId}: ${newLevel}%`; + tracedEventHandler("outOfResource", (data) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + } + }); + }); + } + ); + + // Action: makeDrink + tracedThing.setActionHandler( + "makeDrink", + "makeDrink", + async (params, options) => { + const logic = createTracedLogic("makeDrink"); + + return await logic.execute(async () => { + // Parse parameters with defaults + const { drinkId, size, quantity } = await logic.withProcessing( + "parsing.extractDrinkParameters", async () => { - if (newLevel <= 10) { - // Emit low resource event - await createChildSpan("event.lowResource", async () => { - const eventData = `Low level of ${resourceId}: ${newLevel}%`; - tracedEventHandler("outOfResource", (data) => - thing.emitEvent("outOfResource", data) - )(eventData); - }); - } + const drinkId = options?.uriVariables?.drinkId ?? "americano"; + const size = options?.uriVariables?.size ?? "m"; + const quantity = options?.uriVariables?.quantity ?? 1; + return { drinkId, size, quantity }; + }, + { + "parsing.operation": "drink_parameters", + "defaults.applied": true, + } + ); - if (newLevel === 0) { - // Update maintenance needed flag - await traceDatabaseOperation("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); - } + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( + "select", + "recipes", + async () => { + // Define recipes and quantifiers (would come from database in real system) + const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; + const drinkRecipes: Record> = { + espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, + americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, + cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, + latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, + hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, + hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, + }; + return { drinkRecipes, sizeQuantifiers }; + } + ); + + // Validate drink availability + await logic.withValidation("drinkAvailability", drinkId, async () => { + if (!drinkRecipes[drinkId]) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (!sizeQuantifiers[size]) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); + + // Get current resources + const currentResources = await logic.withDatabase("select", "resources", async () => { + return { ...allAvailableResources }; + }); + + // Calculate resource consumption + const newResources = await logic.withProcessing( + "calculate.resourceConsumption", + async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + + return newResources; }, { - "resource.id": resourceId, - "resource.level": newLevel, - "threshold.low": 10, - "threshold.empty": 0, - "maintenance.needed": maintenanceNeeded, + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption", } ); - // Log resource level change - await createChildSpan( - "logging.resourceUpdate", + // Validate resource availability and emit events if needed + await logic.withValidation("resourceAvailability", newResources, async () => { + const insufficientResources: string[] = []; + for (const [resource, level] of Object.entries(newResources)) { + if (level < 0) { + insufficientResources.push(resource); + } + } + + if (insufficientResources.length > 0) { + // Emit outOfResource event before throwing error + await logic.withProcessing("event.outOfResource", async () => { + const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; + tracedEventHandler("outOfResource", (data) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + + throw new Error(`Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)`); + } + }); + + // Update resources and increment counter + await logic.withDatabase("update", "all_resources", async () => { + Object.assign(allAvailableResources, newResources); + servedCounter += quantity; + }); + + // Simulate brewing process + await logic.withProcessing( + "brewing.process", async () => { - console.log( - `Resource ${resourceId} updated: ${levelChange.previous}% → ${newLevel}% (${levelChange.changeType})` - ); + // Simulate brewing time + await new Promise(resolve => setTimeout(resolve, 1000)); + return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; }, { - "resource.id": resourceId, - "level.previous": levelChange.previous, - "level.new": newLevel, - "change.type": levelChange.changeType, - "change.amount": levelChange.change, + "brewing.drink": drinkId, + "brewing.quantity": quantity, + "brewing.size": size, + "brewing.duration_ms": 1000, } ); + + return { + result: true, + message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, + }; }); - }) + } ); - // Override a read handler for availableResourceLevel property, - // utilizing the uriVariables properly - thing.setPropertyReadHandler( - "availableResourceLevel", - tracedPropertyReadHandler("availableResourceLevel", async (options) => { - // Check if uriVariables are provided - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - if ("id" in uriVariables) { - const id = uriVariables.id; - return allAvailableResources[id]; - } - } - throw Error("Please specify id variable as uriVariables."); - }) - ); + // Action: setSchedule + tracedThing.setActionHandler( + "setSchedule", + "setSchedule", + async (params) => { + const logic = createTracedLogic("setSchedule"); + + return await logic.execute(async () => { + // Parse and validate schedule data + const scheduleData = await logic.withProcessing( + "parsing.extractScheduleData", + async () => { + const data = await (params as any)?.value(); + return { + drinkId: data?.drinkId ?? "americano", + size: data?.size ?? "m", + quantity: data?.quantity ?? 1, + time: data?.time, + mode: data?.mode, + }; + }, + { + "parsing.operation": "schedule_extraction", + } + ); - // Set up a handler for makeDrink action using traced wrapper - thing.setActionHandler( - "makeDrink", - tracedActionHandler("makeDrink", async (_params, options) => { - // Parse input parameters first to use in metadata - let drinkId = "americano"; - let size = "m"; - let quantity = 1; - - if (Boolean(options) && typeof options === "object" && "uriVariables" in options) { - const uriVariables = options.uriVariables as Record; - drinkId = "drinkId" in uriVariables ? (uriVariables.drinkId as string) : drinkId; - size = "size" in uriVariables ? (uriVariables.size as string) : size; - quantity = "quantity" in uriVariables ? (uriVariables.quantity as number) : quantity; - } - - return await traceBusinessLogic( - "makeDrink", - async () => { - // Validate input parameters - await traceValidation("input", options, async () => { - if (!drinkId || !size || !quantity) { - throw new Error("Invalid input parameters"); - } - }); - - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await traceDatabaseOperation( - "select", - "recipes", - async () => { - // Size quantifiers - const sizeQuantifiers: Record = { - s: 0.1, - m: 0.2, - l: 0.3, - }; - - // Drink recipes showing the amount of a resource consumed for a particular drink - const drinkRecipes: Record> = { - espresso: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - americano: { - water: 2, - milk: 0, - chocolate: 0, - coffeeBeans: 2, - }, - cappuccino: { - water: 1, - milk: 1, - chocolate: 0, - coffeeBeans: 2, - }, - latte: { - water: 1, - milk: 2, - chocolate: 0, - coffeeBeans: 2, - }, - hotChocolate: { - water: 0, - milk: 0, - chocolate: 1, - coffeeBeans: 0, - }, - hotWater: { - water: 1, - milk: 0, - chocolate: 0, - coffeeBeans: 0, - }, - }; - - return { drinkRecipes, sizeQuantifiers }; - } - ); + // Validate required fields and format + await logic.withValidation("scheduleData", scheduleData, async () => { + if (!scheduleData.time || !scheduleData.mode) { + throw new Error("Time and mode are required for scheduling"); + } + + // Validate time format (HH:MM in 24-hour format) + const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/; + if (!timeRegex.test(scheduleData.time)) { + throw new Error(`Invalid time format: ${scheduleData.time}. Expected HH:MM (24-hour format)`); + } + + // Validate mode + const validModes = ["once", "everyday", "everyMo", "everyTu", "everyWe", "everyTh", "everyFr", "everySat", "everySun"]; + if (!validModes.includes(scheduleData.mode)) { + throw new Error(`Invalid mode: ${scheduleData.mode}. Must be one of: ${validModes.join(", ")}`); + } + }); - // Validate drink availability - await traceValidation("drinkAvailability", drinkId, async () => { - if (!drinkRecipes[drinkId]) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (!sizeQuantifiers[size]) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); - - // Get current resources from sensors - const currentResources = await traceDatabaseOperation("select", "resources", async () => { - return { ...allAvailableResources }; - }); - - // Calculate resource consumption - const newResources = await createChildSpan( - "calculate.resourceConsumption", - async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; - - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil( - quantity * sizeMultiplier * recipe.coffeeBeans - ); - - return newResources; - }, - { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption", - } - ); - - // Validate resource availability - await traceValidation("resourceAvailability", newResources, async () => { - for (const resource in newResources) { - if (newResources[resource] <= 0) { - const eventData = `Low level of ${resource}: ${newResources[resource]}%`; - await createChildSpan("event.outOfResource", async () => { - tracedEventHandler("outOfResource", (data) => - thing.emitEvent("outOfResource", data) - )(eventData); - }); - throw new Error(`${resource} level is not sufficient`); - } - } - }); - - // Update resources in database - await traceDatabaseOperation("update", "resources", async () => { - allAvailableResources = newResources; - }); - - // Update served counter - await traceDatabaseOperation("update", "counters", async () => { - servedCounter = servedCounter + quantity; - }); - - // Simulate drink preparation - await createChildSpan( - "hardware.prepareDrink", - async () => { - // Simulate time for drink preparation - await new Promise((resolve) => setTimeout(resolve, 100)); - }, - { - "hardware.operation": "drink_preparation", - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - } - ); - - // Return success response - return { - result: true, - message: `Your ${drinkId} is in progress!`, - }; - }, - { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - } - ); - }) - ); + // Add schedule to database + await logic.withDatabase("insert", "schedules", async () => { + schedules.push(scheduleData); + }); - // Set up a handler for setSchedule action using traced wrapper - thing.setActionHandler( - "setSchedule", - tracedActionHandler("setSchedule", async (params, options) => { - // Parse input parameters first for metadata - const paramsp = params ? ((await (params as any).value()) as Record) : null; - - return await traceBusinessLogic( - "setSchedule", - async () => { - // Always create initial validation span to show the process started - const validatedParams = await createChildSpan( - "initialization.parseInput", - async () => { - // Validate input parameters - await traceValidation("input", params, async () => { - if (!paramsp) { - throw new Error("No parameters provided"); - } - }); - - // Validate required parameters - const scheduleData = await traceValidation( - "scheduleParameters", - paramsp, - async () => { - if ( - paramsp == null || - typeof paramsp !== "object" || - !("time" in paramsp) || - !("mode" in paramsp) - ) { - throw new Error( - "Please provide all the required parameters: time and mode." - ); - } - - // Use default values if not provided - const data = { - time: paramsp.time, - mode: paramsp.mode, - drinkId: "drinkId" in paramsp ? paramsp.drinkId : "americano", - size: "size" in paramsp ? paramsp.size : "m", - quantity: "quantity" in paramsp ? paramsp.quantity : 1, - }; - - return data; - } - ); - - // Validate time format - await traceValidation("timeFormat", scheduleData.time, async () => { - const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/; - if (!timeRegex.test(String(scheduleData.time))) { - throw new Error("Invalid time format. Please use HH:MM format."); - } - }); - - return scheduleData; - }, - { - "input.present": !!paramsp, - "input.type": typeof paramsp, - "schedule.time": - paramsp && typeof paramsp === "object" && "time" in paramsp - ? String(paramsp.time) - : "unknown", - "schedule.mode": - paramsp && typeof paramsp === "object" && "mode" in paramsp - ? String(paramsp.mode) - : "unknown", - } - ); - - // Continue with business logic (this will only execute if validation passes) - await createChildSpan( - "business.scheduleProcessing", - async () => { - // Check schedule conflicts - await createChildSpan( - "check.scheduleConflicts", - async () => { - const existingSchedule = schedules.find( - (s) => - typeof s === "object" && - s !== null && - "time" in s && - s.time === validatedParams.time - ); - if (existingSchedule) { - throw new Error( - `Schedule already exists for time ${validatedParams.time}` - ); - } - }, - { - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode), - } - ); - - // Save schedule to database - await traceDatabaseOperation("insert", "schedules", async () => { - schedules.push(validatedParams); - }); - - // Log schedule creation - await createChildSpan("logging.scheduleCreated", async () => { - console.log(`Schedule created: ${JSON.stringify(validatedParams)}`); - }); - }, - { - "business.operation": "schedule_processing", - "schedule.time": String(validatedParams.time), - "schedule.mode": String(validatedParams.mode), - } - ); - - return { - result: true, - message: `Your schedule has been set!`, - }; - }, - { - "schedule.time": - paramsp && typeof paramsp === "object" && "time" in paramsp - ? String(paramsp.time) - : "unknown", - "schedule.mode": - paramsp && typeof paramsp === "object" && "mode" in paramsp - ? String(paramsp.mode) - : "unknown", - } - ); - }) + return { + result: true, + message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, + }; + }); + } ); - // Finally expose the thing thing.expose().then(() => { - console.info(`${thing.getThingDescription().title} ready`); - console.info("ThingIsReady"); + console.info(`${(thingDescription as any).title} ready`); + console.log("ThingIsReady"); }); - console.log(`Produced ${thing.getThingDescription().title}`); }); }) - .catch((e: Error) => { + .catch((e) => { console.log(e); - }); + }); \ No newline at end of file diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index e82369b..87aa523 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -249,12 +249,9 @@ export function createChildSpan( attributes?: Record ): Promise { if (!tracer || !tracer.startActiveSpan) { - // Fallback if tracer is not available - console.log(`[TRACING] No tracer available for: ${operationName}`); return Promise.resolve(operation()); } - console.log(`[TRACING] Creating child span: ${operationName}`); return tracer.startActiveSpan(operationName, async (span: any) => { try { // Add custom attributes if provided @@ -266,7 +263,6 @@ export function createChildSpan( if (span.setStatus) { span.setStatus({ code: SpanStatusCode.OK }); } - console.log(`[TRACING] Child span completed: ${operationName}`); return result; } catch (error) { if (span.setStatus) { @@ -332,7 +328,6 @@ export function traceBusinessLogic( }); } -// Legacy compatibility export const tracedActionHandler = traceAction; export const tracedPropertyReadHandler = tracePropertyRead; export const tracedPropertyWriteHandler = tracePropertyWrite; From 680f3208f2e85de9ef753ee9be9440320945b062 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 00:44:09 -0400 Subject: [PATCH 20/34] fix: fixed jeager endpoint in docker-compose-things --- docker-compose-things.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-things.yml b/docker-compose-things.yml index 6dbfcac..e615bd4 100644 --- a/docker-compose-things.yml +++ b/docker-compose-things.yml @@ -149,7 +149,7 @@ services: environment: - HOSTNAME=${STACK_HOSTNAME} - PORT=${WEB_PORT_OUT} - - JAEGER_ENDPOINT=http://host.docker.internal:14268/api/traces + - JAEGER_ENDPOINT=http://host.docker.internal:8085/api/traces deploy: resources: limits: From 3cb0171151d6312ae53e31d6bf420ecd29015dc9 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 10:26:56 -0400 Subject: [PATCH 21/34] Removed unnecessary method --- .../http/ts/src/auto-tracing.ts | 27 +- .../http/ts/src/main.ts | 762 +++++++++--------- 2 files changed, 382 insertions(+), 407 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts index 6409082..826b545 100644 --- a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts @@ -24,7 +24,6 @@ import { createChildSpan, } from "./tracing"; - interface ValidationConfig { type: string; validator: (data: any) => Promise | void; @@ -139,7 +138,7 @@ export function autoTracedAction( } } - // Execute processing steps + // Execute processing steps if (config.processing) { for (const proc of config.processing) { await createChildSpan(proc.name, async () => {}, proc.attributes); @@ -163,19 +162,11 @@ export function autoTracedAction( export class TracedBusinessLogic { constructor(private baseSpanName: string) {} - async withValidation( - validationType: string, - data: any, - operation: () => Promise | T - ): Promise { + async withValidation(validationType: string, data: any, operation: () => Promise | T): Promise { return await traceValidation(validationType, data, operation); } - async withDatabase( - operation: string, - table: string, - dbOperation: () => Promise | T - ): Promise { + async withDatabase(operation: string, table: string, dbOperation: () => Promise | T): Promise { return await traceDatabaseOperation(operation, table, dbOperation); } @@ -192,7 +183,6 @@ export class TracedBusinessLogic { } } - export function createTracedLogic(spanName: string): TracedBusinessLogic { return new TracedBusinessLogic(spanName); } @@ -249,7 +239,7 @@ export class AutoTracedThing { if (configBuilder) { config = configBuilder(config); } - + this.thing.setPropertyReadHandler( propertyName, autoTracedPropertyRead(propertyName, config.build(), businessLogic) as any @@ -266,7 +256,7 @@ export class AutoTracedThing { if (configBuilder) { config = configBuilder(config); } - + this.thing.setPropertyWriteHandler( propertyName, autoTracedPropertyWrite(propertyName, config.build(), businessLogic) @@ -283,11 +273,8 @@ export class AutoTracedThing { if (configBuilder) { config = configBuilder(config); } - - this.thing.setActionHandler( - actionName, - autoTracedAction(actionName, config.build(), businessLogic) as any - ); + + this.thing.setActionHandler(actionName, autoTracedAction(actionName, config.build(), businessLogic) as any); } // Delegate other methods to the wrapped thing diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 7055530..4372298 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -44,14 +44,18 @@ let schedules: unknown[]; let servedCounter: number; function readFromSensor(sensorType: string): number { - // Actual implementation of reading data from a sensor can go here - // For the sake of example, let's just return a value - return 100; -} - -function notify(subscribers: unknown, msg: string) { - // Actual implementation of notifying subscribers with a message can go here - console.log(msg); + // Simulate realistic sensor readings with some variation + const baseLevels: Record = { + water: 80, + milk: 60, + chocolate: 40, + coffeeBeans: 90, + }; + + const baseLevel = baseLevels[sensorType] || 50; + // Add some realistic variation (±10%) to simulate real sensor readings + const variation = (Math.random() - 0.5) * 20; + return Math.max(0, Math.min(100, Math.round(baseLevel + variation))); } const { @@ -122,233 +126,209 @@ servient const tracedThing = createAutoTracedThing(thing); // Property: allAvailableResources - tracedThing.setPropertyReadHandler( - "allAvailableResources", - "getAllResources", - async (options) => { - const logic = createTracedLogic("getAllResources"); - - return await logic.execute(async () => { - // Validate resource data integrity - await logic.withValidation("resourceData", allAvailableResources, async () => { - const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; - for (const resource of requiredResources) { - if (!(resource in allAvailableResources)) { - throw new Error(`Missing required resource: ${resource}`); - } - if (typeof allAvailableResources[resource] !== "number") { - throw new Error(`Invalid resource level for ${resource}`); - } + tracedThing.setPropertyReadHandler("allAvailableResources", "getAllResources", async (options) => { + const logic = createTracedLogic("getAllResources"); + + return await logic.execute(async () => { + // Validate resource data integrity + await logic.withValidation("resourceData", allAvailableResources, async () => { + const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; + for (const resource of requiredResources) { + if (!(resource in allAvailableResources)) { + throw new Error(`Missing required resource: ${resource}`); } - }); - - // Read sensor data for real-time validation - const sensorData = await logic.withProcessing( - "sensors.readAll", - async () => { - const readings: Record = {}; - for (const resource in allAvailableResources) { - readings[resource] = readFromSensor(resource); - } - return readings; - }, - { - "sensor.count": Object.keys(allAvailableResources).length, - "sensor.type": "resource_level", + if (typeof allAvailableResources[resource] !== "number") { + throw new Error(`Invalid resource level for ${resource}`); } - ); - - // Compare and sync with database - return await logic.withDatabase("select", "resource_levels", async () => { - return { ...allAvailableResources }; - }); + } }); - } - ); - // Property: possibleDrinks - tracedThing.setPropertyReadHandler( - "possibleDrinks", - "getPossibleDrinks", - async (options) => { - const logic = createTracedLogic("getPossibleDrinks"); - - return await logic.execute(async () => { - // Validate drink catalog integrity - await logic.withValidation("drinkCatalog", possibleDrinks, async () => { - if (!Array.isArray(possibleDrinks)) { - throw new Error("Drink catalog is corrupted"); + // Read sensor data for real-time validation + const sensorData = await logic.withProcessing( + "sensors.readAll", + async () => { + const readings: Record = {}; + for (const resource in allAvailableResources) { + readings[resource] = readFromSensor(resource); } - if (possibleDrinks.length === 0) { - throw new Error("No drinks available in catalog"); - } - }); + return readings; + }, + { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level", + } + ); + + // Compare and sync with database + return await logic.withDatabase("select", "resource_levels", async () => { + return { ...allAvailableResources }; + }); + }); + }); - // Load drink availability from database - const availabilityMap = await logic.withDatabase( - "select", - "drink_availability", - async () => { - const availability: Record = {}; - for (const drink of possibleDrinks) { - availability[drink] = true; - } - return availability; - } - ); + // Property: possibleDrinks + tracedThing.setPropertyReadHandler("possibleDrinks", "getPossibleDrinks", async (options) => { + const logic = createTracedLogic("getPossibleDrinks"); + + return await logic.execute(async () => { + // Validate drink catalog integrity + await logic.withValidation("drinkCatalog", possibleDrinks, async () => { + if (!Array.isArray(possibleDrinks)) { + throw new Error("Drink catalog is corrupted"); + } + if (possibleDrinks.length === 0) { + throw new Error("No drinks available in catalog"); + } + }); - // Filter available drinks based on current resources - return await logic.withProcessing( - "processing.filterAvailableDrinks", - async () => { - return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); - }, - { - "drinks.total": possibleDrinks.length, - "filtering.criteria": "resource_availability", - } - ); + // Load drink availability from database + const availabilityMap = await logic.withDatabase("select", "drink_availability", async () => { + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; + } + return availability; }); - } - ); + + // Filter available drinks based on current resources + return await logic.withProcessing( + "processing.filterAvailableDrinks", + async () => { + return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); + }, + { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability", + } + ); + }); + }); // Property: maintenanceNeeded (simple read) tracedThing.setPropertyReadHandler( "maintenanceNeeded", - "getMaintenanceStatus", + "getMaintenanceStatus", async (options) => maintenanceNeeded ); // Property Read: availableResourceLevel (with URI variables) - tracedThing.setPropertyReadHandler( - "availableResourceLevel", - "getResourceLevel", - async (options) => { - const logic = createTracedLogic("getResourceLevel"); - - return await logic.execute(async () => { - // Parse resource ID from URI variables - const resourceId = await logic.withProcessing( - "parsing.extractResourceId", - async () => { - const resourceId = options?.uriVariables?.id as string; - if (!resourceId || !(resourceId in allAvailableResources)) { - throw new Error(`Invalid resource ID: ${resourceId}`); - } - return resourceId; - }, - { - "resource.id": options?.uriVariables?.id || "unknown", - "parsing.operation": "resource_id_extraction", + tracedThing.setPropertyReadHandler("availableResourceLevel", "getResourceLevel", async (options) => { + const logic = createTracedLogic("getResourceLevel"); + + return await logic.execute(async () => { + // Parse resource ID from URI variables + const resourceId = await logic.withProcessing( + "parsing.extractResourceId", + async () => { + const resourceId = options?.uriVariables?.id as string; + if (!resourceId || !(resourceId in allAvailableResources)) { + throw new Error(`Invalid resource ID: ${resourceId}`); } - ); - - // Get resource level from database - return await logic.withDatabase("select", "resource_levels", async () => { - return allAvailableResources[resourceId]; - }); + return resourceId; + }, + { + "resource.id": options?.uriVariables?.id || "unknown", + "parsing.operation": "resource_id_extraction", + } + ); + + // Get resource level from database + return await logic.withDatabase("select", "resource_levels", async () => { + return allAvailableResources[resourceId]; }); - } - ); + }); + }); // Property: schedules - tracedThing.setPropertyReadHandler( - "schedules", - "getSchedules", - async (options) => { - const logic = createTracedLogic("getSchedules"); - - return await logic.execute(async () => { - // Validate system state - await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { - if (!Array.isArray(schedules)) { - throw new Error("Schedules data structure is corrupted"); - } - }); - - // Load schedules from database - const result = await logic.withDatabase("select", "schedules", async () => { - return schedules; - }); + tracedThing.setPropertyReadHandler("schedules", "getSchedules", async (options) => { + const logic = createTracedLogic("getSchedules"); + + return await logic.execute(async () => { + // Validate system state + await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { + if (!Array.isArray(schedules)) { + throw new Error("Schedules data structure is corrupted"); + } + }); - // Process and filter active schedules - return await logic.withProcessing( - "processing.filterActiveSchedules", - async () => { - return result.filter((schedule: any) => true); // For demo, all schedules are active - }, - { - "schedules.count": schedules.length, - "query.time": new Date().toISOString(), - } - ); + // Load schedules from database + const result = await logic.withDatabase("select", "schedules", async () => { + return schedules; }); - } - ); + + // Process and filter active schedules + return await logic.withProcessing( + "processing.filterActiveSchedules", + async () => { + return result.filter((schedule: any) => true); // For demo, all schedules are active + }, + { + "schedules.count": schedules.length, + "query.time": new Date().toISOString(), + } + ); + }); + }); // Property Write: servedCounter - tracedThing.setPropertyWriteHandler( - "servedCounter", - "updateServedCounter", - async (val) => { - const logic = createTracedLogic("updateServedCounter"); - - await logic.execute(async () => { - // Validate input - await logic.withValidation("counterInput", val, async () => { - if (!val) { - throw new Error("No value provided for servedCounter"); - } - }); + tracedThing.setPropertyWriteHandler("servedCounter", "updateServedCounter", async (val) => { + const logic = createTracedLogic("updateServedCounter"); + + await logic.execute(async () => { + // Validate input + await logic.withValidation("counterInput", val, async () => { + if (!val) { + throw new Error("No value provided for servedCounter"); + } + }); - // Parse and validate the new counter value - const newCounterValue = await logic.withProcessing( - "parsing.extractCounterValue", - async () => { - const value = (await (val as any).value()) as number; - if (typeof value !== "number" || value < 0) { - throw new Error(`Invalid served counter value: ${value}`); - } - return value; - }, - { - "input.type": typeof val, - "parsing.operation": "counter_extraction", + // Parse and validate the new counter value + const newCounterValue = await logic.withProcessing( + "parsing.extractCounterValue", + async () => { + const value = (await (val as any).value()) as number; + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); } - ); - - // Update counter in database - await logic.withDatabase("update", "counters", async () => { - servedCounter = newCounterValue; - }); - - // Check maintenance threshold and trigger events if needed - await logic.withProcessing("business.checkMaintenanceThreshold", async () => { - if (servedCounter > 1000) { - // Update maintenance status - await logic.withDatabase("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); + return value; + }, + { + "input.type": typeof val, + "parsing.operation": "counter_extraction", + } + ); + + // Update counter in database + await logic.withDatabase("update", "counters", async () => { + servedCounter = newCounterValue; + }); - // Emit maintenance event - await logic.withProcessing("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); - } - }); + // Check maintenance threshold and trigger events if needed + await logic.withProcessing("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await logic.withDatabase("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + + // Emit maintenance event + await logic.withProcessing("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); + } }); - } - ); + }); + }); // Property Write: availableResourceLevel tracedThing.setPropertyWriteHandler( - "availableResourceLevel", + "availableResourceLevel", "updateResourceLevel", async (val, options) => { const logic = createTracedLogic("updateResourceLevel"); - + await logic.execute(async () => { // Parse and validate resource data const { resourceId, newLevel } = await logic.withProcessing( @@ -356,14 +336,14 @@ servient async () => { const resourceId = options?.uriVariables?.id as string; const newLevel = (await (val as any).value()) as number; - + if (!resourceId || !(resourceId in allAvailableResources)) { throw new Error(`Invalid resource ID: ${resourceId}`); } if (typeof newLevel !== "number" || newLevel < 0 || newLevel > 100) { throw new Error(`Invalid level for ${resourceId}: ${newLevel}`); } - + return { resourceId, newLevel }; }, { @@ -412,198 +392,206 @@ servient } ); - // Action: makeDrink - tracedThing.setActionHandler( - "makeDrink", - "makeDrink", - async (params, options) => { - const logic = createTracedLogic("makeDrink"); - - return await logic.execute(async () => { - // Parse parameters with defaults - const { drinkId, size, quantity } = await logic.withProcessing( - "parsing.extractDrinkParameters", - async () => { - const drinkId = options?.uriVariables?.drinkId ?? "americano"; - const size = options?.uriVariables?.size ?? "m"; - const quantity = options?.uriVariables?.quantity ?? 1; - return { drinkId, size, quantity }; - }, - { - "parsing.operation": "drink_parameters", - "defaults.applied": true, - } - ); - - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( - "select", - "recipes", - async () => { - // Define recipes and quantifiers (would come from database in real system) - const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; - const drinkRecipes: Record> = { - espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, - americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, - cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, - latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, - hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, - hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, - }; - return { drinkRecipes, sizeQuantifiers }; - } - ); - - // Validate drink availability - await logic.withValidation("drinkAvailability", drinkId, async () => { - if (!drinkRecipes[drinkId]) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (!sizeQuantifiers[size]) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); - - // Get current resources - const currentResources = await logic.withDatabase("select", "resources", async () => { - return { ...allAvailableResources }; - }); - - // Calculate resource consumption - const newResources = await logic.withProcessing( - "calculate.resourceConsumption", - async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; - - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); - - return newResources; - }, - { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption", - } - ); - - // Validate resource availability and emit events if needed - await logic.withValidation("resourceAvailability", newResources, async () => { - const insufficientResources: string[] = []; - for (const [resource, level] of Object.entries(newResources)) { - if (level < 0) { - insufficientResources.push(resource); - } - } - - if (insufficientResources.length > 0) { - // Emit outOfResource event before throwing error - await logic.withProcessing("event.outOfResource", async () => { - const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; - tracedEventHandler("outOfResource", (data) => - thing.emitEvent("outOfResource", data) - )(eventData); - }); - - throw new Error(`Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)`); - } - }); + // Action: makeDrink + tracedThing.setActionHandler("makeDrink", "makeDrink", async (params, options) => { + const logic = createTracedLogic("makeDrink"); + + return await logic.execute(async () => { + // Parse parameters with defaults + const { drinkId, size, quantity } = await logic.withProcessing( + "parsing.extractDrinkParameters", + async () => { + const drinkId = options?.uriVariables?.drinkId ?? "americano"; + const size = options?.uriVariables?.size ?? "m"; + const quantity = options?.uriVariables?.quantity ?? 1; + return { drinkId, size, quantity }; + }, + { + "parsing.operation": "drink_parameters", + "defaults.applied": true, + } + ); + + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( + "select", + "recipes", + async () => { + // Define recipes and quantifiers (would come from database in real system) + const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; + const drinkRecipes: Record> = { + espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, + americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, + cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, + latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, + hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, + hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, + }; + return { drinkRecipes, sizeQuantifiers }; + } + ); + + // Validate drink availability + await logic.withValidation("drinkAvailability", drinkId, async () => { + if (!drinkRecipes[drinkId]) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (!sizeQuantifiers[size]) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); - // Update resources and increment counter - await logic.withDatabase("update", "all_resources", async () => { - Object.assign(allAvailableResources, newResources); - servedCounter += quantity; - }); + // Get current resources + const currentResources = await logic.withDatabase("select", "resources", async () => { + return { ...allAvailableResources }; + }); - // Simulate brewing process - await logic.withProcessing( - "brewing.process", - async () => { - // Simulate brewing time - await new Promise(resolve => setTimeout(resolve, 1000)); - return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; - }, - { - "brewing.drink": drinkId, - "brewing.quantity": quantity, - "brewing.size": size, - "brewing.duration_ms": 1000, + // Calculate resource consumption + const newResources = await logic.withProcessing( + "calculate.resourceConsumption", + async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + + return newResources; + }, + { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption", + } + ); + + // Validate resource availability and emit events if needed + await logic.withValidation("resourceAvailability", newResources, async () => { + const insufficientResources: string[] = []; + for (const [resource, level] of Object.entries(newResources)) { + if (level < 0) { + insufficientResources.push(resource); } - ); - - return { - result: true, - message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, - }; + } + + if (insufficientResources.length > 0) { + // Emit outOfResource event before throwing error + await logic.withProcessing("event.outOfResource", async () => { + const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; + tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( + eventData + ); + }); + + throw new Error( + `Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)` + ); + } }); - } - ); - // Action: setSchedule - tracedThing.setActionHandler( - "setSchedule", - "setSchedule", - async (params) => { - const logic = createTracedLogic("setSchedule"); - - return await logic.execute(async () => { - // Parse and validate schedule data - const scheduleData = await logic.withProcessing( - "parsing.extractScheduleData", - async () => { - const data = await (params as any)?.value(); - return { - drinkId: data?.drinkId ?? "americano", - size: data?.size ?? "m", - quantity: data?.quantity ?? 1, - time: data?.time, - mode: data?.mode, - }; - }, - { - "parsing.operation": "schedule_extraction", - } - ); + // Update resources and increment counter + await logic.withDatabase("update", "all_resources", async () => { + Object.assign(allAvailableResources, newResources); + servedCounter += quantity; + }); - // Validate required fields and format - await logic.withValidation("scheduleData", scheduleData, async () => { - if (!scheduleData.time || !scheduleData.mode) { - throw new Error("Time and mode are required for scheduling"); - } - - // Validate time format (HH:MM in 24-hour format) - const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/; - if (!timeRegex.test(scheduleData.time)) { - throw new Error(`Invalid time format: ${scheduleData.time}. Expected HH:MM (24-hour format)`); - } - - // Validate mode - const validModes = ["once", "everyday", "everyMo", "everyTu", "everyWe", "everyTh", "everyFr", "everySat", "everySun"]; - if (!validModes.includes(scheduleData.mode)) { - throw new Error(`Invalid mode: ${scheduleData.mode}. Must be one of: ${validModes.join(", ")}`); - } - }); + // Simulate brewing process + await logic.withProcessing( + "brewing.process", + async () => { + // Simulate brewing time + await new Promise((resolve) => setTimeout(resolve, 1000)); + return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; + }, + { + "brewing.drink": drinkId, + "brewing.quantity": quantity, + "brewing.size": size, + "brewing.duration_ms": 1000, + } + ); + + return { + result: true, + message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, + }; + }); + }); - // Add schedule to database - await logic.withDatabase("insert", "schedules", async () => { - schedules.push(scheduleData); - }); + // Action: setSchedule + tracedThing.setActionHandler("setSchedule", "setSchedule", async (params) => { + const logic = createTracedLogic("setSchedule"); + + return await logic.execute(async () => { + // Parse and validate schedule data + const scheduleData = await logic.withProcessing( + "parsing.extractScheduleData", + async () => { + const data = await (params as any)?.value(); + return { + drinkId: data?.drinkId ?? "americano", + size: data?.size ?? "m", + quantity: data?.quantity ?? 1, + time: data?.time, + mode: data?.mode, + }; + }, + { + "parsing.operation": "schedule_extraction", + } + ); + + // Validate required fields and format + await logic.withValidation("scheduleData", scheduleData, async () => { + if (!scheduleData.time || !scheduleData.mode) { + throw new Error("Time and mode are required for scheduling"); + } + + // Validate time format (HH:MM in 24-hour format) + const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/; + if (!timeRegex.test(scheduleData.time)) { + throw new Error( + `Invalid time format: ${scheduleData.time}. Expected HH:MM (24-hour format)` + ); + } + + // Validate mode + const validModes = [ + "once", + "everyday", + "everyMo", + "everyTu", + "everyWe", + "everyTh", + "everyFr", + "everySat", + "everySun", + ]; + if (!validModes.includes(scheduleData.mode)) { + throw new Error( + `Invalid mode: ${scheduleData.mode}. Must be one of: ${validModes.join(", ")}` + ); + } + }); - return { - result: true, - message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, - }; + // Add schedule to database + await logic.withDatabase("insert", "schedules", async () => { + schedules.push(scheduleData); }); - } - ); + + return { + result: true, + message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, + }; + }); + }); thing.expose().then(() => { console.info(`${(thingDescription as any).title} ready`); @@ -613,4 +601,4 @@ servient }) .catch((e) => { console.log(e); - }); \ No newline at end of file + }); From f12f17965bae5b90e712f63584d86e70a1ab9356 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 16:47:25 -0400 Subject: [PATCH 22/34] fix: hopefully fixed lint errors --- package-lock.json | 199 ++++++++++-------- package.json | 2 + .../http/ts/src/auto-tracing.ts | 75 ++++--- .../http/ts/src/main.ts | 96 ++++++--- .../http/ts/src/tracing.ts | 184 ++++++++++------ 5 files changed, 347 insertions(+), 209 deletions(-) diff --git a/package-lock.json b/package-lock.json index 29213c3..f6e5d1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,10 @@ "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.30.0", + "eslint-plugin-n": "^17.21.3", "eslint-plugin-node": "^11.1.0", "eslint-plugin-notice": "^1.0.0", + "eslint-plugin-promise": "^7.2.1", "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-workspaces": "^0.10.1", "mocha": "^10.7.3", @@ -2106,31 +2108,6 @@ "node": ">= 0.10.x" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/builtins": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", - "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bulk-write-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", @@ -2923,6 +2900,20 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/error": { "version": "7.0.2", "dependencies": { @@ -3167,7 +3158,6 @@ "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^7.5.4" }, @@ -3301,7 +3291,6 @@ "https://opencollective.com/eslint" ], "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.11.0", @@ -3406,45 +3395,43 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "17.21.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.21.3.tgz", + "integrity": "sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=8.23.0" } }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-plugin-n/node_modules/ignore": { @@ -3453,25 +3440,10 @@ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 4" } }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -3553,14 +3525,16 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", - "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz", + "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==", "dev": true, "license": "ISC", - "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4402,7 +4376,6 @@ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -4489,6 +4462,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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, + "license": "MIT" + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -4501,6 +4481,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4918,23 +4905,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -7249,7 +7219,6 @@ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -8066,6 +8035,16 @@ "node": ">=0.10.0" } }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -8164,6 +8143,42 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/ts-declaration-location/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/ts-expect": { "version": "1.3.0", "license": "MIT" diff --git a/package.json b/package.json index 67c296a..8f051fe 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,10 @@ "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.30.0", + "eslint-plugin-n": "^17.21.3", "eslint-plugin-node": "^11.1.0", "eslint-plugin-notice": "^1.0.0", + "eslint-plugin-promise": "^7.2.1", "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-workspaces": "^0.10.1", "mocha": "^10.7.3", diff --git a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts index 826b545..870fc3e 100644 --- a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts @@ -26,7 +26,7 @@ import { interface ValidationConfig { type: string; - validator: (data: any) => Promise | void; + validator: (data: WoT.InteractionInput | null) => Promise | void; } interface DatabaseConfig { @@ -36,7 +36,7 @@ interface DatabaseConfig { interface ProcessingConfig { name: string; - attributes?: Record; + attributes?: Record; } interface BusinessLogicConfig { @@ -44,14 +44,14 @@ interface BusinessLogicConfig { validations?: ValidationConfig[]; database?: DatabaseConfig[]; processing?: ProcessingConfig[]; - metadata?: Record; + metadata?: Record; } // Auto-traced property handler export function autoTracedPropertyRead( propertyName: string, config: BusinessLogicConfig, - businessLogic: (options?: any) => Promise | T + businessLogic: (options?: WoT.InteractionOptions) => Promise | T ): (options?: WoT.InteractionOptions) => Promise { return tracedPropertyReadHandler(propertyName, async (options) => { return await traceBusinessLogic(config.name, async () => { @@ -88,7 +88,7 @@ export function autoTracedPropertyRead( export function autoTracedPropertyWrite( propertyName: string, config: BusinessLogicConfig, - businessLogic: (value: any, options?: any) => Promise | void + businessLogic: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void ): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { return tracedPropertyWriteHandler(propertyName, async (value, options) => { return await traceBusinessLogic(config.name, async () => { @@ -125,15 +125,19 @@ export function autoTracedPropertyWrite( export function autoTracedAction( actionName: string, config: BusinessLogicConfig, - businessLogic: (params?: any, options?: any) => Promise | T + businessLogic: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T ): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { return tracedActionHandler(actionName, async (params, options) => { return await traceBusinessLogic(config.name, async () => { // Execute validations if (config.validations) { for (const validation of config.validations) { - await traceValidation(validation.type, params, async () => { - await validation.validator(params); + await traceValidation(validation.type, params ?? null, async () => { + if (params !== undefined) { + await validation.validator(params); + } else { + await validation.validator(null); + } }); } } @@ -160,9 +164,14 @@ export function autoTracedAction( // Smart wrapper that automatically creates spans based on function calls export class TracedBusinessLogic { + // eslint-disable-next-line no-useless-constructor constructor(private baseSpanName: string) {} - async withValidation(validationType: string, data: any, operation: () => Promise | T): Promise { + async withValidation( + validationType: string, + data: WoT.InteractionInput | null, + operation: () => Promise | T + ): Promise { return await traceValidation(validationType, data, operation); } @@ -173,7 +182,7 @@ export class TracedBusinessLogic { async withProcessing( operationName: string, operation: () => Promise | T, - attributes?: Record + attributes?: Record ): Promise { return await createChildSpan(operationName, operation, attributes); } @@ -190,29 +199,33 @@ export function createTracedLogic(spanName: string): TracedBusinessLogic { export class TracingConfigBuilder { private config: BusinessLogicConfig; + // eslint-disable-next-line no-useless-constructor constructor(businessLogicName: string) { this.config = { name: businessLogicName }; } - addValidation(type: string, validator: (data: any) => Promise | void): TracingConfigBuilder { - if (!this.config.validations) this.config.validations = []; + addValidation( + type: string, + validator: (data: WoT.InteractionInput | null) => Promise | void + ): TracingConfigBuilder { + this.config.validations ??= []; this.config.validations.push({ type, validator }); return this; } addDatabase(operation: string, table: string): TracingConfigBuilder { - if (!this.config.database) this.config.database = []; + this.config.database ??= []; this.config.database.push({ operation, table }); return this; } - addProcessing(name: string, attributes?: Record): TracingConfigBuilder { - if (!this.config.processing) this.config.processing = []; + addProcessing(name: string, attributes?: Record): TracingConfigBuilder { + this.config.processing ??= []; this.config.processing.push({ name, attributes }); return this; } - addMetadata(metadata: Record): TracingConfigBuilder { + addMetadata(metadata: Record): TracingConfigBuilder { this.config.metadata = { ...this.config.metadata, ...metadata }; return this; } @@ -227,12 +240,13 @@ export function tracingConfig(businessLogicName: string): TracingConfigBuilder { } export class AutoTracedThing { + // eslint-disable-next-line no-useless-constructor constructor(private thing: WoT.ExposedThing) {} setPropertyReadHandler( propertyName: string, businessLogicName: string, - businessLogic: (options?: any) => Promise | T, + businessLogic: (options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -242,14 +256,14 @@ export class AutoTracedThing { this.thing.setPropertyReadHandler( propertyName, - autoTracedPropertyRead(propertyName, config.build(), businessLogic) as any + autoTracedPropertyRead(propertyName, config.build(), businessLogic) as WoT.PropertyReadHandler ); } setPropertyWriteHandler( propertyName: string, businessLogicName: string, - businessLogic: (value: any, options?: any) => Promise | void, + businessLogic: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -266,7 +280,7 @@ export class AutoTracedThing { setActionHandler( actionName: string, businessLogicName: string, - businessLogic: (params?: any, options?: any) => Promise | T, + businessLogic: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -274,19 +288,30 @@ export class AutoTracedThing { config = configBuilder(config); } - this.thing.setActionHandler(actionName, autoTracedAction(actionName, config.build(), businessLogic) as any); + this.thing.setActionHandler( + actionName, + autoTracedAction(actionName, config.build(), businessLogic) as WoT.ActionHandler + ); } // Delegate other methods to the wrapped thing - writeProperty(propertyName: string, value: any): Promise { - return (this.thing as any).writeProperty(propertyName, value); + writeProperty(propertyName: string, value: WoT.InteractionInput): Promise { + return ( + this.thing as WoT.ExposedThing & { + writeProperty: (name: string, value: WoT.InteractionInput) => Promise; + } + ).writeProperty(propertyName, value); } readProperty(propertyName: string, options?: WoT.InteractionOptions): Promise { - return (this.thing as any).readProperty(propertyName, options); + return ( + this.thing as WoT.ExposedThing & { + readProperty: (name: string, options?: WoT.InteractionOptions) => Promise; + } + ).readProperty(propertyName, options); } - emitEvent(eventName: string, data?: any): void { + emitEvent(eventName: string, data?: WoT.InteractionInput): void { this.thing.emitEvent(eventName, data); } diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 4372298..525ad79 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -58,6 +58,24 @@ function readFromSensor(sensorType: string): number { return Math.max(0, Math.min(100, Math.round(baseLevel + variation))); } +// Type guard for WoT InteractionInput with value method +function hasValueMethod(input: unknown): input is { value: () => Promise } { + return ( + typeof input === "object" && + input !== null && + "value" in input && + typeof (input as Record).value === "function" + ); +} + +// Helper to safely extract value from WoT InteractionInput +async function extractWoTValue(input: WoT.InteractionInput): Promise { + if (hasValueMethod(input)) { + return await input.value(); + } + return input; +} + const { values: { port }, } = parseArgs({ @@ -144,11 +162,11 @@ servient }); // Read sensor data for real-time validation - const sensorData = await logic.withProcessing( + await logic.withProcessing( "sensors.readAll", async () => { const readings: Record = {}; - for (const resource in allAvailableResources) { + for (const resource of Object.keys(allAvailableResources)) { readings[resource] = readFromSensor(resource); } return readings; @@ -220,14 +238,14 @@ servient const resourceId = await logic.withProcessing( "parsing.extractResourceId", async () => { - const resourceId = options?.uriVariables?.id as string; + const resourceId = (options?.uriVariables as Record)?.id; if (!resourceId || !(resourceId in allAvailableResources)) { throw new Error(`Invalid resource ID: ${resourceId}`); } return resourceId; }, { - "resource.id": options?.uriVariables?.id || "unknown", + "resource.id": (options?.uriVariables as Record)?.id ?? "unknown", "parsing.operation": "resource_id_extraction", } ); @@ -260,7 +278,7 @@ servient return await logic.withProcessing( "processing.filterActiveSchedules", async () => { - return result.filter((schedule: any) => true); // For demo, all schedules are active + return result.filter((schedule: unknown) => true); // For demo, all schedules are active }, { "schedules.count": schedules.length, @@ -277,7 +295,7 @@ servient await logic.execute(async () => { // Validate input await logic.withValidation("counterInput", val, async () => { - if (!val) { + if (val === null || val === undefined) { throw new Error("No value provided for servedCounter"); } }); @@ -286,7 +304,12 @@ servient const newCounterValue = await logic.withProcessing( "parsing.extractCounterValue", async () => { - const value = (await (val as any).value()) as number; + if (val === null || val === undefined) { + throw new Error("No value provided for servedCounter"); + } + // Type guard and extraction for WoT InteractionInput + const value = await extractWoTValue(val); + if (typeof value !== "number" || value < 0) { throw new Error(`Invalid served counter value: ${value}`); } @@ -330,16 +353,22 @@ servient const logic = createTracedLogic("updateResourceLevel"); await logic.execute(async () => { - // Parse and validate resource data + // Parse and validate resource ID and new level const { resourceId, newLevel } = await logic.withProcessing( - "parsing.extractResourceData", + "parsing.extractResourceParameters", async () => { - const resourceId = options?.uriVariables?.id as string; - const newLevel = (await (val as any).value()) as number; - + const resourceId = (options?.uriVariables as Record)?.id; if (!resourceId || !(resourceId in allAvailableResources)) { - throw new Error(`Invalid resource ID: ${resourceId}`); + throw Error("Please specify id variable as uriVariables."); } + + if (val === null || val === undefined) { + throw new Error("No value provided for availableResourceLevel"); + } + + // Type guard and extraction for WoT InteractionInput + const newLevel = await extractWoTValue(val); + if (typeof newLevel !== "number" || newLevel < 0 || newLevel > 100) { throw new Error(`Invalid level for ${resourceId}: ${newLevel}`); } @@ -353,16 +382,17 @@ servient ); // Calculate level change - const change = await logic.withProcessing( + await logic.withProcessing( "calculate.levelChange", async () => { const currentLevel = allAvailableResources[resourceId]; - const change = newLevel - currentLevel; + const levelChange = newLevel - currentLevel; return { previous: currentLevel, new: newLevel, - change: change, - changeType: change > 0 ? "refill" : change < 0 ? "consumption" : "no_change", + change: levelChange, + changeType: + levelChange > 0 ? "refill" : levelChange < 0 ? "consumption" : "no_change", }; }, { @@ -401,9 +431,10 @@ servient const { drinkId, size, quantity } = await logic.withProcessing( "parsing.extractDrinkParameters", async () => { - const drinkId = options?.uriVariables?.drinkId ?? "americano"; - const size = options?.uriVariables?.size ?? "m"; - const quantity = options?.uriVariables?.quantity ?? 1; + const uriVars = options?.uriVariables as Record | undefined; + const drinkId = (uriVars?.drinkId as string) ?? "americano"; + const size = (uriVars?.size as string) ?? "m"; + const quantity = (uriVars?.quantity as number) ?? 1; return { drinkId, size, quantity }; }, { @@ -433,10 +464,10 @@ servient // Validate drink availability await logic.withValidation("drinkAvailability", drinkId, async () => { - if (!drinkRecipes[drinkId]) { + if (drinkRecipes[drinkId] === undefined) { throw new Error(`Drink ${drinkId} is not available`); } - if (!sizeQuantifiers[size]) { + if (sizeQuantifiers[size] === undefined) { throw new Error(`Size ${size} is not valid`); } if (quantity < 1 || quantity > 5) { @@ -534,13 +565,20 @@ servient const scheduleData = await logic.withProcessing( "parsing.extractScheduleData", async () => { - const data = await (params as any)?.value(); + if (params === null || params === undefined) { + throw new Error("No parameters provided for schedule"); + } + + // Type guard and extraction for WoT InteractionInput + const rawData = await extractWoTValue(params); + + const data = rawData as Record; return { - drinkId: data?.drinkId ?? "americano", - size: data?.size ?? "m", - quantity: data?.quantity ?? 1, - time: data?.time, - mode: data?.mode, + drinkId: (data?.drinkId as string) ?? "americano", + size: (data?.size as string) ?? "m", + quantity: (data?.quantity as number) ?? 1, + time: data?.time as string, + mode: data?.mode as string, }; }, { @@ -594,7 +632,7 @@ servient }); thing.expose().then(() => { - console.info(`${(thingDescription as any).title} ready`); + console.info(`${(thingDescription as { title: string }).title} ready`); console.log("ThingIsReady"); }); }); diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/things/advanced-coffee-machine/http/ts/src/tracing.ts index 87aa523..972e506 100644 --- a/things/advanced-coffee-machine/http/ts/src/tracing.ts +++ b/things/advanced-coffee-machine/http/ts/src/tracing.ts @@ -1,33 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and + * Document License (2015-05-13) which is available at + * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. + * + * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 + ********************************************************************************/ import { NodeTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace-node"; import { JaegerExporter } from "@opentelemetry/exporter-jaeger"; import { Resource } from "@opentelemetry/resources"; import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions"; -import { trace, SpanStatusCode, SpanKind } from "@opentelemetry/api"; +import { trace, SpanStatusCode } from "@opentelemetry/api"; import WoT from "wot-typescript-definitions"; -let tracer: any = null; +interface SpanLike { + setAttributes: (attributes: Record) => void; + setStatus: (status: { code: SpanStatusCode; message?: string }) => void; + end: () => void; +} + +interface TracerLike { + startActiveSpan: (name: string, fn: (span: SpanLike) => Promise | unknown) => Promise | unknown; +} -function safeStringify(value: any): string { +let tracer: TracerLike | null = null; + +function safeStringify(value: unknown): string { try { - return value === null || value === undefined - ? String(value) - : typeof value === "string" || typeof value === "number" || typeof value === "boolean" - ? String(value) - : JSON.stringify(value); + if (value === null || value === undefined) { + return String(value); + } + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return JSON.stringify(value); } catch { return `[Unable to serialize: ${typeof value}]`; } } function setSpanAttributes( - span: any, + span: SpanLike, name: string, operation: string, - options: any, - params?: any, - error?: any, - result?: any + options: WoT.InteractionOptions | undefined, + params?: WoT.InteractionInput, + error?: unknown, + result?: unknown ): void { // Set basic attributes const isAction = operation === "invokeaction"; @@ -53,11 +79,11 @@ function setSpanAttributes( }); // Add input options if present - if (options) { + if (options !== undefined) { span.setAttributes({ "input.options": safeStringify(options) }); // Add URI variables if present - if (options.uriVariables) { + if (options.uriVariables !== undefined) { span.setAttributes({ "input.uriVariables": safeStringify(options.uriVariables) }); // Add individual URI variables for easy filtering in Jaeger @@ -77,7 +103,7 @@ function setSpanAttributes( } // Add error or success information - if (error) { + if (error !== undefined) { const errorMessage = safeStringify(error); const isValidationError = errorMessage.includes("validation") || errorMessage.includes("schema") || errorMessage.includes("required"); @@ -115,7 +141,7 @@ export function initTracing(serviceName: string): void { provider.addSpanProcessor( new BatchSpanProcessor( new JaegerExporter({ - endpoint: process.env.JAEGER_ENDPOINT || "http://host.docker.internal:8085/api/traces", + endpoint: process.env.JAEGER_ENDPOINT ?? "http://host.docker.internal:8085/api/traces", }), { // Ensure spans are processed quickly @@ -127,14 +153,14 @@ export function initTracing(serviceName: string): void { ); provider.register(); - tracer = trace.getTracer(serviceName); + tracer = trace.getTracer(serviceName) as TracerLike; console.log(`OpenTelemetry tracing initialized for service: ${serviceName}`); } catch (error) { console.error("Failed to initialize OpenTelemetry tracing:", error); // Create a no-op tracer as fallback tracer = { - startActiveSpan: (name: string, fn: Function) => { + startActiveSpan: (name: string, fn: (span: SpanLike) => Promise | unknown) => { return fn({ setAttributes: () => {}, setStatus: () => {}, @@ -150,31 +176,31 @@ export function traceAction( fn: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise ): (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { return async (params, options) => { - if (!tracer || !tracer.startActiveSpan) { + if (tracer === null || tracer.startActiveSpan === undefined) { // Fallback if tracer is not available return fn(params, options); } - return tracer.startActiveSpan(`action.${name}`, async (span: any) => { + return tracer.startActiveSpan(`action.${name}`, async (span: SpanLike) => { try { const result = await fn(params, options); setSpanAttributes(span, name, "invokeaction", options, params, null, result); - if (span.setStatus) { + if (span.setStatus !== undefined) { span.setStatus({ code: SpanStatusCode.OK }); } return result; } catch (error) { setSpanAttributes(span, name, "invokeaction", options, params, error); - if (span.setStatus) { + if (span.setStatus !== undefined) { span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); } throw error; } finally { - if (span.end) { + if (span.end !== undefined) { span.end(); } } - }); + }) as Promise; }; } @@ -183,20 +209,29 @@ export function tracePropertyRead( fn: (options?: WoT.InteractionOptions) => Promise ): (options?: WoT.InteractionOptions) => Promise { return async (options) => { - return tracer.startActiveSpan(`property.read.${name}`, async (span: any) => { + if (tracer === null || tracer.startActiveSpan === undefined) { + return fn(options); + } + return tracer.startActiveSpan(`property.read.${name}`, async (span: SpanLike) => { try { const result = await fn(options); setSpanAttributes(span, name, "readproperty", options, undefined, null, result); - span.setStatus({ code: SpanStatusCode.OK }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.OK }); + } return result; } catch (error) { setSpanAttributes(span, name, "readproperty", options, undefined, error); - span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + } throw error; } finally { - span.end(); + if (span.end !== undefined) { + span.end(); + } } - }); + }) as Promise; }; } @@ -205,38 +240,57 @@ export function tracePropertyWrite( fn: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise ): (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise { return async (value, options) => { - return tracer.startActiveSpan(`property.write.${name}`, async (span: any) => { + if (tracer === null || tracer.startActiveSpan === undefined) { + return fn(value, options); + } + return tracer.startActiveSpan(`property.write.${name}`, async (span: SpanLike) => { try { await fn(value, options); setSpanAttributes(span, name, "writeproperty", options, value); - span.setStatus({ code: SpanStatusCode.OK }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.OK }); + } } catch (error) { setSpanAttributes(span, name, "writeproperty", options, value, error); - span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + } throw error; } finally { - span.end(); + if (span.end !== undefined) { + span.end(); + } } - }); + }) as Promise; }; } export function traceEvent( name: string, - fn: (data: any, options?: WoT.InteractionOptions) => void -): (data: any, options?: WoT.InteractionOptions) => void { + fn: (data: WoT.InteractionInput, options?: WoT.InteractionOptions) => void +): (data: WoT.InteractionInput, options?: WoT.InteractionOptions) => void { return (data, options) => { - tracer.startActiveSpan(`event.${name}`, async (span: any) => { + if (tracer === null || tracer.startActiveSpan === undefined) { + fn(data, options); + return; + } + tracer.startActiveSpan(`event.${name}`, async (span: SpanLike) => { try { fn(data, options); setSpanAttributes(span, name, "subscribeevent", options, data); - span.setStatus({ code: SpanStatusCode.OK }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.OK }); + } } catch (error) { setSpanAttributes(span, name, "subscribeevent", options, data, error); - span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + if (span.setStatus !== undefined) { + span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); + } throw error; } finally { - span.end(); + if (span.end !== undefined) { + span.end(); + } } }); }; @@ -246,29 +300,29 @@ export function traceEvent( export function createChildSpan( operationName: string, operation: () => Promise | T, - attributes?: Record + attributes?: Record ): Promise { - if (!tracer || !tracer.startActiveSpan) { + if (tracer === null || tracer.startActiveSpan === undefined) { return Promise.resolve(operation()); } - return tracer.startActiveSpan(operationName, async (span: any) => { + return tracer.startActiveSpan(operationName, async (span: SpanLike) => { try { // Add custom attributes if provided - if (attributes && span.setAttributes) { + if (attributes !== undefined && span.setAttributes !== undefined) { span.setAttributes(attributes); } const result = await operation(); - if (span.setStatus) { + if (span.setStatus !== undefined) { span.setStatus({ code: SpanStatusCode.OK }); } return result; } catch (error) { - if (span.setStatus) { + if (span.setStatus !== undefined) { span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); } - if (span.setAttributes) { + if (span.setAttributes !== undefined) { span.setAttributes({ "error.name": error instanceof Error ? error.name : "Error", "error.message": String(error), @@ -276,23 +330,23 @@ export function createChildSpan( } throw error; } finally { - if (span.end) { + if (span.end !== undefined) { span.end(); } } - }); + }) as Promise; } // Helper function to simulate database operations export function traceDatabaseOperation( operation: string, table: string, - operation_fn: () => Promise | T + operationFn: () => Promise | T ): Promise { - if (!tracer) { - return Promise.resolve(operation_fn()); + if (tracer === null) { + return Promise.resolve(operationFn()); } - return createChildSpan(`db.${operation}`, operation_fn, { + return createChildSpan(`db.${operation}`, operationFn, { "db.operation": operation, "db.table": table, "db.system": "memory", // Since we're using in-memory storage @@ -301,11 +355,15 @@ export function traceDatabaseOperation( } // Helper function to trace validation operations -export function traceValidation(validationType: string, data: any, validation_fn: () => Promise | T): Promise { - if (!tracer) { - return Promise.resolve(validation_fn()); +export function traceValidation( + validationType: string, + data: WoT.InteractionInput | null, + validationFn: () => Promise | T +): Promise { + if (tracer === null) { + return Promise.resolve(validationFn()); } - return createChildSpan(`validation.${validationType}`, validation_fn, { + return createChildSpan(`validation.${validationType}`, validationFn, { "validation.type": validationType, "validation.input": safeStringify(data), "span.kind": "internal", @@ -315,13 +373,13 @@ export function traceValidation(validationType: string, data: any, validation // Helper function to trace business logic operations export function traceBusinessLogic( operationName: string, - operation_fn: () => Promise | T, - metadata?: Record + operationFn: () => Promise | T, + metadata?: Record ): Promise { - if (!tracer) { - return Promise.resolve(operation_fn()); + if (tracer === null) { + return Promise.resolve(operationFn()); } - return createChildSpan(`business.${operationName}`, operation_fn, { + return createChildSpan(`business.${operationName}`, operationFn, { "business.operation": operationName, "span.kind": "internal", ...metadata, From 99f5db56ce7a1f81a40753cda3c4ea84bc3f726e Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 16:52:13 -0400 Subject: [PATCH 23/34] Fixed dependancy mismatch --- package-lock.json | 189 ++++++++++++++++++++-------------------------- package.json | 4 +- 2 files changed, 84 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6e5d1e..cacbf0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,10 +26,10 @@ "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.30.0", - "eslint-plugin-n": "^17.21.3", + "eslint-plugin-n": "^16.6.2", "eslint-plugin-node": "^11.1.0", "eslint-plugin-notice": "^1.0.0", - "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-promise": "^6.6.0", "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-workspaces": "^0.10.1", "mocha": "^10.7.3", @@ -2108,6 +2108,29 @@ "node": ">= 0.10.x" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, "node_modules/bulk-write-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", @@ -2900,20 +2923,6 @@ "once": "^1.4.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/error": { "version": "7.0.2", "dependencies": { @@ -3395,43 +3404,43 @@ } }, "node_modules/eslint-plugin-n": { - "version": "17.21.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.21.3.tgz", - "integrity": "sha512-MtxYjDZhMQgsWRm/4xYLL0i2EhusWT7itDxlJ80l1NND2AL2Vi5Mvneqv/ikG9+zpran0VsVRXTEHrpLmUZRNw==", + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.5.0", - "enhanced-resolve": "^5.17.1", - "eslint-plugin-es-x": "^7.8.0", - "get-tsconfig": "^4.8.1", - "globals": "^15.11.0", - "globrex": "^0.1.2", - "ignore": "^5.3.2", - "semver": "^7.6.3", - "ts-declaration-location": "^1.0.6" + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=16.0.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { - "eslint": ">=8.23.0" + "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/eslint-plugin-n/node_modules/ignore": { @@ -3444,6 +3453,19 @@ "node": ">= 4" } }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -3525,16 +3547,13 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz", - "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", "dev": true, "license": "ISC", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0" - }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4462,13 +4481,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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, - "license": "MIT" - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -4481,13 +4493,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4905,6 +4910,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -8035,16 +8056,6 @@ "node": ">=0.10.0" } }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -8143,42 +8154,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-declaration-location": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", - "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", - "dev": true, - "funding": [ - { - "type": "ko-fi", - "url": "https://ko-fi.com/rebeccastevens" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" - } - ], - "license": "BSD-3-Clause", - "dependencies": { - "picomatch": "^4.0.2" - }, - "peerDependencies": { - "typescript": ">=4.0.0" - } - }, - "node_modules/ts-declaration-location/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/ts-expect": { "version": "1.3.0", "license": "MIT" diff --git a/package.json b/package.json index 8f051fe..eeb9163 100644 --- a/package.json +++ b/package.json @@ -35,10 +35,10 @@ "eslint-config-prettier": "^9.1.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.30.0", - "eslint-plugin-n": "^17.21.3", + "eslint-plugin-n": "^16.6.2", "eslint-plugin-node": "^11.1.0", "eslint-plugin-notice": "^1.0.0", - "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-promise": "^6.6.0", "eslint-plugin-unused-imports": "^4.1.4", "eslint-plugin-workspaces": "^0.10.1", "mocha": "^10.7.3", From e69c3e7fdc22518a04fb766f711bfd866bc64dca Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 19 Aug 2025 16:59:00 -0400 Subject: [PATCH 24/34] Fixed hardcoded jeager endpoint --- .env | 1 + docker-compose-things-local.yml | 2 +- docker-compose-things.yml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 010f5bb..fdc5f95 100644 --- a/.env +++ b/.env @@ -13,6 +13,7 @@ COAP_SIMPLE_PORT_OUT=5683 COAP_NEGOTIATION_PORT_OUT=5684 SMART_HOME_SMART_CLOCK_PORT_OUT=5685 TRAEFIK_DASHBOARD_PORT_OUT=8080 +JAEGER_ENDPOINT=http://host.docker.internal:8085/api/traces STACK_HOSTNAME="plugfest.thingweb.io" BROKER_URI="plugfest.thingweb.io" diff --git a/docker-compose-things-local.yml b/docker-compose-things-local.yml index 6bac58a..ef48e6b 100644 --- a/docker-compose-things-local.yml +++ b/docker-compose-things-local.yml @@ -109,7 +109,7 @@ services: environment: - HOSTNAME=${STACK_HOSTNAME} - PORT=${WEB_PORT_OUT} - - JAEGER_ENDPOINT=http://host.docker.internal:8085/api/traces + - JAEGER_ENDPOINT=${JAEGER_ENDPOINT} networks: - things_network http-data-schema-thing: diff --git a/docker-compose-things.yml b/docker-compose-things.yml index e615bd4..885399e 100644 --- a/docker-compose-things.yml +++ b/docker-compose-things.yml @@ -149,7 +149,7 @@ services: environment: - HOSTNAME=${STACK_HOSTNAME} - PORT=${WEB_PORT_OUT} - - JAEGER_ENDPOINT=http://host.docker.internal:8085/api/traces + - JAEGER_ENDPOINT=${JAEGER_ENDPOINT} deploy: resources: limits: From 71d984f9f8ab2975c6caa9f07447ae455dc954e0 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 25 Aug 2025 22:16:20 -0400 Subject: [PATCH 25/34] Updated paths to make tracing in util --- docker-compose-things-local.yml | 4 +- package-lock.json | 49 +- package.json | 1 + .../http/ts/Dockerfile | 17 +- .../http/ts/src/main.ts | 607 +++++++++--------- .../http/ts/test/fixtures.ts | 1 + .../http/ts/test/td.test.ts | 1 + .../http/ts/test/fixtures.ts | 1 + .../data-schema-thing/http/ts/test/td.test.ts | 1 + .../http/ts/src => util}/auto-tracing.ts | 0 util/package.json | 51 ++ .../http/ts/src => util}/tracing.ts | 0 util/tsconfig.json | 9 +- util/util.ts | 75 ++- 14 files changed, 478 insertions(+), 339 deletions(-) rename {things/advanced-coffee-machine/http/ts/src => util}/auto-tracing.ts (100%) create mode 100644 util/package.json rename {things/advanced-coffee-machine/http/ts/src => util}/tracing.ts (100%) diff --git a/docker-compose-things-local.yml b/docker-compose-things-local.yml index ef48e6b..57b61df 100644 --- a/docker-compose-things-local.yml +++ b/docker-compose-things-local.yml @@ -101,8 +101,8 @@ services: - things_network http-advanced-coffee-machine: build: - context: ./things/advanced-coffee-machine - dockerfile: ./http/ts/Dockerfile + context: . + dockerfile: ./things/advanced-coffee-machine/http/ts/Dockerfile labels: - traefik.http.routers.http-advanced-coffee-machine.rule=PathPrefix(`/http-advanced-coffee-machine`) - traefik.http.services.http-advanced-coffee-machine.loadbalancer.server.port=${WEB_PORT_OUT} diff --git a/package-lock.json b/package-lock.json index cacbf0a..ca19f09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "name": "test-things", "license": "EPL-2.0 OR W3C-20150513", "workspaces": [ + "./util", "./mashups/*", "./things/*/*/*" ], @@ -36,6 +37,7 @@ "prettier": "3.3.3" } }, + "../util": {}, "mashups/smart-home": { "version": "1.0.0", "license": "EPL-2.0 OR W3C-20150513", @@ -8056,6 +8058,10 @@ "node": ">=0.10.0" } }, + "node_modules/test-things-util": { + "resolved": "util", + "link": true + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -8893,13 +8899,9 @@ "dependencies": { "@node-wot/binding-http": "0.8.16", "@node-wot/core": "0.8.16", - "@opentelemetry/api": "1.9.0", - "@opentelemetry/exporter-jaeger": "1.9.0", - "@opentelemetry/resources": "1.9.0", - "@opentelemetry/sdk-trace-node": "1.9.0", - "@opentelemetry/semantic-conventions": "1.9.0", "dotenv": "^16.4.5", "json-placeholder-replacer": "^2.0.5", + "test-things-util": "file:../../../../util", "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" }, "devDependencies": { @@ -8909,6 +8911,10 @@ "typescript": "^4.7.4" } }, + "things/advanced-coffee-machine/http/ts/node_modules/test-things-util": { + "resolved": "../util", + "link": true + }, "things/advanced-coffee-machine/http/ts/node_modules/wot-thing-description-types": { "version": "1.1.0-09-November-2023", "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", @@ -9272,6 +9278,39 @@ "jpr": "dist/index.js", "json-placeholder-replacer": "dist/index.js" } + }, + "util": { + "name": "test-things-util", + "version": "1.0.0", + "license": "EPL-2.0 OR W3C-20150513", + "dependencies": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/exporter-jaeger": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0", + "ajv": "^8.12.0", + "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" + }, + "devDependencies": { + "@types/node": "^22.1.0", + "typescript": "^4.7.4" + } + }, + "util/node_modules/wot-thing-description-types": { + "version": "1.1.0-09-November-2023", + "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", + "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", + "license": "W3C-20150513" + }, + "util/node_modules/wot-typescript-definitions": { + "version": "0.8.0-SNAPSHOT.29", + "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", + "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", + "license": "W3C-20150513", + "dependencies": { + "wot-thing-description-types": "1.1.0-09-November-2023" + } } } } diff --git a/package.json b/package.json index eeb9163..81cd36d 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "iot" ], "workspaces": [ + "./util", "./mashups/*", "./things/*/*/*" ], diff --git a/things/advanced-coffee-machine/http/ts/Dockerfile b/things/advanced-coffee-machine/http/ts/Dockerfile index ecca40a..068843f 100644 --- a/things/advanced-coffee-machine/http/ts/Dockerfile +++ b/things/advanced-coffee-machine/http/ts/Dockerfile @@ -1,13 +1,26 @@ FROM node:18-alpine WORKDIR /app -COPY ./advanced-coffee-machine.tm.json . -COPY ./http/ts . +# Copy package files first for better Docker layer caching +COPY ./things/advanced-coffee-machine/http/ts/package*.json ./ +# Copy util folder for tracing dependencies +COPY ./util ../util + +# Copy Thing Model and source files +COPY ./things/advanced-coffee-machine/advanced-coffee-machine.tm.json ./ +COPY ./things/advanced-coffee-machine/http/ts ./ + +# Build util package first +RUN cd ../util && npm install --legacy-peer-deps && npm run build + +# Install dependencies RUN npm install --legacy-peer-deps +# Build the project RUN npm run build +# Copy Thing Model to dist RUN cp ./advanced-coffee-machine.tm.json ./dist/ ENV TM_PATH="./advanced-coffee-machine.tm.json" diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 525ad79..89f9018 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -25,8 +25,10 @@ import { JsonPlaceholderReplacer } from "json-placeholder-replacer"; import { Servient } from "@node-wot/core"; import { HttpServer } from "@node-wot/binding-http"; import dotenv from "dotenv"; -import { initTracing, tracedEventHandler } from "./tracing"; -import { createAutoTracedThing, createTracedLogic } from "./auto-tracing"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency +import { initTracing, tracedEventHandler } from "../../../../../util/dist/tracing"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency +import { createAutoTracedThing, createTracedLogic } from "../../../../../util/dist/auto-tracing"; dotenv.config(); @@ -144,212 +146,232 @@ servient const tracedThing = createAutoTracedThing(thing); // Property: allAvailableResources - tracedThing.setPropertyReadHandler("allAvailableResources", "getAllResources", async (options) => { - const logic = createTracedLogic("getAllResources"); - - return await logic.execute(async () => { - // Validate resource data integrity - await logic.withValidation("resourceData", allAvailableResources, async () => { - const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; - for (const resource of requiredResources) { - if (!(resource in allAvailableResources)) { - throw new Error(`Missing required resource: ${resource}`); - } - if (typeof allAvailableResources[resource] !== "number") { - throw new Error(`Invalid resource level for ${resource}`); + tracedThing.setPropertyReadHandler( + "allAvailableResources", + "getAllResources", + async (options?: WoT.InteractionOptions) => { + const logic = createTracedLogic("getAllResources"); + + return await logic.execute(async () => { + // Validate resource data integrity + await logic.withValidation("resourceData", allAvailableResources, async () => { + const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; + for (const resource of requiredResources) { + if (!(resource in allAvailableResources)) { + throw new Error(`Missing required resource: ${resource}`); + } + if (typeof allAvailableResources[resource] !== "number") { + throw new Error(`Invalid resource level for ${resource}`); + } } - } - }); + }); - // Read sensor data for real-time validation - await logic.withProcessing( - "sensors.readAll", - async () => { - const readings: Record = {}; - for (const resource of Object.keys(allAvailableResources)) { - readings[resource] = readFromSensor(resource); + // Read sensor data for real-time validation + await logic.withProcessing( + "sensors.readAll", + async () => { + const readings: Record = {}; + for (const resource of Object.keys(allAvailableResources)) { + readings[resource] = readFromSensor(resource); + } + return readings; + }, + { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level", } - return readings; - }, - { - "sensor.count": Object.keys(allAvailableResources).length, - "sensor.type": "resource_level", - } - ); + ); - // Compare and sync with database - return await logic.withDatabase("select", "resource_levels", async () => { - return { ...allAvailableResources }; + // Compare and sync with database + return await logic.withDatabase("select", "resource_levels", async () => { + return { ...allAvailableResources }; + }); }); - }); - }); + } + ); // Property: possibleDrinks - tracedThing.setPropertyReadHandler("possibleDrinks", "getPossibleDrinks", async (options) => { - const logic = createTracedLogic("getPossibleDrinks"); + tracedThing.setPropertyReadHandler( + "possibleDrinks", + "getPossibleDrinks", + async (options?: WoT.InteractionOptions) => { + const logic = createTracedLogic("getPossibleDrinks"); + + return await logic.execute(async () => { + // Validate drink catalog integrity + await logic.withValidation("drinkCatalog", possibleDrinks, async () => { + if (!Array.isArray(possibleDrinks)) { + throw new Error("Drink catalog is corrupted"); + } + if (possibleDrinks.length === 0) { + throw new Error("No drinks available in catalog"); + } + }); - return await logic.execute(async () => { - // Validate drink catalog integrity - await logic.withValidation("drinkCatalog", possibleDrinks, async () => { - if (!Array.isArray(possibleDrinks)) { - throw new Error("Drink catalog is corrupted"); - } - if (possibleDrinks.length === 0) { - throw new Error("No drinks available in catalog"); - } - }); + // Load drink availability from database + const availabilityMap = await logic.withDatabase("select", "drink_availability", async () => { + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; + } + return availability; + }); - // Load drink availability from database - const availabilityMap = await logic.withDatabase("select", "drink_availability", async () => { - const availability: Record = {}; - for (const drink of possibleDrinks) { - availability[drink] = true; - } - return availability; + // Filter available drinks based on current resources + return await logic.withProcessing( + "processing.filterAvailableDrinks", + async () => { + return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); + }, + { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability", + } + ); }); - - // Filter available drinks based on current resources - return await logic.withProcessing( - "processing.filterAvailableDrinks", - async () => { - return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); - }, - { - "drinks.total": possibleDrinks.length, - "filtering.criteria": "resource_availability", - } - ); - }); - }); + } + ); // Property: maintenanceNeeded (simple read) tracedThing.setPropertyReadHandler( "maintenanceNeeded", "getMaintenanceStatus", - async (options) => maintenanceNeeded + async (options?: WoT.InteractionOptions) => maintenanceNeeded ); // Property Read: availableResourceLevel (with URI variables) - tracedThing.setPropertyReadHandler("availableResourceLevel", "getResourceLevel", async (options) => { - const logic = createTracedLogic("getResourceLevel"); - - return await logic.execute(async () => { - // Parse resource ID from URI variables - const resourceId = await logic.withProcessing( - "parsing.extractResourceId", - async () => { - const resourceId = (options?.uriVariables as Record)?.id; - if (!resourceId || !(resourceId in allAvailableResources)) { - throw new Error(`Invalid resource ID: ${resourceId}`); + tracedThing.setPropertyReadHandler( + "availableResourceLevel", + "getResourceLevel", + async (options?: WoT.InteractionOptions) => { + const logic = createTracedLogic("getResourceLevel"); + + return await logic.execute(async () => { + // Parse resource ID from URI variables + const resourceId = await logic.withProcessing( + "parsing.extractResourceId", + async () => { + const resourceId = (options?.uriVariables as Record)?.id; + if (!resourceId || !(resourceId in allAvailableResources)) { + throw new Error(`Invalid resource ID: ${resourceId}`); + } + return resourceId; + }, + { + "resource.id": (options?.uriVariables as Record)?.id ?? "unknown", + "parsing.operation": "resource_id_extraction", } - return resourceId; - }, - { - "resource.id": (options?.uriVariables as Record)?.id ?? "unknown", - "parsing.operation": "resource_id_extraction", - } - ); + ); - // Get resource level from database - return await logic.withDatabase("select", "resource_levels", async () => { - return allAvailableResources[resourceId]; + // Get resource level from database + return await logic.withDatabase("select", "resource_levels", async () => { + return allAvailableResources[resourceId]; + }); }); - }); - }); + } + ); // Property: schedules - tracedThing.setPropertyReadHandler("schedules", "getSchedules", async (options) => { - const logic = createTracedLogic("getSchedules"); + tracedThing.setPropertyReadHandler( + "schedules", + "getSchedules", + async (options?: WoT.InteractionOptions) => { + const logic = createTracedLogic("getSchedules"); + + return await logic.execute(async () => { + // Validate system state + await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { + if (!Array.isArray(schedules)) { + throw new Error("Schedules data structure is corrupted"); + } + }); - return await logic.execute(async () => { - // Validate system state - await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { - if (!Array.isArray(schedules)) { - throw new Error("Schedules data structure is corrupted"); - } - }); + // Load schedules from database + const result = await logic.withDatabase("select", "schedules", async () => { + return schedules; + }); - // Load schedules from database - const result = await logic.withDatabase("select", "schedules", async () => { - return schedules; + // Process and filter active schedules + return await logic.withProcessing( + "processing.filterActiveSchedules", + async () => { + return result.filter((schedule: unknown) => true); // For demo, all schedules are active + }, + { + "schedules.count": schedules.length, + "query.time": new Date().toISOString(), + } + ); }); - - // Process and filter active schedules - return await logic.withProcessing( - "processing.filterActiveSchedules", - async () => { - return result.filter((schedule: unknown) => true); // For demo, all schedules are active - }, - { - "schedules.count": schedules.length, - "query.time": new Date().toISOString(), - } - ); - }); - }); + } + ); // Property Write: servedCounter - tracedThing.setPropertyWriteHandler("servedCounter", "updateServedCounter", async (val) => { - const logic = createTracedLogic("updateServedCounter"); - - await logic.execute(async () => { - // Validate input - await logic.withValidation("counterInput", val, async () => { - if (val === null || val === undefined) { - throw new Error("No value provided for servedCounter"); - } - }); + tracedThing.setPropertyWriteHandler( + "servedCounter", + "updateServedCounter", + async (val: WoT.InteractionInput) => { + const logic = createTracedLogic("updateServedCounter"); - // Parse and validate the new counter value - const newCounterValue = await logic.withProcessing( - "parsing.extractCounterValue", - async () => { + await logic.execute(async () => { + // Validate input + await logic.withValidation("counterInput", val, async () => { if (val === null || val === undefined) { throw new Error("No value provided for servedCounter"); } - // Type guard and extraction for WoT InteractionInput - const value = await extractWoTValue(val); + }); - if (typeof value !== "number" || value < 0) { - throw new Error(`Invalid served counter value: ${value}`); + // Parse and validate the new counter value + const newCounterValue = await logic.withProcessing( + "parsing.extractCounterValue", + async () => { + if (val === null || val === undefined) { + throw new Error("No value provided for servedCounter"); + } + // Type guard and extraction for WoT InteractionInput + const value = await extractWoTValue(val); + + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); + } + return value; + }, + { + "input.type": typeof val, + "parsing.operation": "counter_extraction", } - return value; - }, - { - "input.type": typeof val, - "parsing.operation": "counter_extraction", - } - ); + ); - // Update counter in database - await logic.withDatabase("update", "counters", async () => { - servedCounter = newCounterValue; - }); + // Update counter in database + await logic.withDatabase("update", "counters", async () => { + servedCounter = newCounterValue; + }); - // Check maintenance threshold and trigger events if needed - await logic.withProcessing("business.checkMaintenanceThreshold", async () => { - if (servedCounter > 1000) { - // Update maintenance status - await logic.withDatabase("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); - - // Emit maintenance event - await logic.withProcessing("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); - } + // Check maintenance threshold and trigger events if needed + await logic.withProcessing("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await logic.withDatabase("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + + // Emit maintenance event + await logic.withProcessing("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data: WoT.InteractionInput) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); + } + }); }); - }); - }); + } + ); // Property Write: availableResourceLevel tracedThing.setPropertyWriteHandler( "availableResourceLevel", "updateResourceLevel", - async (val, options) => { + async (val: WoT.InteractionInput, options?: WoT.InteractionOptions) => { const logic = createTracedLogic("updateResourceLevel"); await logic.execute(async () => { @@ -412,7 +434,7 @@ servient // Emit low resource event await logic.withProcessing("event.lowResource", async () => { const eventData = `Low level of ${resourceId}: ${newLevel}%`; - tracedEventHandler("outOfResource", (data) => + tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => thing.emitEvent("outOfResource", data) )(eventData); }); @@ -423,141 +445,145 @@ servient ); // Action: makeDrink - tracedThing.setActionHandler("makeDrink", "makeDrink", async (params, options) => { - const logic = createTracedLogic("makeDrink"); - - return await logic.execute(async () => { - // Parse parameters with defaults - const { drinkId, size, quantity } = await logic.withProcessing( - "parsing.extractDrinkParameters", - async () => { - const uriVars = options?.uriVariables as Record | undefined; - const drinkId = (uriVars?.drinkId as string) ?? "americano"; - const size = (uriVars?.size as string) ?? "m"; - const quantity = (uriVars?.quantity as number) ?? 1; - return { drinkId, size, quantity }; - }, - { - "parsing.operation": "drink_parameters", - "defaults.applied": true, - } - ); + tracedThing.setActionHandler( + "makeDrink", + "makeDrink", + async (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { + const logic = createTracedLogic("makeDrink"); + + return await logic.execute(async () => { + // Parse parameters with defaults + const { drinkId, size, quantity } = await logic.withProcessing( + "parsing.extractDrinkParameters", + async () => { + const uriVars = options?.uriVariables as Record | undefined; + const drinkId = (uriVars?.drinkId as string) ?? "americano"; + const size = (uriVars?.size as string) ?? "m"; + const quantity = (uriVars?.quantity as number) ?? 1; + return { drinkId, size, quantity }; + }, + { + "parsing.operation": "drink_parameters", + "defaults.applied": true, + } + ); - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( - "select", - "recipes", - async () => { - // Define recipes and quantifiers (would come from database in real system) - const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; - const drinkRecipes: Record> = { - espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, - americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, - cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, - latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, - hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, - hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, - }; - return { drinkRecipes, sizeQuantifiers }; - } - ); + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( + "select", + "recipes", + async () => { + // Define recipes and quantifiers (would come from database in real system) + const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; + const drinkRecipes: Record> = { + espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, + americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, + cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, + latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, + hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, + hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, + }; + return { drinkRecipes, sizeQuantifiers }; + } + ); - // Validate drink availability - await logic.withValidation("drinkAvailability", drinkId, async () => { - if (drinkRecipes[drinkId] === undefined) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (sizeQuantifiers[size] === undefined) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); + // Validate drink availability + await logic.withValidation("drinkAvailability", drinkId, async () => { + if (drinkRecipes[drinkId] === undefined) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (sizeQuantifiers[size] === undefined) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); - // Get current resources - const currentResources = await logic.withDatabase("select", "resources", async () => { - return { ...allAvailableResources }; - }); + // Get current resources + const currentResources = await logic.withDatabase("select", "resources", async () => { + return { ...allAvailableResources }; + }); - // Calculate resource consumption - const newResources = await logic.withProcessing( - "calculate.resourceConsumption", - async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; + // Calculate resource consumption + const newResources = await logic.withProcessing( + "calculate.resourceConsumption", + async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); - return newResources; - }, - { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption", - } - ); + return newResources; + }, + { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption", + } + ); - // Validate resource availability and emit events if needed - await logic.withValidation("resourceAvailability", newResources, async () => { - const insufficientResources: string[] = []; - for (const [resource, level] of Object.entries(newResources)) { - if (level < 0) { - insufficientResources.push(resource); + // Validate resource availability and emit events if needed + await logic.withValidation("resourceAvailability", newResources, async () => { + const insufficientResources: string[] = []; + for (const [resource, level] of Object.entries(newResources)) { + if (typeof level === "number" && level < 0) { + insufficientResources.push(resource); + } } - } - if (insufficientResources.length > 0) { - // Emit outOfResource event before throwing error - await logic.withProcessing("event.outOfResource", async () => { - const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; - tracedEventHandler("outOfResource", (data) => thing.emitEvent("outOfResource", data))( - eventData - ); - }); + if (insufficientResources.length > 0) { + // Emit outOfResource event before throwing error + await logic.withProcessing("event.outOfResource", async () => { + const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; + tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); - throw new Error( - `Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)` - ); - } - }); + throw new Error( + `Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)` + ); + } + }); - // Update resources and increment counter - await logic.withDatabase("update", "all_resources", async () => { - Object.assign(allAvailableResources, newResources); - servedCounter += quantity; - }); + // Update resources and increment counter + await logic.withDatabase("update", "all_resources", async () => { + Object.assign(allAvailableResources, newResources); + servedCounter += quantity; + }); - // Simulate brewing process - await logic.withProcessing( - "brewing.process", - async () => { - // Simulate brewing time - await new Promise((resolve) => setTimeout(resolve, 1000)); - return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; - }, - { - "brewing.drink": drinkId, - "brewing.quantity": quantity, - "brewing.size": size, - "brewing.duration_ms": 1000, - } - ); + // Simulate brewing process + await logic.withProcessing( + "brewing.process", + async () => { + // Simulate brewing time + await new Promise((resolve) => setTimeout(resolve, 1000)); + return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; + }, + { + "brewing.drink": drinkId, + "brewing.quantity": quantity, + "brewing.size": size, + "brewing.duration_ms": 1000, + } + ); - return { - result: true, - message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, - }; - }); - }); + return { + result: true, + message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, + }; + }); + } + ); // Action: setSchedule - tracedThing.setActionHandler("setSchedule", "setSchedule", async (params) => { + tracedThing.setActionHandler("setSchedule", "setSchedule", async (params?: WoT.InteractionInput) => { const logic = createTracedLogic("setSchedule"); return await logic.execute(async () => { @@ -588,7 +614,12 @@ servient // Validate required fields and format await logic.withValidation("scheduleData", scheduleData, async () => { - if (!scheduleData.time || !scheduleData.mode) { + if ( + typeof scheduleData.time !== "string" || + scheduleData.time.length === 0 || + typeof scheduleData.mode !== "string" || + scheduleData.mode.length === 0 + ) { throw new Error("Time and mode are required for scheduling"); } diff --git a/things/advanced-coffee-machine/http/ts/test/fixtures.ts b/things/advanced-coffee-machine/http/ts/test/fixtures.ts index 48fedf5..2305582 100644 --- a/things/advanced-coffee-machine/http/ts/test/fixtures.ts +++ b/things/advanced-coffee-machine/http/ts/test/fixtures.ts @@ -14,6 +14,7 @@ ********************************************************************************/ import { ChildProcess } from "child_process"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency import { getInitiateMain, ThingStartResponse } from "../../../../../util/util"; import path from "path"; diff --git a/things/advanced-coffee-machine/http/ts/test/td.test.ts b/things/advanced-coffee-machine/http/ts/test/td.test.ts index aba33d0..3b0fda9 100644 --- a/things/advanced-coffee-machine/http/ts/test/td.test.ts +++ b/things/advanced-coffee-machine/http/ts/test/td.test.ts @@ -15,6 +15,7 @@ import * as chai from "chai"; import * as http from "http"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency import { getTDValidate } from "../../../../../util/util"; import { ValidateFunction } from "ajv"; import { port } from "./fixtures"; diff --git a/things/data-schema-thing/http/ts/test/fixtures.ts b/things/data-schema-thing/http/ts/test/fixtures.ts index 70d4341..9560980 100644 --- a/things/data-schema-thing/http/ts/test/fixtures.ts +++ b/things/data-schema-thing/http/ts/test/fixtures.ts @@ -14,6 +14,7 @@ ********************************************************************************/ import { ChildProcess } from "child_process"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency import { getInitiateMain, ThingStartResponse } from "../../../../../util/util"; import path from "path"; diff --git a/things/data-schema-thing/http/ts/test/td.test.ts b/things/data-schema-thing/http/ts/test/td.test.ts index 8c0d118..831af2d 100644 --- a/things/data-schema-thing/http/ts/test/td.test.ts +++ b/things/data-schema-thing/http/ts/test/td.test.ts @@ -15,6 +15,7 @@ import * as chai from "chai"; import * as http from "http"; +// eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency import { getTDValidate } from "../../../../../util/util"; import { ValidateFunction } from "ajv"; import { port } from "./fixtures"; diff --git a/things/advanced-coffee-machine/http/ts/src/auto-tracing.ts b/util/auto-tracing.ts similarity index 100% rename from things/advanced-coffee-machine/http/ts/src/auto-tracing.ts rename to util/auto-tracing.ts diff --git a/util/package.json b/util/package.json new file mode 100644 index 0000000..9d25458 --- /dev/null +++ b/util/package.json @@ -0,0 +1,51 @@ +{ + "name": "util", + "version": "1.0.0", + "description": "Shared utilities for Test Things project", + "main": "dist/util.js", + "exports": { + "./tracing": { + "types": "./dist/tracing.d.ts", + "default": "./dist/tracing.js" + }, + "./auto-tracing": { + "types": "./dist/auto-tracing.d.ts", + "default": "./dist/auto-tracing.js" + }, + ".": { + "types": "./dist/util.d.ts", + "default": "./dist/util.js" + } + }, + "types": "dist/util.d.ts", + "scripts": { + "build": "tsc -b", + "clean": "rm -rf dist", + "test": "echo \"No tests specified for util package\"", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write \"*.ts\" \"**/*.json\"" + }, + "keywords": [ + "wot", + "thing", + "iot", + "tracing", + "utilities" + ], + "author": "Eclipse Thingweb (https://thingweb.io/)", + "license": "EPL-2.0 OR W3C-20150513", + "dependencies": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", + "@opentelemetry/exporter-jaeger": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0", + "wot-typescript-definitions": "0.8.0-SNAPSHOT.29", + "ajv": "^8.12.0" + }, + "devDependencies": { + "@types/node": "^22.1.0", + "typescript": "^4.7.4" + } +} diff --git a/things/advanced-coffee-machine/http/ts/src/tracing.ts b/util/tracing.ts similarity index 100% rename from things/advanced-coffee-machine/http/ts/src/tracing.ts rename to util/tracing.ts diff --git a/util/tsconfig.json b/util/tsconfig.json index de67194..cfb318d 100644 --- a/util/tsconfig.json +++ b/util/tsconfig.json @@ -1,10 +1,11 @@ { "compilerOptions": { - "target": "es6", - "lib": ["dom"], - "skipLibCheck": false, + "target": "ES2020", + "lib": ["ES2020", "dom"], + "skipLibCheck": true, "module": "commonjs", "outDir": "dist", + "rootDir": ".", "strict": true, "composite": true, "incremental": true, @@ -18,7 +19,7 @@ "esModuleInterop": true, "moduleResolution": "node", "resolveJsonModule": false, - "skipDefaultLibCheck": false, + "skipDefaultLibCheck": true, "allowJs": false, "strictNullChecks": true, "forceConsistentCasingInFileNames": true diff --git a/util/util.ts b/util/util.ts index e448967..6149fc6 100644 --- a/util/util.ts +++ b/util/util.ts @@ -15,7 +15,8 @@ import Ajv, { ValidateFunction } from "ajv"; import * as https from "https"; -import { ChildProcess } from "node:child_process"; +import { IncomingMessage } from "http"; +import { ChildProcess, spawn } from "node:child_process"; export type ThingStartResponse = { process?: ChildProcess; @@ -27,18 +28,13 @@ export type ValidateResponse = { message: string; }; -const spawn = require("node:child_process").spawn; - export const getInitiateMain = (mainCmd: string, cmdArgs: string[]): Promise => { return new Promise((resolve, reject) => { const thingProcess = spawn(mainCmd, cmdArgs); // Avoids unsettled promise in case the promise is not settled in a second. const timeout = setTimeout(() => { - reject({ - process: thingProcess, - message: "Thing did not start as expected.", - }); + reject(new Error("Thing did not start as expected.")); }, 1000); thingProcess.stdout!.on("data", (data: Buffer) => { @@ -51,50 +47,53 @@ export const getInitiateMain = (mainCmd: string, cmdArgs: string[]): Promise { - reject({ - process: thingProcess, - message: `Error: ${data}`, - }); + reject(new Error(`Process stderr: ${data}`)); }); - thingProcess.on("error", (error: any) => { - reject({ - process: thingProcess, - message: `Error: ${error}`, - }); + thingProcess.on("error", (error: Error) => { + reject(new Error(`Process error: ${error.message}`)); }); thingProcess.on("close", () => { - reject({ - process: thingProcess, - message: "Failed to initiate the main script.", - }); + reject(new Error("Failed to initiate the main script.")); }); }); }; const ajv = new Ajv({ strict: false, allErrors: true, validateFormats: false }); +const getTDJSONSchema = new Promise>((resolve, reject) => { + https + .get( + "https://raw.githubusercontent.com/w3c/wot-thing-description/main/validation/td-json-schema-validation.json", + function (response: IncomingMessage) { + const body: Buffer[] = []; + response.on("data", (chunk: Buffer) => { + body.push(chunk); + }); + + response.on("end", () => { + try { + const tdSchema = JSON.parse(Buffer.concat(body).toString()) as Record; + resolve(tdSchema); + } catch (error) { + reject(new Error(`Failed to parse TD schema: ${error}`)); + } + }); + + response.on("error", (error: Error) => { + reject(new Error(`HTTP request failed: ${error.message}`)); + }); + } + ) + .on("error", (error: Error) => { + reject(new Error(`HTTP request failed: ${error.message}`)); + }); +}); + export const getTDValidate = async (): Promise => { - const tdSchema: any = await getTDJSONSchema; + const tdSchema: Record = await getTDJSONSchema; return Promise.resolve({ validate: ajv.compile(tdSchema), message: "Success", }); }; - -const getTDJSONSchema = new Promise((resolve, reject) => { - https.get( - "https://raw.githubusercontent.com/w3c/wot-thing-description/main/validation/td-json-schema-validation.json", - function (response: any) { - const body: Buffer[] = []; - response.on("data", (chunk: Buffer) => { - body.push(chunk); - }); - - response.on("end", () => { - const tdSchema = JSON.parse(Buffer.concat(body).toString()); - resolve(tdSchema); - }); - } - ); -}); From 780c89968c19653cee288e56291b3d33645ea66c Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 25 Aug 2025 22:25:46 -0400 Subject: [PATCH 26/34] Fixed counter thing --- docker-compose-things-local.yml | 2 +- things/counter-thing/http/ts/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose-things-local.yml b/docker-compose-things-local.yml index 57b61df..374365b 100644 --- a/docker-compose-things-local.yml +++ b/docker-compose-things-local.yml @@ -129,7 +129,7 @@ services: counter-thing: build: context: ./things/counter-thing - dockerfile: Dockerfile + dockerfile: ./http/ts/Dockerfile labels: - traefik.http.routers.counter-thing.rule=PathPrefix(`/counter-thing`) - traefik.http.services.counter-thing.loadbalancer.server.port=${WEB_PORT_OUT} diff --git a/things/counter-thing/http/ts/Dockerfile b/things/counter-thing/http/ts/Dockerfile index b45f7bd..825e80f 100644 --- a/things/counter-thing/http/ts/Dockerfile +++ b/things/counter-thing/http/ts/Dockerfile @@ -3,13 +3,13 @@ FROM node:18-alpine WORKDIR /app # Copy package files -COPY package*.json ./ +COPY ./http/ts/package*.json ./ # Install dependencies RUN npm install # Copy source code -COPY . . +COPY ./http/ts . # Build TypeScript RUN npm run build From 705329250de0fc2f683251e8e3bd830f50c9ad88 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Tue, 26 Aug 2025 12:24:20 -0400 Subject: [PATCH 27/34] Updated loc file --- package-lock.json | 1539 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 1302 insertions(+), 237 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca19f09..e85bb8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "prettier": "3.3.3" } }, - "../util": {}, "mashups/smart-home": { "version": "1.0.0", "license": "EPL-2.0 OR W3C-20150513", @@ -57,8 +56,6 @@ }, "mashups/smart-home/node_modules/@types/node": { "version": "18.19.120", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.120.tgz", - "integrity": "sha512-WtCGHFXnVI8WHLxDAt5TbnCM4eSE+nI0QN2NJtwzcgMhht2eNz6V9evJrk+lwC8bCY8OWV5Ym8Jz7ZEyGnKnMA==", "dev": true, "license": "MIT", "dependencies": { @@ -67,15 +64,13 @@ }, "mashups/smart-home/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -114,6 +109,37 @@ "kuler": "^2.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", + "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", + "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", + "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -239,6 +265,7 @@ "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -292,6 +319,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true, "license": "BSD-3-Clause" }, @@ -306,9 +334,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, @@ -329,10 +357,42 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "license": "MIT" }, + "node_modules/@napi-rs/snappy-android-arm-eabi": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm-eabi/-/snappy-android-arm-eabi-7.3.2.tgz", + "integrity": "sha512-fX0+uNXt+tIqxjUUKh3uekIz5jW7rKsFVCZb/OR1+u5u8XCR28RcMTucMTjhcmMibg0PvYRZLxbICuP1Wx1UWQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-android-arm64": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-android-arm64/-/snappy-android-arm64-7.3.2.tgz", + "integrity": "sha512-FlN/GGHkQa2SB8y+LXhJky8U133MJb6jqikYgmjQjHRwElB+/5pTtMqLQg2pwJ/70ISAxN5Ct9JlaHadp6Rs+A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@napi-rs/snappy-darwin-arm64": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.3.0.tgz", - "integrity": "sha512-shU1IOgMJRBLxqNvuqRvIr3lP8i2q/UJiwHfkipN05wzjlLN327ej0E98TarsfDgn8SDX92ovsc6zVfb4bhHbg==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-arm64/-/snappy-darwin-arm64-7.3.2.tgz", + "integrity": "sha512-2j5cHSb34BdnQxBITdXa4NkbPrVc00yI/8BT0laD29Qm7nTXKoUNKYEpD8KYV3IvP2UxFDK7n0nMRqhuo2+fug==", "cpu": [ "arm64" ], @@ -345,6 +405,258 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/snappy-darwin-x64": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-darwin-x64/-/snappy-darwin-x64-7.3.2.tgz", + "integrity": "sha512-1Har7sh2PMZE8L5hWhuVQMQKmFZwJiSUoCzhCvhKIB983Ei+obqXWewrhxoaShc3fYrc4YS9hXnnLoFCDLzH1g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-freebsd-x64": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-freebsd-x64/-/snappy-freebsd-x64-7.3.2.tgz", + "integrity": "sha512-oNc4JG+yCAEVRy8e6vKAYJsJpyrXQGl7q4JqX981FRTBGYUISwR4pNgYsBypOj8SUFRYoS/FdG61/ptyh00Hbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm-gnueabihf": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm-gnueabihf/-/snappy-linux-arm-gnueabihf-7.3.2.tgz", + "integrity": "sha512-CUOPVs/bCRKghcpsuxw6/t0BnVV25ZRDXC9qQSuR+KSEbXrQPahDuWyJIvI7KM70P1s2lvmdK4WXWag/tl5Y4A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm64-gnu": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-gnu/-/snappy-linux-arm64-gnu-7.3.2.tgz", + "integrity": "sha512-AKqTWTHzw4DIrzA/qQkUozFfQTMQlYbm2WjFfrzebcRB8+o8BpffyUbvqDS/HsOHw9L53x+jqMFOAAjU5rECvg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-arm64-musl": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-arm64-musl/-/snappy-linux-arm64-musl-7.3.2.tgz", + "integrity": "sha512-rUhajSc4PgFZ2DkG3CTOke7LfoQylkKF4uV90DgedbKUjXI61henWSe8I8XhzJEcrpmBFz3udmihJaj172+2iw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-ppc64-gnu": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-ppc64-gnu/-/snappy-linux-ppc64-gnu-7.3.2.tgz", + "integrity": "sha512-3BqNK9nhBIoUeUeOgY3W/99ArChbKzzHjj4vD0kbkk7eADBatcGTxUzrSIhULlH9vifF28thQQeCu0q/EfpU3A==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-riscv64-gnu": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-riscv64-gnu/-/snappy-linux-riscv64-gnu-7.3.2.tgz", + "integrity": "sha512-dvlKU473USFBpIZoJ1eUFGj90LNzv6SvkY3bJZ1c0BKRTvEJ9DRNIjmdN+bHCZznwxn2UrR1Tv2MWqMM0Ww/cQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-s390x-gnu": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-s390x-gnu/-/snappy-linux-s390x-gnu-7.3.2.tgz", + "integrity": "sha512-+cNweOf2Z7FC7AyFdrX2L8sCoNx34fc2QGsEBtTQ7H2nj6K2byxcIs1pWT7tPrrBFk24SMw2DtgDf+fUtat1/g==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-x64-gnu": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-gnu/-/snappy-linux-x64-gnu-7.3.2.tgz", + "integrity": "sha512-eW1uzodlmb0RitoP1I4xVGRqE50WUOB5T2G6GPceqlwXLs1UzgSpgwZuNbQ7LbRyXI7jK897ukeBBkVOIvhkoQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-linux-x64-musl": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-linux-x64-musl/-/snappy-linux-x64-musl-7.3.2.tgz", + "integrity": "sha512-WBmgzN4P6SmKXUxy936Jz2r+sKwHqqosZIxOg8QLJNoIr72eCmoINaolg6AuVCyuPUb9tc2GdPwag4p27gTIOQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-openharmony-arm64": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-openharmony-arm64/-/snappy-openharmony-arm64-7.3.2.tgz", + "integrity": "sha512-iZwgBJ8cz79UgBO5eoojObIYV2mKpjF2aGSlixB3R9QJfRaNPeACTShYcd8Bc5QheSPcJjqTswiI/7xIFdcDDw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-wasm32-wasi": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-wasm32-wasi/-/snappy-wasm32-wasi-7.3.2.tgz", + "integrity": "sha512-ChdMipqIoFg5ysLciGJ5wLoSsXQMo7Zh8+35du4aEO/vrxVyZ12UMyv6+zEn8sBCrY+3e9A+2YOpryZP2BfKiQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@napi-rs/snappy-win32-arm64-msvc": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-arm64-msvc/-/snappy-win32-arm64-msvc-7.3.2.tgz", + "integrity": "sha512-RAmh06bNKk5wHoOfX6wkFo8FZBKNkSH5J9Q4O648uZpXorf8ZaVQKSpIQaXTZICBVF6+2540FjYGctvhL1b4yw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-win32-ia32-msvc": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-ia32-msvc/-/snappy-win32-ia32-msvc-7.3.2.tgz", + "integrity": "sha512-OP8ySMUm9EEtihDbgqXCcvPFLcD3iAZhy+fZ7sSQhRQHqRxJ4dfAl98Eaec1nIK63pg/FNKJqTHZfCgnmUSL8g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/snappy-win32-x64-msvc": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.3.2.tgz", + "integrity": "sha512-fqPHzNVFy5Wrg/U91dsafIaZ6thTyRcK1xU8KLw384MRkaTI3HA4cs66Om8l33P0gHhnvUZOSlvjJEjEXyAH0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.3.tgz", + "integrity": "sha512-rZxtMsLwjdXkMUGC3WwsPwLNVqVqnTJT6MNIB6e+5fhMcSCPP0AOsNWuMQ5mdCq6HNjs/ZeWAEchpqeprqBD2Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@node-wot/binding-coap": { "version": "0.8.16", "resolved": "https://registry.npmjs.org/@node-wot/binding-coap/-/binding-coap-0.8.16.tgz", @@ -384,6 +696,8 @@ }, "node_modules/@node-wot/binding-http": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/binding-http/-/binding-http-0.8.16.tgz", + "integrity": "sha512-PqpjyEcJt1apjWpObtctPfQ+iK2FAf5IHrwESiMHL0fdGtbA1/tw0KZdC8/krZK7DtI+WvY+fnajdvS0MAqhvw==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@node-wot/core": "0.8.16", @@ -440,6 +754,8 @@ }, "node_modules/@node-wot/core": { "version": "0.8.16", + "resolved": "https://registry.npmjs.org/@node-wot/core/-/core-0.8.16.tgz", + "integrity": "sha512-viHaXIeIryx+sm0H8oBnR5mUSTFj9raWaJYCNa/BGphfOUhcOB5pajS5NOJcQUzSy76Z9XY3JMw3taRAuPTvsw==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@petamoriken/float16": "^3.1.1", @@ -496,6 +812,8 @@ }, "node_modules/@opentelemetry/api": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", "engines": { "node": ">=8.0.0" @@ -503,6 +821,8 @@ }, "node_modules/@opentelemetry/context-async-hooks": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.9.0.tgz", + "integrity": "sha512-Ur+TgRmJgAEvg6VQuhkqzsWsqoOtr+QSZ8r8Yf6WrvlZpAl/sdRU+yUXWjA7r8JFS9VbBq7IEp7oMStFuJT2ow==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -513,6 +833,8 @@ }, "node_modules/@opentelemetry/core": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.9.0.tgz", + "integrity": "sha512-Koy1ApRUp5DB5KpOqhDk0JjO9x6QeEkmcePl8qQDsXZGF4MuHUBShXibd+J2tRNckTsvgEHi1uEuUckDgN+c/A==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "1.9.0" @@ -526,6 +848,8 @@ }, "node_modules/@opentelemetry/exporter-jaeger": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-jaeger/-/exporter-jaeger-1.9.0.tgz", + "integrity": "sha512-XLsDLuTqQyw08s0n03zeqmz2ike/iQHiep819SJliJnJJKMbGta+JvaWWgrh/YUEYlbBLc/mQP1cndXtd8lbaA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.9.0", @@ -542,6 +866,8 @@ }, "node_modules/@opentelemetry/propagator-b3": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.9.0.tgz", + "integrity": "sha512-5M/NvJj7ZHZXEU8lkAFhrSrWaHmCCkFLstNbL8p16qpTn1AOZowuSjMOYRoJJBmL5PUobkZ3W8Gjov1UgldPBg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.9.0" @@ -555,6 +881,8 @@ }, "node_modules/@opentelemetry/propagator-jaeger": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.9.0.tgz", + "integrity": "sha512-oo8RyuyzEbbXdIfeEG9iA5vmTH4Kld+dZMIZICd5G5SmeNcNes3sLrparpunIGms41wIP2mWiIlcOelDCmGceg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.9.0" @@ -568,6 +896,8 @@ }, "node_modules/@opentelemetry/resources": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.9.0.tgz", + "integrity": "sha512-zCyien0p3XWarU6zv72c/JZ6QlG5QW/hc61Nh5TSR1K9ndnljzAGrH55x4nfyQdubfoh9QxLNh9FXH0fWK6vcg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.9.0", @@ -582,6 +912,8 @@ }, "node_modules/@opentelemetry/sdk-trace-base": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.9.0.tgz", + "integrity": "sha512-glNgtJjxAIrDku8DG5Xu3nBK25rT+hkyg7yuXh8RUurp/4BcsXjMyVqpyJvb2kg+lxAX73VJBhncRKGHn9t8QQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "1.9.0", @@ -597,6 +929,8 @@ }, "node_modules/@opentelemetry/sdk-trace-node": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.9.0.tgz", + "integrity": "sha512-VTpjiqGQ4s8f0/szgZmVrtNSSmXFNoHwC4PNVwXyNeEqQcqyAygHvobpUG6m7qCiBFh6ZtrCuLdhhqWE04Objw==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/context-async-hooks": "1.9.0", @@ -615,6 +949,8 @@ }, "node_modules/@opentelemetry/semantic-conventions": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.9.0.tgz", + "integrity": "sha512-po7penSfQ/Z8352lRVDpaBrd9znwA5mHGqXR7nDEiVnxkDFkBIhVf/tKeAJDIq/erFpcRowKFeCsr5eqqcSyFQ==", "license": "Apache-2.0", "engines": { "node": ">=14" @@ -622,6 +958,8 @@ }, "node_modules/@petamoriken/float16": { "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz", + "integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==", "license": "MIT" }, "node_modules/@protobufjs/aspromise": { @@ -948,10 +1286,14 @@ }, "node_modules/@servie/events": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@servie/events/-/events-1.0.0.tgz", + "integrity": "sha512-sBSO19KzdrJCM3gdx6eIxV8M9Gxfgg6iDQmH5TIAGaUu+X9VDdsINXJOnoiZ1Kx3TrHdH4bt5UVglkjsEGBcvw==", "license": "MIT" }, "node_modules/@thingweb/thing-model": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@thingweb/thing-model/-/thing-model-1.0.4.tgz", + "integrity": "sha512-09oa2VVG2yGTXCKbXco25t5bQ5n/BG+BPhKoR/IZrEKLJVPbml20Y9VZusscTTRNxYR2VBrFdON+WhomtIRrdg==", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "ajv": "^8.11.0", @@ -965,6 +1307,8 @@ }, "node_modules/@thingweb/thing-model/node_modules/ajv-formats": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -1006,6 +1350,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -1056,6 +1410,8 @@ }, "node_modules/@types/eventsource": { "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@types/eventsource/-/eventsource-1.1.10.tgz", + "integrity": "sha512-rYzRmJSnm44Xb7FICRXEjwe/26ZiiS+VMGmuD17PevMP56cGgLEsaM955sYQW0S+K7h+mPOL70vGf1hi4WDjVA==", "license": "MIT" }, "node_modules/@types/express": { @@ -1120,21 +1476,23 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.16.5", + "version": "22.18.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.0.tgz", + "integrity": "sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" } }, "node_modules/@types/qs": { @@ -1185,6 +1543,8 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "license": "MIT" }, "node_modules/@types/triple-beam": { @@ -1203,17 +1563,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", - "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz", + "integrity": "sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/type-utils": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/type-utils": "8.41.0", + "@typescript-eslint/utils": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1227,22 +1587,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.38.0", + "@typescript-eslint/parser": "^8.41.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", - "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.41.0.tgz", + "integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "debug": "^4.3.4" }, "engines": { @@ -1254,18 +1614,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", - "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.41.0.tgz", + "integrity": "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.38.0", - "@typescript-eslint/types": "^8.38.0", + "@typescript-eslint/tsconfig-utils": "^8.41.0", + "@typescript-eslint/types": "^8.41.0", "debug": "^4.3.4" }, "engines": { @@ -1276,18 +1636,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", - "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", + "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0" + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1298,9 +1658,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", - "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz", + "integrity": "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==", "dev": true, "license": "MIT", "engines": { @@ -1311,19 +1671,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", - "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz", + "integrity": "sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/utils": "8.41.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -1336,13 +1696,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", - "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", + "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", "dev": true, "license": "MIT", "engines": { @@ -1354,16 +1714,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", - "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", + "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.38.0", - "@typescript-eslint/tsconfig-utils": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/project-service": "8.41.0", + "@typescript-eslint/tsconfig-utils": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1379,20 +1739,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", - "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", + "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0" + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1403,17 +1763,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", - "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", + "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/types": "8.41.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -1458,6 +1818,8 @@ }, "node_modules/accept-language-parser": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==", "license": "MIT" }, "node_modules/accepts": { @@ -1621,6 +1983,8 @@ }, "node_modules/ajv": { "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -1635,6 +1999,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -1649,7 +2015,12 @@ } }, "node_modules/ansi-color": { - "version": "0.2.1" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-color/-/ansi-color-0.2.1.tgz", + "integrity": "sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ==", + "engines": { + "node": "*" + } }, "node_modules/ansi-colors": { "version": "4.1.3", @@ -1665,7 +2036,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -1701,6 +2072,58 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "license": "ISC", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -1929,6 +2352,8 @@ }, "node_modules/basic-auth": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" @@ -1950,10 +2375,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.0.tgz", - "integrity": "sha512-ClDyJGQkc8ZtzdAAbAwBmhMSpwN/sC9HA8jxdYm6nVUbCfZbe2mgza4qh7AuEYyEPB/c4Kznf9s66bnsKMQDjw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-6.1.2.tgz", + "integrity": "sha512-6J3oG82fpJ71WF4l0W6XslkwAPMr+Zcp+AmdxJ0L8LsXNzFeO8GYesV2J9AzGArBjrsb2xR50Ocbn/CL1B44TA==", "license": "MIT", "dependencies": { "@types/readable-stream": "^4.0.0", @@ -2049,6 +2484,18 @@ "node": ">=8" } }, + "node_modules/broker-factory": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.9.tgz", + "integrity": "sha512-MzvndyD6EcbkBtX4NXm/HfdO1+cOR5ONNdMCXEKfHpxGdMtuDz7+o+nJf7HMtyPH1sUVf/lEIP+DMluC5PgaBQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1", + "worker-factory": "^7.0.45" + } + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2100,6 +2547,8 @@ }, "node_modules/bufrw": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/bufrw/-/bufrw-1.4.0.tgz", + "integrity": "sha512-sWm8iPbqvL9+5SiYxXH73UOkyEbGQg7kyHQmReF89WJHQJw2eV4P/yZ0E+b71cczJ4pPobVhXxgQcmfSTgGHxQ==", "dependencies": { "ansi-color": "^0.2.1", "error": "^7.0.0", @@ -2145,6 +2594,8 @@ }, "node_modules/byte-length": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/byte-length/-/byte-length-1.0.2.tgz", + "integrity": "sha512-ovBpjmsgd/teRmgcPh23d4gJvxDoXtAzEL9xTfMU8Yc2kqCDb7L9jAG0XHl1nzuGl+h3ebCIF1i62UFyA9V/2Q==", "license": "MIT" }, "node_modules/bytes": { @@ -2235,6 +2686,8 @@ }, "node_modules/cbor": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "license": "MIT", "dependencies": { "nofilter": "^3.1.0" @@ -2343,8 +2796,17 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC", + "optional": true + }, "node_modules/client-oauth2": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/client-oauth2/-/client-oauth2-4.3.3.tgz", + "integrity": "sha512-k8AvUYJon0vv75ufoVo4nALYb/qwFFicO3I0+39C6xEdflqVtr+f9cy+0ZxAduoVSTfhP5DX2tY2XICAd5hy6Q==", "license": "Apache-2.0", "dependencies": { "popsicle": "^12.0.5", @@ -2356,6 +2818,8 @@ }, "node_modules/client-oauth2/node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -2441,6 +2905,16 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/color": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", @@ -2552,6 +3026,13 @@ "dev": true, "license": "MIT" }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC", + "optional": true + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -2586,6 +3067,8 @@ }, "node_modules/content-type": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -2711,6 +3194,8 @@ }, "node_modules/debug": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2739,11 +3224,26 @@ }, "node_modules/decode-uri-component": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "license": "MIT", "engines": { "node": ">=0.10" } }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/deep-eql": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", @@ -2757,6 +3257,16 @@ "node": ">=6" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2810,6 +3320,13 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT", + "optional": true + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2829,6 +3346,19 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", @@ -2866,6 +3396,8 @@ }, "node_modules/dotenv": { "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -2898,7 +3430,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/enabled": { @@ -2927,6 +3459,8 @@ }, "node_modules/error": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==", "dependencies": { "string-template": "~0.2.1", "xtend": "~4.0.0" @@ -3111,6 +3645,7 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { @@ -3565,9 +4100,9 @@ } }, "node_modules/eslint-plugin-unused-imports": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", - "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.2.0.tgz", + "integrity": "sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -3797,11 +4332,23 @@ }, "node_modules/eventsource": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", "license": "MIT", "engines": { "node": ">=12.0.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -3885,10 +4432,14 @@ }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", + "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { @@ -3937,26 +4488,30 @@ }, "node_modules/fast-querystring": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", + "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "node_modules/fast-unique-numbers": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", - "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", + "version": "9.0.23", + "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.23.tgz", + "integrity": "sha512-jcRIaHo46nfvyvKRMaFSKXmez4jALQ3Qw49gxM5F4siz8HqkyKPPEexpCOYwBSJI1HovrDr4fEedM8QAJ7oX3w==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.8", - "tslib": "^2.6.2" + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.1.0" + "node": ">=18.2.0" } }, "node_modules/fast-uri": { - "version": "3.0.6", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -4026,6 +4581,13 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT", + "optional": true + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4041,6 +4603,8 @@ }, "node_modules/filter-obj": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4081,6 +4645,8 @@ }, "node_modules/find-my-way": { "version": "7.7.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.7.0.tgz", + "integrity": "sha512-+SrHpvQ52Q6W9f3wJoJBbAQULJuNEEQwBvlvYwACDhBTLOTMiQ0HYWh4+vC3OivGP2ENcTI1oKlFA2OepJNjhQ==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4256,6 +4822,13 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT", + "optional": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4267,6 +4840,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -4285,35 +4859,104 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", - "dev": true, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "license": "MIT", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "license": "MIT", + "optional": true, "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/get-caller-file": { @@ -4404,10 +5047,18 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT", + "optional": true + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -4582,6 +5233,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC", + "optional": true + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4612,6 +5270,8 @@ }, "node_modules/hexer": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hexer/-/hexer-1.5.0.tgz", + "integrity": "sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==", "dependencies": { "ansi-color": "^0.2.1", "minimist": "^1.1.0", @@ -4766,6 +5426,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -4778,6 +5439,13 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC", + "optional": true + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -4794,14 +5462,10 @@ } }, "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, "engines": { "node": ">= 12" } @@ -4817,6 +5481,8 @@ }, "node_modules/is-absolute-url": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "license": "MIT", "engines": { "node": ">=8" @@ -5022,7 +5688,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -5319,6 +5985,8 @@ }, "node_modules/jaeger-client": { "version": "3.19.0", + "resolved": "https://registry.npmjs.org/jaeger-client/-/jaeger-client-3.19.0.tgz", + "integrity": "sha512-M0c7cKHmdyEUtjemnJyx/y9uX16XHocL46yQvyqDlPdvAcwPDbHrIbKjQdBqtiE4apQ/9dmr+ZLJYYPGnurgpw==", "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0", @@ -5333,6 +6001,8 @@ }, "node_modules/jaeger-client/node_modules/uuid": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -5361,12 +6031,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -5376,6 +6040,8 @@ }, "node_modules/json-placeholder-replacer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/json-placeholder-replacer/-/json-placeholder-replacer-2.1.2.tgz", + "integrity": "sha512-C4/IPS34x4YKxhrvTBzDf6+Akn/vgRW3QKvzljWm3KLK2mQhBnNYYwXrin+knp7tF7mxmDW7NIMdSPVT33vN0g==", "license": "MIT", "bin": { "jpr": "dist/index.js", @@ -5384,6 +6050,8 @@ }, "node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -5502,6 +6170,8 @@ }, "node_modules/long": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/long/-/long-2.4.0.tgz", + "integrity": "sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==", "license": "Apache-2.0", "engines": { "node": ">=0.6" @@ -5528,10 +6198,14 @@ }, "node_modules/make-error": { "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "license": "ISC" }, "node_modules/make-error-cause": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-2.3.0.tgz", + "integrity": "sha512-etgt+n4LlOkGSJbBTV9VROHA5R7ekIPS4vfh+bCAoJgRrJWdqJCBbpS3osRJ/HrT7R68MzMiY3L3sDJ/Fd8aBg==", "license": "Apache-2.0", "dependencies": { "make-error": "^1.3.5" @@ -5637,6 +6311,19 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -5655,22 +6342,31 @@ }, "node_modules/minimist": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT", + "optional": true + }, "node_modules/mlly": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", - "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.14.0", - "pathe": "^2.0.1", - "pkg-types": "^1.3.0", - "ufo": "^1.5.4" + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" } }, "node_modules/mocha": { @@ -6256,16 +6952,16 @@ } }, "node_modules/mqtt": { - "version": "5.13.3", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.3.tgz", - "integrity": "sha512-91x03kh1+vBBA51OMNbEw2fymXfaUjpHkC0NcMckg9Vf6ee/GrM/HXfE8XeeziHQpJL8adr+9ThTbN5v/WmrRA==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.14.0.tgz", + "integrity": "sha512-H7EmeCJhbGblbWjm6APF5sAH3SkdI7lxHw/UkblZp8fjSNl8b2MsLcdAkIaQKxvZYmiORkdAjffvKjqQWPkd6w==", "license": "MIT", "dependencies": { - "@types/readable-stream": "^4.0.18", + "@types/readable-stream": "^4.0.21", "@types/ws": "^8.18.1", "commist": "^3.2.0", "concat-stream": "^2.0.0", - "debug": "^4.4.0", + "debug": "^4.4.1", "help-me": "^5.0.0", "lru-cache": "^10.4.3", "minimist": "^1.2.8", @@ -6273,10 +6969,10 @@ "number-allocator": "^1.0.14", "readable-stream": "^4.7.0", "rfdc": "^1.4.1", - "socks": "^2.8.3", + "socks": "^2.8.6", "split2": "^4.2.0", - "worker-timers": "^7.1.8", - "ws": "^8.18.0" + "worker-timers": "^8.0.23", + "ws": "^8.18.3" }, "bin": { "mqtt": "build/bin/mqtt.js", @@ -6381,6 +7077,8 @@ }, "node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { @@ -6396,6 +7094,20 @@ "multicast-dns": "cli.js" } }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "license": "MIT", + "optional": true + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6412,12 +7124,48 @@ "node": ">= 0.6" } }, + "node_modules/node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/node-addon-api": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "license": "MIT" }, + "node_modules/node-aead-crypto": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/node-aead-crypto/-/node-aead-crypto-2.2.2.tgz", + "integrity": "sha512-EtCLL1FmVjj2GlBNcLRn75ea+y6yGuEdoTpqc9zIiRkIKk1ucTsOPoKaHYYxHfMAXWqHu2Dw8a44VSSKz45UTg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "2.14.x", + "prebuild-install": "^6.1.3" + }, + "engines": { + "node": ">4" + } + }, "node_modules/node-coap-client": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/node-coap-client/-/node-coap-client-1.0.8.tgz", @@ -6449,6 +7197,8 @@ }, "node_modules/node-fetch": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -6478,10 +7228,14 @@ }, "node_modules/node-int64": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "license": "MIT" }, "node_modules/nofilter": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "license": "MIT", "engines": { "node": ">=12.19" @@ -6497,6 +7251,20 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "node_modules/number-allocator": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", @@ -6507,6 +7275,26 @@ "js-sdsl": "4.3.0" } }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -6635,6 +7423,8 @@ }, "node_modules/opentracing": { "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", "license": "Apache-2.0", "engines": { "node": ">=0.10" @@ -6816,6 +7606,8 @@ }, "node_modules/popsicle": { "version": "12.1.2", + "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-12.1.2.tgz", + "integrity": "sha512-xE2vEUa15TiHvFhGmKTtdKk9aSLL5CHX8Vw5kHfVM3R0YHiaTon6Ybsamw0XYqMR+Ng2RijX88iYUKPBMpLBww==", "license": "MIT", "dependencies": { "popsicle-content-encoding": "^1.0.0", @@ -6833,6 +7625,8 @@ }, "node_modules/popsicle-content-encoding": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popsicle-content-encoding/-/popsicle-content-encoding-1.0.0.tgz", + "integrity": "sha512-4Df+vTfM8wCCJVTzPujiI6eOl3SiWQkcZg0AMrOkD1enMXsF3glIkFUZGvour1Sj7jOWCsNSEhBxpbbhclHhzw==", "license": "MIT", "peerDependencies": { "servie": "^4.0.0" @@ -6840,6 +7634,8 @@ }, "node_modules/popsicle-cookie-jar": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/popsicle-cookie-jar/-/popsicle-cookie-jar-1.0.1.tgz", + "integrity": "sha512-QVIZhADP8nDbXIQW6wq8GU9IOSE8INUACO/9KD9TFKQ7qq8r/y3qUDz59xIi6p6TH19lCJJyBAPSXP1liIoySw==", "license": "MIT", "dependencies": { "@types/tough-cookie": "^4.0.2", @@ -6854,6 +7650,8 @@ }, "node_modules/popsicle-redirects": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/popsicle-redirects/-/popsicle-redirects-1.1.1.tgz", + "integrity": "sha512-mC2HrKjdTAWDalOjGxlXw9j6Qxrz/Yd2ui6bPxpi2IQDYWpF4gUAMxbA8EpSWJhLi0PuWKDwTHHPrUPGutAoIA==", "license": "MIT", "peerDependencies": { "servie": "^4.1.0" @@ -6861,6 +7659,8 @@ }, "node_modules/popsicle-transport-http": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/popsicle-transport-http/-/popsicle-transport-http-1.2.1.tgz", + "integrity": "sha512-i5r3IGHkGiBDm1oPFvOfEeSGWR0lQJcsdTqwvvDjXqcTHYJJi4iSi3ecXIttDiTBoBtRAFAE9nF91fspQr63FQ==", "license": "MIT", "dependencies": { "make-error-cause": "^2.2.0" @@ -6871,6 +7671,8 @@ }, "node_modules/popsicle-transport-xhr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/popsicle-transport-xhr/-/popsicle-transport-xhr-2.0.0.tgz", + "integrity": "sha512-5Sbud4Widngf1dodJE5cjEYXkzEUIl8CzyYRYR57t6vpy9a9KPGQX6KBKdPjmBZlR5A06pOBXuJnVr23l27rtA==", "license": "MIT", "peerDependencies": { "servie": "^4.2.0" @@ -6878,6 +7680,8 @@ }, "node_modules/popsicle-user-agent": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/popsicle-user-agent/-/popsicle-user-agent-1.0.0.tgz", + "integrity": "sha512-epKaq3TTfTzXcxBxjpoKYMcTTcAX8Rykus6QZu77XNhJuRHSRxMd+JJrbX/3PFI0opFGSN0BabbAYCbGxbu0mA==", "license": "MIT", "peerDependencies": { "servie": "^4.0.0" @@ -6893,6 +7697,34 @@ "node": ">= 0.4" } }, + "node_modules/prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6921,6 +7753,8 @@ }, "node_modules/process": { "version": "0.10.1", + "resolved": "https://registry.npmjs.org/process/-/process-0.10.1.tgz", + "integrity": "sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==", "engines": { "node": ">= 0.6.0" } @@ -6932,9 +7766,9 @@ "license": "MIT" }, "node_modules/protobufjs": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", - "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -6976,6 +7810,8 @@ }, "node_modules/psl": { "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -6996,6 +7832,8 @@ }, "node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" @@ -7027,6 +7865,8 @@ }, "node_modules/query-string": { "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", "license": "MIT", "dependencies": { "decode-uri-component": "^0.2.2", @@ -7043,6 +7883,8 @@ }, "node_modules/querystringify": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "license": "MIT" }, "node_modules/queue-microtask": { @@ -7100,6 +7942,32 @@ "node": ">= 0.8" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -7196,6 +8064,8 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7203,6 +8073,8 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, "node_modules/resolve": { @@ -7248,6 +8120,8 @@ }, "node_modules/ret": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", "license": "MIT", "engines": { "node": ">=4" @@ -7279,6 +8153,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -7306,6 +8181,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -7362,6 +8238,8 @@ }, "node_modules/rxjs": { "version": "5.5.11", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", + "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", "license": "Apache-2.0", "dependencies": { "symbol-observable": "1.0.1" @@ -7392,6 +8270,8 @@ }, "node_modules/safe-buffer": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/safe-push-apply": { @@ -7431,6 +8311,8 @@ }, "node_modules/safe-regex2": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", + "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", "license": "MIT", "dependencies": { "ret": "~0.2.0" @@ -7453,6 +8335,8 @@ }, "node_modules/semver": { "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7587,6 +8471,8 @@ }, "node_modules/servie": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/servie/-/servie-4.3.3.tgz", + "integrity": "sha512-b0IrY3b1gVMsWvJppCf19g1p3JSnS0hQi6xu4Hi40CIhf0Lx8pQHcvBL+xunShpmOiQzg1NOia812NAWdSaShw==", "license": "Apache-2.0", "dependencies": { "@servie/events": "^1.0.0", @@ -7594,6 +8480,13 @@ "ts-expect": "^1.1.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC", + "optional": true + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -7744,6 +8637,46 @@ "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==", + "license": "ISC", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -7755,6 +8688,8 @@ }, "node_modules/slugify": { "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -7775,9 +8710,9 @@ "link": true }, "node_modules/snappy": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.3.0.tgz", - "integrity": "sha512-Qd1XxFO71HOOA6RxWkO5yHcYrQyBZOqGFKv99DD75bS34I3J6HEudlO4Lo617B6A6fJJ87YS5oYY9NZXxlXGkw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/snappy/-/snappy-7.3.2.tgz", + "integrity": "sha512-cEA4Wi0huhCIlGDG+/27q0hELqIe9TBcrOToO4HsAE1n/3ibO9SsbtbRB5pAHHTGw8ihrhG700XOOqyxvwSxng==", "license": "MIT", "optional": true, "engines": { @@ -7788,33 +8723,33 @@ "url": "https://github.com/sponsors/Brooooooklyn" }, "optionalDependencies": { - "@napi-rs/snappy-android-arm-eabi": "7.3.0", - "@napi-rs/snappy-android-arm64": "7.3.0", - "@napi-rs/snappy-darwin-arm64": "7.3.0", - "@napi-rs/snappy-darwin-x64": "7.3.0", - "@napi-rs/snappy-freebsd-x64": "7.3.0", - "@napi-rs/snappy-linux-arm-gnueabihf": "7.3.0", - "@napi-rs/snappy-linux-arm64-gnu": "7.3.0", - "@napi-rs/snappy-linux-arm64-musl": "7.3.0", - "@napi-rs/snappy-linux-arm64-ohos": "7.3.0", - "@napi-rs/snappy-linux-ppc64-gnu": "7.3.0", - "@napi-rs/snappy-linux-riscv64-gnu": "7.3.0", - "@napi-rs/snappy-linux-s390x-gnu": "7.3.0", - "@napi-rs/snappy-linux-x64-gnu": "7.3.0", - "@napi-rs/snappy-linux-x64-musl": "7.3.0", - "@napi-rs/snappy-wasm32-wasi": "7.3.0", - "@napi-rs/snappy-win32-arm64-msvc": "7.3.0", - "@napi-rs/snappy-win32-ia32-msvc": "7.3.0", - "@napi-rs/snappy-win32-x64-msvc": "7.3.0" + "@napi-rs/snappy-android-arm-eabi": "7.3.2", + "@napi-rs/snappy-android-arm64": "7.3.2", + "@napi-rs/snappy-darwin-arm64": "7.3.2", + "@napi-rs/snappy-darwin-x64": "7.3.2", + "@napi-rs/snappy-freebsd-x64": "7.3.2", + "@napi-rs/snappy-linux-arm-gnueabihf": "7.3.2", + "@napi-rs/snappy-linux-arm64-gnu": "7.3.2", + "@napi-rs/snappy-linux-arm64-musl": "7.3.2", + "@napi-rs/snappy-linux-ppc64-gnu": "7.3.2", + "@napi-rs/snappy-linux-riscv64-gnu": "7.3.2", + "@napi-rs/snappy-linux-s390x-gnu": "7.3.2", + "@napi-rs/snappy-linux-x64-gnu": "7.3.2", + "@napi-rs/snappy-linux-x64-musl": "7.3.2", + "@napi-rs/snappy-openharmony-arm64": "7.3.2", + "@napi-rs/snappy-wasm32-wasi": "7.3.2", + "@napi-rs/snappy-win32-arm64-msvc": "7.3.2", + "@napi-rs/snappy-win32-ia32-msvc": "7.3.2", + "@napi-rs/snappy-win32-x64-msvc": "7.3.2" } }, "node_modules/socks": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.6.tgz", - "integrity": "sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA==", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -7824,6 +8759,8 @@ }, "node_modules/split-on-first": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", "license": "MIT", "engines": { "node": ">=6" @@ -7838,12 +8775,6 @@ "node": ">= 10.x" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -7878,6 +8809,8 @@ }, "node_modules/strict-uri-encode": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", "license": "MIT", "engines": { "node": ">=4" @@ -7913,13 +8846,15 @@ "license": "MIT" }, "node_modules/string-template": { - "version": "0.2.1" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -7993,7 +8928,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8053,14 +8988,79 @@ }, "node_modules/symbol-observable": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/test-things-util": { - "resolved": "util", - "link": true + "node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, "node_modules/text-hex": { "version": "1.0.0", @@ -8077,6 +9077,8 @@ }, "node_modules/thriftrw": { "version": "3.11.4", + "resolved": "https://registry.npmjs.org/thriftrw/-/thriftrw-3.11.4.tgz", + "integrity": "sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==", "dependencies": { "bufrw": "^1.2.1", "error": "7.0.2", @@ -8091,6 +9093,8 @@ }, "node_modules/throwback": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throwback/-/throwback-4.1.0.tgz", + "integrity": "sha512-dLFe8bU8SeH0xeqeKL7BNo8XoPC/o91nz9/ooeplZPiso+DZukhoyZcSz9TFnUNScm+cA9qjU1m1853M6sPOng==", "license": "MIT" }, "node_modules/thunky": { @@ -8123,6 +9127,8 @@ }, "node_modules/tough-cookie": { "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", @@ -8136,6 +9142,8 @@ }, "node_modules/tr46": { "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/triple-beam": { @@ -8162,6 +9170,8 @@ }, "node_modules/ts-expect": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", "license": "MIT" }, "node_modules/ts-node": { @@ -8237,6 +9247,19 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8372,6 +9395,8 @@ }, "node_modules/typescript": { "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8410,10 +9435,14 @@ }, "node_modules/undici-types": { "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/universalify": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -8439,10 +9468,14 @@ } }, "node_modules/uritemplate": { - "version": "0.3.4" + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/uritemplate/-/uritemplate-0.3.4.tgz", + "integrity": "sha512-enADBvHfhjrwxFMTVWeIIYz51SZ91uC6o2MR/NQTVljJB6HTZ8eQL3Q7JBj3RxNISA14MOwJaU3vpf5R6dyxHA==" }, "node_modules/url-parse": { "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -8457,8 +9490,14 @@ }, "node_modules/url-toolkit": { "version": "2.1.6", + "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz", + "integrity": "sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw==", "license": "Apache-2.0" }, + "node_modules/util": { + "resolved": "util", + "link": true + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8476,6 +9515,8 @@ }, "node_modules/uuid": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -8505,6 +9546,8 @@ }, "node_modules/web-streams-polyfill": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -8512,10 +9555,14 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -8627,6 +9674,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/winston": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", @@ -8689,38 +9746,51 @@ "node": ">=0.10.0" } }, + "node_modules/worker-factory": { + "version": "7.0.45", + "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.45.tgz", + "integrity": "sha512-FFPCiSv7MD6ZDEfiik/ErM8IrIAWajaXhezLyCo3v0FjhUWud6GXnG2BiTE91jLywXGAVCT8IF48Hhr+D/omMw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1" + } + }, "node_modules/worker-timers": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", - "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", + "version": "8.0.24", + "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.24.tgz", + "integrity": "sha512-Ydu/7TRHlxIRjYSGDge1F92L7y9kzInpwR4CkocRVObPE0eRqC6d+0GFh52Hm+m520RHVKiytOERtCUu5sQDVQ==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2", - "worker-timers-broker": "^6.1.8", - "worker-timers-worker": "^7.0.71" + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1", + "worker-timers-broker": "^8.0.10", + "worker-timers-worker": "^9.0.10" } }, "node_modules/worker-timers-broker": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", - "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.10.tgz", + "integrity": "sha512-xvo/9GiuduENbJNdWnvZtkriIkjBKKVbMyw7GXvrBu3n1JHemzZgxqaCcCBNlpfXnRXXF4ekqvXWLh1gb65b8w==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "fast-unique-numbers": "^8.0.13", - "tslib": "^2.6.2", - "worker-timers-worker": "^7.0.71" + "@babel/runtime": "^7.28.3", + "broker-factory": "^3.1.9", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1", + "worker-timers-worker": "^9.0.10" } }, "node_modules/worker-timers-worker": { - "version": "7.0.71", - "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", - "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.10.tgz", + "integrity": "sha512-cfCmAkuoN+nGGJShta/g7CQVP3h7rvQA642EQg72fOHCWP5S2P83rLxDiaGv811Hd+19Cgdqt/tpRBIZ5kj/dw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "tslib": "^2.6.2" + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1", + "worker-factory": "^7.0.45" } }, "node_modules/workerpool": { @@ -8732,14 +9802,20 @@ }, "node_modules/wot-thing-description-types": { "version": "1.1.0-12-March-2025", + "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-12-March-2025.tgz", + "integrity": "sha512-BRRW4uBATljCPqCbpzNhgY2HFXz8Llh7mAJmjkVimxizOPq8bkmlm0Op/Yv8l7pNQ1GaoBtYwn2BQQjhcQCadA==", "license": "W3C-20150513" }, "node_modules/wot-thing-model-types": { "version": "1.1.0-12-March-2025", + "resolved": "https://registry.npmjs.org/wot-thing-model-types/-/wot-thing-model-types-1.1.0-12-March-2025.tgz", + "integrity": "sha512-YqCLluIONdr9m8p8euVqSrVFlyROWVhrI2CVZHGuGJfpm56xU2jtT4yFiZHumrnjKKwp0QfErX0YLB1uxdPNGg==", "license": "W3C-20150513" }, "node_modules/wot-typescript-definitions": { "version": "0.8.0-SNAPSHOT.31", + "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.31.tgz", + "integrity": "sha512-BBUWfJnNsSMb60FlUfQN+TWFP2W71LM4g7in83Y+vO6BjGvsyO0KY4jTbazjhLdxxTjbyftrExNkKNwtBIbxfA==", "license": "W3C-20150513", "dependencies": { "wot-thing-description-types": "1.1.0-12-March-2025" @@ -8792,10 +9868,14 @@ }, "node_modules/xorshift": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xorshift/-/xorshift-1.2.0.tgz", + "integrity": "sha512-iYgNnGyeeJ4t6U11NpA/QiKy+PXn5Aa3Azg5qkwIFz1tBLllQrjjsk9yzD7IAK0naNU4JxdeDgqW9ov4u/hc4g==", "license": "MIT" }, "node_modules/xtend": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", "engines": { "node": ">=0.4" @@ -8812,9 +9892,9 @@ } }, "node_modules/yaml": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", - "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", "bin": { @@ -8899,9 +9979,13 @@ "dependencies": { "@node-wot/binding-http": "0.8.16", "@node-wot/core": "0.8.16", + "@opentelemetry/api": "1.9.0", + "@opentelemetry/exporter-jaeger": "1.9.0", + "@opentelemetry/resources": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", + "@opentelemetry/semantic-conventions": "1.9.0", "dotenv": "^16.4.5", "json-placeholder-replacer": "^2.0.5", - "test-things-util": "file:../../../../util", "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" }, "devDependencies": { @@ -8912,19 +9996,14 @@ } }, "things/advanced-coffee-machine/http/ts/node_modules/test-things-util": { - "resolved": "../util", - "link": true + "extraneous": true }, "things/advanced-coffee-machine/http/ts/node_modules/wot-thing-description-types": { "version": "1.1.0-09-November-2023", - "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", - "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", "license": "W3C-20150513" }, "things/advanced-coffee-machine/http/ts/node_modules/wot-typescript-definitions": { "version": "0.8.0-SNAPSHOT.29", - "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", - "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", "license": "W3C-20150513", "dependencies": { "wot-thing-description-types": "1.1.0-09-November-2023" @@ -9174,6 +10253,7 @@ } } }, + "things/counter-thing": {}, "things/counter-thing/http/ts": { "name": "counter-thing", "version": "1.0.0", @@ -9192,20 +10272,16 @@ "typescript": "^5.0.4" } }, - "things/counter-thing/http/ts/node_modules/@types/node": { - "version": "18.19.121", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.121.tgz", - "integrity": "sha512-bHOrbyztmyYIi4f1R0s17QsPs1uyyYnGcXeZoGEd227oZjry0q6XQBQxd82X1I57zEfwO8h9Xo+Kl5gX1d9MwQ==", + "things/counter-thing/node_modules/@types/node": { + "version": "18.19.112", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, - "things/counter-thing/http/ts/node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "things/counter-thing/node_modules/typescript": { + "version": "5.8.3", "dev": true, "license": "Apache-2.0", "bin": { @@ -9216,10 +10292,8 @@ "node": ">=14.17" } }, - "things/counter-thing/http/ts/node_modules/undici-types": { + "things/counter-thing/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, @@ -9245,14 +10319,10 @@ }, "things/data-schema-thing/http/ts/node_modules/wot-thing-description-types": { "version": "1.1.0-09-November-2023", - "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", - "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", "license": "W3C-20150513" }, "things/data-schema-thing/http/ts/node_modules/wot-typescript-definitions": { "version": "0.8.0-SNAPSHOT.29", - "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", - "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", "license": "W3C-20150513", "dependencies": { "wot-thing-description-types": "1.1.0-09-November-2023" @@ -9280,7 +10350,6 @@ } }, "util": { - "name": "test-things-util", "version": "1.0.0", "license": "EPL-2.0 OR W3C-20150513", "dependencies": { @@ -9299,14 +10368,10 @@ }, "util/node_modules/wot-thing-description-types": { "version": "1.1.0-09-November-2023", - "resolved": "https://registry.npmjs.org/wot-thing-description-types/-/wot-thing-description-types-1.1.0-09-November-2023.tgz", - "integrity": "sha512-qgZ1Khg/L3SkIRSm4POVoj0P5MU4GIwxWdyQz2ckZzhnXesgPqe+AUzGxK37ArlxvaMytyjo0Cx2yfKoDHtlkA==", "license": "W3C-20150513" }, "util/node_modules/wot-typescript-definitions": { "version": "0.8.0-SNAPSHOT.29", - "resolved": "https://registry.npmjs.org/wot-typescript-definitions/-/wot-typescript-definitions-0.8.0-SNAPSHOT.29.tgz", - "integrity": "sha512-V5r/JSbFs/eaWgQavEEvaldjYoMuucJ9Ae0BDfUbSm6d9rJJYLEwfrwFKxBCD25Kdroea+kNlQMrYKk783OREQ==", "license": "W3C-20150513", "dependencies": { "wot-thing-description-types": "1.1.0-09-November-2023" From ff10f89680e9ff2962319fc8c765464f6db9d879 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Wed, 27 Aug 2025 00:29:01 -0400 Subject: [PATCH 28/34] Reduced redundancy in main.ts --- .../http/ts/src/main.ts | 452 ++++++++---------- util/auto-tracing.ts | 111 ++++- 2 files changed, 309 insertions(+), 254 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index 89f9018..ebfacd1 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -28,7 +28,7 @@ import dotenv from "dotenv"; // eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency import { initTracing, tracedEventHandler } from "../../../../../util/dist/tracing"; // eslint-disable-next-line workspaces/no-relative-imports, workspaces/require-dependency -import { createAutoTracedThing, createTracedLogic } from "../../../../../util/dist/auto-tracing"; +import { createAutoTracedThing, TracedBusinessLogic } from "../../../../../util/dist/auto-tracing"; dotenv.config(); @@ -149,43 +149,39 @@ servient tracedThing.setPropertyReadHandler( "allAvailableResources", "getAllResources", - async (options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("getAllResources"); - - return await logic.execute(async () => { - // Validate resource data integrity - await logic.withValidation("resourceData", allAvailableResources, async () => { - const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; - for (const resource of requiredResources) { - if (!(resource in allAvailableResources)) { - throw new Error(`Missing required resource: ${resource}`); - } - if (typeof allAvailableResources[resource] !== "number") { - throw new Error(`Invalid resource level for ${resource}`); - } + async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { + // Validate resource data integrity + await logic.withValidation("resourceData", allAvailableResources, async () => { + const requiredResources = ["water", "milk", "chocolate", "coffeeBeans"]; + for (const resource of requiredResources) { + if (!(resource in allAvailableResources)) { + throw new Error(`Missing required resource: ${resource}`); } - }); + if (typeof allAvailableResources[resource] !== "number") { + throw new Error(`Invalid resource level for ${resource}`); + } + } + }); - // Read sensor data for real-time validation - await logic.withProcessing( - "sensors.readAll", - async () => { - const readings: Record = {}; - for (const resource of Object.keys(allAvailableResources)) { - readings[resource] = readFromSensor(resource); - } - return readings; - }, - { - "sensor.count": Object.keys(allAvailableResources).length, - "sensor.type": "resource_level", + // Read sensor data for real-time validation + await logic.withProcessing( + "sensors.readAll", + async () => { + const readings: Record = {}; + for (const resource of Object.keys(allAvailableResources)) { + readings[resource] = readFromSensor(resource); } - ); + return readings; + }, + { + "sensor.count": Object.keys(allAvailableResources).length, + "sensor.type": "resource_level", + } + ); - // Compare and sync with database - return await logic.withDatabase("select", "resource_levels", async () => { - return { ...allAvailableResources }; - }); + // Compare and sync with database + return await logic.withDatabase("select", "resource_levels", async () => { + return { ...allAvailableResources }; }); } ); @@ -194,41 +190,37 @@ servient tracedThing.setPropertyReadHandler( "possibleDrinks", "getPossibleDrinks", - async (options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("getPossibleDrinks"); - - return await logic.execute(async () => { - // Validate drink catalog integrity - await logic.withValidation("drinkCatalog", possibleDrinks, async () => { - if (!Array.isArray(possibleDrinks)) { - throw new Error("Drink catalog is corrupted"); - } - if (possibleDrinks.length === 0) { - throw new Error("No drinks available in catalog"); - } - }); - - // Load drink availability from database - const availabilityMap = await logic.withDatabase("select", "drink_availability", async () => { - const availability: Record = {}; - for (const drink of possibleDrinks) { - availability[drink] = true; - } - return availability; - }); + async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { + // Validate drink catalog integrity + await logic.withValidation("drinkCatalog", possibleDrinks, async () => { + if (!Array.isArray(possibleDrinks)) { + throw new Error("Drink catalog is corrupted"); + } + if (possibleDrinks.length === 0) { + throw new Error("No drinks available in catalog"); + } + }); - // Filter available drinks based on current resources - return await logic.withProcessing( - "processing.filterAvailableDrinks", - async () => { - return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); - }, - { - "drinks.total": possibleDrinks.length, - "filtering.criteria": "resource_availability", - } - ); + // Load drink availability from database + const availabilityMap = await logic.withDatabase("select", "drink_availability", async () => { + const availability: Record = {}; + for (const drink of possibleDrinks) { + availability[drink] = true; + } + return availability; }); + + // Filter available drinks based on current resources + return await logic.withProcessing( + "processing.filterAvailableDrinks", + async () => { + return possibleDrinks.filter((drink) => availabilityMap[drink] !== false); + }, + { + "drinks.total": possibleDrinks.length, + "filtering.criteria": "resource_availability", + } + ); } ); @@ -243,30 +235,26 @@ servient tracedThing.setPropertyReadHandler( "availableResourceLevel", "getResourceLevel", - async (options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("getResourceLevel"); - - return await logic.execute(async () => { - // Parse resource ID from URI variables - const resourceId = await logic.withProcessing( - "parsing.extractResourceId", - async () => { - const resourceId = (options?.uriVariables as Record)?.id; - if (!resourceId || !(resourceId in allAvailableResources)) { - throw new Error(`Invalid resource ID: ${resourceId}`); - } - return resourceId; - }, - { - "resource.id": (options?.uriVariables as Record)?.id ?? "unknown", - "parsing.operation": "resource_id_extraction", + async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { + // Parse resource ID from URI variables + const resourceId = await logic.withProcessing( + "parsing.extractResourceId", + async () => { + const resourceId = (options?.uriVariables as Record)?.id; + if (!resourceId || !(resourceId in allAvailableResources)) { + throw new Error(`Invalid resource ID: ${resourceId}`); } - ); + return resourceId; + }, + { + "resource.id": (options?.uriVariables as Record)?.id ?? "unknown", + "parsing.operation": "resource_id_extraction", + } + ); - // Get resource level from database - return await logic.withDatabase("select", "resource_levels", async () => { - return allAvailableResources[resourceId]; - }); + // Get resource level from database + return await logic.withDatabase("select", "resource_levels", async () => { + return allAvailableResources[resourceId]; }); } ); @@ -275,34 +263,30 @@ servient tracedThing.setPropertyReadHandler( "schedules", "getSchedules", - async (options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("getSchedules"); - - return await logic.execute(async () => { - // Validate system state - await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { - if (!Array.isArray(schedules)) { - throw new Error("Schedules data structure is corrupted"); - } - }); - - // Load schedules from database - const result = await logic.withDatabase("select", "schedules", async () => { - return schedules; - }); + async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { + // Validate system state + await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { + if (!Array.isArray(schedules)) { + throw new Error("Schedules data structure is corrupted"); + } + }); - // Process and filter active schedules - return await logic.withProcessing( - "processing.filterActiveSchedules", - async () => { - return result.filter((schedule: unknown) => true); // For demo, all schedules are active - }, - { - "schedules.count": schedules.length, - "query.time": new Date().toISOString(), - } - ); + // Load schedules from database + const result = await logic.withDatabase("select", "schedules", async () => { + return schedules; }); + + // Process and filter active schedules + return await logic.withProcessing( + "processing.filterActiveSchedules", + async () => { + return result.filter((schedule: unknown) => true); // For demo, all schedules are active + }, + { + "schedules.count": schedules.length, + "query.time": new Date().toISOString(), + } + ); } ); @@ -310,59 +294,55 @@ servient tracedThing.setPropertyWriteHandler( "servedCounter", "updateServedCounter", - async (val: WoT.InteractionInput) => { - const logic = createTracedLogic("updateServedCounter"); + async (logic: TracedBusinessLogic, val: WoT.InteractionInput) => { + // Validate input + await logic.withValidation("counterInput", val, async () => { + if (val === null || val === undefined) { + throw new Error("No value provided for servedCounter"); + } + }); - await logic.execute(async () => { - // Validate input - await logic.withValidation("counterInput", val, async () => { + // Parse and validate the new counter value + const newCounterValue = await logic.withProcessing( + "parsing.extractCounterValue", + async () => { if (val === null || val === undefined) { throw new Error("No value provided for servedCounter"); } - }); - - // Parse and validate the new counter value - const newCounterValue = await logic.withProcessing( - "parsing.extractCounterValue", - async () => { - if (val === null || val === undefined) { - throw new Error("No value provided for servedCounter"); - } - // Type guard and extraction for WoT InteractionInput - const value = await extractWoTValue(val); + // Type guard and extraction for WoT InteractionInput + const value = await extractWoTValue(val); - if (typeof value !== "number" || value < 0) { - throw new Error(`Invalid served counter value: ${value}`); - } - return value; - }, - { - "input.type": typeof val, - "parsing.operation": "counter_extraction", + if (typeof value !== "number" || value < 0) { + throw new Error(`Invalid served counter value: ${value}`); } - ); - - // Update counter in database - await logic.withDatabase("update", "counters", async () => { - servedCounter = newCounterValue; - }); + return value; + }, + { + "input.type": typeof val, + "parsing.operation": "counter_extraction", + } + ); - // Check maintenance threshold and trigger events if needed - await logic.withProcessing("business.checkMaintenanceThreshold", async () => { - if (servedCounter > 1000) { - // Update maintenance status - await logic.withDatabase("update", "maintenance_status", async () => { - maintenanceNeeded = true; - }); + // Update counter in database + await logic.withDatabase("update", "counters", async () => { + servedCounter = newCounterValue; + }); - // Emit maintenance event - await logic.withProcessing("event.maintenanceNeeded", async () => { - tracedEventHandler("maintenanceNeeded", (data: WoT.InteractionInput) => - thing.emitPropertyChange("maintenanceNeeded") - )(maintenanceNeeded); - }); - } - }); + // Check maintenance threshold and trigger events if needed + await logic.withProcessing("business.checkMaintenanceThreshold", async () => { + if (servedCounter > 1000) { + // Update maintenance status + await logic.withDatabase("update", "maintenance_status", async () => { + maintenanceNeeded = true; + }); + + // Emit maintenance event + await logic.withProcessing("event.maintenanceNeeded", async () => { + tracedEventHandler("maintenanceNeeded", (data: WoT.InteractionInput) => + thing.emitPropertyChange("maintenanceNeeded") + )(maintenanceNeeded); + }); + } }); } ); @@ -371,75 +351,71 @@ servient tracedThing.setPropertyWriteHandler( "availableResourceLevel", "updateResourceLevel", - async (val: WoT.InteractionInput, options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("updateResourceLevel"); - - await logic.execute(async () => { - // Parse and validate resource ID and new level - const { resourceId, newLevel } = await logic.withProcessing( - "parsing.extractResourceParameters", - async () => { - const resourceId = (options?.uriVariables as Record)?.id; - if (!resourceId || !(resourceId in allAvailableResources)) { - throw Error("Please specify id variable as uriVariables."); - } - - if (val === null || val === undefined) { - throw new Error("No value provided for availableResourceLevel"); - } + async (logic: TracedBusinessLogic, val: WoT.InteractionInput, options?: WoT.InteractionOptions) => { + // Parse and validate resource ID and new level + const { resourceId, newLevel } = await logic.withProcessing( + "parsing.extractResourceParameters", + async () => { + const resourceId = (options?.uriVariables as Record)?.id; + if (!resourceId || !(resourceId in allAvailableResources)) { + throw Error("Please specify id variable as uriVariables."); + } - // Type guard and extraction for WoT InteractionInput - const newLevel = await extractWoTValue(val); + if (val === null || val === undefined) { + throw new Error("No value provided for availableResourceLevel"); + } - if (typeof newLevel !== "number" || newLevel < 0 || newLevel > 100) { - throw new Error(`Invalid level for ${resourceId}: ${newLevel}`); - } + // Type guard and extraction for WoT InteractionInput + const newLevel = await extractWoTValue(val); - return { resourceId, newLevel }; - }, - { - "resource.id": "dynamic", - "parsing.operation": "resource_extraction", + if (typeof newLevel !== "number" || newLevel < 0 || newLevel > 100) { + throw new Error(`Invalid level for ${resourceId}: ${newLevel}`); } - ); - // Calculate level change - await logic.withProcessing( - "calculate.levelChange", - async () => { - const currentLevel = allAvailableResources[resourceId]; - const levelChange = newLevel - currentLevel; - return { - previous: currentLevel, - new: newLevel, - change: levelChange, - changeType: - levelChange > 0 ? "refill" : levelChange < 0 ? "consumption" : "no_change", - }; - }, - { - "resource.id": resourceId, - "calculation.type": "level_change", - } - ); + return { resourceId, newLevel }; + }, + { + "resource.id": "dynamic", + "parsing.operation": "resource_extraction", + } + ); - // Update resource level in database - await logic.withDatabase("update", "resource_levels", async () => { - allAvailableResources[resourceId] = newLevel; - }); + // Calculate level change + await logic.withProcessing( + "calculate.levelChange", + async () => { + const currentLevel = allAvailableResources[resourceId]; + const levelChange = newLevel - currentLevel; + return { + previous: currentLevel, + new: newLevel, + change: levelChange, + changeType: + levelChange > 0 ? "refill" : levelChange < 0 ? "consumption" : "no_change", + }; + }, + { + "resource.id": resourceId, + "calculation.type": "level_change", + } + ); - // Check for low resource alerts - await logic.withProcessing("business.checkResourceThresholds", async () => { - if (newLevel <= 10) { - // Emit low resource event - await logic.withProcessing("event.lowResource", async () => { - const eventData = `Low level of ${resourceId}: ${newLevel}%`; - tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => - thing.emitEvent("outOfResource", data) - )(eventData); - }); - } - }); + // Update resource level in database + await logic.withDatabase("update", "resource_levels", async () => { + allAvailableResources[resourceId] = newLevel; + }); + + // Check for low resource alerts + await logic.withProcessing("business.checkResourceThresholds", async () => { + if (newLevel <= 10) { + // Emit low resource event + await logic.withProcessing("event.lowResource", async () => { + const eventData = `Low level of ${resourceId}: ${newLevel}%`; + tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + } }); } ); @@ -448,11 +424,8 @@ servient tracedThing.setActionHandler( "makeDrink", "makeDrink", - async (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { - const logic = createTracedLogic("makeDrink"); - - return await logic.execute(async () => { - // Parse parameters with defaults + async (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { + // Parse parameters with defaults const { drinkId, size, quantity } = await logic.withProcessing( "parsing.extractDrinkParameters", async () => { @@ -574,20 +547,16 @@ servient } ); - return { - result: true, - message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, - }; - }); + return { + result: true, + message: `Enjoy your ${quantity} ${size} ${drinkId}(s)!`, + }; } ); // Action: setSchedule - tracedThing.setActionHandler("setSchedule", "setSchedule", async (params?: WoT.InteractionInput) => { - const logic = createTracedLogic("setSchedule"); - - return await logic.execute(async () => { - // Parse and validate schedule data + tracedThing.setActionHandler("setSchedule", "setSchedule", async (logic: TracedBusinessLogic, params?: WoT.InteractionInput) => { + // Parse and validate schedule data const scheduleData = await logic.withProcessing( "parsing.extractScheduleData", async () => { @@ -655,11 +624,10 @@ servient schedules.push(scheduleData); }); - return { - result: true, - message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, - }; - }); + return { + result: true, + message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, + }; }); thing.expose().then(() => { diff --git a/util/auto-tracing.ts b/util/auto-tracing.ts index 870fc3e..717886c 100644 --- a/util/auto-tracing.ts +++ b/util/auto-tracing.ts @@ -248,16 +248,45 @@ export class AutoTracedThing { businessLogicName: string, businessLogic: (options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setPropertyReadHandler( + propertyName: string, + businessLogicName: string, + businessLogic: (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setPropertyReadHandler( + propertyName: string, + businessLogicName: string, + businessLogic: ((options?: WoT.InteractionOptions) => Promise | T) | ((logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T), + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); if (configBuilder) { config = configBuilder(config); } - this.thing.setPropertyReadHandler( - propertyName, - autoTracedPropertyRead(propertyName, config.build(), businessLogic) as WoT.PropertyReadHandler - ); + // Check if businessLogic expects TracedBusinessLogic as first parameter + if (businessLogic.length >= 2 || (businessLogic.length === 1 && businessLogic.toString().includes('logic'))) { + // Enhanced version with TracedBusinessLogic injection + this.thing.setPropertyReadHandler( + propertyName, + tracedPropertyReadHandler(propertyName, async (options) => { + const logic = createTracedLogic(businessLogicName); + return await logic.execute(async () => { + return await (businessLogic as (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise)(logic, options); + }); + }) as WoT.PropertyReadHandler + ); + } else { + // Original version with config-based tracing + this.thing.setPropertyReadHandler( + propertyName, + autoTracedPropertyRead(propertyName, config.build(), businessLogic as (options?: WoT.InteractionOptions) => Promise) as WoT.PropertyReadHandler + ); + } } setPropertyWriteHandler( @@ -265,16 +294,45 @@ export class AutoTracedThing { businessLogicName: string, businessLogic: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setPropertyWriteHandler( + propertyName: string, + businessLogicName: string, + businessLogic: (logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setPropertyWriteHandler( + propertyName: string, + businessLogicName: string, + businessLogic: ((value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void) | ((logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void), + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); if (configBuilder) { config = configBuilder(config); } - this.thing.setPropertyWriteHandler( - propertyName, - autoTracedPropertyWrite(propertyName, config.build(), businessLogic) - ); + // Check if businessLogic expects TracedBusinessLogic as first parameter + if (businessLogic.length >= 3 || (businessLogic.length >= 2 && businessLogic.toString().includes('logic'))) { + // Enhanced version with TracedBusinessLogic injection + this.thing.setPropertyWriteHandler( + propertyName, + tracedPropertyWriteHandler(propertyName, async (value, options) => { + const logic = createTracedLogic(businessLogicName); + return await logic.execute(async () => { + return await (businessLogic as (logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise)(logic, value, options); + }); + }) as WoT.PropertyWriteHandler + ); + } else { + // Original version with config-based tracing + this.thing.setPropertyWriteHandler( + propertyName, + autoTracedPropertyWrite(propertyName, config.build(), businessLogic as (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise) + ); + } } setActionHandler( @@ -282,16 +340,45 @@ export class AutoTracedThing { businessLogicName: string, businessLogic: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setActionHandler( + actionName: string, + businessLogicName: string, + businessLogic: (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T, + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder + ): void; + + setActionHandler( + actionName: string, + businessLogicName: string, + businessLogic: ((params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T) | ((logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T), + configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); if (configBuilder) { config = configBuilder(config); } - this.thing.setActionHandler( - actionName, - autoTracedAction(actionName, config.build(), businessLogic) as WoT.ActionHandler - ); + // Check if businessLogic expects TracedBusinessLogic as first parameter + if (businessLogic.length >= 3 || (businessLogic.length >= 1 && businessLogic.toString().includes('logic'))) { + // Enhanced version with TracedBusinessLogic injection + this.thing.setActionHandler( + actionName, + tracedActionHandler(actionName, async (params, options) => { + const logic = createTracedLogic(businessLogicName); + return await logic.execute(async () => { + return await (businessLogic as (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise)(logic, params, options); + }); + }) as WoT.ActionHandler + ); + } else { + // Original version with config-based tracing + this.thing.setActionHandler( + actionName, + autoTracedAction(actionName, config.build(), businessLogic as (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise) as WoT.ActionHandler + ); + } } // Delegate other methods to the wrapped thing From d43998d8bc9320795dbf0d19d54f9c3c70a9016c Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Wed, 27 Aug 2025 00:36:18 -0400 Subject: [PATCH 29/34] Updated README --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04b3200..5475ebf 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,20 @@ If you are going to add a completely new Thing: 2. Add your Thing Model under the previously created directory and name it such as `.tm.json`. 3. Follow the steps above to add your protocol and programming language/framework. +**TypeScript Tracing Integration:** +Wrap your WoT Thing with auto-tracing to get detailed OpenTelemetry spans for validation, processing, and database operations: +```typescript +import { createAutoTracedThing, TracedBusinessLogic } from "../../util/dist/auto-tracing"; +const tracedThing = createAutoTracedThing(thing); + +// Enhanced tracing with injected logic +tracedThing.setPropertyReadHandler("prop", "operation", + async (logic: TracedBusinessLogic, options) => { + await logic.withValidation("type", data, async () => {}); + return await logic.withDatabase("select", "table", async () => {}); + }); +``` + ## Current Devices The table below contains the public base URIs of the Things used for protocol testing. @@ -181,4 +195,6 @@ For Node.js-based devices, we use npm workspaces and running `npm install` at th ## Tracing -Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:8084](http://localhost:8084) in your browser (Jaeger UI). Traces are sent to the Jaeger collector on port 14268. +Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:8084](http://localhost:8084) in your browser (Jaeger UI). Traces are sent to the Jaeger collector on port 8085. + +Enhanced auto-tracing automatically injects `TracedBusinessLogic` for detailed span creation without redundancy. Function signatures determine tracing mode. From 4d94a975ace9dec6a1f6073e02896b108a18a9a7 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Wed, 27 Aug 2025 00:36:54 -0400 Subject: [PATCH 30/34] Ran npm run format --- README.md | 6 +- .../http/ts/src/main.ts | 255 +++++++++--------- util/auto-tracing.ts | 81 ++++-- 3 files changed, 198 insertions(+), 144 deletions(-) diff --git a/README.md b/README.md index 5475ebf..903f8bd 100644 --- a/README.md +++ b/README.md @@ -71,16 +71,16 @@ If you are going to add a completely new Thing: **TypeScript Tracing Integration:** Wrap your WoT Thing with auto-tracing to get detailed OpenTelemetry spans for validation, processing, and database operations: + ```typescript import { createAutoTracedThing, TracedBusinessLogic } from "../../util/dist/auto-tracing"; const tracedThing = createAutoTracedThing(thing); // Enhanced tracing with injected logic -tracedThing.setPropertyReadHandler("prop", "operation", - async (logic: TracedBusinessLogic, options) => { +tracedThing.setPropertyReadHandler("prop", "operation", async (logic: TracedBusinessLogic, options) => { await logic.withValidation("type", data, async () => {}); return await logic.withDatabase("select", "table", async () => {}); - }); +}); ``` ## Current Devices diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index ebfacd1..d9c5eb5 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -390,8 +390,7 @@ servient previous: currentLevel, new: newLevel, change: levelChange, - changeType: - levelChange > 0 ? "refill" : levelChange < 0 ? "consumption" : "no_change", + changeType: levelChange > 0 ? "refill" : levelChange < 0 ? "consumption" : "no_change", }; }, { @@ -426,126 +425,126 @@ servient "makeDrink", async (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { // Parse parameters with defaults - const { drinkId, size, quantity } = await logic.withProcessing( - "parsing.extractDrinkParameters", - async () => { - const uriVars = options?.uriVariables as Record | undefined; - const drinkId = (uriVars?.drinkId as string) ?? "americano"; - const size = (uriVars?.size as string) ?? "m"; - const quantity = (uriVars?.quantity as number) ?? 1; - return { drinkId, size, quantity }; - }, - { - "parsing.operation": "drink_parameters", - "defaults.applied": true, - } - ); - - // Load drink recipes and configuration - const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( - "select", - "recipes", - async () => { - // Define recipes and quantifiers (would come from database in real system) - const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; - const drinkRecipes: Record> = { - espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, - americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, - cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, - latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, - hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, - hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, - }; - return { drinkRecipes, sizeQuantifiers }; - } - ); + const { drinkId, size, quantity } = await logic.withProcessing( + "parsing.extractDrinkParameters", + async () => { + const uriVars = options?.uriVariables as Record | undefined; + const drinkId = (uriVars?.drinkId as string) ?? "americano"; + const size = (uriVars?.size as string) ?? "m"; + const quantity = (uriVars?.quantity as number) ?? 1; + return { drinkId, size, quantity }; + }, + { + "parsing.operation": "drink_parameters", + "defaults.applied": true, + } + ); - // Validate drink availability - await logic.withValidation("drinkAvailability", drinkId, async () => { - if (drinkRecipes[drinkId] === undefined) { - throw new Error(`Drink ${drinkId} is not available`); - } - if (sizeQuantifiers[size] === undefined) { - throw new Error(`Size ${size} is not valid`); - } - if (quantity < 1 || quantity > 5) { - throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); - } - }); - - // Get current resources - const currentResources = await logic.withDatabase("select", "resources", async () => { - return { ...allAvailableResources }; - }); - - // Calculate resource consumption - const newResources = await logic.withProcessing( - "calculate.resourceConsumption", - async () => { - const newResources = Object.assign({}, currentResources); - const recipe = drinkRecipes[drinkId]; - const sizeMultiplier = sizeQuantifiers[size]; - - newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); - newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); - newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); - newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); - - return newResources; - }, - { - "drink.id": drinkId, - "drink.size": size, - "drink.quantity": quantity, - "calculation.type": "resource_consumption", - } - ); - - // Validate resource availability and emit events if needed - await logic.withValidation("resourceAvailability", newResources, async () => { - const insufficientResources: string[] = []; - for (const [resource, level] of Object.entries(newResources)) { - if (typeof level === "number" && level < 0) { - insufficientResources.push(resource); - } - } + // Load drink recipes and configuration + const { drinkRecipes, sizeQuantifiers } = await logic.withDatabase( + "select", + "recipes", + async () => { + // Define recipes and quantifiers (would come from database in real system) + const sizeQuantifiers: Record = { s: 0.1, m: 0.2, l: 0.3 }; + const drinkRecipes: Record> = { + espresso: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 2 }, + americano: { water: 2, milk: 0, chocolate: 0, coffeeBeans: 2 }, + cappuccino: { water: 1, milk: 1, chocolate: 0, coffeeBeans: 2 }, + latte: { water: 1, milk: 2, chocolate: 0, coffeeBeans: 2 }, + hotChocolate: { water: 0, milk: 0, chocolate: 1, coffeeBeans: 0 }, + hotWater: { water: 1, milk: 0, chocolate: 0, coffeeBeans: 0 }, + }; + return { drinkRecipes, sizeQuantifiers }; + } + ); - if (insufficientResources.length > 0) { - // Emit outOfResource event before throwing error - await logic.withProcessing("event.outOfResource", async () => { - const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; - tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => - thing.emitEvent("outOfResource", data) - )(eventData); - }); - - throw new Error( - `Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)` - ); - } - }); - - // Update resources and increment counter - await logic.withDatabase("update", "all_resources", async () => { - Object.assign(allAvailableResources, newResources); - servedCounter += quantity; - }); - - // Simulate brewing process - await logic.withProcessing( - "brewing.process", - async () => { - // Simulate brewing time - await new Promise((resolve) => setTimeout(resolve, 1000)); - return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; - }, - { - "brewing.drink": drinkId, - "brewing.quantity": quantity, - "brewing.size": size, - "brewing.duration_ms": 1000, + // Validate drink availability + await logic.withValidation("drinkAvailability", drinkId, async () => { + if (drinkRecipes[drinkId] === undefined) { + throw new Error(`Drink ${drinkId} is not available`); + } + if (sizeQuantifiers[size] === undefined) { + throw new Error(`Size ${size} is not valid`); + } + if (quantity < 1 || quantity > 5) { + throw new Error(`Quantity ${quantity} is not valid (must be 1-5)`); + } + }); + + // Get current resources + const currentResources = await logic.withDatabase("select", "resources", async () => { + return { ...allAvailableResources }; + }); + + // Calculate resource consumption + const newResources = await logic.withProcessing( + "calculate.resourceConsumption", + async () => { + const newResources = Object.assign({}, currentResources); + const recipe = drinkRecipes[drinkId]; + const sizeMultiplier = sizeQuantifiers[size]; + + newResources.water -= Math.ceil(quantity * sizeMultiplier * recipe.water); + newResources.milk -= Math.ceil(quantity * sizeMultiplier * recipe.milk); + newResources.chocolate -= Math.ceil(quantity * sizeMultiplier * recipe.chocolate); + newResources.coffeeBeans -= Math.ceil(quantity * sizeMultiplier * recipe.coffeeBeans); + + return newResources; + }, + { + "drink.id": drinkId, + "drink.size": size, + "drink.quantity": quantity, + "calculation.type": "resource_consumption", + } + ); + + // Validate resource availability and emit events if needed + await logic.withValidation("resourceAvailability", newResources, async () => { + const insufficientResources: string[] = []; + for (const [resource, level] of Object.entries(newResources)) { + if (typeof level === "number" && level < 0) { + insufficientResources.push(resource); } - ); + } + + if (insufficientResources.length > 0) { + // Emit outOfResource event before throwing error + await logic.withProcessing("event.outOfResource", async () => { + const eventData = `Insufficient resources: ${insufficientResources.join(", ")} for making ${quantity} ${size} ${drinkId}(s)`; + tracedEventHandler("outOfResource", (data: WoT.InteractionInput) => + thing.emitEvent("outOfResource", data) + )(eventData); + }); + + throw new Error( + `Insufficient ${insufficientResources[0]} for making ${quantity} ${size} ${drinkId}(s)` + ); + } + }); + + // Update resources and increment counter + await logic.withDatabase("update", "all_resources", async () => { + Object.assign(allAvailableResources, newResources); + servedCounter += quantity; + }); + + // Simulate brewing process + await logic.withProcessing( + "brewing.process", + async () => { + // Simulate brewing time + await new Promise((resolve) => setTimeout(resolve, 1000)); + return `Successfully brewed ${quantity} ${size} ${drinkId}(s)`; + }, + { + "brewing.drink": drinkId, + "brewing.quantity": quantity, + "brewing.size": size, + "brewing.duration_ms": 1000, + } + ); return { result: true, @@ -555,8 +554,11 @@ servient ); // Action: setSchedule - tracedThing.setActionHandler("setSchedule", "setSchedule", async (logic: TracedBusinessLogic, params?: WoT.InteractionInput) => { - // Parse and validate schedule data + tracedThing.setActionHandler( + "setSchedule", + "setSchedule", + async (logic: TracedBusinessLogic, params?: WoT.InteractionInput) => { + // Parse and validate schedule data const scheduleData = await logic.withProcessing( "parsing.extractScheduleData", async () => { @@ -624,11 +626,12 @@ servient schedules.push(scheduleData); }); - return { - result: true, - message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, - }; - }); + return { + result: true, + message: `Schedule set for ${scheduleData.time} (${scheduleData.mode})`, + }; + } + ); thing.expose().then(() => { console.info(`${(thingDescription as { title: string }).title} ready`); diff --git a/util/auto-tracing.ts b/util/auto-tracing.ts index 717886c..d05b1e4 100644 --- a/util/auto-tracing.ts +++ b/util/auto-tracing.ts @@ -260,7 +260,9 @@ export class AutoTracedThing { setPropertyReadHandler( propertyName: string, businessLogicName: string, - businessLogic: ((options?: WoT.InteractionOptions) => Promise | T) | ((logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T), + businessLogic: + | ((options?: WoT.InteractionOptions) => Promise | T) + | ((logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -269,14 +271,19 @@ export class AutoTracedThing { } // Check if businessLogic expects TracedBusinessLogic as first parameter - if (businessLogic.length >= 2 || (businessLogic.length === 1 && businessLogic.toString().includes('logic'))) { + if (businessLogic.length >= 2 || (businessLogic.length === 1 && businessLogic.toString().includes("logic"))) { // Enhanced version with TracedBusinessLogic injection this.thing.setPropertyReadHandler( propertyName, tracedPropertyReadHandler(propertyName, async (options) => { const logic = createTracedLogic(businessLogicName); return await logic.execute(async () => { - return await (businessLogic as (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise)(logic, options); + return await ( + businessLogic as ( + logic: TracedBusinessLogic, + options?: WoT.InteractionOptions + ) => Promise + )(logic, options); }); }) as WoT.PropertyReadHandler ); @@ -284,7 +291,11 @@ export class AutoTracedThing { // Original version with config-based tracing this.thing.setPropertyReadHandler( propertyName, - autoTracedPropertyRead(propertyName, config.build(), businessLogic as (options?: WoT.InteractionOptions) => Promise) as WoT.PropertyReadHandler + autoTracedPropertyRead( + propertyName, + config.build(), + businessLogic as (options?: WoT.InteractionOptions) => Promise + ) as WoT.PropertyReadHandler ); } } @@ -299,14 +310,24 @@ export class AutoTracedThing { setPropertyWriteHandler( propertyName: string, businessLogicName: string, - businessLogic: (logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void, + businessLogic: ( + logic: TracedBusinessLogic, + value: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise | void, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; setPropertyWriteHandler( propertyName: string, businessLogicName: string, - businessLogic: ((value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void) | ((logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void), + businessLogic: + | ((value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void) + | (( + logic: TracedBusinessLogic, + value: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise | void), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -315,14 +336,20 @@ export class AutoTracedThing { } // Check if businessLogic expects TracedBusinessLogic as first parameter - if (businessLogic.length >= 3 || (businessLogic.length >= 2 && businessLogic.toString().includes('logic'))) { + if (businessLogic.length >= 3 || (businessLogic.length >= 2 && businessLogic.toString().includes("logic"))) { // Enhanced version with TracedBusinessLogic injection this.thing.setPropertyWriteHandler( propertyName, tracedPropertyWriteHandler(propertyName, async (value, options) => { const logic = createTracedLogic(businessLogicName); return await logic.execute(async () => { - return await (businessLogic as (logic: TracedBusinessLogic, value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise)(logic, value, options); + return await ( + businessLogic as ( + logic: TracedBusinessLogic, + value: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise + )(logic, value, options); }); }) as WoT.PropertyWriteHandler ); @@ -330,7 +357,11 @@ export class AutoTracedThing { // Original version with config-based tracing this.thing.setPropertyWriteHandler( propertyName, - autoTracedPropertyWrite(propertyName, config.build(), businessLogic as (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise) + autoTracedPropertyWrite( + propertyName, + config.build(), + businessLogic as (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise + ) ); } } @@ -345,14 +376,24 @@ export class AutoTracedThing { setActionHandler( actionName: string, businessLogicName: string, - businessLogic: (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T, + businessLogic: ( + logic: TracedBusinessLogic, + params?: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; - + setActionHandler( actionName: string, businessLogicName: string, - businessLogic: ((params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T) | ((logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T), + businessLogic: + | ((params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T) + | (( + logic: TracedBusinessLogic, + params?: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise | T), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { let config = tracingConfig(businessLogicName); @@ -361,14 +402,20 @@ export class AutoTracedThing { } // Check if businessLogic expects TracedBusinessLogic as first parameter - if (businessLogic.length >= 3 || (businessLogic.length >= 1 && businessLogic.toString().includes('logic'))) { + if (businessLogic.length >= 3 || (businessLogic.length >= 1 && businessLogic.toString().includes("logic"))) { // Enhanced version with TracedBusinessLogic injection this.thing.setActionHandler( actionName, tracedActionHandler(actionName, async (params, options) => { const logic = createTracedLogic(businessLogicName); return await logic.execute(async () => { - return await (businessLogic as (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise)(logic, params, options); + return await ( + businessLogic as ( + logic: TracedBusinessLogic, + params?: WoT.InteractionInput, + options?: WoT.InteractionOptions + ) => Promise + )(logic, params, options); }); }) as WoT.ActionHandler ); @@ -376,7 +423,11 @@ export class AutoTracedThing { // Original version with config-based tracing this.thing.setActionHandler( actionName, - autoTracedAction(actionName, config.build(), businessLogic as (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise) as WoT.ActionHandler + autoTracedAction( + actionName, + config.build(), + businessLogic as (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise + ) as WoT.ActionHandler ); } } From 9a7e0004ca7d40899b421d431180ffd7e0bc2a9e Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Fri, 29 Aug 2025 01:32:09 -0400 Subject: [PATCH 31/34] Updated schema fetching in util.ts --- package-lock.json | 4 +--- util/package.json | 7 ++++--- util/util.ts | 37 +++---------------------------------- 3 files changed, 8 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index e85bb8d..be36cab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9995,9 +9995,6 @@ "typescript": "^4.7.4" } }, - "things/advanced-coffee-machine/http/ts/node_modules/test-things-util": { - "extraneous": true - }, "things/advanced-coffee-machine/http/ts/node_modules/wot-thing-description-types": { "version": "1.1.0-09-November-2023", "license": "W3C-20150513" @@ -10359,6 +10356,7 @@ "@opentelemetry/sdk-trace-node": "1.9.0", "@opentelemetry/semantic-conventions": "1.9.0", "ajv": "^8.12.0", + "wot-thing-description-types": "^1.1.0-09-November-2023", "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" }, "devDependencies": { diff --git a/util/package.json b/util/package.json index 9d25458..c2e498c 100644 --- a/util/package.json +++ b/util/package.json @@ -37,12 +37,13 @@ "license": "EPL-2.0 OR W3C-20150513", "dependencies": { "@opentelemetry/api": "1.9.0", - "@opentelemetry/sdk-trace-node": "1.9.0", "@opentelemetry/exporter-jaeger": "1.9.0", "@opentelemetry/resources": "1.9.0", + "@opentelemetry/sdk-trace-node": "1.9.0", "@opentelemetry/semantic-conventions": "1.9.0", - "wot-typescript-definitions": "0.8.0-SNAPSHOT.29", - "ajv": "^8.12.0" + "ajv": "^8.12.0", + "wot-thing-description-types": "^1.1.0-09-November-2023", + "wot-typescript-definitions": "0.8.0-SNAPSHOT.29" }, "devDependencies": { "@types/node": "^22.1.0", diff --git a/util/util.ts b/util/util.ts index 6149fc6..a6bcf7b 100644 --- a/util/util.ts +++ b/util/util.ts @@ -14,9 +14,8 @@ ********************************************************************************/ import Ajv, { ValidateFunction } from "ajv"; -import * as https from "https"; -import { IncomingMessage } from "http"; import { ChildProcess, spawn } from "node:child_process"; +import * as tdSchema from "wot-thing-description-types"; export type ThingStartResponse = { process?: ChildProcess; @@ -60,40 +59,10 @@ export const getInitiateMain = (mainCmd: string, cmdArgs: string[]): Promise>((resolve, reject) => { - https - .get( - "https://raw.githubusercontent.com/w3c/wot-thing-description/main/validation/td-json-schema-validation.json", - function (response: IncomingMessage) { - const body: Buffer[] = []; - response.on("data", (chunk: Buffer) => { - body.push(chunk); - }); - - response.on("end", () => { - try { - const tdSchema = JSON.parse(Buffer.concat(body).toString()) as Record; - resolve(tdSchema); - } catch (error) { - reject(new Error(`Failed to parse TD schema: ${error}`)); - } - }); - - response.on("error", (error: Error) => { - reject(new Error(`HTTP request failed: ${error.message}`)); - }); - } - ) - .on("error", (error: Error) => { - reject(new Error(`HTTP request failed: ${error.message}`)); - }); -}); - export const getTDValidate = async (): Promise => { - const tdSchema: Record = await getTDJSONSchema; - + // Use the wot-thing-description-types package instead of fetching from remote URL return Promise.resolve({ - validate: ajv.compile(tdSchema), + validate: ajv.compile(tdSchema as Record), message: "Success", }); }; From a43fb54bb6ba54a154c5de1d06db5060b89742e3 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 1 Sep 2025 02:11:51 -0400 Subject: [PATCH 32/34] Made span name handling easier for developer --- .../http/ts/src/main.ts | 9 -------- util/auto-tracing.ts | 21 ++++++------------- util/tsconfig.json | 3 ++- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/things/advanced-coffee-machine/http/ts/src/main.ts b/things/advanced-coffee-machine/http/ts/src/main.ts index d9c5eb5..efc6387 100644 --- a/things/advanced-coffee-machine/http/ts/src/main.ts +++ b/things/advanced-coffee-machine/http/ts/src/main.ts @@ -148,7 +148,6 @@ servient // Property: allAvailableResources tracedThing.setPropertyReadHandler( "allAvailableResources", - "getAllResources", async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { // Validate resource data integrity await logic.withValidation("resourceData", allAvailableResources, async () => { @@ -189,7 +188,6 @@ servient // Property: possibleDrinks tracedThing.setPropertyReadHandler( "possibleDrinks", - "getPossibleDrinks", async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { // Validate drink catalog integrity await logic.withValidation("drinkCatalog", possibleDrinks, async () => { @@ -227,14 +225,12 @@ servient // Property: maintenanceNeeded (simple read) tracedThing.setPropertyReadHandler( "maintenanceNeeded", - "getMaintenanceStatus", async (options?: WoT.InteractionOptions) => maintenanceNeeded ); // Property Read: availableResourceLevel (with URI variables) tracedThing.setPropertyReadHandler( "availableResourceLevel", - "getResourceLevel", async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { // Parse resource ID from URI variables const resourceId = await logic.withProcessing( @@ -262,7 +258,6 @@ servient // Property: schedules tracedThing.setPropertyReadHandler( "schedules", - "getSchedules", async (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => { // Validate system state await logic.withValidation("systemState", { schedulesLength: schedules.length }, async () => { @@ -293,7 +288,6 @@ servient // Property Write: servedCounter tracedThing.setPropertyWriteHandler( "servedCounter", - "updateServedCounter", async (logic: TracedBusinessLogic, val: WoT.InteractionInput) => { // Validate input await logic.withValidation("counterInput", val, async () => { @@ -350,7 +344,6 @@ servient // Property Write: availableResourceLevel tracedThing.setPropertyWriteHandler( "availableResourceLevel", - "updateResourceLevel", async (logic: TracedBusinessLogic, val: WoT.InteractionInput, options?: WoT.InteractionOptions) => { // Parse and validate resource ID and new level const { resourceId, newLevel } = await logic.withProcessing( @@ -421,7 +414,6 @@ servient // Action: makeDrink tracedThing.setActionHandler( - "makeDrink", "makeDrink", async (logic: TracedBusinessLogic, params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => { // Parse parameters with defaults @@ -555,7 +547,6 @@ servient // Action: setSchedule tracedThing.setActionHandler( - "setSchedule", "setSchedule", async (logic: TracedBusinessLogic, params?: WoT.InteractionInput) => { // Parse and validate schedule data diff --git a/util/auto-tracing.ts b/util/auto-tracing.ts index d05b1e4..3d87f3c 100644 --- a/util/auto-tracing.ts +++ b/util/auto-tracing.ts @@ -245,27 +245,24 @@ export class AutoTracedThing { setPropertyReadHandler( propertyName: string, - businessLogicName: string, businessLogic: (options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; setPropertyReadHandler( propertyName: string, - businessLogicName: string, businessLogic: (logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; setPropertyReadHandler( propertyName: string, - businessLogicName: string, businessLogic: | ((options?: WoT.InteractionOptions) => Promise | T) | ((logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { - let config = tracingConfig(businessLogicName); + let config = tracingConfig(propertyName); if (configBuilder) { config = configBuilder(config); } @@ -276,7 +273,7 @@ export class AutoTracedThing { this.thing.setPropertyReadHandler( propertyName, tracedPropertyReadHandler(propertyName, async (options) => { - const logic = createTracedLogic(businessLogicName); + const logic = createTracedLogic(propertyName); return await logic.execute(async () => { return await ( businessLogic as ( @@ -302,14 +299,12 @@ export class AutoTracedThing { setPropertyWriteHandler( propertyName: string, - businessLogicName: string, businessLogic: (value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; setPropertyWriteHandler( propertyName: string, - businessLogicName: string, businessLogic: ( logic: TracedBusinessLogic, value: WoT.InteractionInput, @@ -320,7 +315,6 @@ export class AutoTracedThing { setPropertyWriteHandler( propertyName: string, - businessLogicName: string, businessLogic: | ((value: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | void) | (( @@ -330,7 +324,7 @@ export class AutoTracedThing { ) => Promise | void), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { - let config = tracingConfig(businessLogicName); + let config = tracingConfig(propertyName); if (configBuilder) { config = configBuilder(config); } @@ -341,7 +335,7 @@ export class AutoTracedThing { this.thing.setPropertyWriteHandler( propertyName, tracedPropertyWriteHandler(propertyName, async (value, options) => { - const logic = createTracedLogic(businessLogicName); + const logic = createTracedLogic(propertyName); return await logic.execute(async () => { return await ( businessLogic as ( @@ -368,14 +362,12 @@ export class AutoTracedThing { setActionHandler( actionName: string, - businessLogicName: string, businessLogic: (params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T, configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void; setActionHandler( actionName: string, - businessLogicName: string, businessLogic: ( logic: TracedBusinessLogic, params?: WoT.InteractionInput, @@ -386,7 +378,6 @@ export class AutoTracedThing { setActionHandler( actionName: string, - businessLogicName: string, businessLogic: | ((params?: WoT.InteractionInput, options?: WoT.InteractionOptions) => Promise | T) | (( @@ -396,7 +387,7 @@ export class AutoTracedThing { ) => Promise | T), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { - let config = tracingConfig(businessLogicName); + let config = tracingConfig(actionName); if (configBuilder) { config = configBuilder(config); } @@ -407,7 +398,7 @@ export class AutoTracedThing { this.thing.setActionHandler( actionName, tracedActionHandler(actionName, async (params, options) => { - const logic = createTracedLogic(businessLogicName); + const logic = createTracedLogic(actionName); return await logic.execute(async () => { return await ( businessLogic as ( diff --git a/util/tsconfig.json b/util/tsconfig.json index cfb318d..1bad4f9 100644 --- a/util/tsconfig.json +++ b/util/tsconfig.json @@ -24,5 +24,6 @@ "strictNullChecks": true, "forceConsistentCasingInFileNames": true }, - "include": ["*.ts"] + "include": ["*.ts"], + "exclude": ["dist", "node_modules"] } From 13161c8f3615896c5870facb7bc8dce2009d7273 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 1 Sep 2025 13:02:11 -0400 Subject: [PATCH 33/34] Updated span names and added more info on readme --- README.md | 29 ++++++++++++++++++++---- things/advanced-coffee-machine/README.md | 9 ++++++++ util/auto-tracing.ts | 10 ++++---- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 903f8bd..3e43b4c 100644 --- a/README.md +++ b/README.md @@ -76,10 +76,14 @@ Wrap your WoT Thing with auto-tracing to get detailed OpenTelemetry spans for va import { createAutoTracedThing, TracedBusinessLogic } from "../../util/dist/auto-tracing"; const tracedThing = createAutoTracedThing(thing); -// Enhanced tracing with injected logic -tracedThing.setPropertyReadHandler("prop", "operation", async (logic: TracedBusinessLogic, options) => { - await logic.withValidation("type", data, async () => {}); - return await logic.withDatabase("select", "table", async () => {}); +// Property writes get ".read" suffix +tracedThing.setPropertyReadHandler("allAvailableResources", async (options) => { + return getResources(); // Span: "allAvailableResources.read" +}); + +// Property writes get ".write" suffix +tracedThing.setPropertyWriteHandler("servedCounter", async (value) => { + updateCounter(value); // Span: "servedCounter.write" }); ``` @@ -198,3 +202,20 @@ For Node.js-based devices, we use npm workspaces and running `npm install` at th Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:8084](http://localhost:8084) in your browser (Jaeger UI). Traces are sent to the Jaeger collector on port 8085. Enhanced auto-tracing automatically injects `TracedBusinessLogic` for detailed span creation without redundancy. Function signatures determine tracing mode. + +### Testing and Error Visibility + +The project includes comprehensive test suites that are also traced and visible in Jaeger: + +- **Thing Description (TD) validation tests** - Test if the exposed TD is valid according to W3C WoT standards +- **Thing Model (TM) validation tests** - Validate the Thing Model against the schema +- **Integration tests** - Test actual interactions with the Things + +When tests run, they appear in Jaeger with clear span names like `td.test` or `tm.test`. Failed tests show up as **error spans** with red highlighting in the Jaeger UI, making it easy to: + +- **Debug test failures** by examining the error details and stack traces in span logs +- **Track test performance** and identify slow validation steps +- **Monitor CI/CD pipelines** by observing test execution patterns +- **Correlate test failures** with specific Thing operations or configurations + +Test spans include detailed attributes about what was validated, error messages for failures, and timing information for performance analysis. diff --git a/things/advanced-coffee-machine/README.md b/things/advanced-coffee-machine/README.md index 03aa08d..6218d42 100644 --- a/things/advanced-coffee-machine/README.md +++ b/things/advanced-coffee-machine/README.md @@ -14,6 +14,7 @@ This advanced coffee machine simulates a device with resource management, drink - Make drink and set schedule actions - Out-of-resource event - HTTP protocol implementation +- **Distributed tracing with OpenTelemetry** - All interactions are automatically traced with Jaeger ## Protocol Support @@ -27,3 +28,11 @@ This advanced coffee machine simulates a device with resource management, drink ## Usage The coffee machine exposes properties, actions, and events for managing drinks and resources. See the [Thing Description](http://plugfest.thingweb.io/http-advanced-coffee-machine) for details on endpoints and data formats. + +## Tracing + +This implementation uses the centralized tracing utilities from the `util` package. All property reads, writes, and action invocations are automatically traced with OpenTelemetry: + +- Property reads generate spans named `{propertyName}.read` (e.g., `allAvailableResources.read`) +- Property writes generate spans named `{propertyName}.write` (e.g., `servedCounter.write`) +- Action invocations generate spans named `{actionName}` (e.g., `makeDrink`) diff --git a/util/auto-tracing.ts b/util/auto-tracing.ts index 3d87f3c..27df3dc 100644 --- a/util/auto-tracing.ts +++ b/util/auto-tracing.ts @@ -262,7 +262,8 @@ export class AutoTracedThing { | ((logic: TracedBusinessLogic, options?: WoT.InteractionOptions) => Promise | T), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { - let config = tracingConfig(propertyName); + const spanName = `${propertyName}.read`; + let config = tracingConfig(spanName); if (configBuilder) { config = configBuilder(config); } @@ -273,7 +274,7 @@ export class AutoTracedThing { this.thing.setPropertyReadHandler( propertyName, tracedPropertyReadHandler(propertyName, async (options) => { - const logic = createTracedLogic(propertyName); + const logic = createTracedLogic(spanName); return await logic.execute(async () => { return await ( businessLogic as ( @@ -324,7 +325,8 @@ export class AutoTracedThing { ) => Promise | void), configBuilder?: (builder: TracingConfigBuilder) => TracingConfigBuilder ): void { - let config = tracingConfig(propertyName); + const spanName = `${propertyName}.write`; + let config = tracingConfig(spanName); if (configBuilder) { config = configBuilder(config); } @@ -335,7 +337,7 @@ export class AutoTracedThing { this.thing.setPropertyWriteHandler( propertyName, tracedPropertyWriteHandler(propertyName, async (value, options) => { - const logic = createTracedLogic(propertyName); + const logic = createTracedLogic(spanName); return await logic.execute(async () => { return await ( businessLogic as ( From 68cb5d494887cf6904b03cf96fb26a08589383f5 Mon Sep 17 00:00:00 2001 From: sailalithkanumuri8 Date: Mon, 1 Sep 2025 13:02:47 -0400 Subject: [PATCH 34/34] Updated README --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e43b4c..ffac0fb 100644 --- a/README.md +++ b/README.md @@ -203,9 +203,7 @@ Distributed tracing is enabled using OpenTelemetry and Jaeger. To view all trace Enhanced auto-tracing automatically injects `TracedBusinessLogic` for detailed span creation without redundancy. Function signatures determine tracing mode. -### Testing and Error Visibility - -The project includes comprehensive test suites that are also traced and visible in Jaeger: +Also, there is comprehensive test suites that are also traced and visible in Jaeger: - **Thing Description (TD) validation tests** - Test if the exposed TD is valid according to W3C WoT standards - **Thing Model (TM) validation tests** - Validate the Thing Model against the schema