diff --git a/.dockerignore b/.dockerignore index 907d0f818a..3fd3b242aa 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,7 @@ +.DS_Store node_modules -dist -.routify -.pnpm-store \ No newline at end of file +/.svelte +/build +/functions +.pnpm-store +.pnpm-debug.log diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000000..fba3861946 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,20 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], + plugins: ['svelte3', '@typescript-eslint'], + ignorePatterns: ['*.cjs'], + overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], + settings: { + 'svelte3/typescript': () => require('typescript') + }, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2019 + }, + env: { + browser: true, + es2017: true, + node: true + } +}; diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e2dbc19ba5..5c54556a7e 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -ko_fi: andrasbacsai \ No newline at end of file +ko_fi: andrasbacsai diff --git a/.gitignore b/.gitignore index 90e0552cc4..82beb85048 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,9 @@ -.vscode -.idea -node_modules -dist -dist-ssr -.routify +/node_modules +/.svelte +/.svelte-kit +/.pnpm-store +/build +/functions .env -yarn-error.log -api/development/console.log -.pnpm-debug.log -.pnpm-store \ No newline at end of file +.DS_Store +.pnpm-debug.log \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..b6f27f1359 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..82a5e3e129 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +.svelte/** +static/** +build/** +node_modules/** +.svelte-kit/** \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index da65a6c28f..ff2677efde 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,14 +1,6 @@ { - "arrowParens": "avoid", - "bracketSpacing": true, - "printWidth": 80, - "semi": true, - "singleQuote": false, - "tabWidth": 2, - "trailingComma": "all", - "svelteSortOrder" : "styles-scripts-markup", - "svelteStrictMode": true, - "svelteBracketNewLine": true, - "svelteAllowShorthand": true, - "plugins": ["prettier-plugin-svelte"] - } + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100 +} diff --git a/api/app.js b/api/app.js deleted file mode 100644 index f1fe5aed5e..0000000000 --- a/api/app.js +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = async function (fastify, opts) { - // Private routes - fastify.register(async function (server) { - server.register(require('./plugins/authentication')) - server.register(require('./routes/v1/upgrade'), { prefix: '/upgrade' }) - server.register(require('./routes/v1/settings'), { prefix: '/settings' }) - server.register(require('./routes/v1/dashboard'), { prefix: '/dashboard' }) - server.register(require('./routes/v1/config'), { prefix: '/config' }) - server.register(require('./routes/v1/application/remove'), { prefix: '/application/remove' }) - server.register(require('./routes/v1/application/logs'), { prefix: '/application/logs' }) - server.register(require('./routes/v1/application/check'), { prefix: '/application/check' }) - server.register(require('./routes/v1/application/deploy'), { prefix: '/application/deploy' }) - server.register(require('./routes/v1/application/deploy/logs'), { prefix: '/application/deploy/logs' }) - server.register(require('./routes/v1/databases'), { prefix: '/databases' }) - server.register(require('./routes/v1/services'), { prefix: '/services' }) - server.register(require('./routes/v1/services/deploy'), { prefix: '/services/deploy' }) - server.register(require('./routes/v1/server'), { prefix: '/server' }) - }) - // Public routes - fastify.register(require('./routes/v1/verify'), { prefix: '/verify' }) - fastify.register(require('./routes/v1/login/github'), { - prefix: '/login/github' - }) - fastify.register(require('./routes/v1/webhooks/deploy'), { - prefix: '/webhooks/deploy' - }) - fastify.register(require('./routes/v1/undead'), { - prefix: '/undead' - }) -} diff --git a/api/buildPacks/docker/index.js b/api/buildPacks/docker/index.js deleted file mode 100644 index e572b9f7be..0000000000 --- a/api/buildPacks/docker/index.js +++ /dev/null @@ -1,15 +0,0 @@ -const fs = require('fs').promises -const { streamEvents, docker } = require('../../libs/docker') - -module.exports = async function (configuration) { - const path = `${configuration.general.workdir}/${configuration.build.directory ? configuration.build.directory : ''}` - if (fs.stat(`${path}/Dockerfile`)) { - const stream = await docker.engine.buildImage( - { src: ['.'], context: path }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) - } else { - throw new Error('No custom dockerfile found.') - } -} diff --git a/api/buildPacks/gatsby/index.js b/api/buildPacks/gatsby/index.js deleted file mode 100644 index 46f1b26a70..0000000000 --- a/api/buildPacks/gatsby/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') - -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishStaticDocker = (configuration) => { - return [ - 'FROM nginx:stable-alpine', - 'COPY nginx.conf /etc/nginx/nginx.conf', - 'WORKDIR /usr/share/nginx/html', - `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, - 'EXPOSE 80', - 'CMD ["nginx", "-g", "daemon off;"]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration, true) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/helpers.js b/api/buildPacks/helpers.js deleted file mode 100644 index d6acfc61b6..0000000000 --- a/api/buildPacks/helpers.js +++ /dev/null @@ -1,24 +0,0 @@ -const fs = require('fs').promises -const { streamEvents, docker } = require('../libs/docker') -const buildImageNodeDocker = (configuration) => { - return [ - 'FROM node:lts', - 'WORKDIR /usr/src/app', - `COPY ${configuration.build.directory}/package*.json ./`, - configuration.build.command.installation && `RUN ${configuration.build.command.installation}`, - `COPY ./${configuration.build.directory} ./`, - `RUN ${configuration.build.command.build}` - ].join('\n') -} -async function buildImage (configuration, cacheBuild) { - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, buildImageNodeDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${cacheBuild ? `${configuration.build.container.tag}-cache` : configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} - -module.exports = { - buildImage -} diff --git a/api/buildPacks/index.js b/api/buildPacks/index.js deleted file mode 100644 index 9ca02a9a5b..0000000000 --- a/api/buildPacks/index.js +++ /dev/null @@ -1,13 +0,0 @@ -const Static = require('./static') -const react = require('./react') -const nextjs = require('./nextjs') -const nuxtjs = require('./nuxtjs') -const gatsby = require('./gatsby') -const vuejs = require('./vuejs') -const svelte = require('./svelte') -const nodejs = require('./nodejs') -const php = require('./php') -const docker = require('./docker') -const rust = require('./rust') - -module.exports = { static: Static, nodejs, php, docker, rust, react, vuejs, nextjs, nuxtjs, svelte, gatsby } diff --git a/api/buildPacks/nextjs/index.js b/api/buildPacks/nextjs/index.js deleted file mode 100644 index 2449875d7c..0000000000 --- a/api/buildPacks/nextjs/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') -// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, -const publishNodejsDocker = (configuration) => { - return [ - 'FROM node:lts', - 'WORKDIR /usr/src/app', - configuration.build.command.build - ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` - : ` - COPY ${configuration.build.directory}/package*.json ./ - RUN ${configuration.build.command.installation} - COPY ./${configuration.build.directory} ./`, - `EXPOSE ${configuration.publish.port}`, - 'CMD [ "yarn", "start" ]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishNodejsDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/nodejs/index.js b/api/buildPacks/nodejs/index.js deleted file mode 100644 index 0a8e41eb58..0000000000 --- a/api/buildPacks/nodejs/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') -// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, -const publishNodejsDocker = (configuration) => { - return [ - 'FROM node:lts', - 'WORKDIR /usr/src/app', - configuration.build.command.build - ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` - : ` - COPY ${configuration.build.directory}/package*.json ./ - RUN ${configuration.build.command.installation} - COPY ./${configuration.build.directory} ./`, - `EXPOSE ${configuration.publish.port}`, - 'CMD [ "yarn", "start" ]' - ].join('\n') -} - -module.exports = async function (configuration) { - if (configuration.build.command.build) await buildImage(configuration) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishNodejsDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/nuxtjs/index.js b/api/buildPacks/nuxtjs/index.js deleted file mode 100644 index 2449875d7c..0000000000 --- a/api/buildPacks/nuxtjs/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') -// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, -const publishNodejsDocker = (configuration) => { - return [ - 'FROM node:lts', - 'WORKDIR /usr/src/app', - configuration.build.command.build - ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` - : ` - COPY ${configuration.build.directory}/package*.json ./ - RUN ${configuration.build.command.installation} - COPY ./${configuration.build.directory} ./`, - `EXPOSE ${configuration.publish.port}`, - 'CMD [ "yarn", "start" ]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishNodejsDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/php/index.js b/api/buildPacks/php/index.js deleted file mode 100644 index e22791d095..0000000000 --- a/api/buildPacks/php/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const fs = require('fs').promises -const { streamEvents, docker } = require('../../libs/docker') -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishPHPDocker = (configuration) => { - return [ - 'FROM php:apache', - 'RUN a2enmod rewrite', - 'WORKDIR /usr/src/app', - `COPY ./${configuration.build.directory} /var/www/html`, - 'EXPOSE 80', - ' CMD ["apache2-foreground"]' - ].join('\n') -} - -module.exports = async function (configuration) { - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishPHPDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/react/index.js b/api/buildPacks/react/index.js deleted file mode 100644 index 46f1b26a70..0000000000 --- a/api/buildPacks/react/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') - -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishStaticDocker = (configuration) => { - return [ - 'FROM nginx:stable-alpine', - 'COPY nginx.conf /etc/nginx/nginx.conf', - 'WORKDIR /usr/share/nginx/html', - `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, - 'EXPOSE 80', - 'CMD ["nginx", "-g", "daemon off;"]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration, true) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/rust/index.js b/api/buildPacks/rust/index.js deleted file mode 100644 index e4b076810c..0000000000 --- a/api/buildPacks/rust/index.js +++ /dev/null @@ -1,60 +0,0 @@ -const fs = require('fs').promises -const { streamEvents, docker } = require('../../libs/docker') -const { execShellAsync } = require('../../libs/common') -const TOML = require('@iarna/toml') - -const publishRustDocker = (configuration, custom) => { - return [ - 'FROM rust:latest', - 'WORKDIR /app', - `COPY --from=${configuration.build.container.name}:cache /app/target target`, - `COPY --from=${configuration.build.container.name}:cache /usr/local/cargo /usr/local/cargo`, - 'COPY . .', - `RUN cargo build --release --bin ${custom.name}`, - 'FROM debian:buster-slim', - 'WORKDIR /app', - 'RUN apt-get update -y && apt-get install -y --no-install-recommends openssl libcurl4 ca-certificates && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*', - 'RUN update-ca-certificates', - `COPY --from=${configuration.build.container.name}:cache /app/target/release/${custom.name} ${custom.name}`, - `EXPOSE ${configuration.publish.port}`, - `CMD ["/app/${custom.name}"]` - ].join('\n') -} - -const cacheRustDocker = (configuration, custom) => { - return [ - `FROM rust:latest AS planner-${configuration.build.container.name}`, - 'WORKDIR /app', - 'RUN cargo install cargo-chef', - 'COPY . .', - 'RUN cargo chef prepare --recipe-path recipe.json', - 'FROM rust:latest', - 'WORKDIR /app', - 'RUN cargo install cargo-chef', - `COPY --from=planner-${configuration.build.container.name} /app/recipe.json recipe.json`, - 'RUN cargo chef cook --release --recipe-path recipe.json' - ].join('\n') -} - -module.exports = async function (configuration) { - const cargoToml = await execShellAsync(`cat ${configuration.general.workdir}/Cargo.toml`) - const parsedToml = TOML.parse(cargoToml) - const custom = { - name: parsedToml.package.name - } - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, cacheRustDocker(configuration, custom)) - - let stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:cache` } - ) - await streamEvents(stream, configuration) - - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishRustDocker(configuration, custom)) - - stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/static/index.js b/api/buildPacks/static/index.js deleted file mode 100644 index 65a382d798..0000000000 --- a/api/buildPacks/static/index.js +++ /dev/null @@ -1,27 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') - -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishStaticDocker = (configuration) => { - return [ - 'FROM nginx:stable-alpine', - 'COPY nginx.conf /etc/nginx/nginx.conf', - 'WORKDIR /usr/share/nginx/html', - configuration.build.command.build - ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./` - : `COPY ./${configuration.build.directory} ./`, - 'EXPOSE 80', - 'CMD ["nginx", "-g", "daemon off;"]' - ].join('\n') -} - -module.exports = async function (configuration) { - if (configuration.build.command.build) await buildImage(configuration, true) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/svelte/index.js b/api/buildPacks/svelte/index.js deleted file mode 100644 index 46f1b26a70..0000000000 --- a/api/buildPacks/svelte/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') - -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishStaticDocker = (configuration) => { - return [ - 'FROM nginx:stable-alpine', - 'COPY nginx.conf /etc/nginx/nginx.conf', - 'WORKDIR /usr/share/nginx/html', - `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, - 'EXPOSE 80', - 'CMD ["nginx", "-g", "daemon off;"]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration, true) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/buildPacks/vuejs/index.js b/api/buildPacks/vuejs/index.js deleted file mode 100644 index 46f1b26a70..0000000000 --- a/api/buildPacks/vuejs/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs').promises -const { buildImage } = require('../helpers') -const { streamEvents, docker } = require('../../libs/docker') - -// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', -const publishStaticDocker = (configuration) => { - return [ - 'FROM nginx:stable-alpine', - 'COPY nginx.conf /etc/nginx/nginx.conf', - 'WORKDIR /usr/share/nginx/html', - `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, - 'EXPOSE 80', - 'CMD ["nginx", "-g", "daemon off;"]' - ].join('\n') -} - -module.exports = async function (configuration) { - await buildImage(configuration, true) - await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration)) - const stream = await docker.engine.buildImage( - { src: ['.'], context: configuration.general.workdir }, - { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } - ) - await streamEvents(stream, configuration) -} diff --git a/api/development/mongodb.js b/api/development/mongodb.js deleted file mode 100644 index 9441e48fc4..0000000000 --- a/api/development/mongodb.js +++ /dev/null @@ -1,36 +0,0 @@ -const mongoose = require('mongoose') -const { MongoMemoryServer } = require('mongodb-memory-server-core') - -const mongoServer = new MongoMemoryServer({ - instance: { - port: 27017, - dbName: 'coolify', - storageEngine: 'wiredTiger' - }, - binary: { - version: '4.4.3' - - } -}) - -mongoose.Promise = Promise -mongoServer.getUri().then((mongoUri) => { - const mongooseOpts = { - useNewUrlParser: true, - useUnifiedTopology: true - } - - mongoose.connect(mongoUri, mongooseOpts) - - mongoose.connection.on('error', (e) => { - if (e.message.code === 'ETIMEDOUT') { - console.log(e) - mongoose.connect(mongoUri, mongooseOpts) - } - console.log(e) - }) - - mongoose.connection.once('open', () => { - console.log(`Started in-memory mongodb ${mongoUri}`) - }) -}) diff --git a/api/libs/applications/build/container.js b/api/libs/applications/build/container.js deleted file mode 100644 index e22a47e337..0000000000 --- a/api/libs/applications/build/container.js +++ /dev/null @@ -1,28 +0,0 @@ -const packs = require('../../../buildPacks') -const { saveAppLog } = require('../../logging') -const Deployment = require('../../../models/Deployment') - -module.exports = async function (configuration) { - const { id, organization, name, branch } = configuration.repository - const { domain } = configuration.publish - const deployId = configuration.general.deployId - - const execute = packs[configuration.build.pack] - if (execute) { - await Deployment.findOneAndUpdate( - { repoId: id, branch, deployId, organization, name, domain }, - { repoId: id, branch, deployId, organization, name, domain, progress: 'inprogress' }) - await saveAppLog('### Building application.', configuration) - await execute(configuration) - await saveAppLog('### Building done.', configuration) - } else { - try { - await Deployment.findOneAndUpdate( - { repoId: id, branch, deployId, organization, name, domain }, - { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }) - } catch (error) { - // Hmm. - } - throw new Error('No buildpack found.') - } -} diff --git a/api/libs/applications/cleanup/index.js b/api/libs/applications/cleanup/index.js deleted file mode 100644 index 71b5fca470..0000000000 --- a/api/libs/applications/cleanup/index.js +++ /dev/null @@ -1,35 +0,0 @@ -const { docker } = require('../../docker') -const { execShellAsync } = require('../../common') -const Deployment = require('../../../models/Deployment') - -async function purgeImagesContainers (configuration, deleteAll = false) { - const { name, tag } = configuration.build.container - await execShellAsync('docker container prune -f') - if (deleteAll) { - const IDsToDelete = (await execShellAsync(`docker images ls --filter=reference='${name}' --format '{{json .ID }}'`)).trim().replace(/"/g, '').split('\n') - if (IDsToDelete.length > 0) await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`) - } else { - const IDsToDelete = (await execShellAsync(`docker images ls --filter=reference='${name}' --filter=before='${name}:${tag}' --format '{{json .ID }}'`)).trim().replace(/"/g, '').split('\n') - if (IDsToDelete.length > 1) await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`) - } - await execShellAsync('docker image prune -f') -} - -async function cleanupStuckedDeploymentsInDB () { - // Cleanup stucked deployments. - await Deployment.updateMany( - { progress: { $in: ['queued', 'inprogress'] } }, - { progress: 'failed' } - ) -} - -async function deleteSameDeployments (configuration) { - await (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application').map(async s => { - const running = JSON.parse(s.Spec.Labels.configuration) - if (running.repository.id === configuration.repository.id && running.repository.branch === configuration.repository.branch) { - await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`) - } - }) -} - -module.exports = { cleanupStuckedDeploymentsInDB, deleteSameDeployments, purgeImagesContainers } diff --git a/api/libs/applications/configuration.js b/api/libs/applications/configuration.js deleted file mode 100644 index 74024d8477..0000000000 --- a/api/libs/applications/configuration.js +++ /dev/null @@ -1,113 +0,0 @@ -const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator') -const cuid = require('cuid') -const crypto = require('crypto') -const { docker } = require('../docker') -const { execShellAsync, baseServiceConfiguration } = require('../common') - -function getUniq () { - return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 }) -} - -function setDefaultConfiguration (configuration) { - const nickname = getUniq() - const deployId = cuid() - - const shaBase = JSON.stringify({ repository: configuration.repository }) - const sha256 = crypto.createHash('sha256').update(shaBase).digest('hex') - - configuration.build.container.name = sha256.slice(0, 15) - - configuration.general.nickname = nickname - configuration.general.deployId = deployId - configuration.general.workdir = `/tmp/${deployId}` - - if (!configuration.publish.path) configuration.publish.path = '/' - if (!configuration.publish.port) { - if (configuration.build.pack === 'nodejs' && configuration.build.pack === 'vuejs' && configuration.build.pack === 'nuxtjs' && configuration.build.pack === 'rust' && configuration.build.pack === 'nextjs') { - configuration.publish.port = 3000 - } else { - configuration.publish.port = 80 - } - } - - if (!configuration.build.directory) configuration.build.directory = '' - if (configuration.build.directory.startsWith('/')) configuration.build.directory = configuration.build.directory.replace('/', '') - - if (!configuration.publish.directory) configuration.publish.directory = '' - if (configuration.publish.directory.startsWith('/')) configuration.publish.directory = configuration.publish.directory.replace('/', '') - - if (configuration.build.pack === 'static' || configuration.build.pack === 'nodejs') { - if (!configuration.build.command.installation) configuration.build.command.installation = 'yarn install' - } - - configuration.build.container.baseSHA = crypto.createHash('sha256').update(JSON.stringify(baseServiceConfiguration)).digest('hex') - configuration.baseServiceConfiguration = baseServiceConfiguration - - return configuration -} - -async function updateServiceLabels (configuration) { - // In case of any failure during deployment, still update the current configuration. - const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') - const found = services.find(s => { - const config = JSON.parse(s.Spec.Labels.configuration) - if (config.repository.id === configuration.repository.id && config.repository.branch === configuration.repository.branch) { - return config - } - return null - }) - if (found) { - const { ID } = found - const Labels = { ...JSON.parse(found.Spec.Labels.configuration), ...configuration } - await execShellAsync(`docker service update --label-add configuration='${JSON.stringify(Labels)}' --label-add com.docker.stack.image='${configuration.build.container.name}:${configuration.build.container.tag}' ${ID}`) - } -} - -async function precheckDeployment ({ services, configuration }) { - let foundService = false - let configChanged = false - let imageChanged = false - - let forceUpdate = false - - for (const service of services) { - const running = JSON.parse(service.Spec.Labels.configuration) - if (running) { - if (running.repository.id === configuration.repository.id && running.repository.branch === configuration.repository.branch) { - // Base service configuration changed - if (!running.build.container.baseSHA || running.build.container.baseSHA !== configuration.build.container.baseSHA) { - forceUpdate = true - } - // If the deployment is in error state, forceUpdate - const state = await execShellAsync(`docker stack ps ${running.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] === running.build.container.tag) - if (isError.length > 0) forceUpdate = true - foundService = true - - const runningWithoutContainer = JSON.parse(JSON.stringify(running)) - delete runningWithoutContainer.build.container - - const configurationWithoutContainer = JSON.parse(JSON.stringify(configuration)) - delete configurationWithoutContainer.build.container - - // If only the configuration changed - if (JSON.stringify(runningWithoutContainer.build) !== JSON.stringify(configurationWithoutContainer.build) || JSON.stringify(runningWithoutContainer.publish) !== JSON.stringify(configurationWithoutContainer.publish)) configChanged = true - // If only the image changed - if (running.build.container.tag !== configuration.build.container.tag) imageChanged = true - // If build pack changed, forceUpdate the service - if (running.build.pack !== configuration.build.pack) forceUpdate = true - } - } - } - if (forceUpdate) { - imageChanged = false - configChanged = false - } - return { - foundService, - imageChanged, - configChanged, - forceUpdate - } -} -module.exports = { setDefaultConfiguration, updateServiceLabels, precheckDeployment, baseServiceConfiguration } diff --git a/api/libs/applications/deploy/copyFiles.js b/api/libs/applications/deploy/copyFiles.js deleted file mode 100644 index 41cec0e5d3..0000000000 --- a/api/libs/applications/deploy/copyFiles.js +++ /dev/null @@ -1,65 +0,0 @@ -const fs = require('fs').promises -module.exports = async function (configuration) { - const staticDeployments = ['react', 'vuejs', 'static', 'svelte', 'gatsby'] - try { - // TODO: Write full .dockerignore for all deployments!! - if (configuration.build.pack === 'php') { - await fs.writeFile(`${configuration.general.workdir}/.htaccess`, ` - RewriteEngine On - RewriteBase / - RewriteCond %{REQUEST_FILENAME} !-d - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule ^(.+)$ index.php [QSA,L] - `) - } - // await fs.writeFile(`${configuration.general.workdir}/.dockerignore`, 'node_modules') - if (staticDeployments.includes(configuration.build.pack)) { - await fs.writeFile( - `${configuration.general.workdir}/nginx.conf`, - `user nginx; - worker_processes auto; - - error_log /var/log/nginx/error.log warn; - pid /var/run/nginx.pid; - - events { - worker_connections 1024; - } - - http { - include /etc/nginx/mime.types; - - access_log off; - sendfile on; - #tcp_nopush on; - keepalive_timeout 65; - - server { - listen 80; - server_name localhost; - - location / { - root /usr/share/nginx/html; - index index.html; - try_files $uri $uri/index.html $uri/ /index.html =404; - } - - error_page 404 /50x.html; - - # redirect server error pages to the static page /50x.html - # - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - - } - - } - ` - ) - } - } catch (error) { - throw new Error(error) - } -} diff --git a/api/libs/applications/deploy/deploy.js b/api/libs/applications/deploy/deploy.js deleted file mode 100644 index 5094709a08..0000000000 --- a/api/libs/applications/deploy/deploy.js +++ /dev/null @@ -1,76 +0,0 @@ -const yaml = require('js-yaml') -const fs = require('fs').promises -const { execShellAsync } = require('../../common') -const { docker } = require('../../docker') -const { saveAppLog } = require('../../logging') -const { deleteSameDeployments } = require('../cleanup') - -module.exports = async function (configuration, imageChanged) { - const generateEnvs = {} - for (const secret of configuration.publish.secrets) { - generateEnvs[secret.name] = secret.value - } - const containerName = configuration.build.container.name - - // Only save SHA256 of it in the configuration label - const baseServiceConfiguration = configuration.baseServiceConfiguration - delete configuration.baseServiceConfiguration - - const stack = { - version: '3.8', - services: { - [containerName]: { - image: `${configuration.build.container.name}:${configuration.build.container.tag}`, - networks: [`${docker.network}`], - environment: generateEnvs, - deploy: { - ...baseServiceConfiguration, - labels: [ - 'managedBy=coolify', - 'type=application', - 'configuration=' + JSON.stringify(configuration), - 'traefik.enable=true', - 'traefik.http.services.' + - configuration.build.container.name + - `.loadbalancer.server.port=${configuration.publish.port}`, - 'traefik.http.routers.' + - configuration.build.container.name + - '.entrypoints=websecure', - 'traefik.http.routers.' + - configuration.build.container.name + - '.rule=Host(`' + - configuration.publish.domain + - '`) && PathPrefix(`' + - configuration.publish.path + - '`)', - 'traefik.http.routers.' + - configuration.build.container.name + - '.tls.certresolver=letsencrypt', - 'traefik.http.routers.' + - configuration.build.container.name + - '.middlewares=global-compress' - ] - } - } - }, - networks: { - [`${docker.network}`]: { - external: true - } - } - } - await saveAppLog('### Publishing.', configuration) - await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack)) - if (imageChanged) { - // console.log('image changed') - await execShellAsync(`docker service update --image ${configuration.build.container.name}:${configuration.build.container.tag} ${configuration.build.container.name}_${configuration.build.container.name}`) - } else { - // console.log('new deployment or force deployment or config changed') - await deleteSameDeployments(configuration) - await execShellAsync( - `cat ${configuration.general.workdir}/stack.yml | docker stack deploy --prune -c - ${containerName}` - ) - } - - await saveAppLog('### Published done!', configuration) -} diff --git a/api/libs/applications/github/cloneRepository.js b/api/libs/applications/github/cloneRepository.js deleted file mode 100644 index bf0448c52e..0000000000 --- a/api/libs/applications/github/cloneRepository.js +++ /dev/null @@ -1,44 +0,0 @@ -const jwt = require('jsonwebtoken') -const axios = require('axios') -const { execShellAsync } = require('../../common') - -module.exports = async function (configuration) { - try { - const { workdir } = configuration.general - const { organization, name, branch } = configuration.repository - const github = configuration.github - if (!github.installation.id || !github.app.id) { - throw new Error('Github installation ID is invalid.') - } - const githubPrivateKey = process.env.GITHUB_APP_PRIVATE_KEY.replace(/\\n/g, '\n').replace(/"/g, '') - - const payload = { - iat: Math.round(new Date().getTime() / 1000), - exp: Math.round(new Date().getTime() / 1000 + 60), - iss: parseInt(github.app.id) - } - - const jwtToken = jwt.sign(payload, githubPrivateKey, { - algorithm: 'RS256' - }) - const accessToken = await axios({ - method: 'POST', - url: `https://api.github.com/app/installations/${github.installation.id}/access_tokens`, - data: {}, - headers: { - Authorization: 'Bearer ' + jwtToken, - Accept: 'application/vnd.github.machine-man-preview+json' - } - }) - await execShellAsync( - `mkdir -p ${workdir} && git clone -q -b ${branch} https://x-access-token:${accessToken.data.token}@github.com/${organization}/${name}.git ${workdir}/` - ) - configuration.build.container.tag = ( - await execShellAsync(`cd ${configuration.general.workdir}/ && git rev-parse HEAD`) - ) - .replace('\n', '') - .slice(0, 7) - } catch (error) { - throw new Error(error) - } -} diff --git a/api/libs/applications/index.js b/api/libs/applications/index.js deleted file mode 100644 index f28341d563..0000000000 --- a/api/libs/applications/index.js +++ /dev/null @@ -1,27 +0,0 @@ -const dayjs = require('dayjs') - -const { saveAppLog } = require('../logging') -const copyFiles = require('./deploy/copyFiles') -const buildContainer = require('./build/container') -const deploy = require('./deploy/deploy') -const Deployment = require('../../models/Deployment') -const { updateServiceLabels } = require('./configuration') - -async function queueAndBuild (configuration, imageChanged) { - const { id, organization, name, branch } = configuration.repository - const { domain } = configuration.publish - const { deployId, nickname } = configuration.general - await new Deployment({ - repoId: id, branch, deployId, domain, organization, name, nickname - }).save() - await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration) - await copyFiles(configuration) - await buildContainer(configuration) - await deploy(configuration, imageChanged) - await Deployment.findOneAndUpdate( - { repoId: id, branch, deployId, organization, name, domain }, - { repoId: id, branch, deployId, organization, name, domain, progress: 'done' }) - await updateServiceLabels(configuration) -} - -module.exports = { queueAndBuild } diff --git a/api/libs/common.js b/api/libs/common.js deleted file mode 100644 index 8a9c09bff6..0000000000 --- a/api/libs/common.js +++ /dev/null @@ -1,117 +0,0 @@ -const crypto = require('crypto') -const shell = require('shelljs') -const jsonwebtoken = require('jsonwebtoken') -const { docker } = require('./docker') -const User = require('../models/User') -const algorithm = 'aes-256-cbc' -const key = process.env.SECRETS_ENCRYPTION_KEY - -const baseServiceConfiguration = { - replicas: 1, - restart_policy: { - condition: 'any', - max_attempts: 6 - }, - update_config: { - parallelism: 1, - delay: '10s', - order: 'start-first' - }, - rollback_config: { - parallelism: 1, - delay: '10s', - order: 'start-first', - failure_action: 'rollback' - } -} -function delay (t) { - return new Promise(function (resolve) { - setTimeout(function () { - resolve('OK') - }, t) - }) -} - -async function verifyUserId (authorization) { - try { - const token = authorization.split(' ')[1] - const verify = jsonwebtoken.verify(token, process.env.JWT_SIGN_KEY) - const found = await User.findOne({ uid: verify.jti }) - if (found) { - return true - } else { - return false - } - } catch (error) { - return false - } -} -function execShellAsync (cmd, opts = {}) { - try { - return new Promise(function (resolve, reject) { - shell.config.silent = true - shell.exec(cmd, opts, function (code, stdout, stderr) { - if (code !== 0) return reject(new Error(stderr)) - return resolve(stdout) - }) - }) - } catch (error) { - return new Error('Oops') - } -} -function cleanupTmp (dir) { - if (dir !== '/') shell.rm('-fr', dir) -} - -async function checkImageAvailable (name) { - let cacheAvailable = false - try { - await docker.engine.getImage(name).get() - cacheAvailable = true - } catch (e) { - // Cache image not found - } - return cacheAvailable -} - -function encryptData (text) { - const iv = crypto.randomBytes(16) - const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv) - let encrypted = cipher.update(text) - encrypted = Buffer.concat([encrypted, cipher.final()]) - return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') } -} - -function decryptData (text) { - const iv = Buffer.from(text.iv, 'hex') - const encryptedText = Buffer.from(text.encryptedData, 'hex') - const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv) - let decrypted = decipher.update(encryptedText) - decrypted = Buffer.concat([decrypted, decipher.final()]) - return decrypted.toString() -} - -function createToken (payload) { - const { uuid } = payload - return jsonwebtoken.sign({}, process.env.JWT_SIGN_KEY, { - expiresIn: 15778800, - algorithm: 'HS256', - audience: 'coolify', - issuer: 'coolify', - jwtid: uuid, - subject: `User:${uuid}`, - notBefore: -1000 - }) -} - -module.exports = { - delay, - createToken, - execShellAsync, - cleanupTmp, - checkImageAvailable, - encryptData, - decryptData, - verifyUserId, - baseServiceConfiguration -} diff --git a/api/libs/docker.js b/api/libs/docker.js deleted file mode 100644 index 1ef28ca5c4..0000000000 --- a/api/libs/docker.js +++ /dev/null @@ -1,28 +0,0 @@ -const Dockerode = require('dockerode') -const { saveAppLog } = require('./logging') - -const docker = { - engine: new Dockerode({ - socketPath: process.env.DOCKER_ENGINE - }), - network: process.env.DOCKER_NETWORK -} -async function streamEvents (stream, configuration) { - await new Promise((resolve, reject) => { - docker.engine.modem.followProgress(stream, onFinished, onProgress) - function onFinished (err, res) { - if (err) reject(err) - resolve(res) - } - function onProgress (event) { - if (event.error) { - saveAppLog(event.error, configuration, true) - reject(event.error) - } else if (event.stream) { - saveAppLog(event.stream, configuration) - } - } - }) -} - -module.exports = { streamEvents, docker } diff --git a/api/libs/http-error/handlers.js b/api/libs/http-error/handlers.js deleted file mode 100644 index 013d6c783c..0000000000 --- a/api/libs/http-error/handlers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint-disable */ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.handleErrors = exports.handleValidationError = exports.handleNotFoundError = void 0; -const http_errors_enhanced_1 = require("http-errors-enhanced"); -const interfaces_1 = require("./interfaces"); -const utils_1 = require("./utils"); -const validation_1 = require("./validation"); -function handleNotFoundError(request, reply) { - handleErrors(new http_errors_enhanced_1.NotFoundError('Not found.'), request, reply); -} -exports.handleNotFoundError = handleNotFoundError; -function handleValidationError(error, request) { - /* - As seen in https://github.com/fastify/fastify/blob/master/lib/validation.js - the error.message will always start with the relative section (params, querystring, headers, body) - and fastify throws on first failing section. - */ - const section = error.message.match(/^\w+/)[0]; - return new http_errors_enhanced_1.BadRequestError('One or more validations failed trying to process your request.', { - failedValidations: validation_1.convertValidationErrors(section, Reflect.get(request, section), error.validation) - }); -} -exports.handleValidationError = handleValidationError; -function handleErrors(error, request, reply) { - var _a, _b; - // It is a generic error, handle it - const code = error.code; - if (!('statusCode' in error)) { - if ('validation' in error && ((_a = request[interfaces_1.kHttpErrorsEnhancedConfiguration]) === null || _a === void 0 ? void 0 : _a.convertValidationErrors)) { - // If it is a validation error, convert errors to human friendly format - error = handleValidationError(error, request); - } - else if ((_b = request[interfaces_1.kHttpErrorsEnhancedConfiguration]) === null || _b === void 0 ? void 0 : _b.hideUnhandledErrors) { - // It is requested to hide the error, just log it and then create a generic one - request.log.error({ error: http_errors_enhanced_1.serializeError(error) }); - error = new http_errors_enhanced_1.InternalServerError('An error occurred trying to process your request.'); - } - else { - // Wrap in a HttpError, making the stack explicitily available - error = new http_errors_enhanced_1.InternalServerError(http_errors_enhanced_1.serializeError(error)); - Object.defineProperty(error, 'stack', { enumerable: true }); - } - } - else if (code === 'INVALID_CONTENT_TYPE' || code === 'FST_ERR_CTP_INVALID_MEDIA_TYPE') { - error = new http_errors_enhanced_1.UnsupportedMediaTypeError(utils_1.upperFirst(validation_1.validationMessagesFormatters.contentType())); - } - else if (code === 'FST_ERR_CTP_EMPTY_JSON_BODY') { - error = new http_errors_enhanced_1.BadRequestError(utils_1.upperFirst(validation_1.validationMessagesFormatters.jsonEmpty())); - } - else if (code === 'MALFORMED_JSON' || error.message === 'Invalid JSON' || error.stack.includes('at JSON.parse')) { - error = new http_errors_enhanced_1.BadRequestError(utils_1.upperFirst(validation_1.validationMessagesFormatters.json())); - } - // Get the status code - let { statusCode, headers } = error; - // Code outside HTTP range - if (statusCode < 100 || statusCode > 599) { - statusCode = http_errors_enhanced_1.INTERNAL_SERVER_ERROR; - } - // Create the body - const body = { - statusCode, - error: http_errors_enhanced_1.messagesByCodes[statusCode], - message: error.message - }; - http_errors_enhanced_1.addAdditionalProperties(body, error); - // Send the error back - // eslint-disable-next-line @typescript-eslint/no-floating-promises - reply - .code(statusCode) - .headers(headers !== null && headers !== void 0 ? headers : {}) - .type('application/json') - .send(body); -} -exports.handleErrors = handleErrors; diff --git a/api/libs/http-error/index.js b/api/libs/http-error/index.js deleted file mode 100644 index 4cffd23625..0000000000 --- a/api/libs/http-error/index.js +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable */ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.plugin = exports.validationMessagesFormatters = exports.niceJoin = exports.convertValidationErrors = void 0; -const fastify_plugin_1 = __importDefault(require("fastify-plugin")); -const handlers_1 = require("./handlers"); -const interfaces_1 = require("./interfaces"); -const validation_1 = require("./validation"); -__exportStar(require("./handlers"), exports); -__exportStar(require("./interfaces"), exports); -var validation_2 = require("./validation"); -Object.defineProperty(exports, "convertValidationErrors", { enumerable: true, get: function () { return validation_2.convertValidationErrors; } }); -Object.defineProperty(exports, "niceJoin", { enumerable: true, get: function () { return validation_2.niceJoin; } }); -Object.defineProperty(exports, "validationMessagesFormatters", { enumerable: true, get: function () { return validation_2.validationMessagesFormatters; } }); -exports.plugin = fastify_plugin_1.default(function (instance, options, done) { - var _a, _b, _c, _d; - const isProduction = process.env.NODE_ENV === 'production'; - const convertResponsesValidationErrors = (_a = options.convertResponsesValidationErrors) !== null && _a !== void 0 ? _a : !isProduction; - const configuration = { - hideUnhandledErrors: (_b = options.hideUnhandledErrors) !== null && _b !== void 0 ? _b : isProduction, - convertValidationErrors: (_c = options.convertValidationErrors) !== null && _c !== void 0 ? _c : true, - responseValidatorCustomizer: options.responseValidatorCustomizer, - allowUndeclaredResponses: (_d = options.allowUndeclaredResponses) !== null && _d !== void 0 ? _d : false - }; - instance.decorate(interfaces_1.kHttpErrorsEnhancedConfiguration, null); - instance.decorateRequest(interfaces_1.kHttpErrorsEnhancedConfiguration, null); - instance.addHook('onRequest', async (request) => { - request[interfaces_1.kHttpErrorsEnhancedConfiguration] = configuration; - }); - instance.setErrorHandler(handlers_1.handleErrors); - // instance.setNotFoundHandler(handlers_1.handleNotFoundError); - if (convertResponsesValidationErrors) { - instance.decorate(interfaces_1.kHttpErrorsEnhancedResponseValidations, []); - instance.addHook('onRoute', validation_1.addResponseValidation); - instance.addHook('onReady', validation_1.compileResponseValidationSchema.bind(instance, configuration)); - } - done(); -}, { name: 'fastify-http-errors-enhanced' }); -exports.default = exports.plugin; -// Fix CommonJS exporting -/* istanbul ignore else */ -if (typeof module !== 'undefined') { - module.exports = exports.plugin; - Object.assign(module.exports, exports); -} diff --git a/api/libs/http-error/interfaces.js b/api/libs/http-error/interfaces.js deleted file mode 100644 index 794d587c46..0000000000 --- a/api/libs/http-error/interfaces.js +++ /dev/null @@ -1,6 +0,0 @@ -/* eslint-disable */ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.kHttpErrorsEnhancedResponseValidations = exports.kHttpErrorsEnhancedConfiguration = void 0; -exports.kHttpErrorsEnhancedConfiguration = Symbol('fastify-http-errors-enhanced-configuration'); -exports.kHttpErrorsEnhancedResponseValidations = Symbol('fastify-http-errors-enhanced-response-validation'); diff --git a/api/libs/http-error/utils.js b/api/libs/http-error/utils.js deleted file mode 100644 index caf07313ac..0000000000 --- a/api/libs/http-error/utils.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable */ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.get = exports.upperFirst = void 0; -function upperFirst(source) { - if (typeof source !== 'string' || !source.length) { - return source; - } - return source[0].toUpperCase() + source.substring(1); -} -exports.upperFirst = upperFirst; -function get(target, path) { - var _a; - const tokens = path.split('.').map((t) => t.trim()); - for (const token of tokens) { - if (typeof target === 'undefined' || target === null) { - // We're supposed to be still iterating, but the chain is over - Return undefined - target = undefined; - break; - } - const index = token.match(/^(\d+)|(?:\[(\d+)\])$/); - if (index) { - target = target[parseInt((_a = index[1]) !== null && _a !== void 0 ? _a : index[2], 10)]; - } - else { - target = target[token]; - } - } - return target; -} -exports.get = get; diff --git a/api/libs/http-error/validation.js b/api/libs/http-error/validation.js deleted file mode 100644 index f417be2b00..0000000000 --- a/api/libs/http-error/validation.js +++ /dev/null @@ -1,239 +0,0 @@ -/* eslint-disable */ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.compileResponseValidationSchema = exports.addResponseValidation = exports.convertValidationErrors = exports.validationMessagesFormatters = exports.niceJoin = void 0; -const ajv_1 = __importDefault(require("ajv")); -const http_errors_enhanced_1 = require("http-errors-enhanced"); -const interfaces_1 = require("./interfaces"); -const utils_1 = require("./utils"); -function niceJoin(array, lastSeparator = ' and ', separator = ', ') { - switch (array.length) { - case 0: - return ''; - case 1: - return array[0]; - case 2: - return array.join(lastSeparator); - default: - return array.slice(0, array.length - 1).join(separator) + lastSeparator + array[array.length - 1]; - } -} -exports.niceJoin = niceJoin; -exports.validationMessagesFormatters = { - contentType: () => 'only JSON payloads are accepted. Please set the "Content-Type" header to start with "application/json"', - json: () => 'the body payload is not a valid JSON', - jsonEmpty: () => 'the JSON body payload cannot be empty if the "Content-Type" header is set', - missing: () => 'must be present', - unknown: () => 'is not a valid property', - uuid: () => 'must be a valid GUID (UUID v4)', - timestamp: () => 'must be a valid ISO 8601 / RFC 3339 timestamp (example: 2018-07-06T12:34:56Z)', - date: () => 'must be a valid ISO 8601 / RFC 3339 date (example: 2018-07-06)', - time: () => 'must be a valid ISO 8601 / RFC 3339 time (example: 12:34:56)', - uri: () => 'must be a valid URI', - hostname: () => 'must be a valid hostname', - ipv4: () => 'must be a valid IPv4', - ipv6: () => 'must be a valid IPv6', - paramType: (type) => { - switch (type) { - case 'integer': - return 'must be a valid integer number'; - case 'number': - return 'must be a valid number'; - case 'boolean': - return 'must be a valid boolean (true or false)'; - case 'object': - return 'must be a object'; - case 'array': - return 'must be an array'; - default: - return 'must be a string'; - } - }, - presentString: () => 'must be a non empty string', - minimum: (min) => `must be a number greater than or equal to ${min}`, - maximum: (max) => `must be a number less than or equal to ${max}`, - minimumProperties(min) { - return min === 1 ? 'cannot be a empty object' : `must be a object with at least ${min} properties`; - }, - maximumProperties(max) { - return max === 0 ? 'must be a empty object' : `must be a object with at most ${max} properties`; - }, - minimumItems(min) { - return min === 1 ? 'cannot be a empty array' : `must be an array with at least ${min} items`; - }, - maximumItems(max) { - return max === 0 ? 'must be a empty array' : `must be an array with at most ${max} items`; - }, - enum: (values) => `must be one of the following values: ${niceJoin(values.map((f) => `"${f}"`), ' or ')}`, - pattern: (pattern) => `must match pattern "${pattern.replace(/\(\?:/g, '(')}"`, - invalidResponseCode: (code) => `This endpoint cannot respond with HTTP status ${code}.`, - invalidResponse: (code) => `The response returned from the endpoint violates its specification for the HTTP status ${code}.`, - invalidFormat: (format) => `must match format "${format}" (format)` -}; -function convertValidationErrors(section, data, validationErrors) { - const errors = {}; - if (section === 'querystring') { - section = 'query'; - } - // For each error - for (const e of validationErrors) { - let message = ''; - let pattern; - let value; - let reason; - // Normalize the key - let key = e.dataPath; - if (key.startsWith('.')) { - key = key.substring(1); - } - // Remove useless quotes - /* istanbul ignore next */ - if (key.startsWith('[') && key.endsWith(']')) { - key = key.substring(1, key.length - 1); - } - // Depending on the type - switch (e.keyword) { - case 'required': - case 'dependencies': - key = e.params.missingProperty; - message = exports.validationMessagesFormatters.missing(); - break; - case 'additionalProperties': - key = e.params.additionalProperty; - message = exports.validationMessagesFormatters.unknown(); - break; - case 'type': - message = exports.validationMessagesFormatters.paramType(e.params.type); - break; - case 'minProperties': - message = exports.validationMessagesFormatters.minimumProperties(e.params.limit); - break; - case 'maxProperties': - message = exports.validationMessagesFormatters.maximumProperties(e.params.limit); - break; - case 'minItems': - message = exports.validationMessagesFormatters.minimumItems(e.params.limit); - break; - case 'maxItems': - message = exports.validationMessagesFormatters.maximumItems(e.params.limit); - break; - case 'minimum': - message = exports.validationMessagesFormatters.minimum(e.params.limit); - break; - case 'maximum': - message = exports.validationMessagesFormatters.maximum(e.params.limit); - break; - case 'enum': - message = exports.validationMessagesFormatters.enum(e.params.allowedValues); - break; - case 'pattern': - pattern = e.params.pattern; - value = utils_1.get(data, key); - if (pattern === '.+' && !value) { - message = exports.validationMessagesFormatters.presentString(); - } - else { - message = exports.validationMessagesFormatters.pattern(e.params.pattern); - } - break; - case 'format': - reason = e.params.format; - // Normalize the key - if (reason === 'date-time') { - reason = 'timestamp'; - } - message = (exports.validationMessagesFormatters[reason] || exports.validationMessagesFormatters.invalidFormat)(reason); - break; - } - // No custom message was found, default to input one replacing the starting verb and adding some path info - if (!message.length) { - message = `${e.message.replace(/^should/, 'must')} (${e.keyword})`; - } - // Remove useless quotes - /* istanbul ignore next */ - if (key.match(/(?:^['"])(?:[^.]+)(?:['"]$)/)) { - key = key.substring(1, key.length - 1); - } - // Fix empty properties - if (!key) { - key = '$root'; - } - key = key.replace(/^\//, ''); - errors[key] = message; - } - return { [section]: errors }; -} -exports.convertValidationErrors = convertValidationErrors; -function addResponseValidation(route) { - var _a; - if (!((_a = route.schema) === null || _a === void 0 ? void 0 : _a.response)) { - return; - } - const validators = {}; - /* - Add these validators to the list of the one to compile once the server is started. - This makes possible to handle shared schemas. - */ - this[interfaces_1.kHttpErrorsEnhancedResponseValidations].push([ - this, - validators, - Object.entries(route.schema.response) - ]); - // Note that this hook is not called for non JSON payloads therefore validation is not possible in such cases - route.preSerialization = async function (request, reply, payload) { - const statusCode = reply.raw.statusCode; - // Never validate error 500 - if (statusCode === http_errors_enhanced_1.INTERNAL_SERVER_ERROR) { - return payload; - } - // No validator, it means the HTTP status is not allowed - const validator = validators[statusCode]; - if (!validator) { - if (request[interfaces_1.kHttpErrorsEnhancedConfiguration].allowUndeclaredResponses) { - return payload; - } - throw new http_errors_enhanced_1.InternalServerError(exports.validationMessagesFormatters.invalidResponseCode(statusCode)); - } - // Now validate the payload - const valid = validator(payload); - if (!valid) { - throw new http_errors_enhanced_1.InternalServerError(exports.validationMessagesFormatters.invalidResponse(statusCode), { - failedValidations: convertValidationErrors('response', payload, validator.errors) - }); - } - return payload; - }; -} -exports.addResponseValidation = addResponseValidation; -function compileResponseValidationSchema(configuration) { - // Fix CJS/ESM interoperability - // @ts-expect-error - let AjvConstructor = ajv_1.default; - /* istanbul ignore next */ - if (AjvConstructor.default) { - AjvConstructor = AjvConstructor.default; - } - const hasCustomizer = typeof configuration.responseValidatorCustomizer === 'function'; - for (const [instance, validators, schemas] of this[interfaces_1.kHttpErrorsEnhancedResponseValidations]) { - // @ts-expect-error - const compiler = new AjvConstructor({ - // The fastify defaults, with the exception of removeAdditional and coerceTypes, which have been reversed - removeAdditional: false, - useDefaults: true, - coerceTypes: false, - allErrors: true - }); - compiler.addSchema(Object.values(instance.getSchemas())); - compiler.addKeyword('example'); - if (hasCustomizer) { - configuration.responseValidatorCustomizer(compiler); - } - for (const [code, schema] of schemas) { - validators[code] = compiler.compile(schema); - } - } -} -exports.compileResponseValidationSchema = compileResponseValidationSchema; diff --git a/api/libs/logging.js b/api/libs/logging.js deleted file mode 100644 index f4e08e3954..0000000000 --- a/api/libs/logging.js +++ /dev/null @@ -1,48 +0,0 @@ -const dayjs = require('dayjs') -const axios = require('axios') - -const ApplicationLog = require('../models/Logs/Application') -const ServerLog = require('../models/Logs/Server') -const Settings = require('../models/Settings') -const { version } = require('../../package.json') - -function generateTimestamp () { - return `${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} ` -} -const patterns = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' -].join('|') - -async function saveAppLog (event, configuration, isError) { - try { - const deployId = configuration.general.deployId - const repoId = configuration.repository.id - const branch = configuration.repository.branch - if (isError) { - const clearedEvent = '[ERROR 😱] ' + generateTimestamp() + event.replace(new RegExp(patterns, 'g'), '').replace(/(\r\n|\n|\r)/gm, '') - await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save() - } else { - if (event && event !== '\n') { - const clearedEvent = '[INFO] ' + generateTimestamp() + event.replace(new RegExp(patterns, 'g'), '').replace(/(\r\n|\n|\r)/gm, '') - await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save() - } - } - } catch (error) { - console.log(error) - return error - } -} - -async function saveServerLog (error) { - const settings = await Settings.findOne({ applicationName: 'coolify' }) - const payload = { message: error.message, stack: error.stack, type: error.type || 'spaghetticode', version } - - const found = await ServerLog.find(payload) - if (found.length === 0 && error.message) await new ServerLog(payload).save() - if (settings && settings.sendErrors && process.env.NODE_ENV === 'production') await axios.post('https://errors.coollabs.io/api/error', payload) -} -module.exports = { - saveAppLog, - saveServerLog -} diff --git a/api/libs/services/plausible/index.js b/api/libs/services/plausible/index.js deleted file mode 100644 index 7e8c61fccf..0000000000 --- a/api/libs/services/plausible/index.js +++ /dev/null @@ -1,185 +0,0 @@ -const { execShellAsync, cleanupTmp, baseServiceConfiguration } = require('../../common') -const yaml = require('js-yaml') -const fs = require('fs').promises -const generator = require('generate-password') -const { docker } = require('../../docker') - -async function plausible ({ email, userName, userPassword, baseURL, traefikURL }) { - const deployId = 'plausible' - const workdir = '/tmp/plausible' - const secretKey = generator.generate({ length: 64, numbers: true, strict: true }) - const generateEnvsPostgres = { - POSTGRESQL_PASSWORD: generator.generate({ length: 24, numbers: true, strict: true }), - POSTGRESQL_USERNAME: generator.generate({ length: 10, numbers: true, strict: true }), - POSTGRESQL_DATABASE: 'plausible' - } - - const secrets = [ - { name: 'ADMIN_USER_EMAIL', value: email }, - { name: 'ADMIN_USER_NAME', value: userName }, - { name: 'ADMIN_USER_PWD', value: userPassword }, - { name: 'BASE_URL', value: baseURL }, - { name: 'SECRET_KEY_BASE', value: secretKey }, - { name: 'DISABLE_AUTH', value: 'false' }, - { name: 'DISABLE_REGISTRATION', value: 'true' }, - { name: 'DATABASE_URL', value: `postgresql://${generateEnvsPostgres.POSTGRESQL_USERNAME}:${generateEnvsPostgres.POSTGRESQL_PASSWORD}@plausible_db:5432/${generateEnvsPostgres.POSTGRESQL_DATABASE}` }, - { name: 'CLICKHOUSE_DATABASE_URL', value: 'http://plausible_events_db:8123/plausible' } - ] - - const generateEnvsClickhouse = {} - for (const secret of secrets) generateEnvsClickhouse[secret.name] = secret.value - - const clickhouseConfigXml = ` - - - warning - true - - - - - - - - - - ` - const clickhouseUserConfigXml = ` - - - - 0 - 0 - - - ` - - const clickhouseConfigs = [ - { source: 'plausible-clickhouse-user-config.xml', target: '/etc/clickhouse-server/users.d/logging.xml' }, - { source: 'plausible-clickhouse-config.xml', target: '/etc/clickhouse-server/config.d/logging.xml' }, - { source: 'plausible-init.query', target: '/docker-entrypoint-initdb.d/init.query' }, - { source: 'plausible-init-db.sh', target: '/docker-entrypoint-initdb.d/init-db.sh' } - ] - - const initQuery = 'CREATE DATABASE IF NOT EXISTS plausible;' - const initScript = 'clickhouse client --queries-file /docker-entrypoint-initdb.d/init.query' - await execShellAsync(`mkdir -p ${workdir}`) - await fs.writeFile(`${workdir}/clickhouse-config.xml`, clickhouseConfigXml) - await fs.writeFile(`${workdir}/clickhouse-user-config.xml`, clickhouseUserConfigXml) - await fs.writeFile(`${workdir}/init.query`, initQuery) - await fs.writeFile(`${workdir}/init-db.sh`, initScript) - const stack = { - version: '3.8', - services: { - [deployId]: { - image: 'plausible/analytics:latest', - command: 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"', - networks: [`${docker.network}`], - volumes: [`${deployId}-postgres-data:/var/lib/postgresql/data`], - environment: generateEnvsClickhouse, - deploy: { - ...baseServiceConfiguration, - labels: [ - 'managedBy=coolify', - 'type=service', - 'serviceName=plausible', - 'configuration=' + JSON.stringify({ email, userName, userPassword, baseURL, secretKey, generateEnvsPostgres, generateEnvsClickhouse }), - 'traefik.enable=true', - 'traefik.http.services.' + - deployId + - '.loadbalancer.server.port=8000', - 'traefik.http.routers.' + - deployId + - '.entrypoints=websecure', - 'traefik.http.routers.' + - deployId + - '.rule=Host(`' + - traefikURL + - '`) && PathPrefix(`/`)', - 'traefik.http.routers.' + - deployId + - '.tls.certresolver=letsencrypt', - 'traefik.http.routers.' + - deployId + - '.middlewares=global-compress' - ] - } - }, - plausible_db: { - image: 'bitnami/postgresql:13.2.0', - networks: [`${docker.network}`], - environment: generateEnvsPostgres, - deploy: { - ...baseServiceConfiguration, - labels: [ - 'managedBy=coolify', - 'type=service', - 'serviceName=plausible' - ] - } - }, - plausible_events_db: { - image: 'yandex/clickhouse-server:21.3.2.5', - networks: [`${docker.network}`], - volumes: [`${deployId}-clickhouse-data:/var/lib/clickhouse`], - ulimits: { - nofile: { - soft: 262144, - hard: 262144 - } - }, - configs: [...clickhouseConfigs], - deploy: { - ...baseServiceConfiguration, - labels: [ - 'managedBy=coolify', - 'type=service', - 'serviceName=plausible' - ] - } - } - }, - networks: { - [`${docker.network}`]: { - external: true - } - }, - volumes: { - [`${deployId}-clickhouse-data`]: { - external: true - }, - [`${deployId}-postgres-data`]: { - external: true - } - }, - configs: { - 'plausible-clickhouse-user-config.xml': { - file: `${workdir}/clickhouse-user-config.xml` - }, - 'plausible-clickhouse-config.xml': { - file: `${workdir}/clickhouse-config.xml` - }, - 'plausible-init.query': { - file: `${workdir}/init.query` - }, - 'plausible-init-db.sh': { - file: `${workdir}/init-db.sh` - } - } - } - await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack)) - await execShellAsync('docker stack rm plausible') - await execShellAsync( - `cat ${workdir}/stack.yml | docker stack deploy --prune -c - ${deployId}` - ) - cleanupTmp(workdir) -} - -async function activateAdminUser () { - const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse(JSON.parse((await execShellAsync('docker service inspect plausible_plausible --format=\'{{json .Spec.Labels.configuration}}\'')))).generateEnvsPostgres - const containers = (await execShellAsync('docker ps -a --format=\'{{json .Names}}\'')).replace(/"/g, '').trim().split('\n') - const postgresDB = containers.find(container => container.startsWith('plausible_plausible_db')) - await execShellAsync(`docker exec ${postgresDB} psql -H postgresql://${POSTGRESQL_USERNAME}:${POSTGRESQL_PASSWORD}@localhost:5432/${POSTGRESQL_DATABASE} -c "UPDATE users SET email_verified = true;"`) -} - -module.exports = { plausible, activateAdminUser } diff --git a/api/models/Deployment.js b/api/models/Deployment.js deleted file mode 100644 index 496b5c020f..0000000000 --- a/api/models/Deployment.js +++ /dev/null @@ -1,16 +0,0 @@ -const mongoose = require('mongoose') -const deploymentSchema = mongoose.Schema( - { - deployId: { type: String, required: true }, - nickname: { type: String, required: true }, - repoId: { type: Number, required: true }, - organization: { type: String, required: true }, - name: { type: String, required: true }, - branch: { type: String, required: true }, - domain: { type: String, required: true }, - progress: { type: String, require: true, default: 'queued' } - }, - { timestamps: true } -) - -module.exports = mongoose.model('deployment', deploymentSchema) diff --git a/api/models/Logs/Application.js b/api/models/Logs/Application.js deleted file mode 100644 index eb797ca367..0000000000 --- a/api/models/Logs/Application.js +++ /dev/null @@ -1,10 +0,0 @@ -const mongoose = require('mongoose') -const logSchema = mongoose.Schema( - { - deployId: { type: String, required: true }, - event: { type: String, required: true } - }, - { timestamps: { createdAt: 'createdAt', updatedAt: false } } -) - -module.exports = mongoose.model('logs-application', logSchema) diff --git a/api/models/Logs/Server.js b/api/models/Logs/Server.js deleted file mode 100644 index a5abc460e3..0000000000 --- a/api/models/Logs/Server.js +++ /dev/null @@ -1,14 +0,0 @@ -const mongoose = require('mongoose') -const { version } = require('../../../package.json') -const logSchema = mongoose.Schema( - { - version: { type: String, default: version }, - type: { type: String, required: true }, - message: { type: String, required: true }, - stack: { type: String }, - seen: { type: Boolean, default: false } - }, - { timestamps: { createdAt: 'createdAt', updatedAt: false } } -) - -module.exports = mongoose.model('logs-server', logSchema) diff --git a/api/models/Settings.js b/api/models/Settings.js deleted file mode 100644 index c6d424364e..0000000000 --- a/api/models/Settings.js +++ /dev/null @@ -1,12 +0,0 @@ -const mongoose = require('mongoose') - -const settingsSchema = mongoose.Schema( - { - applicationName: { type: String, required: true, default: 'coolify' }, - allowRegistration: { type: Boolean, required: true, default: false }, - sendErrors: { type: Boolean, required: true, default: true } - }, - { timestamps: true } -) - -module.exports = mongoose.model('settings', settingsSchema) diff --git a/api/models/User.js b/api/models/User.js deleted file mode 100644 index 84fbf8b00e..0000000000 --- a/api/models/User.js +++ /dev/null @@ -1,12 +0,0 @@ -const mongoose = require('mongoose') - -const userSchema = mongoose.Schema( - { - email: { type: String, required: true }, - avatar: { type: String }, - uid: { type: String, required: true } - }, - { timestamps: true } -) - -module.exports = mongoose.model('user', userSchema) diff --git a/api/plugins/authentication.js b/api/plugins/authentication.js deleted file mode 100644 index 4cbde66854..0000000000 --- a/api/plugins/authentication.js +++ /dev/null @@ -1,21 +0,0 @@ -const fp = require('fastify-plugin') -const User = require('../models/User') -module.exports = fp(async function (fastify, options, next) { - fastify.register(require('fastify-jwt'), { - secret: fastify.config.JWT_SIGN_KEY - }) - fastify.addHook('onRequest', async (request, reply) => { - try { - const { jti } = await request.jwtVerify() - const found = await User.findOne({ uid: jti }) - if (found) { - return true - } else { - reply.code(401).send('Unauthorized') - } - } catch (err) { - reply.code(401).send('Unauthorized') - } - }) - next() -}) diff --git a/api/routes/v1/application/check.js b/api/routes/v1/application/check.js deleted file mode 100644 index 0ea8eb853c..0000000000 --- a/api/routes/v1/application/check.js +++ /dev/null @@ -1,37 +0,0 @@ - -const { setDefaultConfiguration } = require('../../../libs/applications/configuration') -const { docker } = require('../../../libs/docker') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - fastify.post('/', async (request, reply) => { - try { - const configuration = setDefaultConfiguration(request.body) - - const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') - let foundDomain = false - - for (const service of services) { - const running = JSON.parse(service.Spec.Labels.configuration) - if (running) { - if ( - running.publish.domain === configuration.publish.domain && - running.repository.id !== configuration.repository.id && - running.publish.path === configuration.publish.path - ) { - foundDomain = true - } - } - } - if (fastify.config.DOMAIN === configuration.publish.domain) foundDomain = true - if (foundDomain) { - reply.code(500).send({ message: 'Domain already in use.' }) - return - } - return { message: 'OK' } - } catch (error) { - await saveServerLog(error) - throw new Error(error) - } - }) -} diff --git a/api/routes/v1/application/deploy/index.js b/api/routes/v1/application/deploy/index.js deleted file mode 100644 index 9b2751afd3..0000000000 --- a/api/routes/v1/application/deploy/index.js +++ /dev/null @@ -1,69 +0,0 @@ - -const Deployment = require('../../../../models/Deployment') -const ApplicationLog = require('../../../../models/Logs/Application') -const { verifyUserId, cleanupTmp } = require('../../../../libs/common') -const { purgeImagesContainers } = require('../../../../libs/applications/cleanup') -const { queueAndBuild } = require('../../../../libs/applications') -const { setDefaultConfiguration, precheckDeployment } = require('../../../../libs/applications/configuration') -const { docker } = require('../../../../libs/docker') -const { saveServerLog } = require('../../../../libs/logging') -const cloneRepository = require('../../../../libs/applications/github/cloneRepository') - -module.exports = async function (fastify) { - fastify.post('/', async (request, reply) => { - let configuration - try { - await verifyUserId(request.headers.authorization) - } catch (error) { - reply.code(500).send({ error: 'Invalid request' }) - return - } - try { - const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') - configuration = setDefaultConfiguration(request.body) - if (!configuration) { - throw new Error('Whaat?') - } - await cloneRepository(configuration) - const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ services, configuration }) - - if (foundService && !forceUpdate && !imageChanged && !configChanged) { - cleanupTmp(configuration.general.workdir) - reply.code(500).send({ message: 'Nothing changed, no need to redeploy.' }) - return - } - - const alreadyQueued = await Deployment.find({ - 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) { - reply.code(200).send({ message: 'Already in the queue.' }) - return - } - - reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name, deployId: configuration.general.deployId }) - await queueAndBuild(configuration, imageChanged) - } catch (error) { - const { id, organization, name, branch } = configuration.repository - const { domain } = configuration.publish - const { deployId } = configuration.general - await Deployment.findOneAndUpdate( - { repoId: id, branch, deployId, organization, name, domain }, - { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }) - if (error.name) { - if (error.message && error.stack) await saveServerLog(error) - if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() - } - throw new Error(error) - } finally { - cleanupTmp(configuration.general.workdir) - await purgeImagesContainers(configuration) - } - }) -} diff --git a/api/routes/v1/application/deploy/logs.js b/api/routes/v1/application/deploy/logs.js deleted file mode 100644 index da4e4b38b3..0000000000 --- a/api/routes/v1/application/deploy/logs.js +++ /dev/null @@ -1,66 +0,0 @@ -const ApplicationLog = require('../../../../models/Logs/Application') -const Deployment = require('../../../../models/Deployment') -const dayjs = require('dayjs') -const utc = require('dayjs/plugin/utc') -const relativeTime = require('dayjs/plugin/relativeTime') -dayjs.extend(utc) -dayjs.extend(relativeTime) - -module.exports = async function (fastify) { - const getLogSchema = { - querystring: { - type: 'object', - properties: { - repoId: { type: 'string' }, - branch: { type: 'string' } - }, - required: ['repoId', 'branch'] - } - } - fastify.get('/', { schema: getLogSchema }, async (request, reply) => { - try { - const { repoId, branch, page } = request.query - const onePage = 5 - const show = Number(page) * onePage || 5 - const deploy = await Deployment.find({ repoId, branch }) - .select('-_id -__v -repoId') - .sort({ createdAt: 'desc' }) - .limit(show) - - const finalLogs = deploy.map(d => { - const finalLogs = { ...d._doc } - - const updatedAt = dayjs(d.updatedAt).utc() - - finalLogs.took = updatedAt.diff(dayjs(d.createdAt)) / 1000 - finalLogs.since = updatedAt.fromNow() - - return finalLogs - }) - return finalLogs - } catch (error) { - throw new Error(error) - } - }) - - fastify.get('/:deployId', async (request, reply) => { - const { deployId } = request.params - try { - const logs = await ApplicationLog.find({ deployId }) - .select('-_id -__v') - .sort({ createdAt: 'asc' }) - - const deploy = await Deployment.findOne({ deployId }) - .select('-_id -__v') - .sort({ createdAt: 'desc' }) - - const finalLogs = {} - finalLogs.progress = deploy.progress - finalLogs.events = logs.map(log => log.event) - finalLogs.human = dayjs(deploy.updatedAt).from(dayjs(deploy.updatedAt)) - return finalLogs - } catch (e) { - throw new Error('No logs found') - } - }) -} diff --git a/api/routes/v1/application/logs.js b/api/routes/v1/application/logs.js deleted file mode 100644 index 155f888414..0000000000 --- a/api/routes/v1/application/logs.js +++ /dev/null @@ -1,16 +0,0 @@ -const { docker } = require('../../../libs/docker') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - try { - const { name } = request.query - const service = await docker.engine.getService(`${name}_${name}`) - const logs = (await service.logs({ stdout: true, stderr: true, timestamps: true })).toString().split('\n').map(l => l.slice(8)).filter((a) => a) - return { logs } - } catch (error) { - await saveServerLog(error) - throw new Error(error) - } - }) -} diff --git a/api/routes/v1/application/remove.js b/api/routes/v1/application/remove.js deleted file mode 100644 index 90d7d21224..0000000000 --- a/api/routes/v1/application/remove.js +++ /dev/null @@ -1,38 +0,0 @@ -const { docker } = require('../../../libs/docker') -const { execShellAsync, delay } = require('../../../libs/common') -const ApplicationLog = require('../../../models/Logs/Application') -const Deployment = require('../../../models/Deployment') -const { purgeImagesContainers } = require('../../../libs/applications/cleanup') - -module.exports = async function (fastify) { - fastify.post('/', async (request, reply) => { - const { organization, name, branch } = request.body - let found = false - try { - (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application').map(s => { - const running = JSON.parse(s.Spec.Labels.configuration) - if (running.repository.organization === organization && - running.repository.name === name && - running.repository.branch === branch) { - found = running - } - return null - }) - if (found) { - const deploys = await Deployment.find({ organization, branch, name }) - for (const deploy of deploys) { - await ApplicationLog.deleteMany({ deployId: deploy.deployId }) - await Deployment.deleteMany({ deployId: deploy.deployId }) - } - await execShellAsync(`docker stack rm ${found.build.container.name}`) - reply.code(200).send({ organization, name, branch }) - await delay(10000) - await purgeImagesContainers(found, true) - } else { - reply.code(500).send({ message: 'Nothing to do.' }) - } - } catch (error) { - reply.code(500).send({ message: 'Nothing to do.' }) - } - }) -} diff --git a/api/routes/v1/config.js b/api/routes/v1/config.js deleted file mode 100644 index 8a9543c062..0000000000 --- a/api/routes/v1/config.js +++ /dev/null @@ -1,28 +0,0 @@ -const { docker } = require('../../libs/docker') - -module.exports = async function (fastify) { - fastify.post('/', async (request, reply) => { - const { name, organization, branch } = request.body - const services = await docker.engine.listServices() - const applications = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') - - const found = applications.find(r => { - const configuration = r.Spec.Labels.configuration ? JSON.parse(r.Spec.Labels.configuration) : null - if (branch) { - if (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 - }) - if (found) { - return JSON.parse(found.Spec.Labels.configuration) - } else { - reply.code(500).send({ message: 'No configuration found.' }) - } - }) -} diff --git a/api/routes/v1/dashboard/index.js b/api/routes/v1/dashboard/index.js deleted file mode 100644 index 7cb7830310..0000000000 --- a/api/routes/v1/dashboard/index.js +++ /dev/null @@ -1,61 +0,0 @@ -const { docker } = require('../../../libs/docker') -const ServerLog = require('../../../models/Logs/Server') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - try { - const serverLogs = await ServerLog.find() - const dockerServices = await docker.engine.listServices() - let applications = dockerServices.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' && r.Spec.Labels.configuration) - let databases = dockerServices.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'database' && r.Spec.Labels.configuration) - let services = dockerServices.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'service' && r.Spec.Labels.configuration) - applications = applications.map(r => { - if (JSON.parse(r.Spec.Labels.configuration)) { - return { - configuration: JSON.parse(r.Spec.Labels.configuration), - UpdatedAt: r.UpdatedAt - } - } - return {} - }) - databases = databases.map(r => { - if (JSON.parse(r.Spec.Labels.configuration)) { - return { - configuration: JSON.parse(r.Spec.Labels.configuration) - } - } - return {} - }) - services = services.map(r => { - if (JSON.parse(r.Spec.Labels.configuration)) { - return { - serviceName: r.Spec.Labels.serviceName, - configuration: JSON.parse(r.Spec.Labels.configuration) - } - } - return {} - }) - applications = [...new Map(applications.map(item => [item.configuration.publish.domain + item.configuration.publish.path, item])).values()] - return { - serverLogs, - applications: { - deployed: applications - }, - databases: { - deployed: databases - }, - services: { - deployed: services - } - } - } catch (error) { - if (error.code === 'ENOENT' && error.errno === -2) { - throw new Error(`Docker service unavailable at ${error.address}.`) - } else { - await saveServerLog(error) - throw new Error(error) - } - } - }) -} diff --git a/api/routes/v1/databases/index.js b/api/routes/v1/databases/index.js deleted file mode 100644 index 01c0a212c7..0000000000 --- a/api/routes/v1/databases/index.js +++ /dev/null @@ -1,192 +0,0 @@ -const yaml = require('js-yaml') -const fs = require('fs').promises -const cuid = require('cuid') -const { docker } = require('../../../libs/docker') -const { execShellAsync } = require('../../../libs/common') -const { saveServerLog } = require('../../../libs/logging') - -const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator') -const generator = require('generate-password') - -function getUniq () { - return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 }) -} -module.exports = async function (fastify) { - fastify.get('/:deployId', async (request, reply) => { - const { deployId } = request.params - try { - const database = (await docker.engine.listServices()).find(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'database' && JSON.parse(r.Spec.Labels.configuration).general.deployId === deployId) - if (database) { - const jsonEnvs = {} - if (database.Spec.TaskTemplate.ContainerSpec.Env) { - for (const d of database.Spec.TaskTemplate.ContainerSpec.Env) { - const s = d.split('=') - jsonEnvs[s[0]] = s[1] - } - } - const payload = { - config: JSON.parse(database.Spec.Labels.configuration), - envs: jsonEnvs || null - } - reply.code(200).send(payload) - } else { - throw new Error() - } - } catch (error) { - throw new Error('No database found?') - } - }) - - const postSchema = { - body: { - type: 'object', - properties: { - type: { type: 'string', enum: ['mongodb', 'postgresql', 'mysql', 'couchdb', 'clickhouse'] } - }, - required: ['type'] - } - } - - fastify.post('/deploy', { schema: postSchema }, async (request, reply) => { - try { - let { type, defaultDatabaseName } = request.body - const passwords = generator.generateMultiple(2, { - length: 24, - numbers: true, - strict: true - }) - const usernames = generator.generateMultiple(2, { - length: 10, - numbers: true, - strict: true - }) - // TODO: Query for existing db with the same name - const nickname = getUniq() - - if (!defaultDatabaseName) defaultDatabaseName = nickname - - reply.code(201).send({ message: 'Deploying.' }) - const deployId = cuid() - const configuration = { - general: { - workdir: `/tmp/${deployId}`, - deployId, - nickname, - type - }, - database: { - usernames, - passwords, - defaultDatabaseName - }, - deploy: { - name: nickname - } - } - await execShellAsync(`mkdir -p ${configuration.general.workdir}`) - let generateEnvs = {} - let image = null - let volume = null - let ulimits = {} - if (type === 'mongodb') { - generateEnvs = { - MONGODB_ROOT_PASSWORD: passwords[0], - MONGODB_USERNAME: usernames[0], - MONGODB_PASSWORD: passwords[1], - MONGODB_DATABASE: defaultDatabaseName - } - image = 'bitnami/mongodb:4.4' - volume = `${configuration.general.deployId}-${type}-data:/bitnami/mongodb` - } else if (type === 'postgresql') { - generateEnvs = { - POSTGRESQL_PASSWORD: passwords[0], - POSTGRESQL_USERNAME: usernames[0], - POSTGRESQL_DATABASE: defaultDatabaseName - } - image = 'bitnami/postgresql:13.2.0' - volume = `${configuration.general.deployId}-${type}-data:/bitnami/postgresql` - } else if (type === 'couchdb') { - generateEnvs = { - COUCHDB_PASSWORD: passwords[0], - COUCHDB_USER: usernames[0] - } - image = 'bitnami/couchdb:3' - volume = `${configuration.general.deployId}-${type}-data:/bitnami/couchdb` - } else if (type === 'mysql') { - generateEnvs = { - MYSQL_ROOT_PASSWORD: passwords[0], - MYSQL_ROOT_USER: usernames[0], - MYSQL_USER: usernames[1], - MYSQL_PASSWORD: passwords[1], - MYSQL_DATABASE: defaultDatabaseName - } - image = 'bitnami/mysql:8.0' - volume = `${configuration.general.deployId}-${type}-data:/bitnami/mysql/data` - } else if (type === 'clickhouse') { - image = 'yandex/clickhouse-server' - volume = `${configuration.general.deployId}-${type}-data:/var/lib/clickhouse` - ulimits = { - nofile: { - soft: 262144, - hard: 262144 - } - } - } - - const stack = { - version: '3.8', - services: { - [configuration.general.deployId]: { - image, - networks: [`${docker.network}`], - environment: generateEnvs, - volumes: [volume], - ulimits, - deploy: { - replicas: 1, - update_config: { - parallelism: 0, - delay: '10s', - order: 'start-first' - }, - rollback_config: { - parallelism: 0, - delay: '10s', - order: 'start-first' - }, - labels: [ - 'managedBy=coolify', - 'type=database', - 'configuration=' + JSON.stringify(configuration) - ] - } - } - }, - networks: { - [`${docker.network}`]: { - external: true - } - }, - volumes: { - [`${configuration.general.deployId}-${type}-data`]: { - external: true - } - } - } - await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack)) - await execShellAsync( - `cat ${configuration.general.workdir}/stack.yml | docker stack deploy -c - ${configuration.general.deployId}` - ) - } catch (error) { - console.log(error) - await saveServerLog(error) - throw new Error(error) - } - }) - - fastify.delete('/:dbName', async (request, reply) => { - const { dbName } = request.params - await execShellAsync(`docker stack rm ${dbName}`) - reply.code(200).send({}) - }) -} diff --git a/api/routes/v1/login/github.js b/api/routes/v1/login/github.js deleted file mode 100644 index bd621faad7..0000000000 --- a/api/routes/v1/login/github.js +++ /dev/null @@ -1,127 +0,0 @@ -const axios = require('axios') -const User = require('../../../models/User') -const Settings = require('../../../models/Settings') -const cuid = require('cuid') -const mongoose = require('mongoose') -const jwt = require('jsonwebtoken') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - const githubCodeSchema = { - schema: { - querystring: { - type: 'object', - properties: { - code: { type: 'string' } - }, - required: ['code'] - } - } - } - fastify.get('/app', { schema: githubCodeSchema }, async (request, reply) => { - const { code } = request.query - try { - const { data } = await axios({ - method: 'post', - url: `https://github.com/login/oauth/access_token?client_id=${fastify.config.VITE_GITHUB_APP_CLIENTID}&client_secret=${fastify.config.GITHUB_APP_CLIENT_SECRET}&code=${code}`, - headers: { - accept: 'application/json' - } - }) - - const token = data.access_token - const githubAxios = axios.create({ - baseURL: 'https://api.github.com' - }) - - githubAxios.defaults.headers.common.Accept = 'Application/json' - githubAxios.defaults.headers.common.Authorization = `token ${token}` - - try { - let uid = cuid() - const { avatar_url } = (await githubAxios.get('/user')).data // eslint-disable-line - const email = (await githubAxios.get('/user/emails')).data.filter( - (e) => e.primary - )[0].email - const settings = await Settings.findOne({ applicationName: 'coolify' }) - const registeredUsers = await User.find().countDocuments() - const foundUser = await User.findOne({ email }) - if (foundUser) { - await User.findOneAndUpdate( - { email }, - { avatar: avatar_url }, - { upsert: true, new: true } - ) - uid = foundUser.uid - } else { - if (registeredUsers === 0) { - const newUser = new User({ - _id: new mongoose.Types.ObjectId(), - email, - avatar: avatar_url, - uid - }) - const defaultSettings = new Settings({ - _id: new mongoose.Types.ObjectId() - }) - try { - await newUser.save() - await defaultSettings.save() - } catch (e) { - console.log(e) - reply.code(500).send({ success: false, error: e }) - return - } - } else { - if (!settings && registeredUsers > 0) { - reply.code(500).send('Registration disabled, enable it in settings.') - } else { - if (!settings.allowRegistration) { - reply.code(500).send('You are not allowed here!') - } else { - const newUser = new User({ - _id: new mongoose.Types.ObjectId(), - email, - avatar: avatar_url, - uid - }) - try { - await newUser.save() - } catch (e) { - console.log(e) - reply.code(500).send({ success: false, error: e }) - return - } - } - } - } - } - const jwtToken = jwt.sign({}, fastify.config.JWT_SIGN_KEY, { - expiresIn: 15778800, - algorithm: 'HS256', - audience: 'coolLabs', - issuer: 'coolLabs', - jwtid: uid, - subject: `User:${uid}`, - notBefore: -1000 - }) - reply - .code(200) - .redirect( - 302, - `/api/v1/login/github/success?jwtToken=${jwtToken}&ghToken=${token}` - ) - } catch (e) { - console.log(e) - reply.code(500).send({ success: false, error: e }) - return - } - } catch (error) { - await saveServerLog(error) - throw new Error(error) - } - }) - fastify.get('/success', async (request, reply) => { - return reply.sendFile('bye.html') - }) -} diff --git a/api/routes/v1/server/index.js b/api/routes/v1/server/index.js deleted file mode 100644 index 278b9a3bf1..0000000000 --- a/api/routes/v1/server/index.js +++ /dev/null @@ -1,14 +0,0 @@ -const Server = require('../../../models/Logs/Server') -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - try { - const serverLogs = await Server.find().select('-_id -__v') - // TODO: Should do better - return { - serverLogs - } - } catch (error) { - throw new Error(error) - } - }) -} diff --git a/api/routes/v1/services/deploy.js b/api/routes/v1/services/deploy.js deleted file mode 100644 index 481bf8b9b0..0000000000 --- a/api/routes/v1/services/deploy.js +++ /dev/null @@ -1,15 +0,0 @@ -const { plausible, activateAdminUser } = require('../../../libs/services/plausible') - -module.exports = async function (fastify) { - fastify.post('/plausible', async (request, reply) => { - let { email, userName, userPassword, baseURL } = request.body - const traefikURL = baseURL - baseURL = `https://${baseURL}` - await plausible({ email, userName, userPassword, baseURL, traefikURL }) - return {} - }) - fastify.patch('/plausible/activate', async (request, reply) => { - await activateAdminUser() - return 'OK' - }) -} diff --git a/api/routes/v1/services/index.js b/api/routes/v1/services/index.js deleted file mode 100644 index b9a5501f15..0000000000 --- a/api/routes/v1/services/index.js +++ /dev/null @@ -1,27 +0,0 @@ -const { execShellAsync } = require('../../../libs/common') -const { docker } = require('../../../libs/docker') - -module.exports = async function (fastify) { - fastify.get('/:serviceName', async (request, reply) => { - const { serviceName } = request.params - try { - const service = (await docker.engine.listServices()).find(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'service' && r.Spec.Labels.serviceName === serviceName && r.Spec.Name === `${serviceName}_${serviceName}`) - if (service) { - const payload = { - config: JSON.parse(service.Spec.Labels.configuration) - } - reply.code(200).send(payload) - } else { - throw new Error() - } - } catch (error) { - console.log(error) - throw new Error('No service found?') - } - }) - fastify.delete('/:serviceName', async (request, reply) => { - const { serviceName } = request.params - await execShellAsync(`docker stack rm ${serviceName}`) - reply.code(200).send({}) - }) -} diff --git a/api/routes/v1/settings/index.js b/api/routes/v1/settings/index.js deleted file mode 100644 index 7a5dbd59d5..0000000000 --- a/api/routes/v1/settings/index.js +++ /dev/null @@ -1,49 +0,0 @@ -const Settings = require('../../../models/Settings') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - const applicationName = 'coolify' - const postSchema = { - body: { - type: 'object', - properties: { - allowRegistration: { type: 'boolean' }, - sendErrors: { type: 'boolean' } - }, - required: [] - } - } - - fastify.get('/', async (request, reply) => { - try { - let settings = await Settings.findOne({ applicationName }).select('-_id -__v') - // TODO: Should do better - if (!settings) { - settings = { - applicationName, - allowRegistration: false - } - } - return { - settings - } - } catch (error) { - await saveServerLog(error) - throw new Error(error) - } - }) - - fastify.post('/', { schema: postSchema }, async (request, reply) => { - try { - const settings = await Settings.findOneAndUpdate( - { applicationName }, - { applicationName, ...request.body }, - { upsert: true, new: true } - ).select('-_id -__v') - reply.code(201).send({ settings }) - } catch (error) { - await saveServerLog(error) - throw new Error(error) - } - }) -} diff --git a/api/routes/v1/undead.js b/api/routes/v1/undead.js deleted file mode 100644 index 61b25391e0..0000000000 --- a/api/routes/v1/undead.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - reply.code(200).send('NO') - }) -} diff --git a/api/routes/v1/upgrade/index.js b/api/routes/v1/upgrade/index.js deleted file mode 100644 index 49c3c016ee..0000000000 --- a/api/routes/v1/upgrade/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const { execShellAsync } = require('../../../libs/common') -const { saveServerLog } = require('../../../libs/logging') - -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - const upgradeP1 = await execShellAsync('bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p1.sh)"') - await saveServerLog({ message: upgradeP1, type: 'UPGRADE-P-1' }) - reply.code(200).send('I\'m trying, okay?') - const upgradeP2 = await execShellAsync('docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -u root coolify bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p2.sh)"') - await saveServerLog({ message: upgradeP2, type: 'UPGRADE-P-2' }) - }) -} diff --git a/api/routes/v1/verify.js b/api/routes/v1/verify.js deleted file mode 100644 index 1122d43ab2..0000000000 --- a/api/routes/v1/verify.js +++ /dev/null @@ -1,20 +0,0 @@ -const User = require('../../models/User') -const jwt = require('jsonwebtoken') - -module.exports = async function (fastify) { - fastify.get('/', async (request, reply) => { - try { - const { authorization } = request.headers - if (!authorization) { - reply.code(401).send({}) - return - } - const token = authorization.split(' ')[1] - const verify = jwt.verify(token, fastify.config.JWT_SIGN_KEY) - const found = await User.findOne({ uid: verify.jti }) - found ? reply.code(200).send({}) : reply.code(401).send({}) - } catch (error) { - reply.code(401).send({}) - } - }) -} diff --git a/api/routes/v1/webhooks/deploy.js b/api/routes/v1/webhooks/deploy.js deleted file mode 100644 index d3bcdb9826..0000000000 --- a/api/routes/v1/webhooks/deploy.js +++ /dev/null @@ -1,121 +0,0 @@ -const crypto = require('crypto') -const { cleanupTmp } = require('../../../libs/common') - -const Deployment = require('../../../models/Deployment') -const ApplicationLog = require('../../../models/Logs/Application') -const ServerLog = require('../../../models/Logs/Server') - -const { queueAndBuild } = require('../../../libs/applications') -const { setDefaultConfiguration, precheckDeployment } = require('../../../libs/applications/configuration') -const { docker } = require('../../../libs/docker') -const cloneRepository = require('../../../libs/applications/github/cloneRepository') -const { purgeImagesContainers } = require('../../../libs/applications/cleanup') - -module.exports = async function (fastify) { - const postSchema = { - body: { - type: 'object', - properties: { - ref: { type: 'string' }, - repository: { - type: 'object', - properties: { - id: { type: 'number' }, - full_name: { type: 'string' } - }, - required: ['id', 'full_name'] - }, - installation: { - type: 'object', - properties: { - id: { type: 'number' } - }, - required: ['id'] - } - }, - required: ['ref', 'repository', 'installation'] - } - } - fastify.post('/', { schema: postSchema }, async (request, reply) => { - let configuration - const hmac = crypto.createHmac('sha256', fastify.config.GITHUP_APP_WEBHOOK_SECRET) - const digest = Buffer.from('sha256=' + hmac.update(JSON.stringify(request.body)).digest('hex'), 'utf8') - const checksum = Buffer.from(request.headers['x-hub-signature-256'], 'utf8') - if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) { - reply.code(500).send({ error: 'Invalid request' }) - return - } - - if (request.headers['x-github-event'] !== 'push') { - reply.code(500).send({ error: 'Not a push event.' }) - return - } - try { - const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') - - configuration = services.find(r => { - if (request.body.ref.startsWith('refs')) { - const branch = request.body.ref.split('/')[2] - if ( - JSON.parse(r.Spec.Labels.configuration).repository.id === request.body.repository.id && - JSON.parse(r.Spec.Labels.configuration).repository.branch === branch - ) { - return r - } - } - - return null - }) - if (!configuration) { - reply.code(500).send({ error: 'No configuration found.' }) - return - } - - configuration = setDefaultConfiguration(JSON.parse(configuration.Spec.Labels.configuration)) - await cloneRepository(configuration) - const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ services, configuration }) - - if (foundService && !forceUpdate && !imageChanged && !configChanged) { - cleanupTmp(configuration.general.workdir) - reply.code(500).send({ message: 'Nothing changed, no need to redeploy.' }) - return - } - const alreadyQueued = await Deployment.find({ - 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) { - reply.code(200).send({ message: 'Already in the queue.' }) - return - } - - reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name }) - await queueAndBuild(configuration, imageChanged) - } catch (error) { - const { id, organization, name, branch } = configuration.repository - const { domain } = configuration.publish - const { deployId } = configuration.general - await Deployment.findOneAndUpdate( - { repoId: id, branch, deployId, organization, name, domain }, - { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' }) - if (error.name === 'Error') { - // Error during runtime - await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() - } else { - // Error in my code - const payload = { message: error.message, stack: error.stack, type: 'spaghetticode' } - if (error.message && error.stack) await new ServerLog(payload).save() - if (reply.sent) await new ApplicationLog({ repoId: id, branch, deployId, event: `[ERROR 😖]: ${error.stack}` }).save() - } - throw new Error(error) - } finally { - cleanupTmp(configuration.general.workdir) - await purgeImagesContainers(configuration) - } - }) -} diff --git a/api/schema.js b/api/schema.js deleted file mode 100644 index fb672b5603..0000000000 --- a/api/schema.js +++ /dev/null @@ -1,49 +0,0 @@ -const schema = { - type: 'object', - required: [ - 'DOMAIN', - 'EMAIL', - 'VITE_GITHUB_APP_CLIENTID', - 'GITHUB_APP_CLIENT_SECRET', - 'GITHUB_APP_PRIVATE_KEY', - 'GITHUP_APP_WEBHOOK_SECRET', - 'JWT_SIGN_KEY', - 'SECRETS_ENCRYPTION_KEY' - ], - properties: { - DOMAIN: { - type: 'string' - }, - EMAIL: { - type: 'string' - }, - VITE_GITHUB_APP_CLIENTID: { - type: 'string' - }, - GITHUB_APP_CLIENT_SECRET: { - type: 'string' - }, - GITHUB_APP_PRIVATE_KEY: { - type: 'string' - }, - GITHUP_APP_WEBHOOK_SECRET: { - type: 'string' - }, - JWT_SIGN_KEY: { - type: 'string' - }, - DOCKER_ENGINE: { - type: 'string', - default: '/var/run/docker.sock' - }, - DOCKER_NETWORK: { - type: 'string', - default: 'coollabs' - }, - SECRETS_ENCRYPTION_KEY: { - type: 'string' - } - } -} - -module.exports = { schema } diff --git a/api/server.js b/api/server.js deleted file mode 100644 index c1254faef5..0000000000 --- a/api/server.js +++ /dev/null @@ -1,109 +0,0 @@ -require('dotenv').config() -const fs = require('fs') -const util = require('util') -const mongoose = require('mongoose') -const path = require('path') -const { saveServerLog } = require('./libs/logging') -const { execShellAsync } = require('./libs/common') -const { cleanupStuckedDeploymentsInDB } = require('./libs/applications/cleanup') -const fastify = require('fastify')({ - trustProxy: true, - logger: { - level: 'error' - } -}) -fastify.register(require('../api/libs/http-error')) - -const { schema } = require('./schema') - -process.on('unhandledRejection', async (reason, p) => { - await saveServerLog({ message: reason.message, type: 'unhandledRejection' }) -}) - -fastify.register(require('fastify-env'), { - schema, - dotenv: true -}) - -if (process.env.NODE_ENV === 'production') { - fastify.register(require('fastify-static'), { - root: path.join(__dirname, '../dist/') - }) - - fastify.setNotFoundHandler(function (request, reply) { - reply.sendFile('index.html') - }) -} else { - fastify.register(require('fastify-static'), { - root: path.join(__dirname, '../public/') - }) -} - -fastify.register(require('./app'), { prefix: '/api/v1' }) - -if (process.env.NODE_ENV === 'production') { - mongoose.connect( - `mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DB}?authSource=${process.env.MONGODB_DB}&readPreference=primary&ssl=false`, - { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false } - ) -} else { - mongoose.connect( - 'mongodb://localhost:27017/coolify?&readPreference=primary&ssl=false', - { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false } - ) -} - -mongoose.connection.on( - 'error', - console.error.bind(console, 'connection error:') -) -mongoose.connection.once('open', async function () { - if (process.env.NODE_ENV === 'production') { - fastify.listen(3000, '0.0.0.0') - console.log('Coolify API is up and running in production.') - } else { - const logFile = fs.createWriteStream('api/development/console.log', { flags: 'w' }) - const logStdout = process.stdout - - console.log = function (d) { - logFile.write(`[INFO]: ${util.format(d)}\n`) - logStdout.write(util.format(d) + '\n') - } - - console.error = function (d) { - logFile.write(`[ERROR]: ${util.format(d)}\n`) - logStdout.write(util.format(d) + '\n') - } - - console.warn = function (d) { - logFile.write(`[WARN]: ${util.format(d)}\n`) - logStdout.write(util.format(d) + '\n') - } - - fastify.listen(3001) - console.log('Coolify API is up and running in development.') - } - try { - // Always cleanup server logs - await mongoose.connection.db.dropCollection('logs-servers') - } catch (error) { - // Could not cleanup logs-servers collection - } - // On start cleanup inprogress/queued deployments. - try { - await cleanupStuckedDeploymentsInDB() - } catch (error) { - // Could not cleanup DB 🤔 - } - try { - // Doing because I do not want to prune these images. Prune skips coolify-reserve labeled images. - const basicImages = ['nginx:stable-alpine', 'node:lts', 'ubuntu:20.04', 'php:apache', 'rust:latest'] - for (const image of basicImages) { - // await execShellAsync(`echo "FROM ${image}" | docker build --label coolify-reserve=true -t ${image} -`) - await execShellAsync(`docker pull ${image}`) - } - } catch (error) { - console.log('Could not pull some basic images from Docker Hub.') - console.log(error) - } -}) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000000..57cc0f1fb9 --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,84 @@ +version: '3.8' + +services: + proxy: + image: traefik:v2.4 + hostname: coollabs-proxy + ports: + - target: 80 + published: 80 + protocol: tcp + mode: host + - target: 443 + published: 443 + protocol: tcp + mode: host + - target: 8080 + published: 8080 + protocol: tcp + mode: host + command: + - --api.insecure=true + - --api.dashboard=true + - --api.debug=true + - --log.level=ERROR + - --providers.docker=true + - --providers.docker.swarmMode=true + - --providers.docker.exposedbydefault=false + - --providers.docker.network=coollabs + - --providers.docker.swarmModeRefreshSeconds=1s + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + networks: + - coollabs + deploy: + update_config: + parallelism: 1 + delay: 10s + order: start-first + replicas: 1 + placement: + constraints: + - node.role == manager + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.api.entrypoints=websecure' + - 'traefik.http.routers.api.service=api@internal' + - 'traefik.http.routers.api.middlewares=auth' + - 'traefik.http.services.traefik.loadbalancer.server.port=80' + + # Global redirect www to non-www + - 'traefik.http.routers.www-catchall.rule=hostregexp(`{host:www.(.+)}`)' + - 'traefik.http.routers.www-catchall.entrypoints=web' + - 'traefik.http.routers.www-catchall.middlewares=redirect-www-to-nonwww' + - "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.regex=^http://(?:www\\.)?(.+)" + - 'traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.replacement=http://$${1}' + mongodb: + image: bitnami/mongodb:4.4 + hostname: coollabs-mongodb + ports: + - target: 27017 + published: 27017 + protocol: tcp + mode: host + environment: + - MONGODB_DISABLE_SYSTEM_LOG=true + - MONGODB_ROOT_PASSWORD=developmentPassword4db + - MONGODB_USERNAME=supercooldbuser + - MONGODB_PASSWORD=developmentPassword4db + - MONGODB_DATABASE=coolify + volumes: + - coollabs-mongodb-data:/bitnami/mongodb + networks: + - coollabs + +volumes: + coollabs-mongodb-data: {} + +networks: + coollabs: + driver: overlay + name: coollabs + external: true diff --git a/index.html b/index.html deleted file mode 100644 index a9c71b1436..0000000000 --- a/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - Coolify - - - - - - - - - - - \ No newline at end of file diff --git a/install/Dockerfile-dev b/install/Dockerfile-dev new file mode 100644 index 0000000000..a5a63844ca --- /dev/null +++ b/install/Dockerfile-dev @@ -0,0 +1,10 @@ +FROM node:latest +LABEL coolify-preserve=true +WORKDIR /usr/src/app +RUN curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-20.10.6.tgz | tar -xzvf - docker/docker -C . --strip-components 1 +RUN mv /usr/src/app/docker /usr/bin/docker +RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o /usr/bin/envsubst +RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/bin/jq +RUN chmod +x /usr/bin/envsubst /usr/bin/jq /usr/bin/docker +ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache +RUN curl -f https://get.pnpm.io/v6.js | node - add --global pnpm \ No newline at end of file diff --git a/install/README.md b/install/README.md index d5f9c46a95..9b9f89f5a8 100644 --- a/install/README.md +++ b/install/README.md @@ -1,6 +1,6 @@ Some of the files are here for backwards compatibility. -I will do things after 2 months: +I will do things after 2 months: - rm ./install.js and ./update.js - rm ../install.sh diff --git a/install/check.js b/install/check.js deleted file mode 100644 index d21f8585e1..0000000000 --- a/install/check.js +++ /dev/null @@ -1,24 +0,0 @@ -require('dotenv').config() -const fastify = require('fastify')() -const { schema } = require('../api/schema') - -checkConfig().then(() => { - console.log('Config: OK') -}).catch((err) => { - console.log('Config: NOT OK') - console.error(err) - process.exit(1) -}) - -function checkConfig () { - return new Promise((resolve, reject) => { - fastify.register(require('fastify-env'), { - schema, - dotenv: true - }) - .ready((err) => { - if (err) reject(err) - resolve() - }) - }) -} diff --git a/install/coolify-template-dev.yml b/install/coolify-template-dev.yml deleted file mode 100644 index 8fa26c0660..0000000000 --- a/install/coolify-template-dev.yml +++ /dev/null @@ -1,73 +0,0 @@ -version: '3.8' - -services: - proxy: - image: traefik:v2.4 - hostname: coollabs-proxy - ports: - - target: 80 - published: 80 - protocol: tcp - mode: host - - target: 443 - published: 443 - protocol: tcp - mode: host - - target: 8080 - published: 8080 - protocol: tcp - mode: host - command: - - --api.insecure=true - - --api.dashboard=true - - --api.debug=true - - --log.level=ERROR - - --providers.docker=true - - --providers.docker.swarmMode=true - - --providers.docker.exposedbydefault=false - - --providers.docker.network=${DOCKER_NETWORK} - - --providers.docker.swarmModeRefreshSeconds=1s - - --entrypoints.web.address=:80 - - --entrypoints.websecure.address=:443 - volumes: - - /var/run/docker.sock:/var/run/docker.sock - networks: - - ${DOCKER_NETWORK} - deploy: - update_config: - parallelism: 1 - delay: 10s - order: start-first - replicas: 1 - placement: - constraints: - - node.role == manager - labels: - - "traefik.enable=true" - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.service=api@internal" - - "traefik.http.routers.api.middlewares=auth" - - "traefik.http.services.traefik.loadbalancer.server.port=80" - - "traefik.http.services.traefik.loadbalancer.server.port=443" - - # Global redirect www to non-www - - "traefik.http.routers.www-catchall.rule=hostregexp(`{host:www.(.+)}`)" - - "traefik.http.routers.www-catchall.entrypoints=web" - - "traefik.http.routers.www-catchall.middlewares=redirect-www-to-nonwww" - - "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.regex=^http://(?:www\\.)?(.+)" - - "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.replacement=http://$$$${1}" - - # Global redirect http to https - - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" - - "traefik.http.routers.http-catchall.entrypoints=web" - - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - - - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - - "traefik.http.middlewares.global-compress.compress=true" - -networks: - ${DOCKER_NETWORK}: - driver: overlay - name: ${DOCKER_NETWORK} - external: true - diff --git a/install/coolify-template.yml b/install/coolify-template.yml index 92f4213706..3ced0cadfd 100644 --- a/install/coolify-template.yml +++ b/install/coolify-template.yml @@ -44,27 +44,27 @@ services: constraints: - node.role == manager labels: - - "traefik.enable=true" - - "traefik.http.routers.api.entrypoints=websecure" - - "traefik.http.routers.api.service=api@internal" - - "traefik.http.routers.api.middlewares=auth" - - "traefik.http.services.traefik.loadbalancer.server.port=80" - - "traefik.http.services.traefik.loadbalancer.server.port=443" + - 'traefik.enable=true' + - 'traefik.http.routers.api.entrypoints=websecure' + - 'traefik.http.routers.api.service=api@internal' + - 'traefik.http.routers.api.middlewares=auth' + - 'traefik.http.services.traefik.loadbalancer.server.port=80' + - 'traefik.http.services.traefik.loadbalancer.server.port=443' # Global redirect www to non-www - - "traefik.http.routers.www-catchall.rule=hostregexp(`{host:www.(.+)}`)" - - "traefik.http.routers.www-catchall.entrypoints=web" - - "traefik.http.routers.www-catchall.middlewares=redirect-www-to-nonwww" + - 'traefik.http.routers.www-catchall.rule=hostregexp(`{host:www.(.+)}`)' + - 'traefik.http.routers.www-catchall.entrypoints=web' + - 'traefik.http.routers.www-catchall.middlewares=redirect-www-to-nonwww' - "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.regex=^http://(?:www\\.)?(.+)" - - "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.replacement=http://$$$${1}" + - 'traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.replacement=http://$$$${1}' # Global redirect http to https - - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" - - "traefik.http.routers.http-catchall.entrypoints=web" - - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" + - 'traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)' + - 'traefik.http.routers.http-catchall.entrypoints=web' + - 'traefik.http.routers.http-catchall.middlewares=redirect-to-https' - - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - - "traefik.http.middlewares.global-compress.compress=true" + - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https' + - 'traefik.http.middlewares.global-compress.compress=true' coolify: image: coolify @@ -73,7 +73,7 @@ services: - .env networks: - ${DOCKER_NETWORK} - command: "yarn start" + command: 'yarn start' volumes: - /var/run/docker.sock:/var/run/docker.sock:ro deploy: @@ -83,16 +83,15 @@ services: order: start-first replicas: 1 labels: - - "traefik.enable=true" - - "traefik.http.routers.coolify.entrypoints=websecure" - - "traefik.http.routers.coolify.tls.certresolver=letsencrypt" - - "traefik.http.routers.coolify.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)" - - "traefik.http.services.coolify.loadbalancer.server.port=3000" - - "traefik.http.routers.coolify.middlewares=global-compress" - + - 'traefik.enable=true' + - 'traefik.http.routers.coolify.entrypoints=websecure' + - 'traefik.http.routers.coolify.tls.certresolver=letsencrypt' + - 'traefik.http.routers.coolify.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)' + - 'traefik.http.services.coolify.loadbalancer.server.port=3000' + - 'traefik.http.routers.coolify.middlewares=global-compress' + networks: ${DOCKER_NETWORK}: driver: overlay name: ${DOCKER_NETWORK} external: true - diff --git a/install/install.js b/install/install.js index 38a7bf66a7..0366bc3b7b 100644 --- a/install/install.js +++ b/install/install.js @@ -1,55 +1,36 @@ -require('dotenv').config() -const { program } = require('commander') -const fastify = require('fastify')() -const { schema } = require('../api/schema') -const shell = require('shelljs') -const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', '') +require('dotenv').config(); +const { program } = require('commander'); +const shell = require('shelljs'); +const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', ''); -program.version('0.0.1') +program.version('0.0.1'); program - .option('-d, --debug', 'Debug outputs.') - .option('-c, --check', 'Only checks configuration.') - .option('-t, --type ', 'Deploy type.') + .option('-d, --debug', 'Debug outputs.') + .option('-c, --check', 'Only checks configuration.') + .option('-t, --type ', 'Deploy type.'); -program.parse(process.argv) +program.parse(process.argv); -const options = program.opts() -if (options.check) { - checkConfig().then(() => { - console.log('Config: OK') - }).catch((err) => { - console.log('Config: NOT OK') - console.error(err) - process.exit(1) - }) -} else { - if (user !== 'root') { - console.error(`Please run as root! Current user: ${user}`) - process.exit(1) - } - shell.exec(`docker network create ${process.env.DOCKER_NETWORK} --driver overlay`, { silent: !options.debug }) - shell.exec('docker build -t coolify -f install/Dockerfile .') - if (options.type === 'all') { - shell.exec('docker stack rm coollabs-coolify', { silent: !options.debug }) - } else if (options.type === 'coolify') { - shell.exec('docker service rm coollabs-coolify_coolify') - } else if (options.type === 'proxy') { - shell.exec('docker service rm coollabs-coolify_proxy') - } - if (options.type !== 'upgrade') { - shell.exec('set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', { silent: !options.debug, shell: '/bin/bash' }) - } -} +const options = program.opts(); -function checkConfig () { - return new Promise((resolve, reject) => { - fastify.register(require('fastify-env'), { - schema, - dotenv: true - }) - .ready((err) => { - if (err) reject(err) - resolve() - }) - }) +if (user !== 'root') { + console.error(`Please run as root! Current user: ${user}`); + process.exit(1); +} +shell.exec(`docker network create ${process.env.DOCKER_NETWORK} --driver overlay`, { + silent: !options.debug +}); +shell.exec('docker build -t coolify -f install/Dockerfile .'); +if (options.type === 'all') { + shell.exec('docker stack rm coollabs-coolify', { silent: !options.debug }); +} else if (options.type === 'coolify') { + shell.exec('docker service rm coollabs-coolify_coolify'); +} else if (options.type === 'proxy') { + shell.exec('docker service rm coollabs-coolify_proxy'); +} +if (options.type !== 'upgrade') { + shell.exec( + 'set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', + { silent: !options.debug, shell: '/bin/bash' } + ); } diff --git a/install/obs/Dockerfile-base-new b/install/obs/Dockerfile-base-new deleted file mode 100644 index 8c1ac91890..0000000000 --- a/install/obs/Dockerfile-base-new +++ /dev/null @@ -1,4 +0,0 @@ -FROM coolify-base-nodejs -WORKDIR /usr/src/app -COPY . . -RUN pnpm install \ No newline at end of file diff --git a/install/obs/Dockerfile-base-nodejs b/install/obs/Dockerfile-base-nodejs deleted file mode 100644 index f35dbc7aea..0000000000 --- a/install/obs/Dockerfile-base-nodejs +++ /dev/null @@ -1,6 +0,0 @@ -FROM node:lts -LABEL coolify-preserve=true -COPY --from=coolify-binaries /usr/bin/docker /usr/bin/docker -COPY --from=coolify-binaries /usr/bin/envsubst /usr/bin/envsubst -COPY --from=coolify-binaries /usr/bin/jq /usr/bin/jq -RUN curl -f https://get.pnpm.io/v6.js | node - add --global pnpm@6 \ No newline at end of file diff --git a/install/obs/Dockerfile-binaries b/install/obs/Dockerfile-binaries deleted file mode 100644 index 5dca5c2862..0000000000 --- a/install/obs/Dockerfile-binaries +++ /dev/null @@ -1,9 +0,0 @@ -FROM ubuntu:20.04 -LABEL coolify-preserve=true -RUN apt update && apt install -y curl gnupg2 ca-certificates -RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - -RUN echo 'deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable' >> /etc/apt/sources.list -RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o /usr/bin/envsubst -RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/bin/jq -RUN chmod +x /usr/bin/envsubst /usr/bin/jq -RUN apt update && apt install -y docker-ce-cli && apt clean all diff --git a/install/update.js b/install/update.js index fb36d8a8ea..1137937ba7 100644 --- a/install/update.js +++ b/install/update.js @@ -1,21 +1,24 @@ -require('dotenv').config() -const { program } = require('commander') -const shell = require('shelljs') -const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', '') -program.version('0.0.1') +require('dotenv').config(); +const { program } = require('commander'); +const shell = require('shelljs'); +const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', ''); +program.version('0.0.1'); program - .option('-d, --debug', 'Debug outputs.') - .option('-c, --check', 'Only checks configuration.') - .option('-t, --type ', 'Deploy type.') + .option('-d, --debug', 'Debug outputs.') + .option('-c, --check', 'Only checks configuration.') + .option('-t, --type ', 'Deploy type.'); -program.parse(process.argv) -const options = program.opts() +program.parse(process.argv); +const options = program.opts(); if (user !== 'root') { - console.error(`Please run as root! Current user: ${user}`) - process.exit(1) + console.error(`Please run as root! Current user: ${user}`); + process.exit(1); } if (options.type === 'upgrade') { - shell.exec('docker service rm coollabs-coolify_coolify') - shell.exec('set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', { silent: !options.debug, shell: '/bin/bash' }) + shell.exec('docker service rm coollabs-coolify_coolify'); + shell.exec( + 'set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', + { silent: !options.debug, shell: '/bin/bash' } + ); } diff --git a/package.json b/package.json index 11363802ad..6f1e5d908c 100644 --- a/package.json +++ b/package.json @@ -1,68 +1,58 @@ { - "name": "coolify", - "description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.", - "version": "1.0.11", - "license": "AGPL-3.0", - "scripts": { - "lint": "standard", - "start": "NODE_ENV=production node api/server", - "dev": "run-p dev:db dev:routify dev:svite dev:server", - "dev:db": "NODE_ENV=development node api/development/mongodb.js", - "dev:server": "nodemon -w api api/server", - "dev:routify": "routify run", - "dev:svite": "svite", - "build": "run-s build:routify build:svite", - "build:routify": "routify run -b", - "build:svite": "svite build" - }, - "dependencies": { - "@iarna/toml": "^2.2.5", - "@roxi/routify": "^2.15.1", - "@zerodevx/svelte-toast": "^0.2.2", - "ajv": "^8.1.0", - "axios": "^0.21.1", - "commander": "^7.2.0", - "compare-versions": "^3.6.0", - "cuid": "^2.1.8", - "dayjs": "^1.10.4", - "deepmerge": "^4.2.2", - "dockerode": "^3.2.1", - "dotenv": "^8.2.0", - "fastify": "^3.14.2", - "fastify-env": "^2.1.0", - "fastify-jwt": "^2.4.0", - "fastify-plugin": "^3.0.0", - "fastify-static": "^4.0.1", - "generate-password": "^1.6.0", - "http-errors-enhanced": "^0.7.0", - "js-yaml": "^4.0.0", - "jsonwebtoken": "^8.5.1", - "mongoose": "^5.12.3", - "shelljs": "^0.8.4", - "svelte-select": "^3.17.0", - "unique-names-generator": "^4.4.0" - }, - "devDependencies": { - "mongodb-memory-server-core": "^6.9.6", - "nodemon": "^2.0.7", - "npm-run-all": "^4.1.5", - "postcss": "^8.2.9", - "postcss-import": "^14.0.1", - "postcss-load-config": "^3.0.1", - "postcss-preset-env": "^6.7.0", - "prettier": "2.2.1", - "prettier-plugin-svelte": "^2.2.0", - "standard": "^16.0.3", - "svelte": "^3.37.0", - "svelte-hmr": "^0.14.0", - "svelte-preprocess": "^4.7.0", - "svite": "0.8.1", - "tailwindcss": "2.1.1" - }, - "keywords": [ - "svelte", - "routify", - "fastify", - "tailwind" - ] + "name": "coolify", + "description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.", + "version": "1.0.12", + "license": "AGPL-3.0", + "scripts": { + "dev:docker:start": "docker-compose -f docker-compose-dev.yml up -d", + "dev:docker:stop": "docker-compose -f docker-compose-dev.yml down", + "dev": "NODE_ENV=development svelte-kit dev --host 0.0.0.0", + "build": "NODE_ENV=production svelte-kit build", + "preview": "svelte-kit preview", + "start": "node build", + "lint": "prettier --check . && eslint --ignore-path .gitignore .", + "format": "prettier --write ." + }, + "devDependencies": { + "@sveltejs/adapter-node": "^1.0.0-next.20", + "@sveltejs/kit": "1.0.0-next.107", + "@types/dockerode": "^3.2.3", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", + "autoprefixer": "^10.2.5", + "cssnano": "^5.0.2", + "dotenv-extended": "^2.9.0", + "eslint": "^7.26.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-svelte3": "^3.2.0", + "postcss": "^8.2.15", + "postcss-load-config": "^3.0.1", + "prettier": "~2.3.0", + "prettier-plugin-svelte": "^2.3.0", + "svelte": "^3.38.2", + "svelte-preprocess": "^4.7.3", + "tailwindcss": "canary", + "tslib": "^2.2.0", + "typescript": "^4.2.4", + "vite": "^2.3.2" + }, + "type": "module", + "dependencies": { + "@iarna/toml": "^2.2.5", + "@zerodevx/svelte-toast": "^0.3.0", + "commander": "^7.2.0", + "compare-versions": "^3.6.0", + "cookie": "^0.4.1", + "cuid": "^2.1.8", + "dayjs": "^1.10.4", + "dockerode": "^3.3.0", + "generate-password": "^1.6.0", + "js-yaml": "^4.1.0", + "jsonwebtoken": "^8.5.1", + "mongoose": "^5.12.9", + "shelljs": "^0.8.4", + "svelte-kit-cookie-session": "^0.4.3", + "svelte-select": "^3.17.0", + "unique-names-generator": "^4.5.0" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f8173149c..2422e03f1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2,131 +2,106 @@ lockfileVersion: 5.3 specifiers: '@iarna/toml': ^2.2.5 - '@roxi/routify': ^2.15.1 - '@zerodevx/svelte-toast': ^0.2.2 - ajv: ^8.1.0 - axios: ^0.21.1 + '@sveltejs/adapter-node': ^1.0.0-next.20 + '@sveltejs/kit': 1.0.0-next.107 + '@types/dockerode': ^3.2.3 + '@typescript-eslint/eslint-plugin': ^4.22.1 + '@typescript-eslint/parser': ^4.22.1 + '@zerodevx/svelte-toast': ^0.3.0 + autoprefixer: ^10.2.5 commander: ^7.2.0 compare-versions: ^3.6.0 + cookie: ^0.4.1 + cssnano: ^5.0.2 cuid: ^2.1.8 dayjs: ^1.10.4 - deepmerge: ^4.2.2 - dockerode: ^3.2.1 - dotenv: ^8.2.0 - fastify: ^3.14.2 - fastify-env: ^2.1.0 - fastify-jwt: ^2.4.0 - fastify-plugin: ^3.0.0 - fastify-static: ^4.0.1 + dockerode: ^3.3.0 + dotenv-extended: ^2.9.0 + eslint: ^7.26.0 + eslint-config-prettier: ^8.3.0 + eslint-plugin-svelte3: ^3.2.0 generate-password: ^1.6.0 - http-errors-enhanced: ^0.7.0 - js-yaml: ^4.0.0 + js-yaml: ^4.1.0 jsonwebtoken: ^8.5.1 - mongodb-memory-server-core: ^6.9.6 - mongoose: ^5.12.3 - nodemon: ^2.0.7 - npm-run-all: ^4.1.5 - postcss: ^8.2.9 - postcss-import: ^14.0.1 + mongoose: ^5.12.7 + postcss: ^8.2.14 postcss-load-config: ^3.0.1 - postcss-preset-env: ^6.7.0 - prettier: 2.2.1 + prettier: ~2.3.0 prettier-plugin-svelte: ^2.2.0 shelljs: ^0.8.4 - standard: ^16.0.3 - svelte: ^3.37.0 - svelte-hmr: ^0.14.0 - svelte-preprocess: ^4.7.0 + svelte: ^3.38.2 + svelte-kit-cookie-session: ^0.4.3 + svelte-preprocess: ^4.7.3 svelte-select: ^3.17.0 - svite: 0.8.1 - tailwindcss: 2.1.1 - unique-names-generator: ^4.4.0 + tailwindcss: canary + tslib: ^2.2.0 + typescript: ^4.2.4 + unique-names-generator: ^4.5.0 + vite: ^2.2.4 dependencies: '@iarna/toml': 2.2.5 - '@roxi/routify': 2.15.1 - '@zerodevx/svelte-toast': 0.2.2 - ajv: 8.1.0 - axios: 0.21.1 + '@zerodevx/svelte-toast': 0.3.0 commander: 7.2.0 compare-versions: 3.6.0 + cookie: 0.4.1 cuid: 2.1.8 dayjs: 1.10.4 - deepmerge: 4.2.2 - dockerode: 3.2.1 - dotenv: 8.2.0 - fastify: 3.14.2 - fastify-env: 2.1.0 - fastify-jwt: 2.4.0 - fastify-plugin: 3.0.0 - fastify-static: 4.0.1 + dockerode: 3.3.0 generate-password: 1.6.0 - http-errors-enhanced: 0.7.0 js-yaml: 4.1.0 jsonwebtoken: 8.5.1 - mongoose: 5.12.4 + mongoose: 5.12.7 shelljs: 0.8.4 + svelte-kit-cookie-session: 0.4.3 svelte-select: 3.17.0 - unique-names-generator: 4.4.0 + unique-names-generator: 4.5.0 devDependencies: - mongodb-memory-server-core: 6.9.6 - nodemon: 2.0.7 - npm-run-all: 4.1.5 - postcss: 8.2.10 - postcss-import: 14.0.1_postcss@8.2.10 + '@sveltejs/adapter-node': 1.0.0-next.20 + '@sveltejs/kit': 1.0.0-next.107_svelte@3.38.2 + '@types/dockerode': 3.2.3 + '@typescript-eslint/eslint-plugin': 4.22.1_b96c9280c6ac79e4dfcda76a733858e3 + '@typescript-eslint/parser': 4.22.1_eslint@7.26.0+typescript@4.2.4 + autoprefixer: 10.2.5_postcss@8.2.14 + cssnano: 5.0.2_postcss@8.2.14 + dotenv-extended: 2.9.0 + eslint: 7.26.0 + eslint-config-prettier: 8.3.0_eslint@7.26.0 + eslint-plugin-svelte3: 3.2.0_eslint@7.26.0+svelte@3.38.2 + postcss: 8.2.14 postcss-load-config: 3.0.1 - postcss-preset-env: 6.7.0 - prettier: 2.2.1 - prettier-plugin-svelte: 2.2.0_prettier@2.2.1+svelte@3.37.0 - standard: 16.0.3 - svelte: 3.37.0 - svelte-hmr: 0.14.0_svelte@3.37.0 - svelte-preprocess: 4.7.0_4a3768216fad352756a1a13607f73a31 - svite: 0.8.1_79b75b88a1dd913f13bddff6afa5f1de - tailwindcss: 2.1.1_postcss@8.2.10 + prettier: 2.3.0 + prettier-plugin-svelte: 2.2.0_prettier@2.3.0+svelte@3.38.2 + svelte: 3.38.2 + svelte-preprocess: 4.7.3_bc60392b3f6116f56fa9e4496adda117 + tailwindcss: 2.2.0-canary.6_b46308bb95614802e1b6d1dce4e25ea6 + tslib: 2.2.0 + typescript: 4.2.4 + vite: 2.2.4 packages: - /@babel/code-frame/7.12.13: - resolution: {integrity: sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==} + /@babel/code-frame/7.12.11: + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} dependencies: - '@babel/highlight': 7.13.10 + '@babel/highlight': 7.14.0 dev: true - /@babel/helper-validator-identifier/7.12.11: - resolution: {integrity: sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==} + /@babel/helper-validator-identifier/7.14.0: + resolution: {integrity: sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==} dev: true - /@babel/highlight/7.13.10: - resolution: {integrity: sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==} + /@babel/highlight/7.14.0: + resolution: {integrity: sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==} dependencies: - '@babel/helper-validator-identifier': 7.12.11 + '@babel/helper-validator-identifier': 7.14.0 chalk: 2.4.2 js-tokens: 4.0.0 dev: true - /@babel/parser/7.13.15: - resolution: {integrity: sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dev: true - - /@babel/types/7.13.14: - resolution: {integrity: sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==} - dependencies: - '@babel/helper-validator-identifier': 7.12.11 - lodash: 4.17.21 - to-fast-properties: 2.0.0 - dev: true - - /@csstools/convert-colors/1.4.0: - resolution: {integrity: sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==} - engines: {node: '>=4.0.0'} - dev: true - - /@eslint/eslintrc/0.2.2: - resolution: {integrity: sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==} + /@eslint/eslintrc/0.4.1: + resolution: {integrity: sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: ajv: 6.12.6 @@ -136,25 +111,12 @@ packages: ignore: 4.0.6 import-fresh: 3.3.0 js-yaml: 3.14.1 - lodash: 4.17.21 minimatch: 3.0.4 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true - /@fastify/forwarded/1.0.0: - resolution: {integrity: sha512-VoO+6WD0aRz8bwgJZ8pkkxjq7o/782cQ1j945HWg0obZMgIadYW3Pew0+an+k1QL7IPZHM3db5WF6OP6x4ymMA==} - engines: {node: '>= 10'} - dev: false - - /@fastify/proxy-addr/3.0.0: - resolution: {integrity: sha512-ty7wnUd/GeSqKTC2Jozsl5xGbnxUnEFC0On2/zPv/8ixywipQmVZwuWvNGnBoitJ2wixwVqofwXNua8j6Y62lQ==} - dependencies: - '@fastify/forwarded': 1.0.0 - ipaddr.js: 2.0.0 - dev: false - /@fullhuman/postcss-purgecss/3.1.3: resolution: {integrity: sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==} dependencies: @@ -165,13 +127,6 @@ packages: resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} dev: false - /@koa/cors/3.1.0: - resolution: {integrity: sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q==} - engines: {node: '>= 8.0.0'} - dependencies: - vary: 1.1.2 - dev: true - /@nodelib/fs.scandir/2.1.4: resolution: {integrity: sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==} engines: {node: '>= 8'} @@ -193,69 +148,6 @@ packages: fastq: 1.11.0 dev: true - /@rollup/plugin-commonjs/16.0.0_rollup@2.45.2: - resolution: {integrity: sha512-LuNyypCP3msCGVQJ7ki8PqYdpjfEkE/xtFa5DqlF+7IBD0JsfMZ87C58heSwIMint58sAUZbt3ITqOmdQv/dXw==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^2.30.0 - dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.45.2 - commondir: 1.0.1 - estree-walker: 2.0.2 - glob: 7.1.6 - is-reference: 1.2.1 - magic-string: 0.25.7 - resolve: 1.20.0 - rollup: 2.45.2 - dev: true - - /@rollup/plugin-json/4.1.0_rollup@2.45.2: - resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.45.2 - rollup: 2.45.2 - dev: true - - /@rollup/plugin-node-resolve/10.0.0_rollup@2.45.2: - resolution: {integrity: sha512-sNijGta8fqzwA1VwUEtTvWCx2E7qC70NMsDh4ZG13byAXYigBNZMxALhKUSycBks5gupJdq0lFrKumFrRZ8H3A==} - engines: {node: '>= 10.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.45.2 - '@types/resolve': 1.17.1 - builtin-modules: 3.2.0 - deepmerge: 4.2.2 - is-module: 1.0.0 - resolve: 1.20.0 - rollup: 2.45.2 - dev: true - - /@rollup/pluginutils/3.1.0: - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.2.3 - dev: true - - /@rollup/pluginutils/3.1.0_rollup@2.45.2: - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.2.3 - rollup: 2.45.2 - dev: true - /@rollup/pluginutils/4.1.0: resolution: {integrity: sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ==} engines: {node: '>= 8.0.0'} @@ -266,190 +158,79 @@ packages: picomatch: 2.2.3 dev: true - /@rollup/pluginutils/4.1.0_rollup@2.45.2: - resolution: {integrity: sha512-TrBhfJkFxA+ER+ew2U2/fHbebhLT/l/2pRk0hfj9KusXUuRXd2v0R58AfaZK9VXDQ4TogOSEmICVrQAA3zFnHQ==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - estree-walker: 2.0.2 - picomatch: 2.2.3 - rollup: 2.45.2 + /@sveltejs/adapter-node/1.0.0-next.20: + resolution: {integrity: sha512-ornNW289XN4TyY3tRXVGH38FxrqLsw1MHn4oq92T7U6EqnSbw/22waMZnPBQUxcj5GxZsXuuFjeBjn1BWt0x2A==} dev: true - /@roxi/routify/2.15.1: - resolution: {integrity: sha512-IRdoaPSfP09EwWtB+tpbHgH6ejYtowale24rgfpxRQhFNyTUK4jYXclvx3XkUD1NSupSgl1kDAsWSiRSG0WvkQ==} + /@sveltejs/kit/1.0.0-next.107_svelte@3.38.2: + resolution: {integrity: sha512-HxomGMWbuWTU8lahk98hqIL/xjW6HzNTAvTZVMnnmlMHN1N8x7+abkz4Y09Zhu8lZkZpFuqBj2UlsgPW4uJXtw==} + engines: {node: '>= 12.17.0'} hasBin: true + peerDependencies: + svelte: ^3.38.2 dependencies: - '@roxi/ssr': 0.2.1 - '@types/node': 12.20.10 - chalk: 4.1.0 + '@sveltejs/vite-plugin-svelte': 1.0.0-next.10_svelte@3.38.2+vite@2.3.2 cheap-watch: 1.0.3 - commander: 7.2.0 - configent: 2.2.0 - esm: 3.2.25 - fs-extra: 9.1.0 - log-symbols: 3.0.0 - picomatch: 2.2.3 - rollup-pluginutils: 2.8.2 - transitivePeerDependencies: - - canvas - dev: false - - /@roxi/ssr/0.2.1: - resolution: {integrity: sha512-C86xWJOmtCGZr/U4MURqePM0oDKFkTlLeEyT07R+7jSKvREKZ2manJAeAebYudJLYEGITEPGqObhRan32bUUbg==} - dependencies: - bufferutil: 4.0.3 - jsdom: 16.5.3_c70f8fc5586dd378b8c866035dbe710b - node-fetch: 2.6.1 - utf-8-validate: 5.0.4 + sade: 1.7.4 + svelte: 3.38.2 + vite: 2.3.2 transitivePeerDependencies: - - canvas - dev: false - - /@sindresorhus/is/0.14.0: - resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} - engines: {node: '>=6'} - dev: true - - /@szmarczak/http-timer/1.1.2: - resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} - engines: {node: '>=6'} - dependencies: - defer-to-connect: 1.1.3 + - rollup + - supports-color dev: true - /@types/accepts/1.3.5: - resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + /@sveltejs/vite-plugin-svelte/1.0.0-next.10_svelte@3.38.2+vite@2.3.2: + resolution: {integrity: sha512-ImvxbhPePm2hWNTKBSA3LHAYGwiEjHjvvgfPLXm4R87sfZ+BMXql9jBmDpzUC/URBLT4BB3Jxos/i523qkJBHg==} + engines: {node: '>=12.0.0'} + peerDependencies: + svelte: ^3.37.0 + vite: ^2.2.3 dependencies: - '@types/node': 14.14.41 + '@rollup/pluginutils': 4.1.0 + chalk: 4.1.1 + debug: 4.3.2 + hash-sum: 2.0.0 + require-relative: 0.8.7 + slash: 4.0.0 + source-map: 0.7.3 + svelte: 3.38.2 + svelte-hmr: 0.14.3_svelte@3.38.2 + vite: 2.3.2 + transitivePeerDependencies: + - rollup + - supports-color dev: true - /@types/body-parser/1.19.0: - resolution: {integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==} - dependencies: - '@types/connect': 3.4.34 - '@types/node': 14.14.41 + /@trysound/sax/0.1.1: + resolution: {integrity: sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow==} + engines: {node: '>=10.13.0'} dev: true /@types/bson/4.0.3: resolution: {integrity: sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==} dependencies: - '@types/node': 14.14.41 - dev: false - - /@types/connect/3.4.34: - resolution: {integrity: sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==} - dependencies: - '@types/node': 14.14.41 - dev: true - - /@types/content-disposition/0.5.3: - resolution: {integrity: sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==} - dev: true - - /@types/cookies/0.7.6: - resolution: {integrity: sha512-FK4U5Qyn7/Sc5ih233OuHO0qAkOpEcD/eG6584yEiLKizTFRny86qHLe/rej3HFQrkBuUjF4whFliAdODbVN/w==} - dependencies: - '@types/connect': 3.4.34 - '@types/express': 4.17.11 - '@types/keygrip': 1.0.2 - '@types/node': 14.14.41 - dev: true - - /@types/estree/0.0.39: - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - dev: true - - /@types/estree/0.0.47: - resolution: {integrity: sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==} - dev: true - - /@types/express-serve-static-core/4.17.19: - resolution: {integrity: sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==} - dependencies: - '@types/node': 14.14.41 - '@types/qs': 6.9.6 - '@types/range-parser': 1.2.3 - dev: true - - /@types/express/4.17.11: - resolution: {integrity: sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==} - dependencies: - '@types/body-parser': 1.19.0 - '@types/express-serve-static-core': 4.17.19 - '@types/qs': 6.9.6 - '@types/serve-static': 1.13.9 - dev: true - - /@types/http-assert/1.5.1: - resolution: {integrity: sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==} - dev: true - - /@types/http-errors/1.8.0: - resolution: {integrity: sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==} - dev: true - - /@types/http-proxy/1.17.5: - resolution: {integrity: sha512-GNkDE7bTv6Sf8JbV2GksknKOsk7OznNYHSdrtvPJXO0qJ9odZig6IZKUi5RFGi6d1bf6dgIAe4uXi3DBc7069Q==} - dependencies: - '@types/node': 14.14.41 - dev: true - - /@types/json5/0.0.29: - resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} - dev: true - - /@types/jsonwebtoken/8.5.1: - resolution: {integrity: sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==} - dependencies: - '@types/node': 14.14.41 + '@types/node': 15.0.1 dev: false - /@types/keygrip/1.0.2: - resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} - dev: true - - /@types/koa-compose/3.2.5: - resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} - dependencies: - '@types/koa': 2.13.1 - dev: true - - /@types/koa/2.13.1: - resolution: {integrity: sha512-Qbno7FWom9nNqu0yHZ6A0+RWt4mrYBhw3wpBAQ3+IuzGcLlfeYkzZrnMq5wsxulN2np8M4KKeUpTodsOsSad5Q==} + /@types/dockerode/3.2.3: + resolution: {integrity: sha512-nZRhpSxm3PYianRBcRExcHxDvEzYHUPfGCnRL5Fe4/fSEZbtxrRNJ7okzCans3lXxj2t298EynFHGTnTC2f1Iw==} dependencies: - '@types/accepts': 1.3.5 - '@types/content-disposition': 0.5.3 - '@types/cookies': 0.7.6 - '@types/http-assert': 1.5.1 - '@types/http-errors': 1.8.0 - '@types/keygrip': 1.0.2 - '@types/koa-compose': 3.2.5 - '@types/node': 14.14.41 + '@types/node': 15.0.1 dev: true - /@types/lru-cache/5.1.0: - resolution: {integrity: sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==} - dev: true - - /@types/mime/1.3.2: - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + /@types/json-schema/7.0.7: + resolution: {integrity: sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==} dev: true /@types/mongodb/3.6.12: resolution: {integrity: sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==} dependencies: '@types/bson': 4.0.3 - '@types/node': 14.14.41 - dev: false - - /@types/node/12.20.10: - resolution: {integrity: sha512-TxCmnSSppKBBOzYzPR2BR25YlX5Oay8z2XGwFBInuA/Co0V9xJhLlW4kjbxKtgeNo3NOMbQP1A5Rc03y+XecPw==} + '@types/node': 15.0.1 dev: false - /@types/node/14.14.41: - resolution: {integrity: sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==} + /@types/node/15.0.1: + resolution: {integrity: sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA==} /@types/parse-json/4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -459,139 +240,120 @@ packages: resolution: {integrity: sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=} dev: true - /@types/qs/6.9.6: - resolution: {integrity: sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==} - dev: true - - /@types/range-parser/1.2.3: - resolution: {integrity: sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==} - dev: true - - /@types/resolve/1.17.1: - resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} - dependencies: - '@types/node': 14.14.41 - dev: true - /@types/sass/1.16.0: resolution: {integrity: sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==} dependencies: - '@types/node': 14.14.41 - dev: true - - /@types/serve-static/1.13.9: - resolution: {integrity: sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==} - dependencies: - '@types/mime': 1.3.2 - '@types/node': 14.14.41 - dev: true - - /@types/tmp/0.2.0: - resolution: {integrity: sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ==} + '@types/node': 15.0.1 dev: true - /@vue/compiler-core/3.0.11: - resolution: {integrity: sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==} + /@typescript-eslint/eslint-plugin/4.22.1_b96c9280c6ac79e4dfcda76a733858e3: + resolution: {integrity: sha512-kVTAghWDDhsvQ602tHBc6WmQkdaYbkcTwZu+7l24jtJiYvm9l+/y/b2BZANEezxPDiX5MK2ZecE+9BFi/YJryw==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + '@typescript-eslint/parser': ^4.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@babel/parser': 7.13.15 - '@babel/types': 7.13.14 - '@vue/shared': 3.0.11 - estree-walker: 2.0.2 - source-map: 0.6.1 + '@typescript-eslint/experimental-utils': 4.22.1_eslint@7.26.0+typescript@4.2.4 + '@typescript-eslint/parser': 4.22.1_eslint@7.26.0+typescript@4.2.4 + '@typescript-eslint/scope-manager': 4.22.1 + debug: 4.3.1 + eslint: 7.26.0 + functional-red-black-tree: 1.0.1 + lodash: 4.17.21 + regexpp: 3.1.0 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.2.4 + typescript: 4.2.4 + transitivePeerDependencies: + - supports-color dev: true - /@vue/compiler-dom/3.0.11: - resolution: {integrity: sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==} + /@typescript-eslint/experimental-utils/4.22.1_eslint@7.26.0+typescript@4.2.4: + resolution: {integrity: sha512-svYlHecSMCQGDO2qN1v477ax/IDQwWhc7PRBiwAdAMJE7GXk5stF4Z9R/8wbRkuX/5e9dHqbIWxjeOjckK3wLQ==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: '*' dependencies: - '@vue/compiler-core': 3.0.11 - '@vue/shared': 3.0.11 + '@types/json-schema': 7.0.7 + '@typescript-eslint/scope-manager': 4.22.1 + '@typescript-eslint/types': 4.22.1 + '@typescript-eslint/typescript-estree': 4.22.1_typescript@4.2.4 + eslint: 7.26.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + transitivePeerDependencies: + - supports-color + - typescript dev: true - /@vue/compiler-sfc/3.0.11_vue@3.0.11: - resolution: {integrity: sha512-7fNiZuCecRleiyVGUWNa6pn8fB2fnuJU+3AGjbjl7r1P5wBivfl02H4pG+2aJP5gh2u+0wXov1W38tfWOphsXw==} + /@typescript-eslint/parser/4.22.1_eslint@7.26.0+typescript@4.2.4: + resolution: {integrity: sha512-l+sUJFInWhuMxA6rtirzjooh8cM/AATAe3amvIkqKFeMzkn85V+eLzb1RyuXkHak4dLfYzOmF6DXPyflJvjQnw==} + engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: - vue: 3.0.11 - dependencies: - '@babel/parser': 7.13.15 - '@babel/types': 7.13.14 - '@vue/compiler-core': 3.0.11 - '@vue/compiler-dom': 3.0.11 - '@vue/compiler-ssr': 3.0.11 - '@vue/shared': 3.0.11 - consolidate: 0.16.0 - estree-walker: 2.0.2 - hash-sum: 2.0.0 - lru-cache: 5.1.1 - magic-string: 0.25.7 - merge-source-map: 1.1.0 - postcss: 8.2.10 - postcss-modules: 4.0.0_postcss@8.2.10 - postcss-selector-parser: 6.0.4 - source-map: 0.6.1 - vue: 3.0.11 - dev: true - - /@vue/compiler-ssr/3.0.11: - resolution: {integrity: sha512-66yUGI8SGOpNvOcrQybRIhl2M03PJ+OrDPm78i7tvVln86MHTKhM3ERbALK26F7tXl0RkjX4sZpucCpiKs3MnA==} + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@vue/compiler-dom': 3.0.11 - '@vue/shared': 3.0.11 + '@typescript-eslint/scope-manager': 4.22.1 + '@typescript-eslint/types': 4.22.1 + '@typescript-eslint/typescript-estree': 4.22.1_typescript@4.2.4 + debug: 4.3.1 + eslint: 7.26.0 + typescript: 4.2.4 + transitivePeerDependencies: + - supports-color dev: true - /@vue/reactivity/3.0.11: - resolution: {integrity: sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw==} + /@typescript-eslint/scope-manager/4.22.1: + resolution: {integrity: sha512-d5bAiPBiessSmNi8Amq/RuLslvcumxLmyhf1/Xa9IuaoFJ0YtshlJKxhlbY7l2JdEk3wS0EnmnfeJWSvADOe0g==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dependencies: - '@vue/shared': 3.0.11 + '@typescript-eslint/types': 4.22.1 + '@typescript-eslint/visitor-keys': 4.22.1 dev: true - /@vue/runtime-core/3.0.11: - resolution: {integrity: sha512-87XPNwHfz9JkmOlayBeCCfMh9PT2NBnv795DSbi//C/RaAnc/bGZgECjmkD7oXJ526BZbgk9QZBPdFT8KMxkAg==} - dependencies: - '@vue/reactivity': 3.0.11 - '@vue/shared': 3.0.11 + /@typescript-eslint/types/4.22.1: + resolution: {integrity: sha512-2HTkbkdAeI3OOcWbqA8hWf/7z9c6gkmnWNGz0dKSLYLWywUlkOAQ2XcjhlKLj5xBFDf8FgAOF5aQbnLRvgNbCw==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dev: true - /@vue/runtime-dom/3.0.11: - resolution: {integrity: sha512-jm3FVQESY3y2hKZ2wlkcmFDDyqaPyU3p1IdAX92zTNeCH7I8zZ37PtlE1b9NlCtzV53WjB4TZAYh9yDCMIEumA==} + /@typescript-eslint/typescript-estree/4.22.1_typescript@4.2.4: + resolution: {integrity: sha512-p3We0pAPacT+onSGM+sPR+M9CblVqdA9F1JEdIqRVlxK5Qth4ochXQgIyb9daBomyQKAXbygxp1aXQRV0GC79A==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@vue/runtime-core': 3.0.11 - '@vue/shared': 3.0.11 - csstype: 2.6.16 - dev: true - - /@vue/shared/3.0.11: - resolution: {integrity: sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==} - dev: true - - /@zerodevx/svelte-toast/0.2.2: - resolution: {integrity: sha512-zriB7tSY54OEbRDqJ1NbHBv5Z83tWKhqqW7a+z8HMtZeR49zZUMLISFXmY7B8tMwzO6auB3A5dxuFyqB9+TZkQ==} - dev: false - - /abab/2.0.5: - resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==} - dev: false - - /abbrev/1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + '@typescript-eslint/types': 4.22.1 + '@typescript-eslint/visitor-keys': 4.22.1 + debug: 4.3.1 + globby: 11.0.3 + is-glob: 4.0.1 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.2.4 + typescript: 4.2.4 + transitivePeerDependencies: + - supports-color dev: true - /abstract-logging/2.0.1: - resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - dev: false - - /accepts/1.3.7: - resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} - engines: {node: '>= 0.6'} + /@typescript-eslint/visitor-keys/4.22.1: + resolution: {integrity: sha512-WPkOrIRm+WCLZxXQHCi+WG8T2MMTUFR70rWjdWYddLT7cEfb2P4a3O/J2U1FBVsSFTocXLCoXWY6MZGejeStvQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dependencies: - mime-types: 2.1.30 - negotiator: 0.6.2 + '@typescript-eslint/types': 4.22.1 + eslint-visitor-keys: 2.0.0 dev: true - /acorn-globals/6.0.0: - resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} - dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 + /@zerodevx/svelte-toast/0.3.0: + resolution: {integrity: sha512-TY5dLB5DEpxuHu60M6gum+fDxzIGXg35R8500orz58JTFs9LiHWoEfeJ4n9t7Afix3iMmYLl2thjhnCHCiQIhQ==} dev: false /acorn-jsx/5.3.1_acorn@7.4.1: @@ -613,24 +375,12 @@ packages: /acorn-walk/7.2.0: resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} engines: {node: '>=0.4.0'} + dev: true /acorn/7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} engines: {node: '>=0.4.0'} hasBin: true - - /acorn/8.1.1: - resolution: {integrity: sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==} - engines: {node: '>=0.4.0'} - hasBin: 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: true /ajv/6.12.6: @@ -640,20 +390,19 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 + dev: true - /ajv/8.1.0: - resolution: {integrity: sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==} + /ajv/8.2.0: + resolution: {integrity: sha512-WSNGFuyWd//XO8n/m/EaOlNLtO0yL8EXT/74LqT4khdhpZjP7lkj/kT5uwRmGitKEVp/Oj7ZUHeGfPtgHhQ5CA==} dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 - dev: false + dev: true - /ansi-align/3.0.0: - resolution: {integrity: sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==} - dependencies: - string-width: 3.1.0 + /alphanum-sort/1.0.2: + resolution: {integrity: sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=} dev: true /ansi-colors/4.1.1: @@ -661,11 +410,6 @@ packages: engines: {node: '>=6'} dev: true - /ansi-regex/4.1.0: - resolution: {integrity: sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==} - engines: {node: '>=6'} - dev: true - /ansi-regex/5.0.0: resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==} engines: {node: '>=8'} @@ -676,15 +420,13 @@ packages: engines: {node: '>=4'} dependencies: color-convert: 1.9.3 + dev: true /ansi-styles/4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - - /any-promise/1.3.0: - resolution: {integrity: sha1-q8av7tzqUugJzcA3au0845Y10X8=} dev: true /anymatch/3.1.2: @@ -695,10 +437,6 @@ packages: picomatch: 2.2.3 dev: true - /archy/1.0.0: - resolution: {integrity: sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=} - dev: false - /argparse/1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -709,125 +447,55 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: false - /array-flatten/1.1.1: - resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=} - dev: true - optional: true - - /array-includes/3.1.3: - resolution: {integrity: sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - get-intrinsic: 1.1.1 - is-string: 1.0.5 - dev: true - /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true - /array.prototype.flat/1.2.4: - resolution: {integrity: sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - dev: true - - /array.prototype.flatmap/1.2.4: - resolution: {integrity: sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - function-bind: 1.1.1 - dev: true - /asn1/0.2.4: resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} dependencies: safer-buffer: 2.1.2 dev: false - /assert-plus/1.0.0: - resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=} - engines: {node: '>=0.8'} - dev: false - - /astral-regex/1.0.0: - resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} - engines: {node: '>=4'} - dev: true - - /async-limiter/1.0.1: - resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} dev: true - optional: true - - /asynckit/0.4.0: - resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} - dev: false /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + dev: true - /atomic-sleep/1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - dev: false + /auto-parse/1.8.0: + resolution: {integrity: sha512-Uri4uC+K5cSi5hjM4snFrqPrjqUpwxeSW5EMTPvN7Ju3PlDzmXXDr5tjdzxPvvwgT3J7bmMDJ3Rm625nbrc72A==} + dependencies: + typpy: 2.3.11 + dev: true - /autoprefixer/9.8.6: - resolution: {integrity: sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==} + /autoprefixer/10.2.5_postcss@8.2.14: + resolution: {integrity: sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA==} + engines: {node: ^10 || ^12 || >=14} hasBin: true + peerDependencies: + postcss: ^8.1.0 dependencies: - browserslist: 4.16.4 - caniuse-lite: 1.0.30001209 + browserslist: 4.16.6 + caniuse-lite: 1.0.30001220 colorette: 1.2.2 + fraction.js: 4.0.13 normalize-range: 0.1.2 - num2fraction: 1.2.2 - postcss: 7.0.35 + postcss: 8.2.14 postcss-value-parser: 4.1.0 dev: true - /avvio/7.2.1: - resolution: {integrity: sha512-b+gox68dqD6c3S3t+bZBKN6rYbVWdwpN12sHQLFTiacDT2rcq7fm07Ww+IKt/AvAkyCIe1f5ArP1bC/vAlx97A==} - dependencies: - archy: 1.0.0 - debug: 4.3.1 - fastq: 1.11.0 - queue-microtask: 1.2.3 - transitivePeerDependencies: - - supports-color - dev: false - - /aws-sign2/0.7.0: - resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=} - dev: false - - /aws4/1.11.0: - resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} - dev: false - - /axios/0.21.1: - resolution: {integrity: sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==} - dependencies: - follow-redirects: 1.13.3 - transitivePeerDependencies: - - debug - dev: false - /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false /bcrypt-pbkdf/1.0.2: resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=} @@ -835,10 +503,6 @@ packages: tweetnacl: 0.14.5 dev: false - /big.js/5.2.2: - resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - dev: true - /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -849,6 +513,7 @@ packages: dependencies: readable-stream: 2.3.7 safe-buffer: 5.2.1 + dev: false /bl/4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -856,44 +521,14 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.0 + dev: false /bluebird/3.5.1: resolution: {integrity: sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==} dev: false - /bluebird/3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: true - - /body-parser/1.19.0: - resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.0 - content-type: 1.0.4 - debug: 2.6.9 - depd: 1.1.2 - http-errors: 1.7.2 - iconv-lite: 0.4.24 - on-finished: 2.3.0 - qs: 6.7.0 - raw-body: 2.4.0 - type-is: 1.6.18 - dev: true - optional: true - - /boxen/4.2.0: - resolution: {integrity: sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==} - engines: {node: '>=8'} - dependencies: - ansi-align: 3.0.0 - camelcase: 5.3.1 - chalk: 3.0.0 - cli-boxes: 2.2.1 - string-width: 4.2.2 - term-size: 2.2.1 - type-fest: 0.8.1 - widest-line: 3.1.0 + /boolbase/1.0.0: + resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=} dev: true /brace-expansion/1.1.11: @@ -909,25 +544,14 @@ packages: fill-range: 7.0.1 dev: true - /brotli-size/4.0.0: - resolution: {integrity: sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==} - engines: {node: '>= 10.16.0'} - dependencies: - duplexer: 0.1.1 - dev: true - - /browser-process-hrtime/1.0.0: - resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} - dev: false - - /browserslist/4.16.4: - resolution: {integrity: sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==} + /browserslist/4.16.6: + resolution: {integrity: sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001209 + caniuse-lite: 1.0.30001220 colorette: 1.2.2 - electron-to-chromium: 1.3.717 + electron-to-chromium: 1.3.725 escalade: 3.1.1 node-releases: 1.1.71 dev: true @@ -935,80 +559,24 @@ packages: /bson/1.1.6: resolution: {integrity: sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==} engines: {node: '>=0.6.19'} - - /buffer-crc32/0.2.13: - resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=} - dev: true + dev: false /buffer-equal-constant-time/1.0.1: resolution: {integrity: sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=} dev: false - /buffer-from/1.1.1: - resolution: {integrity: sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==} - dev: true - /buffer/5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - - /bufferutil/4.0.3: - resolution: {integrity: sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==} - requiresBuild: true - dependencies: - node-gyp-build: 4.2.3 dev: false - /builtin-modules/1.1.1: - resolution: {integrity: sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=} - engines: {node: '>=0.10.0'} - dev: true - - /builtin-modules/3.2.0: - resolution: {integrity: sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==} - engines: {node: '>=6'} - dev: true - /bytes/3.1.0: resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} engines: {node: '>= 0.8'} dev: true - /cac/6.7.2: - resolution: {integrity: sha512-w0bH1IF9rEjdi0a6lTtlXYT+vBZEJL9oytaXXRdsD68MH6+SrZGOGsu7s2saHQvYXqwo/wBdkW75tt8wFpj+mw==} - engines: {node: '>=8'} - dev: true - - /cache-content-type/1.0.1: - resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} - engines: {node: '>= 6.0.0'} - dependencies: - mime-types: 2.1.30 - ylru: 1.2.1 - dev: true - - /cacheable-request/6.1.0: - resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} - engines: {node: '>=8'} - dependencies: - clone-response: 1.0.2 - get-stream: 5.2.0 - http-cache-semantics: 4.1.0 - keyv: 3.1.0 - lowercase-keys: 2.0.0 - normalize-url: 4.5.0 - responselike: 1.0.2 - dev: true - - /call-bind/1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.1.1 - dev: true - /callsites/3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1024,19 +592,19 @@ packages: engines: {node: '>=6'} dev: true - /camelcase/6.2.0: - resolution: {integrity: sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==} - engines: {node: '>=10'} + /caniuse-api/3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + dependencies: + browserslist: 4.16.6 + caniuse-lite: 1.0.30001220 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 dev: true - /caniuse-lite/1.0.30001209: - resolution: {integrity: sha512-2Ktt4OeRM7EM/JaOZjuLzPYAIqmbwQMNnYbgooT+icoRGrKOyAxA1xhlnotBD1KArRSPsuJp3TdYcZYrL7qNxA==} + /caniuse-lite/1.0.30001220: + resolution: {integrity: sha512-pjC2T4DIDyGAKTL4dMvGUQaMUHRmhvPpAgNNTa14jaBWHu+bLQgvpFqElxh9L4829Fdx0PlKiMp3wnYldRtECA==} dev: true - /caseless/0.12.0: - resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=} - dev: false - /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1044,26 +612,20 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - - /chalk/3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 dev: true - /chalk/4.1.0: - resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} + /chalk/4.1.1: + resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==} engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + dev: true /cheap-watch/1.0.3: resolution: {integrity: sha512-xC5CruMhLzjPwJ5ecUxGu1uGmwJQykUhqd2QrCrYbwvsFYdRyviu6jG9+pccwDXJR/OpmOTOJ9yLFunVgQu9wg==} engines: {node: '>=8'} - dev: false + dev: true /chokidar/3.5.1: resolution: {integrity: sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==} @@ -1084,75 +646,26 @@ packages: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: false - /ci-info/2.0.0: - resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - dev: true - - /clean-css/4.2.3: - resolution: {integrity: sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==} - engines: {node: '>= 4.0'} - dependencies: - source-map: 0.6.1 - dev: true - - /cli-boxes/2.2.1: - resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} - engines: {node: '>=6'} - dev: true - - /cli-cursor/3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-spinners/2.6.0: - resolution: {integrity: sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==} - engines: {node: '>=6'} - dev: true - - /cliui/7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.2 - strip-ansi: 6.0.0 - wrap-ansi: 7.0.0 - dev: true - optional: true - - /clone-response/1.0.2: - resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=} - dependencies: - mimic-response: 1.0.1 - dev: true - - /clone/1.0.4: - resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=} - engines: {node: '>=0.8'} - dev: true - - /co/4.6.0: - resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 + dev: true /color-convert/2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 + dev: true /color-name/1.1.3: resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + dev: true /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true /color-string/1.5.5: resolution: {integrity: sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==} @@ -1172,17 +685,6 @@ packages: resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==} dev: true - /combined-stream/1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /commander/2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - /commander/6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -1191,11 +693,6 @@ packages: /commander/7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} - dev: false - - /commondir/1.0.1: - resolution: {integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=} - dev: true /compare-versions/3.6.0: resolution: {integrity: sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==} @@ -1204,80 +701,14 @@ packages: /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} - /configent/2.2.0: - resolution: {integrity: sha512-yIN6zfOWk2nycNJ2JFNiWEai0oiqAhISIht8+pbEBP8bdcpwoQ74AhCZPbUv9aRVJwo7wh1MbCBDUV44UJa7Kw==} - dependencies: - dotenv: 8.2.0 - dev: false - - /configstore/5.0.1: - resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} - engines: {node: '>=8'} - dependencies: - dot-prop: 5.3.0 - graceful-fs: 4.2.6 - make-dir: 3.1.0 - unique-string: 2.0.0 - write-file-atomic: 3.0.3 - xdg-basedir: 4.0.0 - dev: true - - /consolidate/0.16.0: - resolution: {integrity: sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==} - engines: {node: '>= 0.10.0'} - dependencies: - bluebird: 3.7.2 - dev: true - - /contains-path/0.1.0: - resolution: {integrity: sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=} - engines: {node: '>=0.10.0'} - dev: true - - /content-disposition/0.5.3: - resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.1.2 - - /content-type/1.0.4: - resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} - engines: {node: '>= 0.6'} - dev: true - - /convert-source-map/1.7.0: - resolution: {integrity: sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==} - dependencies: - safe-buffer: 5.1.2 - dev: true - optional: true - - /cookie-signature/1.0.6: - resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} - dev: true - optional: true - - /cookie/0.4.0: - resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} - engines: {node: '>= 0.6'} - dev: true - optional: true - /cookie/0.4.1: resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} engines: {node: '>= 0.6'} dev: false - /cookies/0.8.0: - resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - keygrip: 1.1.0 - dev: true - /core-util-is/1.0.2: resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=} + dev: false /cosmiconfig/7.0.0: resolution: {integrity: sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==} @@ -1290,17 +721,6 @@ packages: yaml: 1.10.2 dev: true - /cross-spawn/6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.1 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - /cross-spawn/7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1310,48 +730,49 @@ packages: which: 2.0.2 dev: true - /crypto-random-string/2.0.0: - resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} - engines: {node: '>=8'} + /css-color-names/0.0.4: + resolution: {integrity: sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=} dev: true - /css-blank-pseudo/0.1.4: - resolution: {integrity: sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==} - engines: {node: '>=6.0.0'} - hasBin: true + /css-color-names/1.0.1: + resolution: {integrity: sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==} + dev: true + + /css-declaration-sorter/6.0.0_postcss@8.2.14: + resolution: {integrity: sha512-S0TE4E0ha5+tBHdLWPc5n+S8E4dFBS5xScPvgHkLNZwWvX4ISoFGhGeerLC9uS1cKA/sC+K2wHq6qEbcagT/fg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: ^8.0.9 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 + timsort: 0.3.0 dev: true - /css-has-pseudo/0.10.0: - resolution: {integrity: sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==} - engines: {node: '>=6.0.0'} - hasBin: true + /css-select/3.1.2: + resolution: {integrity: sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==} dependencies: - postcss: 7.0.35 - postcss-selector-parser: 5.0.0 + boolbase: 1.0.0 + css-what: 4.0.0 + domhandler: 4.2.0 + domutils: 2.6.0 + nth-check: 2.0.0 dev: true - /css-prefers-color-scheme/3.1.1: - resolution: {integrity: sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==} - engines: {node: '>=6.0.0'} - hasBin: true + /css-tree/1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} dependencies: - postcss: 7.0.35 + mdn-data: 2.0.14 + source-map: 0.6.1 dev: true /css-unit-converter/1.1.2: resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} dev: true - /cssdb/4.4.0: - resolution: {integrity: sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==} - dev: true - - /cssesc/2.0.0: - resolution: {integrity: sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==} - engines: {node: '>=4'} - hasBin: true + /css-what/4.0.0: + resolution: {integrity: sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==} + engines: {node: '>= 6'} dev: true /cssesc/3.0.0: @@ -1360,64 +781,85 @@ packages: hasBin: true dev: true - /cssom/0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: false - - /cssom/0.4.4: - resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} - dev: false + /cssnano-preset-default/5.0.1_postcss@8.2.14: + resolution: {integrity: sha512-cfmfThYODGqhpQKDq9H0MTAqkMvZ3dGbOUTBKw0xWZiIycMqHid22LsJXJl4r1qX4qzDeKxcSyQ/Xb5Mu3Z//Q==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 + dependencies: + css-declaration-sorter: 6.0.0_postcss@8.2.14 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-calc: 8.0.0_postcss@8.2.14 + postcss-colormin: 5.0.0_postcss@8.2.14 + postcss-convert-values: 5.0.0_postcss@8.2.14 + postcss-discard-comments: 5.0.0_postcss@8.2.14 + postcss-discard-duplicates: 5.0.0_postcss@8.2.14 + postcss-discard-empty: 5.0.0_postcss@8.2.14 + postcss-discard-overridden: 5.0.0_postcss@8.2.14 + postcss-merge-longhand: 5.0.1_postcss@8.2.14 + postcss-merge-rules: 5.0.0_postcss@8.2.14 + postcss-minify-font-values: 5.0.0_postcss@8.2.14 + postcss-minify-gradients: 5.0.0_postcss@8.2.14 + postcss-minify-params: 5.0.0_postcss@8.2.14 + postcss-minify-selectors: 5.0.0_postcss@8.2.14 + postcss-normalize-charset: 5.0.0_postcss@8.2.14 + postcss-normalize-display-values: 5.0.0_postcss@8.2.14 + postcss-normalize-positions: 5.0.0_postcss@8.2.14 + postcss-normalize-repeat-style: 5.0.0_postcss@8.2.14 + postcss-normalize-string: 5.0.0_postcss@8.2.14 + postcss-normalize-timing-functions: 5.0.0_postcss@8.2.14 + postcss-normalize-unicode: 5.0.0_postcss@8.2.14 + postcss-normalize-url: 5.0.0_postcss@8.2.14 + postcss-normalize-whitespace: 5.0.0_postcss@8.2.14 + postcss-ordered-values: 5.0.0_postcss@8.2.14 + postcss-reduce-initial: 5.0.0_postcss@8.2.14 + postcss-reduce-transforms: 5.0.0_postcss@8.2.14 + postcss-svgo: 5.0.0_postcss@8.2.14 + postcss-unique-selectors: 5.0.0_postcss@8.2.14 + dev: true + + /cssnano-utils/2.0.0_postcss@8.2.14: + resolution: {integrity: sha512-xvxmTszdrvSyTACdPe8VU5J6p4sm3egpgw54dILvNqt5eBUv6TFjACLhSxtRuEsxYrgy8uDy269YjScO5aKbGA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 + dependencies: + postcss: 8.2.14 + dev: true - /cssstyle/2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} + /cssnano/5.0.2_postcss@8.2.14: + resolution: {integrity: sha512-8JK3EnPsjQsULme9/e5M2hF564f/480hwsdcHvQ7ZtAIMfQ1O3SCfs+b8Mjf5KJxhYApyRshR2QSovEJi2K72Q==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - cssom: 0.3.8 - dev: false + cosmiconfig: 7.0.0 + cssnano-preset-default: 5.0.1_postcss@8.2.14 + is-resolvable: 1.1.0 + postcss: 8.2.14 + dev: true - /csstype/2.6.16: - resolution: {integrity: sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q==} + /csso/4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + dependencies: + css-tree: 1.1.3 dev: true /cuid/2.1.8: resolution: {integrity: sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==} dev: false - /dashdash/1.14.1: - resolution: {integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: false - - /data-urls/2.0.0: - resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} - engines: {node: '>=10'} - dependencies: - abab: 2.0.5 - whatwg-mimetype: 2.3.0 - whatwg-url: 8.5.0 - dev: false - /dayjs/1.10.4: resolution: {integrity: sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==} dev: false - /debug/2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - dependencies: - ms: 2.0.0 - /debug/3.1.0: resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} dependencies: ms: 2.0.0 - - /debug/3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - dependencies: - ms: 2.1.3 - dev: true + dev: false /debug/4.3.1: resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} @@ -1430,84 +872,30 @@ packages: dependencies: ms: 2.1.2 - /decimal.js/10.2.1: - resolution: {integrity: sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==} - dev: false - - /decompress-response/3.3.0: - resolution: {integrity: sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=} - engines: {node: '>=4'} + /debug/4.3.2: + resolution: {integrity: sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: - mimic-response: 1.0.1 - dev: true - - /deep-equal/1.0.1: - resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=} - dev: true - - /deep-extend/0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + ms: 2.1.2 dev: true /deep-is/0.1.3: resolution: {integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=} - - /deepmerge/4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} - - /defaults/1.0.3: - resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=} - dependencies: - clone: 1.0.4 - dev: true - - /defer-to-connect/1.1.3: - resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} - dev: true - - /define-properties/1.1.3: - resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} - engines: {node: '>= 0.4'} - dependencies: - object-keys: 1.1.1 dev: true /defined/1.0.0: resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=} dev: true - /degit/2.8.4: - resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} - engines: {node: '>=8.0.0'} - hasBin: true - dev: true - - /delayed-stream/1.0.0: - resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} - engines: {node: '>=0.4.0'} - dev: false - - /delegates/1.0.0: - resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} - dev: true - /denque/1.5.0: resolution: {integrity: sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==} engines: {node: '>=0.10'} - - /depd/1.1.2: - resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=} - engines: {node: '>= 0.6'} - - /depd/2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: true - - /destroy/1.0.4: - resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=} + dev: false /detect-indent/6.0.0: resolution: {integrity: sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==} @@ -1539,8 +927,8 @@ packages: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} dev: true - /docker-modem/2.1.4: - resolution: {integrity: sha512-vDTzZjjO1sXMY7m0xKjGdFMMZL7vIUerkC3G4l6rnrpOET2M6AOufM8ajmQoOB+6RfSn6I/dlikCUq/Y91Q1sQ==} + /docker-modem/3.0.0: + resolution: {integrity: sha512-WwFajJ8I5geZ/dDZ5FDMDA6TBkWa76xWwGIGw8uzUjNUGCN0to83wJ8Oi1AxrJTC0JBn+7fvIxUctnawtlwXeg==} engines: {node: '>= 8.0'} dependencies: debug: 4.3.1 @@ -1551,44 +939,49 @@ packages: - supports-color dev: false - /dockerode/3.2.1: - resolution: {integrity: sha512-XsSVB5Wu5HWMg1aelV5hFSqFJaKS5x1aiV/+sT7YOzOq1IRl49I/UwV8Pe4x6t0iF9kiGkWu5jwfvbkcFVupBw==} + /dockerode/3.3.0: + resolution: {integrity: sha512-St08lfOjpYCOXEM8XA0VLu3B3hRjtddODphNW5GFoA0AS3JHgoPQKOz0Qmdzg3P+hUPxhb02g1o1Cu1G+U3lRg==} engines: {node: '>= 8.0'} dependencies: - docker-modem: 2.1.4 + docker-modem: 3.0.0 tar-fs: 2.0.1 transitivePeerDependencies: - supports-color dev: false - /doctrine/1.5.0: - resolution: {integrity: sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=} - engines: {node: '>=0.10.0'} + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 - isarray: 1.0.0 dev: true - /doctrine/2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + /dom-serializer/1.3.1: + resolution: {integrity: sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q==} dependencies: - esutils: 2.0.3 + domelementtype: 2.2.0 + domhandler: 4.2.0 + entities: 2.2.0 dev: true - /doctrine/3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} + /domelementtype/2.2.0: + resolution: {integrity: sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==} + dev: true + + /domhandler/4.2.0: + resolution: {integrity: sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==} + engines: {node: '>= 4'} dependencies: - esutils: 2.0.3 + domelementtype: 2.2.0 dev: true - /domexception/2.0.1: - resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} - engines: {node: '>=8'} + /domutils/2.6.0: + resolution: {integrity: sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==} dependencies: - webidl-conversions: 5.0.0 - dev: false + dom-serializer: 1.3.1 + domelementtype: 2.2.0 + domhandler: 4.2.0 + dev: true /dot-prop/5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} @@ -1597,62 +990,41 @@ packages: is-obj: 2.0.0 dev: true - /dotenv-expand/5.1.0: - resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + /dotenv-extended/2.9.0: + resolution: {integrity: sha512-MKc4WCqZj6Abx4rpDbQ9LsuBJldRLxLgFkY5qE+4JM7hXVYT/v8zyWGgnBeDjSOGzEecWOFPlosNpxfB9YnsCw==} + engines: {node: '>=6'} + hasBin: true + dependencies: + auto-parse: 1.8.0 + camelcase: 5.3.1 + cross-spawn: 7.0.3 + dotenv: 8.2.0 + dev: true /dotenv/8.2.0: resolution: {integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==} engines: {node: '>=8'} - - /duplexer/0.1.1: - resolution: {integrity: sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=} - dev: true - - /duplexer3/0.1.4: - resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=} dev: true - /ecc-jsbn/0.1.2: - resolution: {integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: false - /ecdsa-sig-formatter/1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} dependencies: safe-buffer: 5.2.1 dev: false - /ee-first/1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} - - /electron-to-chromium/1.3.717: - resolution: {integrity: sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==} - dev: true - - /emoji-regex/7.0.3: - resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + /electron-to-chromium/1.3.725: + resolution: {integrity: sha512-2BbeAESz7kc6KBzs7WVrMc1BY5waUphk4D4DX5dSQXJhsc3tP5ZFaiyuL0AB7vUKzDYpIeYwTYlEfxyjsGUrhw==} dev: true /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true - /emojis-list/3.0.0: - resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} - engines: {node: '>= 4'} - dev: true - - /encodeurl/1.0.2: - resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} - engines: {node: '>= 0.8'} - /end-of-stream/1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 + dev: false /enquirer/2.3.6: resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} @@ -1661,13 +1033,9 @@ packages: ansi-colors: 4.1.1 dev: true - /env-schema/2.1.0: - resolution: {integrity: sha512-qvbmiB+31WJlDs4i9/R8jxEYfq3A0K20QzjGLR4cnlX3SD55ljVEULHXHU1iaPdWOkTSho/TajNzZp3jX3Shsw==} - dependencies: - ajv: 6.12.6 - dotenv: 8.2.0 - dotenv-expand: 5.1.0 - dev: false + /entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -1675,48 +1043,14 @@ packages: is-arrayish: 0.2.1 dev: true - /es-abstract/1.18.0: - resolution: {integrity: sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - es-to-primitive: 1.2.1 - function-bind: 1.1.1 - get-intrinsic: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.2 - is-callable: 1.2.3 - is-negative-zero: 2.0.1 - is-regex: 1.1.2 - is-string: 1.0.5 - object-inspect: 1.9.0 - object-keys: 1.1.1 - object.assign: 4.1.2 - string.prototype.trimend: 1.0.4 - string.prototype.trimstart: 1.0.4 - unbox-primitive: 1.0.1 - dev: true - - /es-module-lexer/0.3.26: - resolution: {integrity: sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==} - dev: true - - /es-to-primitive/1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.3 - is-date-object: 1.0.2 - is-symbol: 1.0.3 - dev: true - - /es6-promise/4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + /esbuild/0.11.20: + resolution: {integrity: sha512-QOZrVpN/Yz74xfat0H6euSgn3RnwLevY1mJTEXneukz1ln9qB+ieaerRMzSeETpz/UJWsBMzRVR/andBht5WKw==} + hasBin: true + requiresBuild: true dev: true - optional: true - /esbuild/0.8.57: - resolution: {integrity: sha512-j02SFrUwFTRUqiY0Kjplwjm1psuzO1d6AjaXKuOR9hrY0HuPsT6sV42B6myW34h1q4CRy+Y3g4RU/cGJeI/nNA==} + /esbuild/0.9.7: + resolution: {integrity: sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==} hasBin: true requiresBuild: true dev: true @@ -1726,141 +1060,29 @@ packages: engines: {node: '>=6'} dev: true - /escape-goat/2.1.1: - resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==} - engines: {node: '>=8'} - dev: true - - /escape-html/1.0.3: - resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=} - /escape-string-regexp/1.0.5: resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} engines: {node: '>=0.8.0'} - - /escodegen/2.0.0: - resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} - engines: {node: '>=6.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 5.2.0 - esutils: 2.0.3 - optionator: 0.8.3 - optionalDependencies: - source-map: 0.6.1 - dev: false - - /eslint-config-standard-jsx/10.0.0_d4901a613f352504e6e19464e186980c: - resolution: {integrity: sha512-hLeA2f5e06W1xyr/93/QJulN/rLbUVUmqTlexv9PRKHFwEC9ffJcH2LvJhMoEqYQBEYafedgGZXH2W8NUpt5lA==} - peerDependencies: - eslint: ^7.12.1 - eslint-plugin-react: ^7.21.5 - dependencies: - eslint: 7.13.0 - eslint-plugin-react: 7.21.5_eslint@7.13.0 - dev: true - - /eslint-config-standard/16.0.2_1ebed8346196ff7bde7431d183a61a72: - resolution: {integrity: sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==} - peerDependencies: - eslint: ^7.12.1 - eslint-plugin-import: ^2.22.1 - eslint-plugin-node: ^11.1.0 - eslint-plugin-promise: ^4.2.1 - dependencies: - eslint: 7.13.0 - eslint-plugin-import: 2.22.1_eslint@7.13.0 - eslint-plugin-node: 11.1.0_eslint@7.13.0 - eslint-plugin-promise: 4.2.1 - dev: true - - /eslint-import-resolver-node/0.3.4: - resolution: {integrity: sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==} - dependencies: - debug: 2.6.9 - resolve: 1.20.0 - dev: true - - /eslint-module-utils/2.6.0: - resolution: {integrity: sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==} - engines: {node: '>=4'} - dependencies: - debug: 2.6.9 - pkg-dir: 2.0.0 dev: true - /eslint-plugin-es/3.0.1_eslint@7.13.0: - resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=4.19.1' - dependencies: - eslint: 7.13.0 - eslint-utils: 2.1.0 - regexpp: 3.1.0 - dev: true - - /eslint-plugin-import/2.22.1_eslint@7.13.0: - resolution: {integrity: sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 - dependencies: - array-includes: 3.1.3 - array.prototype.flat: 1.2.4 - contains-path: 0.1.0 - debug: 2.6.9 - doctrine: 1.5.0 - eslint: 7.13.0 - eslint-import-resolver-node: 0.3.4 - eslint-module-utils: 2.6.0 - has: 1.0.3 - minimatch: 3.0.4 - object.values: 1.1.3 - read-pkg-up: 2.0.0 - resolve: 1.20.0 - tsconfig-paths: 3.9.0 - dev: true - - /eslint-plugin-node/11.1.0_eslint@7.13.0: - resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} - engines: {node: '>=8.10.0'} + /eslint-config-prettier/8.3.0_eslint@7.26.0: + resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} + hasBin: true peerDependencies: - eslint: '>=5.16.0' + eslint: '>=7.0.0' dependencies: - eslint: 7.13.0 - eslint-plugin-es: 3.0.1_eslint@7.13.0 - eslint-utils: 2.1.0 - ignore: 5.1.8 - minimatch: 3.0.4 - resolve: 1.20.0 - semver: 6.3.0 + eslint: 7.26.0 dev: true - /eslint-plugin-promise/4.2.1: - resolution: {integrity: sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==} - engines: {node: '>=6'} - dev: true - - /eslint-plugin-react/7.21.5_eslint@7.13.0: - resolution: {integrity: sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==} - engines: {node: '>=4'} + /eslint-plugin-svelte3/3.2.0_eslint@7.26.0+svelte@3.38.2: + resolution: {integrity: sha512-qdWB1QN21dEozsJFdR8XlEhMnsS6aKHjsXWuNmchYwxoet5I6QdCr1Xcq62++IzRBMCNCeH4waXqSOAdqrZzgA==} + engines: {node: '>=10'} peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 + eslint: '>=6.0.0' + svelte: ^3.2.0 dependencies: - array-includes: 3.1.3 - array.prototype.flatmap: 1.2.4 - doctrine: 2.1.0 - eslint: 7.13.0 - has: 1.0.3 - jsx-ast-utils: 3.2.0 - object.entries: 1.1.3 - object.fromentries: 2.0.4 - object.values: 1.1.3 - prop-types: 15.7.2 - resolve: 1.20.0 - string.prototype.matchall: 4.0.4 + eslint: 7.26.0 + svelte: 3.38.2 dev: true /eslint-scope/5.1.1: @@ -1888,15 +1110,15 @@ packages: engines: {node: '>=10'} dev: true - /eslint/7.13.0: - resolution: {integrity: sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==} + /eslint/7.26.0: + resolution: {integrity: sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg==} engines: {node: ^10.12.0 || >=12.0.0} hasBin: true dependencies: - '@babel/code-frame': 7.12.13 - '@eslint/eslintrc': 0.2.2 + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.1 ajv: 6.12.6 - chalk: 4.1.0 + chalk: 4.1.1 cross-spawn: 7.0.3 debug: 4.3.1 doctrine: 3.0.0 @@ -1907,10 +1129,10 @@ packages: espree: 7.3.1 esquery: 1.4.0 esutils: 2.0.3 - file-entry-cache: 5.0.1 + file-entry-cache: 6.0.1 functional-red-black-tree: 1.0.1 glob-parent: 5.1.2 - globals: 12.4.0 + globals: 13.8.0 ignore: 4.0.6 import-fresh: 3.3.0 imurmurhash: 0.1.4 @@ -1927,18 +1149,13 @@ packages: semver: 7.3.5 strip-ansi: 6.0.0 strip-json-comments: 3.1.1 - table: 5.4.6 + table: 6.6.0 text-table: 0.2.0 v8-compile-cache: 2.3.0 transitivePeerDependencies: - supports-color dev: true - /esm/3.2.25: - resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} - engines: {node: '>=6'} - dev: false - /espree/7.3.1: resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1952,6 +1169,7 @@ packages: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + dev: true /esquery/1.4.0: resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} @@ -1975,12 +1193,6 @@ packages: /estraverse/5.2.0: resolution: {integrity: sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==} engines: {node: '>=4.0'} - - /estree-walker/0.6.1: - resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} - - /estree-walker/1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} dev: true /estree-walker/2.0.2: @@ -1990,108 +1202,11 @@ packages: /esutils/2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - - /etag/1.8.1: - resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} - engines: {node: '>= 0.6'} - - /eventemitter3/4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: true - - /execa/4.1.0: - resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.0 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.3 - strip-final-newline: 2.0.0 - dev: true - - /express-history-api-fallback/2.2.1: - resolution: {integrity: sha1-OirSf3vryQ/FM9EQ18bYMJe80Fc=} - dev: true - optional: true - - /express-http-proxy/1.6.2: - resolution: {integrity: sha512-soP7UXySFdLbeeMYL1foBkEoZj6HELq9BDAOCr1sLRpqjPaFruN5o6+bZeC+7U4USWIl4JMKEiIvTeKJ2WQdlQ==} - engines: {node: '>=6.0.0'} - dependencies: - debug: 3.2.7 - es6-promise: 4.2.8 - raw-body: 2.4.1 - dev: true - optional: true - - /express-ws/4.0.0_express@4.17.1: - resolution: {integrity: sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw==} - engines: {node: '>=4.5.0'} - peerDependencies: - express: ^4.0.0 || ^5.0.0-alpha.1 - dependencies: - express: 4.17.1 - ws: 5.2.2 - dev: true - optional: true - - /express/4.17.1: - resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.7 - array-flatten: 1.1.1 - body-parser: 1.19.0 - content-disposition: 0.5.3 - content-type: 1.0.4 - cookie: 0.4.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 1.1.2 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.1.2 - fresh: 0.5.2 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.3.0 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.6 - qs: 6.7.0 - range-parser: 1.2.1 - safe-buffer: 5.1.2 - send: 0.17.1 - serve-static: 1.14.1 - setprototypeof: 1.1.1 - statuses: 1.5.0 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 dev: true - optional: true - - /extend/3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /extsprintf/1.3.0: - resolution: {integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=} - engines: {'0': node >=0.6.0} - dev: false - - /fast-decode-uri-component/1.0.1: - resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} - dev: false /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true /fast-glob/3.2.5: resolution: {integrity: sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==} @@ -2107,136 +1222,23 @@ packages: /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - /fast-json-stringify/2.5.4: - resolution: {integrity: sha512-fu74X0fRzQqADX6LFJ+5lSal1+j/QmX4oWrDnrfVAXV4qT6PwyymZmhGa/1SWgouOmf0tBJzZrHZPLymO00Lxg==} - engines: {node: '>= 10.0.0'} - dependencies: - ajv: 6.12.6 - deepmerge: 4.2.2 - rfdc: 1.3.0 - string-similarity: 4.0.4 - dev: false + dev: true /fast-levenshtein/2.0.6: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} - - /fast-redact/3.0.0: - resolution: {integrity: sha512-a/S/Hp6aoIjx7EmugtzLqXmcNsyFszqbt6qQ99BdG61QjBZF6shNis0BYR6TsZOQ1twYc0FN2Xdhwwbv6+KD0w==} - engines: {node: '>=6'} - dev: false - - /fast-safe-stringify/2.0.7: - resolution: {integrity: sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==} - dev: false - - /fastfall/1.5.1: - resolution: {integrity: sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=} - engines: {node: '>=0.10.0'} - dependencies: - reusify: 1.0.4 - dev: false - - /fastify-env/2.1.0: - resolution: {integrity: sha512-yKQ9s+w7ve5FIPmZg1ll6jUHFFes7lOV1jQpD/VzYfWs+Iavm+pqe7nUuOJN9NRRp5VPJ0BCoPa0qVl+w/+3+A==} - dependencies: - env-schema: 2.1.0 - fastify-plugin: 2.3.4 - dev: false - - /fastify-error/0.3.0: - resolution: {integrity: sha512-Jm2LMTB5rsJqlS1+cmgqqM9tTs0UrlgYR7TvDT3ZgXsUI5ib1NjQlqZHf+tDK5tVPdFGwyq02wAoJtyYIRSiFA==} - dev: false - - /fastify-jwt/2.4.0: - resolution: {integrity: sha512-RZ6TjDmMNajmMwh1xakR0iQcjP3NfrcFhwOc0leWp56G6+g7XX73TCzQxmxDNmLsclWDkgG8WTLUJETfaQWIQg==} - engines: {node: '>=10'} - dependencies: - '@types/jsonwebtoken': 8.5.1 - fastify-plugin: 3.0.0 - http-errors: 1.8.0 - jsonwebtoken: 8.5.1 - steed: 1.1.3 - dev: false - - /fastify-plugin/2.3.4: - resolution: {integrity: sha512-I+Oaj6p9oiRozbam30sh39BiuiqBda7yK2nmSPVwDCfIBlKnT8YB3MY+pRQc2Fcd07bf6KPGklHJaQ2Qu81TYQ==} - dependencies: - semver: 7.3.5 - dev: false - - /fastify-plugin/3.0.0: - resolution: {integrity: sha512-ZdCvKEEd92DNLps5n0v231Bha8bkz1DjnPP/aEz37rz/q42Z5JVLmgnqR4DYuNn3NXAO3IDCPyRvgvxtJ4Ym4w==} - dev: false - - /fastify-static/4.0.1: - resolution: {integrity: sha512-Mjt0My8Gf/nzJqIDai9rz3HsxH4RAJeMGMIPmf40lGMFKAv4SbRiKJ2cmteXoKHrFGPeGxwMq0gXfixwueV8wA==} - dependencies: - content-disposition: 0.5.3 - fastify-plugin: 3.0.0 - glob: 7.1.6 - readable-stream: 3.6.0 - send: 0.17.1 - dev: false - - /fastify-warning/0.2.0: - resolution: {integrity: sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw==} - dev: false - - /fastify/3.14.2: - resolution: {integrity: sha512-/PY//7gJnGxLQORaRHCEW148vpFKFpBIQNz1Yo/DxbHuk5EQqK2comzyE2ug8FSEldDX8nleapTshl0m78Px2w==} - engines: {node: '>=10.16.0'} - dependencies: - '@fastify/proxy-addr': 3.0.0 - abstract-logging: 2.0.1 - ajv: 6.12.6 - avvio: 7.2.1 - fast-json-stringify: 2.5.4 - fastify-error: 0.3.0 - fastify-warning: 0.2.0 - find-my-way: 4.1.0 - flatstr: 1.0.12 - light-my-request: 4.4.1 - pino: 6.11.3 - readable-stream: 3.6.0 - rfdc: 1.3.0 - secure-json-parse: 2.4.0 - semver: 7.3.5 - tiny-lru: 7.0.6 - transitivePeerDependencies: - - supports-color - dev: false - - /fastparallel/2.4.0: - resolution: {integrity: sha512-sacwQ7wwKlQXsa7TN24UvMBLZNLmVcPhmxccC9riFqb3N+fSczJL8eWdnZodZ/KijGVgNBBfvF/NeXER08uXnQ==} - dependencies: - reusify: 1.0.4 - xtend: 4.0.2 - dev: false + dev: true /fastq/1.11.0: resolution: {integrity: sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==} dependencies: reusify: 1.0.4 - - /fastseries/1.7.2: - resolution: {integrity: sha1-0izhO5Qz3/M4jZHb1ri9qbIaD0s=} - dependencies: - reusify: 1.0.4 - xtend: 4.0.2 - dev: false - - /fd-slicer/1.1.0: - resolution: {integrity: sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=} - dependencies: - pend: 1.2.0 dev: true - /file-entry-cache/5.0.1: - resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} - engines: {node: '>=4'} + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 2.0.1 + flat-cache: 3.0.4 dev: true /fill-range/7.0.1: @@ -2246,201 +1248,63 @@ packages: to-regex-range: 5.0.1 dev: true - /finalhandler/1.1.2: - resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} - engines: {node: '>= 0.8'} + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.3.0 - parseurl: 1.3.3 - statuses: 1.5.0 - unpipe: 1.0.0 + flatted: 3.1.1 + rimraf: 3.0.2 dev: true - optional: true - /find-cache-dir/3.3.1: - resolution: {integrity: sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==} - engines: {node: '>=8'} - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 + /flatted/3.1.1: + resolution: {integrity: sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==} dev: true - /find-my-way/4.1.0: - resolution: {integrity: sha512-UBD94MdO6cBi6E97XA0fBA9nwqw+xG5x1TYIPHats33gEi/kNqy7BWHAWx8QHCQQRSU5Txc0JiD8nzba39gvMQ==} - engines: {node: '>=10'} - dependencies: - fast-decode-uri-component: 1.0.1 - fast-deep-equal: 3.1.3 - safe-regex2: 2.0.0 - semver-store: 0.3.0 - dev: false - - /find-package-json/1.2.0: - resolution: {integrity: sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==} + /fraction.js/4.0.13: + resolution: {integrity: sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==} dev: true - /find-up/2.1.0: - resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=} - engines: {node: '>=4'} - dependencies: - locate-path: 2.0.0 - dev: true + /fs-constants/1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: false - /find-up/3.0.0: - resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} - engines: {node: '>=6'} + /fs-extra/9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} dependencies: - locate-path: 3.0.0 + at-least-node: 1.0.0 + graceful-fs: 4.2.6 + jsonfile: 6.1.0 + universalify: 2.0.0 dev: true - /find-up/4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true + /fs.realpath/1.0.0: + resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} - /flat-cache/2.0.1: - resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==} - engines: {node: '>=4'} - dependencies: - flatted: 2.0.2 - rimraf: 2.6.3 - write: 1.0.3 + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] dev: true + optional: true - /flatstr/1.0.12: - resolution: {integrity: sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==} - dev: false + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /flatted/2.0.2: - resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} + /function.name/1.0.13: + resolution: {integrity: sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==} + dependencies: + noop6: 1.0.9 dev: true - /flatten/1.0.3: - resolution: {integrity: sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==} - dev: true - - /follow-redirects/1.13.3: - resolution: {integrity: sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - /forever-agent/0.6.1: - resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=} - dev: false - - /form-data/2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.30 - dev: false - - /forwarded/0.1.2: - resolution: {integrity: sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=} - engines: {node: '>= 0.6'} - dev: true - optional: true - - /fresh/0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} - engines: {node: '>= 0.6'} - - /fs-constants/1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - /fs-extra/9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.6 - jsonfile: 6.1.0 - universalify: 2.0.0 - - /fs.realpath/1.0.0: - resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} - - /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - dev: true - optional: true - - /function-bind/1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - /functional-red-black-tree/1.0.1: - resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} + /functional-red-black-tree/1.0.1: + resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} dev: true /generate-password/1.6.0: resolution: {integrity: sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ==} dev: false - /generic-names/2.0.1: - resolution: {integrity: sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==} - dependencies: - loader-utils: 1.4.0 - dev: true - - /get-caller-file/2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - optional: true - - /get-intrinsic/1.1.1: - resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.2 - dev: true - - /get-port/5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - dev: true - - /get-stdin/8.0.0: - resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} - engines: {node: '>=10'} - dev: true - - /get-stream/4.1.0: - resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} - engines: {node: '>=6'} - dependencies: - pump: 3.0.0 - dev: true - - /get-stream/5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - dependencies: - pump: 3.0.0 - dev: true - - /getpass/0.1.7: - resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=} - dependencies: - assert-plus: 1.0.0 - dev: false - /glob-base/0.3.0: resolution: {integrity: sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=} engines: {node: '>=0.10.0'} @@ -2471,12 +1335,17 @@ packages: minimatch: 3.0.4 once: 1.4.0 path-is-absolute: 1.0.1 + dev: false - /global-dirs/2.1.0: - resolution: {integrity: sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==} - engines: {node: '>=8'} + /glob/7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} dependencies: - ini: 1.3.7 + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 dev: true /globals/12.4.0: @@ -2486,6 +1355,13 @@ packages: type-fest: 0.8.1 dev: true + /globals/13.8.0: + resolution: {integrity: sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + /globby/11.0.3: resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==} engines: {node: '>=10'} @@ -2498,60 +1374,18 @@ packages: slash: 3.0.0 dev: true - /got/9.6.0: - resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} - engines: {node: '>=8.6'} - dependencies: - '@sindresorhus/is': 0.14.0 - '@szmarczak/http-timer': 1.1.2 - cacheable-request: 6.1.0 - decompress-response: 3.3.0 - duplexer3: 0.1.4 - get-stream: 4.1.0 - lowercase-keys: 1.0.1 - mimic-response: 1.0.1 - p-cancelable: 1.1.0 - to-readable-stream: 1.0.0 - url-parse-lax: 3.0.0 - dev: true - /graceful-fs/4.2.6: resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==} - - /har-schema/2.0.0: - resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=} - engines: {node: '>=4'} - dev: false - - /har-validator/5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - dev: false - - /has-bigints/1.0.1: - resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} dev: true /has-flag/3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} engines: {node: '>=4'} + dev: true /has-flag/4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - - /has-symbols/1.0.2: - resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} - engines: {node: '>= 0.4'} - dev: true - - /has-yarn/2.1.0: - resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==} - engines: {node: '>=8'} dev: true /has/1.0.3: @@ -2564,149 +1398,26 @@ packages: resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} dev: true - /hosted-git-info/2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true - - /html-encoding-sniffer/2.0.1: - resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} - engines: {node: '>=10'} - dependencies: - whatwg-encoding: 1.0.5 - dev: false - - /html-tags/3.1.0: - resolution: {integrity: sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==} - engines: {node: '>=8'} - dev: true - - /http-assert/1.4.1: - resolution: {integrity: sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw==} - engines: {node: '>= 0.8'} - dependencies: - deep-equal: 1.0.1 - http-errors: 1.7.3 - dev: true - - /http-cache-semantics/4.1.0: - resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} - dev: true - - /http-errors-enhanced/0.7.0: - resolution: {integrity: sha512-SYVGmRIcKBurS7oDTPDnoYxBnEa8CPR0UZBAU6P0QsBPQY6XjIGoCK5iFxLkg1jeo+dkiq4MxqMJbBEoXcczBg==} - engines: {node: '>=12.15.0'} - dev: false - - /http-errors/1.4.0: - resolution: {integrity: sha1-bAJC3qaz33r9oVPHEImzHG6Cqr8=} - engines: {node: '>= 0.6'} - dependencies: - inherits: 2.0.1 - statuses: 1.5.0 - dev: true - - /http-errors/1.6.3: - resolution: {integrity: sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.3 - setprototypeof: 1.1.0 - statuses: 1.5.0 - dev: true - - /http-errors/1.7.2: - resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.3 - setprototypeof: 1.1.1 - statuses: 1.5.0 - toidentifier: 1.0.0 - dev: true - optional: true - - /http-errors/1.7.3: - resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.4 - setprototypeof: 1.1.1 - statuses: 1.5.0 - toidentifier: 1.0.0 - - /http-errors/1.8.0: - resolution: {integrity: sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 1.5.0 - toidentifier: 1.0.0 - - /http-proxy/1.18.1_debug@4.3.1: - resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} - engines: {node: '>=8.0.0'} - dependencies: - eventemitter3: 4.0.7 - follow-redirects: 1.13.3 - requires-port: 1.0.0 - transitivePeerDependencies: - - debug - dev: true - - /http-signature/1.2.0: - resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=} - engines: {node: '>=0.8', npm: '>=1.3.7'} - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.1 - sshpk: 1.16.1 - dev: false - - /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 + /hex-color-regex/1.1.0: + resolution: {integrity: sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==} dev: true - /human-signals/1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} + /hsl-regex/1.0.0: + resolution: {integrity: sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=} dev: true - /iconv-lite/0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - - /icss-replace-symbols/1.1.0: - resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=} + /hsla-regex/1.0.0: + resolution: {integrity: sha1-wc56MWjIxmFAM6S194d/OyJfnDg=} dev: true - /icss-utils/5.1.0_postcss@8.2.10: - resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 - dependencies: - postcss: 8.2.10 + /html-tags/3.1.0: + resolution: {integrity: sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==} + engines: {node: '>=8'} dev: true /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - /ignore-by-default/1.0.1: - resolution: {integrity: sha1-SMptcvbGo68Aqa1K5odr44ieKwk=} - dev: true + dev: false /ignore/4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} @@ -2740,11 +1451,6 @@ packages: resolve-from: 5.0.0 dev: true - /import-lazy/2.1.0: - resolution: {integrity: sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=} - engines: {node: '>=4'} - dev: true - /imurmurhash/0.1.4: resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} engines: {node: '>=0.8.19'} @@ -2760,49 +1466,18 @@ packages: once: 1.4.0 wrappy: 1.0.2 - /inherits/2.0.1: - resolution: {integrity: sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=} - dev: true - - /inherits/2.0.3: - resolution: {integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=} - dev: true - /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /ini/1.3.7: - resolution: {integrity: sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==} - dev: true - - /ini/1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true - - /internal-slot/1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.1.1 - has: 1.0.3 - side-channel: 1.0.4 - dev: true - /interpret/1.4.0: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} dev: false - /ipaddr.js/1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + /is-absolute-url/3.0.3: + resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==} + engines: {node: '>=8'} dev: true - optional: true - - /ipaddr.js/2.0.0: - resolution: {integrity: sha512-S54H9mIj0rbxRIyrDMEuuER86LdlgUg9FSeZ8duQb6CUG2iRrA36MYVQBSprTF/ZeAwvyQ5mDGuNvIPM0BIl3w==} - engines: {node: '>= 10'} - dev: false /is-arrayish/0.2.1: resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} @@ -2812,10 +1487,6 @@ packages: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} dev: true - /is-bigint/1.0.1: - resolution: {integrity: sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==} - dev: true - /is-binary-path/2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -2823,41 +1494,22 @@ packages: binary-extensions: 2.2.0 dev: true - /is-boolean-object/1.1.0: - resolution: {integrity: sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-callable/1.2.3: - resolution: {integrity: sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==} - engines: {node: '>= 0.4'} - dev: true - - /is-ci/2.0.0: - resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} - hasBin: true + /is-color-stop/1.1.0: + resolution: {integrity: sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=} dependencies: - ci-info: 2.0.0 + css-color-names: 0.0.4 + hex-color-regex: 1.1.0 + hsl-regex: 1.0.0 + hsla-regex: 1.0.0 + rgb-regex: 1.0.1 + rgba-regex: 1.0.0 dev: true - /is-core-module/2.2.0: - resolution: {integrity: sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==} + /is-core-module/2.4.0: + resolution: {integrity: sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==} dependencies: has: 1.0.3 - /is-date-object/1.0.2: - resolution: {integrity: sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==} - engines: {node: '>= 0.4'} - dev: true - - /is-docker/2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - /is-dotfile/1.0.3: resolution: {integrity: sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=} engines: {node: '>=0.10.0'} @@ -2873,21 +1525,11 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-fullwidth-code-point/2.0.0: - resolution: {integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=} - engines: {node: '>=4'} - dev: true - /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: true - /is-generator-function/1.0.8: - resolution: {integrity: sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==} - engines: {node: '>= 0.4'} - dev: true - /is-glob/2.0.1: resolution: {integrity: sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=} engines: {node: '>=0.10.0'} @@ -2902,38 +1544,6 @@ packages: is-extglob: 2.1.1 dev: true - /is-installed-globally/0.3.2: - resolution: {integrity: sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==} - engines: {node: '>=8'} - dependencies: - global-dirs: 2.1.0 - is-path-inside: 3.0.3 - dev: true - - /is-interactive/1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - dev: true - - /is-module/1.0.0: - resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=} - dev: true - - /is-negative-zero/2.0.1: - resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==} - engines: {node: '>= 0.4'} - dev: true - - /is-npm/4.0.0: - resolution: {integrity: sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==} - engines: {node: '>=8'} - dev: true - - /is-number-object/1.0.4: - resolution: {integrity: sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==} - engines: {node: '>= 0.4'} - dev: true - /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2944,202 +1554,60 @@ packages: engines: {node: '>=8'} dev: true - /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} + /is-resolvable/1.1.0: + resolution: {integrity: sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==} dev: true - /is-potential-custom-element-name/1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + /isarray/1.0.0: + resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} dev: false - /is-reference/1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - dependencies: - '@types/estree': 0.0.47 - dev: true - - /is-regex/1.1.2: - resolution: {integrity: sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-symbols: 1.0.2 - dev: true - - /is-stream/2.0.0: - resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} - engines: {node: '>=8'} + /isexe/2.0.0: + resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} dev: true - /is-string/1.0.5: - resolution: {integrity: sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==} - engines: {node: '>= 0.4'} + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true - /is-symbol/1.0.3: - resolution: {integrity: sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==} - engines: {node: '>= 0.4'} + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true dependencies: - has-symbols: 1.0.2 + argparse: 1.0.10 + esprima: 4.0.1 dev: true - /is-typedarray/1.0.0: - resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: false - /is-unicode-supported/0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: true - /is-wsl/2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true - /is-yarn-global/0.3.0: - resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==} + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: true - /isarray/0.0.1: - resolution: {integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=} - dev: true - - /isarray/1.0.0: - resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} - - /isbuiltin/1.0.0: - resolution: {integrity: sha1-RFOykVaQy0fAy5ySVaCAd3gxXJY=} - dependencies: - builtin-modules: 1.1.1 - dev: true - - /isexe/2.0.0: - resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} - dev: true - - /isstream/0.1.2: - resolution: {integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=} - dev: false - - /jest-worker/26.6.2: - resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/node': 14.14.41 - merge-stream: 2.0.0 - supports-color: 7.2.0 - dev: true - - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - dev: false - - /jsbn/0.1.1: - resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=} - dev: false - - /jsdom/16.5.3_c70f8fc5586dd378b8c866035dbe710b: - resolution: {integrity: sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==} - engines: {node: '>=10'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - dependencies: - abab: 2.0.5 - acorn: 8.1.1 - acorn-globals: 6.0.0 - cssom: 0.4.4 - cssstyle: 2.3.0 - data-urls: 2.0.0 - decimal.js: 10.2.1 - domexception: 2.0.1 - escodegen: 2.0.0 - html-encoding-sniffer: 2.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.0 - parse5: 6.0.1 - request: 2.88.2 - request-promise-native: 1.0.9_request@2.88.2 - saxes: 5.0.1 - symbol-tree: 3.2.4 - tough-cookie: 4.0.0 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 2.0.0 - webidl-conversions: 6.1.0 - whatwg-encoding: 1.0.5 - whatwg-mimetype: 2.3.0 - whatwg-url: 8.5.0 - ws: 7.4.4_c70f8fc5586dd378b8c866035dbe710b - xml-name-validator: 3.0.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /json-buffer/3.0.0: - resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} - dev: true - - /json-parse-better-errors/1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: true - - /json-parse-even-better-errors/2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: false - - /json-schema/0.2.3: - resolution: {integrity: sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=} - dev: false - /json-stable-stringify-without-jsonify/1.0.1: resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} dev: true - /json-stringify-safe/5.0.1: - resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} - dev: false - - /json5/1.0.1: - resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} - hasBin: true - dependencies: - minimist: 1.2.5 - dev: true - /jsonfile/6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.6 + dev: true /jsonwebtoken/8.5.1: resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} @@ -3157,24 +1625,6 @@ packages: semver: 5.7.1 dev: false - /jsprim/1.4.1: - resolution: {integrity: sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.2.3 - verror: 1.10.0 - dev: false - - /jsx-ast-utils/3.2.0: - resolution: {integrity: sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==} - engines: {node: '>=4.0'} - dependencies: - array-includes: 3.1.3 - object.assign: 4.1.2 - dev: true - /jwa/1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} dependencies: @@ -3194,129 +1644,6 @@ packages: resolution: {integrity: sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==} dev: false - /keygrip/1.1.0: - resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} - engines: {node: '>= 0.6'} - dependencies: - tsscmp: 1.0.6 - dev: true - - /keyv/3.1.0: - resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} - dependencies: - json-buffer: 3.0.0 - dev: true - - /klona/2.0.4: - resolution: {integrity: sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==} - engines: {node: '>= 8'} - dev: true - - /koa-compose/3.2.1: - resolution: {integrity: sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=} - dependencies: - any-promise: 1.3.0 - dev: true - - /koa-compose/4.1.0: - resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} - dev: true - - /koa-conditional-get/3.0.0: - resolution: {integrity: sha512-VKyPS7SuNH26TjTV2IRz+oh0HV/jc2lYAo51PTQTkj0XFn8ebNZW9riczmrW7ZVBFSnls1Z88DPUYKnvVymruA==} - dev: true - - /koa-convert/1.2.0: - resolution: {integrity: sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=} - engines: {node: '>= 4'} - dependencies: - co: 4.6.0 - koa-compose: 3.2.1 - dev: true - - /koa-etag/4.0.0: - resolution: {integrity: sha512-1cSdezCkBWlyuB9l6c/IFoe1ANCDdPBxkDkRiaIup40xpUub6U/wwRXoKBZw/O5BifX9OlqAjYnDyzM6+l+TAg==} - dependencies: - etag: 1.8.1 - dev: true - - /koa-proxies/0.11.0_debug@4.3.1+koa@2.13.1: - resolution: {integrity: sha512-iXGRADBE0fM7g7AttNOlLZ/cCFKXeVMHbFJKIRb0dUCrSYXi02loyVSdBlKlBQ5ZfVKJLo9Q9FyqwVTp1poVVA==} - peerDependencies: - koa: '>=2' - dependencies: - http-proxy: 1.18.1_debug@4.3.1 - koa: 2.13.1 - path-match: 1.2.4 - transitivePeerDependencies: - - debug - dev: true - - /koa-send/5.0.1: - resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==} - engines: {node: '>= 8'} - dependencies: - debug: 4.3.1 - http-errors: 1.8.0 - resolve-path: 1.4.0 - transitivePeerDependencies: - - supports-color - dev: true - - /koa-static/5.0.0: - resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==} - engines: {node: '>= 7.6.0'} - dependencies: - debug: 3.2.7 - koa-send: 5.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /koa/2.13.1: - resolution: {integrity: sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w==} - engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} - dependencies: - accepts: 1.3.7 - cache-content-type: 1.0.1 - content-disposition: 0.5.3 - content-type: 1.0.4 - cookies: 0.8.0 - debug: 3.1.0 - delegates: 1.0.0 - depd: 2.0.0 - destroy: 1.0.4 - encodeurl: 1.0.2 - escape-html: 1.0.3 - fresh: 0.5.2 - http-assert: 1.4.1 - http-errors: 1.8.0 - is-generator-function: 1.0.8 - koa-compose: 4.1.0 - koa-convert: 1.2.0 - on-finished: 2.3.0 - only: 0.0.2 - parseurl: 1.3.3 - statuses: 1.5.0 - type-is: 1.6.18 - vary: 1.1.2 - dev: true - - /latest-version/5.1.0: - resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==} - engines: {node: '>=8'} - dependencies: - package-json: 6.5.0 - dev: true - - /levn/0.3.0: - resolution: {integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: false - /levn/0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3325,91 +1652,16 @@ packages: type-check: 0.4.0 dev: true - /light-my-request/4.4.1: - resolution: {integrity: sha512-FDNRF2mYjthIRWE7O8d/X7AzDx4otQHl4/QXbu3Q/FRwBFcgb+ZoDaUd5HwN53uQXLAiw76osN+Va0NEaOW6rQ==} - dependencies: - ajv: 6.12.6 - cookie: 0.4.1 - fastify-warning: 0.2.0 - readable-stream: 3.6.0 - set-cookie-parser: 2.4.8 - dev: false - /lines-and-columns/1.1.6: resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=} dev: true - /load-json-file/2.0.0: - resolution: {integrity: sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.6 - parse-json: 2.2.0 - pify: 2.3.0 - strip-bom: 3.0.0 + /lodash.clonedeep/4.5.0: + resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=} dev: true - /load-json-file/4.0.0: - resolution: {integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs=} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.6 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - dev: true - - /load-json-file/5.3.0: - resolution: {integrity: sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==} - engines: {node: '>=6'} - dependencies: - graceful-fs: 4.2.6 - parse-json: 4.0.0 - pify: 4.0.1 - strip-bom: 3.0.0 - type-fest: 0.3.1 - dev: true - - /loader-utils/1.4.0: - resolution: {integrity: sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==} - engines: {node: '>=4.0.0'} - dependencies: - big.js: 5.2.2 - emojis-list: 3.0.0 - json5: 1.0.1 - dev: true - - /locate-path/2.0.0: - resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} - engines: {node: '>=4'} - dependencies: - p-locate: 2.0.0 - path-exists: 3.0.0 - dev: true - - /locate-path/3.0.0: - resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} - engines: {node: '>=6'} - dependencies: - p-locate: 3.0.0 - path-exists: 3.0.0 - dev: true - - /locate-path/5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /lockfile/1.0.4: - resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} - dependencies: - signal-exit: 3.0.3 - dev: true - - /lodash.camelcase/4.3.0: - resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=} + /lodash.flatten/4.4.0: + resolution: {integrity: sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=} dev: true /lodash.includes/4.3.0: @@ -3436,6 +1688,10 @@ packages: resolution: {integrity: sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=} dev: false + /lodash.memoize/4.1.2: + resolution: {integrity: sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=} + dev: true + /lodash.once/4.1.1: resolution: {integrity: sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=} dev: false @@ -3448,45 +1704,16 @@ packages: resolution: {integrity: sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=} dev: true - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - /log-symbols/3.0.0: - resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} - engines: {node: '>=8'} - dependencies: - chalk: 2.4.2 - dev: false - - /log-symbols/4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - dependencies: - chalk: 4.1.0 - is-unicode-supported: 0.1.0 - dev: true - - /loose-envify/1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: true - - /lowercase-keys/1.0.1: - resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} - engines: {node: '>=0.10.0'} + /lodash.truncate/4.4.2: + resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} dev: true - /lowercase-keys/2.0.0: - resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} - engines: {node: '>=8'} + /lodash.uniq/4.5.0: + resolution: {integrity: sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=} dev: true - /lru-cache/5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true /lru-cache/6.0.0: @@ -3494,66 +1721,22 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - - /magic-string/0.25.7: - resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==} - dependencies: - sourcemap-codec: 1.4.8 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: true - - /md5-file/5.0.0: - resolution: {integrity: sha512-xbEFXCYVWrSx/gEKS1VPlg84h/4L20znVIulKw6kMfmBUAZNAnF00eczz9ICMl+/hjQGo5KSXRxbL/47X3rmMw==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /media-typer/0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} - engines: {node: '>= 0.6'} + /mdn-data/2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: true /memory-pager/1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + dev: false optional: true - /memorystream/0.3.1: - resolution: {integrity: sha1-htcJCzDORV1j+64S3aUaR93K+bI=} - engines: {node: '>= 0.10.0'} - dev: true - - /merge-descriptors/1.0.1: - resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} - dev: true - optional: true - - /merge-source-map/1.1.0: - resolution: {integrity: sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==} - dependencies: - source-map: 0.6.1 - dev: true - - /merge-stream/2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true - /methods/1.1.2: - resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=} - engines: {node: '>= 0.6'} - dev: true - optional: true - /micromatch/4.0.4: resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} engines: {node: '>=8.6'} @@ -3562,31 +1745,6 @@ packages: picomatch: 2.2.3 dev: true - /mime-db/1.47.0: - resolution: {integrity: sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==} - engines: {node: '>= 0.6'} - - /mime-types/2.1.30: - resolution: {integrity: sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.47.0 - - /mime/1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - - /mimic-response/1.0.1: - resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} - engines: {node: '>=4'} - dev: true - /min-indent/1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -3605,56 +1763,11 @@ packages: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: false - /mkdirp/0.5.5: - resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} - hasBin: true - dependencies: - minimist: 1.2.5 - dev: true - - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /modern-normalize/1.0.0: - resolution: {integrity: sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw==} + /modern-normalize/1.1.0: + resolution: {integrity: sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==} engines: {node: '>=6'} dev: true - /mongodb-memory-server-core/6.9.6: - resolution: {integrity: sha512-ZcXHTI2TccH3L5N9JyAMGm8bbAsfLn8SUWOeYGHx/vDx7vu4qshyaNXTIxeHjpUQA29N+Z1LtTXA6vXjl1eg6w==} - engines: {node: '>=10.15.0'} - dependencies: - '@types/tmp': 0.2.0 - camelcase: 6.2.0 - cross-spawn: 7.0.3 - debug: 4.3.1 - find-cache-dir: 3.3.1 - find-package-json: 1.2.0 - get-port: 5.1.1 - https-proxy-agent: 5.0.0 - lockfile: 1.0.4 - md5-file: 5.0.0 - mkdirp: 1.0.4 - semver: 7.3.5 - tar-stream: 2.2.0 - tmp: 0.2.1 - uuid: 8.3.2 - yauzl: 2.10.0 - optionalDependencies: - mongodb: 3.6.6 - transitivePeerDependencies: - - aws4 - - bson-ext - - kerberos - - mongodb-client-encryption - - mongodb-extjson - - snappy - - supports-color - dev: true - /mongodb/3.6.6: resolution: {integrity: sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==} engines: {node: '>=4'} @@ -3686,30 +1799,31 @@ packages: safe-buffer: 5.2.1 optionalDependencies: saslprep: 1.0.3 + dev: false - /mongoose-legacy-pluralize/1.0.2_mongoose@5.12.4: + /mongoose-legacy-pluralize/1.0.2_mongoose@5.12.7: resolution: {integrity: sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==} peerDependencies: mongoose: '*' dependencies: - mongoose: 5.12.4 + mongoose: 5.12.7 dev: false - /mongoose/5.12.4: - resolution: {integrity: sha512-iVREPLK/35ylEdaNBCStwTugyUYDv7ZuI7maSW7CdCgAX4dMW4be1CdKvZHJtlexO/ugKphMMFL9/bppcWXQ9Q==} + /mongoose/5.12.7: + resolution: {integrity: sha512-BniNwACn7uflK2h+M3juvyLH5nn9JDFgnB5KE2EwWFwSrRyhSpPnCtanRKJW3OtMCJyPccMIjtGZxHNW7JfnIw==} engines: {node: '>=4.0.0'} dependencies: '@types/mongodb': 3.6.12 bson: 1.1.6 kareem: 2.3.2 mongodb: 3.6.6 - mongoose-legacy-pluralize: 1.0.2_mongoose@5.12.4 + mongoose-legacy-pluralize: 1.0.2_mongoose@5.12.7 mpath: 0.8.3 mquery: 3.2.5 ms: 2.1.2 regexp-clone: 1.0.0 safe-buffer: 5.2.1 - sift: 7.0.1 + sift: 13.5.2 sliced: 1.0.1 transitivePeerDependencies: - aws4 @@ -3736,17 +1850,21 @@ packages: sliced: 1.0.1 dev: false + /mri/1.1.6: + resolution: {integrity: sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==} + engines: {node: '>=4'} + dev: true + /ms/2.0.0: resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} - - /ms/2.1.1: - resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: false /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false /nanoid/3.1.22: resolution: {integrity: sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==} @@ -3754,17 +1872,14 @@ packages: hasBin: true dev: true - /natural-compare/1.4.0: - resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} - dev: true - - /negotiator/0.6.2: - resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} - engines: {node: '>= 0.6'} + /nanoid/3.1.23: + resolution: {integrity: sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true dev: true - /nice-try/1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + /natural-compare/1.4.0: + resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} dev: true /node-emoji/1.10.0: @@ -3773,78 +1888,12 @@ packages: lodash.toarray: 4.4.0 dev: true - /node-fetch/2.6.1: - resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} - engines: {node: 4.x || >=6.0.0} - dev: false - - /node-forge/0.10.0: - resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==} - engines: {node: '>= 6.0.0'} - dev: true - - /node-gyp-build/4.2.3: - resolution: {integrity: sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==} - hasBin: true - dev: false - /node-releases/1.1.71: resolution: {integrity: sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==} dev: true - /nodemon/2.0.7: - resolution: {integrity: sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==} - engines: {node: '>=8.10.0'} - hasBin: true - requiresBuild: true - dependencies: - chokidar: 3.5.1 - debug: 3.2.7 - ignore-by-default: 1.0.1 - minimatch: 3.0.4 - pstree.remy: 1.1.8 - semver: 5.7.1 - supports-color: 5.5.0 - touch: 3.1.0 - undefsafe: 2.0.3 - update-notifier: 4.1.3 - dev: true - - /nollup/0.16.1: - resolution: {integrity: sha512-G4XtdErjDS9QEw5jK38hLR6W57TwkpiMFvTpkpHunPg3t2wSZwsBTPqENTfNPundAip0GFNefyAvT8LGEtvkkQ==} - hasBin: true - dependencies: - '@rollup/pluginutils': 3.1.0 - acorn: 8.1.1 - chokidar: 3.5.1 - convert-source-map: 1.7.0 - express: 4.17.1 - express-history-api-fallback: 2.2.1 - express-http-proxy: 1.6.2 - express-ws: 4.0.0_express@4.17.1 - magic-string: 0.25.7 - mime-types: 2.1.30 - source-map: 0.5.7 - source-map-fast: /source-map/0.7.3 - transitivePeerDependencies: - - rollup - dev: true - optional: true - - /nopt/1.0.10: - resolution: {integrity: sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=} - hasBin: true - dependencies: - abbrev: 1.1.1 - dev: true - - /normalize-package-data/2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.20.0 - semver: 5.7.1 - validate-npm-package-license: 3.0.4 + /noop6/1.0.9: + resolution: {integrity: sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==} dev: true /normalize-path/3.0.0: @@ -3862,41 +1911,12 @@ packages: engines: {node: '>=8'} dev: true - /npm-run-all/4.1.5: - resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} - engines: {node: '>= 4'} - hasBin: true - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.5 - memorystream: 0.3.1 - minimatch: 3.0.4 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.7.2 - string.prototype.padend: 3.1.2 - dev: true - - /npm-run-path/4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + /nth-check/2.0.0: + resolution: {integrity: sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==} dependencies: - path-key: 3.1.1 - dev: true - - /num2fraction/1.2.2: - resolution: {integrity: sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=} + boolbase: 1.0.0 dev: true - /nwsapi/2.2.0: - resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} - dev: false - - /oauth-sign/0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: false - /object-assign/4.1.1: resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} engines: {node: '>=0.10.0'} @@ -3907,99 +1927,14 @@ packages: engines: {node: '>= 6'} dev: true - /object-inspect/1.9.0: - resolution: {integrity: sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==} - dev: true - - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object.assign/4.1.2: - resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - has-symbols: 1.0.2 - object-keys: 1.1.1 - dev: true - - /object.entries/1.1.3: - resolution: {integrity: sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - has: 1.0.3 - dev: true - - /object.fromentries/2.0.4: - resolution: {integrity: sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - has: 1.0.3 - dev: true - - /object.values/1.1.3: - resolution: {integrity: sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - has: 1.0.3 - dev: true - - /on-finished/2.3.0: - resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - /once/1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: wrappy: 1.0.2 - /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - - /only/0.0.2: - resolution: {integrity: sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=} - dev: true - - /open/7.4.2: - resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - is-wsl: 2.2.0 - dev: true - /optional-require/1.0.3: resolution: {integrity: sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==} engines: {node: '>=4'} - - /optionator/0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.3 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.3 dev: false /optionator/0.9.1: @@ -4014,86 +1949,6 @@ packages: word-wrap: 1.2.3 dev: true - /ora/5.4.0: - resolution: {integrity: sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.0 - cli-cursor: 3.1.0 - cli-spinners: 2.6.0 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.0 - wcwidth: 1.0.1 - dev: true - - /p-cancelable/1.1.0: - resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} - engines: {node: '>=6'} - dev: true - - /p-limit/1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} - dependencies: - p-try: 1.0.0 - dev: true - - /p-limit/2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-locate/2.0.0: - resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=} - engines: {node: '>=4'} - dependencies: - p-limit: 1.3.0 - dev: true - - /p-locate/3.0.0: - resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} - engines: {node: '>=6'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate/4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-map-series/2.1.0: - resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} - engines: {node: '>=8'} - dev: true - - /p-try/1.0.0: - resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=} - engines: {node: '>=4'} - dev: true - - /p-try/2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /package-json/6.5.0: - resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} - engines: {node: '>=8'} - dependencies: - got: 9.6.0 - registry-auth-token: 4.2.1 - registry-url: 5.1.0 - semver: 6.3.0 - dev: true - /parent-module/1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -4111,572 +1966,388 @@ packages: is-glob: 2.0.1 dev: true - /parse-json/2.2.0: - resolution: {integrity: sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=} - engines: {node: '>=0.10.0'} - dependencies: - error-ex: 1.3.2 - dev: true - - /parse-json/4.0.0: - resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=} - engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: true - /parse-json/5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.12.13 + '@babel/code-frame': 7.12.11 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.1.6 dev: true - /parse5/6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: false - - /parseurl/1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - dev: true - - /path-exists/3.0.0: - resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} - engines: {node: '>=4'} - dev: true - - /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - /path-is-absolute/1.0.1: resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} - engines: {node: '>=0.10.0'} - - /path-key/2.0.1: - resolution: {integrity: sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=} - engines: {node: '>=4'} - dev: true - - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-match/1.2.4: - resolution: {integrity: sha1-pidH88fgwlFHYml/JEQ1hbCRAOo=} - dependencies: - http-errors: 1.4.0 - path-to-regexp: 1.8.0 - dev: true - - /path-parse/1.0.6: - resolution: {integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==} - - /path-to-regexp/0.1.7: - resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} - dev: true - optional: true - - /path-to-regexp/1.8.0: - resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} - dependencies: - isarray: 0.0.1 - dev: true - - /path-type/2.0.0: - resolution: {integrity: sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=} - engines: {node: '>=4'} - dependencies: - pify: 2.3.0 - dev: true - - /path-type/3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - - /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /pend/1.2.0: - resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=} - dev: true - - /performance-now/2.1.0: - resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=} - dev: false - - /picomatch/2.2.3: - resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==} - engines: {node: '>=8.6'} - - /pidtree/0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - dev: true - - /pify/2.3.0: - resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} - engines: {node: '>=0.10.0'} - dev: true - - /pify/3.0.0: - resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=} - engines: {node: '>=4'} - dev: true - - /pify/4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: true - - /pino-std-serializers/3.2.0: - resolution: {integrity: sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==} - dev: false - - /pino/6.11.3: - resolution: {integrity: sha512-drPtqkkSf0ufx2gaea3TryFiBHdNIdXKf5LN0hTM82SXI4xVIve2wLwNg92e1MT6m3jASLu6VO7eGY6+mmGeyw==} - hasBin: true - dependencies: - fast-redact: 3.0.0 - fast-safe-stringify: 2.0.7 - flatstr: 1.0.12 - pino-std-serializers: 3.2.0 - quick-format-unescaped: 4.0.3 - sonic-boom: 1.4.1 - dev: false - - /pkg-conf/3.1.0: - resolution: {integrity: sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==} - engines: {node: '>=6'} - dependencies: - find-up: 3.0.0 - load-json-file: 5.3.0 - dev: true - - /pkg-dir/2.0.0: - resolution: {integrity: sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=} - engines: {node: '>=4'} - dependencies: - find-up: 2.1.0 - dev: true - - /pkg-dir/4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /postcss-attribute-case-insensitive/4.0.2: - resolution: {integrity: sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==} - dependencies: - postcss: 7.0.35 - postcss-selector-parser: 6.0.4 - dev: true - - /postcss-color-functional-notation/2.0.1: - resolution: {integrity: sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 - dev: true - - /postcss-color-gray/5.0.0: - resolution: {integrity: sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==} - engines: {node: '>=6.0.0'} - dependencies: - '@csstools/convert-colors': 1.4.0 - postcss: 7.0.35 - postcss-values-parser: 2.0.1 - dev: true - - /postcss-color-hex-alpha/5.0.3: - resolution: {integrity: sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 - dev: true - - /postcss-color-mod-function/3.0.3: - resolution: {integrity: sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@csstools/convert-colors': 1.4.0 - postcss: 7.0.35 - postcss-values-parser: 2.0.1 - dev: true + engines: {node: '>=0.10.0'} - /postcss-color-rebeccapurple/4.0.1: - resolution: {integrity: sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} dev: true - /postcss-custom-media/7.0.8: - resolution: {integrity: sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - dev: true + /path-parse/1.0.6: + resolution: {integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==} - /postcss-custom-properties/8.0.11: - resolution: {integrity: sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} dev: true - /postcss-custom-selectors/5.1.2: - resolution: {integrity: sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.35 - postcss-selector-parser: 5.0.0 + /picomatch/2.2.3: + resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==} + engines: {node: '>=8.6'} dev: true - /postcss-dir-pseudo-class/5.0.0: - resolution: {integrity: sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==} - engines: {node: '>=4.0.0'} + /postcss-calc/8.0.0_postcss@8.2.14: + resolution: {integrity: sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==} + peerDependencies: + postcss: ^8.2.2 dependencies: - postcss: 7.0.35 - postcss-selector-parser: 5.0.0 + postcss: 8.2.14 + postcss-selector-parser: 6.0.5 + postcss-value-parser: 4.1.0 dev: true - /postcss-discard-comments/4.0.2: - resolution: {integrity: sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==} - engines: {node: '>=6.9.0'} + /postcss-colormin/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-Yt84+5V6CgS/AhK7d7MA58vG8dSZ7+ytlRtWLaQhag3HXOncTfmYpuUOX4cDoXjvLfw1sHRCHMiBjYhc35CymQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + browserslist: 4.16.6 + color: 3.1.3 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-double-position-gradients/1.0.0: - resolution: {integrity: sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==} - engines: {node: '>=6.0.0'} + /postcss-convert-values/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-V5kmYm4xoBAjNs+eHY/6XzXJkkGeg4kwNf2ocfqhLb1WBPEa4oaSmoi1fnVO7Dkblqvus9h+AenDvhCKUCK7uQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-env-function/2.0.2: - resolution: {integrity: sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==} - engines: {node: '>=6.0.0'} + /postcss-discard-comments/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-Umig6Gxs8m20RihiXY6QkePd6mp4FxkA1Dg+f/Kd6uw0gEMfKRjDeQOyFkLibexbJJGHpE3lrN/Q0R9SMrUMbQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + postcss: 8.2.14 dev: true - /postcss-focus-visible/4.0.0: - resolution: {integrity: sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==} - engines: {node: '>=6.0.0'} + /postcss-discard-duplicates/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-vEJJ+Y3pFUnO1FyCBA6PSisGjHtnphL3V6GsNvkASq/VkP3OX5/No5RYXXLxHa2QegStNzg6HYrYdo71uR4caQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 dev: true - /postcss-focus-within/3.0.0: - resolution: {integrity: sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==} - engines: {node: '>=6.0.0'} + /postcss-discard-empty/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-+wigy099Y1xZxG36WG5L1f2zeH1oicntkJEW4TDIqKKDO2g9XVB3OhoiHTu08rDEjLnbcab4rw0BAccwi2VjiQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 dev: true - /postcss-font-variant/4.0.1: - resolution: {integrity: sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==} + /postcss-discard-overridden/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-hybnScTaZM2iEA6kzVQ6Spozy7kVdLw+lGw8hftLlBEzt93uzXoltkYp9u0tI8xbfhxDLTOOzHsHQCkYdmzRUg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 dev: true /postcss-functions/3.0.0: resolution: {integrity: sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=} dependencies: - glob: 7.1.6 + glob: 7.1.7 object-assign: 4.1.1 postcss: 6.0.23 postcss-value-parser: 3.3.1 dev: true - /postcss-gap-properties/2.0.0: - resolution: {integrity: sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==} - engines: {node: '>=6.0.0'} + /postcss-js/3.0.3: + resolution: {integrity: sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==} + engines: {node: '>=10.0'} dependencies: - postcss: 7.0.35 + camelcase-css: 2.0.1 + postcss: 8.2.15 dev: true - /postcss-image-set-function/3.0.1: - resolution: {integrity: sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==} - engines: {node: '>=6.0.0'} + /postcss-load-config/3.0.1: + resolution: {integrity: sha512-/pDHe30UYZUD11IeG8GWx9lNtu1ToyTsZHnyy45B4Mrwr/Kb6NgYl7k753+05CJNKnjbwh4975amoPJ+TEjHNQ==} + engines: {node: '>= 10'} dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + cosmiconfig: 7.0.0 + import-cwd: 3.0.0 dev: true - /postcss-import/12.0.1: - resolution: {integrity: sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==} - engines: {node: '>=6.0.0'} + /postcss-merge-longhand/5.0.1_postcss@8.2.14: + resolution: {integrity: sha512-H1RO8le5deFGumQzuhJjuL0bIXPRysa+w7xtk5KrHe38oiaSS9ksPXDo24+IOS3SETPhip0J5+1uCOW+ALs3Yw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 - postcss-value-parser: 3.3.1 - read-cache: 1.0.0 - resolve: 1.20.0 + css-color-names: 1.0.1 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 + stylehacks: 5.0.0_postcss@8.2.14 dev: true - /postcss-import/14.0.1_postcss@8.2.10: - resolution: {integrity: sha512-Xn2+z++vWObbEPhiiKO1a78JiyhqipyrXHBb3AHpv0ks7Cdg+GxQQJ24ODNMTanldf7197gSP3axppO9yaG0lA==} - engines: {node: '>=10.0.0'} + /postcss-merge-rules/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-TfsXbKjNYCGfUPEXGIGPySnMiJbdS+3gcVeV8gwmJP4RajyKZHW8E0FYDL1WmggTj3hi+m+WUCAvqRpX2ut4Kg==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.0.0 + postcss: ^8.2.1 dependencies: - postcss: 8.2.10 - postcss-value-parser: 4.1.0 - read-cache: 1.0.0 - resolve: 1.20.0 + browserslist: 4.16.6 + caniuse-api: 3.0.0 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-selector-parser: 6.0.5 + vendors: 1.0.4 dev: true - /postcss-initial/3.0.4: - resolution: {integrity: sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==} + /postcss-minify-font-values/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-zi2JhFaMOcIaNxhndX5uhsqSY1rexKDp23wV8EOmC9XERqzLbHsoRye3aYF716Zm+hkcR4loqKDt8LZlmihwAg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-js/3.0.3: - resolution: {integrity: sha512-gWnoWQXKFw65Hk/mi2+WTQTHdPD5UJdDXZmX073EY/B3BWnYjO4F4t0VneTCnCGQ5E5GsCdMkzPaTXwl3r5dJw==} - engines: {node: '>=10.0'} + /postcss-minify-gradients/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-/jPtNgs6JySMwgsE5dPOq8a2xEopWTW3RyqoB9fLqxgR+mDUNLSi7joKd+N1z7FXWgVkc4l/dEBMXHgNAaUbvg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - camelcase-css: 2.0.1 - postcss: 8.2.10 + cssnano-utils: 2.0.0_postcss@8.2.14 + is-color-stop: 1.1.0 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-lab-function/2.0.1: - resolution: {integrity: sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==} - engines: {node: '>=6.0.0'} + /postcss-minify-params/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-KvZYIxTPBVKjdd+XgObq9A+Sfv8lMkXTpbZTsjhr42XbfWIeLaTItMlygsDWfjArEc3muUfDaUFgNSeDiJ5jug==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - '@csstools/convert-colors': 1.4.0 - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + alphanum-sort: 1.0.2 + browserslist: 4.16.6 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 + uniqs: 2.0.0 dev: true - /postcss-load-config/3.0.1: - resolution: {integrity: sha512-/pDHe30UYZUD11IeG8GWx9lNtu1ToyTsZHnyy45B4Mrwr/Kb6NgYl7k753+05CJNKnjbwh4975amoPJ+TEjHNQ==} - engines: {node: '>= 10'} + /postcss-minify-selectors/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-cEM0O0eWwFIvmo6nfB0lH0vO/XFwgqIvymODbfPXZ1gTA3i76FKnb7TGUrEpiTxaXH6tgYQ6DcTHwRiRS+YQLQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - cosmiconfig: 7.0.0 - import-cwd: 3.0.0 + alphanum-sort: 1.0.2 + postcss: 8.2.14 + postcss-selector-parser: 3.1.2 dev: true - /postcss-logical/3.0.0: - resolution: {integrity: sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==} - engines: {node: '>=6.0.0'} + /postcss-nested/5.0.5_postcss@8.2.14: + resolution: {integrity: sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==} + engines: {node: '>=10.0'} + peerDependencies: + postcss: ^8.1.13 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 + postcss-selector-parser: 6.0.6 dev: true - /postcss-media-minmax/4.0.0: - resolution: {integrity: sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==} - engines: {node: '>=6.0.0'} + /postcss-normalize-charset/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-pqsCkgo9KmQP0ew6DqSA+uP9YN6EfsW20pQ3JU5JoQge09Z6Too4qU0TNDsTNWuEaP8SWsMp+19l15210MsDZQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 dev: true - /postcss-modules-extract-imports/3.0.0_postcss@8.2.10: - resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} - engines: {node: ^10 || ^12 || >= 14} + /postcss-normalize-display-values/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-t4f2d//gH1f7Ns0Jq3eNdnWuPT7TeLuISZ6RQx4j8gpl5XrhkdshdNcOnlrEK48YU6Tcb6jqK7dorME3N4oOGA==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.1.0 + postcss: ^8.2.1 dependencies: - postcss: 8.2.10 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-modules-local-by-default/4.0.0_postcss@8.2.10: - resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} - engines: {node: ^10 || ^12 || >= 14} + /postcss-normalize-positions/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-0o6/qU5ky74X/eWYj/tv4iiKCm3YqJnrhmVADpIMNXxzFZywsSQxl8F7cKs8jQEtF3VrJBgcDHTexZy1zgDoYg==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.1.0 + postcss: ^8.2.1 dependencies: - icss-utils: 5.1.0_postcss@8.2.10 - postcss: 8.2.10 - postcss-selector-parser: 6.0.4 + postcss: 8.2.14 postcss-value-parser: 4.1.0 dev: true - /postcss-modules-scope/3.0.0_postcss@8.2.10: - resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} - engines: {node: ^10 || ^12 || >= 14} + /postcss-normalize-repeat-style/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-KRT14JbrXKcFMYuc4q7lh8lvv8u22wLyMrq+UpHKLtbx2H/LOjvWXYdoDxmNrrrJzomAWL+ViEXr48/IhSUJnQ==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.1.0 + postcss: ^8.2.1 dependencies: - postcss: 8.2.10 - postcss-selector-parser: 6.0.4 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-modules-values/4.0.0_postcss@8.2.10: - resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} - engines: {node: ^10 || ^12 || >= 14} + /postcss-normalize-string/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-wSO4pf7GNcDZpmelREWYADF1+XZWrAcbFLQCOqoE92ZwYgaP/RLumkUTaamEzdT2YKRZAH8eLLKGWotU/7FNPw==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.1.0 + postcss: ^8.2.1 dependencies: - icss-utils: 5.1.0_postcss@8.2.10 - postcss: 8.2.10 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-modules/4.0.0_postcss@8.2.10: - resolution: {integrity: sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==} + /postcss-normalize-timing-functions/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-TwPaDX+wl9wO3MUm23lzGmOzGCGKnpk+rSDgzB2INpakD5dgWR3L6bJq1P1LQYzBAvz8fRIj2NWdnZdV4EV98Q==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.0.0 + postcss: ^8.2.1 dependencies: - generic-names: 2.0.1 - icss-replace-symbols: 1.1.0 - lodash.camelcase: 4.3.0 - postcss: 8.2.10 - postcss-modules-extract-imports: 3.0.0_postcss@8.2.10 - postcss-modules-local-by-default: 4.0.0_postcss@8.2.10 - postcss-modules-scope: 3.0.0_postcss@8.2.10 - postcss-modules-values: 4.0.0_postcss@8.2.10 - string-hash: 1.1.3 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-nested/5.0.5_postcss@8.2.10: - resolution: {integrity: sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==} - engines: {node: '>=10.0'} + /postcss-normalize-unicode/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-2CpVoz/67rXU5s9tsPZDxG1YGS9OFHwoY9gsLAzrURrCxTAb0H7Vp87/62LvVPgRWTa5ZmvgmqTp2rL8tlm72A==} + engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.1.13 + postcss: ^8.2.1 dependencies: - postcss: 8.2.10 - postcss-selector-parser: 6.0.4 + browserslist: 4.16.6 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-nesting/7.0.1: - resolution: {integrity: sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==} - engines: {node: '>=6.0.0'} + /postcss-normalize-url/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-ICDaGFBqLgA3dlrCIRuhblLl80D13YtgEV9NJPTYJtgR72vu61KgxAHv+z/lKMs1EbwfSQa3ALjOFLSmXiE34A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + is-absolute-url: 3.0.3 + normalize-url: 4.5.0 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-overflow-shorthand/2.0.0: - resolution: {integrity: sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==} - engines: {node: '>=6.0.0'} + /postcss-normalize-whitespace/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-KRnxQvQAVkJfaeXSz7JlnD9nBN9sFZF9lrk9452Q2uRoqrRSkinqifF8Iex7wZGei2DZVG/qpmDFDmRvbNAOGA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-page-break/2.0.0: - resolution: {integrity: sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==} + /postcss-ordered-values/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-dPr+SRObiHueCIc4IUaG0aOGQmYkuNu50wQvdXTGKy+rzi2mjmPsbeDsheLk5WPb9Zyf2tp8E+I+h40cnivm6g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-place/4.0.1: - resolution: {integrity: sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==} - engines: {node: '>=6.0.0'} + /postcss-reduce-initial/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-wR6pXUaFbSMG1oCKx8pKVA+rnSXCHlca5jMrlmkmif+uig0HNUTV9oGN5kjKsM3mATQAldv2PF9Tbl2vqLFjnA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 - postcss-values-parser: 2.0.1 + browserslist: 4.16.6 + caniuse-api: 3.0.0 + postcss: 8.2.14 dev: true - /postcss-preset-env/6.7.0: - resolution: {integrity: sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==} - engines: {node: '>=6.0.0'} - dependencies: - autoprefixer: 9.8.6 - browserslist: 4.16.4 - caniuse-lite: 1.0.30001209 - css-blank-pseudo: 0.1.4 - css-has-pseudo: 0.10.0 - css-prefers-color-scheme: 3.1.1 - cssdb: 4.4.0 - postcss: 7.0.35 - postcss-attribute-case-insensitive: 4.0.2 - postcss-color-functional-notation: 2.0.1 - postcss-color-gray: 5.0.0 - postcss-color-hex-alpha: 5.0.3 - postcss-color-mod-function: 3.0.3 - postcss-color-rebeccapurple: 4.0.1 - postcss-custom-media: 7.0.8 - postcss-custom-properties: 8.0.11 - postcss-custom-selectors: 5.1.2 - postcss-dir-pseudo-class: 5.0.0 - postcss-double-position-gradients: 1.0.0 - postcss-env-function: 2.0.2 - postcss-focus-visible: 4.0.0 - postcss-focus-within: 3.0.0 - postcss-font-variant: 4.0.1 - postcss-gap-properties: 2.0.0 - postcss-image-set-function: 3.0.1 - postcss-initial: 3.0.4 - postcss-lab-function: 2.0.1 - postcss-logical: 3.0.0 - postcss-media-minmax: 4.0.0 - postcss-nesting: 7.0.1 - postcss-overflow-shorthand: 2.0.0 - postcss-page-break: 2.0.0 - postcss-place: 4.0.1 - postcss-pseudo-class-any-link: 6.0.0 - postcss-replace-overflow-wrap: 3.0.0 - postcss-selector-matches: 4.0.0 - postcss-selector-not: 4.0.1 - dev: true - - /postcss-pseudo-class-any-link/6.0.0: - resolution: {integrity: sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==} - engines: {node: '>=6.0.0'} + /postcss-reduce-transforms/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-iHdGODW4YzM3WjVecBhPQt6fpJC4lGQZxJKjkBNHpp2b8dzmvj0ogKThqya+IRodQEFzjfXgYeESkf172FH5Lw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - postcss: 7.0.35 - postcss-selector-parser: 5.0.0 + cssnano-utils: 2.0.0_postcss@8.2.14 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 dev: true - /postcss-replace-overflow-wrap/3.0.0: - resolution: {integrity: sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==} + /postcss-selector-parser/3.1.2: + resolution: {integrity: sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==} + engines: {node: '>=8'} dependencies: - postcss: 7.0.35 + dot-prop: 5.3.0 + indexes-of: 1.0.1 + uniq: 1.0.1 dev: true - /postcss-selector-matches/4.0.0: - resolution: {integrity: sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==} + /postcss-selector-parser/6.0.5: + resolution: {integrity: sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==} + engines: {node: '>=4'} dependencies: - balanced-match: 1.0.2 - postcss: 7.0.35 + cssesc: 3.0.0 + util-deprecate: 1.0.2 dev: true - /postcss-selector-not/4.0.1: - resolution: {integrity: sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==} + /postcss-selector-parser/6.0.6: + resolution: {integrity: sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==} + engines: {node: '>=4'} dependencies: - balanced-match: 1.0.2 - postcss: 7.0.35 + cssesc: 3.0.0 + util-deprecate: 1.0.2 dev: true - /postcss-selector-parser/5.0.0: - resolution: {integrity: sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==} - engines: {node: '>=4'} + /postcss-svgo/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-M3/VS4sFI1Yp9g0bPL+xzzCNz5iLdRUztoFaugMit5a8sMfkVzzhwqbsOlD8IFFymCdJDmXmh31waYHWw1K4BA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - cssesc: 2.0.0 - indexes-of: 1.0.1 - uniq: 1.0.1 + postcss: 8.2.14 + postcss-value-parser: 4.1.0 + svgo: 2.3.0 dev: true - /postcss-selector-parser/6.0.4: - resolution: {integrity: sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==} - engines: {node: '>=4'} + /postcss-unique-selectors/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-o9l4pF8SRn7aCMTmzb/kNv/kjV7wPZpZ8Nlb1Gq8v/Qvw969K1wanz1RVA0ehHzWe9+wHXaC2DvZlak/gdMJ5w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 dependencies: - cssesc: 3.0.0 - indexes-of: 1.0.1 - uniq: 1.0.1 - util-deprecate: 1.0.2 + alphanum-sort: 1.0.2 + postcss: 8.2.14 + postcss-selector-parser: 6.0.5 + uniqs: 2.0.0 dev: true /postcss-value-parser/3.3.1: @@ -4687,15 +2358,6 @@ packages: resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} dev: true - /postcss-values-parser/2.0.1: - resolution: {integrity: sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==} - engines: {node: '>=6.14.4'} - dependencies: - flatten: 1.0.3 - indexes-of: 1.0.1 - uniq: 1.0.1 - dev: true - /postcss/6.0.23: resolution: {integrity: sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==} engines: {node: '>=4.0.0'} @@ -4705,17 +2367,17 @@ packages: supports-color: 5.5.0 dev: true - /postcss/7.0.35: - resolution: {integrity: sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==} - engines: {node: '>=6.0.0'} + /postcss/8.2.13: + resolution: {integrity: sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ==} + engines: {node: ^10 || ^12 || >=14} dependencies: - chalk: 2.4.2 + colorette: 1.2.2 + nanoid: 3.1.22 source-map: 0.6.1 - supports-color: 6.1.0 dev: true - /postcss/8.2.10: - resolution: {integrity: sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==} + /postcss/8.2.14: + resolution: {integrity: sha512-+jD0ZijcvyCqPQo/m/CW0UcARpdFylq04of+Q7RKX6f/Tu+dvpUI/9Sp81+i6/vJThnOBX09Quw0ZLOVwpzX3w==} engines: {node: ^10 || ^12 || >=14} dependencies: colorette: 1.2.2 @@ -4723,33 +2385,32 @@ packages: source-map: 0.6.1 dev: true - /prelude-ls/1.1.2: - resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=} - engines: {node: '>= 0.8.0'} - dev: false + /postcss/8.2.15: + resolution: {integrity: sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + colorette: 1.2.2 + nanoid: 3.1.23 + source-map: 0.6.1 + dev: true /prelude-ls/1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: true - /prepend-http/2.0.0: - resolution: {integrity: sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=} - engines: {node: '>=4'} - dev: true - - /prettier-plugin-svelte/2.2.0_prettier@2.2.1+svelte@3.37.0: + /prettier-plugin-svelte/2.2.0_prettier@2.3.0+svelte@3.38.2: resolution: {integrity: sha512-Xdmqgr71tAuMqqzNCK52/v94g/Yv7V7lz+nmbO9NEA+9ol15VV3uUHOfydMNOo3SWvFaVlBcp947ebEaMWqVfQ==} peerDependencies: prettier: ^1.16.4 || ^2.0.0 svelte: ^3.2.0 dependencies: - prettier: 2.2.1 - svelte: 3.37.0 + prettier: 2.3.0 + svelte: 3.38.2 dev: true - /prettier/2.2.1: - resolution: {integrity: sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==} + /prettier/2.3.0: + resolution: {integrity: sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -4761,52 +2422,23 @@ packages: /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false /progress/2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} dev: true - /prop-types/15.7.2: - resolution: {integrity: sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==} - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - dev: true - - /proxy-addr/2.0.6: - resolution: {integrity: sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.1.2 - ipaddr.js: 1.9.1 - dev: true - optional: true - - /psl/1.8.0: - resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} - dev: false - - /pstree.remy/1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - dev: true - /pump/3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: false /punycode/2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} - - /pupa/2.1.1: - resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} - engines: {node: '>=8'} - dependencies: - escape-goat: 2.1.1 dev: true /purgecss/3.1.3: @@ -4814,112 +2446,20 @@ packages: hasBin: true dependencies: commander: 6.2.1 - glob: 7.1.6 - postcss: 8.2.10 - postcss-selector-parser: 6.0.4 - dev: true - - /qs/6.5.2: - resolution: {integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==} - engines: {node: '>=0.6'} - dev: false - - /qs/6.7.0: - resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==} - engines: {node: '>=0.6'} + glob: 7.1.7 + postcss: 8.2.15 + postcss-selector-parser: 6.0.6 dev: true - optional: true /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - /quick-format-unescaped/4.0.3: - resolution: {integrity: sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==} - dev: false + dev: true /quick-lru/5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} dev: true - /randombytes/2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /range-parser/1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - /raw-body/2.4.0: - resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.0 - http-errors: 1.7.2 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: true - optional: true - - /raw-body/2.4.1: - resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.0 - http-errors: 1.7.3 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: true - optional: true - - /rc/1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.5 - strip-json-comments: 2.0.1 - dev: true - - /react-is/16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true - - /read-cache/1.0.0: - resolution: {integrity: sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=} - dependencies: - pify: 2.3.0 - dev: true - - /read-pkg-up/2.0.0: - resolution: {integrity: sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=} - engines: {node: '>=4'} - dependencies: - find-up: 2.1.0 - read-pkg: 2.0.0 - dev: true - - /read-pkg/2.0.0: - resolution: {integrity: sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=} - engines: {node: '>=4'} - dependencies: - load-json-file: 2.0.0 - normalize-package-data: 2.5.0 - path-type: 2.0.0 - dev: true - - /read-pkg/3.0.0: - resolution: {integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=} - engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: true - /readable-stream/2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} dependencies: @@ -4930,6 +2470,7 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 + dev: false /readable-stream/3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} @@ -4938,128 +2479,47 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - - /readdirp/3.5.0: - resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.2.3 - dev: true - - /rechoir/0.6.2: - resolution: {integrity: sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.20.0 - dev: false - - /reduce-css-calc/2.1.8: - resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} - dependencies: - css-unit-converter: 1.1.2 - postcss-value-parser: 3.3.1 - dev: true - - /regexp-clone/1.0.0: - resolution: {integrity: sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==} dev: false - /regexp.prototype.flags/1.3.1: - resolution: {integrity: sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - dev: true - - /regexpp/3.1.0: - resolution: {integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==} - engines: {node: '>=8'} - dev: true - - /registry-auth-token/4.2.1: - resolution: {integrity: sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==} - engines: {node: '>=6.0.0'} - dependencies: - rc: 1.2.8 - dev: true - - /registry-url/5.1.0: - resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==} - engines: {node: '>=8'} + /readdirp/3.5.0: + resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==} + engines: {node: '>=8.10.0'} dependencies: - rc: 1.2.8 + picomatch: 2.2.3 dev: true - /request-promise-core/1.1.4_request@2.88.2: - resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} - engines: {node: '>=0.10.0'} - peerDependencies: - request: ^2.34 + /rechoir/0.6.2: + resolution: {integrity: sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=} + engines: {node: '>= 0.10'} dependencies: - lodash: 4.17.21 - request: 2.88.2 + resolve: 1.20.0 dev: false - /request-promise-native/1.0.9_request@2.88.2: - resolution: {integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==} - engines: {node: '>=0.12.0'} - deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - peerDependencies: - request: ^2.34 + /reduce-css-calc/2.1.8: + resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} dependencies: - request: 2.88.2 - request-promise-core: 1.1.4_request@2.88.2 - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - dev: false + css-unit-converter: 1.1.2 + postcss-value-parser: 3.3.1 + dev: true - /request/2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - dependencies: - aws-sign2: 0.7.0 - aws4: 1.11.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.30 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.2 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 + /regexp-clone/1.0.0: + resolution: {integrity: sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==} dev: false - /require-directory/2.1.1: - resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} - engines: {node: '>=0.10.0'} + /regexpp/3.1.0: + resolution: {integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==} + engines: {node: '>=8'} dev: true - optional: true /require-from-string/2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - dev: false + dev: true /require-relative/0.8.7: resolution: {integrity: sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=} dev: true - /requires-port/1.0.0: - resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=} - dev: true - /resolve-from/4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -5070,150 +2530,34 @@ packages: engines: {node: '>=8'} dev: true - /resolve-path/1.4.0: - resolution: {integrity: sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=} - engines: {node: '>= 0.8'} - dependencies: - http-errors: 1.6.3 - path-is-absolute: 1.0.1 - dev: true - /resolve/1.20.0: resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} dependencies: - is-core-module: 2.2.0 + is-core-module: 2.4.0 path-parse: 1.0.6 - /responselike/1.0.2: - resolution: {integrity: sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=} - dependencies: - lowercase-keys: 1.0.1 - dev: true - - /restore-cursor/3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.3 - dev: true - - /ret/0.2.2: - resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} - engines: {node: '>=4'} - dev: false - /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - /rfdc/1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: false - - /rimraf/2.6.3: - resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} - hasBin: true - dependencies: - glob: 7.1.6 - dev: true - - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.1.6 - dev: true - - /rollup-plugin-dynamic-import-variables/1.1.0_rollup@2.45.2: - resolution: {integrity: sha512-C1avEmnXC8cC4aAQ5dB63O9oQf7IrhEHc98bQw9Qd6H36FxtZooLCvVfcO4SNYrqaNrzH3ErucQt/zdFSLPHNw==} - dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.45.2 - estree-walker: 2.0.2 - globby: 11.0.3 - magic-string: 0.25.7 - transitivePeerDependencies: - - rollup - dev: true - - /rollup-plugin-hot-nollup/0.1.2: - resolution: {integrity: sha512-QE4/CO7CFWSwZDmp/K+bMEOdP+i9aZiEw2u1sF+BiYE+0VQTu/FfzhJUxI0PDthBjzLZfEW31rwQJhVueuSL8w==} - dependencies: - '@rollup/pluginutils': 3.1.0 - transitivePeerDependencies: - - rollup dev: true - /rollup-plugin-svelte-hot/0.11.2_svelte@3.37.0: - resolution: {integrity: sha512-3cQnFZlrQbknbEwtEwxC2TcT2HO3BYR4/9A/7Dfzm93sQ4lvyAYlCh4JS4FximrR1jWrI/mgaOtUKYDudGIkmg==} - peerDependencies: - rollup: '>=1.19.2' - svelte: '>=3.19.0' - dependencies: - require-relative: 0.8.7 - rollup-plugin-hot-nollup: 0.1.2 - rollup-pluginutils: 2.8.2 - sourcemap-codec: 1.4.8 - svelte: 3.37.0 - svelte-hmr: 0.11.6_svelte@3.37.0 - optionalDependencies: - nollup: 0.16.1 + /rgb-regex/1.0.1: + resolution: {integrity: sha1-wODWiC3w4jviVKR16O3UGRX+rrE=} dev: true - /rollup-plugin-terser/7.0.2_rollup@2.45.2: - resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} - peerDependencies: - rollup: ^2.0.0 - dependencies: - '@babel/code-frame': 7.12.13 - jest-worker: 26.6.2 - rollup: 2.45.2 - serialize-javascript: 4.0.0 - terser: 5.6.1 + /rgba-regex/1.0.0: + resolution: {integrity: sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=} dev: true - /rollup-plugin-visualizer/4.2.2: - resolution: {integrity: sha512-10/TsugsaQL5rdynl0lrklBngTtkRBESZdxUJy+3fN+xKqNdg5cr7JQU1OoPx4p5mhQ+nspa6EvX3qc8SsBvnA==} - engines: {node: '>=10'} + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true - peerDependencies: - rollup: '>=1.20.0' - dependencies: - nanoid: 3.1.22 - open: 7.4.2 - source-map: 0.7.3 - yargs: 16.2.0 - dev: true - optional: true - - /rollup-plugin-vue/6.0.0_@vue+compiler-sfc@3.0.11: - resolution: {integrity: sha512-oVvUd84d5u73M2HYM3XsMDLtZRIA/tw2U0dmHlXU2UWP5JARYHzh/U9vcxaN/x/9MrepY7VH3pHFeOhrWpxs/Q==} - peerDependencies: - '@vue/compiler-sfc': '*' - dependencies: - '@vue/compiler-sfc': 3.0.11_vue@3.0.11 - debug: 4.3.1 - hash-sum: 2.0.0 - rollup-pluginutils: 2.8.2 - transitivePeerDependencies: - - supports-color - dev: true - - /rollup-plugin-web-worker-loader/1.6.1_rollup@2.45.2: - resolution: {integrity: sha512-4QywQSz1NXFHKdyiou16mH3ijpcfLtLGOrAqvAqu1Gx+P8+zj+3gwC2BSL/VW1d+LW4nIHC8F7d7OXhs9UdR2A==} - peerDependencies: - rollup: ^1.9.2 || ^2.0.0 dependencies: - rollup: 2.45.2 + glob: 7.1.7 dev: true - /rollup-pluginutils/2.8.2: - resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} - dependencies: - estree-walker: 0.6.1 - - /rollup/2.45.2: - resolution: {integrity: sha512-kRRU7wXzFHUzBIv0GfoFFIN3m9oteY4uAsKllIpQDId5cfnkWF2J130l+27dzDju0E6MScKiV0ZM5Bw8m4blYQ==} + /rollup/2.46.0: + resolution: {integrity: sha512-qPGoUBNl+Z8uNu0z7pD3WPTABWRbcOwIrO/5ccDJzmrtzn0LVf6Lj91+L5CcWhXl6iWf23FQ6m8Jkl2CmN1O7Q==} engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: @@ -5226,64 +2570,42 @@ packages: queue-microtask: 1.2.3 dev: true + /sade/1.7.4: + resolution: {integrity: sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==} + engines: {node: '>= 6'} + dependencies: + mri: 1.1.6 + dev: true + /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - /safe-regex2/2.0.0: - resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} - dependencies: - ret: 0.2.2 dev: false /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /salteen/1.0.0: + resolution: {integrity: sha512-hApiOPudRSzM5aD1dWIWlXL8dPUja8GloMzHMlmDtNiU5brFNyjvQ+SiLLxHVQNeZ2HgKBnzrRHp+BXQiA5vGg==} + engines: {node: '>=6'} + dev: false /saslprep/1.0.3: resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} engines: {node: '>=6'} dependencies: sparse-bitfield: 3.0.3 - optional: true - - /saxes/5.0.1: - resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} - engines: {node: '>=10'} - dependencies: - xmlchars: 2.2.0 - dev: false - - /secure-json-parse/2.4.0: - resolution: {integrity: sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==} - dev: false - - /selfsigned/1.10.8: - resolution: {integrity: sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==} - dependencies: - node-forge: 0.10.0 - dev: true - - /semver-diff/3.1.1: - resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /semver-store/0.3.0: - resolution: {integrity: sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==} dev: false + optional: true /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true - - /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true + dev: false /semver/7.3.5: resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} @@ -5291,61 +2613,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - - /send/0.17.1: - resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} - engines: {node: '>= 0.8.0'} - dependencies: - debug: 2.6.9 - depd: 1.1.2 - destroy: 1.0.4 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 1.7.3 - mime: 1.6.0 - ms: 2.1.1 - on-finished: 2.3.0 - range-parser: 1.2.1 - statuses: 1.5.0 - - /serialize-javascript/4.0.0: - resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} - dependencies: - randombytes: 2.1.0 - dev: true - - /serve-static/1.14.1: - resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.17.1 - dev: true - optional: true - - /set-cookie-parser/2.4.8: - resolution: {integrity: sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==} - dev: false - - /setprototypeof/1.1.0: - resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} - dev: true - - /setprototypeof/1.1.1: - resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} - - /setprototypeof/1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - /shebang-command/1.2.0: - resolution: {integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 dev: true /shebang-command/2.0.0: @@ -5355,20 +2622,11 @@ packages: shebang-regex: 3.0.0 dev: true - /shebang-regex/1.0.0: - resolution: {integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=} - engines: {node: '>=0.10.0'} - dev: true - /shebang-regex/3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true - /shell-quote/1.7.2: - resolution: {integrity: sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==} - dev: true - /shelljs/0.8.4: resolution: {integrity: sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==} engines: {node: '>=4'} @@ -5379,22 +2637,10 @@ packages: rechoir: 0.6.2 dev: false - /side-channel/1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.1 - object-inspect: 1.9.0 - dev: true - - /sift/7.0.1: - resolution: {integrity: sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==} + /sift/13.5.2: + resolution: {integrity: sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==} dev: false - /signal-exit/3.0.3: - resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} - dev: true - /simple-swizzle/0.2.2: resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=} dependencies: @@ -5406,80 +2652,41 @@ packages: engines: {node: '>=8'} dev: true - /slice-ansi/2.1.0: - resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} - engines: {node: '>=6'} + /slash/4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} dependencies: - ansi-styles: 3.2.1 - astral-regex: 1.0.0 - is-fullwidth-code-point: 2.0.0 + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 dev: true /sliced/1.0.1: resolution: {integrity: sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=} dev: false - /sonic-boom/1.4.1: - resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==} - dependencies: - atomic-sleep: 1.0.0 - flatstr: 1.0.12 - dev: false - - /source-map-support/0.5.19: - resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} - dependencies: - buffer-from: 1.1.1 - source-map: 0.6.1 - dev: true - - /source-map/0.5.7: - resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} - engines: {node: '>=0.10.0'} - dev: true - optional: true - /source-map/0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + dev: true /source-map/0.7.3: resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} engines: {node: '>= 8'} dev: true - /sourcemap-codec/1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - dev: true - /sparse-bitfield/3.0.3: resolution: {integrity: sha1-/0rm5oZWBWuks+eSqzM004JzyhE=} dependencies: memory-pager: 1.5.0 + dev: false optional: true - /spdx-correct/3.1.1: - resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.7 - dev: true - - /spdx-exceptions/2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true - - /spdx-expression-parse/3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.7 - dev: true - - /spdx-license-ids/3.0.7: - resolution: {integrity: sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==} - dev: true - /split-ca/1.0.1: resolution: {integrity: sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY=} dev: false @@ -5504,90 +2711,15 @@ packages: ssh2-streams: 0.4.10 dev: false - /sshpk/1.16.1: - resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.4 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: false - - /standard-engine/14.0.1: - resolution: {integrity: sha512-7FEzDwmHDOGva7r9ifOzD3BGdTbA7ujJ50afLVdW/tK14zQEptJjbFuUfn50irqdHDcTbNh0DTIoMPynMCXb0Q==} - engines: {node: '>=8.10'} - dependencies: - get-stdin: 8.0.0 - minimist: 1.2.5 - pkg-conf: 3.1.0 - xdg-basedir: 4.0.0 - dev: true - - /standard/16.0.3: - resolution: {integrity: sha512-70F7NH0hSkNXosXRltjSv6KpTAOkUkSfyu3ynyM5dtRUiLtR+yX9EGZ7RKwuGUqCJiX/cnkceVM6HTZ4JpaqDg==} - engines: {node: ^10.12.0 || >=12.0.0} - hasBin: true - dependencies: - eslint: 7.13.0 - eslint-config-standard: 16.0.2_1ebed8346196ff7bde7431d183a61a72 - eslint-config-standard-jsx: 10.0.0_d4901a613f352504e6e19464e186980c - eslint-plugin-import: 2.22.1_eslint@7.13.0 - eslint-plugin-node: 11.1.0_eslint@7.13.0 - eslint-plugin-promise: 4.2.1 - eslint-plugin-react: 7.21.5_eslint@7.13.0 - standard-engine: 14.0.1 - transitivePeerDependencies: - - supports-color + /stable/0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} dev: true - /statuses/1.5.0: - resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} - engines: {node: '>= 0.6'} - - /stealthy-require/1.1.1: - resolution: {integrity: sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=} - engines: {node: '>=0.10.0'} - dev: false - - /steed/1.1.3: - resolution: {integrity: sha1-8VJd1a2xLrIb90dJU3Zo1iW5q8U=} - dependencies: - fastfall: 1.5.1 - fastparallel: 2.4.0 - fastq: 1.11.0 - fastseries: 1.7.2 - reusify: 1.0.4 - dev: false - /streamsearch/0.1.2: resolution: {integrity: sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=} engines: {node: '>=0.8.0'} dev: false - /string-hash/1.1.3: - resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=} - dev: true - - /string-similarity/4.0.4: - resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} - dev: false - - /string-width/3.1.0: - resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} - engines: {node: '>=6'} - dependencies: - emoji-regex: 7.0.3 - is-fullwidth-code-point: 2.0.0 - strip-ansi: 5.2.0 - dev: true - /string-width/4.2.2: resolution: {integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==} engines: {node: '>=8'} @@ -5597,73 +2729,23 @@ packages: strip-ansi: 6.0.0 dev: true - /string.prototype.matchall/4.0.4: - resolution: {integrity: sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - has-symbols: 1.0.2 - internal-slot: 1.0.3 - regexp.prototype.flags: 1.3.1 - side-channel: 1.0.4 - dev: true - - /string.prototype.padend/3.1.2: - resolution: {integrity: sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - es-abstract: 1.18.0 - dev: true - - /string.prototype.trimend/1.0.4: - resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - dev: true - - /string.prototype.trimstart/1.0.4: - resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.3 - dev: true - /string_decoder/1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 + dev: false /string_decoder/1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 - - /strip-ansi/5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - dependencies: - ansi-regex: 4.1.0 - dev: true + dev: false /strip-ansi/6.0.0: resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==} engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.0 - dev: true - - /strip-bom/3.0.0: - resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} - engines: {node: '>=4'} - dev: true - - /strip-final-newline/2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + dependencies: + ansi-regex: 5.0.0 dev: true /strip-indent/3.0.0: @@ -5673,27 +2755,27 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments/2.0.1: - resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=} - engines: {node: '>=0.10.0'} - dev: true - /strip-json-comments/3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true + /stylehacks/5.0.0_postcss@8.2.14: + resolution: {integrity: sha512-QOWm6XivDLb+fqffTZP8jrmPmPITVChl2KCY2R05nsCWwLi3VGhCdVc3IVGNwd1zzTt1jPd67zIKjpQfxzQZeA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.1 + dependencies: + browserslist: 4.16.6 + postcss: 8.2.14 + postcss-selector-parser: 6.0.5 + dev: true + /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 - - /supports-color/6.1.0: - resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} - engines: {node: '>=6'} - dependencies: - has-flag: 3.0.0 dev: true /supports-color/7.2.0: @@ -5701,25 +2783,24 @@ packages: engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + dev: true - /svelte-hmr/0.11.6_svelte@3.37.0: - resolution: {integrity: sha512-XUYcp7W26q/fF8tABZfCYGklwL4TDH48gc1KOjuBQNlTiMW63l/+rRqmfVOE/qKG5vns0J2NPo3zFjdahkwoHA==} + /svelte-hmr/0.14.3_svelte@3.38.2: + resolution: {integrity: sha512-N56xX405zLMw2tpGHKRx5h+kmdeZwxI21pvyC6OyBHJDCF6DlwWBm9TifdQmSD4dloWSmpDPzHWYa3CSjfopUg==} peerDependencies: svelte: '>=3.19.0' dependencies: - svelte: 3.37.0 + svelte: 3.38.2 dev: true - /svelte-hmr/0.14.0_svelte@3.37.0: - resolution: {integrity: sha512-Rc4w11U+U30m/cHqOJ/xioFSEAY5fd5muiQC7FL6XJuJAuB2OIJoEZl3KEJR2uO1/f4Bw0PdrugtbxcngSsOtQ==} - peerDependencies: - svelte: '>=3.19.0' + /svelte-kit-cookie-session/0.4.3: + resolution: {integrity: sha512-dffh86haFNNY7+Oqf+hD5fELPva7N7aiAmtkqjWzdoJXgH95Yq3TP3NiLzv9Ep3nZBalYRschh5Hg2L5Jtu2Kg==} dependencies: - svelte: 3.37.0 - dev: true + salteen: 1.0.0 + dev: false - /svelte-preprocess/4.7.0_4a3768216fad352756a1a13607f73a31: - resolution: {integrity: sha512-iNrY4YGqi0LD2e6oT9YbdSzOKntxk8gmzfqso1z/lUJOZh4o6fyIqkirmiZ8/dDJFqtIE1spVgDFWgkfhLEYlw==} + /svelte-preprocess/4.7.3_bc60392b3f6116f56fa9e4496adda117: + resolution: {integrity: sha512-Zx1/xLeGOIBlZMGPRCaXtlMe4ZA0faato5Dc3CosEqwu75MIEPuOstdkH6cy+RYTUYynoxzNaDxkPX4DbrPwRA==} engines: {node: '>= 9.11.2'} requiresBuild: true peerDependencies: @@ -5762,78 +2843,51 @@ packages: '@types/pug': 2.0.4 '@types/sass': 1.16.0 detect-indent: 6.0.0 - postcss: 8.2.10 + postcss: 8.2.14 postcss-load-config: 3.0.1 strip-indent: 3.0.0 - svelte: 3.37.0 + svelte: 3.38.2 + typescript: 4.2.4 dev: true /svelte-select/3.17.0: resolution: {integrity: sha512-ITmX/XUiSdkaILmsTviKRkZPaXckM5/FA7Y8BhiUPoamaZG/ZDyOo6ydjFu9fDVFTbwoAUGUi6HBjs+ZdK2AwA==} dev: false - /svelte/3.37.0: - resolution: {integrity: sha512-TRF30F4W4+d+Jr2KzUUL1j8Mrpns/WM/WacxYlo5MMb2E5Qy2Pk1Guj6GylxsW9OnKQl1tnF8q3hG/hQ3h6VUA==} + /svelte/3.38.2: + resolution: {integrity: sha512-q5Dq0/QHh4BLJyEVWGe7Cej5NWs040LWjMbicBGZ+3qpFWJ1YObRmUDZKbbovddLC9WW7THTj3kYbTOFmU9fbg==} engines: {node: '>= 8'} dev: true - /svite/0.8.1_79b75b88a1dd913f13bddff6afa5f1de: - resolution: {integrity: sha512-DZYF0Icw+omJC8903gfrIWEjfiLyekEDdl08sY+AGrTu0j9k3SHkWkySr+22+GyfRxeY5r/Ag6Ngh6rRULPhGA==} - engines: {node: ^12||^14, npm: ^6.14, pnpm: ^5.5, yarn: ^1.22 || ^2} - deprecated: svite 0.8.x for vite1 is no longer supported. prerelease for vite2 is 0.9.x, check https://github.com/svitejs/svite/blob/main/packages/svite + /svgo/2.3.0: + resolution: {integrity: sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==} + engines: {node: '>=10.13.0'} hasBin: true - peerDependencies: - svelte: ^3.29.7 - svelte-hmr: ^0.11.6 dependencies: - '@rollup/pluginutils': 4.1.0 - chalk: 4.1.0 - commander: 6.2.1 - debug: 4.3.1 - degit: 2.8.4 - execa: 4.1.0 - lru-cache: 6.0.0 - rollup-plugin-svelte-hot: 0.11.2_svelte@3.37.0 - svelte: 3.37.0 - svelte-hmr: 0.14.0_svelte@3.37.0 - vite: 1.0.0-rc.13 - optionalDependencies: - rollup-plugin-visualizer: 4.2.2 - svelte-preprocess: 4.7.0_4a3768216fad352756a1a13607f73a31 - transitivePeerDependencies: - - '@babel/core' - - bufferutil - - coffeescript - - less - - node-sass - - postcss - - postcss-load-config - - pug - - rollup - - sass - - stylus - - sugarss - - supports-color - - typescript - - utf-8-validate + '@trysound/sax': 0.1.1 + chalk: 4.1.1 + commander: 7.2.0 + css-select: 3.1.2 + css-tree: 1.1.3 + csso: 4.2.0 + stable: 0.1.8 dev: true - /symbol-tree/3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: false - - /table/5.4.6: - resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} - engines: {node: '>=6.0.0'} + /table/6.6.0: + resolution: {integrity: sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg==} + engines: {node: '>=10.0.0'} dependencies: - ajv: 6.12.6 - lodash: 4.17.21 - slice-ansi: 2.1.0 - string-width: 3.1.0 + ajv: 8.2.0 + lodash.clonedeep: 4.5.0 + lodash.flatten: 4.4.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.2 + strip-ansi: 6.0.0 dev: true - /tailwindcss/2.1.1_postcss@8.2.10: - resolution: {integrity: sha512-zZ6axGqpSZOCBS7wITm/WNHkBzDt5CIZlDlx0eCVldwTxFPELCVGbgh7Xpb3/kZp3cUxOmK7bZUjqhuMrbN6xQ==} + /tailwindcss/2.2.0-canary.6_b46308bb95614802e1b6d1dce4e25ea6: + resolution: {integrity: sha512-gXpjyw8g4Z565tG6yDyzh2VH3mX0riWXeujg/L6Ph4z/t5ztnqRF2QGXVT5toZYyl7LP02YTrfVqxzDY5vuJDw==} engines: {node: '>=12.13.0'} hasBin: true peerDependencies: @@ -5841,8 +2895,9 @@ packages: postcss: ^8.0.9 dependencies: '@fullhuman/postcss-purgecss': 3.1.3 + autoprefixer: 10.2.5_postcss@8.2.14 bytes: 3.1.0 - chalk: 4.1.0 + chalk: 4.1.1 chokidar: 3.5.1 color: 3.1.3 detective: 5.2.0 @@ -5853,16 +2908,16 @@ packages: html-tags: 3.1.0 lodash: 4.17.21 lodash.topath: 4.5.2 - modern-normalize: 1.0.0 + modern-normalize: 1.1.0 node-emoji: 1.10.0 normalize-path: 3.0.0 object-hash: 2.1.1 parse-glob: 3.0.4 - postcss: 8.2.10 + postcss: 8.2.14 postcss-functions: 3.0.0 postcss-js: 3.0.3 - postcss-nested: 5.0.5_postcss@8.2.10 - postcss-selector-parser: 6.0.4 + postcss-nested: 5.0.5_postcss@8.2.14 + postcss-selector-parser: 6.0.6 postcss-value-parser: 4.1.0 pretty-hrtime: 1.0.3 quick-lru: 5.1.1 @@ -5888,46 +2943,14 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.0 - - /term-size/2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - dev: true - - /terser/5.6.1: - resolution: {integrity: sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - commander: 2.20.3 - source-map: 0.7.3 - source-map-support: 0.5.19 - dev: true + dev: false /text-table/0.2.0: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: true - /tiny-lru/7.0.6: - resolution: {integrity: sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow==} - engines: {node: '>=6'} - dev: false - - /tmp/0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - dependencies: - rimraf: 3.0.2 - dev: true - - /to-fast-properties/2.0.0: - resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} - engines: {node: '>=4'} - dev: true - - /to-readable-stream/1.0.0: - resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} - engines: {node: '>=6'} + /timsort/0.3.0: + resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=} dev: true /to-regex-range/5.0.1: @@ -5937,72 +2960,28 @@ packages: is-number: 7.0.0 dev: true - /toidentifier/1.0.0: - resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} - engines: {node: '>=0.6'} - - /touch/3.1.0: - resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} - hasBin: true - dependencies: - nopt: 1.0.10 - dev: true - - /tough-cookie/2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.8.0 - punycode: 2.1.1 - dev: false - - /tough-cookie/4.0.0: - resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} - engines: {node: '>=6'} - dependencies: - psl: 1.8.0 - punycode: 2.1.1 - universalify: 0.1.2 - dev: false - - /tr46/2.0.2: - resolution: {integrity: sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==} - engines: {node: '>=8'} - dependencies: - punycode: 2.1.1 - dev: false - - /tsconfig-paths/3.9.0: - resolution: {integrity: sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.1 - minimist: 1.2.5 - strip-bom: 3.0.0 + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tsscmp/1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} + /tslib/2.2.0: + resolution: {integrity: sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==} dev: true - /tunnel-agent/0.6.0: - resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=} + /tsutils/3.21.0_typescript@4.2.4: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: - safe-buffer: 5.2.1 - dev: false + tslib: 1.14.1 + typescript: 4.2.4 + dev: true /tweetnacl/0.14.5: resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=} dev: false - /type-check/0.3.2: - resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - dev: false - /type-check/0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -6010,9 +2989,9 @@ packages: prelude-ls: 1.2.1 dev: true - /type-fest/0.3.1: - resolution: {integrity: sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==} - engines: {node: '>=6'} + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} dev: true /type-fest/0.8.1: @@ -6020,285 +2999,77 @@ packages: engines: {node: '>=8'} dev: true - /type-is/1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.30 - dev: true - - /typedarray-to-buffer/3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - dependencies: - is-typedarray: 1.0.0 - dev: true - - /unbox-primitive/1.0.1: - resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==} - dependencies: - function-bind: 1.1.1 - has-bigints: 1.0.1 - has-symbols: 1.0.2 - which-boxed-primitive: 1.0.2 + /typescript/4.2.4: + resolution: {integrity: sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==} + engines: {node: '>=4.2.0'} + hasBin: true dev: true - /undefsafe/2.0.3: - resolution: {integrity: sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==} + /typpy/2.3.11: + resolution: {integrity: sha512-Jh/fykZSaxeKO0ceMAs6agki9T5TNA9kiIR6fzKbvafKpIw8UlNlHhzuqKyi5lfJJ5VojJOx9tooIbyy7vHV/g==} dependencies: - debug: 2.6.9 + function.name: 1.0.13 dev: true /uniq/1.0.1: resolution: {integrity: sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=} dev: true - /unique-names-generator/4.4.0: - resolution: {integrity: sha512-0noP+m59TGwolNqnmXfiqMA5KiTudIk6D0VgzNkk2C1Jv3Lr+sY3T07nEWBg8Uq92/FjGca1klsRR6CXFriqFw==} - engines: {node: '>=6'} - dev: false - - /unique-string/2.0.0: - resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} - engines: {node: '>=8'} - dependencies: - crypto-random-string: 2.0.0 + /uniqs/2.0.0: + resolution: {integrity: sha1-/+3ks2slKQaW5uFl1KWe25mOawI=} dev: true - /universalify/0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} + /unique-names-generator/4.5.0: + resolution: {integrity: sha512-GaiWvo3rKIHi1SyYP8/9cDrPMPSwEiYDUo2p0NQHeCHDXzLn8P6p8bttSS3lX7HHS3Yl5vnw/ulybO4GN85CgQ==} + engines: {node: '>=8'} dev: false /universalify/2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} - - /unpipe/1.0.0: - resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=} - engines: {node: '>= 0.8'} - dev: true - optional: true - - /update-notifier/4.1.3: - resolution: {integrity: sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==} - engines: {node: '>=8'} - dependencies: - boxen: 4.2.0 - chalk: 3.0.0 - configstore: 5.0.1 - has-yarn: 2.1.0 - import-lazy: 2.1.0 - is-ci: 2.0.0 - is-installed-globally: 0.3.2 - is-npm: 4.0.0 - is-yarn-global: 0.3.0 - latest-version: 5.1.0 - pupa: 2.1.1 - semver-diff: 3.1.1 - xdg-basedir: 4.0.0 dev: true /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 - - /url-parse-lax/3.0.0: - resolution: {integrity: sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=} - engines: {node: '>=4'} - dependencies: - prepend-http: 2.0.0 dev: true - /utf-8-validate/5.0.4: - resolution: {integrity: sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==} - requiresBuild: true - dependencies: - node-gyp-build: 4.2.3 - dev: false - /util-deprecate/1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} - /utils-merge/1.0.1: - resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} - engines: {node: '>= 0.4.0'} - dev: true - optional: true - - /uuid/3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - hasBin: true - dev: false - - /uuid/8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: true - /v8-compile-cache/2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true - /validate-npm-package-license/3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - dependencies: - spdx-correct: 3.1.1 - spdx-expression-parse: 3.0.1 - dev: true - - /vary/1.1.2: - resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=} - engines: {node: '>= 0.8'} + /vendors/1.0.4: + resolution: {integrity: sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==} dev: true - /verror/1.10.0: - resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /vite/1.0.0-rc.13: - resolution: {integrity: sha512-hLfTbhNPDhwXMCAWR6s6C79G/O8Is0MbslglgoHSQsRby+KnqHgtHChCVBHFeV2oZBV/3xhHhnfm94BDPFe8Ww==} - engines: {node: '>=10.16.0'} + /vite/2.2.4: + resolution: {integrity: sha512-vnIwSNci+phFMp6krhy+FbYzKL0R67Sdt9mVZ96S27AewrApSJjTqncJcalk8sf60BgcbW4+1C6DFIWkxquO9g==} + engines: {node: '>=12.0.0'} hasBin: true dependencies: - '@babel/parser': 7.13.15 - '@koa/cors': 3.1.0 - '@rollup/plugin-commonjs': 16.0.0_rollup@2.45.2 - '@rollup/plugin-json': 4.1.0_rollup@2.45.2 - '@rollup/plugin-node-resolve': 10.0.0_rollup@2.45.2 - '@rollup/pluginutils': 4.1.0_rollup@2.45.2 - '@types/http-proxy': 1.17.5 - '@types/koa': 2.13.1 - '@types/lru-cache': 5.1.0 - '@vue/compiler-dom': 3.0.11 - '@vue/compiler-sfc': 3.0.11_vue@3.0.11 - brotli-size: 4.0.0 - cac: 6.7.2 - chalk: 4.1.0 - chokidar: 3.5.1 - clean-css: 4.2.3 - debug: 4.3.1 - dotenv: 8.2.0 - dotenv-expand: 5.1.0 - es-module-lexer: 0.3.26 - esbuild: 0.8.57 - etag: 1.8.1 - execa: 4.1.0 - fs-extra: 9.1.0 - hash-sum: 2.0.0 - isbuiltin: 1.0.0 - klona: 2.0.4 - koa: 2.13.1 - koa-conditional-get: 3.0.0 - koa-etag: 4.0.0 - koa-proxies: 0.11.0_debug@4.3.1+koa@2.13.1 - koa-send: 5.0.1 - koa-static: 5.0.0 - lru-cache: 6.0.0 - magic-string: 0.25.7 - merge-source-map: 1.1.0 - mime-types: 2.1.30 - minimist: 1.2.5 - open: 7.4.2 - ora: 5.4.0 - p-map-series: 2.1.0 - postcss-discard-comments: 4.0.2 - postcss-import: 12.0.1 - postcss-load-config: 3.0.1 + esbuild: 0.9.7 + postcss: 8.2.13 resolve: 1.20.0 - rollup: 2.45.2 - rollup-plugin-dynamic-import-variables: 1.1.0_rollup@2.45.2 - rollup-plugin-terser: 7.0.2_rollup@2.45.2 - rollup-plugin-vue: 6.0.0_@vue+compiler-sfc@3.0.11 - rollup-plugin-web-worker-loader: 1.6.1_rollup@2.45.2 - selfsigned: 1.10.8 - slash: 3.0.0 - source-map: 0.7.3 - vue: 3.0.11 - ws: 7.4.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - - /vue/3.0.11: - resolution: {integrity: sha512-3/eUi4InQz8MPzruHYSTQPxtM3LdZ1/S/BvaU021zBnZi0laRUyH6pfuE4wtUeLvI8wmUNwj5wrZFvbHUXL9dw==} - dependencies: - '@vue/compiler-dom': 3.0.11 - '@vue/runtime-dom': 3.0.11 - '@vue/shared': 3.0.11 - dev: true - - /w3c-hr-time/1.0.2: - resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} - dependencies: - browser-process-hrtime: 1.0.0 - dev: false - - /w3c-xmlserializer/2.0.0: - resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} - engines: {node: '>=10'} - dependencies: - xml-name-validator: 3.0.0 - dev: false - - /wcwidth/1.0.1: - resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=} - dependencies: - defaults: 1.0.3 - dev: true - - /webidl-conversions/5.0.0: - resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} - engines: {node: '>=8'} - dev: false - - /webidl-conversions/6.1.0: - resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} - engines: {node: '>=10.4'} - dev: false - - /whatwg-encoding/1.0.5: - resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} - dependencies: - iconv-lite: 0.4.24 - dev: false - - /whatwg-mimetype/2.3.0: - resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} - dev: false - - /whatwg-url/8.5.0: - resolution: {integrity: sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==} - engines: {node: '>=10'} - dependencies: - lodash: 4.17.21 - tr46: 2.0.2 - webidl-conversions: 6.1.0 - dev: false - - /which-boxed-primitive/1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.1 - is-boolean-object: 1.1.0 - is-number-object: 1.0.4 - is-string: 1.0.5 - is-symbol: 1.0.3 + rollup: 2.46.0 + optionalDependencies: + fsevents: 2.3.2 dev: true - /which/1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + /vite/2.3.2: + resolution: {integrity: sha512-QhLdOompDrfkyryCNTts9HE+eJhvhN9ibKNJ5Q8DpQai+6nOsuIlaveZNg67e1O/2QaWqXeBo82eHnAs1De2bQ==} + engines: {node: '>=12.0.0'} hasBin: true dependencies: - isexe: 2.0.0 + esbuild: 0.11.20 + postcss: 8.2.15 + resolve: 1.20.0 + rollup: 2.46.0 + optionalDependencies: + fsevents: 2.3.2 dev: true /which/2.0.2: @@ -6309,145 +3080,24 @@ packages: isexe: 2.0.0 dev: true - /widest-line/3.1.0: - resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} - engines: {node: '>=8'} - dependencies: - string-width: 4.2.2 - dev: true - /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} - - /wrap-ansi/7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.2 - strip-ansi: 6.0.0 dev: true - optional: true /wrappy/1.0.2: resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} - /write-file-atomic/3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - dependencies: - imurmurhash: 0.1.4 - is-typedarray: 1.0.0 - signal-exit: 3.0.3 - typedarray-to-buffer: 3.1.5 - dev: true - - /write/1.0.3: - resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==} - engines: {node: '>=4'} - dependencies: - mkdirp: 0.5.5 - dev: true - - /ws/5.2.2: - resolution: {integrity: sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==} - dependencies: - async-limiter: 1.0.1 - dev: true - optional: true - - /ws/7.4.4: - resolution: {integrity: sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - - /ws/7.4.4_c70f8fc5586dd378b8c866035dbe710b: - resolution: {integrity: sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==} - engines: {node: '>=8.3.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dependencies: - bufferutil: 4.0.3 - utf-8-validate: 5.0.4 - dev: false - - /xdg-basedir/4.0.0: - resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} - engines: {node: '>=8'} - dev: true - - /xml-name-validator/3.0.0: - resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} - dev: false - - /xmlchars/2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: false - /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - - /y18n/5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - optional: true - - /yallist/3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} dev: true - - /yargs-parser/20.2.7: - resolution: {integrity: sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==} - engines: {node: '>=10'} - dev: true - optional: true - - /yargs/16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.2 - y18n: 5.0.8 - yargs-parser: 20.2.7 - dev: true - optional: true - - /yauzl/2.10.0: - resolution: {integrity: sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=} - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - dev: true - - /ylru/1.2.1: - resolution: {integrity: sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==} - engines: {node: '>= 4.0.0'} - dev: true diff --git a/postcss.config.cjs b/postcss.config.cjs new file mode 100644 index 0000000000..fba8830b23 --- /dev/null +++ b/postcss.config.cjs @@ -0,0 +1,18 @@ +const tailwindcss = require('tailwindcss'); +const autoprefixer = require('autoprefixer'); +const cssnano = require('cssnano'); + +const mode = process.env.NODE_ENV; +const dev = mode === 'development'; + +module.exports = { + plugins: [ + tailwindcss, + autoprefixer, + + !dev && + cssnano({ + preset: 'default' + }) + ] +}; diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 996b135cf6..0000000000 --- a/postcss.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - plugins: [ - require('postcss-import'), - require('tailwindcss'), - require('postcss-preset-env')({ stage: 1 }) - ] -} diff --git a/public/bye.html b/public/bye.html deleted file mode 100644 index 6b279a3773..0000000000 --- a/public/bye.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/routify.config.js b/routify.config.js deleted file mode 100644 index 7c4e2434de..0000000000 --- a/routify.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - routifyDir: '.routify', - dynamicImports: true, - extensions: ['svelte'] -} diff --git a/src/App.svelte b/src/App.svelte deleted file mode 100644 index 77a76d6b3b..0000000000 --- a/src/App.svelte +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000000..cf2632777d --- /dev/null +++ b/src/app.html @@ -0,0 +1,17 @@ + + + + + + + Coolify + + + + + %svelte.head% + + +
%svelte.body%
+ + diff --git a/src/app.postcss b/src/app.postcss new file mode 100644 index 0000000000..a23ba9216f --- /dev/null +++ b/src/app.postcss @@ -0,0 +1,141 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html { + height: 100%; +} +body { + background-color: rgb(22, 22, 22); + min-height: 100vh; + overflow-x: hidden; + @apply text-white; +} + +:root { + --toastBackground: rgba(41, 37, 36, 0.8); + --toastProgressBackground: transparent; + --toastFont: 'Inter'; +} + +.border-gradient { + border-bottom: 2px solid transparent; + border-image: linear-gradient( + 0.25turn, + rgba(255, 249, 34), + rgba(255, 0, 128), + rgba(56, 2, 155, 0) + ); + border-image-slice: 1; +} +.border-gradient-full { + border: 4px solid transparent; + border-image: linear-gradient( + 0.25turn, + rgba(255, 249, 34), + rgba(255, 0, 128), + rgba(56, 2, 155, 0) + ); + border-image-slice: 1; +} + +[aria-label][role~='tooltip']::after { + background: rgba(41, 37, 36, 0.9); + color: white; + font-family: 'Inter'; + font-size: 16px; + font-weight: 600; + white-space: normal; +} + +[role~='tooltip'][data-microtip-position|='bottom']::before { + background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') + no-repeat; +} + +[role~='tooltip'][data-microtip-position|='top']::before { + background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') + no-repeat; +} +[role~='tooltip'][data-microtip-position='right']::before { + background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') + no-repeat; +} + +[role~='tooltip'][data-microtip-position='left']::before { + background: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E') + no-repeat; +} + +.main { + width: calc(100% - 4rem); + margin-left: 4rem; +} +._toastMsg { + @apply text-sm font-bold !important; +} +._toastItem { + @apply w-full border-l-2 border-green-600 !important; +} +._toastBtn { + @apply text-xs !important; +} +._toastBtn:hover { + @apply bg-gray-500 !important; +} +.icon { + @apply text-white rounded p-2 transition duration-100; +} +.icon:hover { + @apply bg-warmGray-700; +} +input { + @apply text-sm rounded py-2 px-6 font-bold bg-warmGray-800 text-white transition duration-150 outline-none border border-transparent !important; +} +input:hover { + @apply bg-warmGray-700 !important; +} +textarea { + @apply text-sm rounded py-2 px-6 font-bold bg-warmGray-800 text-white transition duration-150 outline-none resize-none !important; +} +textarea:hover { + @apply bg-warmGray-700 !important; +} +select { + @apply text-sm rounded py-2 px-6 font-bold bg-warmGray-800 text-white transition duration-150 outline-none !important; +} +select:hover { + @apply bg-warmGray-700 !important; +} +label { + @apply text-left text-base font-bold text-warmGray-400 !important; +} +button { + @apply outline-none !important; +} +.button { + @apply rounded text-sm font-bold transition-all duration-100 !important; +} +.h-271 { + min-height: 271px !important; +} +.repository-select-search .listItem .item, +.repository-select-search .empty { + @apply text-sm py-3 font-bold bg-warmGray-800 text-white cursor-pointer border-none hover:bg-warmGray-700 !important; +} + +.repository-select-search .listContainer { + @apply bg-transparent !important; +} + +.repository-select-search .clearSelect { + @apply text-white cursor-pointer !important; +} + +.repository-select-search .selectedItem { + @apply text-white relative cursor-pointer font-bold text-sm flex items-center !important; +} +.selectContainer { + background: transparent !important; + @apply border-0 !important; +} diff --git a/src/components/Application/ActiveTab/General.svelte b/src/components/Application/ActiveTab/General.svelte new file mode 100644 index 0000000000..83d3d01411 --- /dev/null +++ b/src/components/Application/ActiveTab/General.svelte @@ -0,0 +1,312 @@ + + +
+
+
Build Packs
+
+
+ Static +
+
+ NodeJS +
+
+ VueJS +
+
+ NuxtJS +
+
+ React/Preact +
+
+ NextJS +
+
+ Gatsby +
+
+ Svelte +
+
+ PHP +
+
+ Rust +
+
+ Docker +
+
+
+
General settings
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ Commands +
+
+
+
+ + + + + +
+
+
+
+ + diff --git a/src/components/Application/Configuration/ActiveTab/Secrets.svelte b/src/components/Application/ActiveTab/Secrets.svelte similarity index 98% rename from src/components/Application/Configuration/ActiveTab/Secrets.svelte rename to src/components/Application/ActiveTab/Secrets.svelte index 5e267f8f32..27ff83d06e 100644 --- a/src/components/Application/Configuration/ActiveTab/Secrets.svelte +++ b/src/components/Application/ActiveTab/Secrets.svelte @@ -1,5 +1,5 @@ + +{#if loading} +
+ + +
+{/if} diff --git a/src/components/Application/Configuration.svelte b/src/components/Application/Configuration.svelte new file mode 100644 index 0000000000..91f2d181cc --- /dev/null +++ b/src/components/Application/Configuration.svelte @@ -0,0 +1,186 @@ + + +
+ {#if relogin} + + {:else} + {#await loadGithubRepositories(false)} + + {:then} + {#if loading.github} + + {:else} +
+ + {#if $application.repository.organization} + + {/if} + + {#if $application.repository.branch} + + {/if} +
+ {/if} + {/await} + {/if} +
diff --git a/src/components/Application/Configuration/ActiveTab/General.svelte b/src/components/Application/Configuration/ActiveTab/General.svelte deleted file mode 100644 index fa2d894e87..0000000000 --- a/src/components/Application/Configuration/ActiveTab/General.svelte +++ /dev/null @@ -1,340 +0,0 @@ - - - - -
-
-
Build Packs
-
-
- Static -
-
- NodeJS -
-
- VueJS -
-
- NuxtJS -
-
- React/Preact -
-
- NextJS -
-
- Gatsby -
-
- Svelte -
-
- PHP -
-
- Rust -
-
- Docker -
-
-
-
General settings
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- Commands -
-
-
-
- - - - - -
-
-
-
diff --git a/src/components/Application/Configuration/Branches.svelte b/src/components/Application/Configuration/Branches.svelte deleted file mode 100644 index 3843d68a59..0000000000 --- a/src/components/Application/Configuration/Branches.svelte +++ /dev/null @@ -1,45 +0,0 @@ - - -{#if loading} -
- - -
-{/if} diff --git a/src/components/Application/Configuration/Configuration.svelte b/src/components/Application/Configuration/Configuration.svelte deleted file mode 100644 index 64068bfb1e..0000000000 --- a/src/components/Application/Configuration/Configuration.svelte +++ /dev/null @@ -1,263 +0,0 @@ - - -{#if !$activePage.new} -
-
- {$application.publish.domain - ? `${$application.publish.domain}${ - $application.publish.path !== "/" ? $application.publish.path : "" - }` - : "example.com"} - - - - - - - -
-
-{:else if $activePage.new} -
-
- New Application -
-
-{/if} - -
- {#if !$session.githubAppToken} - - {:else} - {#await loadGithub()} - - {:then} - {#if loading.github} - - {:else} -
- - {#if $application.repository.organization} - - {/if} - - {#if $application.repository.branch} - - {/if} -
- {/if} - {/await} - {/if} -
diff --git a/src/components/Application/Configuration/Login.svelte b/src/components/Application/Configuration/Login.svelte deleted file mode 100644 index cb16981eac..0000000000 --- a/src/components/Application/Configuration/Login.svelte +++ /dev/null @@ -1,50 +0,0 @@ - - -
-
- Choose your Git provider -
- -
diff --git a/src/components/Application/Configuration/Repositories.svelte b/src/components/Application/Configuration/Repositories.svelte deleted file mode 100644 index 9f9c73db2e..0000000000 --- a/src/components/Application/Configuration/Repositories.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - -
- {#if $githubRepositories.length !== 0} - -
- + +
+ {:else} + + {/if} +
diff --git a/src/components/Application/Tabs.svelte b/src/components/Application/Tabs.svelte new file mode 100644 index 0000000000..80b94e7f76 --- /dev/null +++ b/src/components/Application/Tabs.svelte @@ -0,0 +1,138 @@ + + +{#await load()} + +{:then} +
+ +
+
+
+ {#if activeTab.general} + + {:else if activeTab.secrets} + + {/if} +
+
+{/await} diff --git a/src/components/Database/Configuration.svelte b/src/components/Database/Configuration.svelte new file mode 100644 index 0000000000..44ea021d4c --- /dev/null +++ b/src/components/Database/Configuration.svelte @@ -0,0 +1,109 @@ + + +
+ {#if $page.path === '/database/new'} +
+
(type = 'mongodb')} + > +
+ +
+
MongoDB
+
+
(type = 'couchdb')} + > +
+ +
+
Couchdb
+
+
(type = 'postgresql')} + > +
+ +
+
PostgreSQL
+
+
(type = 'mysql')} + > +
+ +
+
MySQL
+
+ + +
+ {#if type} +
+ + + + +
+ {/if} + {/if} +
diff --git a/src/components/Databases/SVGs/Clickhouse.svelte b/src/components/Database/SVGs/Clickhouse.svelte similarity index 100% rename from src/components/Databases/SVGs/Clickhouse.svelte rename to src/components/Database/SVGs/Clickhouse.svelte diff --git a/src/components/Databases/SVGs/CouchDb.svelte b/src/components/Database/SVGs/CouchDb.svelte similarity index 100% rename from src/components/Databases/SVGs/CouchDb.svelte rename to src/components/Database/SVGs/CouchDb.svelte diff --git a/src/components/Databases/SVGs/MongoDb.svelte b/src/components/Database/SVGs/MongoDb.svelte similarity index 100% rename from src/components/Databases/SVGs/MongoDb.svelte rename to src/components/Database/SVGs/MongoDb.svelte diff --git a/src/components/Databases/SVGs/Mysql.svelte b/src/components/Database/SVGs/Mysql.svelte similarity index 100% rename from src/components/Databases/SVGs/Mysql.svelte rename to src/components/Database/SVGs/Mysql.svelte diff --git a/src/components/Databases/SVGs/Postgresql.svelte b/src/components/Database/SVGs/Postgresql.svelte similarity index 100% rename from src/components/Databases/SVGs/Postgresql.svelte rename to src/components/Database/SVGs/Postgresql.svelte diff --git a/src/components/Databases/Configuration/Configuration.svelte b/src/components/Databases/Configuration/Configuration.svelte deleted file mode 100644 index a4c0e7f872..0000000000 --- a/src/components/Databases/Configuration/Configuration.svelte +++ /dev/null @@ -1,113 +0,0 @@ - - -
- {#if $isActive("/database/new")} -
-
-
- -
-
MongoDB
-
-
-
- -
-
Couchdb
-
-
-
- -
-
PostgreSQL
-
-
-
- -
-
MySQL
-
- - -
- {#if type} -
- - - - -
- {/if} - {/if} -
diff --git a/src/components/Loading.svelte b/src/components/Loading.svelte index 4e1e909ec3..dac63811fc 100644 --- a/src/components/Loading.svelte +++ b/src/components/Loading.svelte @@ -1,79 +1,80 @@ - - - -{#if fullscreen} - {#if github} -
-
-
- -
- {githubLoadingText} + .loader::before { + left: -20px; + animation-delay: 0s; + } + + @keyframes animloader { + 0% { + height: 48px; + } + 100% { + height: 4px; + } + } + + + + + {#if fullscreen} + {#if github} +
+
+
+ +
+ {githubLoadingText} +
-
- {:else} -
- -
+ {:else} +
+ +
+ {/if} {/if} -{/if} + \ No newline at end of file diff --git a/src/components/Service/Plausible.svelte b/src/components/Service/Plausible.svelte new file mode 100644 index 0000000000..97e40bad46 --- /dev/null +++ b/src/components/Service/Plausible.svelte @@ -0,0 +1,87 @@ + + +{#if loading} + +{:else} +
+
+
+
General
+
+ + + +
+ +
+
Domain
+ +
+
+
Email address
+ +
+
+
Username
+ +
+
+
Password
+ +
+
PostgreSQL
+
+
Username
+ +
+
+
Password
+ +
+
+
Database
+ +
+
+
+{/if} diff --git a/src/components/Services/Plausible.svelte b/src/components/Services/Plausible.svelte deleted file mode 100644 index f1189a6b33..0000000000 --- a/src/components/Services/Plausible.svelte +++ /dev/null @@ -1,82 +0,0 @@ - - -{#if loading} - -{:else} -
-
-
-
General
-
- - - -
- -
-
Domain
- -
-
-
Email address
- -
-
-
Username
- -
-
-
Password
- -
-
PostgreSQL
-
-
Username
- -
-
-
Password
- -
-
-
Database
- -
-
-
-{/if} diff --git a/src/components/Tooltip.svelte b/src/components/Tooltip.svelte new file mode 100644 index 0000000000..f4942709d1 --- /dev/null +++ b/src/components/Tooltip.svelte @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/src/components/Tooltip/Tooltip.svelte b/src/components/Tooltip/Tooltip.svelte deleted file mode 100644 index 006b75dffc..0000000000 --- a/src/components/Tooltip/Tooltip.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/src/components/Tooltip/TooltipInfo.svelte b/src/components/TooltipInfo.svelte similarity index 100% rename from src/components/Tooltip/TooltipInfo.svelte rename to src/components/TooltipInfo.svelte diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000000..39ed4217f2 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,115 @@ +/// +/// +/// + +export type DateTimeFormatOptions = { + localeMatcher?: 'lookup' | 'best fit'; + weekday?: 'long' | 'short' | 'narrow'; + era?: 'long' | 'short' | 'narrow'; + year?: 'numeric' | '2-digit'; + month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow'; + day?: 'numeric' | '2-digit'; + hour?: 'numeric' | '2-digit'; + minute?: 'numeric' | '2-digit'; + second?: 'numeric' | '2-digit'; + timeZoneName?: 'long' | 'short'; + formatMatcher?: 'basic' | 'best fit'; + hour12?: boolean; + timeZone?: string; +}; +export type Application = { + github: { + installation: { + id: number; + }; + app: { + id: number; + }; + }; + repository: { + id: number; + organization: string; + name: string; + branch: string; + }; + general: { + deployId: string; + nickname: string; + workdir: string; + }; + build: { + pack: string; + directory: string; + command: { + build: string | null; + installation: string; + }; + container: { + name: string; + tag: string; + baseSHA: string; + }; + }; + publish: { + directory: string; + domain: string; + path: string; + port: number; + secrets: Array>; + }; +}; +export type Database = { + config: + | { + general: { + deployId: string; + nickname: string; + workdir: string; + type: string; + }; + database: { + usernames: Array; + passwords: Array; + defaultDatabaseName: string; + }; + deploy: { + name: string; + }; + } + | Record; + envs: Array; +}; +export type Dashboard = { + databases: { + deployed: + | [ + { + configuration: Database; + } + ] + | []; + }; + services: { + deployed: + | [ + { + configuration: any; + } + ] + | []; + }; + applications: { + deployed: + | [ + { + configuration: Application; + UpdatedAt: any; + } + ] + | []; + }; +}; +export type GithubInstallations = { + id: number; + app_id: number; +}; diff --git a/src/hooks/index.ts b/src/hooks/index.ts new file mode 100644 index 0000000000..5e2077680e --- /dev/null +++ b/src/hooks/index.ts @@ -0,0 +1,80 @@ +import dotEnvExtended from 'dotenv-extended'; +dotEnvExtended.load(); +import { publicPages } from '$lib/consts'; +import mongoose from 'mongoose'; +import { verifyUserId } from '$lib/api/common'; +import { initializeSession } from 'svelte-kit-cookie-session'; + +process.on('SIGINT', function () { + mongoose.connection.close(function () { + console.log('Mongoose default connection disconnected through app termination'); + process.exit(0); + }); +}); + +async function connectMongoDB() { + const { MONGODB_USER, MONGODB_PASSWORD, MONGODB_HOST, MONGODB_PORT, MONGODB_DB } = process.env; + try { + if (process.env.NODE_ENV === 'production') { + await mongoose.connect( + `mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@${MONGODB_HOST}:${MONGODB_PORT}/${MONGODB_DB}?authSource=${MONGODB_DB}&readPreference=primary&ssl=false`, + { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false } + ); + } else { + await mongoose.connect( + 'mongodb://supercooldbuser:developmentPassword4db@localhost:27017/coolify?&readPreference=primary&ssl=false', + { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false } + ); + } + console.log('Connected to mongodb.'); + } catch (error) { + console.log(error); + } +} + +if (mongoose.connection.readyState !== 1) connectMongoDB(); + +export async function handle({ request, render }) { + const { SECRETS_ENCRYPTION_KEY } = process.env; + const session = initializeSession(request.headers, { + secret: SECRETS_ENCRYPTION_KEY, + cookie: { path: '/' } + }); + request.locals.session = session; + if (session?.data?.coolToken) { + try { + await verifyUserId(session.data.coolToken); + request.locals.session = session; + } catch (error) { + request.locals.session.destroy = true; + } + } + const response = await render(request); + if (!session['set-cookie']) { + if (!session?.data?.coolToken && !publicPages.includes(request.path)) { + return { + status: 301, + headers: { + location: '/' + } + }; + } + return response; + } + return { + ...response, + headers: { + ...response.headers, + ...session + } + }; +} +export function getSession(request) { + const { data } = request.locals.session; + return { + isLoggedIn: data && Object.keys(data).length !== 0 ? true : false, + expires: data.expires, + coolToken: data.coolToken, + ghToken: data.ghToken + }; +} diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 68f14a23a9..0000000000 --- a/src/index.css +++ /dev/null @@ -1,53 +0,0 @@ -@import "tailwindcss/base.css"; -@import "tailwindcss/components.css"; -@import "tailwindcss/utilities.css"; - -html { - height: 100%; -} -body { - background-color: rgb(22, 22, 22); - min-height: 100vh; - overflow-x: hidden; -} - -:root { - --toastBackground: rgba(41, 37, 36, 0.8); - --toastProgressBackground: transparent; - --toastFont: 'Inter'; -} - -.border-gradient { - border-bottom: 2px solid transparent; - border-image: linear-gradient(0.25turn, rgba(255, 249, 34), rgba(255, 0, 128), rgba(56, 2, 155, 0)); - border-image-slice: 1; -} -.border-gradient-full { - border: 4px solid transparent; - border-image: linear-gradient(0.25turn, rgba(255, 249, 34), rgba(255, 0, 128), rgba(56, 2, 155, 0)); - border-image-slice: 1; -} - -[aria-label][role~="tooltip"]::after { - background: rgba(41, 37, 36, 0.9); - color: white; - font-family: 'Inter'; - font-size: 16px; - font-weight: 600; - white-space: normal; -} - -[role~="tooltip"][data-microtip-position|="bottom"]::before { - background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat; -} - -[role~="tooltip"][data-microtip-position|="top"]::before { - background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat; -} -[role~="tooltip"][data-microtip-position="right"]::before { - background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat; -} - -[role~="tooltip"][data-microtip-position="left"]::before { - background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2841,%2037,%2036,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat; -} \ No newline at end of file diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 3dce485c3b..0000000000 --- a/src/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import App from './App.svelte' -import './index.css' - -const app = new App({ - target: document.body -}) - -export default app diff --git a/src/lib/api/applications/buildContainer.ts b/src/lib/api/applications/buildContainer.ts new file mode 100644 index 0000000000..aad916aec5 --- /dev/null +++ b/src/lib/api/applications/buildContainer.ts @@ -0,0 +1,29 @@ +import Deployment from '$models/Logs/Deployment'; +import { saveAppLog } from './logging'; +import * as packs from './packs'; + +export default async function (configuration) { + const { id, organization, name, branch } = configuration.repository; + const { domain } = configuration.publish; + const deployId = configuration.general.deployId; + const execute = packs[configuration.build.pack]; + if (execute) { + await Deployment.findOneAndUpdate( + { repoId: id, branch, deployId, organization, name, domain }, + { repoId: id, branch, deployId, organization, name, domain, progress: 'inprogress' } + ); + await saveAppLog('### Building application.', configuration); + await execute(configuration); + await saveAppLog('### Building done.', configuration); + } else { + try { + await Deployment.findOneAndUpdate( + { repoId: id, branch, deployId, organization, name, domain }, + { repoId: id, branch, deployId, organization, name, domain, progress: 'failed' } + ); + } catch (error) { + // Hmm. + } + throw new Error('No buildpack found.'); + } +} diff --git a/src/lib/api/applications/cleanup.ts b/src/lib/api/applications/cleanup.ts new file mode 100644 index 0000000000..28a3fd6be3 --- /dev/null +++ b/src/lib/api/applications/cleanup.ts @@ -0,0 +1,45 @@ +import { docker } from '$lib/api/docker'; +import { execShellAsync } from '../common'; + +export async function deleteSameDeployments(configuration) { + await ( + await docker.engine.listServices() + ) + .filter((r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') + .map(async (s) => { + const running = JSON.parse(s.Spec.Labels.configuration); + if ( + running.repository.id === configuration.repository.id && + running.repository.branch === configuration.repository.branch + ) { + await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`); + } + }); +} + +export async function purgeImagesContainers(configuration, deleteAll = false) { + const { name, tag } = configuration.build.container; + await execShellAsync('docker container prune -f'); + if (deleteAll) { + const IDsToDelete = ( + await execShellAsync(`docker images ls --filter=reference='${name}' --format '{{json .ID }}'`) + ) + .trim() + .replace(/"/g, '') + .split('\n'); + if (IDsToDelete.length > 0) + await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`); + } else { + const IDsToDelete = ( + await execShellAsync( + `docker images ls --filter=reference='${name}' --filter=before='${name}:${tag}' --format '{{json .ID }}'` + ) + ) + .trim() + .replace(/"/g, '') + .split('\n'); + if (IDsToDelete.length > 1) + await execShellAsync(`docker rmi -f ${IDsToDelete.toString().replace(',', ' ')}`); + } + await execShellAsync('docker image prune -f'); +} diff --git a/src/lib/api/applications/cloneRepository.ts b/src/lib/api/applications/cloneRepository.ts new file mode 100644 index 0000000000..5c9b6bda72 --- /dev/null +++ b/src/lib/api/applications/cloneRepository.ts @@ -0,0 +1,48 @@ +import jsonwebtoken from 'jsonwebtoken'; +import { execShellAsync } from '../common'; + +export default async function (configuration) { + try { + const { GITHUB_APP_PRIVATE_KEY } = process.env; + const { workdir } = configuration.general; + const { organization, name, branch } = configuration.repository; + const github = configuration.github; + if (!github.installation.id || !github.app.id) { + throw new Error('Github installation ID is invalid.'); + } + const githubPrivateKey = GITHUB_APP_PRIVATE_KEY.replace(/\\n/g, '\n').replace(/"/g, ''); + + const payload = { + iat: Math.round(new Date().getTime() / 1000), + exp: Math.round(new Date().getTime() / 1000 + 60), + iss: parseInt(github.app.id) + }; + + const jwtToken = jsonwebtoken.sign(payload, githubPrivateKey, { + algorithm: 'RS256' + }); + + const { token } = await ( + await fetch( + `https://api.github.com/app/installations/${github.installation.id}/access_tokens`, + { + method: 'POST', + headers: { + Authorization: 'Bearer ' + jwtToken, + Accept: 'application/vnd.github.machine-man-preview+json' + } + } + ) + ).json(); + await execShellAsync( + `mkdir -p ${workdir} && git clone -q -b ${branch} https://x-access-token:${token}@github.com/${organization}/${name}.git ${workdir}/` + ); + configuration.build.container.tag = ( + await execShellAsync(`cd ${configuration.general.workdir}/ && git rev-parse HEAD`) + ) + .replace('\n', '') + .slice(0, 7); + } catch (error) { + console.log(error); + } +} diff --git a/src/lib/api/applications/common.ts b/src/lib/api/applications/common.ts new file mode 100644 index 0000000000..543e6c3a53 --- /dev/null +++ b/src/lib/api/applications/common.ts @@ -0,0 +1,18 @@ +export const baseServiceConfiguration = { + replicas: 1, + restart_policy: { + condition: 'any', + max_attempts: 6 + }, + update_config: { + parallelism: 1, + delay: '10s', + order: 'start-first' + }, + rollback_config: { + parallelism: 1, + delay: '10s', + order: 'start-first', + failure_action: 'rollback' + } +}; diff --git a/src/lib/api/applications/configuration.ts b/src/lib/api/applications/configuration.ts new file mode 100644 index 0000000000..0d70619449 --- /dev/null +++ b/src/lib/api/applications/configuration.ts @@ -0,0 +1,156 @@ +import cuid from 'cuid'; +import crypto from 'crypto'; +import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator'; +import { docker } from '$lib/api/docker'; +import { baseServiceConfiguration } from './common'; +import { execShellAsync } from '../common'; + +function getUniq() { + return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 }); +} + +export function setDefaultConfiguration(configuration) { + const nickname = getUniq(); + const deployId = cuid(); + + const shaBase = JSON.stringify({ repository: configuration.repository }); + const sha256 = crypto.createHash('sha256').update(shaBase).digest('hex'); + + configuration.build.container.name = sha256.slice(0, 15); + + configuration.general.nickname = nickname; + configuration.general.deployId = deployId; + configuration.general.workdir = `/tmp/${deployId}`; + + if (!configuration.publish.path) configuration.publish.path = '/'; + if (!configuration.publish.port) { + if ( + configuration.build.pack === 'nodejs' || + configuration.build.pack === 'vuejs' || + configuration.build.pack === 'nuxtjs' || + configuration.build.pack === 'rust' || + configuration.build.pack === 'nextjs' + ) { + configuration.publish.port = 3000; + } else { + configuration.publish.port = 80; + } + } + if (!configuration.build.directory) configuration.build.directory = ''; + if (configuration.build.directory.startsWith('/')) + configuration.build.directory = configuration.build.directory.replace('/', ''); + + if (!configuration.publish.directory) configuration.publish.directory = ''; + if (configuration.publish.directory.startsWith('/')) + configuration.publish.directory = configuration.publish.directory.replace('/', ''); + + if (configuration.build.pack === 'static' || configuration.build.pack === 'nodejs') { + if (!configuration.build.command.installation) + configuration.build.command.installation = 'yarn install'; + } + + configuration.build.container.baseSHA = crypto + .createHash('sha256') + .update(JSON.stringify(baseServiceConfiguration)) + .digest('hex'); + configuration.baseServiceConfiguration = baseServiceConfiguration; + + return configuration; +} + +export async function precheckDeployment({ services, configuration }) { + let foundService = false; + let configChanged = false; + let imageChanged = false; + + let forceUpdate = false; + + for (const service of services) { + const running = JSON.parse(service.Spec.Labels.configuration); + if (running) { + if ( + running.repository.id === configuration.repository.id && + running.repository.branch === configuration.repository.branch + ) { + // Base service configuration changed + if ( + !running.build.container.baseSHA || + running.build.container.baseSHA !== configuration.build.container.baseSHA + ) { + forceUpdate = true; + } + // If the deployment is in error state, forceUpdate + const state = await execShellAsync( + `docker stack ps ${running.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] === running.build.container.tag + ); + if (isError.length > 0) forceUpdate = true; + foundService = true; + + const runningWithoutContainer = JSON.parse(JSON.stringify(running)); + delete runningWithoutContainer.build.container; + + const configurationWithoutContainer = JSON.parse(JSON.stringify(configuration)); + delete configurationWithoutContainer.build.container; + + // If only the configuration changed + if ( + JSON.stringify(runningWithoutContainer.build) !== + JSON.stringify(configurationWithoutContainer.build) || + JSON.stringify(runningWithoutContainer.publish) !== + JSON.stringify(configurationWithoutContainer.publish) + ) + configChanged = true; + // If only the image changed + if (running.build.container.tag !== configuration.build.container.tag) imageChanged = true; + // If build pack changed, forceUpdate the service + if (running.build.pack !== configuration.build.pack) forceUpdate = true; + } + } + } + if (forceUpdate) { + imageChanged = false; + configChanged = false; + } + return { + foundService, + imageChanged, + configChanged, + forceUpdate + }; +} + +export async function updateServiceLabels(configuration) { + // In case of any failure during deployment, still update the current configuration. + const services = (await docker.engine.listServices()).filter( + (r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' + ); + const found = services.find((s) => { + const config = JSON.parse(s.Spec.Labels.configuration); + if ( + config.repository.id === configuration.repository.id && + config.repository.branch === configuration.repository.branch + ) { + return config; + } + return null; + }); + if (found) { + const { ID } = found; + const Labels = { ...JSON.parse(found.Spec.Labels.configuration), ...configuration }; + await execShellAsync( + `docker service update --label-add configuration='${JSON.stringify( + Labels + )}' --label-add com.docker.stack.image='${configuration.build.container.name}:${ + configuration.build.container.tag + }' ${ID}` + ); + } +} diff --git a/src/lib/api/applications/copyFiles.ts b/src/lib/api/applications/copyFiles.ts new file mode 100644 index 0000000000..7a6d024248 --- /dev/null +++ b/src/lib/api/applications/copyFiles.ts @@ -0,0 +1,69 @@ +import { promises as fs } from 'fs'; +export default async function (configuration) { + const staticDeployments = ['react', 'vuejs', 'static', 'svelte', 'gatsby']; + try { + // TODO: Write full .dockerignore for all deployments!! + if (configuration.build.pack === 'php') { + await fs.writeFile( + `${configuration.general.workdir}/.htaccess`, + ` + RewriteEngine On + RewriteBase / + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.+)$ index.php [QSA,L] + ` + ); + } + // await fs.writeFile(`${configuration.general.workdir}/.dockerignore`, 'node_modules') + if (staticDeployments.includes(configuration.build.pack)) { + await fs.writeFile( + `${configuration.general.workdir}/nginx.conf`, + `user nginx; + worker_processes auto; + + error_log /var/log/nginx/error.log warn; + pid /var/run/nginx.pid; + + events { + worker_connections 1024; + } + + http { + include /etc/nginx/mime.types; + + access_log off; + sendfile on; + #tcp_nopush on; + keepalive_timeout 65; + + server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html; + try_files $uri $uri/index.html $uri/ /index.html =404; + } + + error_page 404 /50x.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + } + + } + ` + ); + } + } catch (error) { + console.log(error); + throw new Error(error); + } +} diff --git a/src/lib/api/applications/deploy.ts b/src/lib/api/applications/deploy.ts new file mode 100644 index 0000000000..774d9894e9 --- /dev/null +++ b/src/lib/api/applications/deploy.ts @@ -0,0 +1,76 @@ +import { docker } from '$lib/api/docker'; +import { saveAppLog } from './logging'; +import { promises as fs } from 'fs'; +import { deleteSameDeployments } from './cleanup'; +import yaml from 'js-yaml'; +import { execShellAsync } from '../common'; + +export default async function (configuration, imageChanged) { + const generateEnvs = {}; + for (const secret of configuration.publish.secrets) { + generateEnvs[secret.name] = secret.value; + } + const containerName = configuration.build.container.name; + + // Only save SHA256 of it in the configuration label + const baseServiceConfiguration = configuration.baseServiceConfiguration; + delete configuration.baseServiceConfiguration; + + const stack = { + version: '3.8', + services: { + [containerName]: { + image: `${configuration.build.container.name}:${configuration.build.container.tag}`, + networks: [`${docker.network}`], + environment: generateEnvs, + deploy: { + ...baseServiceConfiguration, + labels: [ + 'managedBy=coolify', + 'type=application', + 'configuration=' + JSON.stringify(configuration), + 'traefik.enable=true', + 'traefik.http.services.' + + configuration.build.container.name + + `.loadbalancer.server.port=${configuration.publish.port}`, + 'traefik.http.routers.' + configuration.build.container.name + '.entrypoints=websecure', + 'traefik.http.routers.' + + configuration.build.container.name + + '.rule=Host(`' + + configuration.publish.domain + + '`) && PathPrefix(`' + + configuration.publish.path + + '`)', + 'traefik.http.routers.' + + configuration.build.container.name + + '.tls.certresolver=letsencrypt', + 'traefik.http.routers.' + + configuration.build.container.name + + '.middlewares=global-compress' + ] + } + } + }, + networks: { + [`${docker.network}`]: { + external: true + } + } + }; + await saveAppLog('### Publishing.', configuration); + await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack)); + if (imageChanged) { + // console.log('image changed') + await execShellAsync( + `docker service update --image ${configuration.build.container.name}:${configuration.build.container.tag} ${configuration.build.container.name}_${configuration.build.container.name}` + ); + } else { + // console.log('new deployment or force deployment or config changed') + await deleteSameDeployments(configuration); + await execShellAsync( + `cat ${configuration.general.workdir}/stack.yml | docker stack deploy --prune -c - ${containerName}` + ); + } + + await saveAppLog('### Published done!', configuration); +} diff --git a/src/lib/api/applications/logging.ts b/src/lib/api/applications/logging.ts new file mode 100644 index 0000000000..10f7aac1c2 --- /dev/null +++ b/src/lib/api/applications/logging.ts @@ -0,0 +1,58 @@ +import Settings from '$models/Settings'; +import ServerLog from '$models/Logs/Server'; +import ApplicationLog from '$models/Logs/Application'; +import dayjs from 'dayjs'; +import { version } from '../../../../package.json'; + +function generateTimestamp() { + return `${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} `; +} +const patterns = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' +].join('|'); + +export async function saveAppLog(event, configuration, isError?: boolean) { + try { + const deployId = configuration.general.deployId; + const repoId = configuration.repository.id; + const branch = configuration.repository.branch; + if (isError) { + const clearedEvent = + '[ERROR 😱] ' + + generateTimestamp() + + event.replace(new RegExp(patterns, 'g'), '').replace(/(\r\n|\n|\r)/gm, ''); + await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save(); + } else { + if (event && event !== '\n') { + const clearedEvent = + '[INFO] ' + + generateTimestamp() + + event.replace(new RegExp(patterns, 'g'), '').replace(/(\r\n|\n|\r)/gm, ''); + await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save(); + } + } + } catch (error) { + console.log(error); + return error; + } +} + +export async function saveServerLog(error) { + const settings = await Settings.findOne({ applicationName: 'coolify' }); + const payload = { + message: error.message, + stack: error.stack, + type: error.type || 'spaghetticode', + version + }; + + const found = await ServerLog.find(payload); + if (found.length === 0 && error.message) await new ServerLog(payload).save(); + if (settings && settings.sendErrors && process.env.NODE_ENV === 'production') { + await fetch('https://errors.coollabs.io/api/error', { + method: 'POST', + body: JSON.stringify({ ...payload }) + }); + } +} diff --git a/src/lib/api/applications/packs/docker/index.ts b/src/lib/api/applications/packs/docker/index.ts new file mode 100644 index 0000000000..e3d9f01e3d --- /dev/null +++ b/src/lib/api/applications/packs/docker/index.ts @@ -0,0 +1,17 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; + +export default async function (configuration) { + const path = `${configuration.general.workdir}/${ + configuration.build.directory ? configuration.build.directory : '' + }`; + if (fs.stat(`${path}/Dockerfile`)) { + const stream = await docker.engine.buildImage( + { src: ['.'], context: path }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); + } else { + throw new Error('No custom dockerfile found.'); + } +} diff --git a/src/lib/api/applications/packs/gatsby/index.ts b/src/lib/api/applications/packs/gatsby/index.ts new file mode 100644 index 0000000000..9cb109979d --- /dev/null +++ b/src/lib/api/applications/packs/gatsby/index.ts @@ -0,0 +1,28 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; + +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishStaticDocker = (configuration) => { + return [ + 'FROM nginx:stable-alpine', + 'COPY nginx.conf /etc/nginx/nginx.conf', + 'WORKDIR /usr/share/nginx/html', + `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, + 'EXPOSE 80', + 'CMD ["nginx", "-g", "daemon off;"]' + ].join('\n'); +}; + +export default async function (configuration) { + await buildImage(configuration, true); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishStaticDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/helpers.ts b/src/lib/api/applications/packs/helpers.ts new file mode 100644 index 0000000000..80d54179ec --- /dev/null +++ b/src/lib/api/applications/packs/helpers.ts @@ -0,0 +1,30 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; + +const buildImageNodeDocker = (configuration) => { + return [ + 'FROM node:lts', + 'WORKDIR /usr/src/app', + `COPY ${configuration.build.directory}/package*.json ./`, + configuration.build.command.installation && `RUN ${configuration.build.command.installation}`, + `COPY ./${configuration.build.directory} ./`, + `RUN ${configuration.build.command.build}` + ].join('\n'); +}; +export async function buildImage(configuration, cacheBuild?: boolean) { + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + buildImageNodeDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { + t: `${configuration.build.container.name}:${ + cacheBuild + ? `${configuration.build.container.tag}-cache` + : configuration.build.container.tag + }` + } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/index.ts b/src/lib/api/applications/packs/index.ts new file mode 100644 index 0000000000..1741fa7216 --- /dev/null +++ b/src/lib/api/applications/packs/index.ts @@ -0,0 +1,25 @@ +import vuejs from './vuejs'; +import svelte from './svelte'; +import Static from './static'; +import rust from './rust'; +import react from './react'; +import php from './php'; +import nuxtjs from './nuxtjs'; +import nodejs from './nodejs'; +import nextjs from './nextjs'; +import gatsby from './gatsby'; +import docker from './docker'; + +export { + vuejs, + svelte, + Static as static, + rust, + react, + php, + nuxtjs, + nodejs, + nextjs, + gatsby, + docker +}; diff --git a/src/lib/api/applications/packs/nextjs/index.ts b/src/lib/api/applications/packs/nextjs/index.ts new file mode 100644 index 0000000000..af6821c02a --- /dev/null +++ b/src/lib/api/applications/packs/nextjs/index.ts @@ -0,0 +1,30 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; +// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, +const publishNodejsDocker = (configuration) => { + return [ + 'FROM node:lts', + 'WORKDIR /usr/src/app', + configuration.build.command.build + ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` + : ` + COPY ${configuration.build.directory}/package*.json ./ + RUN ${configuration.build.command.installation} + COPY ./${configuration.build.directory} ./`, + `EXPOSE ${configuration.publish.port}`, + 'CMD [ "yarn", "start" ]' + ].join('\n'); +}; +export default async function (configuration) { + await buildImage(configuration); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishNodejsDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/nodejs/index.ts b/src/lib/api/applications/packs/nodejs/index.ts new file mode 100644 index 0000000000..8001921ea0 --- /dev/null +++ b/src/lib/api/applications/packs/nodejs/index.ts @@ -0,0 +1,31 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; +// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, +const publishNodejsDocker = (configuration) => { + return [ + 'FROM node:lts', + 'WORKDIR /usr/src/app', + configuration.build.command.build + ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` + : ` + COPY ${configuration.build.directory}/package*.json ./ + RUN ${configuration.build.command.installation} + COPY ./${configuration.build.directory} ./`, + `EXPOSE ${configuration.publish.port}`, + 'CMD [ "yarn", "start" ]' + ].join('\n'); +}; + +export default async function (configuration) { + if (configuration.build.command.build) await buildImage(configuration); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishNodejsDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/nuxtjs/index.ts b/src/lib/api/applications/packs/nuxtjs/index.ts new file mode 100644 index 0000000000..eee103ca1d --- /dev/null +++ b/src/lib/api/applications/packs/nuxtjs/index.ts @@ -0,0 +1,31 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; +// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`, +const publishNodejsDocker = (configuration) => { + return [ + 'FROM node:lts', + 'WORKDIR /usr/src/app', + configuration.build.command.build + ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./` + : ` + COPY ${configuration.build.directory}/package*.json ./ + RUN ${configuration.build.command.installation} + COPY ./${configuration.build.directory} ./`, + `EXPOSE ${configuration.publish.port}`, + 'CMD [ "yarn", "start" ]' + ].join('\n'); +}; + +export default async function (configuration) { + await buildImage(configuration); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishNodejsDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/php/index.ts b/src/lib/api/applications/packs/php/index.ts new file mode 100644 index 0000000000..5bd55bb811 --- /dev/null +++ b/src/lib/api/applications/packs/php/index.ts @@ -0,0 +1,25 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishPHPDocker = (configuration) => { + return [ + 'FROM php:apache', + 'RUN a2enmod rewrite', + 'WORKDIR /usr/src/app', + `COPY ./${configuration.build.directory} /var/www/html`, + 'EXPOSE 80', + ' CMD ["apache2-foreground"]' + ].join('\n'); +}; + +export default async function (configuration) { + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishPHPDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/react/index.ts b/src/lib/api/applications/packs/react/index.ts new file mode 100644 index 0000000000..9cb109979d --- /dev/null +++ b/src/lib/api/applications/packs/react/index.ts @@ -0,0 +1,28 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; + +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishStaticDocker = (configuration) => { + return [ + 'FROM nginx:stable-alpine', + 'COPY nginx.conf /etc/nginx/nginx.conf', + 'WORKDIR /usr/share/nginx/html', + `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, + 'EXPOSE 80', + 'CMD ["nginx", "-g", "daemon off;"]' + ].join('\n'); +}; + +export default async function (configuration) { + await buildImage(configuration, true); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishStaticDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/rust/index.ts b/src/lib/api/applications/packs/rust/index.ts new file mode 100644 index 0000000000..c11a9db328 --- /dev/null +++ b/src/lib/api/applications/packs/rust/index.ts @@ -0,0 +1,66 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import TOML from '@iarna/toml'; +import { execShellAsync } from '$lib/api/common'; + +const publishRustDocker = (configuration, custom) => { + return [ + 'FROM rust:latest', + 'WORKDIR /app', + `COPY --from=${configuration.build.container.name}:cache /app/target target`, + `COPY --from=${configuration.build.container.name}:cache /usr/local/cargo /usr/local/cargo`, + 'COPY . .', + `RUN cargo build --release --bin ${custom.name}`, + 'FROM debian:buster-slim', + 'WORKDIR /app', + 'RUN apt-get update -y && apt-get install -y --no-install-recommends openssl libcurl4 ca-certificates && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*', + 'RUN update-ca-certificates', + `COPY --from=${configuration.build.container.name}:cache /app/target/release/${custom.name} ${custom.name}`, + `EXPOSE ${configuration.publish.port}`, + `CMD ["/app/${custom.name}"]` + ].join('\n'); +}; + +const cacheRustDocker = (configuration, custom) => { + return [ + `FROM rust:latest AS planner-${configuration.build.container.name}`, + 'WORKDIR /app', + 'RUN cargo install cargo-chef', + 'COPY . .', + 'RUN cargo chef prepare --recipe-path recipe.json', + 'FROM rust:latest', + 'WORKDIR /app', + 'RUN cargo install cargo-chef', + `COPY --from=planner-${configuration.build.container.name} /app/recipe.json recipe.json`, + 'RUN cargo chef cook --release --recipe-path recipe.json' + ].join('\n'); +}; + +export default async function (configuration) { + const cargoToml = await execShellAsync(`cat ${configuration.general.workdir}/Cargo.toml`); + const parsedToml = TOML.parse(cargoToml); + const custom = { + name: parsedToml.package.name + }; + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + cacheRustDocker(configuration, custom) + ); + + let stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:cache` } + ); + await streamEvents(stream, configuration); + + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishRustDocker(configuration, custom) + ); + + stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/static/index.ts b/src/lib/api/applications/packs/static/index.ts new file mode 100644 index 0000000000..5f4d5c302e --- /dev/null +++ b/src/lib/api/applications/packs/static/index.ts @@ -0,0 +1,30 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; + +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishStaticDocker = (configuration) => { + return [ + 'FROM nginx:stable-alpine', + 'COPY nginx.conf /etc/nginx/nginx.conf', + 'WORKDIR /usr/share/nginx/html', + configuration.build.command.build + ? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./` + : `COPY ./${configuration.build.directory} ./`, + 'EXPOSE 80', + 'CMD ["nginx", "-g", "daemon off;"]' + ].join('\n'); +}; + +export default async function (configuration) { + if (configuration.build.command.build) await buildImage(configuration, true); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishStaticDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/svelte/index.ts b/src/lib/api/applications/packs/svelte/index.ts new file mode 100644 index 0000000000..9cb109979d --- /dev/null +++ b/src/lib/api/applications/packs/svelte/index.ts @@ -0,0 +1,28 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; + +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishStaticDocker = (configuration) => { + return [ + 'FROM nginx:stable-alpine', + 'COPY nginx.conf /etc/nginx/nginx.conf', + 'WORKDIR /usr/share/nginx/html', + `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, + 'EXPOSE 80', + 'CMD ["nginx", "-g", "daemon off;"]' + ].join('\n'); +}; + +export default async function (configuration) { + await buildImage(configuration, true); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishStaticDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/packs/vuejs/index.ts b/src/lib/api/applications/packs/vuejs/index.ts new file mode 100644 index 0000000000..d0f688a9af --- /dev/null +++ b/src/lib/api/applications/packs/vuejs/index.ts @@ -0,0 +1,28 @@ +import { docker, streamEvents } from '$lib/api/docker'; +import { promises as fs } from 'fs'; +import { buildImage } from '../helpers'; + +// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1', +const publishStaticDocker = (configuration) => { + return [ + 'FROM nginx:stable-alpine', + 'COPY nginx.conf /etc/nginx/nginx.conf', + 'WORKDIR /usr/share/nginx/html', + `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag}-cache /usr/src/app/${configuration.publish.directory} ./`, + 'EXPOSE 80', + 'CMD ["nginx", "-g", "daemon off;"]' + ].join('\n'); +}; + +export default async function (configuration) { + await buildImage(configuration, true); + await fs.writeFile( + `${configuration.general.workdir}/Dockerfile`, + publishStaticDocker(configuration) + ); + const stream = await docker.engine.buildImage( + { src: ['.'], context: configuration.general.workdir }, + { t: `${configuration.build.container.name}:${configuration.build.container.tag}` } + ); + await streamEvents(stream, configuration); +} diff --git a/src/lib/api/applications/queueAndBuild.ts b/src/lib/api/applications/queueAndBuild.ts new file mode 100644 index 0000000000..a8a3ed892a --- /dev/null +++ b/src/lib/api/applications/queueAndBuild.ts @@ -0,0 +1,31 @@ +import Deployment from '$models/Logs/Deployment'; +import dayjs from 'dayjs'; +import buildContainer from './buildContainer'; +import { updateServiceLabels } from './configuration'; +import copyFiles from './copyFiles'; +import deploy from './deploy'; +import { saveAppLog } from './logging'; + +export default async function (configuration, imageChanged) { + const { id, organization, name, branch } = configuration.repository; + const { domain } = configuration.publish; + const { deployId, nickname } = configuration.general; + await new Deployment({ + repoId: id, + branch, + deployId, + domain, + organization, + name, + nickname + }).save(); + await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration); + await copyFiles(configuration); + await buildContainer(configuration); + await deploy(configuration, imageChanged); + await Deployment.findOneAndUpdate( + { repoId: id, branch, deployId, organization, name, domain }, + { repoId: id, branch, deployId, organization, name, domain, progress: 'done' } + ); + await updateServiceLabels(configuration); +} diff --git a/src/lib/api/applications/templates.ts b/src/lib/api/applications/templates.ts new file mode 100644 index 0000000000..41de3b756f --- /dev/null +++ b/src/lib/api/applications/templates.ts @@ -0,0 +1,57 @@ +const defaultBuildAndDeploy = { + installation: 'yarn install', + build: 'yarn build' +}; + +const templates = { + svelte: { + pack: 'svelte', + ...defaultBuildAndDeploy, + directory: 'public', + name: 'Svelte' + }, + next: { + pack: 'nextjs', + ...defaultBuildAndDeploy, + port: 3000, + name: 'NextJS' + }, + nuxt: { + pack: 'nuxtjs', + ...defaultBuildAndDeploy, + port: 3000, + name: 'NuxtJS' + }, + 'react-scripts': { + pack: 'react', + ...defaultBuildAndDeploy, + directory: 'build', + name: 'React' + }, + 'parcel-bundler': { + pack: 'static', + ...defaultBuildAndDeploy, + directory: 'dist', + name: 'Parcel' + }, + '@vue/cli-service': { + pack: 'vuejs', + ...defaultBuildAndDeploy, + directory: 'dist', + name: 'Vue' + }, + gatsby: { + pack: 'gatsby', + ...defaultBuildAndDeploy, + directory: 'public', + name: 'Gatsby' + }, + 'preact-cli': { + pack: 'react', + ...defaultBuildAndDeploy, + directory: 'build', + name: 'Preact' + } +}; + +export default templates; diff --git a/src/lib/api/common.ts b/src/lib/api/common.ts new file mode 100644 index 0000000000..1b077bd64f --- /dev/null +++ b/src/lib/api/common.ts @@ -0,0 +1,44 @@ +import shell from 'shelljs'; +import User from '$models/User'; +import jsonwebtoken from 'jsonwebtoken'; + +export function execShellAsync(cmd, opts = {}) { + try { + return new Promise(function (resolve, reject) { + shell.config.silent = true; + shell.exec(cmd, opts, function (code, stdout, stderr) { + if (code !== 0) return reject(new Error(stderr)); + return resolve(stdout); + }); + }); + } catch (error) { + return new Error('Oops'); + } +} +export function cleanupTmp(dir) { + if (dir !== '/') shell.rm('-fr', dir); +} + +export async function verifyUserId(token) { + const { JWT_SIGN_KEY } = process.env; + try { + const verify = jsonwebtoken.verify(token, JWT_SIGN_KEY); + const found = await User.findOne({ uid: verify.jti }); + if (found) { + return Promise.resolve(true); + } else { + return Promise.reject(false); + } + } catch (error) { + console.log(error); + return Promise.reject(false); + } +} + +export function delay(t) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve('OK'); + }, t); + }); +} diff --git a/src/lib/api/docker.ts b/src/lib/api/docker.ts new file mode 100644 index 0000000000..0c623e590b --- /dev/null +++ b/src/lib/api/docker.ts @@ -0,0 +1,27 @@ +import Dockerode from 'dockerode'; +import { saveAppLog } from './applications/logging'; + +const { DOCKER_ENGINE, DOCKER_NETWORK } = process.env; +export const docker = { + engine: new Dockerode({ + socketPath: DOCKER_ENGINE + }), + network: DOCKER_NETWORK +}; +export async function streamEvents(stream, configuration) { + await new Promise((resolve, reject) => { + docker.engine.modem.followProgress(stream, onFinished, onProgress); + function onFinished(err, res) { + if (err) reject(err); + resolve(res); + } + function onProgress(event) { + if (event.error) { + saveAppLog(event.error, configuration, true); + reject(event.error); + } else if (event.stream) { + saveAppLog(event.stream, configuration); + } + } + }); +} diff --git a/src/lib/api/request.ts b/src/lib/api/request.ts new file mode 100644 index 0000000000..108fdbf9b4 --- /dev/null +++ b/src/lib/api/request.ts @@ -0,0 +1,102 @@ +import { toast } from '@zerodevx/svelte-toast'; +import { browser } from '$app/env'; + +export async function request( + url, + session, + { + method, + body, + customHeaders + }: { + url?: string; + session?: any; + fetch?: any; + method?: string; + body?: any; + customHeaders?: Record; + } = {} +) { + let fetch; + if (browser) { + fetch = window.fetch; + } else { + fetch = session.fetch; + } + let headers = { 'content-type': 'application/json; charset=UTF-8' }; + if (method === 'DELETE') { + delete headers['content-type']; + } + const isGithub = url.match(/api.github.com/); + if (isGithub) { + headers = Object.assign(headers, { + Authorization: `token ${session.ghToken}` + }); + } + const config: any = { + method: method || (body ? 'POST' : 'GET'), + cache: isGithub ? 'no-cache' : 'default', + headers: { + ...headers, + ...customHeaders + } + }; + if (body) { + config.body = JSON.stringify(body); + } + const response = await fetch(url, config); + if (response.status >= 200 && response.status <= 299) { + if (response.headers.get('content-type').match(/application\/json/)) { + const json = await response.json(); + if (json?.success === false) { + browser && json.showToast !== false && toast.push(json.message); + return Promise.reject({ + status: response.status, + error: json.message + }); + } + return json; + } else if (response.headers.get('content-type').match(/text\/plain/)) { + return await response.text(); + } else if (response.headers.get('content-type').match(/multipart\/form-data/)) { + return await response.formData(); + } else { + console.log(response); + if (response.headers.get('content-disposition')) { + const blob = await response.blob(); + console.log(blob); + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = response.headers.get('content-disposition').split('=')[1] || 'backup.gz'; + link.target = '_blank'; + link.setAttribute('type', 'hidden'); + document.body.appendChild(link); + link.click(); + link.remove(); + return; + } + return await response.blob(); + } + } else { + if (response.status === 401) { + browser && toast.push('Unauthorized'); + return Promise.reject({ + status: response.status, + error: 'Unauthorized' + }); + } else if (response.status >= 500) { + const error = (await response.json()).error; + browser && toast.push(error); + return Promise.reject({ + status: response.status, + error: error || 'Oops, something is not okay. Are you okay?' + }); + } else { + browser && toast.push(response.statusText); + return Promise.reject({ + status: response.status, + error: response.statusText + }); + } + } +} diff --git a/src/lib/consts.ts b/src/lib/consts.ts new file mode 100644 index 0000000000..de4694694d --- /dev/null +++ b/src/lib/consts.ts @@ -0,0 +1 @@ +export const publicPages = ['/', '/api/v1/login/github/app', '/api/v1/webhooks/deploy', '/success']; diff --git a/src/models/Logs/Application.ts b/src/models/Logs/Application.ts new file mode 100644 index 0000000000..7e8291dadf --- /dev/null +++ b/src/models/Logs/Application.ts @@ -0,0 +1,11 @@ +import mongoose from 'mongoose'; +const { Schema } = mongoose; + +const ApplicationLogsSchema = new Schema({ + deployId: { type: String, required: true }, + event: { type: String, required: true } +}); + +ApplicationLogsSchema.set('timestamps', true); + +export default mongoose.model('logs-application', ApplicationLogsSchema); diff --git a/src/models/Logs/Deployment.ts b/src/models/Logs/Deployment.ts new file mode 100644 index 0000000000..34d5df654e --- /dev/null +++ b/src/models/Logs/Deployment.ts @@ -0,0 +1,17 @@ +import mongoose from 'mongoose'; +const { Schema } = mongoose; + +const DeploymentSchema = new Schema({ + deployId: { type: String, required: true }, + nickname: { type: String, required: true }, + repoId: { type: Number, required: true }, + organization: { type: String, required: true }, + name: { type: String, required: true }, + branch: { type: String, required: true }, + domain: { type: String, required: true }, + progress: { type: String, require: true, default: 'queued' } +}); + +DeploymentSchema.set('timestamps', true); + +export default mongoose.model('deployment', DeploymentSchema); diff --git a/src/models/Logs/Server.ts b/src/models/Logs/Server.ts new file mode 100644 index 0000000000..0c949b4d8b --- /dev/null +++ b/src/models/Logs/Server.ts @@ -0,0 +1,23 @@ +import mongoose from 'mongoose'; +import { version } from '../../../package.json'; +const { Schema, Document } = mongoose; + +// export interface ILogsServer extends Document { +// version: string; +// type: string; +// message: string; +// stack: string; +// seen: Boolean; +// } + +const LogsServerSchema = new Schema({ + version: { type: String, default: version }, + type: { type: String, required: true }, + message: { type: String, required: true }, + stack: { type: String }, + seen: { type: Boolean, default: false } +}); + +LogsServerSchema.set('timestamps', { createdAt: 'createdAt', updatedAt: false }); + +export default mongoose.model('logs-server', LogsServerSchema); diff --git a/src/models/Settings.ts b/src/models/Settings.ts new file mode 100644 index 0000000000..63686c9804 --- /dev/null +++ b/src/models/Settings.ts @@ -0,0 +1,17 @@ +import mongoose from 'mongoose'; +const { Schema } = mongoose; +export interface ISettings extends Document { + applicationName: string; + allowRegistration: string; + sendErrors: boolean; +} + +const SettingsSchema = new Schema({ + applicationName: { type: String, required: true, default: 'coolify' }, + allowRegistration: { type: Boolean, required: true, default: false }, + sendErrors: { type: Boolean, required: true, default: true } +}); + +SettingsSchema.set('timestamps', true); + +export default mongoose.model('settings', SettingsSchema); diff --git a/src/models/User.ts b/src/models/User.ts new file mode 100644 index 0000000000..818aa4946f --- /dev/null +++ b/src/models/User.ts @@ -0,0 +1,17 @@ +import mongoose from 'mongoose'; +const { Schema } = mongoose; +export interface IUser extends Document { + email: string; + avatar?: string; + uid: string; +} + +const UserSchema = new Schema({ + email: { type: String, required: true, unique: true }, + avatar: { type: String }, + uid: { type: String, required: true } +}); + +UserSchema.set('timestamps', true); + +export default mongoose.model('user', UserSchema); diff --git a/src/pages/_fallback.svelte b/src/pages/_fallback.svelte deleted file mode 100644 index 6d8ba0f642..0000000000 --- a/src/pages/_fallback.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - -
-
- 404 -
-
Ah you lost. Don't worry. I'm here for you!
- Go back -
diff --git a/src/pages/_layout.svelte b/src/pages/_layout.svelte deleted file mode 100644 index e49e7f5d82..0000000000 --- a/src/pages/_layout.svelte +++ /dev/null @@ -1,354 +0,0 @@ - - - - -{#await verifyToken() then notUsed} - {#if showAck} -
-
-
- We implemented an automatic error reporting feature, which is enabled - by default. -
-
- Why? Because we would like to hunt down bugs faster and easier. -
-
- If you do not like it, you can turn it off in the . -
- -
-
- {/if} - {#if $route.path !== "/index"} - - {/if} - {#if upgradeAvailable} -
-
-
-
- {#if !upgradeDisabled} - - {:else if upgradeDone} - - {:else} - - {/if} -
-
- {/if} -
- -
-{:catch test} - {$goto("/index")} -{/await} diff --git a/src/pages/application/[organization]/[name]/[branch]/configuration.svelte b/src/pages/application/[organization]/[name]/[branch]/configuration.svelte deleted file mode 100644 index 48bcc3ca6c..0000000000 --- a/src/pages/application/[organization]/[name]/[branch]/configuration.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/pages/application/[organization]/[name]/[branch]/index.svelte b/src/pages/application/[organization]/[name]/[branch]/index.svelte deleted file mode 100644 index d17f7bec5f..0000000000 --- a/src/pages/application/[organization]/[name]/[branch]/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/application/[organization]/[name]/[branch]/logs/[deployId].svelte b/src/pages/application/[organization]/[name]/[branch]/logs/[deployId].svelte deleted file mode 100644 index 591b28afcd..0000000000 --- a/src/pages/application/[organization]/[name]/[branch]/logs/[deployId].svelte +++ /dev/null @@ -1,62 +0,0 @@ - - -
-
Deployment log
-
-{#await loadLogs()} - -{:then} -
-
-
-      {#if logs.length > 0}
-        {#each logs as log}
-          {log + '\n'}
-        {/each}
-      {:else}
-        It's starting soon.
-      {/if}
-    
-
-
-{/await} diff --git a/src/pages/application/[organization]/[name]/[branch]/logs/index.svelte b/src/pages/application/[organization]/[name]/[branch]/logs/index.svelte deleted file mode 100644 index 42a91340e4..0000000000 --- a/src/pages/application/[organization]/[name]/[branch]/logs/index.svelte +++ /dev/null @@ -1,140 +0,0 @@ - - - - -
-
Logs
-
-{#await loadDeploymentLogs()} - -{:then} -
-
-
-
Application logs
- {#if logs.length === 0} -
Waiting for the logs...
- {:else} -
-            {#each logs as log}
-              {log + '\n'}
-            {/each}
-          
- {/if} -
-
-
- Deployment logs -
- {#if deployments.length > 0} - {#each deployments as deployment} -
-
- {deployment.branch} -
-
-
-
- {deployment.since} -
- {#if deployment.progress === "done"} -
- Deployed in {deployment.took}s -
- {:else if deployment.progress === "failed"} -
Failed
- {:else} -
Deploying...
- {/if} -
-
- {/each} - - {:else} -
- No deployments found -
- {/if} -
-
-
-{:catch} -
No logs found
-{/await} diff --git a/src/pages/application/[organization]/[name]/[branch]/overview.svelte b/src/pages/application/[organization]/[name]/[branch]/overview.svelte deleted file mode 100644 index 992438afe0..0000000000 --- a/src/pages/application/[organization]/[name]/[branch]/overview.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - -
-
- Overview of - {$application.publish.domain} - - - -
-
- - - diff --git a/src/pages/application/[organization]/[name]/index.svelte b/src/pages/application/[organization]/[name]/index.svelte deleted file mode 100644 index 69f34470d2..0000000000 --- a/src/pages/application/[organization]/[name]/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/application/[organization]/index.svelte b/src/pages/application/[organization]/index.svelte deleted file mode 100644 index 69f34470d2..0000000000 --- a/src/pages/application/[organization]/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/application/_layout.svelte b/src/pages/application/_layout.svelte deleted file mode 100644 index cac22ce5af..0000000000 --- a/src/pages/application/_layout.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - -{#await loadConfiguration()} - -{:then} - -
- -
-{/await} diff --git a/src/pages/application/index.svelte b/src/pages/application/index.svelte deleted file mode 100644 index 69f34470d2..0000000000 --- a/src/pages/application/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/application/new.svelte b/src/pages/application/new.svelte deleted file mode 100644 index 9517ccadb0..0000000000 --- a/src/pages/application/new.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/pages/dashboard/_layout.svelte b/src/pages/dashboard/_layout.svelte deleted file mode 100644 index e64ba72235..0000000000 --- a/src/pages/dashboard/_layout.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - -
- -
diff --git a/src/pages/dashboard/applications.svelte b/src/pages/dashboard/applications.svelte deleted file mode 100644 index 58da198700..0000000000 --- a/src/pages/dashboard/applications.svelte +++ /dev/null @@ -1,295 +0,0 @@ - - -
-
Applications
- -
-
- {#if $deployments.applications?.deployed.length > 0} -
-
- {#each $deployments.applications.deployed as application} -
-
-
- {#if application.configuration.build.pack === "static"} - - {:else if application.configuration.build.pack === "react"} - - - - {:else if application.configuration.build.pack === "gatsby"} - - - - {:else if application.configuration.build.pack === "nuxtjs"} - - - - - - - - {:else if application.configuration.build.pack === "svelte"} - - - - - {:else if application.configuration.build.pack === "vuejs"} - - - - {:else if application.configuration.build.pack === "nextjs"} - - - - {:else if application.configuration.build.pack === "nodejs"} - - {:else if application.configuration.build.pack === "php"} - - - - {:else if application.configuration.build.pack === "docker"} - - - - {:else if application.configuration.build.pack === "rust"} - - - - {/if} -
-
- {application.configuration.publish - .domain}{application.configuration.publish - .path !== "/" - ? application.configuration.publish.path - : ""} -
-
- Last deployment
- {new Intl.DateTimeFormat("default", $dateOptions).format( - new Date(application.UpdatedAt), - )} -
-
-
-
-
- {/each} -
-
- {:else} -
No applications found
- {/if} -
diff --git a/src/pages/dashboard/databases.svelte b/src/pages/dashboard/databases.svelte deleted file mode 100644 index 09a35b693a..0000000000 --- a/src/pages/dashboard/databases.svelte +++ /dev/null @@ -1,156 +0,0 @@ - - - - -
-
Databases
- -
-
- {#if $deployments.databases?.deployed.length > 0} -
-
- {#each $deployments.databases.deployed as database} -
-
-
- {#if database.configuration.general.type == "mongodb"} - - {:else if database.configuration.general.type == "postgresql"} - - {:else if database.configuration.general.type == "mysql"} - - {:else if database.configuration.general.type == "couchdb"} - - {:else if database.configuration.general.type == "clickhouse"} - - {/if} -
-
- {database.configuration.general.nickname} -
-
- ({database.configuration.general.type}) -
-
-
-
-
- {/each} - {#if $dbInprogress} -
-
- Working... -
-
- {/if} -
-
- {:else if $dbInprogress} -
-
-
-
- Working... -
-
-
-
- {:else} -
No databases found
- {/if} -
diff --git a/src/pages/dashboard/index.svelte b/src/pages/dashboard/index.svelte deleted file mode 100644 index 69f34470d2..0000000000 --- a/src/pages/dashboard/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/dashboard/services.svelte b/src/pages/dashboard/services.svelte deleted file mode 100644 index b79b3f9287..0000000000 --- a/src/pages/dashboard/services.svelte +++ /dev/null @@ -1,74 +0,0 @@ - - -
-
Services
- -
-
- {#if $deployments?.services?.deployed.length > 0} -
-
- {#each $deployments?.services?.deployed as service} -
-
-
- {#if service.serviceName == "plausible"} -
- plausible logo -
Plausible Analytics
-
- {/if} -
-
-
- {/each} -
-
- {:else} -
No services found
- {/if} -
diff --git a/src/pages/database/[name]/configuration.svelte b/src/pages/database/[name]/configuration.svelte deleted file mode 100644 index 158c079376..0000000000 --- a/src/pages/database/[name]/configuration.svelte +++ /dev/null @@ -1,87 +0,0 @@ - - -{#await loadDatabaseConfig()} - -{:then} -
-
-
{$database.config.general.nickname}
-
- {#if $database.config.general.type === "mongodb"} - - {:else if $database.config.general.type === "postgresql"} - - {:else if $database.config.general.type === "mysql"} - - {:else if $database.config.general.type === "couchdb"} - - {/if} -
-
-
-
-
-
Database
-
-
Connection string
- {#if $database.config.general.type === "mongodb"} - - {:else if $database.config.general.type === "postgresql"} - - {:else if $database.config.general.type === "mysql"} - - {:else if $database.config.general.type === "couchdb"} - - {:else if $database.config.general.type === "clickhouse"} - - - {/if} -
-
- {#if $database.config.general.type === "mongodb"} -
-
Root password
- -
- {/if} -
-{/await} diff --git a/src/pages/database/[name]/index.svelte b/src/pages/database/[name]/index.svelte deleted file mode 100644 index bf5c5bdf1c..0000000000 --- a/src/pages/database/[name]/index.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/src/pages/database/_layout.svelte b/src/pages/database/_layout.svelte deleted file mode 100644 index a0a3186ae9..0000000000 --- a/src/pages/database/_layout.svelte +++ /dev/null @@ -1,80 +0,0 @@ - - -{#if !$isActive("/database/new")} - -{/if} -
- -
diff --git a/src/pages/database/index.svelte b/src/pages/database/index.svelte deleted file mode 100644 index dbc608a221..0000000000 --- a/src/pages/database/index.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/src/pages/database/new.svelte b/src/pages/database/new.svelte deleted file mode 100644 index 0626f6533e..0000000000 --- a/src/pages/database/new.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- Select a database -
-
- - diff --git a/src/pages/index.svelte b/src/pages/index.svelte deleted file mode 100644 index 7aee968243..0000000000 --- a/src/pages/index.svelte +++ /dev/null @@ -1,65 +0,0 @@ - - -
-
-
-

- Coolify -

-

- An open-source, hassle-free, self-hostable
- Heroku - & Netlify alternative -

-
- {#if !$loggedIn} - - {:else} - - {/if} -
-
-
-
diff --git a/src/pages/service/[name]/_layout.svelte b/src/pages/service/[name]/_layout.svelte deleted file mode 100644 index 6043ca2d1e..0000000000 --- a/src/pages/service/[name]/_layout.svelte +++ /dev/null @@ -1,74 +0,0 @@ - - - - -
- -
diff --git a/src/pages/service/[name]/configuration.svelte b/src/pages/service/[name]/configuration.svelte deleted file mode 100644 index c687021063..0000000000 --- a/src/pages/service/[name]/configuration.svelte +++ /dev/null @@ -1,68 +0,0 @@ - - -{#await loadServiceConfig()} - -{:then} - -
-
- {#if name === "plausible"} - - {/if} -
-
-{/await} diff --git a/src/pages/service/[name]/index.svelte b/src/pages/service/[name]/index.svelte deleted file mode 100644 index a5319b72ed..0000000000 --- a/src/pages/service/[name]/index.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/src/pages/service/new/[type]/_layout.svelte b/src/pages/service/new/[type]/_layout.svelte deleted file mode 100644 index 21c2204823..0000000000 --- a/src/pages/service/new/[type]/_layout.svelte +++ /dev/null @@ -1,32 +0,0 @@ - - -{#await checkService()} - -{:then} -
- -
-{/await} diff --git a/src/pages/service/new/[type]/index.svelte b/src/pages/service/new/[type]/index.svelte deleted file mode 100644 index 49f8899bb7..0000000000 --- a/src/pages/service/new/[type]/index.svelte +++ /dev/null @@ -1,136 +0,0 @@ - - -
-
- Deploy new - {#if type === "plausible"} - Plausible Analytics - {/if} -
-
-{#if loading} - -{:else} -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
-{/if} diff --git a/src/pages/service/new/index.svelte b/src/pages/service/new/index.svelte deleted file mode 100644 index 1b91a83aff..0000000000 --- a/src/pages/service/new/index.svelte +++ /dev/null @@ -1,32 +0,0 @@ - - -
-
- Select a service -
-
-
- {#if $isActive("/service/new")} -
-
- plausible logo -
Plausible Analytics
-
-
- {/if} -
diff --git a/src/pages/settings/index.svelte b/src/pages/settings/index.svelte deleted file mode 100644 index bcd707d541..0000000000 --- a/src/pages/settings/index.svelte +++ /dev/null @@ -1,174 +0,0 @@ - - -
-
-
Settings
-
-
-{#await loadSettings()} - -{:then} -
-
-
-
General
-
-
-
    -
  • -
    -

    - Registration allowed? -

    -

    - Allow further registrations to the application. It's turned - off after the first registration. -

    -
    - -
  • -
  • -
    -

    - Send errors automatically? -

    -

    - Allow to send errors automatically to developer(s) at coolLabs (Andras Bacsai). This will help to fix bugs quicker. 🙏 -

    -
    - -
  • -
-
-
-
-
-
-{/await} diff --git a/src/routes/__error.svelte b/src/routes/__error.svelte new file mode 100644 index 0000000000..62f45fc132 --- /dev/null +++ b/src/routes/__error.svelte @@ -0,0 +1,15 @@ + + + + +

{error}

\ No newline at end of file diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte new file mode 100644 index 0000000000..dce2976752 --- /dev/null +++ b/src/routes/__layout.svelte @@ -0,0 +1,315 @@ + + + + + + +{#if showAck && $page.path !== '/success' && $page.path !== '/'} +
+
+
We implemented an automatic error reporting feature, which is enabled by default.
+
Why? Because we would like to hunt down bugs faster and easier.
+
+ If you do not like it, you can turn it off in the . +
+ +
+
+{/if} +
+ {#if $page.path !== '/' && $page.path !== '/success'} + + {/if} + +
+{#if upgradeAvailable && $page.path !== '/success' && $page.path !== '/'} +
+
+
+
+ {#if !upgradeDisabled} + + {:else if upgradeDone} + + {:else} + + {/if} +
+
+{/if} diff --git a/src/routes/api/_index.ts b/src/routes/api/_index.ts new file mode 100644 index 0000000000..feefe2c6da --- /dev/null +++ b/src/routes/api/_index.ts @@ -0,0 +1,42 @@ +import type { Request } from '@sveltejs/kit'; + +// export async function api(request: Request, resource: string, data?: {}) { +// const base = 'https://github.com/'; +// if (!request.context.isLoggedIn) { +// return { status: 401, body: 'Unauthorized' }; +// } + +// const res = await fetch(`${base}${resource}`, { +// method: request.method, +// headers: { +// 'content-type': 'application/json' +// }, +// body: data && JSON.stringify(data) +// }); +// return { +// status: res.status, +// body: await res.json() +// }; +// } + +export async function githubAPI( + request: Request, + resource: string, + token?: string, + data?: Record +) { + const base = 'https://api.github.com'; + const res = await fetch(`${base}${resource}`, { + method: request.method, + headers: { + 'content-type': 'application/json', + accept: 'application/json', + authorization: token ? `token ${token}` : '' + }, + body: data && JSON.stringify(data) + }); + return { + status: res.status, + body: await res.json() + }; +} diff --git a/src/routes/api/v1/application/check.ts b/src/routes/api/v1/application/check.ts new file mode 100644 index 0000000000..5774609cc2 --- /dev/null +++ b/src/routes/api/v1/application/check.ts @@ -0,0 +1,51 @@ +import { setDefaultConfiguration } from '$lib/api/applications/configuration'; +import { saveServerLog } from '$lib/api/applications/logging'; +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; + +export async function post(request: Request) { + try { + const { DOMAIN } = process.env; + const configuration = setDefaultConfiguration(request.body); + + const services = (await docker.engine.listServices()).filter( + (r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' + ); + let foundDomain = false; + + for (const service of services) { + const running = JSON.parse(service.Spec.Labels.configuration); + if (running) { + if ( + running.publish.domain === configuration.publish.domain && + running.repository.id !== configuration.repository.id && + running.publish.path === configuration.publish.path + ) { + foundDomain = true; + } + } + } + if (DOMAIN === configuration.publish.domain) foundDomain = true; + if (foundDomain) { + return { + status: 200, + body: { + success: false, + message: 'Domain already in use.' + } + }; + } + return { + status: 200, + body: { success: true, message: 'OK' } + }; + } catch (error) { + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/application/config.ts b/src/routes/api/v1/application/config.ts new file mode 100644 index 0000000000..7df760bda9 --- /dev/null +++ b/src/routes/api/v1/application/config.ts @@ -0,0 +1,50 @@ +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; + +export async function post(request: Request) { + const { name, organization, branch }: any = request.body || {}; + if (name && organization && branch) { + const services = await docker.engine.listServices(); + const applications = services.filter( + (r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' + ); + const found = applications.find((r) => { + const configuration = r.Spec.Labels.configuration + ? JSON.parse(r.Spec.Labels.configuration) + : null; + if (branch) { + if ( + 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; + }); + if (found) { + return { + status: 200, + body: { + success: true, + ...JSON.parse(found.Spec.Labels.configuration) + } + }; + } else { + return { + status: 500, + body: { + error: 'No configuration found.' + } + }; + } + } +} diff --git a/src/routes/api/v1/application/deploy/index.ts b/src/routes/api/v1/application/deploy/index.ts new file mode 100644 index 0000000000..54329f9a6e --- /dev/null +++ b/src/routes/api/v1/application/deploy/index.ts @@ -0,0 +1,90 @@ +import type { Request } from '@sveltejs/kit'; +import Deployment from '$models/Logs/Deployment'; +import { docker } from '$lib/api/docker'; +import { precheckDeployment, setDefaultConfiguration } from '$lib/api/applications/configuration'; +import cloneRepository from '$lib/api/applications/cloneRepository'; +import { cleanupTmp } from '$lib/api/common'; +import queueAndBuild from '$lib/api/applications/queueAndBuild'; +export async function post(request: Request) { + let configuration; + try { + const services = (await docker.engine.listServices()).filter( + (r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' + ); + configuration = setDefaultConfiguration(request.body); + + if (!configuration) { + return { + status: 500, + body: { + error: 'Whaaat?' + } + }; + } + await cloneRepository(configuration); + const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ + services, + configuration + }); + if (foundService && !forceUpdate && !imageChanged && !configChanged) { + cleanupTmp(configuration.general.workdir); + return { + status: 200, + body: { + success: false, + message: 'Nothing changed, no need to redeploy.' + } + }; + } + const alreadyQueued = await Deployment.find({ + 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.' + } + }; + } + queueAndBuild(configuration, imageChanged); + return { + status: 200, + body: { + message: 'Deployment queued.', + nickname: configuration.general.nickname, + name: configuration.build.container.name, + deployId: configuration.general.deployId + } + }; + } catch (error) { + await Deployment.findOneAndUpdate( + { + 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 { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/application/deploy/logs/[deployId].ts b/src/routes/api/v1/application/deploy/logs/[deployId].ts new file mode 100644 index 0000000000..8a1d37d662 --- /dev/null +++ b/src/routes/api/v1/application/deploy/logs/[deployId].ts @@ -0,0 +1,35 @@ +import type { Request } from '@sveltejs/kit'; +import ApplicationLog from '$models/Logs/Application'; +import Deployment from '$models/Logs/Deployment'; +import dayjs from 'dayjs'; + +export async function get(request: Request) { + const { deployId } = request.params; + try { + const logs: any = await ApplicationLog.find({ deployId }) + .select('-_id -__v') + .sort({ createdAt: 'asc' }); + + const deploy: any = await Deployment.findOne({ deployId }) + .select('-_id -__v') + .sort({ createdAt: 'desc' }); + + const finalLogs: any = {}; + finalLogs.progress = deploy.progress; + finalLogs.events = logs.map((log) => log.event); + finalLogs.human = dayjs(deploy.updatedAt).from(dayjs(deploy.updatedAt)); + return { + status: 200, + body: { + ...finalLogs + } + }; + } catch (e) { + return { + status: 500, + body: { + error: e + } + }; + } +} diff --git a/src/routes/api/v1/application/deploy/logs/index.ts b/src/routes/api/v1/application/deploy/logs/index.ts new file mode 100644 index 0000000000..3308e1b0de --- /dev/null +++ b/src/routes/api/v1/application/deploy/logs/index.ts @@ -0,0 +1,47 @@ +import type { Request } from '@sveltejs/kit'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc.js'; +import relativeTime from 'dayjs/plugin/relativeTime.js'; +import Deployment from '$models/Logs/Deployment'; +dayjs.extend(utc); +dayjs.extend(relativeTime); +export async function get(request: Request) { + try { + const repoId = request.query.get('repoId'); + const branch = request.query.get('branch'); + const page = request.query.get('page'); + + const onePage = 5; + const show = Number(page) * onePage || 5; + const deploy: any = await Deployment.find({ repoId, branch }) + .select('-_id -__v -repoId') + .sort({ createdAt: 'desc' }) + .limit(show); + + const finalLogs = deploy.map((d) => { + const finalLogs = { ...d._doc }; + + const updatedAt = dayjs(d.updatedAt).utc(); + + finalLogs.took = updatedAt.diff(dayjs(d.createdAt)) / 1000; + finalLogs.since = updatedAt.fromNow(); + + return finalLogs; + }); + return { + status: 200, + body: { + success: true, + logs: finalLogs + } + }; + } catch (error) { + console.log(error); + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/application/logs.ts b/src/routes/api/v1/application/logs.ts new file mode 100644 index 0000000000..b39ae1d866 --- /dev/null +++ b/src/routes/api/v1/application/logs.ts @@ -0,0 +1,27 @@ +import { saveServerLog } from '$lib/api/applications/logging'; +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; + +export async function get(request: Request) { + try { + const name = request.query.get('name'); + const service = await docker.engine.getService(`${name}_${name}`); + const logs = (await service.logs({ stdout: true, stderr: true, timestamps: true })) + .toString() + .split('\n') + .map((l) => l.slice(8)) + .filter((a) => a); + return { + status: 200, + body: { success: true, logs } + }; + } catch (error) { + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/application/remove.ts b/src/routes/api/v1/application/remove.ts new file mode 100644 index 0000000000..9e1067fc2c --- /dev/null +++ b/src/routes/api/v1/application/remove.ts @@ -0,0 +1,60 @@ +import { purgeImagesContainers } from '$lib/api/applications/cleanup'; +import { docker } from '$lib/api/docker'; +import Deployment from '$models/Logs/Deployment'; +import ApplicationLog from '$models/Logs/Application'; +import { delay, execShellAsync } from '$lib/api/common'; + +async function call(found) { + await delay(10000); + await purgeImagesContainers(found, true); +} +export async function post(request: Request) { + const { organization, name, branch } = request.body; + let found = false; + try { + (await docker.engine.listServices()) + .filter((r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application') + .map((s) => { + const running = JSON.parse(s.Spec.Labels.configuration); + if ( + running.repository.organization === organization && + running.repository.name === name && + running.repository.branch === branch + ) { + found = running; + } + return null; + }); + if (found) { + const deploys = await Deployment.find({ organization, branch, name }); + for (const deploy of deploys) { + await ApplicationLog.deleteMany({ deployId: deploy.deployId }); + await Deployment.deleteMany({ deployId: deploy.deployId }); + } + await execShellAsync(`docker stack rm ${found.build.container.name}`); + call(found); + return { + status: 200, + body: { + organization, + name, + branch + } + }; + } else { + return { + status: 500, + error: { + message: 'Nothing to do.' + } + }; + } + } catch (error) { + return { + status: 500, + error: { + message: 'Nothing to do.' + } + }; + } +} diff --git a/src/routes/api/v1/dashboard.ts b/src/routes/api/v1/dashboard.ts new file mode 100644 index 0000000000..c199508e3b --- /dev/null +++ b/src/routes/api/v1/dashboard.ts @@ -0,0 +1,76 @@ +import { docker } from '$lib/api/docker'; +import LogsServer from '$models/Logs/Server'; +import type { Request } from '@sveltejs/kit'; + +export async function get(request: Request) { + const serverLogs = await LogsServer.find(); + const dockerServices = await docker.engine.listServices(); + let applications: any = dockerServices.filter( + (r) => + r.Spec.Labels.managedBy === 'coolify' && + r.Spec.Labels.type === 'application' && + r.Spec.Labels.configuration + ); + let databases: any = dockerServices.filter( + (r) => + r.Spec.Labels.managedBy === 'coolify' && + r.Spec.Labels.type === 'database' && + r.Spec.Labels.configuration + ); + let services: any = dockerServices.filter( + (r) => + r.Spec.Labels.managedBy === 'coolify' && + r.Spec.Labels.type === 'service' && + r.Spec.Labels.configuration + ); + applications = applications.map((r) => { + if (JSON.parse(r.Spec.Labels.configuration)) { + return { + configuration: JSON.parse(r.Spec.Labels.configuration), + UpdatedAt: r.UpdatedAt + }; + } + return {}; + }); + databases = databases.map((r) => { + if (JSON.parse(r.Spec.Labels.configuration)) { + return { + configuration: JSON.parse(r.Spec.Labels.configuration) + }; + } + return {}; + }); + services = services.map((r) => { + if (JSON.parse(r.Spec.Labels.configuration)) { + return { + serviceName: r.Spec.Labels.serviceName, + configuration: JSON.parse(r.Spec.Labels.configuration) + }; + } + return {}; + }); + applications = [ + ...new Map( + applications.map((item) => [ + item.configuration.publish.domain + item.configuration.publish.path, + item + ]) + ).values() + ]; + return { + status: 200, + body: { + success: true, + serverLogs, + applications: { + deployed: applications + }, + databases: { + deployed: databases + }, + services: { + deployed: services + } + } + }; +} diff --git a/src/routes/api/v1/databases/[deployId]/backup.ts b/src/routes/api/v1/databases/[deployId]/backup.ts new file mode 100644 index 0000000000..1762a9b2ee --- /dev/null +++ b/src/routes/api/v1/databases/[deployId]/backup.ts @@ -0,0 +1,122 @@ +import type { Request } from '@sveltejs/kit'; +import { saveServerLog } from '$lib/api/applications/logging'; +import { execShellAsync } from '$lib/api/common'; +import { docker } from '$lib/api/docker'; +import fs from 'fs'; + +export async function post(request: Request) { + const tmpdir = '/tmp/backups'; + const { deployId } = request.params; + try { + const now = new Date(); + const configuration = JSON.parse( + JSON.parse(await execShellAsync(`docker inspect ${deployId}_${deployId}`))[0].Spec.Labels + .configuration + ); + const type = configuration.general.type; + const serviceId = configuration.general.deployId; + const databaseService = (await docker.engine.listContainers()).find( + (r) => r.Labels['com.docker.stack.namespace'] === serviceId && r.State === 'running' + ); + const containerID = databaseService.Labels['com.docker.swarm.task.name']; + await execShellAsync(`mkdir -p ${tmpdir}`); + if (type === 'mongodb') { + if (databaseService) { + const username = configuration.database.usernames[0]; + const password = configuration.database.passwords[1]; + const databaseName = configuration.database.defaultDatabaseName; + const filename = `${databaseName}_${now.getTime()}.gz`; + const fullfilename = `${tmpdir}/${filename}`; + await execShellAsync( + `docker exec -i ${containerID} /bin/bash -c "mkdir -p ${tmpdir};mongodump --uri='mongodb://${username}:${password}@${deployId}:27017' -d ${databaseName} --gzip --archive=${fullfilename}"` + ); + await execShellAsync(`docker cp ${containerID}:${fullfilename} ${fullfilename}`); + await execShellAsync(`docker exec -i ${containerID} /bin/bash -c "rm -f ${fullfilename}"`); + return { + status: 200, + headers: { + 'Content-Type': 'application/octet-stream', + 'Content-Transfer-Encoding': 'binary', + 'Content-Disposition': `attachment; filename=${filename}` + }, + body: fs.readFileSync(`${fullfilename}`) + }; + } + } else if (type === 'postgresql') { + if (databaseService) { + const username = configuration.database.usernames[0]; + const password = configuration.database.passwords[0]; + const databaseName = configuration.database.defaultDatabaseName; + const filename = `${databaseName}_${now.getTime()}.sql.gz`; + const fullfilename = `${tmpdir}/${filename}`; + await execShellAsync( + `docker exec -i ${containerID} /bin/bash -c "PGPASSWORD=${password} pg_dump --username ${username} -Z 9 ${databaseName}" > ${fullfilename}` + ); + return { + status: 200, + headers: { + 'Content-Type': 'application/octet-stream', + 'Content-Transfer-Encoding': 'binary', + 'Content-Disposition': `attachment; filename=${filename}` + }, + body: fs.readFileSync(`${fullfilename}`) + }; + } + } else if (type === 'couchdb') { + if (databaseService) { + const databaseName = configuration.database.defaultDatabaseName; + const filename = `${databaseName}_${now.getTime()}.tar.gz`; + const fullfilename = `${tmpdir}/${filename}`; + await execShellAsync( + `docker exec -i ${containerID} /bin/bash -c "cd /bitnami/couchdb/data/ && tar -czvf - ." > ${fullfilename}` + ); + return { + status: 200, + headers: { + 'Content-Type': 'application/octet-stream', + 'Content-Transfer-Encoding': 'binary', + 'Content-Disposition': `attachment; filename=${filename}` + }, + body: fs.readFileSync(`${fullfilename}`) + }; + } + } else if (type === 'mysql') { + if (databaseService) { + const username = configuration.database.usernames[0]; + const password = configuration.database.passwords[0]; + const databaseName = configuration.database.defaultDatabaseName; + const filename = `${databaseName}_${now.getTime()}.sql.gz`; + const fullfilename = `${tmpdir}/${filename}`; + await execShellAsync( + `docker exec -i ${containerID} /bin/bash -c "mysqldump -u ${username} -p${password} ${databaseName} | gzip -9 -" > ${fullfilename}` + ); + return { + status: 200, + headers: { + 'Content-Type': 'application/octet-stream', + 'Content-Transfer-Encoding': 'binary', + 'Content-Disposition': `attachment; filename=${filename}` + }, + body: fs.readFileSync(`${fullfilename}`) + }; + } + } + return { + status: 501, + body: { + error: `Backup method not implemented yet for ${type}.` + } + }; + } catch (error) { + console.log(error); + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } finally { + await execShellAsync(`rm -fr ${tmpdir}`); + } +} diff --git a/src/routes/api/v1/databases/[deployId]/index.ts b/src/routes/api/v1/databases/[deployId]/index.ts new file mode 100644 index 0000000000..a7a5ab7ab5 --- /dev/null +++ b/src/routes/api/v1/databases/[deployId]/index.ts @@ -0,0 +1,59 @@ +import { execShellAsync } from '$lib/api/common'; +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; + +export async function del(request: Request) { + const { deployId } = request.params; + await execShellAsync(`docker stack rm ${deployId}`); + return { + status: 200, + body: {} + }; +} +export async function get(request: Request) { + const { deployId } = request.params; + + try { + const database = (await docker.engine.listServices()).find( + (r) => + r.Spec.Labels.managedBy === 'coolify' && + r.Spec.Labels.type === 'database' && + JSON.parse(r.Spec.Labels.configuration).general.deployId === deployId + ); + + if (database) { + const jsonEnvs = {}; + if (database.Spec.TaskTemplate.ContainerSpec.Env) { + for (const d of database.Spec.TaskTemplate.ContainerSpec.Env) { + const s = d.split('='); + jsonEnvs[s[0]] = s[1]; + } + } + const payload = { + config: JSON.parse(database.Spec.Labels.configuration), + envs: jsonEnvs || null + }; + + return { + status: 200, + body: { + ...payload + } + }; + } else { + return { + status: 500, + body: { + error: 'No database found.' + } + }; + } + } catch (error) { + return { + status: 500, + body: { + error: 'No database found.' + } + }; + } +} diff --git a/src/routes/api/v1/databases/deploy.ts b/src/routes/api/v1/databases/deploy.ts new file mode 100644 index 0000000000..ea2aa40947 --- /dev/null +++ b/src/routes/api/v1/databases/deploy.ts @@ -0,0 +1,161 @@ +import { saveServerLog } from '$lib/api/applications/logging'; +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; +import yaml from 'js-yaml'; +import { promises as fs } from 'fs'; +import cuid from 'cuid'; +import generator from 'generate-password'; +import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator'; +import { execShellAsync } from '$lib/api/common'; + +function getUniq() { + return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 }); +} + +export async function post(request: Request) { + try { + const { type } = request.body; + let { defaultDatabaseName } = request.body; + const passwords = generator.generateMultiple(2, { + length: 24, + numbers: true, + strict: true + }); + const usernames = generator.generateMultiple(2, { + length: 10, + numbers: true, + strict: true + }); + // TODO: Query for existing db with the same name + const nickname = getUniq(); + + if (!defaultDatabaseName) defaultDatabaseName = nickname; + + const deployId = cuid(); + const configuration = { + general: { + workdir: `/tmp/${deployId}`, + deployId, + nickname, + type + }, + database: { + usernames, + passwords, + defaultDatabaseName + }, + deploy: { + name: nickname + } + }; + await execShellAsync(`mkdir -p ${configuration.general.workdir}`); + let generateEnvs = {}; + let image = null; + let volume = null; + let ulimits = {}; + if (type === 'mongodb') { + generateEnvs = { + MONGODB_ROOT_PASSWORD: passwords[0], + MONGODB_USERNAME: usernames[0], + MONGODB_PASSWORD: passwords[1], + MONGODB_DATABASE: defaultDatabaseName + }; + image = 'bitnami/mongodb:4.4'; + volume = `${configuration.general.deployId}-${type}-data:/bitnami/mongodb`; + } else if (type === 'postgresql') { + generateEnvs = { + POSTGRESQL_PASSWORD: passwords[0], + POSTGRESQL_USERNAME: usernames[0], + POSTGRESQL_DATABASE: defaultDatabaseName + }; + image = 'bitnami/postgresql:13.2.0'; + volume = `${configuration.general.deployId}-${type}-data:/bitnami/postgresql`; + } else if (type === 'couchdb') { + generateEnvs = { + COUCHDB_PASSWORD: passwords[0], + COUCHDB_USER: usernames[0] + }; + image = 'bitnami/couchdb:3'; + volume = `${configuration.general.deployId}-${type}-data:/bitnami/couchdb`; + } else if (type === 'mysql') { + generateEnvs = { + MYSQL_ROOT_PASSWORD: passwords[0], + MYSQL_ROOT_USER: usernames[0], + MYSQL_USER: usernames[1], + MYSQL_PASSWORD: passwords[1], + MYSQL_DATABASE: defaultDatabaseName + }; + image = 'bitnami/mysql:8.0'; + volume = `${configuration.general.deployId}-${type}-data:/bitnami/mysql/data`; + } else if (type === 'clickhouse') { + image = 'yandex/clickhouse-server'; + volume = `${configuration.general.deployId}-${type}-data:/var/lib/clickhouse`; + ulimits = { + nofile: { + soft: 262144, + hard: 262144 + } + }; + } + + const stack = { + version: '3.8', + services: { + [configuration.general.deployId]: { + image, + networks: [`${docker.network}`], + environment: generateEnvs, + volumes: [volume], + ulimits, + deploy: { + replicas: 1, + update_config: { + parallelism: 0, + delay: '10s', + order: 'start-first' + }, + rollback_config: { + parallelism: 0, + delay: '10s', + order: 'start-first' + }, + labels: [ + 'managedBy=coolify', + 'type=database', + 'configuration=' + JSON.stringify(configuration) + ] + } + } + }, + networks: { + [`${docker.network}`]: { + external: true + } + }, + volumes: { + [`${configuration.general.deployId}-${type}-data`]: { + external: true + } + } + }; + await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack)); + await execShellAsync( + `cat ${configuration.general.workdir}/stack.yml | docker stack deploy -c - ${configuration.general.deployId}` + ); + return { + status: 201, + body: { + message: 'Deployed.' + } + }; + } catch (error) { + console.log(error); + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/login/github/app.ts b/src/routes/api/v1/login/github/app.ts new file mode 100644 index 0000000000..e0df7e996d --- /dev/null +++ b/src/routes/api/v1/login/github/app.ts @@ -0,0 +1,110 @@ +import { githubAPI } from '$api'; +import type { Request } from '@sveltejs/kit'; +import mongoose from 'mongoose'; +import User from '$models/User'; +import Settings from '$models/Settings'; +import cuid from 'cuid'; +import jsonwebtoken from 'jsonwebtoken'; + +export async function get(request: Request) { + const code = request.query.get('code'); + const { GITHUB_APP_CLIENT_SECRET, JWT_SIGN_KEY, VITE_GITHUB_APP_CLIENTID } = process.env; + try { + let uid = cuid(); + const { access_token } = await ( + await fetch( + `https://github.com/login/oauth/access_token?client_id=${VITE_GITHUB_APP_CLIENTID}&client_secret=${GITHUB_APP_CLIENT_SECRET}&code=${code}`, + { headers: { accept: 'application/json' } } + ) + ).json(); + const { avatar_url, id } = await (await githubAPI(request, '/user', access_token)).body; + const email = (await githubAPI(request, '/user/emails', access_token)).body.filter( + (e) => e.primary + )[0].email; + const settings = await Settings.findOne({ applicationName: 'coolify' }); + const registeredUsers = await User.find().countDocuments(); + const foundUser = await User.findOne({ email }); + if (foundUser) { + await User.findOneAndUpdate({ email }, { avatar: avatar_url }, { upsert: true, new: true }); + uid = foundUser.uid; + } else { + if (registeredUsers === 0) { + const newUser = new User({ + _id: new mongoose.Types.ObjectId(), + email, + avatar: avatar_url, + uid + }); + const defaultSettings = new Settings({ + _id: new mongoose.Types.ObjectId() + }); + try { + await newUser.save(); + await defaultSettings.save(); + } catch (e) { + console.log(e); + return { + status: 500, + body: e + }; + } + } else { + if (!settings && registeredUsers > 0) { + return { + status: 500, + body: { + error: 'Registration disabled, enable it in settings.' + } + }; + } else { + if (!settings.allowRegistration) { + return { + status: 500, + body: { + error: 'You are not allowed here!' + } + }; + } else { + const newUser = new User({ + _id: new mongoose.Types.ObjectId(), + email, + avatar: avatar_url, + uid + }); + try { + await newUser.save(); + } catch (e) { + console.log(e); + return { + status: 500, + body: { + error: e + } + }; + } + } + } + } + } + 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: access_token }; + return { + status: 302, + headers: { + location: `/success` + } + }; + } catch (error) { + console.log('error happened'); + console.log(error); + return { status: 500, body: { ...error } }; + } +} diff --git a/src/routes/api/v1/logout.ts b/src/routes/api/v1/logout.ts new file mode 100644 index 0000000000..e51bcab4f7 --- /dev/null +++ b/src/routes/api/v1/logout.ts @@ -0,0 +1,10 @@ +import type { Request } from '@sveltejs/kit'; +export async function del(request: Request) { + request.locals.session.destroy = true; + + return { + body: { + ok: true + } + }; +} diff --git a/src/routes/api/v1/services/[serviceName].ts b/src/routes/api/v1/services/[serviceName].ts new file mode 100644 index 0000000000..007ffeedc1 --- /dev/null +++ b/src/routes/api/v1/services/[serviceName].ts @@ -0,0 +1,52 @@ +import { execShellAsync } from '$lib/api/common'; +import { docker } from '$lib/api/docker'; +import type { Request } from '@sveltejs/kit'; + +export async function get(request: Request) { + const { serviceName } = request.params; + try { + const service = (await docker.engine.listServices()).find( + (r) => + r.Spec.Labels.managedBy === 'coolify' && + r.Spec.Labels.type === 'service' && + r.Spec.Labels.serviceName === serviceName && + r.Spec.Name === `${serviceName}_${serviceName}` + ); + if (service) { + const payload = { + config: JSON.parse(service.Spec.Labels.configuration) + }; + return { + status: 200, + body: { + success: true, + ...payload + } + }; + } else { + return { + status: 200, + body: { + success: false, + showToast: false, + message: 'Not found' + } + }; + } + } catch (error) { + console.log(error); + return { + status: 500, + body: { + success: false, + error + } + }; + } +} + +export async function del(request: Request) { + const { serviceName } = request.params; + await execShellAsync(`docker stack rm ${serviceName}`); + return { status: 200, body: {} }; +} diff --git a/src/routes/api/v1/services/deploy/plausible/activate.ts b/src/routes/api/v1/services/deploy/plausible/activate.ts new file mode 100644 index 0000000000..420aa43d15 --- /dev/null +++ b/src/routes/api/v1/services/deploy/plausible/activate.ts @@ -0,0 +1,24 @@ +import { execShellAsync } from '$lib/api/common'; +import type { Request } from '@sveltejs/kit'; + +export async function patch(request: Request) { + const { POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, POSTGRESQL_DATABASE } = JSON.parse( + JSON.parse( + await execShellAsync( + "docker service inspect plausible_plausible --format='{{json .Spec.Labels.configuration}}'" + ) + ) + ).generateEnvsPostgres; + const containers = (await execShellAsync("docker ps -a --format='{{json .Names}}'")) + .replace(/"/g, '') + .trim() + .split('\n'); + const postgresDB = containers.find((container) => container.startsWith('plausible_plausible_db')); + await execShellAsync( + `docker exec ${postgresDB} psql -H postgresql://${POSTGRESQL_USERNAME}:${POSTGRESQL_PASSWORD}@localhost:5432/${POSTGRESQL_DATABASE} -c "UPDATE users SET email_verified = true;"` + ); + return { + status: 200, + body: { message: 'OK' } + }; +} diff --git a/src/routes/api/v1/services/deploy/plausible/index.ts b/src/routes/api/v1/services/deploy/plausible/index.ts new file mode 100644 index 0000000000..c67f0cb14a --- /dev/null +++ b/src/routes/api/v1/services/deploy/plausible/index.ts @@ -0,0 +1,187 @@ +import type { Request } from '@sveltejs/kit'; +import generator from 'generate-password'; +import { promises as fs } from 'fs'; +import yaml from 'js-yaml'; +import { docker } from '$lib/api/docker'; +import { baseServiceConfiguration } from '$lib/api/applications/common'; +import { cleanupTmp, execShellAsync } from '$lib/api/common'; + +export async function post(request: Request) { + const { email, userName, userPassword } = request.body; + let { baseURL } = request.body; + const traefikURL = baseURL; + baseURL = `https://${baseURL}`; + const deployId = 'plausible'; + const workdir = '/tmp/plausible'; + const secretKey = generator.generate({ length: 64, numbers: true, strict: true }); + const generateEnvsPostgres = { + POSTGRESQL_PASSWORD: generator.generate({ length: 24, numbers: true, strict: true }), + POSTGRESQL_USERNAME: generator.generate({ length: 10, numbers: true, strict: true }), + POSTGRESQL_DATABASE: 'plausible' + }; + + const secrets = [ + { name: 'ADMIN_USER_EMAIL', value: email }, + { name: 'ADMIN_USER_NAME', value: userName }, + { name: 'ADMIN_USER_PWD', value: userPassword }, + { name: 'BASE_URL', value: baseURL }, + { name: 'SECRET_KEY_BASE', value: secretKey }, + { name: 'DISABLE_AUTH', value: 'false' }, + { name: 'DISABLE_REGISTRATION', value: 'true' }, + { + name: 'DATABASE_URL', + value: `postgresql://${generateEnvsPostgres.POSTGRESQL_USERNAME}:${generateEnvsPostgres.POSTGRESQL_PASSWORD}@plausible_db:5432/${generateEnvsPostgres.POSTGRESQL_DATABASE}` + }, + { name: 'CLICKHOUSE_DATABASE_URL', value: 'http://plausible_events_db:8123/plausible' } + ]; + + const generateEnvsClickhouse = {}; + for (const secret of secrets) generateEnvsClickhouse[secret.name] = secret.value; + + const clickhouseConfigXml = ` + + + warning + true + + + + + + + + + + `; + const clickhouseUserConfigXml = ` + + + + 0 + 0 + + + `; + + const clickhouseConfigs = [ + { + source: 'plausible-clickhouse-user-config.xml', + target: '/etc/clickhouse-server/users.d/logging.xml' + }, + { + source: 'plausible-clickhouse-config.xml', + target: '/etc/clickhouse-server/config.d/logging.xml' + }, + { source: 'plausible-init.query', target: '/docker-entrypoint-initdb.d/init.query' }, + { source: 'plausible-init-db.sh', target: '/docker-entrypoint-initdb.d/init-db.sh' } + ]; + + const initQuery = 'CREATE DATABASE IF NOT EXISTS plausible;'; + const initScript = 'clickhouse client --queries-file /docker-entrypoint-initdb.d/init.query'; + await execShellAsync(`mkdir -p ${workdir}`); + await fs.writeFile(`${workdir}/clickhouse-config.xml`, clickhouseConfigXml); + await fs.writeFile(`${workdir}/clickhouse-user-config.xml`, clickhouseUserConfigXml); + await fs.writeFile(`${workdir}/init.query`, initQuery); + await fs.writeFile(`${workdir}/init-db.sh`, initScript); + const stack = { + version: '3.8', + services: { + [deployId]: { + image: 'plausible/analytics:latest', + command: + 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run"', + networks: [`${docker.network}`], + volumes: [`${deployId}-postgres-data:/var/lib/postgresql/data`], + environment: generateEnvsClickhouse, + deploy: { + ...baseServiceConfiguration, + labels: [ + 'managedBy=coolify', + 'type=service', + 'serviceName=plausible', + 'configuration=' + + JSON.stringify({ + email, + userName, + userPassword, + baseURL, + secretKey, + generateEnvsPostgres, + generateEnvsClickhouse + }), + 'traefik.enable=true', + 'traefik.http.services.' + deployId + '.loadbalancer.server.port=8000', + 'traefik.http.routers.' + deployId + '.entrypoints=websecure', + 'traefik.http.routers.' + + deployId + + '.rule=Host(`' + + traefikURL + + '`) && PathPrefix(`/`)', + 'traefik.http.routers.' + deployId + '.tls.certresolver=letsencrypt', + 'traefik.http.routers.' + deployId + '.middlewares=global-compress' + ] + } + }, + plausible_db: { + image: 'bitnami/postgresql:13.2.0', + networks: [`${docker.network}`], + environment: generateEnvsPostgres, + deploy: { + ...baseServiceConfiguration, + labels: ['managedBy=coolify', 'type=service', 'serviceName=plausible'] + } + }, + plausible_events_db: { + image: 'yandex/clickhouse-server:21.3.2.5', + networks: [`${docker.network}`], + volumes: [`${deployId}-clickhouse-data:/var/lib/clickhouse`], + ulimits: { + nofile: { + soft: 262144, + hard: 262144 + } + }, + configs: [...clickhouseConfigs], + deploy: { + ...baseServiceConfiguration, + labels: ['managedBy=coolify', 'type=service', 'serviceName=plausible'] + } + } + }, + networks: { + [`${docker.network}`]: { + external: true + } + }, + volumes: { + [`${deployId}-clickhouse-data`]: { + external: true + }, + [`${deployId}-postgres-data`]: { + external: true + } + }, + configs: { + 'plausible-clickhouse-user-config.xml': { + file: `${workdir}/clickhouse-user-config.xml` + }, + 'plausible-clickhouse-config.xml': { + file: `${workdir}/clickhouse-config.xml` + }, + 'plausible-init.query': { + file: `${workdir}/init.query` + }, + 'plausible-init-db.sh': { + file: `${workdir}/init-db.sh` + } + } + }; + await fs.writeFile(`${workdir}/stack.yml`, yaml.dump(stack)); + await execShellAsync('docker stack rm plausible'); + await execShellAsync(`cat ${workdir}/stack.yml | docker stack deploy --prune -c - ${deployId}`); + cleanupTmp(workdir); + return { + status: 200, + body: { message: 'OK' } + }; +} diff --git a/src/routes/api/v1/settings.ts b/src/routes/api/v1/settings.ts new file mode 100644 index 0000000000..759c838688 --- /dev/null +++ b/src/routes/api/v1/settings.ts @@ -0,0 +1,52 @@ +import { saveServerLog } from '$lib/api/applications/logging'; +import Settings from '$models/Settings'; +import type { Request } from '@sveltejs/kit'; +const applicationName = 'coolify'; + +export async function get(request: Request) { + try { + const settings = await Settings.findOne({ applicationName }).select('-_id -__v'); + const payload = { + applicationName, + allowRegistration: false, + ...settings._doc + }; + return { + status: 200, + body: { + ...payload + } + }; + } catch (error) { + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } +} +export async function post(request: Request) { + try { + const settings = await Settings.findOneAndUpdate( + { applicationName }, + { applicationName, ...request.body }, + { upsert: true, new: true } + ).select('-_id -__v'); + return { + status: 201, + body: { + ...settings._doc + } + }; + } catch (error) { + await saveServerLog(error); + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/api/v1/upgrade.ts b/src/routes/api/v1/upgrade.ts new file mode 100644 index 0000000000..874d2a2ca2 --- /dev/null +++ b/src/routes/api/v1/upgrade.ts @@ -0,0 +1,20 @@ +import { saveServerLog } from '$lib/api/applications/logging'; +import { execShellAsync } from '$lib/api/common'; +import type { Request } from '@sveltejs/kit'; + +export async function get(request: Request) { + const upgradeP1 = await execShellAsync( + 'bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p1.sh)"' + ); + await saveServerLog({ message: upgradeP1, type: 'UPGRADE-P-1' }); + execShellAsync( + 'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -u root coolify bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p2.sh)"' + ); + // saveServerLog({ message: upgradeP2, type: 'UPGRADE-P-2' }) + return { + status: 200, + body: { + message: "I'm trying, okay?" + } + }; +} diff --git a/src/routes/api/v1/verify.ts b/src/routes/api/v1/verify.ts new file mode 100644 index 0000000000..3e56b48751 --- /dev/null +++ b/src/routes/api/v1/verify.ts @@ -0,0 +1,24 @@ +// import { deleteCookies } from '$lib/api/common'; +// import { verifyUserId } from '$lib/api/common'; +// import type { Request } from '@sveltejs/kit'; +// import * as cookie from 'cookie'; + +// export async function post(request: Request) { +// const { coolToken } = cookie.parse(request.headers.cookie || ''); +// try { +// await verifyUserId(coolToken); +// return { +// status: 200, +// body: { success: true } +// }; +// } catch (error) { +// return { +// status: 301, +// headers: { +// location: '/', +// 'set-cookie': [...deleteCookies] +// }, +// body: { error: 'Unauthorized' } +// }; +// } +// } diff --git a/src/routes/api/v1/webhooks/deploy.ts b/src/routes/api/v1/webhooks/deploy.ts new file mode 100644 index 0000000000..b84b09f5ea --- /dev/null +++ b/src/routes/api/v1/webhooks/deploy.ts @@ -0,0 +1,113 @@ +import type { Request } from '@sveltejs/kit'; +import crypto from 'crypto'; +import Deployment from '$models/Logs/Deployment'; +import { docker } from '$lib/api/docker'; +import { precheckDeployment, setDefaultConfiguration } from '$lib/api/applications/configuration'; +import cloneRepository from '$lib/api/applications/cloneRepository'; +import { cleanupTmp } from '$lib/api/common'; +import queueAndBuild from '$lib/api/applications/queueAndBuild'; +export async function post(request: Request) { + let configuration; + const { GITHUP_APP_WEBHOOK_SECRET } = process.env; + const hmac = crypto.createHmac('sha256', GITHUP_APP_WEBHOOK_SECRET); + const digest = Buffer.from( + 'sha256=' + hmac.update(JSON.stringify(request.body)).digest('hex'), + 'utf8' + ); + const checksum = Buffer.from(request.headers['x-hub-signature-256'], 'utf8'); + if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) { + return { + status: 500, + body: { + error: 'Invalid request' + } + }; + } + + if (request.headers['x-github-event'] !== 'push') { + return { + status: 500, + body: { + error: 'Not a push event.' + } + }; + } + try { + const services = (await docker.engine.listServices()).filter( + (r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' + ); + + configuration = services.find((r) => { + if (request.body.ref.startsWith('refs')) { + const branch = request.body.ref.split('/')[2]; + if ( + JSON.parse(r.Spec.Labels.configuration).repository.id === request.body.repository.id && + JSON.parse(r.Spec.Labels.configuration).repository.branch === branch + ) { + return r; + } + } + + return null; + }); + configuration = setDefaultConfiguration(JSON.parse(configuration.Spec.Labels.configuration)); + + if (!configuration) { + return { + status: 500, + body: { + error: 'Whaaat?' + } + }; + } + await cloneRepository(configuration); + const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ + services, + configuration + }); + if (foundService && !forceUpdate && !imageChanged && !configChanged) { + cleanupTmp(configuration.general.workdir); + return { + status: 200, + body: { + success: false, + message: 'Nothing changed, no need to redeploy.' + } + }; + } + const alreadyQueued = await Deployment.find({ + 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.' + } + }; + } + queueAndBuild(configuration, imageChanged); + return { + status: 201, + body: { + message: 'Deployment queued.', + nickname: configuration.general.nickname, + name: configuration.build.container.name, + deployId: configuration.general.deployId + } + }; + } catch (error) { + return { + status: 500, + body: { + error + } + }; + } +} diff --git a/src/routes/application/[organization]/[name]/[branch]/configuration.svelte b/src/routes/application/[organization]/[name]/[branch]/configuration.svelte new file mode 100644 index 0000000000..9e90cf014d --- /dev/null +++ b/src/routes/application/[organization]/[name]/[branch]/configuration.svelte @@ -0,0 +1,6 @@ + + + diff --git a/src/routes/application/[organization]/[name]/[branch]/logs/[deployId].svelte b/src/routes/application/[organization]/[name]/[branch]/logs/[deployId].svelte new file mode 100644 index 0000000000..d40fb8976b --- /dev/null +++ b/src/routes/application/[organization]/[name]/[branch]/logs/[deployId].svelte @@ -0,0 +1,83 @@ + + +
+
Deployment log
+ + + + +
+{#await loadLogs()} + +{:then} +
+
+
+      {#if logs.length > 0}
+        {#each logs as log}
+          {log + '\n'}
+        {/each}
+      {:else}
+        It's starting soon.
+      {/if}
+    
+
+
+{/await} diff --git a/src/routes/application/[organization]/[name]/[branch]/logs/index.svelte b/src/routes/application/[organization]/[name]/[branch]/logs/index.svelte new file mode 100644 index 0000000000..620a6084e6 --- /dev/null +++ b/src/routes/application/[organization]/[name]/[branch]/logs/index.svelte @@ -0,0 +1,135 @@ + + +
+
Logs
+
+{#await loadDeploymentLogs()} + +{:then} +
+
+
+
Application logs
+ {#if logs.length === 0} +
Waiting for the logs...
+ {:else} +
+            {#each logs as log}
+              {log + '\n'}
+            {/each}
+          
+ {/if} +
+
+
Deployment logs
+ {#if deployments.length > 0} +
+ {#each deployments as deployment} +
goto(`./logs/${deployment.deployId}`)} + > +
+ {deployment.branch} +
+
+
+
+ {deployment.since} +
+ {#if deployment.progress === 'done'} +
+ Deployed in {deployment.took}s +
+ {:else if deployment.progress === 'failed'} +
Failed
+ {:else} +
Deploying...
+ {/if} +
+
+ {/each} +
+ + {:else} +
No deployments found
+ {/if} +
+
+
+{:catch} +
No logs found
+{/await} + + diff --git a/src/routes/application/__layout.svelte b/src/routes/application/__layout.svelte new file mode 100644 index 0000000000..5a7a1617e5 --- /dev/null +++ b/src/routes/application/__layout.svelte @@ -0,0 +1,127 @@ + + +{#await loadConfiguration()} + +{:then} + +
+ {#if $page.path.endsWith('configuration')} +
+
+ {$application.publish.domain + ? `${$application.publish.domain}${ + $application.publish.path !== '/' ? $application.publish.path : '' + }` + : 'example.com'} + + + + + + + +
+
+ {:else if $page.path === '/application/new'} +
+
+ New Application +
+
+ {/if} + +
+{/await} diff --git a/src/routes/application/new.svelte b/src/routes/application/new.svelte new file mode 100644 index 0000000000..21d65c11e2 --- /dev/null +++ b/src/routes/application/new.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/dashboard/__layout.svelte b/src/routes/dashboard/__layout.svelte new file mode 100644 index 0000000000..23672d4725 --- /dev/null +++ b/src/routes/dashboard/__layout.svelte @@ -0,0 +1,44 @@ + + + + +
+ +
diff --git a/src/routes/dashboard/applications.svelte b/src/routes/dashboard/applications.svelte new file mode 100644 index 0000000000..859e0aae0d --- /dev/null +++ b/src/routes/dashboard/applications.svelte @@ -0,0 +1,299 @@ + + +
+
Applications
+ +
+
+ {#if $dashboard?.applications?.deployed.length > 0} +
+
+ {#each $dashboard.applications.deployed as application} +
+
{ + goto( + `/application/${application.configuration.repository.organization}/${application.configuration.repository.name}/${application.configuration.repository.branch}/configuration` + ); + }} + > +
+ {#if application.configuration.build.pack === 'static'} + + {:else if application.configuration.build.pack === 'react'} + + + + {:else if application.configuration.build.pack === 'gatsby'} + + + + {:else if application.configuration.build.pack === 'nuxtjs'} + + + + + + + + {:else if application.configuration.build.pack === 'svelte'} + + + + + {:else if application.configuration.build.pack === 'vuejs'} + + + + {:else if application.configuration.build.pack === 'nextjs'} + + + + {:else if application.configuration.build.pack === 'nodejs'} + + {:else if application.configuration.build.pack === 'php'} + + + + {:else if application.configuration.build.pack === 'docker'} + + + + {:else if application.configuration.build.pack === 'rust'} + + + + {/if} +
+
+ {application.configuration.publish.domain}{application.configuration.publish + .path !== '/' + ? application.configuration.publish.path + : ''} +
+
+ Last deployment
+ {new Intl.DateTimeFormat('default', dateOptions).format( + new Date(application.UpdatedAt) + )} +
+
+
+
+
+ {/each} +
+
+ {:else} +
No applications found
+ {/if} +
diff --git a/src/routes/dashboard/databases.svelte b/src/routes/dashboard/databases.svelte new file mode 100644 index 0000000000..fd6740915e --- /dev/null +++ b/src/routes/dashboard/databases.svelte @@ -0,0 +1,82 @@ + + +
+
Databases
+ +
+
+ {#if $dashboard.databases?.deployed.length > 0} +
+
+ {#each $dashboard.databases.deployed as database} +
+ goto(`/database/${database.configuration.general.deployId}/configuration`)} + > +
+
+ {#if database.configuration.general.type == 'mongodb'} + + {:else if database.configuration.general.type == 'postgresql'} + + {:else if database.configuration.general.type == 'mysql'} + + {:else if database.configuration.general.type == 'couchdb'} + + {:else if database.configuration.general.type == 'clickhouse'} + + {/if} +
+
+ {database.configuration.general.nickname} +
+
+ ({database.configuration.general.type}) +
+
+
+
+
+ {/each} +
+
+ {:else} +
No databases found
+ {/if} +
+ diff --git a/src/routes/dashboard/services.svelte b/src/routes/dashboard/services.svelte new file mode 100644 index 0000000000..2b66b57a4d --- /dev/null +++ b/src/routes/dashboard/services.svelte @@ -0,0 +1,62 @@ + + +
+
Services
+ +
+
+ {#if $dashboard?.services?.deployed.length > 0} +
+
+ {#each $dashboard?.services?.deployed as service} +
goto(`/service/${service.serviceName}/configuration`)} + > +
+
+ {#if service.serviceName == 'plausible'} +
+ plausible logo +
Plausible Analytics
+
+ {/if} +
+
+
+ {/each} +
+
+ {:else} +
No services found
+ {/if} +
diff --git a/src/routes/database/[name]/configuration.svelte b/src/routes/database/[name]/configuration.svelte new file mode 100644 index 0000000000..98dcdf8d47 --- /dev/null +++ b/src/routes/database/[name]/configuration.svelte @@ -0,0 +1,110 @@ + + +{#await loadDatabaseConfig()} + +{:then} +
+
+
{$database.config.general.nickname}
+
+ {#if $database.config.general.type === 'mongodb'} + + {:else if $database.config.general.type === 'postgresql'} + + {:else if $database.config.general.type === 'mysql'} + + {:else if $database.config.general.type === 'couchdb'} + + {/if} +
+
+
+
+
+
Database
+
+
Connection string
+ {#if $database.config.general.type === 'mongodb'} + + {:else if $database.config.general.type === 'postgresql'} + + {:else if $database.config.general.type === 'mysql'} + + {:else if $database.config.general.type === 'couchdb'} + + {:else if $database.config.general.type === 'clickhouse'} + + + {/if} +
+
+ {#if $database.config.general.type === 'mongodb'} +
+
Root password
+ +
+ {/if} +
+
Backup
+
+ +
+
+
+{/await} diff --git a/src/routes/database/__layout.svelte b/src/routes/database/__layout.svelte new file mode 100644 index 0000000000..dffeb9f50e --- /dev/null +++ b/src/routes/database/__layout.svelte @@ -0,0 +1,78 @@ + + +{#if $page.path !== '/database/new'} + +{/if} +
+ +
diff --git a/src/routes/database/new.svelte b/src/routes/database/new.svelte new file mode 100644 index 0000000000..4253673dc2 --- /dev/null +++ b/src/routes/database/new.svelte @@ -0,0 +1,11 @@ + + +
+
+ Select a database +
+
+ + diff --git a/src/routes/index.svelte b/src/routes/index.svelte new file mode 100644 index 0000000000..da48bf1ee4 --- /dev/null +++ b/src/routes/index.svelte @@ -0,0 +1,60 @@ + + +
+
+
+

+ Coolify +

+

+ An open-source, hassle-free, self-hostable
+ Heroku + & Netlify alternative +

+
+ {#if !$session.isLoggedIn} + + {:else} + + {/if} +
+
+
+
diff --git a/src/routes/service/[name]/__layout.svelte b/src/routes/service/[name]/__layout.svelte new file mode 100644 index 0000000000..116a120bc9 --- /dev/null +++ b/src/routes/service/[name]/__layout.svelte @@ -0,0 +1,71 @@ + + + + +
+ +
diff --git a/src/routes/service/[name]/configuration.svelte b/src/routes/service/[name]/configuration.svelte new file mode 100644 index 0000000000..d30e9aea5f --- /dev/null +++ b/src/routes/service/[name]/configuration.svelte @@ -0,0 +1,83 @@ + + +{#await loadServiceConfig()} + +{:then} +
+
+
{$page.params.name === 'plausible' ? 'Plausible Analytics' : $page.params.name}
+
+ {#if $page.params.name === 'plausible'} + plausible logo + {/if} +
+ + + + + + + +
+
+
+
+ {#if $page.params.name === 'plausible'} + + {/if} +
+
+{/await} diff --git a/src/routes/service/new/[type]/__layout.svelte b/src/routes/service/new/[type]/__layout.svelte new file mode 100644 index 0000000000..8465e82d74 --- /dev/null +++ b/src/routes/service/new/[type]/__layout.svelte @@ -0,0 +1,42 @@ + + +{#await checkService()} + +{:then} +
+ +
+{/await} diff --git a/src/routes/service/new/[type]/index.svelte b/src/routes/service/new/[type]/index.svelte new file mode 100644 index 0000000000..ec06846f5b --- /dev/null +++ b/src/routes/service/new/[type]/index.svelte @@ -0,0 +1,130 @@ + + +
+
+ Deploy new + {#if $page.params.type === 'plausible'} + Plausible Analytics + {/if} +
+
+{#if loading} + +{:else} +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+{/if} diff --git a/src/routes/service/new/index.svelte b/src/routes/service/new/index.svelte new file mode 100644 index 0000000000..8072746723 --- /dev/null +++ b/src/routes/service/new/index.svelte @@ -0,0 +1,29 @@ + + +
+
+ Select a service +
+
+
+ {#if $page.path === '/service/new'} +
+
goto('/service/new/plausible')} + > + plausible logo +
Plausible Analytics
+
+
+ {/if} +
diff --git a/src/routes/settings.svelte b/src/routes/settings.svelte new file mode 100644 index 0000000000..44c2abb2fa --- /dev/null +++ b/src/routes/settings.svelte @@ -0,0 +1,190 @@ + + + + +
+
+
Settings
+
+
+ +
+
+
+
General
+
+
+
    +
  • +
    +

    Registration allowed?

    +

    + Allow further registrations to the application. It's turned off after the first + registration. +

    +
    + +
  • +
  • +
    +

    Send errors automatically?

    +

    + Allow to send errors automatically to developer(s) at coolLabs (Andras Bacsai). This will help to fix bugs quicker. 🙏 +

    +
    + +
  • +
+
+
+
+
+
diff --git a/src/routes/success.svelte b/src/routes/success.svelte new file mode 100644 index 0000000000..796b7dfa41 --- /dev/null +++ b/src/routes/success.svelte @@ -0,0 +1,13 @@ + + +
+
Succesfully logged in! 🎉
+
diff --git a/src/store.js b/src/store.js deleted file mode 100644 index c73b019773..0000000000 --- a/src/store.js +++ /dev/null @@ -1,244 +0,0 @@ -import { writable, derived, readable } from 'svelte/store' - -const sessionStore = { - token: window.localStorage.getItem('token') || null, - githubAppToken: null -} - -function waitAtLeast (time, promise) { - const timeoutPromise = new Promise((resolve) => { - setTimeout(resolve, time) - }) - return Promise.all([promise, timeoutPromise]).then((values) => values[0]) -}; - -export const fetch = writable( - async ( - url, - { method, body, ...customConfig } = { body: null, method: null } - ) => { - let headers = { 'Content-type': 'application/json; charset=UTF-8' } - if (method === 'DELETE') { - delete headers['Content-type'] - } - const isGithub = url.match(/api.github.com/) - if (isGithub) { - headers = Object.assign(headers, { - Authorization: `token ${sessionStore.githubAppToken}` - }) - } else { - headers = Object.assign(headers, { - Authorization: `Bearer ${sessionStore.token}` - }) - } - const config = { - cache: 'no-cache', - method: method || (body ? 'POST' : 'GET'), - ...customConfig, - headers: { - ...headers, - ...customConfig.headers - } - } - if (body) { - config.body = JSON.stringify(body) - } - // const response = await waitAtLeast(350, window.fetch(url, config)) - const response = await window.fetch(url, config) - if (response.status >= 200 && response.status <= 299) { - if (response.headers.get('content-type').match(/application\/json/)) { - return await response.json() - } else if (response.headers.get('content-type').match(/text\/plain/)) { - return await response.text() - } else if (response.headers.get('content-type').match(/multipart\/form-data/)) { - return await response.formData() - } else { - return await response.blob() - } - } else { - /* eslint-disable */ - if (response.status === 401) { - return Promise.reject({ - code: response.status, - error: 'Unauthorized' - }) - } else if (response.status >= 500) { - const error = (await response.json()).message - return Promise.reject({ - code: response.status, - error: error || 'Oops, something is not okay. Are you okay?' - }) - } else { - return Promise.reject({ - code: response.status, - error: response.statusText - }) - } - /* eslint-enable */ - } - } -) -export const activePage = writable({ - application: null, - new: false, - mainmenu: null -}) -export const session = writable(sessionStore) -export const loggedIn = derived(session, ($session) => { - return $session.token -}) -export const githubRepositories = writable([]) -export const githubInstallations = writable({}) -export const savedBranch = writable() - -export const dateOptions = readable({ - year: 'numeric', - month: 'short', - day: '2-digit', - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - hour12: false -}) - -export const deployments = writable([]) - -export const initConf = writable({}) -export const application = writable({ - github: { - installation: { - id: null - }, - app: { - id: null - } - }, - repository: { - id: null, - organization: 'new', - name: 'start', - branch: null - }, - general: { - deployId: null, - nickname: null, - workdir: null - }, - build: { - pack: 'static', - directory: null, - command: { - build: null, - installation: null - }, - container: { - name: null, - tag: null, - baseSHA: null - } - }, - publish: { - directory: null, - domain: null, - path: '/', - port: null, - secrets: [] - } -}) - -export const initialApplication = { - github: { - installation: { - id: null - }, - app: { - id: null - } - }, - repository: { - id: null, - organization: null, - name: null, - branch: null - }, - general: { - deployId: null, - nickname: null, - workdir: null - }, - build: { - pack: 'static', - directory: null, - command: { - build: null, - installation: null - }, - container: { - name: null, - tag: null - } - }, - publish: { - directory: null, - domain: null, - path: '/', - port: null, - secrets: [] - } -} -export const initialDatabase = { - config: { - general: { - workdir: null, - deployId: null, - nickname: null, - type: null - }, - database: { - username: null, - passwords: [], - defaultDatabaseName: null - }, - deploy: { - name: null - } - }, - envs: {} -} - -export const database = writable({ - config: { - general: { - workdir: null, - deployId: null, - nickname: null, - type: null - }, - database: { - username: null, - passwords: [], - defaultDatabaseName: null - }, - deploy: { - name: null - } - }, - envs: {} -}) - -export const dbInprogress = writable(false) - -export const newService = writable({ - email: null, - userName: 'admin', - userPassword: null, - userPasswordAgain: null, - baseURL: null -}) -export const initialNewService = { - email: null, - userName: 'admin', - userPassword: null, - userPasswordAgain: null, - baseURL: null -} diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000000..407e00852a --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,154 @@ +import type { + Application, + Dashboard, + Database, + DateTimeFormatOptions, + GithubInstallations +} from 'src/global'; +import { writable, derived, readable, Writable } from 'svelte/store'; + +export const dashboard = writable({ + databases: { + deployed: [] + }, + applications: { + deployed: [] + }, + services: { + deployed: [] + } +}); +export const dateOptions: DateTimeFormatOptions = { + year: 'numeric', + month: 'short', + day: '2-digit', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: false +}; + +export const githubRepositories = writable([]); +export const githubInstallations = writable([]); +export const application = writable({ + github: { + installation: { + id: null + }, + app: { + id: null + } + }, + repository: { + id: null, + organization: 'new', + name: 'start', + branch: null + }, + general: { + deployId: null, + nickname: null, + workdir: null + }, + build: { + pack: 'static', + directory: null, + command: { + build: null, + installation: null + }, + container: { + name: null, + tag: null, + baseSHA: null + } + }, + publish: { + directory: null, + domain: null, + path: '/', + port: null, + secrets: [] + } +}); + +export const initConf = writable({}); + +export const initialApplication: Application = { + github: { + installation: { + id: null + }, + app: { + id: null + } + }, + repository: { + id: null, + organization: null, + name: null, + branch: null + }, + general: { + deployId: null, + nickname: null, + workdir: null + }, + build: { + pack: 'static', + directory: null, + command: { + build: null, + installation: null + }, + container: { + name: null, + tag: null, + baseSHA: null + } + }, + publish: { + directory: null, + domain: null, + path: '/', + port: null, + secrets: [] + } +}; +export const initialDatabase: Database = { + config: { + general: { + workdir: null, + deployId: null, + nickname: null, + type: null + }, + database: { + username: null, + passwords: [], + defaultDatabaseName: null + }, + deploy: { + name: null + } + }, + envs: {} +}; +export const database = writable({ + config: {}, + envs: [] +}); +export const newService = writable({ + email: null, + userName: 'admin', + userPassword: null, + userPasswordAgain: null, + baseURL: null +}); +export const initialNewService = { + email: null, + userName: 'admin', + userPassword: null, + userPasswordAgain: null, + baseURL: null +}; diff --git a/src/utils/templates.js b/src/utils/templates.js deleted file mode 100644 index f49e3f566e..0000000000 --- a/src/utils/templates.js +++ /dev/null @@ -1,57 +0,0 @@ -const defaultBuildAndDeploy = { - installation: 'yarn install', - build: 'yarn build' -} - -const templates = { - svelte: { - pack: 'svelte', - ...defaultBuildAndDeploy, - directory: 'public', - name: 'Svelte' - }, - next: { - pack: 'nextjs', - ...defaultBuildAndDeploy, - port: 3000, - name: 'NextJS' - }, - nuxt: { - pack: 'nuxtjs', - ...defaultBuildAndDeploy, - port: 3000, - name: 'NuxtJS' - }, - 'react-scripts': { - pack: 'react', - ...defaultBuildAndDeploy, - directory: 'build', - name: 'React' - }, - 'parcel-bundler': { - pack: 'static', - ...defaultBuildAndDeploy, - directory: 'dist', - name: 'Parcel' - }, - '@vue/cli-service': { - pack: 'vuejs', - ...defaultBuildAndDeploy, - directory: 'dist', - name: 'Vue' - }, - gatsby: { - pack: 'gatsby', - ...defaultBuildAndDeploy, - directory: 'public', - name: 'Gatsby' - }, - 'preact-cli': { - pack: 'react', - ...defaultBuildAndDeploy, - directory: 'build', - name: 'Preact' - } -} - -export default templates diff --git a/public/favicon.png b/static/favicon.png similarity index 100% rename from public/favicon.png rename to static/favicon.png diff --git a/svelte.config.js b/svelte.config.js index bdb4e30475..a341c9c8f4 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,39 @@ -const { postcss } = require('svelte-preprocess') -module.exports = { - preprocess: [postcss()] -} +import dotEnvExtended from 'dotenv-extended'; +dotEnvExtended.load(); +import preprocess from 'svelte-preprocess'; +import path from 'path'; +import adapter from '@sveltejs/adapter-node'; +/** @type {import('@sveltejs/kit').Config} */ +export default { + preprocess: [ + preprocess({ + postcss: true + }) + ], + kit: { + adapter: adapter({ + out: 'build' + }), + target: '#svelte', + hostHeader: 'X-Forwarded-Host', + floc: true, + prerender: { + enabled: false + }, + vite: { + server: { + hmr: { + port: 23456 + } + }, + resolve: { + alias: { + $components: path.resolve('./src/components/'), + $store: path.resolve('./src/store/index.ts'), + $api: path.resolve('./src/routes/api/_index.ts'), + $models: path.resolve('./src/models/') + } + } + } + } +}; diff --git a/tailwind.config.cjs b/tailwind.config.cjs new file mode 100644 index 0000000000..5fe5504052 --- /dev/null +++ b/tailwind.config.cjs @@ -0,0 +1,66 @@ +const defaultTheme = require('tailwindcss/defaultTheme'); +const colors = require('tailwindcss/colors'); +const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles'); + +const svelteClassColonExtractor = (content) => { + return content.match(/(?<=class:)([a-zA-Z0-9_-]+)/gm) || []; +}; +module.exports = { + mode: 'jit', + purge: ['./**/*.html', './src/**/*.{js,jsx,ts,tsx,svelte}'], + // purge: { + // enabled: process.env.NODE_ENV === 'production', + // content: ['./src/**/*.svelte', './src/**/*.html', './src/**/*.css', './index.html'], + // preserveHtmlElements: true, + // options: { + // safelist: [ + // /svelte-/, + // 'border-green-500', + // 'border-yellow-300', + // 'border-red-500', + // 'hover:border-green-500', + // 'hover:border-red-200', + // 'hover:bg-red-200', + // 'hover:bg-warmGray-900', + // 'hover:bg-transparent' + // ], + // defaultExtractor: (content) => { + // // WARNING: tailwindExtractor is internal tailwind api + // // if this breaks after a tailwind update, report to svite repo + // return [...tailwindExtractor(content), ...svelteClassColonExtractor(content)]; + // }, + // keyframes: false + // } + // }, + important: true, + theme: { + extend: { + keyframes: { + wiggle: { + '0%, 100%': { transform: 'rotate(-3deg)' }, + '50%': { transform: 'rotate(3deg)' } + } + }, + animation: { + wiggle: 'wiggle 0.5s ease-in-out infinite' + }, + fontFamily: { + sans: ['Montserrat', ...defaultTheme.fontFamily.sans] + }, + colors: { + ...colors, + coolblack: '#161616', + 'coolgray-100': '#181818', + 'coolgray-200': '#202020', + 'coolgray-300': '#242424' + } + } + }, + variants: { + extend: { + opacity: ['disabled'], + animation: ['hover', 'focus'] + } + }, + plugins: [] +}; diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100644 index 31732265a5..0000000000 --- a/tailwind.config.js +++ /dev/null @@ -1,63 +0,0 @@ -const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles') - -const svelteClassColonExtractor = (content) => { - return content.match(/(?<=class:)([a-zA-Z0-9_-]+)/gm) || [] -} -const defaultTheme = require('tailwindcss/defaultTheme') -const colors = require('tailwindcss/colors') -module.exports = { - purge: { - enabled: process.env.NODE_ENV === 'production', - content: [ - './src/**/*.svelte', - './src/**/*.html', - './src/**/*.css', - './index.html' - ], - preserveHtmlElements: true, - options: { - safelist: [/svelte-/, 'border-green-500', 'border-yellow-300', 'border-red-500', 'hover:border-green-500', 'hover:border-red-200', 'hover:bg-red-200', 'hover:bg-warmGray-900', 'hover:bg-transparent'], - defaultExtractor: (content) => { - // WARNING: tailwindExtractor is internal tailwind api - // if this breaks after a tailwind update, report to svite repo - return [ - ...tailwindExtractor(content), - ...svelteClassColonExtractor(content) - ] - }, - keyframes: false - } - }, - darkMode: false, - important: true, - theme: { - extend: { - keyframes: { - wiggle: { - '0%, 100%': { transform: 'rotate(-3deg)' }, - '50%': { transform: 'rotate(3deg)' } - } - }, - animation: { - wiggle: 'wiggle 0.5s ease-in-out infinite' - }, - fontFamily: { - sans: ['Montserrat', ...defaultTheme.fontFamily.sans] - }, - colors: { - ...colors, - coolblack: '#161616', - 'coolgray-100': '#181818', - 'coolgray-200': '#202020', - 'coolgray-300': '#242424' - } - } - }, - variants: { - extend: { - opacity: ['disabled'], - animation: ['hover', 'focus'] - } - }, - plugins: [] -} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..cd76718b3a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "module": "es2020", + "lib": ["es2020"], + "target": "es2019", + /** + svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript + to enforce using \`import type\` instead of \`import\` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + To have warnings/errors of the Svelte compiler at the correct position, + enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "allowJs": true, + "checkJs": true, + "paths": { + "$lib/*": ["src/lib/*"], + "$store": ["src/store/index.ts"], + "$api": ["src/routes/api/_index.ts"], + "$models/*": ["src/models/*"], + "$components/*": ["src/components/*"] + } + }, + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"] +} diff --git a/vite.config.js b/vite.config.js deleted file mode 100644 index 8d1555687d..0000000000 --- a/vite.config.js +++ /dev/null @@ -1,38 +0,0 @@ -module.exports = { - alias: { - '@store': '/src/store.js' - // '/@components/': path.resolve(__dirname, '/src/components'), - }, - optimizeDeps: { - exclude: [ - '@roxi/routify', - 'fastify-static', - 'fastify', - 'fastify-autoload', - 'fastify-jwt', - 'dotenv', - 'dotenv-extended', - 'commander', - 'axios', - 'fastify-env', - 'fastify-plugin', - 'mongoose', - 'js-yaml', - 'shelljs', - 'jsonwebtoken', - 'deepmerge', - 'dockerode', - 'dayjs', - '@zerodevx/svelte-toast', - 'mongodb-memory-server-core', - 'unique-names-generator', - 'generate-password', - '@iarna/toml', - 'http-errors-enhanced', - 'ajv' - ] - }, - proxy: { - '/api': 'http://127.0.0.1:3001/' - } -}