diff --git a/api/.prettierrc.yaml b/api/.prettierrc.yaml index 0176969..59b6ad3 100644 --- a/api/.prettierrc.yaml +++ b/api/.prettierrc.yaml @@ -1 +1,3 @@ singleQuote: true +tabWidth: 4 +arrowParens: avoid diff --git a/api/package-lock.json b/api/package-lock.json index bdcbb29..c46ae87 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -1,1019 +1,1019 @@ { - "name": "piston-api", - "version": "3.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "piston-api", - "version": "3.0.0", - "license": "MIT", - "dependencies": { - "body-parser": "^1.19.0", - "chownr": "^2.0.0", - "express": "^4.17.1", - "is-docker": "^2.1.1", - "logplease": "^1.2.15", - "nocamel": "HexF/nocamel#patch-1", - "node-fetch": "^2.6.1", - "semver": "^7.3.4", - "uuid": "^8.3.2", - "waitpid": "git+https://github.com/HexF/node-waitpid.git" - }, - "devDependencies": { - "prettier": "2.2.1" - } - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logplease": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", - "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.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/mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", - "dependencies": { - "mime-db": "1.46.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nocamel": { - "resolved": "git+ssh://git@github.com/HexF/nocamel.git#89a5bfbbd07c72c302d968b967d0f4fe54846544" - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "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/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/waitpid": { - "resolved": "git+ssh://git@github.com/HexF/node-waitpid.git#a08d116a5d993a747624fe72ff890167be8c34aa" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - }, - "dependencies": { - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==" - }, - "logplease": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", - "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" - }, - "mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", - "requires": { - "mime-db": "1.46.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "nocamel": { - "version": "git+ssh://git@github.com/HexF/nocamel.git#89a5bfbbd07c72c302d968b967d0f4fe54846544", - "from": "nocamel@HexF/nocamel#patch-1" - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "prettier": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "name": "piston-api", + "version": "3.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "piston-api", + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "body-parser": "^1.19.0", + "chownr": "^2.0.0", + "express": "^4.17.1", + "is-docker": "^2.1.1", + "logplease": "^1.2.15", + "nocamel": "HexF/nocamel#patch-1", + "node-fetch": "^2.6.1", + "semver": "^7.3.4", + "uuid": "^8.3.2", + "waitpid": "git+https://github.com/HexF/node-waitpid.git" + }, + "devDependencies": { + "prettier": "2.2.1" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logplease": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.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/mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "dependencies": { + "mime-db": "1.46.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nocamel": { + "resolved": "git+ssh://git@github.com/HexF/nocamel.git#89a5bfbbd07c72c302d968b967d0f4fe54846544" + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "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/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/waitpid": { + "resolved": "git+ssh://git@github.com/HexF/node-waitpid.git#a08d116a5d993a747624fe72ff890167be8c34aa" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } - } }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "waitpid": { - "version": "git+ssh://git@github.com/HexF/node-waitpid.git#a08d116a5d993a747624fe72ff890167be8c34aa", - "from": "waitpid@git+https://github.com/HexF/node-waitpid.git" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==" + }, + "logplease": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "requires": { + "mime-db": "1.46.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nocamel": { + "version": "git+ssh://git@github.com/HexF/nocamel.git#89a5bfbbd07c72c302d968b967d0f4fe54846544", + "from": "nocamel@HexF/nocamel#patch-1" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "waitpid": { + "version": "git+ssh://git@github.com/HexF/node-waitpid.git#a08d116a5d993a747624fe72ff890167be8c34aa", + "from": "waitpid@git+https://github.com/HexF/node-waitpid.git" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } - } } diff --git a/api/package.json b/api/package.json index a227cc2..ab34063 100644 --- a/api/package.json +++ b/api/package.json @@ -1,25 +1,25 @@ { - "name": "piston-api", - "version": "3.0.0", - "description": "API for piston - a high performance code execution engine", - "main": "src/index.js", - "dependencies": { - "body-parser": "^1.19.0", - "chownr": "^2.0.0", - "express": "^4.17.1", - "is-docker": "^2.1.1", - "logplease": "^1.2.15", - "nocamel": "HexF/nocamel#patch-1", - "node-fetch": "^2.6.1", - "semver": "^7.3.4", - "uuid": "^8.3.2", - "waitpid": "git+https://github.com/HexF/node-waitpid.git" - }, - "license": "MIT", - "scripts": { - "lint": "prettier . --write" - }, - "devDependencies": { - "prettier": "2.2.1" - } + "name": "piston-api", + "version": "3.0.0", + "description": "API for piston - a high performance code execution engine", + "main": "src/index.js", + "dependencies": { + "body-parser": "^1.19.0", + "chownr": "^2.0.0", + "express": "^4.17.1", + "is-docker": "^2.1.1", + "logplease": "^1.2.15", + "nocamel": "HexF/nocamel#patch-1", + "node-fetch": "^2.6.1", + "semver": "^7.3.4", + "uuid": "^8.3.2", + "waitpid": "git+https://github.com/HexF/node-waitpid.git" + }, + "license": "MIT", + "scripts": { + "lint": "prettier . --write" + }, + "devDependencies": { + "prettier": "2.2.1" + } } diff --git a/api/src/api/v2.js b/api/src/api/v2.js index d6b59a0..e3e8c68 100644 --- a/api/src/api/v2.js +++ b/api/src/api/v2.js @@ -8,217 +8,217 @@ const package = require('../package'); const logger = require('logplease').create('api/v2'); router.use((req, res, next) => { - if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) { - return next(); - } + if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) { + return next(); + } - if (!req.headers['content-type'].startsWith('application/json')) { - return res.status(415).send({ - message: 'requests must be of type application/json', - }); - } + if (!req.headers['content-type'].startsWith('application/json')) { + return res.status(415).send({ + message: 'requests must be of type application/json', + }); + } - next(); + next(); }); router.post('/execute', async (req, res) => { - const { - language, - version, - files, - stdin, - args, - run_timeout, - compile_timeout, - compile_memory_limit, - run_memory_limit, - } = req.body; + const { + language, + version, + files, + stdin, + args, + run_timeout, + compile_timeout, + compile_memory_limit, + run_memory_limit, + } = req.body; - if (!language || typeof language !== 'string') { - return res.status(400).send({ - message: 'language is required as a string', + if (!language || typeof language !== 'string') { + return res.status(400).send({ + message: 'language is required as a string', + }); + } + + if (!version || typeof version !== 'string') { + return res.status(400).send({ + message: 'version is required as a string', + }); + } + + if (!files || !Array.isArray(files)) { + return res.status(400).send({ + message: 'files is required as an array', + }); + } + + for (const [i, file] of files.entries()) { + if (typeof file.content !== 'string') { + return res.status(400).send({ + message: `files[${i}].content is required as a string`, + }); + } + } + + if (compile_memory_limit) { + if (typeof compile_memory_limit !== 'number') { + return res.status(400).send({ + message: 'if specified, compile_memory_limit must be a number', + }); + } + + if ( + config.compile_memory_limit >= 0 && + (compile_memory_limit > config.compile_memory_limit || + compile_memory_limit < 0) + ) { + return res.status(400).send({ + message: + 'compile_memory_limit cannot exceed the configured limit of ' + + config.compile_memory_limit, + }); + } + } + + if (run_memory_limit) { + if (typeof run_memory_limit !== 'number') { + return res.status(400).send({ + message: 'if specified, run_memory_limit must be a number', + }); + } + + if ( + config.run_memory_limit >= 0 && + (run_memory_limit > config.run_memory_limit || run_memory_limit < 0) + ) { + return res.status(400).send({ + message: + 'run_memory_limit cannot exceed the configured limit of ' + + config.run_memory_limit, + }); + } + } + + const rt = runtime.get_latest_runtime_matching_language_version( + language, + version + ); + + if (rt === undefined) { + return res.status(400).send({ + message: `${language}-${version} runtime is unknown`, + }); + } + + const job = new Job({ + runtime: rt, + alias: language, + files: files, + args: args || [], + stdin: stdin || '', + timeouts: { + run: run_timeout || 3000, + compile: compile_timeout || 10000, + }, + memory_limits: { + run: run_memory_limit || config.run_memory_limit, + compile: compile_memory_limit || config.compile_memory_limit, + }, }); - } - if (!version || typeof version !== 'string') { - return res.status(400).send({ - message: 'version is required as a string', - }); - } + await job.prime(); - if (!files || !Array.isArray(files)) { - return res.status(400).send({ - message: 'files is required as an array', - }); - } + const result = await job.execute(); - for (const [i, file] of files.entries()) { - if (typeof file.content !== 'string') { - return res.status(400).send({ - message: `files[${i}].content is required as a string`, - }); - } - } + await job.cleanup(); - if (compile_memory_limit) { - if (typeof compile_memory_limit !== 'number') { - return res.status(400).send({ - message: 'if specified, compile_memory_limit must be a number', - }); - } - - if ( - config.compile_memory_limit >= 0 && - (compile_memory_limit > config.compile_memory_limit || - compile_memory_limit < 0) - ) { - return res.status(400).send({ - message: - 'compile_memory_limit cannot exceed the configured limit of ' + - config.compile_memory_limit, - }); - } - } - - if (run_memory_limit) { - if (typeof run_memory_limit !== 'number') { - return res.status(400).send({ - message: 'if specified, run_memory_limit must be a number', - }); - } - - if ( - config.run_memory_limit >= 0 && - (run_memory_limit > config.run_memory_limit || run_memory_limit < 0) - ) { - return res.status(400).send({ - message: - 'run_memory_limit cannot exceed the configured limit of ' + - config.run_memory_limit, - }); - } - } - - const rt = runtime.get_latest_runtime_matching_language_version( - language, - version - ); - - if (rt === undefined) { - return res.status(400).send({ - message: `${language}-${version} runtime is unknown`, - }); - } - - const job = new Job({ - runtime: rt, - alias: language, - files: files, - args: args || [], - stdin: stdin || '', - timeouts: { - run: run_timeout || 3000, - compile: compile_timeout || 10000, - }, - memory_limits: { - run: run_memory_limit || config.run_memory_limit, - compile: compile_memory_limit || config.compile_memory_limit, - }, - }); - - await job.prime(); - - const result = await job.execute(); - - await job.cleanup(); - - return res.status(200).send(result); + return res.status(200).send(result); }); router.get('/runtimes', (req, res) => { - const runtimes = runtime.map((rt) => { - return { - language: rt.language, - version: rt.version.raw, - aliases: rt.aliases, - runtime: rt.runtime, - }; - }); + const runtimes = runtime.map(rt => { + return { + language: rt.language, + version: rt.version.raw, + aliases: rt.aliases, + runtime: rt.runtime, + }; + }); - return res.status(200).send(runtimes); + return res.status(200).send(runtimes); }); router.get('/packages', async (req, res) => { - logger.debug('Request to list packages'); - let packages = await package.get_package_list(); + logger.debug('Request to list packages'); + let packages = await package.get_package_list(); - packages = packages.map((pkg) => { - return { - language: pkg.language, - language_version: pkg.version.raw, - installed: pkg.installed, - }; - }); + packages = packages.map(pkg => { + return { + language: pkg.language, + language_version: pkg.version.raw, + installed: pkg.installed, + }; + }); - return res.status(200).send(packages); + return res.status(200).send(packages); }); router.post('/packages/:language/:version', async (req, res) => { - logger.debug('Request to install package'); + logger.debug('Request to install package'); - const { language, version } = req.params; + const { language, version } = req.params; - const pkg = await package.get_package(language, version); + const pkg = await package.get_package(language, version); - if (pkg == null) { - return res.status(404).send({ - message: `Requested package ${language}-${version} does not exist`, - }); - } + if (pkg == null) { + return res.status(404).send({ + message: `Requested package ${language}-${version} does not exist`, + }); + } - try { - const response = await pkg.install(); + try { + const response = await pkg.install(); - return res.status(200).send(response); - } catch (e) { - logger.error( - `Error while installing package ${pkg.language}-${pkg.version}:`, - e.message - ); + return res.status(200).send(response); + } catch (e) { + logger.error( + `Error while installing package ${pkg.language}-${pkg.version}:`, + e.message + ); - return res.status(500).send({ - message: e.message, - }); - } + return res.status(500).send({ + message: e.message, + }); + } }); router.delete('/packages/:language/:version', async (req, res) => { - logger.debug('Request to uninstall package'); + logger.debug('Request to uninstall package'); - const { language, version } = req.params; + const { language, version } = req.params; - const pkg = await package.get_package(language, version); + const pkg = await package.get_package(language, version); - if (pkg == null) { - return res.status(404).send({ - message: `Requested package ${language}-${version} does not exist`, - }); - } + if (pkg == null) { + return res.status(404).send({ + message: `Requested package ${language}-${version} does not exist`, + }); + } - try { - const response = await pkg.uninstall(); + try { + const response = await pkg.uninstall(); - return res.status(200).send(response); - } catch (e) { - logger.error( - `Error while uninstalling package ${pkg.language}-${pkg.version}:`, - e.message - ); + return res.status(200).send(response); + } catch (e) { + logger.error( + `Error while uninstalling package ${pkg.language}-${pkg.version}:`, + e.message + ); - return res.status(500).send({ - message: e.message, - }); - } + return res.status(500).send({ + message: e.message, + }); + } }); module.exports = router; diff --git a/api/src/config.js b/api/src/config.js index a17617f..acf45ce 100644 --- a/api/src/config.js +++ b/api/src/config.js @@ -3,114 +3,117 @@ const Logger = require('logplease'); const logger = Logger.create('config'); const options = [ - { - key: 'log_level', - desc: 'Level of data to log', - default: 'INFO', - options: Object.values(Logger.LogLevels), - validators: [ - (x) => - Object.values(Logger.LogLevels).includes(x) || - `Log level ${x} does not exist`, - ], - }, - { - key: 'bind_address', - desc: 'Address to bind REST API on\nThank @Bones for the number', - default: '0.0.0.0:2000', - validators: [], - }, - { - key: 'data_directory', - desc: 'Absolute path to store all piston related data at', - default: '/piston', - validators: [(x) => fss.exists_sync(x) || `Directory ${x} does not exist`], - }, - { - key: 'runner_uid_min', - desc: 'Minimum uid to use for runner', - default: 1001, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'runner_uid_max', - desc: 'Maximum uid to use for runner', - default: 1500, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'runner_gid_min', - desc: 'Minimum gid to use for runner', - default: 1001, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'runner_gid_max', - desc: 'Maximum gid to use for runner', - default: 1500, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'disable_networking', - desc: 'Set to true to disable networking', - default: true, - parser: (x) => x === 'true', - validators: [(x) => typeof x === 'boolean' || `${x} is not a boolean`], - }, - { - key: 'output_max_size', - desc: 'Max size of each stdio buffer', - default: 1024, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'max_process_count', - desc: 'Max number of processes per job', - default: 64, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'max_open_files', - desc: 'Max number of open files per job', - default: 2048, - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'max_file_size', - desc: 'Max file size in bytes for a file', - default: 10000000, //10MB - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'compile_memory_limit', - desc: - 'Max memory usage for compile stage in bytes (set to -1 for no limit)', - default: -1, // no limit - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'run_memory_limit', - desc: 'Max memory usage for run stage in bytes (set to -1 for no limit)', - default: -1, // no limit - parser: parse_int, - validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], - }, - { - key: 'repo_url', - desc: 'URL of repo index', - default: - 'https://github.com/engineer-man/piston/releases/download/pkgs/index', - validators: [], - }, + { + key: 'log_level', + desc: 'Level of data to log', + default: 'INFO', + options: Object.values(Logger.LogLevels), + validators: [ + x => + Object.values(Logger.LogLevels).includes(x) || + `Log level ${x} does not exist`, + ], + }, + { + key: 'bind_address', + desc: 'Address to bind REST API on\nThank @Bones for the number', + default: '0.0.0.0:2000', + validators: [], + }, + { + key: 'data_directory', + desc: 'Absolute path to store all piston related data at', + default: '/piston', + validators: [ + x => fss.exists_sync(x) || `Directory ${x} does not exist`, + ], + }, + { + key: 'runner_uid_min', + desc: 'Minimum uid to use for runner', + default: 1001, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'runner_uid_max', + desc: 'Maximum uid to use for runner', + default: 1500, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'runner_gid_min', + desc: 'Minimum gid to use for runner', + default: 1001, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'runner_gid_max', + desc: 'Maximum gid to use for runner', + default: 1500, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'disable_networking', + desc: 'Set to true to disable networking', + default: true, + parser: x => x === 'true', + validators: [x => typeof x === 'boolean' || `${x} is not a boolean`], + }, + { + key: 'output_max_size', + desc: 'Max size of each stdio buffer', + default: 1024, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'max_process_count', + desc: 'Max number of processes per job', + default: 64, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'max_open_files', + desc: 'Max number of open files per job', + default: 2048, + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'max_file_size', + desc: 'Max file size in bytes for a file', + default: 10000000, //10MB + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'compile_memory_limit', + desc: + 'Max memory usage for compile stage in bytes (set to -1 for no limit)', + default: -1, // no limit + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'run_memory_limit', + desc: + 'Max memory usage for run stage in bytes (set to -1 for no limit)', + default: -1, // no limit + parser: parse_int, + validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], + }, + { + key: 'repo_url', + desc: 'URL of repo index', + default: + 'https://github.com/engineer-man/piston/releases/download/pkgs/index', + validators: [], + }, ]; logger.info(`Loading Configuration from environment`); @@ -119,34 +122,37 @@ let errored = false; let config = {}; -options.forEach((option) => { - const env_key = 'PISTON_' + option.key.to_upper_case(); +options.forEach(option => { + const env_key = 'PISTON_' + option.key.to_upper_case(); - const parser = option.parser || ((x) => x); + const parser = option.parser || (x => x); - const env_val = process.env[env_key]; + const env_val = process.env[env_key]; - const parsed_val = parser(env_val); + const parsed_val = parser(env_val); - const value = env_val || option.default; + const value = env_val || option.default; - option.validators.for_each((validator) => { - let response = null; - if (env_val) response = validator(parsed_val, env_val); - else response = validator(value, value); + option.validators.for_each(validator => { + let response = null; + if (env_val) response = validator(parsed_val, env_val); + else response = validator(value, value); - if (response !== true) { - errored = true; - logger.error(`Config option ${option.key} failed validation:`, response); - return; - } - }); + if (response !== true) { + errored = true; + logger.error( + `Config option ${option.key} failed validation:`, + response + ); + return; + } + }); - config[option.key] = value; + config[option.key] = value; }); if (errored) { - process.exit(1); + process.exit(1); } logger.info('Configuration successfully loaded'); diff --git a/api/src/globals.js b/api/src/globals.js index 4546f74..933d2ca 100644 --- a/api/src/globals.js +++ b/api/src/globals.js @@ -2,19 +2,19 @@ const is_docker = require('is-docker'); const fs = require('fs'); const platform = `${is_docker() ? 'docker' : 'baremetal'}-${fs - .read_file_sync('/etc/os-release') - .toString() - .split('\n') - .find((x) => x.startsWith('ID')) - .replace('ID=', '')}`; + .read_file_sync('/etc/os-release') + .toString() + .split('\n') + .find(x => x.startsWith('ID')) + .replace('ID=', '')}`; module.exports = { - data_directories: { - packages: 'packages', - jobs: 'jobs', - }, - version: require('../package.json').version, - platform, - pkg_installed_file: '.ppman-installed', //Used as indication for if a package was installed - clean_directories: ['/dev/shm', '/run/lock', '/tmp', '/var/tmp'], + data_directories: { + packages: 'packages', + jobs: 'jobs', + }, + version: require('../package.json').version, + platform, + pkg_installed_file: '.ppman-installed', //Used as indication for if a package was installed + clean_directories: ['/dev/shm', '/run/lock', '/tmp', '/var/tmp'], }; diff --git a/api/src/index.js b/api/src/index.js index 75fda40..ef16916 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -14,77 +14,77 @@ const logger = Logger.create('index'); const app = express(); (async () => { - logger.info('Setting loglevel to', config.log_level); - Logger.setLogLevel(config.log_level); - logger.debug('Ensuring data directories exist'); + logger.info('Setting loglevel to', config.log_level); + Logger.setLogLevel(config.log_level); + logger.debug('Ensuring data directories exist'); - Object.values(globals.data_directories).for_each((dir) => { - let data_path = path.join(config.data_directory, dir); + Object.values(globals.data_directories).for_each(dir => { + let data_path = path.join(config.data_directory, dir); - logger.debug(`Ensuring ${data_path} exists`); + logger.debug(`Ensuring ${data_path} exists`); - if (!fss.exists_sync(data_path)) { - logger.info(`${data_path} does not exist.. Creating..`); + if (!fss.exists_sync(data_path)) { + logger.info(`${data_path} does not exist.. Creating..`); - try { - fss.mkdir_sync(data_path); - } catch (e) { - logger.error(`Failed to create ${data_path}: `, e.message); - } - } - }); + try { + fss.mkdir_sync(data_path); + } catch (e) { + logger.error(`Failed to create ${data_path}: `, e.message); + } + } + }); - logger.info('Loading packages'); - const pkgdir = path.join( - config.data_directory, - globals.data_directories.packages - ); - - const pkglist = await fs.readdir(pkgdir); - - const languages = await Promise.all( - pkglist.map((lang) => { - return fs.readdir(path.join(pkgdir, lang)).then((x) => { - return x.map((y) => path.join(pkgdir, lang, y)); - }); - }) - ); - - const installed_languages = languages - .flat() - .filter((pkg) => - fss.exists_sync(path.join(pkg, globals.pkg_installed_file)) + logger.info('Loading packages'); + const pkgdir = path.join( + config.data_directory, + globals.data_directories.packages ); - installed_languages.for_each((pkg) => runtime.load_package(pkg)); + const pkglist = await fs.readdir(pkgdir); - logger.info('Starting API Server'); - logger.debug('Constructing Express App'); - logger.debug('Registering middleware'); + const languages = await Promise.all( + pkglist.map(lang => { + return fs.readdir(path.join(pkgdir, lang)).then(x => { + return x.map(y => path.join(pkgdir, lang, y)); + }); + }) + ); - app.use(body_parser.urlencoded({ extended: true })); - app.use(body_parser.json()); + const installed_languages = languages + .flat() + .filter(pkg => + fss.exists_sync(path.join(pkg, globals.pkg_installed_file)) + ); - app.use((err, req, res, next) => { - return res.status(400).send({ - stack: err.stack, + installed_languages.for_each(pkg => runtime.load_package(pkg)); + + logger.info('Starting API Server'); + logger.debug('Constructing Express App'); + logger.debug('Registering middleware'); + + app.use(body_parser.urlencoded({ extended: true })); + app.use(body_parser.json()); + + app.use((err, req, res, next) => { + return res.status(400).send({ + stack: err.stack, + }); }); - }); - logger.debug('Registering Routes'); + logger.debug('Registering Routes'); - const api_v2 = require('./api/v2'); - app.use('/api/v2', api_v2); - app.use('/api/v2', api_v2); + const api_v2 = require('./api/v2'); + app.use('/api/v2', api_v2); + app.use('/api/v2', api_v2); - app.use((req, res, next) => { - return res.status(404).send({ message: 'Not Found' }); - }); + app.use((req, res, next) => { + return res.status(404).send({ message: 'Not Found' }); + }); - logger.debug('Calling app.listen'); - const [address, port] = config.bind_address.split(':'); + logger.debug('Calling app.listen'); + const [address, port] = config.bind_address.split(':'); - app.listen(port, address, () => { - logger.info('API server started on', config.bind_address); - }); + app.listen(port, address, () => { + logger.info('API server started on', config.bind_address); + }); })(); diff --git a/api/src/job.js b/api/src/job.js index f301a5e..d4b90ea 100644 --- a/api/src/job.js +++ b/api/src/job.js @@ -8,268 +8,278 @@ const fs = require('fs/promises'); const wait_pid = require('waitpid'); const job_states = { - READY: Symbol('Ready to be primed'), - PRIMED: Symbol('Primed and ready for execution'), - EXECUTED: Symbol('Executed and ready for cleanup'), + READY: Symbol('Ready to be primed'), + PRIMED: Symbol('Primed and ready for execution'), + EXECUTED: Symbol('Executed and ready for cleanup'), }; let uid = 0; let gid = 0; class Job { - constructor({ runtime, files, args, stdin, timeouts, memory_limits }) { - this.uuid = uuidv4(); - this.runtime = runtime; - this.files = files.map((file, i) => ({ - name: file.name || `file${i}.code`, - content: file.content, - })); + constructor({ runtime, files, args, stdin, timeouts, memory_limits }) { + this.uuid = uuidv4(); + this.runtime = runtime; + this.files = files.map((file, i) => ({ + name: file.name || `file${i}.code`, + content: file.content, + })); - this.args = args; - this.stdin = stdin; - this.timeouts = timeouts; - this.memory_limits = memory_limits; + this.args = args; + this.stdin = stdin; + this.timeouts = timeouts; + this.memory_limits = memory_limits; - this.uid = config.runner_uid_min + uid; - this.gid = config.runner_gid_min + gid; + this.uid = config.runner_uid_min + uid; + this.gid = config.runner_gid_min + gid; - uid++; - gid++; + uid++; + gid++; - uid %= config.runner_uid_max - config.runner_uid_min + 1; - gid %= config.runner_gid_max - config.runner_gid_min + 1; + uid %= config.runner_uid_max - config.runner_uid_min + 1; + gid %= config.runner_gid_max - config.runner_gid_min + 1; - this.state = job_states.READY; - this.dir = path.join( - config.data_directory, - globals.data_directories.jobs, - this.uuid - ); - } - - async prime() { - logger.info(`Priming job uuid=${this.uuid}`); - - logger.debug('Writing files to job cache'); - - logger.debug(`Transfering ownership uid=${this.uid} gid=${this.gid}`); - - await fs.mkdir(this.dir, { mode: 0o700 }); - await fs.chown(this.dir, this.uid, this.gid); - - for (const file of this.files) { - let file_path = path.join(this.dir, file.name); - - await fs.write_file(file_path, file.content); - await fs.chown(file_path, this.uid, this.gid); + this.state = job_states.READY; + this.dir = path.join( + config.data_directory, + globals.data_directories.jobs, + this.uuid + ); } - this.state = job_states.PRIMED; + async prime() { + logger.info(`Priming job uuid=${this.uuid}`); - logger.debug('Primed job'); - } + logger.debug('Writing files to job cache'); - async safe_call(file, args, timeout, memory_limit) { - return new Promise((resolve, reject) => { - const nonetwork = config.disable_networking ? ['nosocket'] : []; + logger.debug(`Transfering ownership uid=${this.uid} gid=${this.gid}`); - const prlimit = [ - 'prlimit', - '--nproc=' + config.max_process_count, - '--nofile=' + config.max_open_files, - '--fsize=' + config.max_file_size, - ]; + await fs.mkdir(this.dir, { mode: 0o700 }); + await fs.chown(this.dir, this.uid, this.gid); - if (memory_limit >= 0) { - prlimit.push('--as=' + memory_limit); - } + for (const file of this.files) { + let file_path = path.join(this.dir, file.name); - const proc_call = [...prlimit, ...nonetwork, 'bash', file, ...args]; - - var stdout = ''; - var stderr = ''; - var output = ''; - - const proc = cp.spawn(proc_call[0], proc_call.splice(1), { - env: { - ...this.runtime.env_vars, - PISTON_LANGUAGE: this.runtime.language, - }, - stdio: 'pipe', - cwd: this.dir, - uid: this.uid, - gid: this.gid, - detached: true, //give this process its own process group - }); - - proc.stdin.write(this.stdin); - proc.stdin.end(); - proc.stdin.destroy(); - - const kill_timeout = set_timeout((_) => proc.kill('SIGKILL'), timeout); - - proc.stderr.on('data', (data) => { - if (stderr.length > config.output_max_size) { - proc.kill('SIGKILL'); - } else { - stderr += data; - output += data; + await fs.write_file(file_path, file.content); + await fs.chown(file_path, this.uid, this.gid); } - }); - proc.stdout.on('data', (data) => { - if (stdout.length > config.output_max_size) { - proc.kill('SIGKILL'); - } else { - stdout += data; - output += data; - } - }); + this.state = job_states.PRIMED; - const exit_cleanup = () => { - clear_timeout(kill_timeout); - - proc.stderr.destroy(); - proc.stdout.destroy(); - }; - - proc.on('exit', (code, signal) => { - exit_cleanup(); - - resolve({ stdout, stderr, code, signal, output }); - }); - - proc.on('error', (err) => { - exit_cleanup(); - - reject({ error: err, stdout, stderr, output }); - }); - }); - } - - async execute() { - if (this.state !== job_states.PRIMED) { - throw new Error( - 'Job must be in primed state, current state: ' + this.state.toString() - ); + logger.debug('Primed job'); } - logger.info( - `Executing job uuid=${this.uuid} uid=${this.uid} gid=${ - this.gid - } runtime=${this.runtime.toString()}` - ); + async safe_call(file, args, timeout, memory_limit) { + return new Promise((resolve, reject) => { + const nonetwork = config.disable_networking ? ['nosocket'] : []; - logger.debug('Compiling'); + const prlimit = [ + 'prlimit', + '--nproc=' + config.max_process_count, + '--nofile=' + config.max_open_files, + '--fsize=' + config.max_file_size, + ]; - let compile; + if (memory_limit >= 0) { + prlimit.push('--as=' + memory_limit); + } - if (this.runtime.compiled) { - compile = await this.safe_call( - path.join(this.runtime.pkgdir, 'compile'), - this.files.map((x) => x.name), - this.timeouts.compile, - this.memory_limits.compile - ); - } + const proc_call = [...prlimit, ...nonetwork, 'bash', file, ...args]; - logger.debug('Running'); + var stdout = ''; + var stderr = ''; + var output = ''; - const run = await this.safe_call( - path.join(this.runtime.pkgdir, 'run'), - [this.files[0].name, ...this.args], - this.timeouts.run, - this.memory_limits.run - ); - - this.state = job_states.EXECUTED; - - return { - compile, - run, - language: this.runtime.language, - version: this.runtime.version.raw, - }; - } - - async cleanup_processes() { - let processes = [1]; - - while (processes.length > 0) { - processes = await new Promise((resolve, reject) => - cp.execFile('ps', ['awwxo', 'pid,ruid'], (err, stdout) => { - if (err === null) { - const lines = stdout.split('\n').slice(1); //Remove header with slice - const procs = lines.map((line) => { - const [pid, ruid] = line - .trim() - .split(/\s+/) - .map((n) => parseInt(n)); - - return { pid, ruid }; + const proc = cp.spawn(proc_call[0], proc_call.splice(1), { + env: { + ...this.runtime.env_vars, + PISTON_LANGUAGE: this.runtime.language, + }, + stdio: 'pipe', + cwd: this.dir, + uid: this.uid, + gid: this.gid, + detached: true, //give this process its own process group }); - resolve(procs); - } else { - reject(error); - } - }) - ); + proc.stdin.write(this.stdin); + proc.stdin.end(); + proc.stdin.destroy(); - processes = processes.filter((proc) => proc.ruid === this.uid); + const kill_timeout = set_timeout( + _ => proc.kill('SIGKILL'), + timeout + ); - for (const proc of processes) { - // First stop the processes, but keep their resources allocated so they cant re-fork - try { - process.kill(proc.pid, 'SIGSTOP'); - } catch { - // Could already be dead - } - } + proc.stderr.on('data', data => { + if (stderr.length > config.output_max_size) { + proc.kill('SIGKILL'); + } else { + stderr += data; + output += data; + } + }); - for (const proc of processes) { - // Then clear them out of the process tree - try { - process.kill(proc.pid, 'SIGKILL'); - } catch { - // Could already be dead and just needs to be waited on - } + proc.stdout.on('data', data => { + if (stdout.length > config.output_max_size) { + proc.kill('SIGKILL'); + } else { + stdout += data; + output += data; + } + }); - wait_pid(proc.pid); - } - } - } + const exit_cleanup = () => { + clear_timeout(kill_timeout); - async cleanup_filesystem() { - for (const clean_path of globals.clean_directories) { - const contents = await fs.readdir(clean_path); + proc.stderr.destroy(); + proc.stdout.destroy(); + }; - for (const file of contents) { - const file_path = path.join(clean_path, file); + proc.on('exit', (code, signal) => { + exit_cleanup(); - try { - const stat = await fs.stat(file_path); + resolve({ stdout, stderr, code, signal, output }); + }); - if (stat.uid === this.uid) { - await fs.rm(file_path, { recursive: true, force: true }); - } - } catch (e) { - // File was somehow deleted in the time that we read the dir to when we checked the file - logger.warn(`Error removing file ${file_path}: ${e}`); - } - } + proc.on('error', err => { + exit_cleanup(); + + reject({ error: err, stdout, stderr, output }); + }); + }); } - await fs.rm(this.dir, { recursive: true, force: true }); - } + async execute() { + if (this.state !== job_states.PRIMED) { + throw new Error( + 'Job must be in primed state, current state: ' + + this.state.toString() + ); + } - async cleanup() { - logger.info(`Cleaning up job uuid=${this.uuid}`); + logger.info( + `Executing job uuid=${this.uuid} uid=${this.uid} gid=${ + this.gid + } runtime=${this.runtime.toString()}` + ); - await Promise.all([this.cleanup_processes(), this.cleanup_filesystem()]); - } + logger.debug('Compiling'); + + let compile; + + if (this.runtime.compiled) { + compile = await this.safe_call( + path.join(this.runtime.pkgdir, 'compile'), + this.files.map(x => x.name), + this.timeouts.compile, + this.memory_limits.compile + ); + } + + logger.debug('Running'); + + const run = await this.safe_call( + path.join(this.runtime.pkgdir, 'run'), + [this.files[0].name, ...this.args], + this.timeouts.run, + this.memory_limits.run + ); + + this.state = job_states.EXECUTED; + + return { + compile, + run, + language: this.runtime.language, + version: this.runtime.version.raw, + }; + } + + async cleanup_processes() { + let processes = [1]; + + while (processes.length > 0) { + processes = await new Promise((resolve, reject) => + cp.execFile('ps', ['awwxo', 'pid,ruid'], (err, stdout) => { + if (err === null) { + const lines = stdout.split('\n').slice(1); //Remove header with slice + const procs = lines.map(line => { + const [pid, ruid] = line + .trim() + .split(/\s+/) + .map(n => parseInt(n)); + + return { pid, ruid }; + }); + + resolve(procs); + } else { + reject(error); + } + }) + ); + + processes = processes.filter(proc => proc.ruid === this.uid); + + for (const proc of processes) { + // First stop the processes, but keep their resources allocated so they cant re-fork + try { + process.kill(proc.pid, 'SIGSTOP'); + } catch { + // Could already be dead + } + } + + for (const proc of processes) { + // Then clear them out of the process tree + try { + process.kill(proc.pid, 'SIGKILL'); + } catch { + // Could already be dead and just needs to be waited on + } + + wait_pid(proc.pid); + } + } + } + + async cleanup_filesystem() { + for (const clean_path of globals.clean_directories) { + const contents = await fs.readdir(clean_path); + + for (const file of contents) { + const file_path = path.join(clean_path, file); + + try { + const stat = await fs.stat(file_path); + + if (stat.uid === this.uid) { + await fs.rm(file_path, { + recursive: true, + force: true, + }); + } + } catch (e) { + // File was somehow deleted in the time that we read the dir to when we checked the file + logger.warn(`Error removing file ${file_path}: ${e}`); + } + } + } + + await fs.rm(this.dir, { recursive: true, force: true }); + } + + async cleanup() { + logger.info(`Cleaning up job uuid=${this.uuid}`); + + await Promise.all([ + this.cleanup_processes(), + this.cleanup_filesystem(), + ]); + } } module.exports = { - Job, + Job, }; diff --git a/api/src/package.js b/api/src/package.js index ae6f944..1baa8af 100644 --- a/api/src/package.js +++ b/api/src/package.js @@ -13,197 +13,208 @@ const chownr = require('chownr'); const util = require('util'); class Package { - constructor({ language, version, download, checksum }) { - this.language = language; - this.version = semver.parse(version); - this.checksum = checksum; - this.download = download; - } - - get installed() { - return fss.exists_sync( - path.join(this.install_path, globals.pkg_installed_file) - ); - } - - get install_path() { - return path.join( - config.data_directory, - globals.data_directories.packages, - this.language, - this.version.raw - ); - } - - async install() { - if (this.installed) { - throw new Error('Already installed'); + constructor({ language, version, download, checksum }) { + this.language = language; + this.version = semver.parse(version); + this.checksum = checksum; + this.download = download; } - logger.info(`Installing ${this.language}-${this.version.raw}`); - - if (fss.exists_sync(this.install_path)) { - logger.warn( - `${this.language}-${this.version.raw} has residual files. Removing them.` - ); - await fs.rm(this.install_path, { recursive: true, force: true }); + get installed() { + return fss.exists_sync( + path.join(this.install_path, globals.pkg_installed_file) + ); } - logger.debug(`Making directory ${this.install_path}`); - await fs.mkdir(this.install_path, { recursive: true }); - - logger.debug( - `Downloading package from ${this.download} in to ${this.install_path}` - ); - const pkgpath = path.join(this.install_path, 'pkg.tar.gz'); - const download = await fetch(this.download); - - const file_stream = fss.create_write_stream(pkgpath); - await new Promise((resolve, reject) => { - download.body.pipe(file_stream); - download.body.on('error', reject); - - file_stream.on('finish', resolve); - }); - - logger.debug('Validating checksums'); - logger.debug(`Assert sha256(pkg.tar.gz) == ${this.checksum}`); - const cs = crypto - .create_hash('sha256') - .update(fss.readFileSync(pkgpath)) - .digest('hex'); - - if (cs !== this.checksum) { - throw new Error(`Checksum miss-match want: ${val} got: ${cs}`); + get install_path() { + return path.join( + config.data_directory, + globals.data_directories.packages, + this.language, + this.version.raw + ); } - logger.debug( - `Extracting package files from archive ${pkgpath} in to ${this.install_path}` - ); + async install() { + if (this.installed) { + throw new Error('Already installed'); + } - await new Promise((resolve, reject) => { - const proc = cp.exec( - `bash -c 'cd "${this.install_path}" && tar xzf ${pkgpath}'` - ); + logger.info(`Installing ${this.language}-${this.version.raw}`); - proc.once('exit', (code, _) => { - code === 0 ? resolve() : reject(); - }); + if (fss.exists_sync(this.install_path)) { + logger.warn( + `${this.language}-${this.version.raw} has residual files. Removing them.` + ); + await fs.rm(this.install_path, { recursive: true, force: true }); + } - proc.stdout.pipe(process.stdout); - proc.stderr.pipe(process.stderr); + logger.debug(`Making directory ${this.install_path}`); + await fs.mkdir(this.install_path, { recursive: true }); - proc.once('error', reject); - }); + logger.debug( + `Downloading package from ${this.download} in to ${this.install_path}` + ); + const pkgpath = path.join(this.install_path, 'pkg.tar.gz'); + const download = await fetch(this.download); - logger.debug('Registering runtime'); - runtime.load_package(this.install_path); + const file_stream = fss.create_write_stream(pkgpath); + await new Promise((resolve, reject) => { + download.body.pipe(file_stream); + download.body.on('error', reject); - logger.debug('Caching environment'); - const get_env_command = `cd ${this.install_path}; source environment; env`; + file_stream.on('finish', resolve); + }); - const envout = await new Promise((resolve, reject) => { - let stdout = ''; + logger.debug('Validating checksums'); + logger.debug(`Assert sha256(pkg.tar.gz) == ${this.checksum}`); + const cs = crypto + .create_hash('sha256') + .update(fss.readFileSync(pkgpath)) + .digest('hex'); - const proc = cp.spawn('env', ['-i', 'bash', '-c', `${get_env_command}`], { - stdio: ['ignore', 'pipe', 'pipe'], - }); + if (cs !== this.checksum) { + throw new Error(`Checksum miss-match want: ${val} got: ${cs}`); + } - proc.once('exit', (code, _) => { - code === 0 ? resolve(stdout) : reject(); - }); + logger.debug( + `Extracting package files from archive ${pkgpath} in to ${this.install_path}` + ); - proc.stdout.on('data', (data) => { - stdout += data; - }); + await new Promise((resolve, reject) => { + const proc = cp.exec( + `bash -c 'cd "${this.install_path}" && tar xzf ${pkgpath}'` + ); - proc.once('error', reject); - }); + proc.once('exit', (code, _) => { + code === 0 ? resolve() : reject(); + }); - const filtered_env = envout - .split('\n') - .filter( - (l) => !['PWD', 'OLDPWD', '_', 'SHLVL'].includes(l.split('=', 2)[0]) - ) - .join('\n'); + proc.stdout.pipe(process.stdout); + proc.stderr.pipe(process.stderr); - await fs.write_file(path.join(this.install_path, '.env'), filtered_env); + proc.once('error', reject); + }); - logger.debug('Changing Ownership of package directory'); - await util.promisify(chownr)(this.install_path, 0, 0); + logger.debug('Registering runtime'); + runtime.load_package(this.install_path); - logger.debug('Writing installed state to disk'); - await fs.write_file( - path.join(this.install_path, globals.pkg_installed_file), - Date.now().toString() - ); + logger.debug('Caching environment'); + const get_env_command = `cd ${this.install_path}; source environment; env`; - logger.info(`Installed ${this.language}-${this.version.raw}`); + const envout = await new Promise((resolve, reject) => { + let stdout = ''; - return { - language: this.language, - version: this.version.raw, - }; - } + const proc = cp.spawn( + 'env', + ['-i', 'bash', '-c', `${get_env_command}`], + { + stdio: ['ignore', 'pipe', 'pipe'], + } + ); - async uninstall() { - logger.info(`Uninstalling ${this.language}-${this.version.raw}`); + proc.once('exit', (code, _) => { + code === 0 ? resolve(stdout) : reject(); + }); - logger.debug('Finding runtime'); - const found_runtime = runtime.get_runtime_by_name_and_version( - this.language, - this.version.raw - ); + proc.stdout.on('data', data => { + stdout += data; + }); - if (!found_runtime) { - logger.error( - `Uninstalling ${this.language}-${this.version.raw} failed: Not installed` - ); - throw new Error(`${this.language}-${this.version.raw} is not installed`); + proc.once('error', reject); + }); + + const filtered_env = envout + .split('\n') + .filter( + l => + !['PWD', 'OLDPWD', '_', 'SHLVL'].includes( + l.split('=', 2)[0] + ) + ) + .join('\n'); + + await fs.write_file(path.join(this.install_path, '.env'), filtered_env); + + logger.debug('Changing Ownership of package directory'); + await util.promisify(chownr)(this.install_path, 0, 0); + + logger.debug('Writing installed state to disk'); + await fs.write_file( + path.join(this.install_path, globals.pkg_installed_file), + Date.now().toString() + ); + + logger.info(`Installed ${this.language}-${this.version.raw}`); + + return { + language: this.language, + version: this.version.raw, + }; } - logger.debug('Unregistering runtime'); - found_runtime.unregister(); + async uninstall() { + logger.info(`Uninstalling ${this.language}-${this.version.raw}`); - logger.debug('Cleaning files from disk'); - await fs.rmdir(this.install_path, { recursive: true }); + logger.debug('Finding runtime'); + const found_runtime = runtime.get_runtime_by_name_and_version( + this.language, + this.version.raw + ); - logger.info(`Uninstalled ${this.language}-${this.version.raw}`); + if (!found_runtime) { + logger.error( + `Uninstalling ${this.language}-${this.version.raw} failed: Not installed` + ); + throw new Error( + `${this.language}-${this.version.raw} is not installed` + ); + } - return { - language: this.language, - version: this.version.raw, - }; - } + logger.debug('Unregistering runtime'); + found_runtime.unregister(); - static async get_package_list() { - const repo_content = await fetch(config.repo_url).then((x) => x.text()); + logger.debug('Cleaning files from disk'); + await fs.rmdir(this.install_path, { recursive: true }); - const entries = repo_content.split('\n').filter((x) => x.length > 0); + logger.info(`Uninstalled ${this.language}-${this.version.raw}`); - return entries.map((line) => { - const [language, version, checksum, download] = line.split(',', 4); + return { + language: this.language, + version: this.version.raw, + }; + } - return new Package({ - language, - version, - checksum, - download, - }); - }); - } + static async get_package_list() { + const repo_content = await fetch(config.repo_url).then(x => x.text()); - static async get_package(lang, version) { - const packages = await Package.get_package_list(); + const entries = repo_content.split('\n').filter(x => x.length > 0); - const candidates = packages.filter((pkg) => { - return pkg.language == lang && semver.satisfies(pkg.version, version); - }); + return entries.map(line => { + const [language, version, checksum, download] = line.split(',', 4); - candidates.sort((a, b) => semver.rcompare(a.version, b.version)); + return new Package({ + language, + version, + checksum, + download, + }); + }); + } - return candidates[0] || null; - } + static async get_package(lang, version) { + const packages = await Package.get_package_list(); + + const candidates = packages.filter(pkg => { + return ( + pkg.language == lang && semver.satisfies(pkg.version, version) + ); + }); + + candidates.sort((a, b) => semver.rcompare(a.version, b.version)); + + return candidates[0] || null; + } } module.exports = Package; diff --git a/api/src/runtime.js b/api/src/runtime.js index 418dc42..191fc5d 100644 --- a/api/src/runtime.js +++ b/api/src/runtime.js @@ -8,118 +8,118 @@ const path = require('path'); const runtimes = []; class Runtime { - constructor({ language, version, aliases, pkgdir, runtime }) { - this.language = language; - this.version = version; - this.aliases = aliases || []; - this.pkgdir = pkgdir; - this.runtime = runtime; - } - - static load_package(package_dir) { - let info = JSON.parse( - fss.read_file_sync(path.join(package_dir, 'pkg-info.json')) - ); - - let { language, version, build_platform, aliases, provides } = info; - version = semver.parse(version); - - if (build_platform !== globals.platform) { - logger.warn( - `Package ${language}-${version} was built for platform ${build_platform}, ` + - `but our platform is ${globals.platform}` - ); + constructor({ language, version, aliases, pkgdir, runtime }) { + this.language = language; + this.version = version; + this.aliases = aliases || []; + this.pkgdir = pkgdir; + this.runtime = runtime; } - if (provides) { - // Multiple languages in 1 package - provides.forEach((lang) => { - runtimes.push( - new Runtime({ - language: lang.language, - aliases: lang.aliases, - version, - pkgdir: package_dir, - runtime: language, - }) + static load_package(package_dir) { + let info = JSON.parse( + fss.read_file_sync(path.join(package_dir, 'pkg-info.json')) ); - }); - } else { - runtimes.push( - new Runtime({ - language, - version, - aliases, - pkgdir: package_dir, - }) - ); + + let { language, version, build_platform, aliases, provides } = info; + version = semver.parse(version); + + if (build_platform !== globals.platform) { + logger.warn( + `Package ${language}-${version} was built for platform ${build_platform}, ` + + `but our platform is ${globals.platform}` + ); + } + + if (provides) { + // Multiple languages in 1 package + provides.forEach(lang => { + runtimes.push( + new Runtime({ + language: lang.language, + aliases: lang.aliases, + version, + pkgdir: package_dir, + runtime: language, + }) + ); + }); + } else { + runtimes.push( + new Runtime({ + language, + version, + aliases, + pkgdir: package_dir, + }) + ); + } + + logger.debug(`Package ${language}-${version} was loaded`); } - logger.debug(`Package ${language}-${version} was loaded`); - } + get compiled() { + if (this._compiled === undefined) { + this._compiled = fss.exists_sync(path.join(this.pkgdir, 'compile')); + } - get compiled() { - if (this._compiled === undefined) { - this._compiled = fss.exists_sync(path.join(this.pkgdir, 'compile')); + return this._compiled; } - return this._compiled; - } + get env_vars() { + if (!this._env_vars) { + const env_file = path.join(this.pkgdir, '.env'); + const env_content = fss.read_file_sync(env_file).toString(); - get env_vars() { - if (!this._env_vars) { - const env_file = path.join(this.pkgdir, '.env'); - const env_content = fss.read_file_sync(env_file).toString(); + this._env_vars = {}; - this._env_vars = {}; + env_content + .trim() + .split('\n') + .map(line => line.split('=', 2)) + .forEach(([key, val]) => { + this._env_vars[key.trim()] = val.trim(); + }); + } - env_content - .trim() - .split('\n') - .map((line) => line.split('=', 2)) - .forEach(([key, val]) => { - this._env_vars[key.trim()] = val.trim(); - }); + return this._env_vars; } - return this._env_vars; - } + toString() { + return `${this.language}-${this.version.raw}`; + } - toString() { - return `${this.language}-${this.version.raw}`; - } - - unregister() { - const index = runtimes.indexOf(this); - runtimes.splice(index, 1); //Remove from runtimes list - } + unregister() { + const index = runtimes.indexOf(this); + runtimes.splice(index, 1); //Remove from runtimes list + } } module.exports = runtimes; module.exports.Runtime = Runtime; module.exports.get_runtimes_matching_language_version = function (lang, ver) { - return runtimes.filter( - (rt) => - (rt.language == lang || rt.aliases.includes(lang)) && - semver.satisfies(rt.version, ver) - ); + return runtimes.filter( + rt => + (rt.language == lang || rt.aliases.includes(lang)) && + semver.satisfies(rt.version, ver) + ); }; module.exports.get_latest_runtime_matching_language_version = function ( - lang, - ver + lang, + ver ) { - return module.exports - .get_runtimes_matching_language_version(lang, ver) - .sort((a, b) => semver.rcompare(a.version, b.version))[0]; + return module.exports + .get_runtimes_matching_language_version(lang, ver) + .sort((a, b) => semver.rcompare(a.version, b.version))[0]; }; module.exports.get_runtime_by_name_and_version = function (runtime, ver) { - return runtimes.find( - (rt) => - (rt.runtime == runtime || - (rt.runtime === undefined && rt.language == runtime)) && - semver.satisfies(rt.version, ver) - ); + return runtimes.find( + rt => + (rt.runtime == runtime || + (rt.runtime === undefined && rt.language == runtime)) && + semver.satisfies(rt.version, ver) + ); }; module.exports.load_package = Runtime.load_package;