Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
5111897b78 | |||
be79d178ff | |||
97ad29ade0 | |||
f31951c478 | |||
d0c4272f51 | |||
eeb104ee60 | |||
a51fc71990 | |||
c2f53a4703 | |||
3141586477 | |||
c5a76c28ad | |||
b02b20528a | |||
1a89440624 | |||
fb7d8fdd37 | |||
a014b0b531 | |||
693ab863c2 | |||
dde5a13550 | |||
3326e0e9e3 | |||
845773f3f1 | |||
d4052f03a1 | |||
c9cf7ae603 | |||
b2439a7a49 | |||
274620c994 | |||
26e79bbb20 | |||
4b8591f51e | |||
cfcd17d45e | |||
|
7797eb9210 | ||
6cb78c657f | |||
b6f21b8192 | |||
5fe7f45728 | |||
23471d5bb3 |
17
.dockerignore
Normal file
17
.dockerignore
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
.kpt-pipeline/
|
||||||
|
k8s/
|
||||||
|
skaffold.yaml
|
||||||
|
README.md
|
||||||
|
.git/
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
*.kpt-pipeline
|
@ -1,5 +1,5 @@
|
|||||||
# pull official node image
|
# pull official node image
|
||||||
FROM node
|
FROM node AS dev
|
||||||
|
|
||||||
# define /app as working directory
|
# define /app as working directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
@ -13,4 +13,8 @@ RUN npm install
|
|||||||
COPY . /app
|
COPY . /app
|
||||||
|
|
||||||
# launch node server
|
# launch node server
|
||||||
ENTRYPOINT node server.js
|
ENTRYPOINT npm run dev
|
||||||
|
|
||||||
|
# production
|
||||||
|
FROM dev AS prod
|
||||||
|
ENTRYPOINT npm run start
|
640
backend/package-lock.json
generated
640
backend/package-lock.json
generated
@ -13,6 +13,9 @@
|
|||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"minio": "^7.0.26",
|
"minio": "^7.0.26",
|
||||||
"mongodb": "^4.3.1"
|
"mongodb": "^4.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
@ -40,6 +43,12 @@
|
|||||||
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/abbrev": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.7",
|
"version": "1.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
@ -52,6 +61,19 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/anymatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
@ -89,6 +111,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
@ -108,6 +136,15 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/binary-extensions": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/block-stream2": {
|
"node_modules/block-stream2": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
||||||
@ -141,6 +178,28 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brorand": {
|
"node_modules/brorand": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||||
@ -269,6 +328,33 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "3.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"glob-parent": "~5.1.2",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.10.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cipher-base": {
|
"node_modules/cipher-base": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||||
@ -278,6 +364,12 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
@ -609,6 +701,18 @@
|
|||||||
"url": "https://paypal.me/naturalintelligence"
|
"url": "https://paypal.me/naturalintelligence"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
@ -647,6 +751,20 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@ -680,6 +798,18 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has": {
|
"node_modules/has": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||||
@ -699,6 +829,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has-symbols": {
|
"node_modules/has-symbols": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||||
@ -801,6 +940,12 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/ignore-by-default": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
@ -858,6 +1003,18 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-boolean-object": {
|
"node_modules/is-boolean-object": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
||||||
@ -898,6 +1055,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-generator-function": {
|
"node_modules/is-generator-function": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
||||||
@ -912,6 +1078,18 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-negative-zero": {
|
"node_modules/is-negative-zero": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||||
@ -923,6 +1101,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-number-object": {
|
"node_modules/is-number-object": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
|
||||||
@ -1121,6 +1308,18 @@
|
|||||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||||
},
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
@ -1210,6 +1409,73 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nodemon": {
|
||||||
|
"version": "2.0.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
|
||||||
|
"integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^3.5.2",
|
||||||
|
"debug": "^3.2.7",
|
||||||
|
"ignore-by-default": "^1.0.1",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"pstree.remy": "^1.1.8",
|
||||||
|
"semver": "^5.7.1",
|
||||||
|
"simple-update-notifier": "^1.0.7",
|
||||||
|
"supports-color": "^5.5.0",
|
||||||
|
"touch": "^3.1.0",
|
||||||
|
"undefsafe": "^2.0.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nodemon": "bin/nodemon.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/nodemon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nodemon/node_modules/debug": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nodemon/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/nopt": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": "1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nopt": "bin/nopt.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -1302,6 +1568,18 @@
|
|||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -1314,6 +1592,12 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pstree.remy": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/public-encrypt": {
|
"node_modules/public-encrypt": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
||||||
@ -1412,6 +1696,18 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ripemd160": {
|
"node_modules/ripemd160": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
||||||
@ -1462,6 +1758,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "0.17.2",
|
"version": "0.17.2",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
||||||
@ -1534,6 +1839,27 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-update-notifier": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "~7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/simple-update-notifier/node_modules/semver": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/smart-buffer": {
|
"node_modules/smart-buffer": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||||
@ -1610,6 +1936,18 @@
|
|||||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/through2": {
|
"node_modules/through2": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
||||||
@ -1619,6 +1957,18 @@
|
|||||||
"readable-stream": "2 || 3"
|
"readable-stream": "2 || 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
@ -1627,6 +1977,18 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/touch": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"nopt": "~1.0.10"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nodetouch": "bin/nodetouch.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tr46": {
|
"node_modules/tr46": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
||||||
@ -1664,6 +2026,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undefsafe": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@ -1823,6 +2191,12 @@
|
|||||||
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"abbrev": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"accepts": {
|
"accepts": {
|
||||||
"version": "1.3.7",
|
"version": "1.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
@ -1832,6 +2206,16 @@
|
|||||||
"negotiator": "0.6.2"
|
"negotiator": "0.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"anymatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"array-flatten": {
|
"array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
@ -1865,11 +2249,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||||
},
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||||
},
|
},
|
||||||
|
"binary-extensions": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"block-stream2": {
|
"block-stream2": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz",
|
||||||
@ -1900,6 +2296,25 @@
|
|||||||
"type-is": "~1.6.18"
|
"type-is": "~1.6.18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"brorand": {
|
"brorand": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||||
@ -2005,6 +2420,22 @@
|
|||||||
"get-intrinsic": "^1.0.2"
|
"get-intrinsic": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"chokidar": {
|
||||||
|
"version": "3.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"fsevents": "~2.3.2",
|
||||||
|
"glob-parent": "~5.1.2",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cipher-base": {
|
"cipher-base": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||||
@ -2014,6 +2445,12 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"content-disposition": {
|
"content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
@ -2299,6 +2736,15 @@
|
|||||||
"strnum": "^1.0.4"
|
"strnum": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"finalhandler": {
|
"finalhandler": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
@ -2328,6 +2774,13 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@ -2352,6 +2805,15 @@
|
|||||||
"get-intrinsic": "^1.1.1"
|
"get-intrinsic": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"has": {
|
"has": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||||
@ -2365,6 +2827,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
|
||||||
"integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
|
"integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
|
||||||
},
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"has-symbols": {
|
"has-symbols": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||||
@ -2432,6 +2900,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||||
},
|
},
|
||||||
|
"ignore-by-default": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
@ -2474,6 +2948,15 @@
|
|||||||
"has-bigints": "^1.0.1"
|
"has-bigints": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-boolean-object": {
|
"is-boolean-object": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
||||||
@ -2496,6 +2979,12 @@
|
|||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-generator-function": {
|
"is-generator-function": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
|
||||||
@ -2504,11 +2993,26 @@
|
|||||||
"has-tostringtag": "^1.0.0"
|
"has-tostringtag": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-negative-zero": {
|
"is-negative-zero": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||||
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
|
"integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
|
||||||
},
|
},
|
||||||
|
"is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-number-object": {
|
"is-number-object": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
|
||||||
@ -2652,6 +3156,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||||
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
|
||||||
},
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
@ -2726,6 +3239,56 @@
|
|||||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||||
},
|
},
|
||||||
|
"nodemon": {
|
||||||
|
"version": "2.0.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz",
|
||||||
|
"integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chokidar": "^3.5.2",
|
||||||
|
"debug": "^3.2.7",
|
||||||
|
"ignore-by-default": "^1.0.1",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"pstree.remy": "^1.1.8",
|
||||||
|
"semver": "^5.7.1",
|
||||||
|
"simple-update-notifier": "^1.0.7",
|
||||||
|
"supports-color": "^5.5.0",
|
||||||
|
"touch": "^3.1.0",
|
||||||
|
"undefsafe": "^2.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nopt": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"abbrev": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@ -2794,6 +3357,12 @@
|
|||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -2803,6 +3372,12 @@
|
|||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pstree.remy": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"public-encrypt": {
|
"public-encrypt": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
|
||||||
@ -2881,6 +3456,15 @@
|
|||||||
"util-deprecate": "^1.0.1"
|
"util-deprecate": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ripemd160": {
|
"ripemd160": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
|
||||||
@ -2914,6 +3498,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||||
},
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"send": {
|
"send": {
|
||||||
"version": "0.17.2",
|
"version": "0.17.2",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
|
||||||
@ -2976,6 +3566,23 @@
|
|||||||
"object-inspect": "^1.9.0"
|
"object-inspect": "^1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"simple-update-notifier": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"semver": "~7.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"smart-buffer": {
|
"smart-buffer": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||||
@ -3035,6 +3642,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||||
},
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"through2": {
|
"through2": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
||||||
@ -3044,11 +3660,29 @@
|
|||||||
"readable-stream": "2 || 3"
|
"readable-stream": "2 || 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"toidentifier": {
|
"toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||||
},
|
},
|
||||||
|
"touch": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"nopt": "~1.0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tr46": {
|
"tr46": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
||||||
@ -3077,6 +3711,12 @@
|
|||||||
"which-boxed-primitive": "^1.0.2"
|
"which-boxed-primitive": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"undefsafe": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"unpipe": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "node server.js",
|
"dev": "nodemon server.js -e ejs,js,css,html,jpg,png,scss",
|
||||||
"build": "cd frontend && npm install && npm run build"
|
"prod": "node.js server.js"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
@ -16,5 +16,8 @@
|
|||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"minio": "^7.0.26",
|
"minio": "^7.0.26",
|
||||||
"mongodb": "^4.3.1"
|
"mongodb": "^4.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,12 @@
|
|||||||
const { MongoClient } = require("mongodb");
|
const { MongoClient, MongoClientOptions } = require("mongodb");
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const minio = require('minio');
|
|
||||||
|
|
||||||
/*============== VARIABLE DECLARATION ==============*/
|
/*============== VARIABLE DECLARATION ==============*/
|
||||||
// Mongo set-up variables
|
// Mongo set-up variables
|
||||||
const mongoCollection = process.env.MONGO_COLLECTION || 'eventlog';
|
const mongoCollection = process.env.MONGO_COLLECTION || 'log';
|
||||||
const mongoUri = process.env.MONGO_URI || 'mongodb://127.0.0.1:27017/default?replicaSet=rs0';
|
const mongoUri = process.env.MONGODB_HOST || 'mongodb://127.0.0.1:27017/default?replicaSet=rs0';
|
||||||
|
|
||||||
// Minio set-up variables
|
const historyNumber = parseInt(process.env.HISTORY_AMOUNT) || 50;
|
||||||
const minioAccessKey = process.env.MINIO_ACCESS_KEY || 'kspace-mugshot';
|
|
||||||
const minioSecretKey = process.env.MINIO_SECRET_KEY || '2mSI6HdbJ8';
|
|
||||||
const minioHostname = process.env.MINIO_HOSTNAME || '127.0.0.1';
|
|
||||||
const minioPort = process.env.MINIO_PORT || 9000;
|
|
||||||
const minioScheme = process.env.MINIO_SCHEME || 'http';
|
|
||||||
const minioBucket = process.env.MINIO_BUCKET || 'kspace-mugshot';
|
|
||||||
console.info("Using bucket:", minioBucket);
|
|
||||||
const historyNumber = parseInt(process.env.HISTORY_AMOUNT) || 10;
|
|
||||||
|
|
||||||
// Stream set-up variables
|
// Stream set-up variables
|
||||||
let changeStream;
|
let changeStream;
|
||||||
@ -24,8 +15,10 @@ const pipeline = [];
|
|||||||
const PORT = process.env.PORT || 3002;
|
const PORT = process.env.PORT || 3002;
|
||||||
|
|
||||||
// Create Mongo client
|
// Create Mongo client
|
||||||
const mongoClient = new MongoClient(mongoUri);
|
const mongoOptions = {
|
||||||
|
readPreference: 'secondaryPreferred'
|
||||||
|
}
|
||||||
|
const mongoClient = new MongoClient(mongoUri, mongoOptions);
|
||||||
|
|
||||||
/*============== CODE ==============*/
|
/*============== CODE ==============*/
|
||||||
async function run() {
|
async function run() {
|
||||||
@ -38,63 +31,47 @@ async function run() {
|
|||||||
|
|
||||||
changeStream = collection.watch(pipeline, options);
|
changeStream = collection.watch(pipeline, options);
|
||||||
console.log("Started watching changes in database");
|
console.log("Started watching changes in database");
|
||||||
console.log("Minio hostname:", minioHostname);
|
|
||||||
console.log("Minio port:", minioPort);
|
const filterOptions = {
|
||||||
console.log("Minio protocol:", minioScheme);
|
'kubernetes.namespace': await collection.distinct('kubernetes.namespace'),
|
||||||
|
'kubernetes.pod.name': await collection.distinct('kubernetes.pod.name'),
|
||||||
|
'kubernetes.container.name': await collection.distinct('kubernetes.container.name')
|
||||||
|
}
|
||||||
|
|
||||||
|
const writeMessage = (response, blob) => {
|
||||||
|
const id = blob._id || null
|
||||||
|
const message = `id: ${id}\nevent: message\ndata: ${JSON.stringify(blob)}\n\n`
|
||||||
|
response.write(message)
|
||||||
|
}
|
||||||
|
|
||||||
// Triggers on GET at /event route
|
// Triggers on GET at /event route
|
||||||
app.get('/events', async function (request, response) {
|
app.get('/events', async function (request, response) {
|
||||||
let minioClient = new minio.Client({
|
|
||||||
endPoint: minioHostname,
|
|
||||||
port: parseInt(minioPort),
|
|
||||||
useSSL: minioScheme == 'https',
|
|
||||||
accessKey: minioAccessKey,
|
|
||||||
secretKey: minioSecretKey
|
|
||||||
});
|
|
||||||
|
|
||||||
async function wrapEvent(doc) {
|
// Notify SSE to React
|
||||||
let arr = [];
|
|
||||||
let blob;
|
|
||||||
if (doc && doc.screenshot_count) {
|
|
||||||
for (let i = 1; i <= doc.screenshot_count ; i++) {
|
|
||||||
arr.push({
|
|
||||||
url: await minioClient.presignedUrl('GET', minioBucket,
|
|
||||||
`${doc.camera}/${doc._id}/${i}.jpg`, 60 * 60)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (doc && doc.screenshots) {
|
|
||||||
for (let j = 0; j < doc.screenshots.length; j++) {
|
|
||||||
let path = doc.screenshots[j];
|
|
||||||
arr.push({
|
|
||||||
url: await minioClient.presignedUrl('GET', minioBucket,
|
|
||||||
`thumb/${path}`, 60 * 60),
|
|
||||||
orig: await minioClient.presignedUrl('GET', minioBucket,
|
|
||||||
`${path}`, 60 * 60)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (arr.length > 0) {
|
|
||||||
blob = JSON.stringify({...doc, screenshots: [...arr]});
|
|
||||||
} else {
|
|
||||||
blob = JSON.stringify({...doc});
|
|
||||||
}
|
|
||||||
return `event: log-entry\ndata: ${blob}\n\n`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify SSE to React
|
|
||||||
const header = { 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive' };
|
const header = { 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive' };
|
||||||
response.writeHead(200, "OK", header);
|
response.writeHead(200, "OK", header);
|
||||||
|
|
||||||
const historyCursor = collection.find().sort({$natural:-1}).limit(historyNumber);
|
const message = `id: 1\nevent: filters\ndata: ${JSON.stringify(filterOptions)}\n\n`
|
||||||
|
response.write(message)
|
||||||
|
|
||||||
historyCursor.forEach(async (document) => {
|
const historyCursor = collection.find()
|
||||||
response.write(await wrapEvent(document));
|
.sort({$natural:-1})
|
||||||
|
.limit(historyNumber).toArray().then((res) => {
|
||||||
|
res.reverse().forEach((document) => {
|
||||||
|
writeMessage(response, document)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const changeListener = async (change) => {
|
||||||
|
// Ignore events without fullDocument, e.g. deletes.
|
||||||
|
if (change.fullDocument) {
|
||||||
|
writeMessage(response, change.fullDocument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeStream.on("change", changeListener);
|
||||||
|
response.on('close', () => {
|
||||||
|
changeStream.removeListener("change", changeListener)
|
||||||
})
|
})
|
||||||
|
|
||||||
changeStream.on("change", async(data) => {
|
|
||||||
response.write(await wrapEvent(data.fullDocument));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(PORT);
|
app.listen(PORT);
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
./node_modules
|
.kpt-pipeline/
|
||||||
./build
|
k8s/
|
||||||
.git
|
skaffold.yaml
|
||||||
*.md
|
README.md
|
||||||
.gitignore
|
.git/
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
*.kpt-pipeline
|
||||||
|
29
frontend/.gitignore
vendored
Normal file
29
frontend/.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
*.kpt-pipeline
|
@ -1,39 +1,22 @@
|
|||||||
# pull official base image
|
FROM node AS dev
|
||||||
FROM node AS builder
|
|
||||||
|
|
||||||
# set working directory
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
COPY package* ./
|
||||||
# install app dependencies
|
|
||||||
#copies package.json and package-lock.json to Docker environment
|
|
||||||
COPY package.json ./
|
|
||||||
|
|
||||||
# Installs all node packages
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
ENTRYPOINT ["npm", "run", "dev"]
|
||||||
|
|
||||||
# Copies everything over to Docker environment
|
# builder
|
||||||
COPY . ./
|
FROM dev AS builder
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
#Stage 2
|
# serve
|
||||||
#######################################
|
FROM nginx AS prod
|
||||||
#pull the official nginx:1.19.0 base image
|
|
||||||
FROM nginx
|
|
||||||
|
|
||||||
#copies React to the container directory
|
|
||||||
# Set working directory to nginx resources directory
|
|
||||||
WORKDIR /usr/share/nginx/html
|
WORKDIR /usr/share/nginx/html
|
||||||
# Remove default nginx static resources
|
|
||||||
RUN rm -rf ./*
|
RUN rm -rf ./*
|
||||||
RUN apt-get install bash
|
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY --from=builder /app/dist .
|
||||||
# Copies configuration files
|
|
||||||
COPY ./default.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
# Copies static resources from builder stage
|
|
||||||
COPY --from=builder /app/build .
|
|
||||||
|
|
||||||
# Containers run nginx with global directives and daemon off
|
|
||||||
ENTRYPOINT ["nginx", "-g", "daemon off;"]
|
ENTRYPOINT ["nginx", "-g", "daemon off;"]
|
67
frontend/README.md
Normal file
67
frontend/README.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# log-viewer microfrontend (WIP)
|
||||||
|
This is an experimental microfrontend to view logs coming from camtiler, testing microfrontends concept and developing
|
||||||
|
Javascript/Node application directly on Kubernetes cluster using Skaffold (hot-reloading source files works!)
|
||||||
|
|
||||||
|
Currently the application itself is a really minimalistic frontend based on Vue.js 3 framework.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
0. Have access with kubectl to desired Kubernetes cluster
|
||||||
|
0. Have local Docker daemon ready along with access to your image registry (building in-cluster with Kaniko is currently not tested)
|
||||||
|
1. Get Skaffold 2.0.0-beta*: https://github.com/GoogleContainerTools/skaffold/releases
|
||||||
|
2. Run `skaffold dev --namespace {desired K8S namespace}`
|
||||||
|
|
||||||
|
And you should be good to go. Skaffold would create a deployment, build the container and upload it to your registry
|
||||||
|
and deploy it.
|
||||||
|
|
||||||
|
## Good to know
|
||||||
|
### Skaffold
|
||||||
|
All Skaffold configuration is in skaffold.yml. There we have:
|
||||||
|
1. App/deployment name (metadata)
|
||||||
|
2. Build artifacts - artifact that Skaffold would build and use, either in case of development or also actual deploy
|
||||||
|
3. Profiles - similar to `npm` commands/profiles, you can have many different actions (run `skaffold {action}`).
|
||||||
|
We only have `dev` which will build and deploy the `log-viewer-frontend` container
|
||||||
|
(in manner how it's defined in Kubernetes manifest), and then enable `manual sync`, which defines which
|
||||||
|
changed files will be copied to the container when it's running - change in everything else will trigger
|
||||||
|
rebuilding the container.
|
||||||
|
|
||||||
|
### Hot-reload vs rebuilding the container
|
||||||
|
Currently the files that will be copied are fine-tuned as they are known to work well with Vue.js hot-reload feature
|
||||||
|
(eg actual frontend code). Other files, such as framework configuration files (`vite.config.js`, `vue.config.js`)
|
||||||
|
will trigger rebuilding and more importantly, restarting the container, to provide stability. It might not be necessary
|
||||||
|
to restart the container, this is just testing at this point. You can try it by introducing less explicit `sync`
|
||||||
|
config in `skaffold.yml`.
|
||||||
|
|
||||||
|
Change in `packages*` files will also trigger rebuilding and restarting the container, with the difference of
|
||||||
|
caching the result of the `npm install` command - `node_modules` directory. So in case of changing framework config,
|
||||||
|
the container will be quickly rebuilt and restarted, but when changing packages in `package.json`, `npm install`
|
||||||
|
will also be ran when re-building the container.
|
||||||
|
|
||||||
|
### Dockerfile
|
||||||
|
This is a really simple Dockerfile based on the official Node Docker image.
|
||||||
|
Only extra stuff it does is:
|
||||||
|
1. exposing the port for reference
|
||||||
|
2. changing workdir(?)
|
||||||
|
3. running `npm install` on-demand
|
||||||
|
4. copying other code into the container
|
||||||
|
5. defining the run command (important!)
|
||||||
|
|
||||||
|
We also have the `.dockerignore` to filter out files that never need to make into the container, such as IDE
|
||||||
|
metadata directories, Git, readme etc.
|
||||||
|
|
||||||
|
With the current config, your local Docker daemon will be used to build the image and upload it to your image registry.
|
||||||
|
Building in-cluster with Kaniko should be supported (https://skaffold.dev/docs/pipeline-stages/builders/docker/)
|
||||||
|
but currently not tested.
|
||||||
|
|
||||||
|
### Kubernetes
|
||||||
|
The Kubernetes manifest(s) are supposed to be in the `k8s/` directory.
|
||||||
|
Skaffold will pick them up automatically from there, apply them (also cleaning up after itself),
|
||||||
|
and match the container images from it's manifest and Kubernetes manifest, so it knows when to make the Kubernetes
|
||||||
|
redeploy the image.
|
||||||
|
|
||||||
|
Here we have a simple deployment, where `https://playground.k-space.ee/` takes us to the (development) frontend
|
||||||
|
container and `https://playground.k-space.ee/events` gets data from the `camtiler log-backend`.
|
||||||
|
|
||||||
|
The actual production usage may vary a lot in case of frontend - one would usually not run a
|
||||||
|
Node.js server to serve frontend assets, unless it's a SSR frontend (Nuxt, Next frameworks).
|
||||||
|
But for Node.js backends, it's pretty close to the standard.
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 3003;
|
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html index.htm;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /events {
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_pass http://127.0.0.1:3002/events;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
13
frontend/index.html
Normal file
13
frontend/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Log Viewer</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
9
frontend/nginx.conf
Normal file
9
frontend/nginx.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
}
|
||||||
|
}
|
27815
frontend/package-lock.json
generated
27815
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,40 +1,31 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "@k-space/log-viewer",
|
||||||
"version": "0.1.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@testing-library/jest-dom": "^5.16.1",
|
|
||||||
"@testing-library/react": "^12.1.2",
|
|
||||||
"@testing-library/user-event": "^13.5.0",
|
|
||||||
"react": "^17.0.2",
|
|
||||||
"react-dom": "^17.0.2",
|
|
||||||
"react-hooks-sse": "^2.0.0",
|
|
||||||
"react-scripts": "5.0.0",
|
|
||||||
"web-vitals": "^2.1.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "react-scripts build",
|
"build": "vite build",
|
||||||
"test": "react-scripts test",
|
"dev": "vite --port 8080 --host",
|
||||||
"eject": "react-scripts eject"
|
"preview": "vite preview --port 3003"
|
||||||
},
|
},
|
||||||
"proxy": "http://localhost:3002",
|
"dependencies": {
|
||||||
"eslintConfig": {
|
"@ag-grid-community/core": "^28.2.0",
|
||||||
"extends": [
|
"@mdi/font": "5.9.55",
|
||||||
"react-app",
|
"@vue/cli-service": "^5.0.8",
|
||||||
"react-app/jest"
|
"ag-grid-vue3": "^28.2.0",
|
||||||
]
|
"core-js": "^3.25.1",
|
||||||
|
"event-hooks-webpack-plugin": "^2.2.0",
|
||||||
|
"pinia": "^2.0.21",
|
||||||
|
"roboto-fontface": "*",
|
||||||
|
"single-spa-vue": "^2.5.1",
|
||||||
|
"systemjs-webpack-interop": "^2.3.7",
|
||||||
|
"vue": "^3.2.39",
|
||||||
|
"vuetify": "^3.0.0-beta.0",
|
||||||
|
"webfontloader": "^1.0.0"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"devDependencies": {
|
||||||
"production": [
|
"@vitejs/plugin-vue": "^3.0.3",
|
||||||
">0.2%",
|
"vite": "^3.0.9",
|
||||||
"not dead",
|
"vue-cli-plugin-vuetify": "~2.5.8",
|
||||||
"not op_mini all"
|
"webpack-plugin-vuetify": "^2.0.0-alpha.0"
|
||||||
],
|
|
||||||
"development": [
|
|
||||||
"last 1 chrome version",
|
|
||||||
"last 1 firefox version",
|
|
||||||
"last 1 safari version"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.2 KiB |
@ -1,41 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta
|
|
||||||
name="Event logging"
|
|
||||||
content="Web site created using create-react-app"
|
|
||||||
/>
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<title>Event log</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.4 KiB |
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"short_name": "React App",
|
|
||||||
"name": "Create React App Sample",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "favicon.ico",
|
|
||||||
"sizes": "64x64 32x32 24x24 16x16",
|
|
||||||
"type": "image/x-icon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo192.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "192x192"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo512.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "512x512"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"theme_color": "#000000",
|
|
||||||
"background_color": "#ffffff"
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
# https://www.robotstxt.org/robotstxt.html
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
15
frontend/src/App.vue
Normal file
15
frontend/src/App.vue
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<script setup>
|
||||||
|
import LogViewer from './components/LogViewer.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<LogViewer />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'app1',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
1
frontend/src/assets/logo.svg
Normal file
1
frontend/src/assets/logo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69" xmlns:v="https://vecta.io/nano"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
After Width: | Height: | Size: 308 B |
15
frontend/src/assets/main.css
Normal file
15
frontend/src/assets/main.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
div#app {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screenshots-drawer {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-theme-material {
|
||||||
|
--ag-value-change-value-highlight-background-color: #f9ff99;
|
||||||
|
}
|
29
frontend/src/components/ComboboxFilter.js
Normal file
29
frontend/src/components/ComboboxFilter.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export default {
|
||||||
|
template: `
|
||||||
|
<select v-model="filter" class="v-select">
|
||||||
|
<option value=""> </option>
|
||||||
|
<option v-for="option in params.options" :value="option">
|
||||||
|
{{ option }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
`,
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
filter: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateFilter() {
|
||||||
|
this.params.filterChangedCallback();
|
||||||
|
},
|
||||||
|
|
||||||
|
doesFilterPass(params) {
|
||||||
|
const value = this.params.field.split('.').reduce((a, b) => a[b], params.data);
|
||||||
|
return value === this.filter;
|
||||||
|
},
|
||||||
|
|
||||||
|
isFilterActive() {
|
||||||
|
return this.filter !== ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
83
frontend/src/components/ExamineLogModal.vue
Normal file
83
frontend/src/components/ExamineLogModal.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<v-dialog
|
||||||
|
v-model="examineLog"
|
||||||
|
width="50wv"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-text style="height: 70vh">
|
||||||
|
<ag-grid-vue
|
||||||
|
style="width: 100%; height: 100%;"
|
||||||
|
class="ag-theme-material"
|
||||||
|
@grid-ready="onGridReady"
|
||||||
|
:columnDefs="columnDefs"
|
||||||
|
:row-data="examineLogContent"
|
||||||
|
:supress-horisontal-scroll="true"
|
||||||
|
:enable-scrolling="true"
|
||||||
|
:enableCellTextSelection="true"
|
||||||
|
:ensureDomOrder="true"
|
||||||
|
></ag-grid-vue>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn color="primary" block @click="closeModal">Close</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { AgGridVue } from "ag-grid-vue3";
|
||||||
|
import "ag-grid-community/styles//ag-grid.css";
|
||||||
|
import "ag-grid-community/styles//ag-theme-material.css";
|
||||||
|
import ScreenshotCell from "./ScreenshotCell.js";
|
||||||
|
import { VCard, VCardText, VCardActions } from 'vuetify/components/VCard'
|
||||||
|
import { VDialog } from 'vuetify/components/VDialog'
|
||||||
|
import { VBtn } from 'vuetify/components/VBtn'
|
||||||
|
import { VTable } from 'vuetify/components/VTable'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
AgGridVue,
|
||||||
|
VCard,
|
||||||
|
VCardText,
|
||||||
|
VCardActions,
|
||||||
|
VBtn,
|
||||||
|
VDialog,
|
||||||
|
VTable,
|
||||||
|
ScreenshotCell: ScreenshotCell
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columnDefs: [
|
||||||
|
{
|
||||||
|
field: 'key',
|
||||||
|
sortable: true,
|
||||||
|
filter: 'agTextColumnFilter',
|
||||||
|
resizable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'value',
|
||||||
|
sortable: true,
|
||||||
|
filter: 'agTextColumnFilter',
|
||||||
|
resizable: true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
examineLogContent: Array,
|
||||||
|
closeModal: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
examineLog() {
|
||||||
|
return !!this.examineLogContent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onGridReady(params) {
|
||||||
|
params.api.sizeColumnsToFit()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
173
frontend/src/components/LogViewer.vue
Normal file
173
frontend/src/components/LogViewer.vue
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<div style="height: 100%; width: 100%">
|
||||||
|
<ag-grid-vue
|
||||||
|
style="width: 100%; height: 100%;"
|
||||||
|
class="ag-theme-material"
|
||||||
|
@grid-ready="onGridReady"
|
||||||
|
:defaultColDef="defaultColDef"
|
||||||
|
:columnDefs="columnDefs"
|
||||||
|
:pagination="true"
|
||||||
|
:paginationAutoPageSize=true
|
||||||
|
:row-data="null"
|
||||||
|
row-selection="single"
|
||||||
|
:onRowSelected="openExamineLog"
|
||||||
|
:supress-horisontal-scroll="true"
|
||||||
|
:enable-scrolling="true"
|
||||||
|
></ag-grid-vue>
|
||||||
|
<ExamineLogModal :examine-log-content="examineLogContent" :close-modal="closeExamineLog" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { AgGridVue } from "ag-grid-vue3";
|
||||||
|
import "ag-grid-community/styles//ag-grid.css";
|
||||||
|
import "ag-grid-community/styles//ag-theme-material.css";
|
||||||
|
import ScreenshotCell from "./ScreenshotCell.js";
|
||||||
|
import ExamineLogModal from "./ExamineLogModal.vue";
|
||||||
|
import ComboboxFilter from "./ComboboxFilter.js";
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ExamineLogModal,
|
||||||
|
AgGridVue,
|
||||||
|
ComboboxFilter,
|
||||||
|
ScreenshotCell: ScreenshotCell
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
examineLogContent: null,
|
||||||
|
gridApi: null,
|
||||||
|
gridColumnApi: null,
|
||||||
|
defaultColDef: {
|
||||||
|
width: 50,
|
||||||
|
initialPinned: true,
|
||||||
|
resizable: true,
|
||||||
|
enableCellChangeFlash: true
|
||||||
|
},
|
||||||
|
currentRowCount: 0,
|
||||||
|
comboBoxOptions: {},
|
||||||
|
viewRowCount: 20,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
columnDefs() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field: '@timestamp',
|
||||||
|
width: 70,
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'kubernetes.namespace',
|
||||||
|
headerName: 'namespace',
|
||||||
|
tooltipValueGetter: (params) => params.value,
|
||||||
|
filter: ComboboxFilter,
|
||||||
|
filterParams: {
|
||||||
|
options: this.comboBoxOptions['kubernetes.namespace'],
|
||||||
|
field: 'kubernetes.namespace',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'kubernetes.pod.name',
|
||||||
|
headerName: 'pod',
|
||||||
|
tooltipValueGetter: (params) => params.value,
|
||||||
|
filter: ComboboxFilter,
|
||||||
|
filterParams: {
|
||||||
|
options: this.comboBoxOptions['kubernetes.pod.name'],
|
||||||
|
field: 'kubernetes.pod.name',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'kubernetes.container.name',
|
||||||
|
headerName: 'container',
|
||||||
|
tooltipValueGetter: (params) => params.value,
|
||||||
|
filter: ComboboxFilter,
|
||||||
|
filterParams: {
|
||||||
|
options: this.comboBoxOptions['kubernetes.container.name'],
|
||||||
|
field: 'kubernetes.container.name',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'message',
|
||||||
|
tooltipValueGetter: (params) => params.value,
|
||||||
|
width: 500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'stream',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.setupStream()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setupStream() {
|
||||||
|
let es = new EventSource('/events');
|
||||||
|
es.onmessage = (e) => this.handleReceiveMessage(e)
|
||||||
|
es.addEventListener("filters", (e) => this.handleReceiveFilters(e))
|
||||||
|
},
|
||||||
|
onGridReady(params) {
|
||||||
|
this.gridApi = params.api;
|
||||||
|
this.gridColumnApi = params.columnApi;
|
||||||
|
},
|
||||||
|
handleReceiveMessage (event) {
|
||||||
|
const eventData = this.parseEventData(event.data);
|
||||||
|
const res = this.gridApi.applyTransaction({
|
||||||
|
add: [eventData]
|
||||||
|
});
|
||||||
|
const rowNode = res.add[0]
|
||||||
|
this.gridApi.flashCells({ rowNodes: [rowNode]});
|
||||||
|
this.gridApi.sizeColumnsToFit()
|
||||||
|
},
|
||||||
|
handleReceiveFilters (event) {
|
||||||
|
this.comboBoxOptions = this.parseEventData(event.data);
|
||||||
|
},
|
||||||
|
parseEventData (eventData) {
|
||||||
|
try {
|
||||||
|
let json = JSON.parse(eventData)
|
||||||
|
if (!json.message) {
|
||||||
|
json.message = JSON.stringify(json.json)
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e, eventData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openExamineLog (row) {
|
||||||
|
const selectedRow = row.data
|
||||||
|
row.node.setSelected(false)
|
||||||
|
this.examineLog = true
|
||||||
|
const flattened = flattenObj(selectedRow)
|
||||||
|
const pairs = [];
|
||||||
|
Object.keys(flattened).map((key) => {
|
||||||
|
pairs.push({
|
||||||
|
key: key,
|
||||||
|
value: flattened[key]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.examineLogContent = pairs
|
||||||
|
},
|
||||||
|
closeExamineLog () {
|
||||||
|
this.examineLogContent = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const flattenObj = (ob) => {
|
||||||
|
let result = {};
|
||||||
|
for (const i in ob) {
|
||||||
|
if ((typeof ob[i]) === 'object' && !Array.isArray(ob[i])) {
|
||||||
|
const temp = flattenObj(ob[i]);
|
||||||
|
for (const j in temp) {
|
||||||
|
result[i + '.' + j] = temp[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[i] = ob[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
</script>
|
30
frontend/src/components/ScreenshotCell.js
Normal file
30
frontend/src/components/ScreenshotCell.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
export default {
|
||||||
|
template: `<div>
|
||||||
|
<a @click="openDrawer">View screenshots</a>
|
||||||
|
<div v-if="drawerOpen" class="screenshots-drawer">
|
||||||
|
<img v-for="screenshot in screenshots" :src="screenshot.orig"/>
|
||||||
|
</div>
|
||||||
|
</div>`,
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
screenshots: [],
|
||||||
|
drawerOpen: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
this.updateImage(this.params);
|
||||||
|
this.updateImage(this.params);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateImage(params) {
|
||||||
|
this.screenshots = params.value
|
||||||
|
this.value = params.value;
|
||||||
|
},
|
||||||
|
refresh(params) {
|
||||||
|
this.updateImage(params);
|
||||||
|
},
|
||||||
|
openDrawer () {
|
||||||
|
this.drawerOpen = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
@ -1,3 +0,0 @@
|
|||||||
body {
|
|
||||||
background-color: #eafaf9;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { useSSE, SSEProvider } from 'react-hooks-sse';
|
|
||||||
import './App.css';
|
|
||||||
import EventList from '../eventList/EventList.js';
|
|
||||||
|
|
||||||
|
|
||||||
import './App.css';
|
|
||||||
|
|
||||||
|
|
||||||
const Component = () => {
|
|
||||||
const event = useSSE('log-entry')
|
|
||||||
const [events, setEvents] = useState([])
|
|
||||||
|
|
||||||
useEffect(() =>{
|
|
||||||
console.info(event);
|
|
||||||
if (event) {
|
|
||||||
for (var j = 0; j < events.length; j++) {
|
|
||||||
if (events[j].timestamp <= event.timestamp) {
|
|
||||||
if (events[j]._id == event._id) {
|
|
||||||
setEvents([...events.slice(0, j), event, ...events.slice(j+1)]);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
setEvents([...events.slice(0, j), event, ...events.slice(j)]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setEvents([event, ...events]);
|
|
||||||
}
|
|
||||||
}, [event])
|
|
||||||
return <EventList data={events} />
|
|
||||||
}
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
|
|
||||||
<SSEProvider endpoint="/events" >
|
|
||||||
<Component />
|
|
||||||
|
|
||||||
|
|
||||||
</SSEProvider>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,18 +0,0 @@
|
|||||||
.eventDiv {
|
|
||||||
background-color: aliceblue;
|
|
||||||
border: 2px solid #26A69A;
|
|
||||||
border-radius: 15px;
|
|
||||||
text-align: left;
|
|
||||||
padding: 5px;
|
|
||||||
max-width: fit-content;
|
|
||||||
font-family: apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
|
||||||
color: #092a26;
|
|
||||||
margin: 7px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eventPic {
|
|
||||||
border-radius: 15px;
|
|
||||||
border: 1px groove #d5f6f2;
|
|
||||||
max-width:100%;
|
|
||||||
max-height:100%;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import "./Event.css";
|
|
||||||
|
|
||||||
function Event(props) {
|
|
||||||
|
|
||||||
let imgArray = [];
|
|
||||||
|
|
||||||
if (props.data.hasOwnProperty('screenshots')) {
|
|
||||||
props.data.screenshots.forEach(element => {
|
|
||||||
imgArray = [...imgArray, (<a href={element.orig} target="_blank"><img src={element.url} className="eventPic"></img></a>)]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="eventDiv">
|
|
||||||
{JSON.stringify(props.data.source)}
|
|
||||||
<br></br>
|
|
||||||
{[...imgArray]}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Event;
|
|
@ -1,11 +0,0 @@
|
|||||||
.eventListUl {
|
|
||||||
background-color: #c1f1ec;
|
|
||||||
max-width: 75%;
|
|
||||||
padding: 5px;
|
|
||||||
border: 5px solid #26A69A;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.eventListLi {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import Event from '../event/Event.js';
|
|
||||||
import './EventList.css';
|
|
||||||
|
|
||||||
function EventList(props) {
|
|
||||||
return (
|
|
||||||
<ul className="eventListUl">
|
|
||||||
{props.data.map((event) => {
|
|
||||||
return <li className="eventListLi"><Event data={event} /></li>
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EventList;
|
|
@ -1,3 +0,0 @@
|
|||||||
body {
|
|
||||||
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import './index.css';
|
|
||||||
import App from './components/app/App.js';
|
|
||||||
import reportWebVitals from './reportWebVitals';
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
|
||||||
reportWebVitals();
|
|
10
frontend/src/main.js
Normal file
10
frontend/src/main.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import vuetify from './plugins/vuetify'
|
||||||
|
import { loadFonts } from './plugins/webfontloader'
|
||||||
|
import './assets/main.css'
|
||||||
|
loadFonts()
|
||||||
|
|
||||||
|
createApp(App)
|
||||||
|
.use(vuetify)
|
||||||
|
.mount('#app')
|
@ -1,13 +0,0 @@
|
|||||||
const reportWebVitals = onPerfEntry => {
|
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
|
||||||
getCLS(onPerfEntry);
|
|
||||||
getFID(onPerfEntry);
|
|
||||||
getFCP(onPerfEntry);
|
|
||||||
getLCP(onPerfEntry);
|
|
||||||
getTTFB(onPerfEntry);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default reportWebVitals;
|
|
3
frontend/src/set-public-path.js
Normal file
3
frontend/src/set-public-path.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { setPublicPath } from "systemjs-webpack-interop";
|
||||||
|
|
||||||
|
setPublicPath("app1");
|
@ -1,5 +0,0 @@
|
|||||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|
||||||
// allows you to do things like:
|
|
||||||
// expect(element).toHaveTextContent(/react/i)
|
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
|
||||||
import '@testing-library/jest-dom';
|
|
14
frontend/src/stores/counter.js
Normal file
14
frontend/src/stores/counter.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useCounterStore = defineStore('counter', () => {
|
||||||
|
const count = ref(0)
|
||||||
|
const doubleCount = computed(() => count.value * 2)
|
||||||
|
function increment() {
|
||||||
|
count.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return { count, doubleCount, increment }
|
||||||
|
})
|
26
frontend/vite.config.js
Normal file
26
frontend/vite.config.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
vue: 'vue/dist/vue.esm-bundler.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
input: 'src/main.js',
|
||||||
|
format: 'system',
|
||||||
|
preserveEntrySignatures: true
|
||||||
|
},
|
||||||
|
plugins: [vue({
|
||||||
|
template: {
|
||||||
|
transformAssetUrls: {
|
||||||
|
base: '/src'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})],
|
||||||
|
pluginOptions: {
|
||||||
|
vuetify: {
|
||||||
|
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vuetify-loader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
frontend/vue.config.js
Normal file
43
frontend/vue.config.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const EventHooksPlugin = require('event-hooks-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
publicPath: '/logs',
|
||||||
|
chainWebpack: (config) => {
|
||||||
|
config.devServer.headers({
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
});
|
||||||
|
config.devServer.set('port', 8080);
|
||||||
|
config.devServer.set('hot', true);
|
||||||
|
|
||||||
|
config.output.filename('[name].js');
|
||||||
|
config.output.publicPath('/logs');
|
||||||
|
|
||||||
|
config.externals([
|
||||||
|
'vue',
|
||||||
|
'vue-router'
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
lintOnSave: true,
|
||||||
|
filenameHashing: false,
|
||||||
|
configureWebpack: {
|
||||||
|
plugins: [
|
||||||
|
new EventHooksPlugin({
|
||||||
|
done: () => {
|
||||||
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
|
const buildDir = path.join(__dirname, '/dist');
|
||||||
|
fs.unlinkSync(`${buildDir}/index.html`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
pluginOptions: {
|
||||||
|
vuetify: {
|
||||||
|
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vuetify-loader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
102
k8s/dev/deployment.yaml
Normal file
102
k8s/dev/deployment.yaml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: playground
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: traefik
|
||||||
|
cert-manager.io/cluster-issuer: default
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.middlewares: traefik-sso@kubernetescrd
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
external-dns.alpha.kubernetes.io/target: traefik.k-space.ee
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: playground.k-space.ee
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/events"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: log-viewer-backend
|
||||||
|
port:
|
||||||
|
number: 3002
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- playground.k-space.ee
|
||||||
|
secretName: playground-tls
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: log-viewer-backend
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 3002
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: log-viewer-frontend
|
||||||
|
image: harbor.k-space.ee/playground/log-viewer-frontend
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: log-viewer-backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: log-viewer-backend
|
||||||
|
image: harbor.k-space.ee/playground/log-viewer-backend
|
||||||
|
ports:
|
||||||
|
- containerPort: 3002
|
||||||
|
env:
|
||||||
|
- name: MONGODB_HOST
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mongodb-application-readwrite
|
||||||
|
key: connectionString.standard
|
102
k8s/staging/deployment.yaml
Normal file
102
k8s/staging/deployment.yaml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: playground
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: traefik
|
||||||
|
cert-manager.io/cluster-issuer: default
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.middlewares: traefik-sso@kubernetescrd
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
external-dns.alpha.kubernetes.io/target: traefik.k-space.ee
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: playground.k-space.ee
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
- pathType: Prefix
|
||||||
|
path: "/events"
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: log-viewer-backend
|
||||||
|
port:
|
||||||
|
number: 3002
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- playground.k-space.ee
|
||||||
|
secretName: playground-tls
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: log-viewer-backend
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 3002
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: log-viewer-frontend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: log-viewer-frontend
|
||||||
|
image: harbor.k-space.ee/playground/log-viewer-frontend
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: log-viewer-backend
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: log-viewer-backend
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: log-viewer-backend
|
||||||
|
image: harbor.k-space.ee/playground/log-viewer-backend
|
||||||
|
ports:
|
||||||
|
- containerPort: 3002
|
||||||
|
env:
|
||||||
|
- name: MONGODB_HOST
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: mongodb-application-readwrite
|
||||||
|
key: connectionString.standard
|
56
skaffold.yaml
Normal file
56
skaffold.yaml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
apiVersion: skaffold/v3alpha1
|
||||||
|
kind: Config
|
||||||
|
metadata:
|
||||||
|
name: log-viewer-backend
|
||||||
|
|
||||||
|
build:
|
||||||
|
artifacts:
|
||||||
|
- image: harbor.k-space.ee/playground/log-viewer-backend
|
||||||
|
context: backend
|
||||||
|
docker:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
- image: harbor.k-space.ee/playground/log-viewer-frontend
|
||||||
|
context: frontend
|
||||||
|
docker:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
kubectl: {}
|
||||||
|
|
||||||
|
manifests:
|
||||||
|
rawYaml:
|
||||||
|
- k8s/staging/deployment.yaml
|
||||||
|
|
||||||
|
profiles:
|
||||||
|
- name: dev
|
||||||
|
activation:
|
||||||
|
- command: dev
|
||||||
|
build:
|
||||||
|
artifacts:
|
||||||
|
- image: harbor.k-space.ee/playground/log-viewer-backend
|
||||||
|
context: backend
|
||||||
|
docker:
|
||||||
|
target: dev
|
||||||
|
sync:
|
||||||
|
manual:
|
||||||
|
- src: '**/*.js'
|
||||||
|
dest: .
|
||||||
|
- image: harbor.k-space.ee/playground/log-viewer-frontend
|
||||||
|
context: frontend
|
||||||
|
docker:
|
||||||
|
target: dev
|
||||||
|
sync:
|
||||||
|
manual:
|
||||||
|
- src: 'src/**/*.vue'
|
||||||
|
dest: .
|
||||||
|
- src: 'src/**/*.js'
|
||||||
|
dest: .
|
||||||
|
- src: 'src/**/*.css'
|
||||||
|
dest: .
|
||||||
|
- src: 'src/**/*.svg'
|
||||||
|
dest: .
|
||||||
|
- src: 'index.html'
|
||||||
|
dest: .
|
||||||
|
manifests:
|
||||||
|
rawYaml:
|
||||||
|
- k8s/dev/deployment.yaml
|
Loading…
Reference in New Issue
Block a user