From 9417264850d1840d619bb6f2bb1da5bf33d4c119 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 25 Mar 2019 21:50:26 -0400 Subject: [PATCH] Making package browser compatible --- package-lock.json | 593 +++++++++++++++++++++++++++++++++++++++++-- package.json | 16 +- src/base.ts | 235 +++++++++++++++++ src/browser.ts | 10 + src/consolewriter.ts | 24 +- src/filewriter.ts | 6 +- src/index.ts | 280 ++------------------ src/inspect.ts | 415 ++++++++++++++++++++++++++++++ src/test.ts | 10 +- src/types.ts | 18 +- 10 files changed, 1296 insertions(+), 311 deletions(-) create mode 100644 src/base.ts create mode 100644 src/browser.ts create mode 100644 src/inspect.ts diff --git a/package-lock.json b/package-lock.json index 2dc7111..ac3b5e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "@hibas123/nodelogging", - "version": "1.4.0", + "version": "1.5.0-alpha.2", "lockfileVersion": 1, "requires": true, "dependencies": { "@hibas123/utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hibas123/utils/-/utils-2.0.0.tgz", - "integrity": "sha512-kczMJvwLGqUgnFamxtPJjb7V+C5tKHc3dtgKYaCQexbzwQ44VNlwTngYNK7izRA5HfD0N+abAGA0IoBMDmKDpg==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@hibas123/utils/-/utils-2.0.2.tgz", + "integrity": "sha512-5yrpuuUv0YlL2BixiTQLta4EmPLMNZ9Waorymu6dbERiSIcBxDs8mcJDUDW7CGiewpHHQUMsqLycLUYPDx0LWw==" }, "@types/node": { - "version": "8.10.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.45.tgz", - "integrity": "sha512-tGVTbA+i3qfXsLbq9rEq/hezaHY55QxQLeXQL2ejNgFAxxrgu8eMmYIOsRcl7hN1uTLVsKOOYacV/rcJM3sfgQ==", + "version": "11.11.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.7.tgz", + "integrity": "sha512-bHbRcyD6XpXVLg42QYaQCjvDXaCFkvb3WbCIxSDmhGbJYVroxvYzekk9QGg1beeIawfvSLkdZpP0h7jxE4ihnA==", "dev": true }, "abbrev": { @@ -324,6 +324,23 @@ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -361,6 +378,40 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concurrently": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.1.0.tgz", + "integrity": "sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "date-fns": "^1.23.0", + "lodash": "^4.17.10", + "read-pkg": "^4.0.1", + "rxjs": "^6.3.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^4.5.0", + "tree-kill": "^1.1.0", + "yargs": "^12.0.1" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", @@ -413,6 +464,12 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -430,6 +487,12 @@ } } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -498,6 +561,24 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -672,6 +753,15 @@ } } }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -707,7 +797,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -728,12 +819,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -748,17 +841,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -875,7 +971,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -887,6 +984,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -901,6 +999,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -908,12 +1007,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -932,6 +1033,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1012,7 +1114,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -1024,6 +1127,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -1109,7 +1213,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -1145,6 +1250,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -1164,6 +1270,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -1207,15 +1314,23 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -1321,6 +1436,12 @@ } } }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -1351,6 +1472,12 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -1371,6 +1498,12 @@ } } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -1563,6 +1696,12 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -1578,6 +1717,31 @@ "package-json": "^4.0.0" } }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1603,6 +1767,15 @@ "pify": "^3.0.0" } }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -1618,6 +1791,17 @@ "object-visit": "^1.0.0" } }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -1639,6 +1823,12 @@ "to-regex": "^3.0.2" } }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1707,6 +1897,12 @@ "to-regex": "^3.0.1" } }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "nodemon": { "version": "1.18.10", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.10.tgz", @@ -1734,6 +1930,18 @@ "abbrev": "1" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1749,6 +1957,12 @@ "path-key": "^2.0.0" } }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -1798,12 +2012,107 @@ "isobject": "^3.0.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -1816,6 +2125,16 @@ "semver": "^5.1.0" } }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -1828,6 +2147,12 @@ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1846,6 +2171,12 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -1882,6 +2213,16 @@ "integrity": "sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -1894,6 +2235,17 @@ "strip-json-comments": "~2.0.1" } }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -1967,6 +2319,27 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -1979,6 +2352,15 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2009,6 +2391,12 @@ "semver": "^5.0.3" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", @@ -2194,6 +2582,44 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -2339,10 +2765,22 @@ "nopt": "~1.0.10" } }, + "tree-kill": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", + "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==", + "dev": true + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.3.4000", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.4000.tgz", + "integrity": "sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==", "dev": true }, "undefsafe": { @@ -2506,6 +2944,16 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -2515,6 +2963,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, "widest-line": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", @@ -2524,6 +2978,59 @@ "string-width": "^2.1.1" } }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "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": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, "write-file-atomic": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", @@ -2541,11 +3048,55 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", + "dev": true + } + } } } } diff --git a/package.json b/package.json index ee99587..5410094 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,16 @@ { "name": "@hibas123/nodelogging", - "version": "1.5.0-alpha.1", + "version": "1.5.0-alpha.2", "description": "", "main": "out/index.js", "types": "out/index.d.ts", + "browser": "out/browser.js", "scripts": { "prepublish": "tsc", "build": "tsc", - "watch": "tsc --watch", + "watch-ts": "tsc --watch", + "watch-js": "nodemon out/test.js", + "watch": "concurrently npm:watch-*", "test": "node out/test.js", "live": "nodemon out/test.js" }, @@ -18,11 +21,12 @@ "author": "Fabian Stamm", "license": "MIT", "devDependencies": { - "@types/node": "^8.0.24", + "@types/node": "^11.11.7", + "concurrently": "^4.1.0", "nodemon": "^1.17.4", - "typescript": "^2.4.2" + "typescript": "^3.3.4000" }, "dependencies": { - "@hibas123/utils": "^2.0.0" + "@hibas123/utils": "^2.0.2" } -} \ No newline at end of file +} diff --git a/src/base.ts b/src/base.ts new file mode 100644 index 0000000..9820f61 --- /dev/null +++ b/src/base.ts @@ -0,0 +1,235 @@ +import { Observable } from "@hibas123/utils"; +import { ConsoleWriter } from "./consolewriter"; +import inspect from "./inspect"; +import { Adapter, LoggingTypes, Message } from "./types"; + +export const Colors = { + Reset: "\x1b[0m", + Bright: "\x1b[1m", + Dim: "\x1b[2m", + Underscore: "\x1b[4m", + Blink: "\x1b[5m", + Reverse: "\x1b[7m", + Hidden: "\x1b[8m", + + FgBlack: "\x1b[30m", + FgRed: "\x1b[31m", + FgGreen: "\x1b[32m", + FgYellow: "\x1b[33m", + FgBlue: "\x1b[34m", + FgMagenta: "\x1b[35m", + FgCyan: "\x1b[36m", + FgWhite: "\x1b[37m", + + BgBlack: "\x1b[40m", + BgRed: "\x1b[41m", + BgGreen: "\x1b[42m", + BgYellow: "\x1b[43m", + BgBlue: "\x1b[44m", + BgMagenta: "\x1b[45m", + BgCyan: "\x1b[46m", + BgWhite: "\x1b[47m" +} + + +export interface LoggingBaseOptions { + /** + * Name will be prefixed on Console output and added to logfiles, if not specified here + */ + name: string, + /** + * Prints output to console + */ + console: boolean; +} + +export class LoggingBase { + private logFile: any; + private errorFile: any; + private adapter: Adapter[] = []; + private adapter_init: Promise[] = []; + + private messageObservable = new Observable(); + protected name: string; + + constructor(options?: Partial | string) { + let opt: Partial; + if (!options) opt = {} + else if (typeof options === "string") { + opt = { name: options }; + } else { + opt = options; + } + + let config = { + name: undefined, + console: true, + files: true, + ...opt + }; + + if (config.name) + this.name = config.name; + + for (let key in this) { + if (typeof this[key] === "function") this[key] = (this[key]).bind(this); + } + + if (config.console) { + this.addAdapter(new ConsoleWriter()); + } + } + + addAdapter(adapter: Adapter) { + this.adapter.push(adapter); + let prms = Promise.resolve(adapter.init(this.messageObservable.getPublicApi(), this.name)); + this.adapter_init.push(prms); + } + + flush(sync: true): void; + flush(sync: false): Promise; + flush(sync: boolean): void | Promise { + if (sync) { + this.adapter.forEach(elm => elm.flush(true)); + } else { + return Promise.all(this.adapter.map(elm => elm.flush(false))).then(() => { }); + } + } + + public waitForSetup() { + return Promise.all(this.adapter_init); + } + + debug(...message: any[]) { + this.message(LoggingTypes.Debug, message); + } + + log(...message: any[]) { + this.message(LoggingTypes.Log, message); + } + + warning(...message: any[]) { + this.message(LoggingTypes.Warning, message); + } + + logWithCustomColors(type: LoggingTypes, colors: string, ...message: any[]) { + this.message(type, message, colors); + } + + error(error: Error | string) { + if (!error) error = "Empty ERROR was passed, so no informations available"; + if (typeof error === "string") { + let e = new Error() + this.message(LoggingTypes.Error, [error, "\n", e.stack]); + } else { + this.message(LoggingTypes.Error, [error.message, "\n", error.stack], undefined, getCallerFromExisting(error)); + } + } + + errorMessage(...message: any[]) { + this.message(LoggingTypes.Error, message); + } + + private message(type: LoggingTypes, message: any[] | string, customColors?: string, caller?: { file: string, line: number }) { + let file_raw = caller || getCallerFile(); + let file = `${file_raw.file}:${String(file_raw.line).padEnd(3, " ")}`; + + let mb = ""; + if (typeof message === "string") { + mb = message; + } else { + message.forEach((e, i) => { + if (typeof e !== "string") e = inspect(e, { colors: true, showHidden: true, depth: 3 }); + if (e.endsWith("\n") || i === message.length - 1) { + mb += e; + } else { + mb += e + " "; + } + }); + } + + let lines = mb.split("\n"); + + let date = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''); + let prefix = `[ ${date} ][${LoggingTypes[type].toUpperCase().padEnd(5, " ")}][${file}]: `; + + let formatted = lines.map(line => prefix + line); + + let msg: Message = { + date: new Date(), + file, + name: this.name, + text: { + raw: lines, + formatted + }, + type, + customColors + } + + this.messageObservable.send(msg); + } +} + +function getStack() { + // Save original Error.prepareStackTrace + let origPrepareStackTrace = (Error).prepareStackTrace; + + // Override with function that just returns `stack` + (Error).prepareStackTrace = function (_, stack) { + return stack + } + + // Create a new `Error`, which automatically gets `stack` + let err = new Error(); + + // Evaluate `err.stack`, which calls our new `Error.prepareStackTrace` + let stack: any[] = err.stack; + + // Restore original `Error.prepareStackTrace` + (Error).prepareStackTrace = origPrepareStackTrace; + + // Remove superfluous function call on stack + stack.shift(); // getStack --> Error + + return stack +} + +function baseName(path) { + return path.split(/[\\/]/).pop(); +} + +function getCallerFile() { + try { + let stack = getStack() + + let current_file = stack.shift().getFileName(); + + while (stack.length) { + let caller_file = stack.shift(); + const util = require("util") + if (current_file !== caller_file.getFileName()) + return { + file: baseName(caller_file.getFileName()), + line: caller_file.getLineNumber() + }; + } + } catch (err) { } + return { file: undefined, line: 0 }; +} + +function getCallerFromExisting(err: Error): { file: string, line: number } { + if (!err || !err.stack) return { file: "NOFILE", line: 0 }; + let lines = err.stack.split("\n"); + lines.shift();// removing first line + while (lines.length > 0) { + let line = lines.shift(); + let matches = line.match(/[a-zA-Z_-]+[.][a-zA-Z_-]+[:][0-9]+/g) + if (matches && matches.length > 0) { + let [f, line] = matches[0].split(":") + return { + file: f, line: Number(line) + }; + } + } +} \ No newline at end of file diff --git a/src/browser.ts b/src/browser.ts new file mode 100644 index 0000000..822c65c --- /dev/null +++ b/src/browser.ts @@ -0,0 +1,10 @@ +import { LoggingBase } from "./base"; +export { Colors, LoggingBase } from "./base"; +export { Adapter, LoggingTypes, Message } from "./types"; + + +export let Logging: LoggingBase = undefined; +if (process.env.LOGGING_NO_DEFAULT !== "true") { + Logging = new LoggingBase(); +} +export default Logging; diff --git a/src/consolewriter.ts b/src/consolewriter.ts index a3e5e9c..13556e2 100644 --- a/src/consolewriter.ts +++ b/src/consolewriter.ts @@ -1,16 +1,16 @@ -import {Adapter, Message, LoggingTypes} from "./types"; -import { ObservableInterface } from "@hibas123/utils" +import { ObservableInterface } from "@hibas123/utils"; import { Colors } from "./index"; +import { Adapter, LoggingTypes, Message } from "./types"; export class ConsoleWriter implements Adapter { - init(observable:ObservableInterface) { - observable.subscribe(this.onMessage.bind(this)); - } + init(observable: ObservableInterface) { + observable.subscribe(this.onMessage.bind(this)); + } - flush() {} + flush() { } - onMessage(message:Message) { + onMessage(message: Message) { let consoleLogFormat = Colors.Reset; if (!message.customColors) { switch (message.type) { @@ -31,9 +31,9 @@ export class ConsoleWriter implements Adapter { consoleLogFormat += message.customColors; } - let lines = message.text.formatted; - let name = ""; - if(message.name) name = `[${message.name}]=>`; - lines.forEach(line=>console.log(consoleLogFormat + name + line + Colors.Reset)) - } + let lines = message.text.formatted; + let name = ""; + if (message.name) name = `[${message.name}]=>`; + lines.forEach(line => console.log(consoleLogFormat + name + line + Colors.Reset)) + } } \ No newline at end of file diff --git a/src/filewriter.ts b/src/filewriter.ts index d224215..11992f9 100644 --- a/src/filewriter.ts +++ b/src/filewriter.ts @@ -1,7 +1,7 @@ -import { Lock, ObservableInterface } from "@hibas123/utils" -import * as path from "path"; +import { Lock, ObservableInterface } from "@hibas123/utils"; import * as fs from "fs"; -import { Adapter, Message, LoggingTypes } from "./types"; +import * as path from "path"; +import { Adapter, LoggingTypes, Message } from "./types"; const maxFileSize = 500000000; diff --git a/src/index.ts b/src/index.ts index eb9ffe1..71e3a99 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,46 +1,10 @@ -import * as util from "util"; -import * as fs from "fs"; -import { EventEmitter } from "events"; -import * as path from "path"; -import { Lock, Observable } from "@hibas123/utils"; -import { Adapter, LoggingTypes, Message } from "./types"; -import { ConsoleWriter } from "./consolewriter"; +import { LoggingBase, LoggingBaseOptions } from "./base"; +import { LoggingFiles } from "./filewriter"; -const OriginalErrorStackFunction = (Error.prototype).prepareStackTrace +export { Colors } from "./base"; +export { Adapter, LoggingTypes, Message } from "./types"; -export const Colors = { - Reset: "\x1b[0m", - Bright: "\x1b[1m", - Dim: "\x1b[2m", - Underscore: "\x1b[4m", - Blink: "\x1b[5m", - Reverse: "\x1b[7m", - Hidden: "\x1b[8m", - - FgBlack: "\x1b[30m", - FgRed: "\x1b[31m", - FgGreen: "\x1b[32m", - FgYellow: "\x1b[33m", - FgBlue: "\x1b[34m", - FgMagenta: "\x1b[35m", - FgCyan: "\x1b[36m", - FgWhite: "\x1b[37m", - - BgBlack: "\x1b[40m", - BgRed: "\x1b[41m", - BgGreen: "\x1b[42m", - BgYellow: "\x1b[43m", - BgBlue: "\x1b[44m", - BgMagenta: "\x1b[45m", - BgCyan: "\x1b[46m", - BgWhite: "\x1b[47m" -} - -export interface LoggingBaseOptions { - /** - * Name will be prefixed on Console output and added to logfiles, if not specified here - */ - name: string, +export interface LoggingOptions extends LoggingBaseOptions { files: boolean | { /** * Filename/path of the logfile. Skip if generated with name @@ -51,234 +15,40 @@ export interface LoggingBaseOptions { */ errorfile: string; } - /** - * Prints output to console - */ - console: boolean; } +export class LoggingExtended extends LoggingBase { + constructor(config: Partial | string = {}) { + super(config); -export class LoggingBase { - private logFile: any; - private errorFile: any; - private adapter: Adapter[] = []; - private adapter_init: Promise[] = []; - - private messageObservable = new Observable(); - private name: string; - - constructor(options?: Partial | string) { - let opt: Partial; - if (!options) opt = {} - else if (typeof options === "string") { - opt = { name: options }; - } else { - opt = options; - } - - let config = { - name: undefined, - console: true, - files: true, - ...opt - }; - - if (typeof config.files === "boolean") { - if (config.files === true) { - let name = ""; - if (config.name) - name = "." + config.name; - config.files = { - logfile: `./logs/all${name}.log`, - errorfile: `./logs/error${name}.log` - } + if (typeof config === "string" || config.files !== false) { + let logfile: string; + let errorfile: string; + if (typeof config !== "string" && typeof config.files === "object") { + logfile = config.files.logfile; + errorfile = config.files.errorfile; } else { - config.files = undefined; - } - } - - if (config.name) - this.name = config.name; - - for (let key in this) { - if (typeof this[key] === "function") this[key] = (this[key]).bind(this); - } - - if (typeof config.files !== "boolean" && config.files !== undefined && (config.files.logfile || config.files.errorfile)) { - const { LoggingFiles } = require("./filewriter"); - if (config.files.logfile) { - this.addAdapter(new LoggingFiles(config.files.logfile)); + let name = this.name ? "." + this.name : ""; + logfile = `./logs/all${name}.log`; + errorfile = `./logs/error${name}.log`; } - if (config.files.errorfile) { - this.addAdapter(new LoggingFiles(config.files.errorfile, true)); + if (logfile) { + this.addAdapter(new LoggingFiles(logfile)); + } + + if (errorfile) { + this.addAdapter(new LoggingFiles(errorfile, true)); } } - - if (config.console) { - this.addAdapter(new ConsoleWriter()); - } - } - - addAdapter(adapter: Adapter) { - this.adapter.push(adapter); - let prms = Promise.resolve(adapter.init(this.messageObservable.getPublicApi(), this.name)); - this.adapter_init.push(prms); - } - - flush(sync: true): void; - flush(sync: false): Promise; - flush(sync: boolean): void | Promise { - if (sync) { - this.adapter.forEach(elm => elm.flush(true)); - } else { - return Promise.all(this.adapter.map(elm => elm.flush(false))).then(() => { }); - } - } - - public waitForSetup() { - return Promise.all(this.adapter_init); - } - - public events: EventEmitter = new EventEmitter(); - - debug(...message: any[]) { - this.message(LoggingTypes.Debug, message); - } - - log(...message: any[]) { - this.message(LoggingTypes.Log, message); - } - - warning(...message: any[]) { - this.message(LoggingTypes.Warning, message); - } - - logWithCustomColors(type: LoggingTypes, colors: string, ...message: any[]) { - this.message(type, message, colors); - } - - error(error: Error | string) { - if (!error) error = "Empty ERROR was passed, so no informations available"; - if (typeof error === "string") { - let e = new Error() - this.message(LoggingTypes.Error, [error, "\n", e.stack]); - } else { - this.message(LoggingTypes.Error, [error.message, "\n", error.stack], undefined, getCallerFromExisting(error)); - } - } - - errorMessage(...message: any[]) { - this.message(LoggingTypes.Error, message); - } - - private message(type: LoggingTypes, message: any[] | string, customColors?: string, caller?: { file: string, line: number }) { - let file_raw = caller || getCallerFile(); - let file = `${file_raw.file}:${String(file_raw.line).padEnd(3, " ")}`; - - let mb = ""; - if (typeof message === "string") { - mb = message; - } else { - message.forEach((e, i) => { - if (typeof e !== "string") e = util.inspect(e, false, null); - if (e.endsWith("\n") || i === message.length - 1) { - mb += e; - } else { - mb += e + " "; - } - }); - } - - let lines = mb.split("\n"); - - let date = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''); - let prefix = `[ ${date} ][${LoggingTypes[type].toUpperCase().padEnd(5, " ")}][${file}]: `; - - let formatted = lines.map(line => prefix + line); - - let msg: Message = { - date: new Date(), - file, - name: this.name, - text: { - raw: lines, - formatted - }, - type, - customColors - } - - this.messageObservable.send(msg); } } -export let Logging: LoggingBase = undefined; +export let Logging: LoggingExtended = undefined; if (process.env.LOGGING_NO_DEFAULT !== "true") { - Logging = new LoggingBase(); + Logging = new LoggingExtended(); } export default Logging; -function getStack() { - // Save original Error.prepareStackTrace - let origPrepareStackTrace = (Error).prepareStackTrace; - - // Override with function that just returns `stack` - (Error).prepareStackTrace = function (_, stack) { - return stack - } - - // Create a new `Error`, which automatically gets `stack` - let err = new Error(); - - // Evaluate `err.stack`, which calls our new `Error.prepareStackTrace` - let stack: any[] = err.stack; - - // Restore original `Error.prepareStackTrace` - (Error).prepareStackTrace = origPrepareStackTrace; - - // Remove superfluous function call on stack - stack.shift(); // getStack --> Error - - return stack -} - -function getCallerFile() { - try { - let stack = getStack() - - let current_file = stack.shift().getFileName(); - - while (stack.length) { - let caller_file = stack.shift(); - const util = require("util") - if (current_file !== caller_file.getFileName()) - return { - file: path.basename(caller_file.getFileName()), - line: caller_file.getLineNumber() - }; - } - } catch (err) { } - return { file: undefined, line: 0 }; -} - -function getCallerFromExisting(err: Error): { file: string, line: number } { - if (!err || !err.stack) return { file: "NOFILE", line: 0 }; - let lines = err.stack.split("\n"); - let current = path.basename(__filename); - lines.shift();// removing first line - while (lines.length > 0) { - let line = lines.shift(); - let matches = line.match(/[a-zA-Z_-]+[.][a-zA-Z_-]+[:][0-9]+/g) - if (matches && matches.length > 0) { - let [f, line] = matches[0].split(":") - if (f != current) { - return { - file: f, line: Number(line) - }; - } - } - } -} \ No newline at end of file diff --git a/src/inspect.ts b/src/inspect.ts new file mode 100644 index 0000000..222df8d --- /dev/null +++ b/src/inspect.ts @@ -0,0 +1,415 @@ + +/** + * Module exports. + */ + +interface InspectOptions { + depth: number; + colors: boolean; + showHidden: boolean; +} + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + * @license MIT (© Joyent) + */ +/* legacy: obj, showHidden, depth, colors*/ +export default function inspect(obj: any, opts: Partial) { + // default options + let ctx = { + seen: [], + stylize: stylizeNoColor, + depth: undefined, + colors: undefined, + showHidden: undefined, + customInspect: undefined + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + _extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold': [1, 22], + 'italic': [3, 23], + 'underline': [4, 24], + 'inverse': [7, 27], + 'white': [37, 39], + 'grey': [90, 39], + 'black': [30, 39], + 'blue': [34, 39], + 'cyan': [36, 39], + 'green': [32, 39], + 'magenta': [35, 39], + 'red': [31, 39], + 'yellow': [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + +function stylizeNoColor(str, styleType) { + return str; +} + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} + +function isUndefined(arg) { + return arg === void 0; +} + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isString(arg) { + return typeof arg === 'string'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isNull(arg) { + return arg === null; +} + +function hasOwn(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function (val, idx) { + hash[val] = true; + }); + + return hash; +} + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwn(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function (key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + try { + if (ctx.showHidden && Object.getOwnPropertyNames) { + keys = Object.getOwnPropertyNames(value); + } + } catch (e) { + // ignore + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (Array.isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function (key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = { value: void 0 }; + try { + // ie6 › navigator.toString + // throws Error: Object doesn't support this property or method + desc.value = value[key]; + } catch (e) { + // ignore + } + try { + // ie10 › Object.getOwnPropertyDescriptor(window.location, 'hash') + // throws TypeError: Object doesn't support this action + if (Object.getOwnPropertyDescriptor) { + desc = Object.getOwnPropertyDescriptor(value, key) || desc; + } + } catch (e) { + // ignore + } + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwn(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function (line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function (line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function (prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function _extend(origin: T, add: Y) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +} \ No newline at end of file diff --git a/src/test.ts b/src/test.ts index 985ecf0..0e22988 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,6 +1,6 @@ -import { Logging, LoggingBase } from "./index"; import { randomBytes } from "crypto"; import * as fs from "fs"; +import { Logging, LoggingExtended } from "./index"; const deleteFolderRecursive = function (path: string) { if (fs.existsSync(path)) { fs.readdirSync(path).forEach(function (file, index) { @@ -28,13 +28,13 @@ Logging.log("\x1b[31m\x1b[31m\x1b[31m\x1b[31m\x1b[31m\x1b[31m TEST \x1b[31m\x1b[ let err = new Error() if (typeof err.stack !== "string") console.log("Stacktrace invalid", err.stack) -let cus = new LoggingBase({ name: "test" }); +let cus = new LoggingExtended({ name: "test" }); cus.log("Hello from custom Logger") -let cus2 = new LoggingBase("test2"); +let cus2 = new LoggingExtended("test2"); cus2.log("Hello from custom Logger 2") -let cus22 = new LoggingBase("test2"); +let cus22 = new LoggingExtended("test2"); cus22.log("Hello from custom Logger 22") cus2.log("Hello from custom Logger 2") cus22.log("Hello from custom Logger 22") @@ -46,7 +46,7 @@ cus2.log("Hello from custom Logger 2") cus22.log("Hello from custom Logger 22") cus2.log("Hello from custom Logger 2") -const BenchmarkLogger = new LoggingBase({ +const BenchmarkLogger = new LoggingExtended({ console: false, name: "bench" }) diff --git a/src/types.ts b/src/types.ts index 76fa74e..d285d21 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,22 +1,22 @@ -import { ObservableInterface }from "@hibas123/utils"; +import { ObservableInterface } from "@hibas123/utils"; export enum LoggingTypes { - Log, - Warning, - Error, - Debug + Log, + Warning, + Error, + Debug } export interface Message { type: LoggingTypes; - name?:string; + name?: string; text: { - raw: string[], - formatted: string[] + raw: string[], + formatted: string[] }; date: Date; file: string; - customColors?:string; + customColors?: string; } export interface Adapter {