diff --git a/.gitignore b/.gitignore index 3f6d2b15..dae2806f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ npm-debug.log* build .DS_Store tmp -.vscode +/packages/mockotlpserver/db diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..25fa6215 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/package-lock.json b/package-lock.json index 910c43d7..18a56b0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,14 @@ "@elastic/opentelemetry-node": "file:./packages/opentelemetry-node" }, "devDependencies": { + "@types/node": "^20.10.5", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.0", "eslint-plugin-n": "^16.3.1", "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-promise": "^6.1.1" + "eslint-plugin-promise": "^6.1.1", + "typescript": "^4.4.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -1551,6 +1553,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/http-server": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@types/http-server/-/http-server-0.12.4.tgz", + "integrity": "sha512-vsn4pvP2oRFALLuM5Rca6qUmSPG7u0VNjOuqvL57l3bKldQRWdUZPeSiARhzagDxgfNCHn/o8WlWk4KinBauUg==", + "dev": true, + "dependencies": { + "@types/connect": "*" + } + }, "node_modules/@types/ioredis4": { "name": "@types/ioredis", "version": "4.28.10", @@ -1629,8 +1640,9 @@ } }, "node_modules/@types/node": { - "version": "20.10.0", - "license": "MIT", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dependencies": { "undici-types": "~5.26.4" } @@ -1887,6 +1899,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -1905,6 +1925,17 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -1996,7 +2027,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -2019,7 +2049,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2067,6 +2096,14 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2140,7 +2177,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -2669,6 +2705,11 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/execa": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", @@ -2830,6 +2871,25 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -2916,7 +2976,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", @@ -3033,7 +3092,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3060,7 +3118,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -3069,7 +3126,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -3081,7 +3137,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3093,7 +3148,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -3126,6 +3180,64 @@ "node": ">= 0.4" } }, + "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==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.2", "dev": true, @@ -3147,6 +3259,17 @@ "node": ">=14.18.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", @@ -3655,6 +3778,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "license": "MIT" @@ -3705,6 +3833,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -3733,11 +3872,21 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/module-details-from-path": { "version": "1.0.3", "license": "MIT" @@ -3802,7 +3951,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3922,6 +4070,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -4058,6 +4214,27 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/postgres-array": { "version": "2.0.0", "dev": true, @@ -4161,6 +4338,20 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4217,6 +4408,11 @@ "node": ">=8.6.0" } }, + "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==" + }, "node_modules/resolve": { "version": "1.22.8", "license": "MIT", @@ -4408,6 +4604,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==" + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -4430,6 +4631,16 @@ "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==" + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + }, "node_modules/semver": { "version": "7.5.4", "license": "ISC", @@ -4447,7 +4658,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dev": true, "dependencies": { "define-data-property": "^1.1.1", "get-intrinsic": "^1.2.1", @@ -4501,7 +4711,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -4621,7 +4830,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -4797,6 +5005,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -4816,6 +5037,17 @@ "version": "5.26.5", "license": "MIT" }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -4834,11 +5066,27 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, "license": "BSD-2-Clause" }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "dev": true, @@ -4980,6 +5228,7 @@ "dependencies": { "@grpc/grpc-js": "^1.9.13", "@grpc/proto-loader": "^0.7.10", + "http-server": "^14.1.1", "protobufjs": "^7.2.5", "safe-stable-stringify": "^2.4.3" }, @@ -4988,10 +5237,11 @@ "@opentelemetry/exporter-trace-otlp-grpc": "^0.46.0", "@opentelemetry/exporter-trace-otlp-http": "^0.46.0", "@opentelemetry/exporter-trace-otlp-proto": "^0.46.0", - "@opentelemetry/sdk-node": "^0.46.0" + "@opentelemetry/sdk-node": "^0.46.0", + "@types/http-server": "^0.12.4" }, "engines": { - "node": ">=14" + "node": ">=14.17.0" } }, "packages/mockotlpserver/node_modules/@opentelemetry/api-logs": { @@ -5374,6 +5624,8 @@ "@opentelemetry/exporter-trace-otlp-http": "^0.46.0", "@opentelemetry/exporter-trace-otlp-proto": "^0.46.0", "@opentelemetry/sdk-node": "^0.46.0", + "@types/http-server": "^0.12.4", + "http-server": "^14.1.1", "protobufjs": "^7.2.5", "safe-stable-stringify": "^2.4.3" }, @@ -6547,6 +6799,15 @@ "version": "2.0.4", "dev": true }, + "@types/http-server": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@types/http-server/-/http-server-0.12.4.tgz", + "integrity": "sha512-vsn4pvP2oRFALLuM5Rca6qUmSPG7u0VNjOuqvL57l3bKldQRWdUZPeSiARhzagDxgfNCHn/o8WlWk4KinBauUg==", + "dev": true, + "requires": { + "@types/connect": "*" + } + }, "@types/ioredis4": { "version": "npm:@types/ioredis@4.28.10", "dev": true, @@ -6615,7 +6876,9 @@ } }, "@types/node": { - "version": "20.10.0", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "requires": { "undici-types": "~5.26.4" } @@ -6800,6 +7063,14 @@ "is-shared-array-buffer": "^1.0.2" } }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "requires": { + "lodash": "^4.17.14" + } + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -6812,6 +7083,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "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==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -6878,7 +7157,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dev": true, "requires": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -6895,7 +7173,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6927,6 +7204,11 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6976,7 +7258,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dev": true, "requires": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -7355,6 +7636,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "execa": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", @@ -7486,6 +7772,11 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -7547,7 +7838,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dev": true, "requires": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", @@ -7625,7 +7915,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "requires": { "get-intrinsic": "^1.1.3" } @@ -7645,14 +7934,12 @@ "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 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-property-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, "requires": { "get-intrinsic": "^1.2.2" } @@ -7660,14 +7947,12 @@ "has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", @@ -7684,6 +7969,49 @@ "function-bind": "^1.1.2" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "requires": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + } + }, "https-proxy-agent": { "version": "7.0.2", "dev": true, @@ -7698,6 +8026,14 @@ "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ignore": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", @@ -8046,6 +8382,11 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.camelcase": { "version": "4.3.0" }, @@ -8083,6 +8424,11 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -8101,8 +8447,15 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } }, "module-details-from-path": { "version": "1.0.3" @@ -8143,8 +8496,7 @@ "object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" }, "object-keys": { "version": "1.1.1", @@ -8228,6 +8580,11 @@ "is-wsl": "^2.2.0" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -8321,6 +8678,26 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "requires": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "postgres-array": { "version": "2.0.0", "dev": true @@ -8385,6 +8762,14 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -8413,6 +8798,11 @@ "resolve": "^1.22.1" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.8", "requires": { @@ -8533,6 +8923,11 @@ "isarray": "^2.0.5" } }, + "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==" + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -8549,6 +8944,16 @@ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + }, "semver": { "version": "7.5.4", "requires": { @@ -8559,7 +8964,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dev": true, "requires": { "define-data-property": "^1.1.1", "get-intrinsic": "^1.2.1", @@ -8600,7 +9004,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -8682,7 +9085,6 @@ "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, "requires": { "has-flag": "^4.0.0" } @@ -8805,6 +9207,12 @@ "is-typed-array": "^1.1.9" } }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -8820,6 +9228,14 @@ "undici-types": { "version": "5.26.5" }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "requires": { + "qs": "^6.4.0" + } + }, "untildify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", @@ -8835,10 +9251,23 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "webidl-conversions": { "version": "3.0.1", "dev": true }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" + } + }, "whatwg-url": { "version": "5.0.0", "dev": true, diff --git a/package.json b/package.json index f1de521a..365176f7 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,13 @@ "@elastic/opentelemetry-node": "file:./packages/opentelemetry-node" }, "devDependencies": { + "@types/node": "^20.10.5", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.0", "eslint-plugin-n": "^16.3.1", "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-promise": "^6.1.1" + "eslint-plugin-promise": "^6.1.1", + "typescript": "^4.4.4" } } diff --git a/packages/mockotlpserver/db/README.md b/packages/mockotlpserver/db/README.md new file mode 100644 index 00000000..66ad2fb2 --- /dev/null +++ b/packages/mockotlpserver/db/README.md @@ -0,0 +1,3 @@ +# UI traces folder + +this folder is to place all the traces data we want to plt in the web ui. \ No newline at end of file diff --git a/packages/mockotlpserver/lib/client.js b/packages/mockotlpserver/lib/client.js deleted file mode 100644 index 9ac2b02e..00000000 --- a/packages/mockotlpserver/lib/client.js +++ /dev/null @@ -1,62 +0,0 @@ -const {resolve} = require('path'); - -const grpc = require('@grpc/grpc-js'); -const loader = require('@grpc/proto-loader'); - -const prefix = resolve(__dirname, '../opentelemetry/proto'); -const pkgsBase = resolve(__dirname, '..'); -const traceDefinition = loader.loadSync( - `${prefix}/collector/trace/v1/trace_service.proto`, - { - includeDirs: [pkgsBase], - } -); -const traceDescriptor = grpc.loadPackageDefinition(traceDefinition); -const traceNamespace = traceDescriptor.opentelemetry.proto.collector.trace.v1; - -const client = new traceNamespace.TraceService( - 'localhost:4317', - grpc.credentials.createInsecure() -); - -client.Export( - { - resourceSpans: [ - { - resource: { - attributes: [ - { - key: 'service.name', - value: { - stringValue: 'unknown_service:node', - }, - }, - { - key: 'telemetry.sdk.language', - value: { - stringValue: 'nodejs', - }, - }, - { - key: 'telemetry.sdk.name', - value: { - stringValue: 'opentelemetry', - }, - }, - { - key: 'telemetry.sdk.version', - value: { - stringValue: '1.15.2', - }, - }, - ], - droppedAttributesCount: 0, - }, - }, - ], - }, - (err, response) => { - console.log('From server error', err); - console.log('From server response', response); - } -); diff --git a/packages/mockotlpserver/lib/diagch.js b/packages/mockotlpserver/lib/diagch.js index fb1c6d26..0d2b97d5 100644 --- a/packages/mockotlpserver/lib/diagch.js +++ b/packages/mockotlpserver/lib/diagch.js @@ -5,8 +5,15 @@ const diagnostics_channel = require('diagnostics_channel'); // Keep a references to channels created for `ch.subscribe(name)` to avoid // https://github.com/nodejs/node/issues/42170 bug with Node.js <16.17.0. +/** @type {Record} */ const diagchFromName = {}; +/** + * Returns the diagnostics channel with the given name + * + * @param {string} name + * @returns {diagnostics_channel.Channel} + */ function diagchGet(name) { if (!(name in diagchFromName)) { diagchFromName[name] = diagnostics_channel.channel(name); @@ -14,6 +21,12 @@ function diagchGet(name) { return diagchFromName[name]; } +/** + * Subscribes a message handler to the diagnostics channel with the given name + * + * @param {string} name + * @param {(msg: any) => void} onMessage + */ function diagchSub(name, onMessage) { if (diagnostics_channel.subscribe) { // `diagnostics_channel.subscribe` was added in Node.js 16.17.0. diff --git a/packages/mockotlpserver/lib/grpc.js b/packages/mockotlpserver/lib/grpc.js index 7be364b4..4dafb588 100644 --- a/packages/mockotlpserver/lib/grpc.js +++ b/packages/mockotlpserver/lib/grpc.js @@ -15,6 +15,11 @@ const { // but maybe its better to have a submodule like otel-js does const prefix = resolve(__dirname, '../opentelemetry/proto'); const pkgsBase = resolve(__dirname, '..'); + +// TODO: type si `any`since we mutate the properties to a diffrent type +// also we do not have type info from the proto files. Maybe we can provide +// a generic later +/** @type {any} */ const packages = { logs: '/collector/logs/v1/logs_service.proto', metrics: '/collector/metrics/v1/metrics_service.proto', @@ -25,21 +30,29 @@ for (const [name, path] of Object.entries(packages)) { const definition = loader.loadSync(`${prefix}${path}`, { includeDirs: [pkgsBase], }); + /** @type {any} */ const descriptor = grpc.loadPackageDefinition(definition); const namespace = descriptor.opentelemetry.proto.collector[name].v1; + descriptor.opentelemetry; + packages[name] = namespace; } // helper functions function intakeTraces(call, callback) { - diagchGet(CH_OTLP_V1_TRACE).publish(call.request); callback(null, { partial_success: { rejected_spans: 0, }, }); + // We publish into diagnostics channel after returning a response to the client to avoid not returning + // a response if one of the handlers throws (the hanlders run synchronously in the + // same context). + // https://nodejs.org/api/diagnostics_channel.html#channelpublishmessage + // TODO: maybe surround with try/catch to not blow up the server? + diagchGet(CH_OTLP_V1_TRACE).publish(call.request); } // function intakeMetrics(call, callback) { @@ -53,7 +66,7 @@ function intakeTraces(call, callback) { /** * * @param {Object} opts - * @param {import('./luggite').Logger} opts.log + * @param {import('./luggite').LoggerInstance} opts.log * @param {string} opts.hostname * @param {number} opts.port */ diff --git a/packages/mockotlpserver/lib/http.js b/packages/mockotlpserver/lib/http.js index ad30b01f..67f7c0f7 100644 --- a/packages/mockotlpserver/lib/http.js +++ b/packages/mockotlpserver/lib/http.js @@ -61,9 +61,9 @@ function badRequest(res) { } /** - * @param {Logger} log + * @param {import('./luggite').LoggerInstance} _log * @param {Buffer} buff - * @param {http.IncomingMessage} req + * @param {http.IncomingMessage} _req */ function jsonParser(_log, buff, _req) { const reqText = buff.toString('utf-8'); @@ -73,7 +73,7 @@ function jsonParser(_log, buff, _req) { } /** - * @param {Logger} log + * @param {import('./luggite').LoggerInstance} _log * @param {Buffer} buff * @param {http.IncomingMessage} req */ @@ -102,8 +102,8 @@ function protoParser(_log, buff, req) { /** * - * @param {Logger} log - * @param {Buffer} buff + * @param {import('./luggite').LoggerInstance} log + * @param {Buffer} _buff * @param {http.IncomingMessage} req */ function unknownParser(log, _buff, req) { @@ -117,7 +117,7 @@ function unknownParser(log, _buff, req) { /** * * @param {Object} opts - * @param {import('./luggite').Logger} opts.log + * @param {import('./luggite').LoggerInstance} opts.log * @param {string} opts.hostname * @param {number} opts.port */ @@ -132,20 +132,6 @@ function startHttp(opts) { return badRequest(res); } - const contentType = req.headers['content-type']; - const parseData = parsersMap[contentType] || unknownParser; - const reqBuffer = Buffer.concat(chunks); - const reqUrl = req.url; - const data = parseData(log, reqBuffer, req); - const diagCh = diagChFromReqUrl(reqUrl); - if (!data) { - log.warn({contentType, reqUrl}, 'do not know how to parse req'); - } else if (!diagCh) { - log.warn({reqUrl}, 'could not find diagnostic channel for req'); - } else { - diagCh.publish(data); - } - // TODO: in future response may add some header to communicate back // some information about // - the collector @@ -155,16 +141,44 @@ function startHttp(opts) { // because of: high load, sample rate changed, et al?? res.writeHead(200); res.end( + // TODO: return a response based on the service proto file if needed (check if the properties are camelCase) + // PS: probably the partial_success is optional and we could send an empty object back + // - logs { partial_success? { rejected_log_records: number; error_message?: string } } + // - metrics { partial_success? { rejected_data_points: number; error_message?: string } } + // - traces { partial_success? { rejected_spans: number; error_message?: string } } JSON.stringify({ ok: 1, }) ); + + // We publish into diagnostics channel after returning a response to the client to avoid not returning + // a response if one of the handlers throws (the hanlders run synchronously in the + // same context). + // https://nodejs.org/api/diagnostics_channel.html#channelpublishmessage + // TODO: maybe surround with try/catch to not blow up the server? + const contentType = req.headers['content-type']; + const parseData = parsersMap[contentType] || unknownParser; + const reqBuffer = Buffer.concat(chunks); + const reqUrl = req.url; + const data = parseData(log, reqBuffer, req); + const diagCh = diagChFromReqUrl(reqUrl); + if (!data) { + log.warn({contentType, reqUrl}, 'do not know how to parse req'); + } else if (!diagCh) { + log.warn({reqUrl}, 'could not find diagnostic channel for req'); + } else { + diagCh.publish(data); + } }); req.resume(); }); server.listen(port, hostname, function () { + // /** @type {import('net').AddressInfo} */ + // TODO: the api retours string | AddressInfo + // we should cover this case and use type assertions + /** @type {any} */ const addr = server.address(); const endpoint = addr.family === 'IPv6' diff --git a/packages/mockotlpserver/lib/index.js b/packages/mockotlpserver/lib/index.js index 3ee01d92..a69cead6 100644 --- a/packages/mockotlpserver/lib/index.js +++ b/packages/mockotlpserver/lib/index.js @@ -1,6 +1,7 @@ const luggite = require('./luggite'); const {startHttp} = require('./http'); const {startGrpc} = require('./grpc'); +const {startUi} = require('./ui'); const {InspectPrinter} = require('./printers'); const log = luggite.createLogger({name: 'mockotlpserver'}); @@ -11,6 +12,7 @@ const log = luggite.createLogger({name: 'mockotlpserver'}); const DEFAULT_HOSTNAME = 'localhost'; const DEFAULT_HTTP_PORT = 4318; const DEFAULT_GRPC_PORT = 4317; +const DEFAULT_UI_PORT = 8080; // Start a server which accepts incoming OTLP/HTTP calls and publishes // received request data to the `otlp.*` diagnostic channels. @@ -32,5 +34,11 @@ startGrpc({ port: DEFAULT_GRPC_PORT, }); -const printer = new InspectPrinter(); +startUi({ + log, + hostname: DEFAULT_HOSTNAME, + port: DEFAULT_UI_PORT, +}); + +const printer = new InspectPrinter(log); printer.subscribe(); diff --git a/packages/mockotlpserver/lib/luggite.js b/packages/mockotlpserver/lib/luggite.js index 2d28dfb0..0535314e 100644 --- a/packages/mockotlpserver/lib/luggite.js +++ b/packages/mockotlpserver/lib/luggite.js @@ -12,6 +12,21 @@ var stream = require('stream'); var safeStableStringify = require('safe-stable-stringify'); +/** + * TODO: add properties here + * @typedef {Object} LogRecord + */ + +/** + * @typedef {Object} LoggerInstance + * @property {function(Record | string, ...any): undefined} fatal + * @property {function(Record | string, ...any): undefined} error + * @property {function(Record | string, ...any): undefined} warn + * @property {function(Record | string, ...any): undefined} info + * @property {function(Record | string, ...any): undefined} debug + * @property {function(Record | string, ...any): undefined} trace + */ + var EOL = '\n'; //---- Internal support stuff @@ -73,19 +88,20 @@ Object.keys(levelFromName).forEach(function (name) { /** * Resolve a level number, name (upper or lowercase) to a level number value. * - * @param nameOrNum {String|Number} A level name (case-insensitive) or positive + * @param {string|number} nameOrNum A level name (case-insensitive) or positive * integer level. * @api public */ function resolveLevel(nameOrNum) { var level; var type = typeof nameOrNum; - if (type === 'string') { + + if (typeof nameOrNum === 'string') { level = levelFromName[nameOrNum.toLowerCase()]; if (!level) { throw new Error(format('unknown level name: "%s"', nameOrNum)); } - } else if (type !== 'number') { + } else if (typeof nameOrNum !== 'number') { throw new TypeError( format('cannot resolve level: invalid arg (%s):', type, nameOrNum) ); @@ -99,6 +115,11 @@ function resolveLevel(nameOrNum) { return level; } +/** + * Tells if the object is writable + * @param {any} obj + * @returns {boolean} + */ function isWritable(obj) { if (obj instanceof stream.Writable) { return true; @@ -132,7 +153,9 @@ function Logger(opts) { } /** - * Add a stream + * Adds a stream + * @param {any} s + * @param {number|string} [defaultLevel] */ Logger.prototype._addStream = function _addStream(s, defaultLevel) { if (defaultLevel === null || defaultLevel === undefined) { @@ -187,6 +210,8 @@ Logger.prototype._addStream = function _addStream(s, defaultLevel) { * Set Usage: * log.level(INFO) // set all streams to level INFO * log.level('info') // can use 'info' et al aliases + * + * @param {number | string} value */ Logger.prototype.level = function level(value) { if (value === undefined) { @@ -205,8 +230,8 @@ Logger.prototype.level = function level(value) { * * Pre-condition: This is only called if there is at least one serializer. * - * @param fields (Object) The log record fields. - * @param excludeFields (Object) Optional mapping of keys to `true` for + * @param {Object} fields The log record fields. + * @param {Object} excludeFields Optional mapping of keys to `true` for * keys to NOT apply a serializer. */ Logger.prototype._applySerializers = function (fields, excludeFields) { @@ -245,7 +270,7 @@ Logger.prototype._applySerializers = function (fields, excludeFields) { /** * Emit a log record. * - * @param rec {log record} + * @param {LogRecord} rec The log record */ Logger.prototype._emit = function (rec) { var i; @@ -267,6 +292,11 @@ Logger.prototype._emit = function (rec) { /** * Build a record object suitable for emitting from the arguments * provided to the a log emitter. + * + * @param {any} log + * @param {any} minLevel + * @param {Array} args + * @returns {LogRecord} */ function mkRecord(log, minLevel, args) { var excludeFields, fields, msgArgs; @@ -333,6 +363,9 @@ function mkRecord(log, minLevel, args) { /** * Build a log emitter function for level minLevel. I.e. this is the * creator of `log.info`, `log.error`, etc. + * + * @param {number} minLevel + * @returns {(fields?: Record, msg?: string) => void} */ function mkLogEmitter(minLevel) { return function LOG(...args) { @@ -388,12 +421,16 @@ Logger.prototype.error = mkLogEmitter(ERROR); Logger.prototype.fatal = mkLogEmitter(FATAL); // ---- Serializers -// A serializer is a function that serializes a JavaScript object to a -// JSON representation for logging. There is a standard set of presumed -// interesting objects in node.js-land. - -// Serialize an Error object -// (Core error properties are enumerable in node 0.4, not in 0.6). +/** + * A serializer is a function that serializes a JavaScript object to a + * JSON representation for logging. There is a standard set of presumed + * interesting objects in node.js-land. + * + * Serialize an Error object + * (Core error properties are enumerable in node 0.4, not in 0.6). + * @param {Error | Object} err + * @returns {Object} + */ var errSerializer = function (err) { if (!err || !err.stack) return err; var obj = { @@ -408,7 +445,14 @@ var errSerializer = function (err) { //---- Exports +/** + * @param {any} options + * @returns {LoggerInstance} + */ function createLogger(options) { + // TODO: I do not know yet if possible to document Function + prototype + // edit in JsDoc + // @ts-ignore return new Logger(options); } diff --git a/packages/mockotlpserver/lib/printers.js b/packages/mockotlpserver/lib/printers.js index 7810b760..52d1888a 100644 --- a/packages/mockotlpserver/lib/printers.js +++ b/packages/mockotlpserver/lib/printers.js @@ -14,23 +14,57 @@ const { CH_OTLP_V1_TRACE, } = require('./diagch'); +// TODO: typewise it would be nice to have a type that forces printers +// to have at least one of the functions +// We can consider do composition instead of inheritance +// const Printer = { +// subscribe () { ... } +// } +// const InspectPrinter = { ... } + +// function getPrinterInstance (specificPrinter) { +// return Object.assign({}, Printer, specificPrinter); +// } + +// // usage +// const inspectPrinter = getPrinterInstance(InspectPrinter); +// inspectPrinter.subscribe(); + +/** Abstract printer class */ class Printer { + constructor(log) { + this._log = log; + } subscribe() { - if (typeof this.printTrace === 'function') { - diagchSub(CH_OTLP_V1_TRACE, this.printTrace.bind(this)); + /** @type {any} */ + const inst = this; + if (typeof inst.printTrace === 'function') { + // TODO: do this for the other print*(). + diagchSub(CH_OTLP_V1_TRACE, (...args) => { + try { + inst.printTrace(...args); + } catch (err) { + console.error('TODO .printTrace threw: %s', err); + } + }); } - if (typeof this.printMetrics === 'function') { - diagchSub(CH_OTLP_V1_METRICS, this.printMetrics.bind(this)); + if (typeof inst.printMetrics === 'function') { + diagchSub(CH_OTLP_V1_METRICS, inst.printMetrics.bind(this)); } - if (typeof this.printLogs === 'function') { - diagchSub(CH_OTLP_V1_LOGS, this.printTrace.bind(this)); + if (typeof inst.printLogs === 'function') { + diagchSub(CH_OTLP_V1_LOGS, inst.printTrace.bind(this)); } } } +/** + * Specific printer for inspect format + * @extends {Printer} + */ class InspectPrinter extends Printer { - constructor() { - super(); + constructor(log) { + super(log); + /** @private */ this._inspectOpts = {depth: 9, breakLength: process.stdout.columns}; } printTrace(trace) { @@ -45,5 +79,6 @@ class InspectPrinter extends Printer { } module.exports = { + Printer, InspectPrinter, }; diff --git a/packages/mockotlpserver/lib/types.d.ts b/packages/mockotlpserver/lib/types.d.ts new file mode 100644 index 00000000..c208ce8c --- /dev/null +++ b/packages/mockotlpserver/lib/types.d.ts @@ -0,0 +1,44 @@ +import type EventEmitter from 'events'; + +type Long = { low: number; high: number; unsigned: boolean }; +type StringValue = { stringValue: string }; +type IntValue = { intValue: Long }; + +export type AttributeValue = StringValue | IntValue; +export interface Attribute { + key: string; + value: AttributeValue; +} + +export interface Span { + traceId: Buffer; + spanId: Buffer; + parentSpanId: Buffer; + name: string; + kind: number; + startTimeUnixNano: Long; + endTimeUnixNano: Long; + attributes: Attribute[]; + droppedAttributesCount: number; + events?: any[]; + droppedEventsCount: number; + links?: any[]; + droppedLinksCount: number; + status: { code: number }; +} + +export interface ScopeSpan { + scope: { name: string; version: string }; + spans: Span[]; +} + +export interface ResourceSpan { + resource: { + attributes: Attribute[]; + }, + scopeSpans: ScopeSpan[]; +} + +export interface ExportTraceServiceRequest { + resourceSpans: ResourceSpan[]; +} diff --git a/packages/mockotlpserver/lib/ui.js b/packages/mockotlpserver/lib/ui.js new file mode 100644 index 00000000..52fc5823 --- /dev/null +++ b/packages/mockotlpserver/lib/ui.js @@ -0,0 +1,94 @@ +const fs = require('fs'); +const path = require('path'); + +const httpServer = require('http-server'); + +const {Printer} = require('./printers'); + +// helper functions + +/** + * @typedef {Object} SpanTree + * @property {import('./types').Span} span + * @property {import('./types').Span[]} children + */ + +/** + * @typedef {Object} TraceTree + * @property {string} id + * @property {SpanTree[]} children + */ + +class UiPrinter extends Printer { + constructor(log) { + super(log); + this._dbDir = path.resolve(__dirname, '../db'); + } + + /** + * Prints into files the spns belonging to a trace + * @param {import('./types').ExportTraceServiceRequest} traceReq + */ + printTrace(traceReq) { + /** @type {Map} */ + const tracesMap = new Map(); + + // Group all spans by trace + traceReq.resourceSpans.forEach((resSpan) => { + resSpan.scopeSpans.forEach((scopeSpan) => { + scopeSpan.spans.forEach((span) => { + const traceId = span.traceId.toString('hex'); + let traceSpans = tracesMap.get(traceId); + + if (!traceSpans) { + traceSpans = []; + tracesMap.set(traceId, traceSpans); + } + traceSpans.push(span); + }); + }); + }); + + // Write into a file + // TODO: manage lifetime of old trace ndjson files. + for (const [traceId, traceSpans] of tracesMap.entries()) { + const filePath = path.join(this._dbDir, `trace-${traceId}.ndjson`); + const stream = fs.createWriteStream(filePath, { + flags: 'a', + encoding: 'utf-8', + }); + + for (const span of traceSpans) { + stream.write(JSON.stringify(span) + '\n'); + } + stream.close(); + } + } +} + +/** + * + * @param {Object} opts + * @param {import('./luggite').LoggerInstance} opts.log + * @param {string} opts.hostname + * @param {number} opts.port + */ +function startUi(opts) { + const {log, hostname, port} = opts; + const server = httpServer.createServer({ + root: path.join(__dirname, '/../ui'), + }); + + server.listen(port, hostname, function () { + const endpoint = `http://${hostname}:${port}`; + log.info(`UI listening at ${endpoint}`); + }); + + // Use specific printer for UI + const printer = new UiPrinter(log); + printer.subscribe(); +} + +module.exports = { + startUi, +}; diff --git a/packages/mockotlpserver/package.json b/packages/mockotlpserver/package.json index dd253098..6628afc6 100644 --- a/packages/mockotlpserver/package.json +++ b/packages/mockotlpserver/package.json @@ -25,7 +25,9 @@ "node": ">=14.17.0" }, "scripts": { - "lint": "eslint --ext=js,mjs,cjs . # requires node >=16.0.0", + "lint": "npm run lint:eslint && npm run lint:types", + "lint:eslint": "eslint --ext=js,mjs,cjs . # requires node >=16.0.0", + "lint:types": "tsc", "lint:fix": "eslint --ext=js,mjs,cjs --fix . # requires node >=16.0.0", "start": "node lib/index.js", "watch": "node --watch lib/index.js # requires node >=18.11" @@ -34,6 +36,7 @@ "dependencies": { "@grpc/grpc-js": "^1.9.13", "@grpc/proto-loader": "^0.7.10", + "http-server": "^14.1.1", "protobufjs": "^7.2.5", "safe-stable-stringify": "^2.4.3" }, @@ -42,6 +45,7 @@ "@opentelemetry/exporter-trace-otlp-grpc": "^0.46.0", "@opentelemetry/exporter-trace-otlp-http": "^0.46.0", "@opentelemetry/exporter-trace-otlp-proto": "^0.46.0", - "@opentelemetry/sdk-node": "^0.46.0" + "@opentelemetry/sdk-node": "^0.46.0", + "@types/http-server": "^0.12.4" } } diff --git a/packages/mockotlpserver/tsconfig.json b/packages/mockotlpserver/tsconfig.json new file mode 100644 index 00000000..48954a9a --- /dev/null +++ b/packages/mockotlpserver/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["lib"], +} \ No newline at end of file diff --git a/packages/mockotlpserver/ui/index.html b/packages/mockotlpserver/ui/index.html new file mode 100644 index 00000000..366b4179 --- /dev/null +++ b/packages/mockotlpserver/ui/index.html @@ -0,0 +1,9 @@ + + + + Mock OLTP Server UI + + + Hello world + + \ No newline at end of file diff --git a/packages/opentelemetry-node/lib/luggite.js b/packages/opentelemetry-node/lib/luggite.js index 2d28dfb0..dcbb5c12 100644 --- a/packages/opentelemetry-node/lib/luggite.js +++ b/packages/opentelemetry-node/lib/luggite.js @@ -12,10 +12,40 @@ var stream = require('stream'); var safeStableStringify = require('safe-stable-stringify'); +/** + * TODO: add properties here + * @typedef {Object} LogRecord + */ + +/** + * @typedef {Object} LoggerInstance + * @property {function(Record | string, ...any): undefined} fatal + * @property {function(Record | string, ...any): undefined} error + * @property {function(Record | string, ...any): undefined} warn + * @property {function(Record | string, ...any): undefined} info + * @property {function(Record | string, ...any): undefined} debug + * @property {function(Record | string, ...any): undefined} trace + */ + var EOL = '\n'; //---- Internal support stuff +/** + * Type assertion so TS can narrow types in if/else blocks + * @type {(value: any) => value is string} + */ +function isString(value) { + return typeof value === 'string'; +} +/** + * Type assertion so TS can narrow types in if/else blocks + * @type {(value: any) => value is number} + */ +function isNumber(value) { + return typeof value === 'number'; +} + /** * Warn about an internal processing error. * @@ -73,19 +103,19 @@ Object.keys(levelFromName).forEach(function (name) { /** * Resolve a level number, name (upper or lowercase) to a level number value. * - * @param nameOrNum {String|Number} A level name (case-insensitive) or positive + * @param {string|number} nameOrNum A level name (case-insensitive) or positive * integer level. * @api public */ function resolveLevel(nameOrNum) { var level; var type = typeof nameOrNum; - if (type === 'string') { + if (isString(nameOrNum)) { level = levelFromName[nameOrNum.toLowerCase()]; if (!level) { throw new Error(format('unknown level name: "%s"', nameOrNum)); } - } else if (type !== 'number') { + } else if (!isNumber(nameOrNum)) { throw new TypeError( format('cannot resolve level: invalid arg (%s):', type, nameOrNum) ); @@ -99,6 +129,11 @@ function resolveLevel(nameOrNum) { return level; } +/** + * Tells if the object is writable + * @param {any} obj + * @returns {boolean} + */ function isWritable(obj) { if (obj instanceof stream.Writable) { return true; @@ -132,7 +167,9 @@ function Logger(opts) { } /** - * Add a stream + * Adds a stream + * @param {any} s + * @param {number} [defaultLevel] */ Logger.prototype._addStream = function _addStream(s, defaultLevel) { if (defaultLevel === null || defaultLevel === undefined) { @@ -187,6 +224,8 @@ Logger.prototype._addStream = function _addStream(s, defaultLevel) { * Set Usage: * log.level(INFO) // set all streams to level INFO * log.level('info') // can use 'info' et al aliases + * + * @param {number | string} value */ Logger.prototype.level = function level(value) { if (value === undefined) { @@ -205,8 +244,8 @@ Logger.prototype.level = function level(value) { * * Pre-condition: This is only called if there is at least one serializer. * - * @param fields (Object) The log record fields. - * @param excludeFields (Object) Optional mapping of keys to `true` for + * @param {Object} fields The log record fields. + * @param {Object} excludeFields Optional mapping of keys to `true` for * keys to NOT apply a serializer. */ Logger.prototype._applySerializers = function (fields, excludeFields) { @@ -245,7 +284,7 @@ Logger.prototype._applySerializers = function (fields, excludeFields) { /** * Emit a log record. * - * @param rec {log record} + * @param {LogRecord} rec The log record */ Logger.prototype._emit = function (rec) { var i; @@ -267,6 +306,11 @@ Logger.prototype._emit = function (rec) { /** * Build a record object suitable for emitting from the arguments * provided to the a log emitter. + * + * @param {any} log + * @param {any} minLevel + * @param {Array} args + * @returns {LogRecord} */ function mkRecord(log, minLevel, args) { var excludeFields, fields, msgArgs; @@ -333,6 +377,9 @@ function mkRecord(log, minLevel, args) { /** * Build a log emitter function for level minLevel. I.e. this is the * creator of `log.info`, `log.error`, etc. + * + * @param {number} minLevel + * @returns {(fields?: Record, msg?: string) => void} */ function mkLogEmitter(minLevel) { return function LOG(...args) { @@ -388,12 +435,16 @@ Logger.prototype.error = mkLogEmitter(ERROR); Logger.prototype.fatal = mkLogEmitter(FATAL); // ---- Serializers -// A serializer is a function that serializes a JavaScript object to a -// JSON representation for logging. There is a standard set of presumed -// interesting objects in node.js-land. - -// Serialize an Error object -// (Core error properties are enumerable in node 0.4, not in 0.6). +/** + * A serializer is a function that serializes a JavaScript object to a + * JSON representation for logging. There is a standard set of presumed + * interesting objects in node.js-land. + * + * Serialize an Error object + * (Core error properties are enumerable in node 0.4, not in 0.6). + * @param {Error | Object} err + * @returns {Object} + */ var errSerializer = function (err) { if (!err || !err.stack) return err; var obj = { @@ -408,7 +459,14 @@ var errSerializer = function (err) { //---- Exports +/** + * @param {any} options + * @returns {LoggerInstance} + */ function createLogger(options) { + // TODO: I do not know yet if possible to document Function + prototype + // edit in JsDoc + // @ts-ignore return new Logger(options); } diff --git a/packages/opentelemetry-node/package.json b/packages/opentelemetry-node/package.json index d4701fb0..d7e9e02f 100644 --- a/packages/opentelemetry-node/package.json +++ b/packages/opentelemetry-node/package.json @@ -24,7 +24,9 @@ }, "scripts": { "demo": "node -r ./start examples/simple-http-server.js", - "lint": "eslint --ext=js,mjs,cjs . # requires node >=16.0.0", + "lint": "npm run lint:eslint && npm run lint:types", + "lint:eslint": "eslint --ext=js,mjs,cjs . # requires node >=16.0.0", + "lint:types": "tsc", "lint:fix": "eslint --ext=js,mjs,cjs --fix . # requires node >=16.0.0" }, "main": "lib/index.js", diff --git a/packages/opentelemetry-node/tsconfig.json b/packages/opentelemetry-node/tsconfig.json new file mode 100644 index 00000000..48954a9a --- /dev/null +++ b/packages/opentelemetry-node/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["lib"], +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d58f3fe6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "noEmit": true, + "allowJs": true, + "checkJs": true, + "target": "ESNext", + "resolveJsonModule": true, + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["ES2020"] + }, + "exclude": ["node_modules"] +} \ No newline at end of file