mirror of
https://github.com/ershisan99/coolify.git
synced 2025-12-19 12:33:11 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ea0de3fb8 | ||
|
|
b4c836afbd | ||
|
|
2d0f22b379 | ||
|
|
a8e9668c2b | ||
|
|
425feba0e2 | ||
|
|
c09b8d888f | ||
|
|
748e691a58 | ||
|
|
f8c81ff95f | ||
|
|
d11c4a3cd7 | ||
|
|
3f3ea151ef | ||
|
|
7e2f68870c | ||
|
|
df41cf14da | ||
|
|
111370c025 | ||
|
|
bcb2ba0b1b | ||
|
|
807d526ffa |
@@ -54,7 +54,6 @@ With Github integration
|
|||||||
- [VSCode Server](https://github.com/cdr/code-server)
|
- [VSCode Server](https://github.com/cdr/code-server)
|
||||||
- [MinIO](https://min.io)
|
- [MinIO](https://min.io)
|
||||||
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
- Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai)
|
- Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai)
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "coolify",
|
"name": "coolify",
|
||||||
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
|
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
|
||||||
"version": "1.0.20",
|
"version": "1.0.24",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:docker:start": "docker-compose -f docker-compose-dev.yml up -d",
|
"dev:docker:start": "docker-compose -f docker-compose-dev.yml up -d",
|
||||||
"dev:docker:stop": "docker-compose -f docker-compose-dev.yml down",
|
"dev:docker:stop": "docker-compose -f docker-compose-dev.yml down",
|
||||||
"dev": "NODE_ENV=development svelte-kit dev --host 0.0.0.0",
|
"dev": "TAILWIND_MODE=watch NODE_ENV=development svelte-kit dev --host 0.0.0.0",
|
||||||
"build": "NODE_ENV=production svelte-kit build",
|
"build": "NODE_ENV=production svelte-kit build",
|
||||||
"preview": "svelte-kit preview",
|
"preview": "svelte-kit preview",
|
||||||
"start": "node build",
|
"start": "node build",
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
"format": "prettier --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-node": "1.0.0-next.26",
|
"@sveltejs/adapter-node": "1.0.0-next.39",
|
||||||
"@sveltejs/kit": "1.0.0-next.115",
|
"@sveltejs/kit": "1.0.0-next.142",
|
||||||
"@types/dockerode": "^3.2.3",
|
"@types/dockerode": "^3.2.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.26.1",
|
"@typescript-eslint/eslint-plugin": "^4.26.1",
|
||||||
"@typescript-eslint/parser": "^4.26.1",
|
"@typescript-eslint/parser": "^4.26.1",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"prettier-plugin-svelte": "^2.3.0",
|
"prettier-plugin-svelte": "^2.3.0",
|
||||||
"svelte": "^3.38.2",
|
"svelte": "^3.38.2",
|
||||||
"svelte-preprocess": "^4.7.3",
|
"svelte-preprocess": "^4.7.3",
|
||||||
"tailwindcss": "2.2.0",
|
"tailwindcss": "2.2.4",
|
||||||
"tslib": "^2.2.0",
|
"tslib": "^2.2.0",
|
||||||
"typescript": "^4.3.2",
|
"typescript": "^4.3.2",
|
||||||
"vite": "^2.3.6"
|
"vite": "^2.3.6"
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iarna/toml": "^2.2.5",
|
"@iarna/toml": "^2.2.5",
|
||||||
"@zerodevx/svelte-toast": "^0.3.0",
|
"@zerodevx/svelte-toast": "^0.3.0",
|
||||||
|
"bcrypt": "^5.0.1",
|
||||||
"commander": "^7.2.0",
|
"commander": "^7.2.0",
|
||||||
"compare-versions": "^3.6.0",
|
"compare-versions": "^3.6.0",
|
||||||
"cookie": "^0.4.1",
|
"cookie": "^0.4.1",
|
||||||
@@ -49,9 +50,10 @@
|
|||||||
"generate-password": "^1.6.0",
|
"generate-password": "^1.6.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
"microtip": "^0.2.2",
|
||||||
"mongoose": "^5.12.13",
|
"mongoose": "^5.12.13",
|
||||||
"shelljs": "^0.8.4",
|
"shelljs": "^0.8.4",
|
||||||
"svelte-kit-cookie-session": "^1.0.6",
|
"svelte-kit-cookie-session": "^1.3.1",
|
||||||
"svelte-select": "^3.17.0",
|
"svelte-select": "^3.17.0",
|
||||||
"systeminformation": "^5.7.7",
|
"systeminformation": "^5.7.7",
|
||||||
"unique-names-generator": "^4.5.0"
|
"unique-names-generator": "^4.5.0"
|
||||||
|
|||||||
368
pnpm-lock.yaml
generated
368
pnpm-lock.yaml
generated
@@ -2,13 +2,14 @@ lockfileVersion: 5.3
|
|||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@iarna/toml': ^2.2.5
|
'@iarna/toml': ^2.2.5
|
||||||
'@sveltejs/adapter-node': 1.0.0-next.26
|
'@sveltejs/adapter-node': 1.0.0-next.33
|
||||||
'@sveltejs/kit': 1.0.0-next.115
|
'@sveltejs/kit': 1.0.0-next.125
|
||||||
'@types/dockerode': ^3.2.3
|
'@types/dockerode': ^3.2.3
|
||||||
'@typescript-eslint/eslint-plugin': ^4.26.1
|
'@typescript-eslint/eslint-plugin': ^4.26.1
|
||||||
'@typescript-eslint/parser': ^4.26.1
|
'@typescript-eslint/parser': ^4.26.1
|
||||||
'@zerodevx/svelte-toast': ^0.3.0
|
'@zerodevx/svelte-toast': ^0.3.0
|
||||||
autoprefixer: ^10.2.6
|
autoprefixer: ^10.2.6
|
||||||
|
bcrypt: ^5.0.1
|
||||||
commander: ^7.2.0
|
commander: ^7.2.0
|
||||||
compare-versions: ^3.6.0
|
compare-versions: ^3.6.0
|
||||||
cookie: ^0.4.1
|
cookie: ^0.4.1
|
||||||
@@ -23,6 +24,7 @@ specifiers:
|
|||||||
generate-password: ^1.6.0
|
generate-password: ^1.6.0
|
||||||
js-yaml: ^4.1.0
|
js-yaml: ^4.1.0
|
||||||
jsonwebtoken: ^8.5.1
|
jsonwebtoken: ^8.5.1
|
||||||
|
microtip: ^0.2.2
|
||||||
mongoose: ^5.12.13
|
mongoose: ^5.12.13
|
||||||
postcss: ^8.3.0
|
postcss: ^8.3.0
|
||||||
postcss-load-config: ^3.0.1
|
postcss-load-config: ^3.0.1
|
||||||
@@ -34,7 +36,7 @@ specifiers:
|
|||||||
svelte-preprocess: ^4.7.3
|
svelte-preprocess: ^4.7.3
|
||||||
svelte-select: ^3.17.0
|
svelte-select: ^3.17.0
|
||||||
systeminformation: ^5.7.7
|
systeminformation: ^5.7.7
|
||||||
tailwindcss: 2.2.0
|
tailwindcss: 2.2.4
|
||||||
tslib: ^2.2.0
|
tslib: ^2.2.0
|
||||||
typescript: ^4.3.2
|
typescript: ^4.3.2
|
||||||
unique-names-generator: ^4.5.0
|
unique-names-generator: ^4.5.0
|
||||||
@@ -43,6 +45,7 @@ specifiers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@iarna/toml': 2.2.5
|
'@iarna/toml': 2.2.5
|
||||||
'@zerodevx/svelte-toast': 0.3.0
|
'@zerodevx/svelte-toast': 0.3.0
|
||||||
|
bcrypt: 5.0.1
|
||||||
commander: 7.2.0
|
commander: 7.2.0
|
||||||
compare-versions: 3.6.0
|
compare-versions: 3.6.0
|
||||||
cookie: 0.4.1
|
cookie: 0.4.1
|
||||||
@@ -53,6 +56,7 @@ dependencies:
|
|||||||
generate-password: 1.6.0
|
generate-password: 1.6.0
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsonwebtoken: 8.5.1
|
jsonwebtoken: 8.5.1
|
||||||
|
microtip: 0.2.2
|
||||||
mongoose: 5.12.13
|
mongoose: 5.12.13
|
||||||
shelljs: 0.8.4
|
shelljs: 0.8.4
|
||||||
svelte-kit-cookie-session: 1.0.6
|
svelte-kit-cookie-session: 1.0.6
|
||||||
@@ -61,8 +65,8 @@ dependencies:
|
|||||||
unique-names-generator: 4.5.0
|
unique-names-generator: 4.5.0
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@sveltejs/adapter-node': 1.0.0-next.26
|
'@sveltejs/adapter-node': 1.0.0-next.33
|
||||||
'@sveltejs/kit': 1.0.0-next.115_svelte@3.38.2
|
'@sveltejs/kit': 1.0.0-next.125_svelte@3.38.2
|
||||||
'@types/dockerode': 3.2.3
|
'@types/dockerode': 3.2.3
|
||||||
'@typescript-eslint/eslint-plugin': 4.26.1_c8cbd5e7f5f92609ec78d991aced454b
|
'@typescript-eslint/eslint-plugin': 4.26.1_c8cbd5e7f5f92609ec78d991aced454b
|
||||||
'@typescript-eslint/parser': 4.26.1_eslint@7.28.0+typescript@4.3.2
|
'@typescript-eslint/parser': 4.26.1_eslint@7.28.0+typescript@4.3.2
|
||||||
@@ -77,7 +81,7 @@ devDependencies:
|
|||||||
prettier-plugin-svelte: 2.3.0_prettier@2.3.1+svelte@3.38.2
|
prettier-plugin-svelte: 2.3.0_prettier@2.3.1+svelte@3.38.2
|
||||||
svelte: 3.38.2
|
svelte: 3.38.2
|
||||||
svelte-preprocess: 4.7.3_ddfd8490a44ef0de606159ff3aef985a
|
svelte-preprocess: 4.7.3_ddfd8490a44ef0de606159ff3aef985a
|
||||||
tailwindcss: 2.2.0_6daa0ece57b4377652e73c9c66c3b94c
|
tailwindcss: 2.2.4_6daa0ece57b4377652e73c9c66c3b94c
|
||||||
tslib: 2.2.0
|
tslib: 2.2.0
|
||||||
typescript: 4.3.2
|
typescript: 4.3.2
|
||||||
vite: 2.3.6
|
vite: 2.3.6
|
||||||
@@ -153,6 +157,23 @@ packages:
|
|||||||
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
|
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@mapbox/node-pre-gyp/1.0.5:
|
||||||
|
resolution: {integrity: sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 1.0.3
|
||||||
|
https-proxy-agent: 5.0.0
|
||||||
|
make-dir: 3.1.0
|
||||||
|
node-fetch: 2.6.1
|
||||||
|
nopt: 5.0.0
|
||||||
|
npmlog: 4.1.2
|
||||||
|
rimraf: 3.0.2
|
||||||
|
semver: 7.3.5
|
||||||
|
tar: 6.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@nodelib/fs.scandir/2.1.5:
|
/@nodelib/fs.scandir/2.1.5:
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -181,46 +202,48 @@ packages:
|
|||||||
rollup: ^1.20.0||^2.0.0
|
rollup: ^1.20.0||^2.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
estree-walker: 2.0.2
|
estree-walker: 2.0.2
|
||||||
picomatch: 2.2.3
|
picomatch: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/adapter-node/1.0.0-next.26:
|
/@sveltejs/adapter-node/1.0.0-next.33:
|
||||||
resolution: {integrity: sha512-jhlCBJH/Gyge0u5sx67UgEEHzoBk69Z9pXXtvERXrDyfmbao5v55zEaroPucc089CHKQvLRQJ3mGU81QZmk31Q==}
|
resolution: {integrity: sha512-0mABbAWQ5Dg7eSptvpX+fmZ0tgifscgNwgtg4iX6GRhWGizTYYBgp4yAHl4IXPqlAQkW7Lh0gw3+G2tQcs2qcQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.12.6
|
esbuild: 0.12.6
|
||||||
|
tiny-glob: 0.2.9
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/kit/1.0.0-next.115_svelte@3.38.2:
|
/@sveltejs/kit/1.0.0-next.125_svelte@3.38.2:
|
||||||
resolution: {integrity: sha512-XbkL9hI7LI0Dfum9crtBIeENqdJEjMfDaX3qQTTgdYkhlb4KNNYErmDWo8bJNJKEfdV0BJBVN/I0wiat3cd/yA==}
|
resolution: {integrity: sha512-msYbZak97rW2Cgk08NiJW5Sz4S6XnVcjwTXrMo1G4MkYn8cZeL/eKWhuYrjGFvv4U3bYOZhTj/WfAzXNVEFX0A==}
|
||||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
engines: {node: ^12.20 || >=14.13}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
svelte: ^3.38.2
|
svelte: ^3.34.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 1.0.0-next.11_svelte@3.38.2+vite@2.3.7
|
'@sveltejs/vite-plugin-svelte': 1.0.0-next.12_svelte@3.38.2+vite@2.4.2
|
||||||
cheap-watch: 1.0.3
|
cheap-watch: 1.0.3
|
||||||
sade: 1.7.4
|
sade: 1.7.4
|
||||||
svelte: 3.38.2
|
svelte: 3.38.2
|
||||||
vite: 2.3.7
|
vite: 2.4.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- rollup
|
- rollup
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/vite-plugin-svelte/1.0.0-next.11_svelte@3.38.2+vite@2.3.7:
|
/@sveltejs/vite-plugin-svelte/1.0.0-next.12_svelte@3.38.2+vite@2.4.2:
|
||||||
resolution: {integrity: sha512-EYR1I145k5rflVqhPwk3442m3bkYimTKSHM9uO5KdomXzt+GS9ZSBJQE3/wy1Di9V8OnGa3oKpckI3OZsHkTIA==}
|
resolution: {integrity: sha512-cuyNkJ6leptfv+7qL/fWQ7EpGWdguosFOUI0z93oQUmFTcX7QxJ5h+QI3NQyktBzlKL/761L8BbG2hHNkVbLIQ==}
|
||||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
svelte: ^3.38.2
|
svelte: ^3.34.0
|
||||||
vite: ^2.3.7
|
vite: ^2.3.7
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 4.1.0
|
'@rollup/pluginutils': 4.1.0
|
||||||
chalk: 4.1.1
|
|
||||||
debug: 4.3.2
|
debug: 4.3.2
|
||||||
|
kleur: 4.1.4
|
||||||
|
magic-string: 0.25.7
|
||||||
require-relative: 0.8.7
|
require-relative: 0.8.7
|
||||||
svelte: 3.38.2
|
svelte: 3.38.2
|
||||||
svelte-hmr: 0.14.4_svelte@3.38.2
|
svelte-hmr: 0.14.5_svelte@3.38.2
|
||||||
vite: 2.3.7
|
vite: 2.4.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- rollup
|
- rollup
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -381,6 +404,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-TY5dLB5DEpxuHu60M6gum+fDxzIGXg35R8500orz58JTFs9LiHWoEfeJ4n9t7Afix3iMmYLl2thjhnCHCiQIhQ==}
|
resolution: {integrity: sha512-TY5dLB5DEpxuHu60M6gum+fDxzIGXg35R8500orz58JTFs9LiHWoEfeJ4n9t7Afix3iMmYLl2thjhnCHCiQIhQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/abbrev/1.1.1:
|
||||||
|
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/acorn-jsx/5.3.1_acorn@7.4.1:
|
/acorn-jsx/5.3.1_acorn@7.4.1:
|
||||||
resolution: {integrity: sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==}
|
resolution: {integrity: sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -408,6 +435,15 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/agent-base/6.0.2:
|
||||||
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
|
engines: {node: '>= 6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
debug: 4.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ajv/6.12.6:
|
/ajv/6.12.6:
|
||||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -435,6 +471,11 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ansi-regex/2.1.1:
|
||||||
|
resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ansi-regex/5.0.0:
|
/ansi-regex/5.0.0:
|
||||||
resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==}
|
resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -462,6 +503,17 @@ packages:
|
|||||||
picomatch: 2.3.0
|
picomatch: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/aproba/1.2.0:
|
||||||
|
resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/are-we-there-yet/1.1.5:
|
||||||
|
resolution: {integrity: sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==}
|
||||||
|
dependencies:
|
||||||
|
delegates: 1.0.0
|
||||||
|
readable-stream: 2.3.7
|
||||||
|
dev: false
|
||||||
|
|
||||||
/arg/5.0.0:
|
/arg/5.0.0:
|
||||||
resolution: {integrity: sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==}
|
resolution: {integrity: sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -527,6 +579,17 @@ packages:
|
|||||||
tweetnacl: 0.14.5
|
tweetnacl: 0.14.5
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/bcrypt/5.0.1:
|
||||||
|
resolution: {integrity: sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw==}
|
||||||
|
engines: {node: '>= 10.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
|
dependencies:
|
||||||
|
'@mapbox/node-pre-gyp': 1.0.5
|
||||||
|
node-addon-api: 3.2.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
/binary-extensions/2.2.0:
|
/binary-extensions/2.2.0:
|
||||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -670,6 +733,16 @@ packages:
|
|||||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/chownr/2.0.0:
|
||||||
|
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/code-point-at/1.1.0:
|
||||||
|
resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/color-convert/1.9.3:
|
/color-convert/1.9.3:
|
||||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -729,6 +802,10 @@ packages:
|
|||||||
/concat-map/0.0.1:
|
/concat-map/0.0.1:
|
||||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||||
|
|
||||||
|
/console-control-strings/1.1.0:
|
||||||
|
resolution: {integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cookie/0.4.1:
|
/cookie/0.4.1:
|
||||||
resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
|
resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -919,6 +996,10 @@ packages:
|
|||||||
resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
|
resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/delegates/1.0.0:
|
||||||
|
resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/denque/1.5.0:
|
/denque/1.5.0:
|
||||||
resolution: {integrity: sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==}
|
resolution: {integrity: sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==}
|
||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
@@ -929,6 +1010,12 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/detect-libc/1.0.3:
|
||||||
|
resolution: {integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=}
|
||||||
|
engines: {node: '>=0.10'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/detective/5.2.0:
|
/detective/5.2.0:
|
||||||
resolution: {integrity: sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==}
|
resolution: {integrity: sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==}
|
||||||
engines: {node: '>=0.8.0'}
|
engines: {node: '>=0.8.0'}
|
||||||
@@ -1063,6 +1150,12 @@ packages:
|
|||||||
is-arrayish: 0.2.1
|
is-arrayish: 0.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/esbuild/0.12.15:
|
||||||
|
resolution: {integrity: sha512-72V4JNd2+48eOVCXx49xoSWHgC3/cCy96e7mbXKY+WOWghN00cCmlGnwVLRhRHorvv0dgCyuMYBZlM2xDM5OQw==}
|
||||||
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/esbuild/0.12.6:
|
/esbuild/0.12.6:
|
||||||
resolution: {integrity: sha512-RDvVLvAjsq/kIZJoneMiUOH7EE7t2QaW7T3Q7EdQij14+bZbDq5sndb0tTanmHIFSqZVMBMMyqzVHkS3dJobeA==}
|
resolution: {integrity: sha512-RDvVLvAjsq/kIZJoneMiUOH7EE7t2QaW7T3Q7EdQij14+bZbDq5sndb0tTanmHIFSqZVMBMMyqzVHkS3dJobeA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1308,6 +1401,13 @@ packages:
|
|||||||
universalify: 2.0.0
|
universalify: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fs-minipass/2.1.0:
|
||||||
|
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
dependencies:
|
||||||
|
minipass: 3.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fs.realpath/1.0.0:
|
/fs.realpath/1.0.0:
|
||||||
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
|
resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
|
||||||
|
|
||||||
@@ -1331,6 +1431,19 @@ packages:
|
|||||||
resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=}
|
resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/gauge/2.7.4:
|
||||||
|
resolution: {integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=}
|
||||||
|
dependencies:
|
||||||
|
aproba: 1.2.0
|
||||||
|
console-control-strings: 1.1.0
|
||||||
|
has-unicode: 2.0.1
|
||||||
|
object-assign: 4.1.1
|
||||||
|
signal-exit: 3.0.3
|
||||||
|
string-width: 1.0.2
|
||||||
|
strip-ansi: 3.0.1
|
||||||
|
wide-align: 1.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/generate-password/1.6.0:
|
/generate-password/1.6.0:
|
||||||
resolution: {integrity: sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ==}
|
resolution: {integrity: sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -1369,7 +1482,6 @@ packages:
|
|||||||
minimatch: 3.0.4
|
minimatch: 3.0.4
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
path-is-absolute: 1.0.1
|
path-is-absolute: 1.0.1
|
||||||
dev: true
|
|
||||||
|
|
||||||
/globals/13.8.0:
|
/globals/13.8.0:
|
||||||
resolution: {integrity: sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==}
|
resolution: {integrity: sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==}
|
||||||
@@ -1385,6 +1497,10 @@ packages:
|
|||||||
type-fest: 0.20.2
|
type-fest: 0.20.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/globalyzer/0.1.0:
|
||||||
|
resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/globby/11.0.3:
|
/globby/11.0.3:
|
||||||
resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==}
|
resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1397,6 +1513,10 @@ packages:
|
|||||||
slash: 3.0.0
|
slash: 3.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/globrex/0.1.2:
|
||||||
|
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/graceful-fs/4.2.6:
|
/graceful-fs/4.2.6:
|
||||||
resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==}
|
resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -1411,6 +1531,10 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/has-unicode/2.0.1:
|
||||||
|
resolution: {integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/has/1.0.3:
|
/has/1.0.3:
|
||||||
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
||||||
engines: {node: '>= 0.4.0'}
|
engines: {node: '>= 0.4.0'}
|
||||||
@@ -1434,6 +1558,16 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/https-proxy-agent/5.0.0:
|
||||||
|
resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
dependencies:
|
||||||
|
agent-base: 6.0.2
|
||||||
|
debug: 4.3.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ieee754/1.2.1:
|
/ieee754/1.2.1:
|
||||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -1530,6 +1664,13 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/is-fullwidth-code-point/1.0.0:
|
||||||
|
resolution: {integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dependencies:
|
||||||
|
number-is-nan: 1.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/is-fullwidth-code-point/3.0.0:
|
/is-fullwidth-code-point/3.0.0:
|
||||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1636,6 +1777,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==}
|
resolution: {integrity: sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/kleur/4.1.4:
|
||||||
|
resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/levn/0.4.1:
|
/levn/0.4.1:
|
||||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -1644,6 +1790,11 @@ packages:
|
|||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/lilconfig/2.0.3:
|
||||||
|
resolution: {integrity: sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/lines-and-columns/1.1.6:
|
/lines-and-columns/1.1.6:
|
||||||
resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=}
|
resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -1717,8 +1868,20 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
|
|
||||||
|
/magic-string/0.25.7:
|
||||||
|
resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
|
||||||
|
dependencies:
|
||||||
|
sourcemap-codec: 1.4.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/make-dir/3.1.0:
|
||||||
|
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
semver: 6.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mdn-data/2.0.14:
|
/mdn-data/2.0.14:
|
||||||
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
|
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -1741,6 +1904,10 @@ packages:
|
|||||||
picomatch: 2.3.0
|
picomatch: 2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/microtip/0.2.2:
|
||||||
|
resolution: {integrity: sha512-oah38eH5vSHVFP6yXjbKWOYt92mav++0j3zh844h1vhOscqEg7Rf4agDEIwUTFCcAPPdlhYUQMe6eZfHgD+4oQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/min-indent/1.0.1:
|
/min-indent/1.0.1:
|
||||||
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -1755,10 +1922,31 @@ packages:
|
|||||||
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
|
resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/minipass/3.1.3:
|
||||||
|
resolution: {integrity: sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/minizlib/2.1.2:
|
||||||
|
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
dependencies:
|
||||||
|
minipass: 3.1.3
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mkdirp-classic/0.5.3:
|
/mkdirp-classic/0.5.3:
|
||||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/mkdirp/1.0.4:
|
||||||
|
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/modern-normalize/1.1.0:
|
/modern-normalize/1.1.0:
|
||||||
resolution: {integrity: sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==}
|
resolution: {integrity: sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -1872,12 +2060,21 @@ packages:
|
|||||||
resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
|
resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/node-addon-api/3.2.1:
|
||||||
|
resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/node-emoji/1.10.0:
|
/node-emoji/1.10.0:
|
||||||
resolution: {integrity: sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==}
|
resolution: {integrity: sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.toarray: 4.4.0
|
lodash.toarray: 4.4.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/node-fetch/2.6.1:
|
||||||
|
resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/node-releases/1.1.71:
|
/node-releases/1.1.71:
|
||||||
resolution: {integrity: sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==}
|
resolution: {integrity: sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -1886,6 +2083,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==}
|
resolution: {integrity: sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/nopt/5.0.0:
|
||||||
|
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
abbrev: 1.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/normalize-path/3.0.0:
|
/normalize-path/3.0.0:
|
||||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1901,12 +2106,31 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/npmlog/4.1.2:
|
||||||
|
resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==}
|
||||||
|
dependencies:
|
||||||
|
are-we-there-yet: 1.1.5
|
||||||
|
console-control-strings: 1.1.0
|
||||||
|
gauge: 2.7.4
|
||||||
|
set-blocking: 2.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/nth-check/2.0.0:
|
/nth-check/2.0.0:
|
||||||
resolution: {integrity: sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==}
|
resolution: {integrity: sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
boolbase: 1.0.0
|
boolbase: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/number-is-nan/1.0.1:
|
||||||
|
resolution: {integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/object-assign/4.1.1:
|
||||||
|
resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/object-hash/2.2.0:
|
/object-hash/2.2.0:
|
||||||
resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
|
resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -1967,11 +2191,6 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/picomatch/2.2.3:
|
|
||||||
resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==}
|
|
||||||
engines: {node: '>=8.6'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/picomatch/2.3.0:
|
/picomatch/2.3.0:
|
||||||
resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
|
resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
|
||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
@@ -2062,6 +2281,20 @@ packages:
|
|||||||
import-cwd: 3.0.0
|
import-cwd: 3.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/postcss-load-config/3.1.0:
|
||||||
|
resolution: {integrity: sha512-ipM8Ds01ZUophjDTQYSVP70slFSYg3T0/zyfII5vzhN6V57YSxMgG5syXuwi5VtS8wSf3iL30v0uBdoIVx4Q0g==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
peerDependencies:
|
||||||
|
ts-node: '>=9.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
ts-node:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
import-cwd: 3.0.0
|
||||||
|
lilconfig: 2.0.3
|
||||||
|
yaml: 1.10.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/postcss-merge-longhand/5.0.2_postcss@8.3.0:
|
/postcss-merge-longhand/5.0.2_postcss@8.3.0:
|
||||||
resolution: {integrity: sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==}
|
resolution: {integrity: sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw==}
|
||||||
engines: {node: ^10 || ^12 || >=14.0}
|
engines: {node: ^10 || ^12 || >=14.0}
|
||||||
@@ -2490,7 +2723,6 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
glob: 7.1.7
|
glob: 7.1.7
|
||||||
dev: true
|
|
||||||
|
|
||||||
/rollup/2.46.0:
|
/rollup/2.46.0:
|
||||||
resolution: {integrity: sha512-qPGoUBNl+Z8uNu0z7pD3WPTABWRbcOwIrO/5ccDJzmrtzn0LVf6Lj91+L5CcWhXl6iWf23FQ6m8Jkl2CmN1O7Q==}
|
resolution: {integrity: sha512-qPGoUBNl+Z8uNu0z7pD3WPTABWRbcOwIrO/5ccDJzmrtzn0LVf6Lj91+L5CcWhXl6iWf23FQ6m8Jkl2CmN1O7Q==}
|
||||||
@@ -2543,13 +2775,21 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/semver/6.3.0:
|
||||||
|
resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/semver/7.3.5:
|
/semver/7.3.5:
|
||||||
resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==}
|
resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: 6.0.0
|
lru-cache: 6.0.0
|
||||||
dev: true
|
|
||||||
|
/set-blocking/2.0.0:
|
||||||
|
resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/shebang-command/2.0.0:
|
/shebang-command/2.0.0:
|
||||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||||
@@ -2575,6 +2815,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==}
|
resolution: {integrity: sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/signal-exit/3.0.3:
|
||||||
|
resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/simple-swizzle/0.2.2:
|
/simple-swizzle/0.2.2:
|
||||||
resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=}
|
resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2609,6 +2853,10 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/sourcemap-codec/1.4.8:
|
||||||
|
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/sparse-bitfield/3.0.3:
|
/sparse-bitfield/3.0.3:
|
||||||
resolution: {integrity: sha1-/0rm5oZWBWuks+eSqzM004JzyhE=}
|
resolution: {integrity: sha1-/0rm5oZWBWuks+eSqzM004JzyhE=}
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2649,6 +2897,15 @@ packages:
|
|||||||
engines: {node: '>=0.8.0'}
|
engines: {node: '>=0.8.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/string-width/1.0.2:
|
||||||
|
resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dependencies:
|
||||||
|
code-point-at: 1.1.0
|
||||||
|
is-fullwidth-code-point: 1.0.0
|
||||||
|
strip-ansi: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/string-width/4.2.2:
|
/string-width/4.2.2:
|
||||||
resolution: {integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==}
|
resolution: {integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2670,6 +2927,13 @@ packages:
|
|||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/strip-ansi/3.0.1:
|
||||||
|
resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dependencies:
|
||||||
|
ansi-regex: 2.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/strip-ansi/6.0.0:
|
/strip-ansi/6.0.0:
|
||||||
resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==}
|
resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2714,8 +2978,8 @@ packages:
|
|||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/svelte-hmr/0.14.4_svelte@3.38.2:
|
/svelte-hmr/0.14.5_svelte@3.38.2:
|
||||||
resolution: {integrity: sha512-kItFF7vqzStckSigoFmMnxJpTOdB9TWnQAW6Js+yAB4277tLbJIIE5KBlGHNmJNpA7MguqidsPB27Uw5UzQPCA==}
|
resolution: {integrity: sha512-3O+kkbT1XKAomKB0LRcdY8JUTzONoNZ8rSH4iEdG7piIYsw+KkXpTkbbU1Sc1yPY4onfXkmCrHElYsxr0V1Snw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
svelte: '>=3.19.0'
|
svelte: '>=3.19.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -2822,8 +3086,8 @@ packages:
|
|||||||
strip-ansi: 6.0.0
|
strip-ansi: 6.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/tailwindcss/2.2.0_6daa0ece57b4377652e73c9c66c3b94c:
|
/tailwindcss/2.2.4_6daa0ece57b4377652e73c9c66c3b94c:
|
||||||
resolution: {integrity: sha512-vzyictuac60cUfky6R4gFW98glcc/UxpaCH+Mt9dq+LEPdZq2Dpvo5iYpPaemutOIjfeiY0Y8j0ZgJG3wBaFDQ==}
|
resolution: {integrity: sha512-OdBCPgazNNsknSP+JfrPzkay9aqKjhKtFhbhgxHgvEFdHy/GuRPo2SCJ4w1SFTN8H6FPI4m6qD/Jj20NWY1GkA==}
|
||||||
engines: {node: '>=12.13.0'}
|
engines: {node: '>=12.13.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2854,7 +3118,7 @@ packages:
|
|||||||
object-hash: 2.2.0
|
object-hash: 2.2.0
|
||||||
postcss: 8.3.0
|
postcss: 8.3.0
|
||||||
postcss-js: 3.0.3
|
postcss-js: 3.0.3
|
||||||
postcss-load-config: 3.0.1
|
postcss-load-config: 3.1.0
|
||||||
postcss-nested: 5.0.5_postcss@8.3.0
|
postcss-nested: 5.0.5_postcss@8.3.0
|
||||||
postcss-selector-parser: 6.0.6
|
postcss-selector-parser: 6.0.6
|
||||||
postcss-value-parser: 4.1.0
|
postcss-value-parser: 4.1.0
|
||||||
@@ -2863,6 +3127,8 @@ packages:
|
|||||||
reduce-css-calc: 2.1.8
|
reduce-css-calc: 2.1.8
|
||||||
resolve: 1.20.0
|
resolve: 1.20.0
|
||||||
tmp: 0.2.1
|
tmp: 0.2.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- ts-node
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/tar-fs/2.0.1:
|
/tar-fs/2.0.1:
|
||||||
@@ -2885,6 +3151,18 @@ packages:
|
|||||||
readable-stream: 3.6.0
|
readable-stream: 3.6.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/tar/6.1.0:
|
||||||
|
resolution: {integrity: sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
dependencies:
|
||||||
|
chownr: 2.0.0
|
||||||
|
fs-minipass: 2.1.0
|
||||||
|
minipass: 3.1.3
|
||||||
|
minizlib: 2.1.2
|
||||||
|
mkdirp: 1.0.4
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/text-table/0.2.0:
|
/text-table/0.2.0:
|
||||||
resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=}
|
resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2893,6 +3171,13 @@ packages:
|
|||||||
resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=}
|
resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tiny-glob/0.2.9:
|
||||||
|
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
|
||||||
|
dependencies:
|
||||||
|
globalyzer: 0.1.0
|
||||||
|
globrex: 0.1.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tmp/0.2.1:
|
/tmp/0.2.1:
|
||||||
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
|
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
|
||||||
engines: {node: '>=8.17.0'}
|
engines: {node: '>=8.17.0'}
|
||||||
@@ -2997,13 +3282,13 @@ packages:
|
|||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite/2.3.7:
|
/vite/2.4.2:
|
||||||
resolution: {integrity: sha512-Y0xRz11MPYu/EAvzN94+FsOZHbSvO6FUvHv127CyG7mV6oDoay2bw+g5y9wW3Blf8OY3chaz3nc/DcRe1IQ3Nw==}
|
resolution: {integrity: sha512-2MifxD2I9fjyDmmEzbULOo3kOUoqX90A58cT6mECxoVQlMYFuijZsPQBuA14mqSwvV3ydUsqnq+BRWXyO9Qa+w==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.12.6
|
esbuild: 0.12.15
|
||||||
postcss: 8.3.0
|
postcss: 8.3.5
|
||||||
resolve: 1.20.0
|
resolve: 1.20.0
|
||||||
rollup: 2.46.0
|
rollup: 2.46.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -3017,6 +3302,12 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
||||||
|
/wide-align/1.1.3:
|
||||||
|
resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==}
|
||||||
|
dependencies:
|
||||||
|
string-width: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/word-wrap/1.2.3:
|
/word-wrap/1.2.3:
|
||||||
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -3032,7 +3323,6 @@ packages:
|
|||||||
|
|
||||||
/yallist/4.0.0:
|
/yallist/4.0.0:
|
||||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/yaml/1.10.2:
|
/yaml/1.10.2:
|
||||||
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
|
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<link rel="dns-prefetch" href="https://cdn.coollabs.io/" />
|
<link rel="dns-prefetch" href="https://cdn.coollabs.io/" />
|
||||||
<link rel="preconnect" href="https://cdn.coollabs.io/" crossorigin="" />
|
<link rel="preconnect" href="https://cdn.coollabs.io/" crossorigin="" />
|
||||||
<link rel="stylesheet" href="https://cdn.coollabs.io/fonts/montserrat/montserrat.css" />
|
<link rel="stylesheet" href="https://cdn.coollabs.io/fonts/montserrat/montserrat.css" />
|
||||||
<link rel="stylesheet" href="https://cdn.coollabs.io/css/microtip-0.2.2.min.css" />
|
|
||||||
%svelte.head%
|
%svelte.head%
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { VITE_GITHUB_APP_NAME } from '$lib/consts';
|
import { VITE_GITHUB_APP_NAME } from '$lib/consts';
|
||||||
import { application, isPullRequestPermissionsGranted } from '$store';
|
import { application, isPullRequestPermissionsGranted, originalDomain } from '$store';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import TooltipInfo from '$components/TooltipInfo.svelte';
|
import TooltipInfo from '$components/TooltipInfo.svelte';
|
||||||
import { request } from '$lib/request';
|
import { request } from '$lib/request';
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
async function setPreviewDeployment() {
|
async function setPreviewDeployment() {
|
||||||
if ($application.general.isPreviewDeploymentEnabled) {
|
if ($application.general.isPreviewDeploymentEnabled) {
|
||||||
const result = window.confirm(
|
const result = window.confirm(
|
||||||
"Are you sure? It will delete all PR deployments - it's NOT reversible!"
|
"DANGER ZONE! It will delete all PR deployments. It's NOT reversible! Are you sure?"
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
loading.previewDeployment = true;
|
loading.previewDeployment = true;
|
||||||
@@ -194,9 +194,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (!$application.publish.domain) domainInput.focus();
|
if (!$application.publish.domain) {
|
||||||
|
domainInput.focus();
|
||||||
|
} else {
|
||||||
|
$originalDomain = $application.publish.domain;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -378,7 +381,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{#if loading.previewDeployment}
|
{#if loading.previewDeployment}
|
||||||
<div class="absolute left-0 bottom-0 -mb-4 -ml-2 text-xs font-bold">{$application.general.isPreviewDeploymentEnabled ? 'Enabling...' : 'Disabling...' }</div>
|
<div class="absolute left-0 bottom-0 -mb-4 -ml-2 text-xs font-bold">
|
||||||
|
{$application.general.isPreviewDeploymentEnabled ? 'Enabling...' : 'Disabling...'}
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -438,6 +443,10 @@
|
|||||||
<input
|
<input
|
||||||
bind:this={domainInput}
|
bind:this={domainInput}
|
||||||
class="border-2"
|
class="border-2"
|
||||||
|
disabled={$page.path !== '/application/new'}
|
||||||
|
class:cursor-not-allowed={$page.path !== '/application/new'}
|
||||||
|
class:bg-warmGray-900={$page.path !== '/application/new'}
|
||||||
|
class:hover:bg-warmGray-900={$page.path !== '/application/new'}
|
||||||
class:placeholder-red-500={$application.publish.domain == null ||
|
class:placeholder-red-500={$application.publish.domain == null ||
|
||||||
$application.publish.domain == ''}
|
$application.publish.domain == ''}
|
||||||
class:border-red-500={$application.publish.domain == null ||
|
class:border-red-500={$application.publish.domain == null ||
|
||||||
@@ -455,7 +464,15 @@
|
|||||||
}/api`}
|
}/api`}
|
||||||
/></label
|
/></label
|
||||||
>
|
>
|
||||||
<input id="Path" bind:value={$application.publish.path} placeholder="/" />
|
<input
|
||||||
|
id="Path"
|
||||||
|
bind:value={$application.publish.path}
|
||||||
|
disabled={$page.path !== '/application/new'}
|
||||||
|
class:cursor-not-allowed={$page.path !== '/application/new'}
|
||||||
|
class:bg-warmGray-900={$page.path !== '/application/new'}
|
||||||
|
class:hover:bg-warmGray-900={$page.path !== '/application/new'}
|
||||||
|
placeholder="/"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label for="Port" class:text-warmGray-800={!buildpacks[$application.build.pack].port.active}
|
<label for="Port" class:text-warmGray-800={!buildpacks[$application.build.pack].port.active}
|
||||||
@@ -590,5 +607,4 @@
|
|||||||
.buildpack {
|
.buildpack {
|
||||||
@apply px-6 py-2 mx-2 my-2 bg-warmGray-800 w-48 ease-in-out hover:scale-105 text-center rounded border-2 border-transparent border-dashed cursor-pointer transition duration-100;
|
@apply px-6 py-2 mx-2 my-2 bg-warmGray-800 w-48 ease-in-out hover:scale-105 text-center rounded border-2 border-transparent border-dashed cursor-pointer transition duration-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -19,37 +19,29 @@
|
|||||||
async function getPRDeployments() {
|
async function getPRDeployments() {
|
||||||
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
||||||
body: {
|
body: {
|
||||||
name: $application.repository.name,
|
nickname: $application.general.nickname
|
||||||
organization: $application.repository.organization,
|
|
||||||
branch: $application.repository.branch
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
||||||
}
|
}
|
||||||
async function removePR(prConfiguration) {
|
async function removePR(prConfiguration) {
|
||||||
const result = window.confirm("Are you sure? It's NOT reversible!");
|
const result = window.confirm("DANGER ZONE! It's NOT reversible! Are you sure?");
|
||||||
if (result) {
|
if (result) {
|
||||||
await request(`/api/v1/application/remove`, $session, {
|
await request(`/api/v1/application/remove`, $session, {
|
||||||
body: {
|
body: {
|
||||||
organization: prConfiguration.repository.organization,
|
nickname: prConfiguration.general.nickname
|
||||||
name: prConfiguration.repository.name,
|
|
||||||
branch: prConfiguration.repository.branch,
|
|
||||||
domain: prConfiguration.publish.domain
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
browser && toast.push('PR deployment removed.');
|
browser && toast.push('PR deployment removed.');
|
||||||
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
||||||
body: {
|
body: {
|
||||||
name: prConfiguration.repository.name,
|
nickname: prConfiguration.general.nickname
|
||||||
organization: prConfiguration.repository.organization,
|
|
||||||
branch: prConfiguration.repository.branch
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="text-2xl font-bold border-gradient w-48">Pull Requests</div>
|
<div class="text-2xl font-bold border-gradient w-48">Pull Requests</div>
|
||||||
|
|||||||
@@ -1,27 +1,29 @@
|
|||||||
<script>
|
<script>
|
||||||
import { application } from "$store";
|
import { application } from '$store';
|
||||||
|
import BuildEnv from '../BuildEnv.svelte';
|
||||||
|
|
||||||
let secret = {
|
let secret = {
|
||||||
name: null,
|
name: null,
|
||||||
value: null,
|
value: null,
|
||||||
|
isBuild: false
|
||||||
};
|
};
|
||||||
let foundSecret = null;
|
let foundSecret = null;
|
||||||
async function saveSecret() {
|
async function saveSecret() {
|
||||||
if (secret.name && secret.value) {
|
if (secret.name && secret.value) {
|
||||||
const found = $application.publish.secrets.find(
|
const found = $application.publish.secrets.find((s) => s.name === secret.name);
|
||||||
s => s.name === secret.name,
|
|
||||||
);
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
$application.publish.secrets = [
|
$application.publish.secrets = [
|
||||||
...$application.publish.secrets,
|
...$application.publish.secrets,
|
||||||
{
|
{
|
||||||
name: secret.name,
|
name: secret.name,
|
||||||
value: secret.value,
|
value: secret.value,
|
||||||
},
|
isBuild: secret.isBuild
|
||||||
|
}
|
||||||
];
|
];
|
||||||
secret = {
|
secret = {
|
||||||
name: null,
|
name: null,
|
||||||
value: null,
|
value: null,
|
||||||
|
isBuild: false
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
foundSecret = found;
|
foundSecret = found;
|
||||||
@@ -30,49 +32,95 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function removeSecret(name) {
|
async function removeSecret(name) {
|
||||||
foundSecret = null
|
foundSecret = null;
|
||||||
$application.publish.secrets = [
|
$application.publish.secrets = [...$application.publish.secrets.filter((s) => s.name !== name)];
|
||||||
...$application.publish.secrets.filter(s => s.name !== name),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="text-2xl font-bold border-gradient w-24">Secrets</div>
|
<div class="text-2xl font-bold border-gradient w-24">Secrets</div>
|
||||||
<div class="max-w-xl mx-auto text-center pt-4">
|
<div class="max-w-3xl mx-auto text-center pt-4">
|
||||||
<div class="text-left text-base font-bold tracking-tight text-warmGray-400">
|
|
||||||
New Secret
|
|
||||||
</div>
|
|
||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<input id="secretName" bind:value="{secret.name}" placeholder="Name" class="w-64 border-2 border-transparent" />
|
<div class="grid grid-flow-row">
|
||||||
<input id="secretValue" bind:value="{secret.value}" placeholder="Value" class="w-64 border-2 border-transparent" />
|
<label for="secretName">Secret Name</label>
|
||||||
<button class="icon hover:text-green-500" on:click="{saveSecret}">
|
<input
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
id="secretName"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
bind:value={secret.name}
|
||||||
|
placeholder="Name"
|
||||||
|
class="w-64 border-2 border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-flow-row">
|
||||||
|
<label for="secretValue">Secret Value</label>
|
||||||
|
<input
|
||||||
|
id="secretValue"
|
||||||
|
bind:value={secret.value}
|
||||||
|
placeholder="Value"
|
||||||
|
class="w-64 border-2 border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-flow-row">
|
||||||
|
<label for="buildVariable">Is build variable?</label>
|
||||||
|
<div class="mt-2 w-full">
|
||||||
|
<BuildEnv {secret} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-6">
|
||||||
|
<button class="icon hover:text-green-500" on:click={saveSecret}>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-6 w-6"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if $application.publish.secrets.length > 0}
|
{#if $application.publish.secrets.length > 0}
|
||||||
<div class="py-4">
|
<div class="pt-1">
|
||||||
{#each $application.publish.secrets as s}
|
{#each $application.publish.secrets as secret}
|
||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4 space-y-2">
|
||||||
<input
|
<input
|
||||||
id="{s.name}"
|
id={secret.name}
|
||||||
value="{s.name}"
|
value={secret.name}
|
||||||
disabled
|
disabled
|
||||||
class="border-2 bg-transparent border-transparent w-64"
|
class="border-2 bg-transparent border-transparent w-64 hover:bg-transparent"
|
||||||
class:border-red-600="{foundSecret && foundSecret.name === s.name}"
|
class:border-red-600={foundSecret && foundSecret.name === secret.name}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id="{s.createdAt}"
|
id={secret.createdAt}
|
||||||
value="SAVED"
|
value="SAVED"
|
||||||
disabled
|
disabled
|
||||||
class="border-2 bg-transparent border-transparent w-64"
|
class="border-2 bg-transparent border-transparent w-64 hover:bg-transparent"
|
||||||
|
/>
|
||||||
|
<div class="flex justify-center items-center px-12">
|
||||||
|
<BuildEnv {secret} readOnly />
|
||||||
|
</div>
|
||||||
|
<button class="icon hover:text-red-500" on:click={() => removeSecret(secret.name)}>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-6 w-6"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
||||||
/>
|
/>
|
||||||
<button class="icon hover:text-red-500" on:click="{() => removeSecret(s.name)}">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
55
src/components/Application/BuildEnv.svelte
Normal file
55
src/components/Application/BuildEnv.svelte
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<script>
|
||||||
|
export let secret;
|
||||||
|
export let readOnly = false;
|
||||||
|
function isBuildSet() {
|
||||||
|
if (!readOnly) secret.isBuild = !secret.isBuild;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="buildVariable"
|
||||||
|
type="button"
|
||||||
|
aria-pressed="false"
|
||||||
|
on:click={isBuildSet}
|
||||||
|
class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-100"
|
||||||
|
class:bg-green-600={secret.isBuild}
|
||||||
|
class:bg-warmGray-700={!secret.isBuild}
|
||||||
|
class:opacity-50={readOnly}
|
||||||
|
class:cursor-not-allowed={readOnly}
|
||||||
|
>
|
||||||
|
<span class="sr-only">Use setting</span>
|
||||||
|
<span
|
||||||
|
class="pointer-events-none relative inline-block h-5 w-5 rounded-full bg-white shadow transition ease-in-out duration-200 transform"
|
||||||
|
class:translate-x-5={secret.isBuild}
|
||||||
|
class:translate-x-0={!secret.isBuild}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class=" ease-in duration-200 absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
|
class:opacity-0={secret.isBuild}
|
||||||
|
class:opacity-100={!secret.isBuild}
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<svg class="bg-white h-3 w-3 text-red-600" fill="none" viewBox="0 0 12 12">
|
||||||
|
<path
|
||||||
|
d="M4 8l2-2m0 0l2-2M6 6L4 4m2 2l2 2"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="ease-out duration-100 absolute inset-0 h-full w-full flex items-center justify-center transition-opacity"
|
||||||
|
aria-hidden="true"
|
||||||
|
class:opacity-100={secret.isBuild}
|
||||||
|
class:opacity-0={!secret.isBuild}
|
||||||
|
>
|
||||||
|
<svg class="bg-white h-3 w-3 text-green-600" fill="currentColor" viewBox="0 0 12 12">
|
||||||
|
<path
|
||||||
|
d="M3.707 5.293a1 1 0 00-1.414 1.414l1.414-1.414zM5 8l-.707.707a1 1 0 001.414 0L5 8zm4.707-3.293a1 1 0 00-1.414-1.414l1.414 1.414zm-7.414 2l2 2 1.414-1.414-2-2-1.414 1.414zm3.414 2l4-4-1.414-1.414-4 4 1.414 1.414z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
import Tabs from '$components/Application/Tabs.svelte';
|
import Tabs from '$components/Application/Tabs.svelte';
|
||||||
import Repositories from '$components/Application/Repositories.svelte';
|
import Repositories from '$components/Application/Repositories.svelte';
|
||||||
import Login from '$components/Application/Login.svelte';
|
import Login from '$components/Application/Login.svelte';
|
||||||
|
import { dashify } from '$lib/common';
|
||||||
let loading = {
|
let loading = {
|
||||||
github: false,
|
github: false,
|
||||||
branches: false
|
branches: false
|
||||||
@@ -26,15 +27,7 @@
|
|||||||
let branches = [];
|
let branches = [];
|
||||||
let relogin = false;
|
let relogin = false;
|
||||||
let permissions = {};
|
let permissions = {};
|
||||||
function dashify(str: string, options?: any) {
|
|
||||||
if (typeof str !== 'string') return str;
|
|
||||||
return str
|
|
||||||
.trim()
|
|
||||||
.replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-'))
|
|
||||||
.replace(/^-+|-+$/g, '')
|
|
||||||
.replace(/-{2,}/g, (m) => (options && options.condense ? '-' : m))
|
|
||||||
.toLowerCase();
|
|
||||||
}
|
|
||||||
async function getGithubRepos(id, page) {
|
async function getGithubRepos(id, page) {
|
||||||
return await request(
|
return await request(
|
||||||
`https://api.github.com/user/installations/${id}/repositories?per_page=100&page=${page}`,
|
`https://api.github.com/user/installations/${id}/repositories?per_page=100&page=${page}`,
|
||||||
@@ -174,7 +167,6 @@
|
|||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div in:fade={{ duration: 100 }}>
|
<div in:fade={{ duration: 100 }}>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { application, initialApplication, initConf } from '$store';
|
import { application, initialApplication, initConf, originalDomain } from '$store';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { toast } from '@zerodevx/svelte-toast';
|
import { toast } from '@zerodevx/svelte-toast';
|
||||||
import Tooltip from '$components/Tooltip.svelte';
|
import Tooltip from '$components/Tooltip.svelte';
|
||||||
@@ -9,15 +9,12 @@
|
|||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
async function removeApplication() {
|
async function removeApplication() {
|
||||||
const result = window.confirm(
|
const result = window.confirm(
|
||||||
"Are you sure? It will delete all deployments, including PR's - it's NOT reversible!"
|
"DANGER ZONE! It will delete all deployments, including PR's. It's NOT reversible! Are you sure?"
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
await request(`/api/v1/application/remove`, $session, {
|
await request(`/api/v1/application/remove`, $session, {
|
||||||
body: {
|
body: {
|
||||||
organization: $application.repository.organization,
|
nickname: $application.general.nickname
|
||||||
name: $application.repository.name,
|
|
||||||
branch: $application.repository.branch,
|
|
||||||
domain: $application.publish.domain
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,17 +43,14 @@
|
|||||||
$initConf = JSON.parse(JSON.stringify($application));
|
$initConf = JSON.parse(JSON.stringify($application));
|
||||||
if (browser) {
|
if (browser) {
|
||||||
toast.push('Application deployment queued.');
|
toast.push('Application deployment queued.');
|
||||||
goto(
|
goto(`/application/${$application.general.nickname}/logs/${$application.general.deployId}`, {
|
||||||
`/application/${$application.repository.organization}/${$application.repository.name}/${$application.repository.branch}/logs/${$application.general.deployId}`,
|
replaceState: true
|
||||||
{ replaceState: true }
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.log(error);
|
// browser && toast.push(error.error || error || 'Ooops something went wrong.');
|
||||||
// toast.push(error.error || error || 'Ooops something went wrong.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav class="flex text-white justify-end items-center m-4 fixed right-0 top-0 space-x-4 z-50">
|
<nav class="flex text-white justify-end items-center m-4 fixed right-0 top-0 space-x-4 z-50">
|
||||||
@@ -132,10 +126,7 @@
|
|||||||
class:cursor-not-allowed={$page.path === '/application/new'}
|
class:cursor-not-allowed={$page.path === '/application/new'}
|
||||||
class:text-blue-400={/logs\/*/.test($page.path)}
|
class:text-blue-400={/logs\/*/.test($page.path)}
|
||||||
class:bg-warmGray-700={/logs\/*/.test($page.path)}
|
class:bg-warmGray-700={/logs\/*/.test($page.path)}
|
||||||
on:click={() =>
|
on:click={() => goto(`/application/${$application.general.nickname}/logs`)}
|
||||||
goto(
|
|
||||||
`/application/${$application.repository.organization}/${$application.repository.name}/${$application.repository.branch}/logs`
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-6"
|
class="w-6"
|
||||||
@@ -161,10 +152,7 @@
|
|||||||
$page.path === '/application/new'}
|
$page.path === '/application/new'}
|
||||||
class:bg-warmGray-700={$page.path.endsWith('configuration') ||
|
class:bg-warmGray-700={$page.path.endsWith('configuration') ||
|
||||||
$page.path === '/application/new'}
|
$page.path === '/application/new'}
|
||||||
on:click={() =>
|
on:click={() => goto(`/application/${$application.general.nickname}/configuration`)}
|
||||||
goto(
|
|
||||||
`/application/${$application.repository.organization}/${$application.repository.name}/${$application.repository.branch}/configuration`
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-6"
|
class="w-6"
|
||||||
|
|||||||
@@ -27,28 +27,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function load() {
|
async function load() {
|
||||||
const found = $dashboard?.applications?.deployed.find((deployment) => {
|
|
||||||
if (
|
|
||||||
deployment.configuration.repository.organization === $application.repository.organization &&
|
|
||||||
deployment.configuration.repository.name === $application.repository.name &&
|
|
||||||
deployment.configuration.repository.branch === $application.repository.branch
|
|
||||||
) {
|
|
||||||
return deployment;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (found) {
|
|
||||||
$application = { ...found.configuration };
|
|
||||||
if ($page.path === '/application/new') {
|
|
||||||
if (browser) {
|
|
||||||
toast.push('This repository & branch is already defined. Redirecting...');
|
|
||||||
goto(
|
|
||||||
`/application/${$application.repository.organization}/${$application.repository.name}/${$application.repository.branch}/configuration`,
|
|
||||||
{ replaceState: true }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($page.path === '/application/new') {
|
if ($page.path === '/application/new') {
|
||||||
try {
|
try {
|
||||||
const dir = await request(
|
const dir = await request(
|
||||||
|
|||||||
@@ -1,3 +1,44 @@
|
|||||||
|
<script>
|
||||||
|
export let github = false;
|
||||||
|
export let githubLoadingText = 'Loading GitHub...';
|
||||||
|
export let fullscreen = true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if fullscreen}
|
||||||
|
{#if github}
|
||||||
|
<div class="fixed left-0 top-0 flex flex-wrap content-center h-full w-full">
|
||||||
|
<div class="main flex justify-center items-center">
|
||||||
|
<div class="w-64">
|
||||||
|
<svg
|
||||||
|
class=" w-28 animate-bounce mx-auto"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
><path
|
||||||
|
d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
<div class="text-xl font-bold text-center">
|
||||||
|
{githubLoadingText}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="main fixed left-0 top-0 flex flex-wrap content-center h-full">
|
||||||
|
<span class="loader" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{:else}
|
||||||
|
<div class="main h-64 py-24 left-0 top-0 flex flex-wrap content-center mx-auto">
|
||||||
|
<span class="loader" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.loader {
|
.loader {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
@@ -14,7 +55,7 @@
|
|||||||
|
|
||||||
.loader::after,
|
.loader::after,
|
||||||
.loader::before {
|
.loader::before {
|
||||||
content: "";
|
content: '';
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -40,41 +81,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
|
||||||
export let github = false;
|
|
||||||
export let githubLoadingText = "Loading GitHub...";
|
|
||||||
export let fullscreen = true;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if fullscreen}
|
|
||||||
{#if github}
|
|
||||||
<div class="fixed left-0 top-0 flex flex-wrap content-center h-full w-full">
|
|
||||||
<div class="main flex justify-center items-center">
|
|
||||||
<div class="w-64">
|
|
||||||
<svg
|
|
||||||
class=" w-28 animate-bounce mx-auto"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
><path
|
|
||||||
d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"
|
|
||||||
></path></svg
|
|
||||||
>
|
|
||||||
<div class="text-xl font-bold text-center">
|
|
||||||
{githubLoadingText}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="main fixed left-0 top-0 flex flex-wrap content-center h-full">
|
|
||||||
<span class=" loader"></span>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
<script>
|
<script>
|
||||||
export let value;
|
export let value;
|
||||||
let showPassword = false;
|
let showPassword = false;
|
||||||
|
export let isEditable = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative w-full">
|
<div class="relative w-full">
|
||||||
<input
|
{#if showPassword}
|
||||||
type="{showPassword ? 'text' : 'password'}"
|
<input type="text" class="w-full" bind:value disabled={!isEditable} />
|
||||||
class="w-full "
|
{:else}
|
||||||
{value}
|
<input type="password" class="w-full" bind:value disabled={!isEditable} />
|
||||||
disabled
|
{/if}
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="absolute top-0 my-2 mx-2 right-0 cursor-pointer text-warmGray-600 hover:text-white"
|
class="absolute top-0 my-2 mx-2 right-0 cursor-pointer text-warmGray-600 hover:text-white"
|
||||||
on:click="{() => showPassword = !showPassword}"
|
on:click={() => (showPassword = !showPassword)}
|
||||||
>
|
>
|
||||||
{#if showPassword}
|
{#if showPassword}
|
||||||
<svg
|
<svg
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
|
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
|
||||||
></path>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{:else}
|
{:else}
|
||||||
<svg
|
<svg
|
||||||
@@ -41,13 +42,14 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||||
|
/>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
||||||
></path>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -98,10 +98,10 @@ export async function handle({ request, resolve }) {
|
|||||||
try {
|
try {
|
||||||
session = initializeSession(request.headers, {
|
session = initializeSession(request.headers, {
|
||||||
secret: SECRETS_ENCRYPTION_KEY,
|
secret: SECRETS_ENCRYPTION_KEY,
|
||||||
cookie: { path: '/' }
|
cookie: { path: '/', secure: true }
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error);
|
||||||
return {
|
return {
|
||||||
status: 302,
|
status: 302,
|
||||||
headers: {
|
headers: {
|
||||||
@@ -124,7 +124,7 @@ export async function handle({ request, resolve }) {
|
|||||||
if (!session['set-cookie']) {
|
if (!session['set-cookie']) {
|
||||||
if (!session?.data?.coolToken && !publicPages.includes(request.path)) {
|
if (!session?.data?.coolToken && !publicPages.includes(request.path)) {
|
||||||
return {
|
return {
|
||||||
status: 301,
|
status: 302,
|
||||||
headers: {
|
headers: {
|
||||||
location: '/'
|
location: '/'
|
||||||
}
|
}
|
||||||
@@ -146,6 +146,6 @@ export function getSession(request) {
|
|||||||
isLoggedIn: data && Object.keys(data).length !== 0 ? true : false,
|
isLoggedIn: data && Object.keys(data).length !== 0 ? true : false,
|
||||||
expires: data.expires,
|
expires: data.expires,
|
||||||
coolToken: data.coolToken,
|
coolToken: data.coolToken,
|
||||||
ghToken: data.ghToken
|
ghToken: data.ghToken || null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { docker } from '$lib/api/docker';
|
import { docker } from '$lib/api/docker';
|
||||||
import Deployment from '$models/Deployment';
|
import Deployment from '$models/Deployment';
|
||||||
import { execShellAsync } from '../common';
|
import { execShellAsync } from '../common';
|
||||||
|
import crypto from 'crypto';
|
||||||
export async function deleteSameDeployments(configuration) {
|
export async function deleteSameDeployments(configuration, originalDomain = null) {
|
||||||
await (
|
await (
|
||||||
await docker.engine.listServices()
|
await docker.engine.listServices()
|
||||||
)
|
)
|
||||||
@@ -12,7 +12,7 @@ export async function deleteSameDeployments(configuration) {
|
|||||||
if (
|
if (
|
||||||
running.repository.id === configuration.repository.id &&
|
running.repository.id === configuration.repository.id &&
|
||||||
running.repository.branch === configuration.repository.branch &&
|
running.repository.branch === configuration.repository.branch &&
|
||||||
running.publish.domain === configuration.publish.domain
|
running.publish.domain === originalDomain || configuration.publish.domain
|
||||||
) {
|
) {
|
||||||
await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`);
|
await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-
|
|||||||
import { docker } from '$lib/api/docker';
|
import { docker } from '$lib/api/docker';
|
||||||
import { baseServiceConfiguration } from './common';
|
import { baseServiceConfiguration } from './common';
|
||||||
import { execShellAsync } from '../common';
|
import { execShellAsync } from '../common';
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import Configuration from '$models/Configuration';
|
||||||
function getUniq() {
|
function getUniq() {
|
||||||
return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 });
|
return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 });
|
||||||
}
|
}
|
||||||
@@ -12,7 +13,7 @@ function getUniq() {
|
|||||||
export function setDefaultConfiguration(configuration) {
|
export function setDefaultConfiguration(configuration) {
|
||||||
const nickname = configuration.general.nickname || getUniq();
|
const nickname = configuration.general.nickname || getUniq();
|
||||||
const deployId = cuid();
|
const deployId = cuid();
|
||||||
const shaBase = JSON.stringify({ repository: configuration.repository });
|
const shaBase = JSON.stringify({ path: configuration.publish.path, domain: configuration.publish.domain });
|
||||||
const sha256 = crypto.createHash('sha256').update(shaBase).digest('hex');
|
const sha256 = crypto.createHash('sha256').update(shaBase).digest('hex');
|
||||||
|
|
||||||
configuration.build.container.name = sha256.slice(0, 15);
|
configuration.build.container.name = sha256.slice(0, 15);
|
||||||
@@ -51,7 +52,7 @@ export function setDefaultConfiguration(configuration) {
|
|||||||
if (configuration.publish.directory.startsWith('/'))
|
if (configuration.publish.directory.startsWith('/'))
|
||||||
configuration.publish.directory = configuration.publish.directory.replace('/', '');
|
configuration.publish.directory = configuration.publish.directory.replace('/', '');
|
||||||
|
|
||||||
if (configuration.build.pack === 'static' || configuration.build.pack === 'nodejs') {
|
if (configuration.build.pack === 'nodejs') {
|
||||||
if (!configuration.build.command.installation)
|
if (!configuration.build.command.installation)
|
||||||
configuration.build.command.installation = 'yarn install';
|
configuration.build.command.installation = 'yarn install';
|
||||||
}
|
}
|
||||||
@@ -81,34 +82,37 @@ export function setDefaultConfiguration(configuration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function precheckDeployment(configuration) {
|
export async function precheckDeployment(configuration) {
|
||||||
const services = (await docker.engine.listServices()).filter(
|
const services = await Configuration.find({
|
||||||
(r) =>
|
'publish.domain': configuration.publish.domain,
|
||||||
r.Spec.Labels.managedBy === 'coolify' &&
|
'publish.path': configuration.publish.path
|
||||||
r.Spec.Labels.type === 'application' &&
|
})
|
||||||
JSON.parse(r.Spec.Labels.configuration).publish.domain === configuration.publish.domain
|
// const services = (await docker.engine.listServices()).filter(
|
||||||
);
|
// (r) =>
|
||||||
|
// r.Spec.Labels.managedBy === 'coolify' &&
|
||||||
|
// r.Spec.Labels.type === 'application' &&
|
||||||
|
// JSON.parse(r.Spec.Labels.configuration).publish.domain === configuration.publish.domain
|
||||||
|
// );
|
||||||
let foundService = false;
|
let foundService = false;
|
||||||
let configChanged = false;
|
let configChanged = false;
|
||||||
let imageChanged = false;
|
let imageChanged = false;
|
||||||
let forceUpdate = false;
|
let forceUpdate = false;
|
||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
const running = JSON.parse(service.Spec.Labels.configuration);
|
// const running = JSON.parse(service.Spec.Labels.configuration);
|
||||||
if (running) {
|
|
||||||
if (
|
if (
|
||||||
running.repository.id === configuration.repository.id &&
|
service.repository.id === configuration.repository.id &&
|
||||||
running.repository.branch === configuration.repository.branch
|
service.repository.branch === configuration.repository.branch
|
||||||
) {
|
) {
|
||||||
foundService = true;
|
foundService = true;
|
||||||
// Base service configuration changed
|
// Base service configuration changed
|
||||||
if (
|
if (
|
||||||
!running.build.container.baseSHA ||
|
!service.build.container.baseSHA ||
|
||||||
running.build.container.baseSHA !== configuration.build.container.baseSHA
|
service.build.container.baseSHA !== configuration.build.container.baseSHA
|
||||||
) {
|
) {
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
// If the deployment is in error state, forceUpdate
|
// If the deployment is in error state, forceUpdate
|
||||||
const state = await execShellAsync(
|
const state = await execShellAsync(
|
||||||
`docker stack ps ${running.build.container.name} --format '{{ json . }}'`
|
`docker stack ps ${service.build.container.name} --format '{{ json . }}'`
|
||||||
);
|
);
|
||||||
const isError = state
|
const isError = state
|
||||||
.split('\n')
|
.split('\n')
|
||||||
@@ -116,7 +120,7 @@ export async function precheckDeployment(configuration) {
|
|||||||
.map((s) => JSON.parse(s))
|
.map((s) => JSON.parse(s))
|
||||||
.filter(
|
.filter(
|
||||||
(n) =>
|
(n) =>
|
||||||
n.DesiredState !== 'Running' && n.Image.split(':')[1] === running.build.container.tag
|
n.DesiredState !== 'Running' && n.Image.split(':')[1] === service.build.container.tag
|
||||||
);
|
);
|
||||||
if (isError.length > 0) {
|
if (isError.length > 0) {
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
@@ -145,7 +149,7 @@ export async function precheckDeployment(configuration) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const runningWithoutContainer = JSON.parse(JSON.stringify(running));
|
const runningWithoutContainer = JSON.parse(JSON.stringify(service));
|
||||||
delete runningWithoutContainer.build.container;
|
delete runningWithoutContainer.build.container;
|
||||||
|
|
||||||
const configurationWithoutContainer = JSON.parse(JSON.stringify(configuration));
|
const configurationWithoutContainer = JSON.parse(JSON.stringify(configuration));
|
||||||
@@ -162,16 +166,16 @@ export async function precheckDeployment(configuration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If only the image changed
|
// If only the image changed
|
||||||
if (running.build.container.tag !== configuration.build.container.tag) imageChanged = true;
|
if (service.build.container.tag !== configuration.build.container.tag) imageChanged = true;
|
||||||
// If build pack changed, forceUpdate the service
|
// If build pack changed, forceUpdate the service
|
||||||
if (running.build.pack !== configuration.build.pack) forceUpdate = true;
|
if (service.build.pack !== configuration.build.pack) forceUpdate = true;
|
||||||
if (
|
if (
|
||||||
configuration.general.isPreviewDeploymentEnabled &&
|
configuration.general.isPreviewDeploymentEnabled &&
|
||||||
configuration.general.pullRequest !== 0
|
configuration.general.pullRequest !== 0
|
||||||
)
|
)
|
||||||
forceUpdate = true;
|
forceUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (forceUpdate) {
|
if (forceUpdate) {
|
||||||
imageChanged = false;
|
imageChanged = false;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { deleteSameDeployments, purgeImagesContainers } from './cleanup';
|
|||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { delay, execShellAsync } from '../common';
|
import { delay, execShellAsync } from '../common';
|
||||||
|
|
||||||
export default async function (configuration, imageChanged) {
|
export default async function (configuration, nextStep) {
|
||||||
const generateEnvs = {};
|
const generateEnvs = {};
|
||||||
for (const secret of configuration.publish.secrets) {
|
for (const secret of configuration.publish.secrets) {
|
||||||
generateEnvs[secret.name] = secret.value;
|
generateEnvs[secret.name] = secret.value;
|
||||||
@@ -56,23 +56,25 @@ export default async function (configuration, imageChanged) {
|
|||||||
};
|
};
|
||||||
await saveAppLog('### Publishing.', configuration);
|
await saveAppLog('### Publishing.', configuration);
|
||||||
await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack));
|
await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack));
|
||||||
if (imageChanged) {
|
if (nextStep === 2) {
|
||||||
// console.log('image changed')
|
// console.log('image changed')
|
||||||
await execShellAsync(
|
await execShellAsync(
|
||||||
`docker service update --image ${containerName}:${containerTag} ${containerName}_${containerName}`
|
`docker service update --image ${containerName}:${containerTag} ${containerName}_${containerName}`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// console.log('new deployment or force deployment or config changed')
|
// console.log('new deployment or force deployment or config changed')
|
||||||
await deleteSameDeployments(configuration);
|
// if (originalDomain !== configuration.publish.domain) {
|
||||||
|
// await deleteSameDeployments(configuration, originalDomain);
|
||||||
|
// } else {
|
||||||
|
// await deleteSameDeployments(configuration);
|
||||||
|
// }
|
||||||
|
// await deleteSameDeployments(configuration);
|
||||||
await execShellAsync(
|
await execShellAsync(
|
||||||
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy --prune -c - ${containerName}`
|
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy --prune -c - ${containerName}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
async function purgeImagesAsync(found) {
|
|
||||||
await delay(10000);
|
|
||||||
await purgeImagesContainers(found, true);
|
|
||||||
}
|
|
||||||
purgeImagesAsync(configuration);
|
|
||||||
|
|
||||||
await saveAppLog('### Published done!', configuration);
|
await saveAppLog('### Published done!', configuration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { docker, streamEvents } from '$lib/api/docker';
|
import { docker, streamEvents } from '$lib/api/docker';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
|
|
||||||
const buildImageNodeDocker = (configuration, prodBuild) => {
|
const buildImageNodeDocker = (configuration, prodBuild, generateEnvs) => {
|
||||||
return [
|
return [
|
||||||
'FROM node:lts',
|
'FROM node:lts',
|
||||||
|
...generateEnvs,
|
||||||
'WORKDIR /usr/src/app',
|
'WORKDIR /usr/src/app',
|
||||||
`COPY ${configuration.build.directory}/package*.json ./`,
|
`COPY ${configuration.build.directory}/package*.json ./`,
|
||||||
configuration.build.command.installation && `RUN ${configuration.build.command.installation}`,
|
configuration.build.command.installation && `RUN ${configuration.build.command.installation}`,
|
||||||
@@ -13,15 +14,26 @@ const buildImageNodeDocker = (configuration, prodBuild) => {
|
|||||||
].join('\n');
|
].join('\n');
|
||||||
};
|
};
|
||||||
export async function buildImage(configuration, cacheBuild?: boolean, prodBuild?: boolean) {
|
export async function buildImage(configuration, cacheBuild?: boolean, prodBuild?: boolean) {
|
||||||
|
// TODO: Edit secrets
|
||||||
|
// TODO: Add secret from .env file / json
|
||||||
|
const generateEnvs = [];
|
||||||
|
const dotEnv = []
|
||||||
|
for (const secret of configuration.publish.secrets) {
|
||||||
|
dotEnv.push(`${secret.name}=${secret.value}`)
|
||||||
|
if (secret.isBuild) generateEnvs.push(`ENV ${secret.name}=${secret.value}`)
|
||||||
|
}
|
||||||
|
await fs.writeFile(
|
||||||
|
`${configuration.general.workdir}/.env`,
|
||||||
|
dotEnv.join('\n')
|
||||||
|
)
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
`${configuration.general.workdir}/Dockerfile`,
|
`${configuration.general.workdir}/Dockerfile`,
|
||||||
buildImageNodeDocker(configuration, prodBuild)
|
buildImageNodeDocker(configuration, prodBuild, generateEnvs)
|
||||||
);
|
);
|
||||||
const stream = await docker.engine.buildImage(
|
const stream = await docker.engine.buildImage(
|
||||||
{ src: ['.'], context: configuration.general.workdir },
|
{ src: ['.'], context: configuration.general.workdir },
|
||||||
{
|
{
|
||||||
t: `${configuration.build.container.name}:${
|
t: `${configuration.build.container.name}:${cacheBuild
|
||||||
cacheBuild
|
|
||||||
? `${configuration.build.container.tag}-cache`
|
? `${configuration.build.container.tag}-cache`
|
||||||
: configuration.build.container.tag
|
: configuration.build.container.tag
|
||||||
}`
|
}`
|
||||||
|
|||||||
76
src/lib/api/applications/preChecks.ts
Normal file
76
src/lib/api/applications/preChecks.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import Configuration from "$models/Configuration";
|
||||||
|
import { compareObjects, execShellAsync } from "../common";
|
||||||
|
|
||||||
|
export default async function (configuration) {
|
||||||
|
/*
|
||||||
|
0 => nothing changed, no need to redeploy
|
||||||
|
1 => force update
|
||||||
|
2 => configuration changed
|
||||||
|
3 => continue normally
|
||||||
|
*/
|
||||||
|
const currentConfiguration = await Configuration.findOne({
|
||||||
|
'general.nickname': configuration.general.nickname
|
||||||
|
})
|
||||||
|
if (currentConfiguration) {
|
||||||
|
// Base service configuration changed
|
||||||
|
if (
|
||||||
|
!currentConfiguration.build.container.baseSHA ||
|
||||||
|
currentConfiguration.build.container.baseSHA !== configuration.build.container.baseSHA
|
||||||
|
) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the deployment is in error state, forceUpdate
|
||||||
|
try {
|
||||||
|
const state = await execShellAsync(
|
||||||
|
`docker stack ps ${currentConfiguration.build.container.name} --format '{{ json . }}'`
|
||||||
|
);
|
||||||
|
const isError = state
|
||||||
|
.split('\n')
|
||||||
|
.filter((n) => n)
|
||||||
|
.map((s) => JSON.parse(s))
|
||||||
|
.filter(
|
||||||
|
(n) =>
|
||||||
|
n.DesiredState !== 'Running' && n.Image.split(':')[1] === currentConfiguration.build.container.tag
|
||||||
|
);
|
||||||
|
if (isError.length > 0) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
} catch(error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If previewDeployments enabled
|
||||||
|
if (
|
||||||
|
currentConfiguration.general.isPreviewDeploymentEnabled &&
|
||||||
|
currentConfiguration.general.pullRequest !== 0
|
||||||
|
) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
// If build pack changed, forceUpdate the service
|
||||||
|
if (currentConfiguration.build.pack !== configuration.build.pack) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentConfigurationCompare = JSON.parse(JSON.stringify(currentConfiguration));
|
||||||
|
const configurationCompare = JSON.parse(JSON.stringify(configuration));
|
||||||
|
delete currentConfigurationCompare.build.container;
|
||||||
|
delete configurationCompare.build.container;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!compareObjects(currentConfigurationCompare.build, configurationCompare.build) ||
|
||||||
|
!compareObjects(currentConfigurationCompare.publish, configurationCompare.publish) ||
|
||||||
|
currentConfigurationCompare.general.isPreviewDeploymentEnabled !==
|
||||||
|
configurationCompare.general.isPreviewDeploymentEnabled
|
||||||
|
) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConfiguration.build.container.tag !== configuration.build.container.tag) {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 3
|
||||||
|
}
|
||||||
44
src/lib/api/applications/preTasks.ts
Normal file
44
src/lib/api/applications/preTasks.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import Configuration from "$models/Configuration";
|
||||||
|
import Deployment from "$models/Deployment";
|
||||||
|
|
||||||
|
export default async function (configuration) {
|
||||||
|
// Check if deployment is already queued
|
||||||
|
const alreadyQueued = await Deployment.find({
|
||||||
|
path: configuration.publish.path,
|
||||||
|
domain: configuration.publish.domain,
|
||||||
|
progress: { $in: ['queued', 'inprogress'] }
|
||||||
|
});
|
||||||
|
if (alreadyQueued.length > 0) {
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
success: false,
|
||||||
|
message: 'Deployment already queued.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const { id, organization, name, branch } = configuration.repository;
|
||||||
|
const { domain, path } = configuration.publish;
|
||||||
|
const { deployId, nickname } = configuration.general;
|
||||||
|
// Save new deployment
|
||||||
|
await new Deployment({
|
||||||
|
repoId: id,
|
||||||
|
branch,
|
||||||
|
deployId,
|
||||||
|
domain,
|
||||||
|
organization,
|
||||||
|
name,
|
||||||
|
nickname
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
await Configuration.findOneAndUpdate(
|
||||||
|
{
|
||||||
|
'publish.domain': domain,
|
||||||
|
'publish.path': path,
|
||||||
|
'general.pullRequest': { $in: [null, 0] }
|
||||||
|
},
|
||||||
|
{ ...configuration },
|
||||||
|
{ upsert: true, new: true }
|
||||||
|
);
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -1,26 +1,28 @@
|
|||||||
import Deployment from '$models/Deployment';
|
import Deployment from '$models/Deployment';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import buildContainer from './buildContainer';
|
import buildContainer from './buildContainer';
|
||||||
|
import { purgeImagesContainers } from './cleanup';
|
||||||
import { updateServiceLabels } from './configuration';
|
import { updateServiceLabels } from './configuration';
|
||||||
import copyFiles from './copyFiles';
|
import copyFiles from './copyFiles';
|
||||||
import deploy from './deploy';
|
import deploy from './deploy';
|
||||||
import { saveAppLog } from './logging';
|
import { saveAppLog } from './logging';
|
||||||
|
|
||||||
export default async function (configuration, imageChanged) {
|
export default async function (configuration, nextStep) {
|
||||||
const { id, organization, name, branch } = configuration.repository;
|
const { id, organization, name, branch } = configuration.repository;
|
||||||
const { domain } = configuration.publish;
|
const { domain } = configuration.publish;
|
||||||
const { deployId } = configuration.general;
|
const { deployId } = configuration.general;
|
||||||
try {
|
try {
|
||||||
await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration);
|
await saveAppLog(`### Successfully queued.`, configuration);
|
||||||
await copyFiles(configuration);
|
await copyFiles(configuration);
|
||||||
await buildContainer(configuration);
|
await buildContainer(configuration);
|
||||||
await deploy(configuration, imageChanged);
|
await deploy(configuration, nextStep);
|
||||||
await Deployment.findOneAndUpdate(
|
await Deployment.findOneAndUpdate(
|
||||||
{ repoId: id, branch, deployId, organization, name, domain },
|
{ repoId: id, branch, deployId, organization, name, domain },
|
||||||
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' }
|
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await updateServiceLabels(configuration);
|
await updateServiceLabels(configuration);
|
||||||
|
await purgeImagesContainers(configuration);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await Deployment.findOneAndUpdate(
|
await Deployment.findOneAndUpdate(
|
||||||
{ repoId: id, branch, deployId, organization, name, domain },
|
{ repoId: id, branch, deployId, organization, name, domain },
|
||||||
|
|||||||
@@ -46,3 +46,27 @@ export function delay(t) {
|
|||||||
}, t);
|
}, t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function compareObjects(a, b) {
|
||||||
|
if (a === b) return true;
|
||||||
|
|
||||||
|
if (typeof a != 'object' || typeof b != 'object' || a == null || b == null) return false;
|
||||||
|
|
||||||
|
const keysA = Object.keys(a),
|
||||||
|
keysB = Object.keys(b);
|
||||||
|
|
||||||
|
if (keysA.length != keysB.length) return false;
|
||||||
|
|
||||||
|
for (const key of keysA) {
|
||||||
|
if (!keysB.includes(key)) return false;
|
||||||
|
|
||||||
|
if (typeof a[key] === 'function' || typeof b[key] === 'function') {
|
||||||
|
if (a[key].toString() != b[key].toString()) return false;
|
||||||
|
} else {
|
||||||
|
if (!compareObjects(a[key], b[key])) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
9
src/lib/common.ts
Normal file
9
src/lib/common.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function dashify(str: string, options?: any) {
|
||||||
|
if (typeof str !== 'string') return str;
|
||||||
|
return str
|
||||||
|
.trim()
|
||||||
|
.replace(/\W/g, (m) => (/[À-ž]/.test(m) ? m : '-'))
|
||||||
|
.replace(/^-+|-+$/g, '')
|
||||||
|
.replace(/-{2,}/g, (m) => (options && options.condense ? '-' : m))
|
||||||
|
.toLowerCase();
|
||||||
|
}
|
||||||
@@ -1,2 +1,8 @@
|
|||||||
export const publicPages = ['/', '/api/v1/login/github/app', '/api/v1/webhooks/deploy', '/success'];
|
export const publicPages = [
|
||||||
|
'/',
|
||||||
|
'/api/v1/login/github/app',
|
||||||
|
'/api/v1/webhooks/deploy',
|
||||||
|
'/success',
|
||||||
|
'/api/v1/login/email'
|
||||||
|
];
|
||||||
export const VITE_GITHUB_APP_NAME = import.meta.env.VITE_GITHUB_APP_NAME;
|
export const VITE_GITHUB_APP_NAME = import.meta.env.VITE_GITHUB_APP_NAME;
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ const ConfigurationSchema = new Schema({
|
|||||||
domain: { type: String, required: true },
|
domain: { type: String, required: true },
|
||||||
path: { type: String },
|
path: { type: String },
|
||||||
port: { type: Number },
|
port: { type: Number },
|
||||||
secrets: { type: Array }
|
secrets: [{
|
||||||
|
name: { type: String },
|
||||||
|
value: { type: String },
|
||||||
|
isBuild: { type: Boolean, default: false },
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ export interface IUser extends Document {
|
|||||||
email: string;
|
email: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
uid: string;
|
uid: string;
|
||||||
|
type: string;
|
||||||
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserSchema = new Schema({
|
const UserSchema = new Schema({
|
||||||
email: { type: String, required: true, unique: true },
|
email: { type: String, required: true, unique: true },
|
||||||
avatar: { type: String },
|
avatar: { type: String },
|
||||||
uid: { type: String, required: true }
|
uid: { type: String, required: true },
|
||||||
|
type: { type: String, required: true, default: 'github' },
|
||||||
|
password: { type: String }
|
||||||
});
|
});
|
||||||
|
|
||||||
UserSchema.set('timestamps', true);
|
UserSchema.set('timestamps', true);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
if (!publicPages.includes(path)) {
|
if (!publicPages.includes(path)) {
|
||||||
if (!session.session.isLoggedIn) {
|
if (!session.session.isLoggedIn) {
|
||||||
return {
|
return {
|
||||||
status: 301,
|
status: 302,
|
||||||
redirect: '/'
|
redirect: '/'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -17,16 +17,16 @@
|
|||||||
}
|
}
|
||||||
if (!publicPages.includes(path)) {
|
if (!publicPages.includes(path)) {
|
||||||
return {
|
return {
|
||||||
status: 301,
|
status: 302,
|
||||||
redirect: '/'
|
redirect: '/'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import 'microtip/microtip.css';
|
||||||
import '../app.postcss';
|
import '../app.postcss';
|
||||||
export let initDashboard;
|
export let initDashboard;
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
@@ -37,8 +37,9 @@
|
|||||||
import Tooltip from '$components/Tooltip.svelte';
|
import Tooltip from '$components/Tooltip.svelte';
|
||||||
import compareVersions from 'compare-versions';
|
import compareVersions from 'compare-versions';
|
||||||
import packageJson from '../../package.json';
|
import packageJson from '../../package.json';
|
||||||
import { dashboard } from '$store';
|
import { dashboard, settings } from '$store';
|
||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
|
$settings.clientId = import.meta.env.VITE_GITHUB_APP_CLIENTID !== 'null' ? import.meta.env.VITE_GITHUB_APP_CLIENTID : null
|
||||||
$dashboard = initDashboard;
|
$dashboard = initDashboard;
|
||||||
const branch =
|
const branch =
|
||||||
process.env.NODE_ENV === 'production' &&
|
process.env.NODE_ENV === 'production' &&
|
||||||
@@ -53,7 +54,7 @@
|
|||||||
let upgradeDisabled = false;
|
let upgradeDisabled = false;
|
||||||
let upgradeDone = false;
|
let upgradeDone = false;
|
||||||
let showAck = false;
|
let showAck = false;
|
||||||
let globalFeatureFlag = browser && localStorage.getItem('globalFeatureFlag')
|
let globalFeatureFlag = browser && localStorage.getItem('globalFeatureFlag');
|
||||||
const options = {
|
const options = {
|
||||||
duration: 2000
|
duration: 2000
|
||||||
};
|
};
|
||||||
@@ -104,7 +105,6 @@
|
|||||||
localStorage.setItem('automaticErrorReportsAck', 'true');
|
localStorage.setItem('automaticErrorReportsAck', 'true');
|
||||||
showAck = false;
|
showAck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SvelteToast {options} />
|
<SvelteToast {options} />
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
class:border-purple-500={$page.path === '/dashboard/databases'}
|
class:border-purple-500={$page.path === '/dashboard/databases'}
|
||||||
>
|
>
|
||||||
<div class="w-10 pt-4 pb-4"><img src="/favicon.png" alt="coolLabs logo" /></div>
|
<div class="w-10 pt-4 pb-4"><img src="/favicon.png" alt="coolLabs logo" /></div>
|
||||||
|
{#if $settings.clientId}
|
||||||
<Tooltip position="right" label="Applications">
|
<Tooltip position="right" label="Applications">
|
||||||
<div
|
<div
|
||||||
class="p-2 hover:bg-warmGray-700 rounded hover:text-green-500 mt-4 transition-all duration-100 cursor-pointer"
|
class="p-2 hover:bg-warmGray-700 rounded hover:text-green-500 mt-4 transition-all duration-100 cursor-pointer"
|
||||||
@@ -165,12 +165,17 @@
|
|||||||
y1="20"
|
y1="20"
|
||||||
x2="9"
|
x2="9"
|
||||||
y2="23"
|
y2="23"
|
||||||
/><line x1="15" y1="20" x2="15" y2="23" /><line x1="20" y1="9" x2="23" y2="9" /><line
|
/><line x1="15" y1="20" x2="15" y2="23" /><line
|
||||||
x1="20"
|
x1="20"
|
||||||
y1="14"
|
y1="9"
|
||||||
x2="23"
|
x2="23"
|
||||||
|
y2="9"
|
||||||
|
/><line x1="20" y1="14" x2="23" y2="14" /><line x1="1" y1="9" x2="4" y2="9" /><line
|
||||||
|
x1="1"
|
||||||
|
y1="14"
|
||||||
|
x2="4"
|
||||||
y2="14"
|
y2="14"
|
||||||
/><line x1="1" y1="9" x2="4" y2="9" /><line x1="1" y1="14" x2="4" y2="14" /></svg
|
/></svg
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -199,6 +204,68 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
{:else}
|
||||||
|
<Tooltip
|
||||||
|
position="right"
|
||||||
|
label="Applications disabled, no GitHub Integration detected"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
<div class="p-2 text-warmGray-700 mt-4 transition-all duration-100 cursor-pointer">
|
||||||
|
<svg
|
||||||
|
class="w-8"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
><rect x="4" y="4" width="16" height="16" rx="2" ry="2" /><rect
|
||||||
|
x="9"
|
||||||
|
y="9"
|
||||||
|
width="6"
|
||||||
|
height="6"
|
||||||
|
/><line x1="9" y1="1" x2="9" y2="4" /><line x1="15" y1="1" x2="15" y2="4" /><line
|
||||||
|
x1="9"
|
||||||
|
y1="20"
|
||||||
|
x2="9"
|
||||||
|
y2="23"
|
||||||
|
/><line x1="15" y1="20" x2="15" y2="23" /><line
|
||||||
|
x1="20"
|
||||||
|
y1="9"
|
||||||
|
x2="23"
|
||||||
|
y2="9"
|
||||||
|
/><line x1="20" y1="14" x2="23" y2="14" /><line x1="1" y1="9" x2="4" y2="9" /><line
|
||||||
|
x1="1"
|
||||||
|
y1="14"
|
||||||
|
x2="4"
|
||||||
|
y2="14"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip position="right" label="Databases disabled, no GitHub Integration detected" size="large">
|
||||||
|
<div
|
||||||
|
class="p-2 text-warmGray-700 my-4 transition-all duration-100 cursor-pointer"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-8"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<Tooltip position="right" label="Services">
|
<Tooltip position="right" label="Services">
|
||||||
<div
|
<div
|
||||||
class="p-2 hover:bg-warmGray-700 rounded hover:text-blue-500 transition-all duration-100 cursor-pointer"
|
class="p-2 hover:bg-warmGray-700 rounded hover:text-blue-500 transition-all duration-100 cursor-pointer"
|
||||||
@@ -226,7 +293,7 @@
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<div class="flex-1" />
|
<div class="flex-1" />
|
||||||
{#if globalFeatureFlag}
|
{#if globalFeatureFlag}
|
||||||
<Tooltip position="right" label="Server(s)">
|
<Tooltip position="right" label="Servers">
|
||||||
<div
|
<div
|
||||||
class="p-2 hover:bg-warmGray-700 rounded hover:text-red-500 mb-4 transition-all duration-100 cursor-pointer"
|
class="p-2 hover:bg-warmGray-700 rounded hover:text-red-500 mb-4 transition-all duration-100 cursor-pointer"
|
||||||
on:click={() => goto('/servers')}
|
on:click={() => goto('/servers')}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { setDefaultConfiguration } from '$lib/api/applications/configuration';
|
import { setDefaultConfiguration } from '$lib/api/applications/configuration';
|
||||||
import { saveServerLog } from '$lib/api/applications/logging';
|
import { saveServerLog } from '$lib/api/applications/logging';
|
||||||
import { docker } from '$lib/api/docker';
|
|
||||||
import Configuration from '$models/Configuration';
|
import Configuration from '$models/Configuration';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
@@ -8,16 +7,16 @@ export async function post(request: Request) {
|
|||||||
try {
|
try {
|
||||||
const { DOMAIN } = process.env;
|
const { DOMAIN } = process.env;
|
||||||
const configuration = setDefaultConfiguration(request.body);
|
const configuration = setDefaultConfiguration(request.body);
|
||||||
const configurationFound = await Configuration.find({
|
const sameDomainAndPath = await Configuration.find({
|
||||||
'repository.id': { $ne: configuration.repository.id },
|
'publish.path': configuration.publish.path,
|
||||||
'publish.domain': configuration.publish.domain
|
'publish.domain': configuration.publish.domain
|
||||||
}).select('-_id -__v -createdAt -updatedAt');
|
}).select('-_id -__v -createdAt -updatedAt');
|
||||||
if (configurationFound.length > 0 || configuration.publish.domain === DOMAIN) {
|
if (sameDomainAndPath.length > 1 || configuration.publish.domain === DOMAIN) {
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Domain already in use.'
|
message: 'Domain/path are already in use.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3,14 +3,11 @@ import Configuration from '$models/Configuration';
|
|||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
const { name, organization, branch }: any = request.body || {};
|
const { nickname }: any = request.body || {};
|
||||||
if (name && organization && branch) {
|
if (nickname) {
|
||||||
const configurationFound = await Configuration.find({
|
const configurationFound = await Configuration.find({
|
||||||
'repository.name': name,
|
'general.nickname': nickname
|
||||||
'repository.organization': organization,
|
|
||||||
'repository.branch': branch
|
|
||||||
}).select('-_id -__v -createdAt -updatedAt');
|
}).select('-_id -__v -createdAt -updatedAt');
|
||||||
|
|
||||||
if (configurationFound) {
|
if (configurationFound) {
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
@@ -28,22 +25,8 @@ export async function post(request: Request) {
|
|||||||
const configuration = r.Spec.Labels.configuration
|
const configuration = r.Spec.Labels.configuration
|
||||||
? JSON.parse(r.Spec.Labels.configuration)
|
? JSON.parse(r.Spec.Labels.configuration)
|
||||||
: null;
|
: null;
|
||||||
if (branch) {
|
|
||||||
if (
|
if (configuration.general.nickname === nickname) return r;
|
||||||
configuration.repository.name === name &&
|
|
||||||
configuration.repository.organization === organization &&
|
|
||||||
configuration.repository.branch === branch
|
|
||||||
) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
configuration.repository.name === name &&
|
|
||||||
configuration.repository.organization === organization
|
|
||||||
) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import cloneRepository from '$lib/api/applications/cloneRepository';
|
|||||||
import { cleanupTmp } from '$lib/api/common';
|
import { cleanupTmp } from '$lib/api/common';
|
||||||
import queueAndBuild from '$lib/api/applications/queueAndBuild';
|
import queueAndBuild from '$lib/api/applications/queueAndBuild';
|
||||||
import Configuration from '$models/Configuration';
|
import Configuration from '$models/Configuration';
|
||||||
|
import preChecks from '$lib/api/applications/preChecks';
|
||||||
|
import preTasks from '$lib/api/applications/preTasks';
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
const configuration = setDefaultConfiguration(request.body);
|
const configuration = setDefaultConfiguration(request.body);
|
||||||
@@ -18,10 +20,8 @@ export async function post(request: Request) {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await cloneRepository(configuration);
|
await cloneRepository(configuration);
|
||||||
const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment(
|
const nextStep = await preChecks(configuration);
|
||||||
configuration
|
if (nextStep === 0) {
|
||||||
);
|
|
||||||
if (foundService && !forceUpdate && !imageChanged && !configChanged) {
|
|
||||||
cleanupTmp(configuration.general.workdir);
|
cleanupTmp(configuration.general.workdir);
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
@@ -31,50 +31,9 @@ export async function post(request: Request) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const alreadyQueued = await Deployment.find({
|
await preTasks(configuration)
|
||||||
repoId: configuration.repository.id,
|
|
||||||
branch: configuration.repository.branch,
|
|
||||||
organization: configuration.repository.organization,
|
|
||||||
name: configuration.repository.name,
|
|
||||||
domain: configuration.publish.domain,
|
|
||||||
progress: { $in: ['queued', 'inprogress'] }
|
|
||||||
});
|
|
||||||
if (alreadyQueued.length > 0) {
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
body: {
|
|
||||||
success: false,
|
|
||||||
message: 'Already in the queue.'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { id, organization, name, branch } = configuration.repository;
|
|
||||||
const { domain } = configuration.publish;
|
|
||||||
const { deployId, nickname, pullRequest } = configuration.general;
|
|
||||||
|
|
||||||
await new Deployment({
|
queueAndBuild(configuration, nextStep);
|
||||||
repoId: id,
|
|
||||||
branch,
|
|
||||||
deployId,
|
|
||||||
domain,
|
|
||||||
organization,
|
|
||||||
name,
|
|
||||||
nickname
|
|
||||||
}).save();
|
|
||||||
|
|
||||||
await Configuration.findOneAndUpdate(
|
|
||||||
{
|
|
||||||
'repository.id': id,
|
|
||||||
'repository.organization': organization,
|
|
||||||
'repository.name': name,
|
|
||||||
'repository.branch': branch,
|
|
||||||
'general.pullRequest': { $in: [null, 0] }
|
|
||||||
},
|
|
||||||
{ ...configuration },
|
|
||||||
{ upsert: true, new: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
queueAndBuild(configuration, imageChanged);
|
|
||||||
return {
|
return {
|
||||||
status: 201,
|
status: 201,
|
||||||
body: {
|
body: {
|
||||||
@@ -86,23 +45,7 @@ export async function post(request: Request) {
|
|||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
await Deployment.findOneAndUpdate(
|
await Deployment.findOneAndUpdate({ nickname: configuration.general.nickname }, { $set: { progress: 'failed' } });
|
||||||
{
|
|
||||||
repoId: configuration.repository.id,
|
|
||||||
branch: configuration.repository.branch,
|
|
||||||
organization: configuration.repository.organization,
|
|
||||||
name: configuration.repository.name,
|
|
||||||
domain: configuration.publish.domain
|
|
||||||
},
|
|
||||||
{
|
|
||||||
repoId: configuration.repository.id,
|
|
||||||
branch: configuration.repository.branch,
|
|
||||||
organization: configuration.repository.organization,
|
|
||||||
name: configuration.repository.name,
|
|
||||||
domain: configuration.publish.domain,
|
|
||||||
progress: 'failed'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return {
|
return {
|
||||||
status: 500,
|
status: 500,
|
||||||
body: {
|
body: {
|
||||||
|
|||||||
@@ -4,63 +4,47 @@ import ApplicationLog from '$models/ApplicationLog';
|
|||||||
import { delay, execShellAsync } from '$lib/api/common';
|
import { delay, execShellAsync } from '$lib/api/common';
|
||||||
import Configuration from '$models/Configuration';
|
import Configuration from '$models/Configuration';
|
||||||
|
|
||||||
async function purgeImagesAsync(found) {
|
|
||||||
await delay(10000);
|
|
||||||
await purgeImagesContainers(found, true);
|
|
||||||
}
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
const { organization, name, branch, domain } = request.body;
|
const { nickname } = request.body;
|
||||||
try {
|
try {
|
||||||
const configurationFound = await Configuration.findOne({
|
const configurationFound = await Configuration.findOne({
|
||||||
'repository.organization': organization,
|
'general.nickname': nickname
|
||||||
'repository.name': name,
|
|
||||||
'repository.branch': branch,
|
|
||||||
'publish.domain': domain
|
|
||||||
});
|
});
|
||||||
if (configurationFound) {
|
if (configurationFound) {
|
||||||
const id = configurationFound._id;
|
const id = configurationFound._id;
|
||||||
if (configurationFound?.general?.pullRequest === 0) {
|
if (configurationFound?.general?.pullRequest === 0) {
|
||||||
// Main deployment deletion request; deleting main + PRs
|
// Main deployment deletion request; deleting main + PRs
|
||||||
const allConfiguration = await Configuration.find({
|
const allConfiguration = await Configuration.find({
|
||||||
'repository.name': name,
|
'publish.domain': { $regex: `.*${configurationFound.publish.domain}`, $options: 'i' },
|
||||||
'repository.organization': organization,
|
'publish.path': configurationFound.publish.path
|
||||||
'repository.branch': branch
|
|
||||||
});
|
});
|
||||||
for (const config of allConfiguration) {
|
for (const config of allConfiguration) {
|
||||||
await Configuration.findOneAndRemove({
|
|
||||||
'repository.name': config.repository.name,
|
|
||||||
'repository.organization': config.repository.organization,
|
|
||||||
'repository.branch': config.repository.branch
|
|
||||||
});
|
|
||||||
await execShellAsync(`docker stack rm ${config.build.container.name}`);
|
await execShellAsync(`docker stack rm ${config.build.container.name}`);
|
||||||
}
|
}
|
||||||
const deploys = await Deployment.find({ organization, branch, name });
|
await Configuration.deleteMany({
|
||||||
|
'publish.domain': { $regex: `.*${configurationFound.publish.domain}`, $options: 'i' },
|
||||||
|
'publish.path': configurationFound.publish.path
|
||||||
|
});
|
||||||
|
const deploys = await Deployment.find({ nickname });
|
||||||
for (const deploy of deploys) {
|
for (const deploy of deploys) {
|
||||||
await ApplicationLog.deleteMany({ deployId: deploy.deployId });
|
await ApplicationLog.deleteMany({ deployId: deploy.deployId });
|
||||||
await Deployment.deleteMany({ deployId: deploy.deployId });
|
await Deployment.deleteMany({ deployId: deploy.deployId });
|
||||||
}
|
}
|
||||||
|
|
||||||
purgeImagesAsync(configurationFound);
|
|
||||||
} else {
|
} else {
|
||||||
// Delete only PRs
|
// Delete only PRs
|
||||||
await Configuration.findByIdAndRemove(id);
|
await Configuration.findByIdAndRemove(id);
|
||||||
await execShellAsync(`docker stack rm ${configurationFound.build.container.name}`);
|
await execShellAsync(`docker stack rm ${configurationFound.build.container.name}`);
|
||||||
const deploys = await Deployment.find({ organization, branch, name, domain });
|
const deploys = await Deployment.find({ nickname });
|
||||||
for (const deploy of deploys) {
|
for (const deploy of deploys) {
|
||||||
await ApplicationLog.deleteMany({ deployId: deploy.deployId });
|
await ApplicationLog.deleteMany({ deployId: deploy.deployId });
|
||||||
await Deployment.deleteMany({ deployId: deploy.deployId });
|
await Deployment.deleteMany({ deployId: deploy.deployId });
|
||||||
}
|
}
|
||||||
purgeImagesAsync(configurationFound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {}
|
||||||
organization,
|
|
||||||
name,
|
|
||||||
branch
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
104
src/routes/api/v1/login/email.ts
Normal file
104
src/routes/api/v1/login/email.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
import Settings from '$models/Settings';
|
||||||
|
import User from '$models/User';
|
||||||
|
import bcrypt from 'bcrypt';
|
||||||
|
import cuid from 'cuid';
|
||||||
|
import jsonwebtoken from 'jsonwebtoken';
|
||||||
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
const saltRounds = 15;
|
||||||
|
|
||||||
|
export async function post(request: Request) {
|
||||||
|
const { email, password } = request.body;
|
||||||
|
const { JWT_SIGN_KEY } = process.env;
|
||||||
|
const settings = await Settings.findOne({ applicationName: 'coolify' });
|
||||||
|
const registeredUsers = await User.find().countDocuments();
|
||||||
|
const foundUser = await User.findOne({ email });
|
||||||
|
try {
|
||||||
|
let uid = cuid();
|
||||||
|
if (foundUser) {
|
||||||
|
if (foundUser.type === 'github') {
|
||||||
|
return {
|
||||||
|
status: 500,
|
||||||
|
body: {
|
||||||
|
error: 'Wrong password or email address.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
uid = foundUser.uid;
|
||||||
|
if (!(await bcrypt.compare(password, foundUser.password))) {
|
||||||
|
return {
|
||||||
|
status: 500,
|
||||||
|
body: {
|
||||||
|
error: 'Wrong password or email address.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (registeredUsers === 0) {
|
||||||
|
const newUser = new User({
|
||||||
|
_id: new mongoose.Types.ObjectId(),
|
||||||
|
email,
|
||||||
|
uid,
|
||||||
|
type: 'email',
|
||||||
|
password: await bcrypt.hash(password, saltRounds)
|
||||||
|
});
|
||||||
|
const defaultSettings = new Settings({
|
||||||
|
_id: new mongoose.Types.ObjectId()
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await newUser.save();
|
||||||
|
await defaultSettings.save();
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 500,
|
||||||
|
error: error.message || error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!settings?.allowRegistration) {
|
||||||
|
return {
|
||||||
|
status: 500,
|
||||||
|
body: {
|
||||||
|
error: 'Registration disabled, enable it in settings.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const newUser = new User({
|
||||||
|
_id: new mongoose.Types.ObjectId(),
|
||||||
|
email,
|
||||||
|
uid,
|
||||||
|
type: 'email',
|
||||||
|
password: await bcrypt.hash(password, saltRounds)
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await newUser.save();
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 500,
|
||||||
|
error: error.message || error
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const coolToken = jsonwebtoken.sign({}, JWT_SIGN_KEY, {
|
||||||
|
expiresIn: 15778800,
|
||||||
|
algorithm: 'HS256',
|
||||||
|
audience: 'coolLabs',
|
||||||
|
issuer: 'coolLabs',
|
||||||
|
jwtid: uid,
|
||||||
|
subject: `User:${uid}`,
|
||||||
|
notBefore: -1000
|
||||||
|
});
|
||||||
|
request.locals.session.data = { coolToken, ghToken: null };
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
message: 'Successfully logged in.'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { status: 500, body: { error: error.message || error } };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,8 @@ export async function get(request: Request) {
|
|||||||
_id: new mongoose.Types.ObjectId(),
|
_id: new mongoose.Types.ObjectId(),
|
||||||
email,
|
email,
|
||||||
avatar: avatar_url,
|
avatar: avatar_url,
|
||||||
uid
|
uid,
|
||||||
|
type: 'github'
|
||||||
});
|
});
|
||||||
const defaultSettings = new Settings({
|
const defaultSettings = new Settings({
|
||||||
_id: new mongoose.Types.ObjectId()
|
_id: new mongoose.Types.ObjectId()
|
||||||
@@ -68,7 +69,8 @@ export async function get(request: Request) {
|
|||||||
_id: new mongoose.Types.ObjectId(),
|
_id: new mongoose.Types.ObjectId(),
|
||||||
email,
|
email,
|
||||||
avatar: avatar_url,
|
avatar: avatar_url,
|
||||||
uid
|
uid,
|
||||||
|
type: 'github'
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await newUser.save();
|
await newUser.save();
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
export async function del(request: Request) {
|
export async function del(request: Request) {
|
||||||
request.locals.session.destroy = true;
|
request.locals.session.destroy()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
body: {
|
body: {
|
||||||
ok: true
|
ok: true
|
||||||
|
|||||||
@@ -2,17 +2,19 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
try {
|
try {
|
||||||
const output = await execShellAsync('docker builder prune -af')
|
const output = await execShellAsync('docker builder prune -af');
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
message: 'OK',
|
message: 'OK',
|
||||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
output: output
|
||||||
}
|
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||||
|
.split('\n')
|
||||||
|
.pop()
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await saveServerLog(error);
|
await saveServerLog(error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,17 +2,19 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
try {
|
try {
|
||||||
const output = await execShellAsync('docker container prune -f')
|
const output = await execShellAsync('docker container prune -f');
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
message: 'OK',
|
message: 'OK',
|
||||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
output: output
|
||||||
}
|
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||||
|
.split('\n')
|
||||||
|
.pop()
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await saveServerLog(error);
|
await saveServerLog(error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,17 +2,19 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
try {
|
try {
|
||||||
const output = await execShellAsync('docker image prune -af')
|
const output = await execShellAsync('docker image prune -af');
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
message: 'OK',
|
message: 'OK',
|
||||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
output: output
|
||||||
}
|
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||||
|
.split('\n')
|
||||||
|
.pop()
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await saveServerLog(error);
|
await saveServerLog(error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,17 +2,19 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
|
||||||
export async function post(request: Request) {
|
export async function post(request: Request) {
|
||||||
try {
|
try {
|
||||||
const output = await execShellAsync('docker volume prune -f')
|
const output = await execShellAsync('docker volume prune -f');
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
message: 'OK',
|
message: 'OK',
|
||||||
output: output.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm,"").split('\n').pop()
|
output: output
|
||||||
}
|
.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, '')
|
||||||
|
.split('\n')
|
||||||
|
.pop()
|
||||||
}
|
}
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await saveServerLog(error);
|
await saveServerLog(error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -2,26 +2,26 @@ import { saveServerLog } from '$lib/api/applications/logging';
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import { docker } from '$lib/api/docker';
|
import { docker } from '$lib/api/docker';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
import systeminformation from 'systeminformation'
|
import systeminformation from 'systeminformation';
|
||||||
|
|
||||||
export async function get(request: Request) {
|
export async function get(request: Request) {
|
||||||
try {
|
try {
|
||||||
const df = await execShellAsync(
|
const df = await execShellAsync(`docker system df --format '{{ json . }}'`);
|
||||||
`docker system df --format '{{ json . }}'`
|
|
||||||
);
|
|
||||||
const dockerReclaimable = df
|
const dockerReclaimable = df
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.filter((n) => n)
|
.filter((n) => n)
|
||||||
.map((s) => JSON.parse(s))
|
.map((s) => JSON.parse(s));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
hostname: await (await systeminformation.osInfo()).hostname,
|
hostname: await (await systeminformation.osInfo()).hostname,
|
||||||
filesystems: await (await systeminformation.fsSize()).filter(fs => !fs.fs.match('/dev/loop') || !fs.fs.match('/var/lib/docker/')),
|
filesystems: await (
|
||||||
|
await systeminformation.fsSize()
|
||||||
|
).filter((fs) => !fs.fs.match('/dev/loop') || !fs.fs.match('/var/lib/docker/')),
|
||||||
dockerReclaimable
|
dockerReclaimable
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await saveServerLog(error);
|
await saveServerLog(error);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ export async function post(request: Request) {
|
|||||||
volumes: {
|
volumes: {
|
||||||
[`${deployId}-code-server-data`]: {
|
[`${deployId}-code-server-data`]: {
|
||||||
external: true
|
external: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
await execShellAsync(`mkdir -p ${workdir}`);
|
await execShellAsync(`mkdir -p ${workdir}`);
|
||||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { execShellAsync } from '$lib/api/common';
|
import { execShellAsync } from '$lib/api/common';
|
||||||
import type { Request } from '@sveltejs/kit';
|
import type { Request } from '@sveltejs/kit';
|
||||||
import yaml from "js-yaml"
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
export async function get(request: Request) {
|
export async function get(request: Request) {
|
||||||
// const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse(
|
// const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse(
|
||||||
@@ -15,9 +15,11 @@ export async function get(request: Request) {
|
|||||||
.trim()
|
.trim()
|
||||||
.split('\n');
|
.split('\n');
|
||||||
const codeServer = containers.find((container) => container.startsWith('code-server'));
|
const codeServer = containers.find((container) => container.startsWith('code-server'));
|
||||||
const configYaml = yaml.load(await execShellAsync(
|
const configYaml = yaml.load(
|
||||||
|
await execShellAsync(
|
||||||
`docker exec ${codeServer} cat /home/coder/.config/code-server/config.yaml`
|
`docker exec ${codeServer} cat /home/coder/.config/code-server/config.yaml`
|
||||||
))
|
)
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: { message: 'OK', password: configYaml.password }
|
body: { message: 'OK', password: configYaml.password }
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ export async function post(request: Request) {
|
|||||||
const workdir = '/tmp/minio';
|
const workdir = '/tmp/minio';
|
||||||
const deployId = 'minio';
|
const deployId = 'minio';
|
||||||
const secrets = [
|
const secrets = [
|
||||||
{ name: 'MINIO_ROOT_USER', value: generator.generate({ length: 12, numbers: true, strict: true }) },
|
{
|
||||||
{ name: 'MINIO_ROOT_PASSWORD', value: generator.generate({ length: 24, numbers: true, strict: true }) }
|
name: 'MINIO_ROOT_USER',
|
||||||
|
value: generator.generate({ length: 12, numbers: true, strict: true })
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'MINIO_ROOT_PASSWORD',
|
||||||
|
value: generator.generate({ length: 24, numbers: true, strict: true })
|
||||||
|
}
|
||||||
];
|
];
|
||||||
const generateEnvsMinIO = {};
|
const generateEnvsMinIO = {};
|
||||||
for (const secret of secrets) generateEnvsMinIO[secret.name] = secret.value;
|
for (const secret of secrets) generateEnvsMinIO[secret.name] = secret.value;
|
||||||
@@ -62,8 +67,8 @@ export async function post(request: Request) {
|
|||||||
volumes: {
|
volumes: {
|
||||||
[`${deployId}-minio-data`]: {
|
[`${deployId}-minio-data`]: {
|
||||||
external: true
|
external: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
await execShellAsync(`mkdir -p ${workdir}`);
|
await execShellAsync(`mkdir -p ${workdir}`);
|
||||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||||
|
|||||||
@@ -10,16 +10,18 @@ export async function post(request: Request) {
|
|||||||
let { baseURL, remoteDB, database, wordpressExtraConfiguration } = request.body;
|
let { baseURL, remoteDB, database, wordpressExtraConfiguration } = request.body;
|
||||||
const traefikURL = baseURL;
|
const traefikURL = baseURL;
|
||||||
baseURL = `https://${baseURL}`;
|
baseURL = `https://${baseURL}`;
|
||||||
console.log({ baseURL, remoteDB, database, wordpressExtraConfiguration })
|
|
||||||
|
|
||||||
const workdir = '/tmp/wordpress';
|
const workdir = '/tmp/wordpress';
|
||||||
const deployId = `wp-${generator.generate({ length: 5, numbers: true, strict: true })}`
|
const deployId = `wp-${generator.generate({ length: 5, numbers: true, strict: true })}`;
|
||||||
const defaultDatabaseName = generator.generate({ length: 12, numbers: true, strict: true })
|
const defaultDatabaseName = generator.generate({ length: 12, numbers: true, strict: true });
|
||||||
const defaultDatabaseHost = `${deployId}-mysql`
|
const defaultDatabaseHost = `${deployId}-mysql`;
|
||||||
const defaultDatabaseUser = generator.generate({ length: 12, numbers: true, strict: true })
|
const defaultDatabaseUser = generator.generate({ length: 12, numbers: true, strict: true });
|
||||||
const defaultDatabasePassword = generator.generate({ length: 24, numbers: true, strict: true })
|
const defaultDatabasePassword = generator.generate({ length: 24, numbers: true, strict: true });
|
||||||
const defaultDatabaseRootPassword = generator.generate({ length: 24, numbers: true, strict: true })
|
const defaultDatabaseRootPassword = generator.generate({
|
||||||
const defaultDatabaseRootUser = generator.generate({ length: 12, numbers: true, strict: true })
|
length: 24,
|
||||||
|
numbers: true,
|
||||||
|
strict: true
|
||||||
|
});
|
||||||
|
const defaultDatabaseRootUser = generator.generate({ length: 12, numbers: true, strict: true });
|
||||||
let secrets = [
|
let secrets = [
|
||||||
{ name: 'WORDPRESS_DB_HOST', value: defaultDatabaseHost },
|
{ name: 'WORDPRESS_DB_HOST', value: defaultDatabaseHost },
|
||||||
{ name: 'WORDPRESS_DB_USER', value: defaultDatabaseUser },
|
{ name: 'WORDPRESS_DB_USER', value: defaultDatabaseUser },
|
||||||
@@ -46,7 +48,7 @@ export async function post(request: Request) {
|
|||||||
{ name: 'WORDPRESS_DB_NAME', value: database.name },
|
{ name: 'WORDPRESS_DB_NAME', value: database.name },
|
||||||
{ name: 'WORDPRESS_TABLE_PREFIX', value: database.tablePrefix },
|
{ name: 'WORDPRESS_TABLE_PREFIX', value: database.tablePrefix },
|
||||||
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
{ name: 'WORDPRESS_CONFIG_EXTRA', value: wordpressExtraConfiguration }
|
||||||
]
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateEnvsWordpress = {};
|
const generateEnvsWordpress = {};
|
||||||
@@ -91,11 +93,7 @@ export async function post(request: Request) {
|
|||||||
volumes: [volume],
|
volumes: [volume],
|
||||||
deploy: {
|
deploy: {
|
||||||
...baseServiceConfiguration,
|
...baseServiceConfiguration,
|
||||||
labels: [
|
labels: ['managedBy=coolify', 'type=service', 'serviceName=' + deployId]
|
||||||
'managedBy=coolify',
|
|
||||||
'type=service',
|
|
||||||
'serviceName=' + deployId,
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -111,7 +109,7 @@ export async function post(request: Request) {
|
|||||||
[`${deployId}-mysql-data`]: {
|
[`${deployId}-mysql-data`]: {
|
||||||
external: true
|
external: true
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
if (remoteDB) {
|
if (remoteDB) {
|
||||||
stack = {
|
stack = {
|
||||||
@@ -157,10 +155,9 @@ export async function post(request: Request) {
|
|||||||
[`${deployId}-wordpress-data`]: {
|
[`${deployId}-wordpress-data`]: {
|
||||||
external: true
|
external: true
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
console.log(stack)
|
|
||||||
await execShellAsync(`mkdir -p ${workdir}`);
|
await execShellAsync(`mkdir -p ${workdir}`);
|
||||||
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack));
|
||||||
await execShellAsync(`docker stack rm ${deployId}`);
|
await execShellAsync(`docker stack rm ${deployId}`);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export async function post(request: Request) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Monorepo support here. Find all configurations by id and update all deployments! Tough!
|
||||||
try {
|
try {
|
||||||
const applications = await Configuration.find({
|
const applications = await Configuration.find({
|
||||||
'repository.id': request.body.repository.id
|
'repository.id': request.body.repository.id
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
|
<script context="module" lang="ts">
|
||||||
|
/**
|
||||||
|
* @type {import('@sveltejs/kit').Load}
|
||||||
|
*/
|
||||||
|
export async function load(session) {
|
||||||
|
if (!browser) {
|
||||||
|
if (!import.meta.env.VITE_GITHUB_APP_CLIENTID) {
|
||||||
|
return {
|
||||||
|
status: 302,
|
||||||
|
redirect: '/dashboard/services'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { application, initialApplication, initConf, dashboard, prApplication } from '$store';
|
import { application, initialApplication, initConf, dashboard, prApplication, originalDomain } from '$store';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import Loading from '$components/Loading.svelte';
|
import Loading from '$components/Loading.svelte';
|
||||||
import Navbar from '$components/Application/Navbar.svelte';
|
import Navbar from '$components/Application/Navbar.svelte';
|
||||||
@@ -8,17 +25,12 @@
|
|||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
import { request } from '$lib/request';
|
import { request } from '$lib/request';
|
||||||
|
|
||||||
$application.repository.organization = $page.params.organization;
|
$application.general.nickname = $page.params.nickname;
|
||||||
$application.repository.name = $page.params.name;
|
|
||||||
$application.repository.branch = $page.params.branch;
|
|
||||||
|
|
||||||
async function setConfiguration() {
|
async function setConfiguration() {
|
||||||
try {
|
try {
|
||||||
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
const { configuration } = await request(`/api/v1/application/config`, $session, {
|
||||||
body: {
|
body: {
|
||||||
name: $application.repository.name,
|
nickname: $application.general.nickname
|
||||||
organization: $application.repository.organization,
|
|
||||||
branch: $application.repository.branch
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
$prApplication = configuration.filter((c) => c.general.pullRequest !== 0);
|
||||||
@@ -34,12 +46,8 @@
|
|||||||
await setConfiguration();
|
await setConfiguration();
|
||||||
} else {
|
} else {
|
||||||
const found = $dashboard.applications.deployed.find((app) => {
|
const found = $dashboard.applications.deployed.find((app) => {
|
||||||
const { organization, name, branch } = app.configuration.repository;
|
const { domain } = app.configuration.publish;
|
||||||
if (
|
if (domain === $application.publish.domain) {
|
||||||
organization === $application.repository.organization &&
|
|
||||||
name === $application.repository.name &&
|
|
||||||
branch === $application.repository.branch
|
|
||||||
) {
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -50,6 +58,8 @@
|
|||||||
await setConfiguration();
|
await setConfiguration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$originalDomain = $application.publish.domain
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$application = JSON.parse(JSON.stringify(initialApplication));
|
$application = JSON.parse(JSON.stringify(initialApplication));
|
||||||
}
|
}
|
||||||
@@ -58,7 +68,6 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
$application = JSON.parse(JSON.stringify(initialApplication));
|
$application = JSON.parse(JSON.stringify(initialApplication));
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#await loadConfiguration()}
|
{#await loadConfiguration()}
|
||||||
|
|||||||
@@ -1,8 +1,31 @@
|
|||||||
|
<script context="module" lang="ts">
|
||||||
|
import { request } from '$lib/request';
|
||||||
|
/**
|
||||||
|
* @type {import('@sveltejs/kit').Load}
|
||||||
|
*/
|
||||||
|
export async function load(session) {
|
||||||
|
if (!browser) {
|
||||||
|
if (!import.meta.env.VITE_GITHUB_APP_CLIENTID) {
|
||||||
|
return {
|
||||||
|
status: 302,
|
||||||
|
redirect: '/dashboard/services'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
initDashboard: await request('/api/v1/dashboard', session)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { dashboard, dateOptions } from '$store';
|
import { dashboard, dateOptions, settings } from '$store';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
import { browser } from '$app/env';
|
||||||
|
import { dashify } from '$lib/common';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -39,9 +62,7 @@
|
|||||||
<div
|
<div
|
||||||
class="relative rounded-xl p-6 bg-warmGray-800 border-2 border-dashed border-transparent hover:border-green-500 text-white shadow-md cursor-pointer ease-in-out hover:scale-105 duration-100 group"
|
class="relative rounded-xl p-6 bg-warmGray-800 border-2 border-dashed border-transparent hover:border-green-500 text-white shadow-md cursor-pointer ease-in-out hover:scale-105 duration-100 group"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
goto(
|
goto(`/application/${application.configuration.general.nickname}/configuration`);
|
||||||
`/application/${application.configuration.repository.organization}/${application.configuration.repository.name}/${application.configuration.repository.branch}/configuration`
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
<script context="module" lang="ts">
|
||||||
|
/**
|
||||||
|
* @type {import('@sveltejs/kit').Load}
|
||||||
|
*/
|
||||||
|
export async function load(session) {
|
||||||
|
if (!browser && !process.env.VITE_GITHUB_APP_CLIENTID) {
|
||||||
|
return {
|
||||||
|
status: 302,
|
||||||
|
redirect: '/dashboard/services'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import MongoDb from '$components/Database/SVGs/MongoDb.svelte';
|
import MongoDb from '$components/Database/SVGs/MongoDb.svelte';
|
||||||
@@ -8,7 +23,7 @@
|
|||||||
import { dashboard } from '$store';
|
import { dashboard } from '$store';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import Redis from '$components/Database/SVGs/Redis.svelte';
|
import Redis from '$components/Database/SVGs/Redis.svelte';
|
||||||
|
import { browser } from '$app/env';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="py-5 text-left px-6 text-3xl tracking-tight font-bold flex items-center">
|
<div class="py-5 text-left px-6 text-3xl tracking-tight font-bold flex items-center">
|
||||||
@@ -59,9 +74,7 @@
|
|||||||
customClass="w-10 h-10 fill-current text-red-600 absolute top-0 left-0 -m-4"
|
customClass="w-10 h-10 fill-current text-red-600 absolute top-0 left-0 -m-4"
|
||||||
/>
|
/>
|
||||||
{:else if database.configuration.general.type == 'redis'}
|
{:else if database.configuration.general.type == 'redis'}
|
||||||
<Redis
|
<Redis customClass="w-10 h-10 absolute top-0 left-0 -m-4" />
|
||||||
customClass="w-10 h-10 absolute top-0 left-0 -m-4"
|
|
||||||
/>
|
|
||||||
{:else if database.configuration.general.type == 'clickhouse'}
|
{:else if database.configuration.general.type == 'clickhouse'}
|
||||||
<Clickhouse
|
<Clickhouse
|
||||||
customClass="w-10 h-10 fill-current text-red-600 absolute top-0 left-0 -m-4"
|
customClass="w-10 h-10 fill-current text-red-600 absolute top-0 left-0 -m-4"
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<script>
|
<script>
|
||||||
import { browser } from '$app/env';
|
import { browser } from '$app/env';
|
||||||
|
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { session } from '$app/stores';
|
import { session } from '$app/stores';
|
||||||
|
import { toast } from '@zerodevx/svelte-toast';
|
||||||
|
import PasswordField from '$components/PasswordField.svelte';
|
||||||
import { request } from '$lib/request';
|
import { request } from '$lib/request';
|
||||||
|
import { settings } from '$store';
|
||||||
|
import Loading from '$components/Loading.svelte';
|
||||||
|
let loading = false;
|
||||||
|
let email = null;
|
||||||
|
let password = null;
|
||||||
async function login() {
|
async function login() {
|
||||||
const left = screen.width / 2 - 1020 / 2;
|
const left = screen.width / 2 - 1020 / 2;
|
||||||
const top = screen.height / 2 - 618 / 2;
|
const top = screen.height / 2 - 618 / 2;
|
||||||
@@ -22,11 +27,30 @@
|
|||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
if (newWindow?.closed) {
|
if (newWindow?.closed) {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
browser && location.reload()
|
// WHY need to navigate to / to get cookies?!
|
||||||
|
browser && window.location.replace('/')
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
async function loginWithEmail() {
|
||||||
|
try {
|
||||||
|
loading = true;
|
||||||
|
const { message } = await request('/api/v1/login/email', $session, {
|
||||||
|
body: {
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toast.push(message);
|
||||||
|
setTimeout(() => {
|
||||||
|
// WHY need to navigate to / to get cookies?!
|
||||||
|
browser && window.location.replace('/')
|
||||||
|
}, 1000);
|
||||||
|
} catch (error) {
|
||||||
|
loading = false;
|
||||||
|
browser && toast.push(error.error || error || 'Ooops something went wrong.');
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex justify-center items-center h-screen w-full bg-warmGray-900">
|
<div class="flex justify-center items-center h-screen w-full bg-warmGray-900">
|
||||||
@@ -37,24 +61,56 @@
|
|||||||
>
|
>
|
||||||
<span class="border-gradient">Coolify</span>
|
<span class="border-gradient">Coolify</span>
|
||||||
</p>
|
</p>
|
||||||
<h2 class="text-2xl md:text-3xl font-extrabold text-white">
|
<h2 class="text-2xl md:text-3xl font-extrabold text-white py-10">
|
||||||
An open-source, hassle-free, self-hostable<br />
|
An open-source, hassle-free, self-hostable<br />
|
||||||
<span class="text-indigo-400">Heroku</span>
|
<span class="text-indigo-400">Heroku</span>
|
||||||
& <span class="text-green-400">Netlify</span> alternative
|
& <span class="text-green-400">Netlify</span> alternative
|
||||||
</h2>
|
</h2>
|
||||||
<div class="text-center py-10">
|
{#if loading}
|
||||||
|
<Loading fullscreen={false} />
|
||||||
|
{:else}
|
||||||
|
<div class="text-center py-10 max-w-7xl">
|
||||||
{#if !$session.isLoggedIn}
|
{#if !$session.isLoggedIn}
|
||||||
|
{#if $settings.clientId}
|
||||||
<button
|
<button
|
||||||
class="text-white bg-warmGray-800 hover:bg-warmGray-700 rounded p-2 px-10 font-bold"
|
class="text-white bg-warmGray-800 hover:bg-warmGray-700 rounded p-2 px-10 font-bold"
|
||||||
on:click={login}>Login with Github</button
|
on:click={login}>Login with GitHub</button
|
||||||
>
|
>
|
||||||
|
{:else}
|
||||||
|
<div>
|
||||||
|
<div class="grid grid-flow-row gap-2 items-center pb-6">
|
||||||
|
<div class="grid grid-flow-row">
|
||||||
|
<label for="Email" class="">Email address</label>
|
||||||
|
<input
|
||||||
|
class="border-2"
|
||||||
|
id="Email"
|
||||||
|
bind:value={email}
|
||||||
|
placeholder="hi@coollabs.io"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-flow-row">
|
||||||
|
<label for="Password" class="">Password</label>
|
||||||
|
<PasswordField bind:value={password} isEditable />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="space-x-4 pt-10">
|
||||||
|
<button
|
||||||
|
class="text-white bg-warmGray-800 hover:bg-warmGray-700 rounded p-2 px-10 font-bold"
|
||||||
|
on:click={loginWithEmail}>Login with Email</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
class="text-white bg-warmGray-800 hover:bg-warmGray-700 rounded p-2 px-10 font-bold"
|
class="text-white bg-warmGray-800 hover:bg-warmGray-700 rounded p-2 px-10 font-bold"
|
||||||
on:click={() => goto('/dashboard/applications')}>Get Started</button
|
on:click={() =>
|
||||||
|
$settings.clientId ? goto('/dashboard/applications') : goto('/dashboard/services')}
|
||||||
|
>Get Started</button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import type {
|
|||||||
GithubInstallations
|
GithubInstallations
|
||||||
} from 'src/global';
|
} from 'src/global';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
export const settings = writable({
|
||||||
|
clientId: null
|
||||||
|
});
|
||||||
export const dashboard = writable<Dashboard>({
|
export const dashboard = writable<Dashboard>({
|
||||||
databases: {
|
databases: {
|
||||||
deployed: []
|
deployed: []
|
||||||
@@ -30,6 +32,7 @@ export const dateOptions: DateTimeFormatOptions = {
|
|||||||
|
|
||||||
export const githubRepositories = writable([]);
|
export const githubRepositories = writable([]);
|
||||||
export const githubInstallations = writable<GithubInstallations>([]);
|
export const githubInstallations = writable<GithubInstallations>([]);
|
||||||
|
export const originalDomain = writable(null)
|
||||||
export const application = writable<Application>({
|
export const application = writable<Application>({
|
||||||
github: {
|
github: {
|
||||||
installation: {
|
installation: {
|
||||||
@@ -79,9 +82,7 @@ export const application = writable<Application>({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
export const prApplication = writable([]);
|
export const prApplication = writable([]);
|
||||||
|
|
||||||
export const initConf = writable({});
|
export const initConf = writable({});
|
||||||
|
|
||||||
export const initialApplication: Application = {
|
export const initialApplication: Application = {
|
||||||
github: {
|
github: {
|
||||||
installation: {
|
installation: {
|
||||||
@@ -179,5 +180,4 @@ export const newWordpressService = writable({
|
|||||||
},
|
},
|
||||||
wordpressExtraConfiguration: null
|
wordpressExtraConfiguration: null
|
||||||
});
|
});
|
||||||
|
|
||||||
export const isPullRequestPermissionsGranted = writable(false);
|
export const isPullRequestPermissionsGranted = writable(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user