fix: build queue system

This commit is contained in:
Andras Bacsai
2022-08-25 10:04:46 +02:00
parent f379519d40
commit 01e71958b2
18 changed files with 915 additions and 753 deletions

View File

@@ -27,7 +27,7 @@
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"bree": "9.1.2", "bree": "9.1.2",
"cabin": "9.1.2", "cabin": "9.1.2",
"compare-versions": "4.1.3", "compare-versions": "4.1.4",
"cuid": "2.1.8", "cuid": "2.1.8",
"dayjs": "1.11.5", "dayjs": "1.11.5",
"dockerode": "3.3.4", "dockerode": "3.3.4",
@@ -43,17 +43,17 @@
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"node-forge": "1.3.1", "node-forge": "1.3.1",
"node-os-utils": "1.3.7", "node-os-utils": "1.3.7",
"p-queue": "7.3.0", "p-all": "4.0.0",
"public-ip": "6.0.1", "public-ip": "6.0.1",
"ssh-config": "4.1.6", "ssh-config": "4.1.6",
"strip-ansi": "7.0.1", "strip-ansi": "7.0.1",
"unique-names-generator": "4.7.1" "unique-names-generator": "4.7.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "18.7.11", "@types/node": "18.7.13",
"@types/node-os-utils": "1.3.0", "@types/node-os-utils": "1.3.0",
"@typescript-eslint/eslint-plugin": "5.34.0", "@typescript-eslint/eslint-plugin": "5.35.1",
"@typescript-eslint/parser": "5.34.0", "@typescript-eslint/parser": "5.35.1",
"esbuild": "0.15.5", "esbuild": "0.15.5",
"eslint": "8.22.0", "eslint": "8.22.0",
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",

View File

@@ -0,0 +1,29 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Setting" (
"id" TEXT NOT NULL PRIMARY KEY,
"fqdn" TEXT,
"isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"minPort" INTEGER NOT NULL DEFAULT 9000,
"maxPort" INTEGER NOT NULL DEFAULT 9100,
"proxyPassword" TEXT NOT NULL,
"proxyUser" TEXT NOT NULL,
"proxyHash" TEXT,
"isAutoUpdateEnabled" BOOLEAN NOT NULL DEFAULT false,
"isDNSCheckEnabled" BOOLEAN NOT NULL DEFAULT true,
"DNSServers" TEXT,
"isTraefikUsed" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"ipv4" TEXT,
"ipv6" TEXT,
"arch" TEXT,
"concurrentBuilds" INTEGER NOT NULL DEFAULT 1
);
INSERT INTO "new_Setting" ("DNSServers", "arch", "createdAt", "dualCerts", "fqdn", "id", "ipv4", "ipv6", "isAutoUpdateEnabled", "isDNSCheckEnabled", "isRegistrationEnabled", "isTraefikUsed", "maxPort", "minPort", "proxyHash", "proxyPassword", "proxyUser", "updatedAt") SELECT "DNSServers", "arch", "createdAt", "dualCerts", "fqdn", "id", "ipv4", "ipv6", "isAutoUpdateEnabled", "isDNSCheckEnabled", "isRegistrationEnabled", "isTraefikUsed", "maxPort", "minPort", "proxyHash", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting";
DROP TABLE "Setting";
ALTER TABLE "new_Setting" RENAME TO "Setting";
CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,24 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Build" (
"id" TEXT NOT NULL PRIMARY KEY,
"type" TEXT NOT NULL,
"applicationId" TEXT,
"destinationDockerId" TEXT,
"gitSourceId" TEXT,
"githubAppId" TEXT,
"gitlabAppId" TEXT,
"commit" TEXT,
"pullmergeRequestId" TEXT,
"forceRebuild" BOOLEAN NOT NULL DEFAULT false,
"sourceBranch" TEXT,
"branch" TEXT,
"status" TEXT DEFAULT 'queued',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
INSERT INTO "new_Build" ("applicationId", "branch", "commit", "createdAt", "destinationDockerId", "gitSourceId", "githubAppId", "gitlabAppId", "id", "status", "type", "updatedAt") SELECT "applicationId", "branch", "commit", "createdAt", "destinationDockerId", "gitSourceId", "githubAppId", "gitlabAppId", "id", "status", "type", "updatedAt" FROM "Build";
DROP TABLE "Build";
ALTER TABLE "new_Build" RENAME TO "Build";
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -27,6 +27,7 @@ model Setting {
ipv4 String? ipv4 String?
ipv6 String? ipv6 String?
arch String? arch String?
concurrentBuilds Int @default(1)
} }
model User { model User {
@@ -197,6 +198,9 @@ model Build {
githubAppId String? githubAppId String?
gitlabAppId String? gitlabAppId String?
commit String? commit String?
pullmergeRequestId String?
forceRebuild Boolean @default(false)
sourceBranch String?
branch String? branch String?
status String? @default("queued") status String? @default("queued")
createdAt DateTime @default(now()) createdAt DateTime @default(now())

View File

@@ -5,7 +5,7 @@ import env from '@fastify/env';
import cookie from '@fastify/cookie'; import cookie from '@fastify/cookie';
import path, { join } from 'path'; import path, { join } from 'path';
import autoLoad from '@fastify/autoload'; import autoLoad from '@fastify/autoload';
import { asyncExecShell, isDev, listSettings, prisma, version } from './lib/common'; import { asyncExecShell, asyncSleep, isDev, listSettings, prisma, version } from './lib/common';
import { scheduler } from './lib/scheduler'; import { scheduler } from './lib/scheduler';
import axios from 'axios'; import axios from 'axios';
import compareVersions from 'compare-versions'; import compareVersions from 'compare-versions';
@@ -104,14 +104,16 @@ fastify.listen({ port, host }, async (err: any, address: any) => {
} }
console.log(`Coolify's API is listening on ${host}:${port}`); console.log(`Coolify's API is listening on ${host}:${port}`);
await initServer(); await initServer();
await scheduler.start('deployApplication');
await scheduler.start('cleanupStorage');
await scheduler.start('cleanupPrismaEngines'); await scheduler.start('cleanupPrismaEngines');
await scheduler.start('checkProxies'); await scheduler.start('checkProxies');
// Check if no build is running setInterval(async () => {
if (!scheduler.workers.has('deployApplication')) {
scheduler.run('deployApplication');
}
}, 2000)
// Check for update // Check for update & if no build is running
setInterval(async () => { setInterval(async () => {
const { isAutoUpdateEnabled } = await prisma.setting.findFirst(); const { isAutoUpdateEnabled } = await prisma.setting.findFirst();
if (isAutoUpdateEnabled) { if (isAutoUpdateEnabled) {
@@ -128,8 +130,8 @@ fastify.listen({ port, host }, async (err: any, address: any) => {
const latestVersion = versions['coolify'].main.version; const latestVersion = versions['coolify'].main.version;
const isUpdateAvailable = compareVersions(latestVersion, currentVersion); const isUpdateAvailable = compareVersions(latestVersion, currentVersion);
if (isUpdateAvailable === 1) { if (isUpdateAvailable === 1) {
if (scheduler.workers.has('deployApplication')) { if (!scheduler.workers.has('deployApplication')) {
scheduler.workers.get('deployApplication').postMessage("status:autoUpdater"); await scheduler.run('autoUpdater')
} }
} }
} }
@@ -137,16 +139,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => {
// Cleanup storage // Cleanup storage
setInterval(async () => { setInterval(async () => {
if (scheduler.workers.has('deployApplication')) { if (!scheduler.workers.has('deployApplication') && !scheduler.workers.has('cleanupStorage')) {
scheduler.workers.get('deployApplication').postMessage("status:cleanupStorage"); await scheduler.run('cleanupStorage')
} }
}, isDev ? 5000 : 60000 * 10) }, isDev ? 5000 : 60000 * 10)
scheduler.on('worker deleted', async (name) => {
if (name === 'autoUpdater' || name === 'cleanupStorage') {
if (!scheduler.workers.has('deployApplication')) await scheduler.start('deployApplication');
}
});
await getArch(); await getArch();
await getIPAddress(); await getIPAddress();
}); });
@@ -170,6 +167,12 @@ async function initServer() {
try { try {
await asyncExecShell(`docker network create --attachable coolify`); await asyncExecShell(`docker network create --attachable coolify`);
} catch (error) { } } catch (error) { }
try {
const isOlder = compareVersions('3.8.1', version);
if (isOlder === -1) {
await prisma.build.updateMany({ where: { status: { in: ['running', 'queued'] } }, data: { status: 'failed' } });
}
} catch (error) { }
} }
async function getArch() { async function getArch() {
try { try {

View File

@@ -1,5 +1,5 @@
import { parentPort } from 'node:worker_threads'; import { parentPort } from 'node:worker_threads';
import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma, version } from '../lib/common'; import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma } from '../lib/common';
(async () => { (async () => {
if (parentPort) { if (parentPort) {

View File

@@ -0,0 +1,366 @@
import { parentPort } from 'node:worker_threads';
import crypto from 'crypto';
import fs from 'fs/promises';
import yaml from 'js-yaml';
import { copyBaseConfigurationFiles, makeLabelForStandaloneApplication, saveBuildLog, setDefaultConfiguration } from '../lib/buildPacks/common';
import { createDirectories, decrypt, defaultComposeConfiguration, executeDockerCmd, getDomain, prisma } from '../lib/common';
import * as importers from '../lib/importers';
import * as buildpacks from '../lib/buildPacks';
(async () => {
if (parentPort) {
const concurrency = 1
const PQueue = await import('p-queue');
const queue = new PQueue.default({ concurrency });
parentPort.on('message', async (message) => {
if (parentPort) {
if (message === 'error') throw new Error('oops');
if (message === 'cancel') {
parentPort.postMessage('cancelled');
return;
}
if (message === 'status:autoUpdater') {
parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'autoUpdater' });
return;
}
if (message === 'status:cleanupStorage') {
parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'cleanupStorage' });
return;
}
if (message === 'action:flushQueue') {
queue.clear()
return;
}
await queue.add(async () => {
const {
id: applicationId,
repository,
name,
destinationDocker,
destinationDockerId,
gitSource,
build_id: buildId,
configHash,
fqdn,
projectId,
secrets,
phpModules,
type,
pullmergeRequestId = null,
sourceBranch = null,
settings,
persistentStorage,
pythonWSGI,
pythonModule,
pythonVariable,
denoOptions,
exposePort,
baseImage,
baseBuildImage,
deploymentType,
forceRebuild
} = message
let {
branch,
buildPack,
port,
installCommand,
buildCommand,
startCommand,
baseDirectory,
publishDirectory,
dockerFileLocation,
denoMainFile
} = message
const currentHash = crypto
.createHash('sha256')
.update(
JSON.stringify({
pythonWSGI,
pythonModule,
pythonVariable,
deploymentType,
denoOptions,
baseImage,
baseBuildImage,
buildPack,
port,
exposePort,
installCommand,
buildCommand,
startCommand,
secrets,
branch,
repository,
fqdn
})
)
.digest('hex');
try {
const { debug } = settings;
if (concurrency === 1) {
await prisma.build.updateMany({
where: {
status: { in: ['queued', 'running'] },
id: { not: buildId },
applicationId,
createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) }
},
data: { status: 'failed' }
});
}
let imageId = applicationId;
let domain = getDomain(fqdn);
const volumes =
persistentStorage?.map((storage) => {
return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : ''
}${storage.path}`;
}) || [];
// Previews, we need to get the source branch and set subdomain
if (pullmergeRequestId) {
branch = sourceBranch;
domain = `${pullmergeRequestId}.${domain}`;
imageId = `${applicationId}-${pullmergeRequestId}`;
}
let deployNeeded = true;
let destinationType;
if (destinationDockerId) {
destinationType = 'docker';
}
if (destinationType === 'docker') {
await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } });
const { workdir, repodir } = await createDirectories({ repository, buildId });
const configuration = await setDefaultConfiguration(message);
buildPack = configuration.buildPack;
port = configuration.port;
installCommand = configuration.installCommand;
startCommand = configuration.startCommand;
buildCommand = configuration.buildCommand;
publishDirectory = configuration.publishDirectory;
baseDirectory = configuration.baseDirectory;
dockerFileLocation = configuration.dockerFileLocation;
denoMainFile = configuration.denoMainFile;
const commit = await importers[gitSource.type]({
applicationId,
debug,
workdir,
repodir,
githubAppId: gitSource.githubApp?.id,
gitlabAppId: gitSource.gitlabApp?.id,
customPort: gitSource.customPort,
repository,
branch,
buildId,
apiUrl: gitSource.apiUrl,
htmlUrl: gitSource.htmlUrl,
projectId,
deployKeyId: gitSource.gitlabApp?.deployKeyId || null,
privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null,
forPublic: gitSource.forPublic
});
if (!commit) {
throw new Error('No commit found?');
}
let tag = commit.slice(0, 7);
if (pullmergeRequestId) {
tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`;
}
try {
await prisma.build.update({ where: { id: buildId }, data: { commit } });
} catch (err) {
console.log(err);
}
if (!pullmergeRequestId) {
if (configHash !== currentHash) {
deployNeeded = true;
if (configHash) {
await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId });
}
} else {
deployNeeded = false;
}
} else {
deployNeeded = true;
}
let imageFound = false;
try {
await executeDockerCmd({
dockerId: destinationDocker.id,
command: `docker image inspect ${applicationId}:${tag}`
})
imageFound = true;
} catch (error) {
//
}
await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage);
if (forceRebuild) deployNeeded = true
if (!imageFound || deployNeeded) {
// if (true) {
if (buildpacks[buildPack])
await buildpacks[buildPack]({
dockerId: destinationDocker.id,
buildId,
applicationId,
domain,
name,
type,
pullmergeRequestId,
buildPack,
repository,
branch,
projectId,
publishDirectory,
debug,
commit,
tag,
workdir,
port: exposePort ? `${exposePort}:${port}` : port,
installCommand,
buildCommand,
startCommand,
baseDirectory,
secrets,
phpModules,
pythonWSGI,
pythonModule,
pythonVariable,
dockerFileLocation,
denoMainFile,
denoOptions,
baseImage,
baseBuildImage,
deploymentType
});
else {
await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId });
throw new Error(`Build pack ${buildPack} not found.`);
}
} else {
await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId });
}
try {
await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` })
await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` })
} catch (error) {
//
}
const envs = [
`PORT=${port}`
];
if (secrets.length > 0) {
secrets.forEach((secret) => {
if (pullmergeRequestId) {
if (secret.isPRMRSecret) {
envs.push(`${secret.name}=${secret.value}`);
}
} else {
if (!secret.isPRMRSecret) {
envs.push(`${secret.name}=${secret.value}`);
}
}
});
}
await fs.writeFile(`${workdir}/.env`, envs.join('\n'));
const labels = makeLabelForStandaloneApplication({
applicationId,
fqdn,
name,
type,
pullmergeRequestId,
buildPack,
repository,
branch,
projectId,
port: exposePort ? `${exposePort}:${port}` : port,
commit,
installCommand,
buildCommand,
startCommand,
baseDirectory,
publishDirectory
});
let envFound = false;
try {
envFound = !!(await fs.stat(`${workdir}/.env`));
} catch (error) {
//
}
try {
await saveBuildLog({ line: 'Deployment started.', buildId, applicationId });
const composeVolumes = volumes.map((volume) => {
return {
[`${volume.split(':')[0]}`]: {
name: volume.split(':')[0]
}
};
});
const composeFile = {
version: '3.8',
services: {
[imageId]: {
image: `${applicationId}:${tag}`,
container_name: imageId,
volumes,
env_file: envFound ? [`${workdir}/.env`] : [],
labels,
depends_on: [],
expose: [port],
...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}),
// logging: {
// driver: 'fluentd',
// },
...defaultComposeConfiguration(destinationDocker.network),
}
},
networks: {
[destinationDocker.network]: {
external: true
}
},
volumes: Object.assign({}, ...composeVolumes)
};
await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile));
await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` })
await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId });
} catch (error) {
await saveBuildLog({ line: error, buildId, applicationId });
await prisma.build.updateMany({
where: { id: message.build_id, status: { in: ['queued', 'running'] } },
data: { status: 'failed' }
});
throw new Error(error);
}
await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId });
await prisma.build.update({ where: { id: message.build_id }, data: { status: 'success' } });
if (!pullmergeRequestId) await prisma.application.update({
where: { id: applicationId },
data: { configHash: currentHash }
});
}
}
catch (error) {
await prisma.build.updateMany({
where: { id: message.build_id, status: { in: ['queued', 'running'] } },
data: { status: 'failed' }
});
await saveBuildLog({ line: error, buildId, applicationId });
} finally {
await prisma.$disconnect();
}
});
await prisma.$disconnect();
}
});
} else process.exit(0);
})();

View File

@@ -10,30 +10,26 @@ import * as buildpacks from '../lib/buildPacks';
(async () => { (async () => {
if (parentPort) { if (parentPort) {
const concurrency = 1
const PQueue = await import('p-queue');
const queue = new PQueue.default({ concurrency });
parentPort.on('message', async (message) => { parentPort.on('message', async (message) => {
if (parentPort) {
if (message === 'error') throw new Error('oops'); if (message === 'error') throw new Error('oops');
if (message === 'cancel') { if (message === 'cancel') {
parentPort.postMessage('cancelled'); parentPort.postMessage('cancelled');
return; process.exit(0);
}
if (message === 'status:autoUpdater') {
parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'autoUpdater' });
return;
}
if (message === 'status:cleanupStorage') {
parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'cleanupStorage' });
return;
}
if (message === 'action:flushQueue') {
queue.clear()
return;
} }
});
try {
parentPort.postMessage({ deploying: true });
const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } });
const { concurrentBuilds } = await prisma.setting.findFirst({})
if (queuedBuilds.length > 0) {
const concurrency = concurrentBuilds;
const pAll = await import('p-all');
const actions = []
await queue.add(async () => { for (const queueBuild of queuedBuilds) {
actions.push(async () => {
const application = await prisma.application.findUnique({ where: { id: queueBuild.applicationId }, include: { destinationDocker: true, gitSource: { include: { githubApp: true, gitlabApp: true } }, persistentStorage: true, secrets: true, settings: true, teams: true } })
const { id: buildId, type, sourceBranch = null, pullmergeRequestId = null, forceRebuild } = queueBuild
const { const {
id: applicationId, id: applicationId,
repository, repository,
@@ -41,15 +37,11 @@ import * as buildpacks from '../lib/buildPacks';
destinationDocker, destinationDocker,
destinationDockerId, destinationDockerId,
gitSource, gitSource,
build_id: buildId,
configHash, configHash,
fqdn, fqdn,
projectId, projectId,
secrets, secrets,
phpModules, phpModules,
type,
pullmergeRequestId = null,
sourceBranch = null,
settings, settings,
persistentStorage, persistentStorage,
pythonWSGI, pythonWSGI,
@@ -60,8 +52,7 @@ import * as buildpacks from '../lib/buildPacks';
baseImage, baseImage,
baseBuildImage, baseBuildImage,
deploymentType, deploymentType,
forceRebuild } = application
} = message
let { let {
branch, branch,
buildPack, buildPack,
@@ -73,7 +64,7 @@ import * as buildpacks from '../lib/buildPacks';
publishDirectory, publishDirectory,
dockerFileLocation, dockerFileLocation,
denoMainFile denoMainFile
} = message } = application
const currentHash = crypto const currentHash = crypto
.createHash('sha256') .createHash('sha256')
.update( .update(
@@ -134,7 +125,7 @@ import * as buildpacks from '../lib/buildPacks';
if (destinationType === 'docker') { if (destinationType === 'docker') {
await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } });
const { workdir, repodir } = await createDirectories({ repository, buildId }); const { workdir, repodir } = await createDirectories({ repository, buildId });
const configuration = await setDefaultConfiguration(message); const configuration = await setDefaultConfiguration(application);
buildPack = configuration.buildPack; buildPack = configuration.buildPack;
port = configuration.port; port = configuration.port;
@@ -178,7 +169,6 @@ import * as buildpacks from '../lib/buildPacks';
} }
if (!pullmergeRequestId) { if (!pullmergeRequestId) {
if (configHash !== currentHash) { if (configHash !== currentHash) {
deployNeeded = true; deployNeeded = true;
if (configHash) { if (configHash) {
@@ -335,32 +325,38 @@ import * as buildpacks from '../lib/buildPacks';
} catch (error) { } catch (error) {
await saveBuildLog({ line: error, buildId, applicationId }); await saveBuildLog({ line: error, buildId, applicationId });
await prisma.build.updateMany({ await prisma.build.updateMany({
where: { id: message.build_id, status: { in: ['queued', 'running'] } }, where: { id: buildId, status: { in: ['queued', 'running'] } },
data: { status: 'failed' } data: { status: 'failed' }
}); });
throw new Error(error); throw new Error(error);
} }
await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId });
await prisma.build.update({ where: { id: message.build_id }, data: { status: 'success' } }); await prisma.build.update({ where: { id: buildId }, data: { status: 'success' } });
if (!pullmergeRequestId) await prisma.application.update({ if (!pullmergeRequestId) await prisma.application.update({
where: { id: applicationId }, where: { id: applicationId },
data: { configHash: currentHash } data: { configHash: currentHash }
}); });
} }
} }
catch (error) { catch (error) {
await prisma.build.updateMany({ await prisma.build.updateMany({
where: { id: message.build_id, status: { in: ['queued', 'running'] } }, where: { id: buildId, status: { in: ['queued', 'running'] } },
data: { status: 'failed' } data: { status: 'failed' }
}); });
await saveBuildLog({ line: error, buildId, applicationId }); await saveBuildLog({ line: error, buildId, applicationId });
}
});
}
await pAll.default(actions, { concurrency })
}
} catch (error) {
process.exit(0);
} finally { } finally {
await prisma.$disconnect(); await prisma.$disconnect();
process.exit(0);
} }
});
await prisma.$disconnect();
}
});
} else process.exit(0); } else process.exit(0);
})(); })();

View File

@@ -553,7 +553,7 @@ export async function buildImage({
await executeDockerCmd({ debug, buildId, applicationId, dockerId, command: `docker build --progress plain -f ${workdir}/${dockerFile} -t ${cache} ${workdir}` }) await executeDockerCmd({ debug, buildId, applicationId, dockerId, command: `docker build --progress plain -f ${workdir}/${dockerFile} -t ${cache} ${workdir}` })
const { status } = await prisma.build.findUnique({ where: { id: buildId } }) const { status } = await prisma.build.findUnique({ where: { id: buildId } })
if (status === 'canceled') { if (status === 'canceled') {
throw new Error('Build canceled.') throw new Error('Deployment canceled.')
} }
if (isCache) { if (isCache) {
await saveBuildLog({ line: `Building cache image successful.`, buildId, applicationId }); await saveBuildLog({ line: `Building cache image successful.`, buildId, applicationId });

View File

@@ -93,7 +93,6 @@ export const asyncExecShellStream = async ({ debug, buildId, applicationId, comm
const { execaCommand } = await import('execa') const { execaCommand } = await import('execa')
const subprocess = execaCommand(command, { env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } }) const subprocess = execaCommand(command, { env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } })
if (debug) { if (debug) {
await saveBuildLog({ line: `=========================`, buildId, applicationId });
subprocess.stdout.on('data', async (data) => { subprocess.stdout.on('data', async (data) => {
const stdout = data.toString(); const stdout = data.toString();
const array = stdout.split('\n') const array = stdout.split('\n')
@@ -123,7 +122,6 @@ export const asyncExecShellStream = async ({ debug, buildId, applicationId, comm
} }
subprocess.on('exit', async (code) => { subprocess.on('exit', async (code) => {
await asyncSleep(1000); await asyncSleep(1000);
await saveBuildLog({ line: `=========================`, buildId, applicationId });
if (code === 0) { if (code === 0) {
resolve(code) resolve(code)
} else { } else {
@@ -1871,7 +1869,7 @@ export async function stopBuild(buildId, applicationId) {
let count = 0; let count = 0;
await new Promise<void>(async (resolve, reject) => { await new Promise<void>(async (resolve, reject) => {
const { destinationDockerId, status } = await prisma.build.findFirst({ where: { id: buildId } }); const { destinationDockerId, status } = await prisma.build.findFirst({ where: { id: buildId } });
const { engine, id: dockerId } = await prisma.destinationDocker.findFirst({ where: { id: destinationDockerId } }); const { id: dockerId } = await prisma.destinationDocker.findFirst({ where: { id: destinationDockerId } });
const interval = setInterval(async () => { const interval = setInterval(async () => {
try { try {
if (status === 'failed' || status === 'canceled') { if (status === 'failed' || status === 'canceled') {
@@ -1881,10 +1879,10 @@ export async function stopBuild(buildId, applicationId) {
if (count > 15) { if (count > 15) {
clearInterval(interval); clearInterval(interval);
if (scheduler.workers.has('deployApplication')) { if (scheduler.workers.has('deployApplication')) {
scheduler.workers.get('deployApplication').postMessage("action:flushQueue") scheduler.workers.get('deployApplication').postMessage('cancel')
} }
await cleanupDB(buildId); await cleanupDB(buildId, applicationId);
return reject(new Error('Build canceled')); return reject(new Error('Deployment canceled.'));
} }
const { stdout: buildContainers } = await executeDockerCmd({ dockerId, command: `docker container ls --filter "label=coolify.buildId=${buildId}" --format '{{json .}}'` }) const { stdout: buildContainers } = await executeDockerCmd({ dockerId, command: `docker container ls --filter "label=coolify.buildId=${buildId}" --format '{{json .}}'` })
if (buildContainers) { if (buildContainers) {
@@ -1896,9 +1894,9 @@ export async function stopBuild(buildId, applicationId) {
await removeContainer({ id, dockerId }); await removeContainer({ id, dockerId });
clearInterval(interval); clearInterval(interval);
if (scheduler.workers.has('deployApplication')) { if (scheduler.workers.has('deployApplication')) {
scheduler.workers.get('deployApplication').postMessage("action:flushQueue") scheduler.workers.get('deployApplication').postMessage('cancel')
} }
await cleanupDB(buildId); await cleanupDB(buildId, applicationId);
return resolve(); return resolve();
} }
} }
@@ -1909,11 +1907,12 @@ export async function stopBuild(buildId, applicationId) {
}); });
} }
async function cleanupDB(buildId: string) { async function cleanupDB(buildId: string, applicationId: string) {
const data = await prisma.build.findUnique({ where: { id: buildId } }); const data = await prisma.build.findUnique({ where: { id: buildId } });
if (data?.status === 'queued' || data?.status === 'running') { if (data?.status === 'queued' || data?.status === 'running') {
await prisma.build.update({ where: { id: buildId }, data: { status: 'canceled' } }); await prisma.build.update({ where: { id: buildId }, data: { status: 'canceled' } });
} }
await saveBuildLog({ line: 'Deployment canceled.', buildId, applicationId });
} }
export function convertTolOldVolumeNames(type) { export function convertTolOldVolumeNames(type) {

View File

@@ -9,27 +9,17 @@ Bree.extend(TSBree);
const options: any = { const options: any = {
defaultExtension: 'js', defaultExtension: 'js',
logger: false, logger: new Cabin(),
workerMessageHandler: async ({ name, message }) => { workerMessageHandler: async ({ name, message }) => {
if (name === 'deployApplication') { if (name === 'deployApplication' && message?.deploying) {
if (message.pending === 0 && message.size === 0) { if (scheduler.workers.has('autoUpdater') || scheduler.workers.has('cleanupStorage')) {
if (message.caller === 'autoUpdater') { scheduler.workers.get('deployApplication').postMessage('cancel')
if (!scheduler.workers.has('autoUpdater')) {
await scheduler.run('autoUpdater')
}
}
if (message.caller === 'cleanupStorage') {
if (!scheduler.workers.has('cleanupStorage')) {
await scheduler.run('cleanupStorage')
}
}
} }
} }
}, },
jobs: [ jobs: [
{ {
name: 'deployApplication' name: 'deployApplication',
}, },
{ {
name: 'cleanupStorage', name: 'cleanupStorage',

View File

@@ -75,7 +75,6 @@ export async function getApplicationStatus(request: FastifyRequest<OnlyId>) {
isExited = await isContainerExited(application.destinationDocker.id, id); isExited = await isContainerExited(application.destinationDocker.id, id);
} }
return { return {
isQueueActive: scheduler.workers.has('deployApplication'),
isRunning, isRunning,
isExited, isExited,
}; };
@@ -453,6 +452,8 @@ export async function deployApplication(request: FastifyRequest<DeployApplicatio
id: buildId, id: buildId,
applicationId: id, applicationId: id,
branch: application.branch, branch: application.branch,
pullmergeRequestId,
forceRebuild,
destinationDockerId: application.destinationDocker?.id, destinationDockerId: application.destinationDocker?.id,
gitSourceId: application.gitSource?.id, gitSourceId: application.gitSource?.id,
githubAppId: application.gitSource?.githubApp?.id, githubAppId: application.gitSource?.githubApp?.id,
@@ -461,24 +462,6 @@ export async function deployApplication(request: FastifyRequest<DeployApplicatio
type: 'manual' type: 'manual'
} }
}); });
if (pullmergeRequestId) {
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'manual',
...application,
sourceBranch: branch,
pullmergeRequestId,
forceRebuild
});
} else {
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'manual',
...application,
forceRebuild
});
}
return { return {
buildId buildId
}; };

View File

@@ -142,12 +142,6 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
type: 'webhook_commit' type: 'webhook_commit'
} }
}); });
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'webhook_commit',
...applicationFound
});
return { return {
message: 'Queued. Thank you!' message: 'Queued. Thank you!'
}; };
@@ -183,6 +177,8 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
await prisma.build.create({ await prisma.build.create({
data: { data: {
id: buildId, id: buildId,
pullmergeRequestId,
sourceBranch,
applicationId: applicationFound.id, applicationId: applicationFound.id,
destinationDockerId: applicationFound.destinationDocker.id, destinationDockerId: applicationFound.destinationDocker.id,
gitSourceId: applicationFound.gitSource.id, gitSourceId: applicationFound.gitSource.id,
@@ -192,13 +188,6 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
type: 'webhook_pr' type: 'webhook_pr'
} }
}); });
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'webhook_pr',
...applicationFound,
sourceBranch,
pullmergeRequestId
});
return { return {
message: 'Queued. Thank you!' message: 'Queued. Thank you!'

View File

@@ -89,12 +89,6 @@ export async function gitLabEvents(request: FastifyRequest<GitLabEvents>) {
} }
}); });
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'webhook_commit',
...applicationFound
});
return { return {
message: 'Queued. Thank you!' message: 'Queued. Thank you!'
}; };
@@ -141,6 +135,8 @@ export async function gitLabEvents(request: FastifyRequest<GitLabEvents>) {
await prisma.build.create({ await prisma.build.create({
data: { data: {
id: buildId, id: buildId,
pullmergeRequestId,
sourceBranch,
applicationId: applicationFound.id, applicationId: applicationFound.id,
destinationDockerId: applicationFound.destinationDocker.id, destinationDockerId: applicationFound.destinationDocker.id,
gitSourceId: applicationFound.gitSource.id, gitSourceId: applicationFound.gitSource.id,
@@ -150,14 +146,6 @@ export async function gitLabEvents(request: FastifyRequest<GitLabEvents>) {
type: 'webhook_mr' type: 'webhook_mr'
} }
}); });
scheduler.workers.get('deployApplication').postMessage({
build_id: buildId,
type: 'webhook_mr',
...applicationFound,
sourceBranch,
pullmergeRequestId
});
return { return {
message: 'Queued. Thank you!' message: 'Queued. Thank you!'
}; };

View File

@@ -14,20 +14,20 @@
"format": "prettier --write --plugin-search-dir=. ." "format": "prettier --write --plugin-search-dir=. ."
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "1.24.2", "@playwright/test": "1.25.1",
"@sveltejs/kit": "1.0.0-next.405", "@sveltejs/kit": "1.0.0-next.405",
"@types/js-cookie": "3.0.2", "@types/js-cookie": "3.0.2",
"@typescript-eslint/eslint-plugin": "5.33.0", "@typescript-eslint/eslint-plugin": "5.35.1",
"@typescript-eslint/parser": "5.33.0", "@typescript-eslint/parser": "5.35.1",
"autoprefixer": "10.4.8", "autoprefixer": "10.4.8",
"eslint": "8.21.0", "eslint": "8.22.0",
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
"eslint-plugin-svelte3": "4.0.0", "eslint-plugin-svelte3": "4.0.0",
"postcss": "8.4.16", "postcss": "8.4.16",
"prettier": "2.7.1", "prettier": "2.7.1",
"prettier-plugin-svelte": "2.7.0", "prettier-plugin-svelte": "2.7.0",
"svelte": "3.49.0", "svelte": "3.49.0",
"svelte-check": "2.8.0", "svelte-check": "2.8.1",
"svelte-preprocess": "4.10.7", "svelte-preprocess": "4.10.7",
"tailwindcss": "3.1.8", "tailwindcss": "3.1.8",
"tailwindcss-scrollbar": "0.1.0", "tailwindcss-scrollbar": "0.1.0",
@@ -39,7 +39,7 @@
"dependencies": { "dependencies": {
"@sveltejs/adapter-static": "1.0.0-next.39", "@sveltejs/adapter-static": "1.0.0-next.39",
"cuid": "2.1.8", "cuid": "2.1.8",
"daisyui": "2.22.0", "daisyui": "2.24.0",
"js-cookie": "3.0.1", "js-cookie": "3.0.1",
"p-limit": "4.0.0", "p-limit": "4.0.0",
"svelte-select": "4.4.7", "svelte-select": "4.4.7",

View File

@@ -66,7 +66,6 @@
let loading = false; let loading = false;
let statusInterval: any; let statusInterval: any;
let isQueueActive = false;
$disabledButton = $disabledButton =
!$appSession.isAdmin || !$appSession.isAdmin ||
(!application.fqdn && !application.settings.isBot) || (!application.fqdn && !application.settings.isBot) ||
@@ -121,7 +120,6 @@
if ($status.application.loading) return; if ($status.application.loading) return;
$status.application.loading = true; $status.application.loading = true;
const data = await get(`/applications/${id}/status`); const data = await get(`/applications/${id}/status`);
isQueueActive = data.isQueueActive;
$status.application.isRunning = data.isRunning; $status.application.isRunning = data.isRunning;
$status.application.isExited = data.isExited; $status.application.isExited = data.isExited;
$status.application.loading = false; $status.application.loading = false;
@@ -259,13 +257,10 @@
<form on:submit|preventDefault={() => handleDeploySubmit(true)}> <form on:submit|preventDefault={() => handleDeploySubmit(true)}>
<button <button
type="submit" type="submit"
disabled={$disabledButton || !isQueueActive} disabled={$disabledButton}
class:hover:text-green-500={isQueueActive}
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2" class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2"
data-tip={$appSession.isAdmin data-tip={$appSession.isAdmin
? isQueueActive
? 'Force Rebuild Application' ? 'Force Rebuild Application'
: 'Autoupdate inprogress. Cannot rebuild application.'
: 'You do not have permission to rebuild application.'} : 'You do not have permission to rebuild application.'}
> >
<svg <svg
@@ -287,7 +282,7 @@
</button> </button>
</form> </form>
{:else} {:else}
<form on:submit|preventDefault={handleDeploySubmit}> <form on:submit|preventDefault={() => handleDeploySubmit(false)}>
<button <button
type="submit" type="submit"
disabled={$disabledButton} disabled={$disabledButton}
@@ -359,7 +354,7 @@
<button <button
disabled={$disabledButton} disabled={$disabledButton}
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm" class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
data-tip="Secret" data-tip="Secrets"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View File

@@ -178,7 +178,7 @@
{#if !noMoreBuilds} {#if !noMoreBuilds}
{#if buildCount > 5} {#if buildCount > 5}
<div class="flex space-x-2"> <div class="flex space-x-2">
<button disabled={noMoreBuilds} class="w-full" on:click={loadMoreBuilds} <button disabled={noMoreBuilds} class=" btn btn-sm w-full" on:click={loadMoreBuilds}
>{$t('application.build.load_more')}</button >{$t('application.build.load_more')}</button
> >
</div> </div>

386
pnpm-lock.yaml generated
View File

@@ -23,15 +23,15 @@ importers:
'@fastify/static': 6.5.0 '@fastify/static': 6.5.0
'@iarna/toml': 2.2.5 '@iarna/toml': 2.2.5
'@prisma/client': 3.15.2 '@prisma/client': 3.15.2
'@types/node': 18.7.11 '@types/node': 18.7.13
'@types/node-os-utils': 1.3.0 '@types/node-os-utils': 1.3.0
'@typescript-eslint/eslint-plugin': 5.34.0 '@typescript-eslint/eslint-plugin': 5.35.1
'@typescript-eslint/parser': 5.34.0 '@typescript-eslint/parser': 5.35.1
axios: 0.27.2 axios: 0.27.2
bcryptjs: 2.4.3 bcryptjs: 2.4.3
bree: 9.1.2 bree: 9.1.2
cabin: 9.1.2 cabin: 9.1.2
compare-versions: 4.1.3 compare-versions: 4.1.4
cuid: 2.1.8 cuid: 2.1.8
dayjs: 1.11.5 dayjs: 1.11.5
dockerode: 3.3.4 dockerode: 3.3.4
@@ -52,7 +52,7 @@ importers:
node-forge: 1.3.1 node-forge: 1.3.1
node-os-utils: 1.3.7 node-os-utils: 1.3.7
nodemon: 2.0.19 nodemon: 2.0.19
p-queue: 7.3.0 p-all: 4.0.0
prettier: 2.7.1 prettier: 2.7.1
prisma: 3.15.2 prisma: 3.15.2
public-ip: 6.0.1 public-ip: 6.0.1
@@ -63,7 +63,7 @@ importers:
typescript: 4.7.4 typescript: 4.7.4
unique-names-generator: 4.7.1 unique-names-generator: 4.7.1
dependencies: dependencies:
'@breejs/ts-worker': 2.0.0_vko2uubnomvm6mw63pxqdtopyq '@breejs/ts-worker': 2.0.0_rzqxabipis2a5sxrpk4obdh4zu
'@fastify/autoload': 5.2.0 '@fastify/autoload': 5.2.0
'@fastify/cookie': 8.0.0 '@fastify/cookie': 8.0.0
'@fastify/cors': 8.1.0 '@fastify/cors': 8.1.0
@@ -76,7 +76,7 @@ importers:
bcryptjs: 2.4.3 bcryptjs: 2.4.3
bree: 9.1.2 bree: 9.1.2
cabin: 9.1.2 cabin: 9.1.2
compare-versions: 4.1.3 compare-versions: 4.1.4
cuid: 2.1.8 cuid: 2.1.8
dayjs: 1.11.5 dayjs: 1.11.5
dockerode: 3.3.4 dockerode: 3.3.4
@@ -92,16 +92,16 @@ importers:
jsonwebtoken: 8.5.1 jsonwebtoken: 8.5.1
node-forge: 1.3.1 node-forge: 1.3.1
node-os-utils: 1.3.7 node-os-utils: 1.3.7
p-queue: 7.3.0 p-all: 4.0.0
public-ip: 6.0.1 public-ip: 6.0.1
ssh-config: 4.1.6 ssh-config: 4.1.6
strip-ansi: 7.0.1 strip-ansi: 7.0.1
unique-names-generator: 4.7.1 unique-names-generator: 4.7.1
devDependencies: devDependencies:
'@types/node': 18.7.11 '@types/node': 18.7.13
'@types/node-os-utils': 1.3.0 '@types/node-os-utils': 1.3.0
'@typescript-eslint/eslint-plugin': 5.34.0_euudt5oqhhodkyae5tf6wjmsda '@typescript-eslint/eslint-plugin': 5.35.1_ktjxjibzrfqejavile4bhmzhjq
'@typescript-eslint/parser': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
esbuild: 0.15.5 esbuild: 0.15.5
eslint: 8.22.0 eslint: 8.22.0
eslint-config-prettier: 8.5.0_eslint@8.22.0 eslint-config-prettier: 8.5.0_eslint@8.22.0
@@ -115,16 +115,16 @@ importers:
apps/ui: apps/ui:
specifiers: specifiers:
'@playwright/test': 1.24.2 '@playwright/test': 1.25.1
'@sveltejs/adapter-static': 1.0.0-next.39 '@sveltejs/adapter-static': 1.0.0-next.39
'@sveltejs/kit': 1.0.0-next.405 '@sveltejs/kit': 1.0.0-next.405
'@types/js-cookie': 3.0.2 '@types/js-cookie': 3.0.2
'@typescript-eslint/eslint-plugin': 5.33.0 '@typescript-eslint/eslint-plugin': 5.35.1
'@typescript-eslint/parser': 5.33.0 '@typescript-eslint/parser': 5.35.1
autoprefixer: 10.4.8 autoprefixer: 10.4.8
cuid: 2.1.8 cuid: 2.1.8
daisyui: 2.22.0 daisyui: 2.24.0
eslint: 8.21.0 eslint: 8.22.0
eslint-config-prettier: 8.5.0 eslint-config-prettier: 8.5.0
eslint-plugin-svelte3: 4.0.0 eslint-plugin-svelte3: 4.0.0
js-cookie: 3.0.1 js-cookie: 3.0.1
@@ -133,7 +133,7 @@ importers:
prettier: 2.7.1 prettier: 2.7.1
prettier-plugin-svelte: 2.7.0 prettier-plugin-svelte: 2.7.0
svelte: 3.49.0 svelte: 3.49.0
svelte-check: 2.8.0 svelte-check: 2.8.1
svelte-preprocess: 4.10.7 svelte-preprocess: 4.10.7
svelte-select: 4.4.7 svelte-select: 4.4.7
sveltekit-i18n: 2.2.2 sveltekit-i18n: 2.2.2
@@ -145,26 +145,26 @@ importers:
dependencies: dependencies:
'@sveltejs/adapter-static': 1.0.0-next.39 '@sveltejs/adapter-static': 1.0.0-next.39
cuid: 2.1.8 cuid: 2.1.8
daisyui: 2.22.0_25hquoklqeoqwmt7fwvvcyxm5e daisyui: 2.24.0_25hquoklqeoqwmt7fwvvcyxm5e
js-cookie: 3.0.1 js-cookie: 3.0.1
p-limit: 4.0.0 p-limit: 4.0.0
svelte-select: 4.4.7 svelte-select: 4.4.7
sveltekit-i18n: 2.2.2_svelte@3.49.0 sveltekit-i18n: 2.2.2_svelte@3.49.0
devDependencies: devDependencies:
'@playwright/test': 1.24.2 '@playwright/test': 1.25.1
'@sveltejs/kit': 1.0.0-next.405_svelte@3.49.0+vite@3.0.5 '@sveltejs/kit': 1.0.0-next.405_svelte@3.49.0+vite@3.0.5
'@types/js-cookie': 3.0.2 '@types/js-cookie': 3.0.2
'@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq '@typescript-eslint/eslint-plugin': 5.35.1_ktjxjibzrfqejavile4bhmzhjq
'@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
autoprefixer: 10.4.8_postcss@8.4.16 autoprefixer: 10.4.8_postcss@8.4.16
eslint: 8.21.0 eslint: 8.22.0
eslint-config-prettier: 8.5.0_eslint@8.21.0 eslint-config-prettier: 8.5.0_eslint@8.22.0
eslint-plugin-svelte3: 4.0.0_a7wk4ghvg4hia4trwaglu7p6cq eslint-plugin-svelte3: 4.0.0_laaqauvsmoyypsiqkozwyi2fn4
postcss: 8.4.16 postcss: 8.4.16
prettier: 2.7.1 prettier: 2.7.1
prettier-plugin-svelte: 2.7.0_o3ioganyptcsrh6x4hnxvjkpqi prettier-plugin-svelte: 2.7.0_o3ioganyptcsrh6x4hnxvjkpqi
svelte: 3.49.0 svelte: 3.49.0
svelte-check: 2.8.0_vylzxgme5yisu3bsyvcau4hjtq svelte-check: 2.8.1_vylzxgme5yisu3bsyvcau4hjtq
svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme
tailwindcss: 3.1.8 tailwindcss: 3.1.8
tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8
@@ -211,14 +211,14 @@ packages:
engines: {node: '>= 10'} engines: {node: '>= 10'}
dev: false dev: false
/@breejs/ts-worker/2.0.0_vko2uubnomvm6mw63pxqdtopyq: /@breejs/ts-worker/2.0.0_rzqxabipis2a5sxrpk4obdh4zu:
resolution: {integrity: sha512-6anHRcmgYlF7mrm/YVRn6rx2cegLuiY3VBxkkimOTWC/dVQeH336imVSuIKEGKTwiuNTPr2hswVdDSneNuXg3A==} resolution: {integrity: sha512-6anHRcmgYlF7mrm/YVRn6rx2cegLuiY3VBxkkimOTWC/dVQeH336imVSuIKEGKTwiuNTPr2hswVdDSneNuXg3A==}
engines: {node: '>= 12.11'} engines: {node: '>= 12.11'}
peerDependencies: peerDependencies:
bree: '>=9.0.0' bree: '>=9.0.0'
dependencies: dependencies:
bree: 9.1.2 bree: 9.1.2
ts-node: 10.8.2_yuzmdm4dwbtqx7oi4ad7vmtwja ts-node: 10.8.2_57uwcby55h6tzvkj3v5sfcgxoe
tsconfig-paths: 4.1.0 tsconfig-paths: 4.1.0
transitivePeerDependencies: transitivePeerDependencies:
- '@swc/core' - '@swc/core'
@@ -401,13 +401,13 @@ packages:
'@nodelib/fs.scandir': 2.1.5 '@nodelib/fs.scandir': 2.1.5
fastq: 1.13.0 fastq: 1.13.0
/@playwright/test/1.24.2: /@playwright/test/1.25.1:
resolution: {integrity: sha512-Q4X224pRHw4Dtkk5PoNJplZCokLNvVbXD9wDQEMrHcEuvWpJWEQDeJ9gEwkZ3iCWSFSWBshIX177B231XW4wOQ==} resolution: {integrity: sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
dependencies: dependencies:
'@types/node': 18.6.5 '@types/node': 18.7.13
playwright-core: 1.24.2 playwright-core: 1.25.1
dev: true dev: true
/@prisma/client/3.15.2_prisma@3.15.2: /@prisma/client/3.15.2_prisma@3.15.2:
@@ -534,7 +534,7 @@ packages:
dependencies: dependencies:
'@types/http-cache-semantics': 4.0.1 '@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.4 '@types/keyv': 3.1.4
'@types/node': 18.7.11 '@types/node': 18.7.13
'@types/responselike': 1.0.0 '@types/responselike': 1.0.0
dev: false dev: false
@@ -557,7 +557,7 @@ packages:
/@types/keyv/3.1.4: /@types/keyv/3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies: dependencies:
'@types/node': 18.7.11 '@types/node': 18.7.13
dev: false dev: false
/@types/lodash/4.14.182: /@types/lodash/4.14.182:
@@ -568,16 +568,8 @@ packages:
resolution: {integrity: sha512-XwVteWQx/XkfRPyaGkw8dEbrCAkoRZ73pI3XznUYIpzbCfpQB3UnDlR5TnmdhetlT889tUJGF8QWo9xrgTpsiA==} resolution: {integrity: sha512-XwVteWQx/XkfRPyaGkw8dEbrCAkoRZ73pI3XznUYIpzbCfpQB3UnDlR5TnmdhetlT889tUJGF8QWo9xrgTpsiA==}
dev: true dev: true
/@types/node/18.0.3: /@types/node/18.7.13:
resolution: {integrity: sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==} resolution: {integrity: sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==}
dev: true
/@types/node/18.6.5:
resolution: {integrity: sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==}
dev: true
/@types/node/18.7.11:
resolution: {integrity: sha512-KZhFpSLlmK/sdocfSAjqPETTMd0ug6HIMIAwkwUpU79olnZdQtMxpQP+G1wDzCH7na+FltSIhbaZuKdwZ8RDrw==}
/@types/normalize-package-data/2.4.1: /@types/normalize-package-data/2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -590,17 +582,17 @@ packages:
/@types/responselike/1.0.0: /@types/responselike/1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies: dependencies:
'@types/node': 18.7.11 '@types/node': 18.7.13
dev: false dev: false
/@types/sass/1.43.1: /@types/sass/1.43.1:
resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==}
dependencies: dependencies:
'@types/node': 18.0.3 '@types/node': 18.7.13
dev: true dev: true
/@typescript-eslint/eslint-plugin/5.33.0_njno5y7ry2l2lcmiu4tywxkwnq: /@typescript-eslint/eslint-plugin/5.35.1_ktjxjibzrfqejavile4bhmzhjq:
resolution: {integrity: sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==} resolution: {integrity: sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^5.0.0 '@typescript-eslint/parser': ^5.0.0
@@ -610,37 +602,10 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
'@typescript-eslint/scope-manager': 5.33.0 '@typescript-eslint/scope-manager': 5.35.1
'@typescript-eslint/type-utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq '@typescript-eslint/type-utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
'@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq '@typescript-eslint/utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
debug: 4.3.4
eslint: 8.21.0
functional-red-black-tree: 1.0.1
ignore: 5.2.0
regexpp: 3.2.0
semver: 7.3.7
tsutils: 3.21.0_typescript@4.7.4
typescript: 4.7.4
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/eslint-plugin/5.34.0_euudt5oqhhodkyae5tf6wjmsda:
resolution: {integrity: sha512-eRfPPcasO39iwjlUAMtjeueRGuIrW3TQ9WseIDl7i5UWuFbf83yYaU7YPs4j8+4CxUMIsj1k+4kV+E+G+6ypDQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
'@typescript-eslint/parser': ^5.0.0
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/parser': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq
'@typescript-eslint/scope-manager': 5.34.0
'@typescript-eslint/type-utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq
'@typescript-eslint/utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq
debug: 4.3.4 debug: 4.3.4
eslint: 8.22.0 eslint: 8.22.0
functional-red-black-tree: 1.0.1 functional-red-black-tree: 1.0.1
@@ -653,8 +618,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: /@typescript-eslint/parser/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==} resolution: {integrity: sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@@ -663,29 +628,9 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/scope-manager': 5.33.0 '@typescript-eslint/scope-manager': 5.35.1
'@typescript-eslint/types': 5.33.0 '@typescript-eslint/types': 5.35.1
'@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 '@typescript-eslint/typescript-estree': 5.35.1_typescript@4.7.4
debug: 4.3.4
eslint: 8.21.0
typescript: 4.7.4
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/parser/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-SZ3NEnK4usd2CXkoV3jPa/vo1mWX1fqRyIVUQZR4As1vyp4fneknBNJj+OFtV8WAVgGf+rOHMSqQbs2Qn3nFZQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 5.34.0
'@typescript-eslint/types': 5.34.0
'@typescript-eslint/typescript-estree': 5.34.0_typescript@4.7.4
debug: 4.3.4 debug: 4.3.4
eslint: 8.22.0 eslint: 8.22.0
typescript: 4.7.4 typescript: 4.7.4
@@ -693,24 +638,16 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/scope-manager/5.33.0: /@typescript-eslint/scope-manager/5.35.1:
resolution: {integrity: sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==} resolution: {integrity: sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies: dependencies:
'@typescript-eslint/types': 5.33.0 '@typescript-eslint/types': 5.35.1
'@typescript-eslint/visitor-keys': 5.33.0 '@typescript-eslint/visitor-keys': 5.35.1
dev: true dev: true
/@typescript-eslint/scope-manager/5.34.0: /@typescript-eslint/type-utils/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-HNvASMQlah5RsBW6L6c7IJ0vsm+8Sope/wu5sEAf7joJYWNb1LDbJipzmdhdUOnfrDFE6LR1j57x1EYVxrY4ow==} resolution: {integrity: sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.34.0
'@typescript-eslint/visitor-keys': 5.34.0
dev: true
/@typescript-eslint/type-utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq:
resolution: {integrity: sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: '*' eslint: '*'
@@ -719,26 +656,7 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq '@typescript-eslint/utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
debug: 4.3.4
eslint: 8.21.0
tsutils: 3.21.0_typescript@4.7.4
typescript: 4.7.4
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/type-utils/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-Pxlno9bjsQ7hs1pdWRUv9aJijGYPYsHpwMeCQ/Inavhym3/XaKt1ZKAA8FIw4odTBfowBdZJDMxf2aavyMDkLg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '*'
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq
debug: 4.3.4 debug: 4.3.4
eslint: 8.22.0 eslint: 8.22.0
tsutils: 3.21.0_typescript@4.7.4 tsutils: 3.21.0_typescript@4.7.4
@@ -747,18 +665,13 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/types/5.33.0: /@typescript-eslint/types/5.35.1:
resolution: {integrity: sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==} resolution: {integrity: sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true dev: true
/@typescript-eslint/types/5.34.0: /@typescript-eslint/typescript-estree/5.35.1_typescript@4.7.4:
resolution: {integrity: sha512-49fm3xbbUPuzBIOcy2CDpYWqy/X7VBkxVN+DC21e0zIm3+61Z0NZi6J9mqPmSW1BDVk9FIOvuCFyUPjXz93sjA==} resolution: {integrity: sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@typescript-eslint/typescript-estree/5.33.0_typescript@4.7.4:
resolution: {integrity: sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
@@ -766,8 +679,8 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/types': 5.33.0 '@typescript-eslint/types': 5.35.1
'@typescript-eslint/visitor-keys': 5.33.0 '@typescript-eslint/visitor-keys': 5.35.1
debug: 4.3.4 debug: 4.3.4
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
@@ -778,55 +691,16 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/typescript-estree/5.34.0_typescript@4.7.4: /@typescript-eslint/utils/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-mXHAqapJJDVzxauEkfJI96j3D10sd567LlqroyCeJaHnu42sDbjxotGb3XFtGPYKPD9IyLjhsoULML1oI3M86A==} resolution: {integrity: sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 5.34.0
'@typescript-eslint/visitor-keys': 5.34.0
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
semver: 7.3.7
tsutils: 3.21.0_typescript@4.7.4
typescript: 4.7.4
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq:
resolution: {integrity: sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies: dependencies:
'@types/json-schema': 7.0.11 '@types/json-schema': 7.0.11
'@typescript-eslint/scope-manager': 5.33.0 '@typescript-eslint/scope-manager': 5.35.1
'@typescript-eslint/types': 5.33.0 '@typescript-eslint/types': 5.35.1
'@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 '@typescript-eslint/typescript-estree': 5.35.1_typescript@4.7.4
eslint: 8.21.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0_eslint@8.21.0
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/@typescript-eslint/utils/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq:
resolution: {integrity: sha512-kWRYybU4Rn++7lm9yu8pbuydRyQsHRoBDIo11k7eqBWTldN4xUdVUMCsHBiE7aoEkFzrUEaZy3iH477vr4xHAQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
'@types/json-schema': 7.0.11
'@typescript-eslint/scope-manager': 5.34.0
'@typescript-eslint/types': 5.34.0
'@typescript-eslint/typescript-estree': 5.34.0_typescript@4.7.4
eslint: 8.22.0 eslint: 8.22.0
eslint-scope: 5.1.1 eslint-scope: 5.1.1
eslint-utils: 3.0.0_eslint@8.22.0 eslint-utils: 3.0.0_eslint@8.22.0
@@ -835,19 +709,11 @@ packages:
- typescript - typescript
dev: true dev: true
/@typescript-eslint/visitor-keys/5.33.0: /@typescript-eslint/visitor-keys/5.35.1:
resolution: {integrity: sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==} resolution: {integrity: sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies: dependencies:
'@typescript-eslint/types': 5.33.0 '@typescript-eslint/types': 5.35.1
eslint-visitor-keys: 3.3.0
dev: true
/@typescript-eslint/visitor-keys/5.34.0:
resolution: {integrity: sha512-O1moYjOSrab0a2fUvFpsJe0QHtvTC+cR+ovYpgKrAVXzqQyc74mv76TgY6z+aEtjQE2vgZux3CQVtGryqdcOAw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
'@typescript-eslint/types': 5.34.0
eslint-visitor-keys: 3.3.0 eslint-visitor-keys: 3.3.0
dev: true dev: true
@@ -2073,8 +1939,8 @@ packages:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: false dev: false
/compare-versions/4.1.3: /compare-versions/4.1.4:
resolution: {integrity: sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==} resolution: {integrity: sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==}
dev: false dev: false
/component-emitter/1.3.0: /component-emitter/1.3.0:
@@ -2224,8 +2090,8 @@ packages:
resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==}
dev: false dev: false
/daisyui/2.22.0_25hquoklqeoqwmt7fwvvcyxm5e: /daisyui/2.24.0_25hquoklqeoqwmt7fwvvcyxm5e:
resolution: {integrity: sha512-H08aQP+Mfl2fQOmyaxd1NP54gQbr2xRUj2MmFFvfJ5EDGbthVBICDMNFKyia/zBfR58G8eTJo3CmydglM81/7Q==} resolution: {integrity: sha512-Fdu/4LCdTfWLWAbCuPxvnaRotEfJ+hVPgZ2kv/aUk9RZ00Yk8fGdJtIf0kXJ3IgUKOr8rCXUpfQY6DQU9usPCQ==}
peerDependencies: peerDependencies:
autoprefixer: ^10.0.2 autoprefixer: ^10.0.2
postcss: ^8.1.6 postcss: ^8.1.6
@@ -2984,15 +2850,6 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dev: false dev: false
/eslint-config-prettier/8.5.0_eslint@8.21.0:
resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
eslint: 8.21.0
dev: true
/eslint-config-prettier/8.5.0_eslint@8.22.0: /eslint-config-prettier/8.5.0_eslint@8.22.0:
resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
hasBin: true hasBin: true
@@ -3019,13 +2876,13 @@ packages:
prettier-linter-helpers: 1.0.0 prettier-linter-helpers: 1.0.0
dev: true dev: true
/eslint-plugin-svelte3/4.0.0_a7wk4ghvg4hia4trwaglu7p6cq: /eslint-plugin-svelte3/4.0.0_laaqauvsmoyypsiqkozwyi2fn4:
resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==}
peerDependencies: peerDependencies:
eslint: '>=8.0.0' eslint: '>=8.0.0'
svelte: ^3.2.0 svelte: ^3.2.0
dependencies: dependencies:
eslint: 8.21.0 eslint: 8.22.0
svelte: 3.49.0 svelte: 3.49.0
dev: true dev: true
@@ -3045,16 +2902,6 @@ packages:
estraverse: 5.3.0 estraverse: 5.3.0
dev: true dev: true
/eslint-utils/3.0.0_eslint@8.21.0:
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
peerDependencies:
eslint: '>=5'
dependencies:
eslint: 8.21.0
eslint-visitor-keys: 2.1.0
dev: true
/eslint-utils/3.0.0_eslint@8.22.0: /eslint-utils/3.0.0_eslint@8.22.0:
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
@@ -3075,54 +2922,6 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true dev: true
/eslint/8.21.0:
resolution: {integrity: sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint/eslintrc': 1.3.0
'@humanwhocodes/config-array': 0.10.4
'@humanwhocodes/gitignore-to-minimatch': 1.0.2
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.1.1
eslint-utils: 3.0.0_eslint@8.21.0
eslint-visitor-keys: 3.3.0
espree: 9.3.3
esquery: 1.4.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
find-up: 5.0.0
functional-red-black-tree: 1.0.1
glob-parent: 6.0.2
globals: 13.15.0
globby: 11.1.0
grapheme-splitter: 1.0.4
ignore: 5.2.0
import-fresh: 3.3.0
imurmurhash: 0.1.4
is-glob: 4.0.3
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.1
regexpp: 3.2.0
strip-ansi: 6.0.1
strip-json-comments: 3.1.1
text-table: 0.2.0
v8-compile-cache: 2.3.0
transitivePeerDependencies:
- supports-color
dev: true
/eslint/8.22.0: /eslint/8.22.0:
resolution: {integrity: sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==} resolution: {integrity: sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3223,10 +3022,6 @@ packages:
engines: {node: '>=6'} engines: {node: '>=6'}
dev: false dev: false
/eventemitter3/4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
dev: false
/execa/6.1.0: /execa/6.1.0:
resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -4703,6 +4498,13 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/p-all/4.0.0:
resolution: {integrity: sha512-QXqMc8PpYu0gmNM6VcKP0uYqeI+dtvSNeaDb8ktnNjposr+nftHHCSYbj/S/oUceF6R868jw1XOxkJKUSiHgEQ==}
engines: {node: '>=12.20'}
dependencies:
p-map: 5.5.0
dev: false
/p-cancelable/3.0.0: /p-cancelable/3.0.0:
resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==}
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
@@ -4754,12 +4556,11 @@ packages:
p-limit: 3.1.0 p-limit: 3.1.0
dev: true dev: true
/p-queue/7.3.0: /p-map/5.5.0:
resolution: {integrity: sha512-5fP+yVQ0qp0rEfZoDTlP2c3RYBgxvRsw30qO+VtPPc95lyvSG+x6USSh1TuLB4n96IO6I8/oXQGsTgtna4q2nQ==} resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==}
engines: {node: '>=12'} engines: {node: '>=12'}
dependencies: dependencies:
eventemitter3: 4.0.7 aggregate-error: 4.0.1
p-timeout: 5.0.2
dev: false dev: false
/p-timeout/3.2.0: /p-timeout/3.2.0:
@@ -4769,11 +4570,6 @@ packages:
p-finally: 1.0.0 p-finally: 1.0.0
dev: false dev: false
/p-timeout/5.0.2:
resolution: {integrity: sha512-sEmji9Yaq+Tw+STwsGAE56hf7gMy9p0tQfJojIAamB7WHJYJKf1qlsg9jqBWG8q9VCxKPhZaP/AcXwEoBcYQhQ==}
engines: {node: '>=12'}
dev: false
/p-try/2.2.0: /p-try/2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -4954,8 +4750,8 @@ packages:
find-up: 3.0.0 find-up: 3.0.0
dev: false dev: false
/playwright-core/1.24.2: /playwright-core/1.25.1:
resolution: {integrity: sha512-zfAoDoPY/0sDLsgSgLZwWmSCevIg1ym7CppBwllguVBNiHeixZkc1AdMuYUPZC6AdEYc4CxWEyLMBTw2YcmRrA==} resolution: {integrity: sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
dev: true dev: true
@@ -5751,8 +5547,8 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
/svelte-check/2.8.0_vylzxgme5yisu3bsyvcau4hjtq: /svelte-check/2.8.1_vylzxgme5yisu3bsyvcau4hjtq:
resolution: {integrity: sha512-HRL66BxffMAZusqe5I5k26mRWQ+BobGd9Rxm3onh7ZVu0nTk8YTKJ9vu3LVPjUGLU9IX7zS+jmwPVhJYdXJ8vg==} resolution: {integrity: sha512-cibyY1sgt3ONIDnQbSgV2X9AJFhwEslRHNo95lijrYfPzVEvTvbmL2ohsUyqB5L7j1GhLXtQbjCJ4lZZ/fwbeQ==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
svelte: ^3.24.0 svelte: ^3.24.0
@@ -5988,7 +5784,7 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/ts-node/10.8.2_yuzmdm4dwbtqx7oi4ad7vmtwja: /ts-node/10.8.2_57uwcby55h6tzvkj3v5sfcgxoe:
resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -6007,7 +5803,7 @@ packages:
'@tsconfig/node12': 1.0.9 '@tsconfig/node12': 1.0.9
'@tsconfig/node14': 1.0.1 '@tsconfig/node14': 1.0.1
'@tsconfig/node16': 1.0.2 '@tsconfig/node16': 1.0.2
'@types/node': 18.7.11 '@types/node': 18.7.13
acorn: 8.8.0 acorn: 8.8.0
acorn-walk: 8.2.0 acorn-walk: 8.2.0
arg: 4.1.3 arg: 4.1.3