diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 3a62cc0..e528f07 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -318,6 +318,13 @@ "watchThrottled": true, "watchTriggerable": true, "watchWithFilter": true, - "whenever": true + "whenever": true, + "DirectiveBinding": true, + "MaybeRef": true, + "MaybeRefOrGetter": true, + "onWatcherCleanup": true, + "useId": true, + "useModel": true, + "useTemplateRef": true } } diff --git a/.nsprc b/.nsprc index 8d9b2e1..e69de29 100644 --- a/.nsprc +++ b/.nsprc @@ -1,6 +0,0 @@ -{ - "vue3-perfect-scrollbar": { - "active": true, - "notes": "Ignored since the latest version is not working with vue" - } -} diff --git a/.repo/product/diagrams.md b/.repo/product/diagrams.md new file mode 100644 index 0000000..45e1073 --- /dev/null +++ b/.repo/product/diagrams.md @@ -0,0 +1,57 @@ +Here's a brief explanation of Vulnetix as of Sept + +This sequence diagram illustrates from the user's initial actions in the GitHub Marketplace to the final steps performed by Vulnetix Cloud. + +```mermaid +sequenceDiagram + actor User + participant GM as GitHub Marketplace + participant VC as Vulnetix Cloud + participant GH as GitHub + participant OSV as OSV.dev + participant FIRST as FIRST.org + + User->>GM: Choose Install + User->>GM: Select Plan + User->>VC: Integrate App with Vulnetix Cloud + VC->>GH: Obtain OAuth credentials + Note over VC,GH: Supports "Login with GitHub" + + VC->>GH: Pull repositories information + VC->>GH: Pull SARIF from CodeQL SAST scans + VC->>GH: Pull Dependency Graph + Note over VC,GH: For SPDX SBOM creation + + VC->>VC: Correlate with vulnerability database + VC->>OSV: Check for new information + + alt New information found + VC->>VC: Process new information + else No new information + VC->>VC: Generate VEX + VC->>VC: Queue finding for triage + end + + VC->>VC: Use CVSS vectors for prioritization + VC->>VC: Correlate with exploit database + VC->>FIRST: Check for EPSS information + VC->>VC: Calculate SSVC decision + VC->>VC: Pix automates outcomes + VC->>VC: Generate VEX +``` + +Here's a brief explanation of the diagram: + +1. The user starts by choosing to install and selecting a plan in the GitHub Marketplace. +2. The user then integrates the app with Vulnetix Cloud. +3. Vulnetix Cloud obtains OAuth credentials from GitHub for "Login with GitHub" functionality. +4. Vulnetix pulls various data from GitHub, including repository information, SARIF from CodeQL scans, and the Dependency Graph. +5. Vulnetix then performs several internal processes: + - Correlates data with its vulnerability database + - Checks for new information from OSV.dev + - Uses CVSS vectors for prioritisation + - Correlates with its exploit database + - Checks for EPSS information from FIRST.org + - Calculates an SSVC decision +6. Throughout the process, when there's no new information, Vulnetix generates a VEX and queues the finding for triage. +7. Finally, Pix automates outcomes and provides a VEX. diff --git a/.repo/scratchad.sql b/.repo/scratchad.sql new file mode 100644 index 0000000..3210739 --- /dev/null +++ b/.repo/scratchad.sql @@ -0,0 +1,12 @@ +-- PRAGMA table_list; +-- PRAGMA table_info(Artifact); +-- DELETE FROM Artifact; +-- SELECT * FROM IntegrationConfig -- ORDER BY `date` DESC LIMIT 10; +-- UPDATE Finding SET malicious = 0; +-- SELECT * FROM SPDXInfo LIMIT 10; +-- SELECT DISTINCT malicious FROM Finding; +-- ALTER TABLE Finding DROP COLUMN malicious; +-- ALTER TABLE Finding ADD malicious INTEGER; +SELECT * +FROM Finding +WHERE cvssVectorString IS NOT NULL; diff --git a/.vscode/settings.json b/.vscode/settings.json index 439183f..70735c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,5 +29,14 @@ "source.fixAll.stylelint": "explicit", "source.organizeImports": "explicit" }, - "eslint.format.enable": true + "eslint.format.enable": true, + "sqltools.connections": [ + { + "previewLimit": 1000, + "driver": "SQLite", + "name": "vulnetix", + "database": "${workspaceFolder:vulnetix}/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/5739f20a3d0d5e6506506143f65618856465fde8eb11c9ee70bd2ebed4ac5dd4.sqlite" + } + ], + "sqltools.useNodeRuntime": true } diff --git a/Makefile b/Makefile index 98e0737..5f40ba1 100644 --- a/Makefile +++ b/Makefile @@ -60,20 +60,20 @@ git-demo: git stash pop || true _purge_data: ## FOR DOCO ONLY - npx wrangler d1 execute vulnetix --local --command "DELETE FROM findings;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM triage_activity;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM git_repos;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM sarif;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM sarif_results;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM spdx;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM cdx;" - npx wrangler d1 execute vulnetix --local --command "DELETE FROM integration_usage_log;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM Finding;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM Triage;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM GitRepo;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM SARIFInfo;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM SarifResults;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM CycloneDXInfo;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM SPDXInfo;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM IntegrationUsageLog;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM Link;" + npx wrangler d1 execute vulnetix --local --command "DELETE FROM Artifact;" _helpers: ## FOR DOCO ONLY npx wrangler d1 execute vulnetix --local --file ./migrations/0001_init.sql - npx wrangler d1 execute vulnetix --local --command "PRAGMA table_list;" - npx wrangler d1 execute vulnetix --local --command "PRAGMA table_info(members);" - npx wrangler d1 execute vulnetix --local --command "SELECT * FROM members;" + npx wrangler d1 execute vulnetix --local --command "SELECT * FROM Member;" npx prisma migrate diff \ --from-empty \ --to-schema-datamodel ./prisma/schema.prisma \ diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 7742dd1..fe2545a 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -79,6 +79,7 @@ declare global { const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] const onUnmounted: typeof import('vue')['onUnmounted'] const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] const provide: typeof import('vue')['provide'] const provideLocal: typeof import('@vueuse/core')['provideLocal'] @@ -195,6 +196,7 @@ declare global { const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] const useGamepad: typeof import('@vueuse/core')['useGamepad'] const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] + const useId: typeof import('vue')['useId'] const useIdle: typeof import('@vueuse/core')['useIdle'] const useImage: typeof import('@vueuse/core')['useImage'] const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] @@ -214,6 +216,7 @@ declare global { const useMemoize: typeof import('@vueuse/core')['useMemoize'] const useMemory: typeof import('@vueuse/core')['useMemory'] const useMin: typeof import('@vueuse/math')['useMin'] + const useModel: typeof import('vue')['useModel'] const useMounted: typeof import('@vueuse/core')['useMounted'] const useMouse: typeof import('@vueuse/core')['useMouse'] const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] @@ -265,6 +268,7 @@ declare global { const useSum: typeof import('@vueuse/math')['useSum'] const useSupported: typeof import('@vueuse/core')['useSupported'] const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] @@ -317,7 +321,7 @@ declare global { // for type re-export declare global { // @ts-ignore - export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') } // for vue template auto import @@ -398,6 +402,7 @@ declare module 'vue' { readonly onStartTyping: UnwrapRef readonly onUnmounted: UnwrapRef readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef readonly pausableWatch: UnwrapRef readonly provide: UnwrapRef readonly provideLocal: UnwrapRef @@ -514,6 +519,7 @@ declare module 'vue' { readonly useFullscreen: UnwrapRef readonly useGamepad: UnwrapRef readonly useGeolocation: UnwrapRef + readonly useId: UnwrapRef readonly useIdle: UnwrapRef readonly useImage: UnwrapRef readonly useInfiniteScroll: UnwrapRef @@ -533,6 +539,7 @@ declare module 'vue' { readonly useMemoize: UnwrapRef readonly useMemory: UnwrapRef readonly useMin: UnwrapRef + readonly useModel: UnwrapRef readonly useMounted: UnwrapRef readonly useMouse: UnwrapRef readonly useMouseInElement: UnwrapRef @@ -584,6 +591,7 @@ declare module 'vue' { readonly useSum: UnwrapRef readonly useSupported: UnwrapRef readonly useSwipe: UnwrapRef + readonly useTemplateRef: UnwrapRef readonly useTemplateRefsList: UnwrapRef readonly useTextDirection: UnwrapRef readonly useTextSelection: UnwrapRef diff --git a/components.d.ts b/components.d.ts index a515c1d..2546166 100644 --- a/components.d.ts +++ b/components.d.ts @@ -11,6 +11,7 @@ declare module '@vue/runtime-core' { export interface GlobalComponents { AppBarSearch: typeof import('./src/@core/components/AppBarSearch.vue')['default'] AppSearchHeader: typeof import('./src/@core/components/AppSearchHeader.vue')['default'] + AppSelect: typeof import('./src/@core/components/AppSelect.vue')['default'] CardStatisticsHorizontal: typeof import('./src/@core/components/cards/CardStatisticsHorizontal.vue')['default'] CardStatisticsVertical: typeof import('./src/@core/components/cards/CardStatisticsVertical.vue')['default'] CardStatisticsWithImages: typeof import('./src/@core/components/cards/CardStatisticsWithImages.vue')['default'] diff --git a/functions/cdx/results.js b/functions/cdx/results.js deleted file mode 100644 index 5c8d62b..0000000 --- a/functions/cdx/results.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Server } from "@/utils"; -import { PrismaD1 } from '@prisma/adapter-d1'; -import { PrismaClient } from '@prisma/client'; - -export async function onRequestGet(context) { - const { - request, // same as existing Worker API - env, // same as existing Worker API - params, // if filename includes [id] or [[path]] - waitUntil, // same as ctx.waitUntil in existing Worker API - next, // used for middleware or to fetch assets - data, // arbitrary space for passing data between middlewares - } = context - const adapter = new PrismaD1(env.d1db) - const prisma = new PrismaClient({ - adapter, - transactionOptions: { - maxWait: 1500, // default: 2000 - timeout: 2000, // default: 5000 - }, - }) - const verificationResult = await (new Server(request, prisma)).authenticate() - if (!verificationResult.isValid) { - return Response.json({ ok: false, result: verificationResult.message }) - } - const { searchParams } = new URL(request.url) - const take = parseInt(searchParams.get('take'), 10) || 50 - const skip = parseInt(searchParams.get('skip'), 10) || 0 - const cdx = await prisma.cdx.findMany({ - where: { - memberEmail: verificationResult.session.memberEmail, - }, - omit: { - memberEmail: true, - }, - include: { - repo: true, - }, - take, - skip, - orderBy: { - createdAt: 'desc', - }, - }) - - return Response.json({ ok: true, cdx }) -} diff --git a/functions/enrich/[findingKey].js b/functions/enrich/[findingKey].js deleted file mode 100644 index 7ffddfb..0000000 --- a/functions/enrich/[findingKey].js +++ /dev/null @@ -1,165 +0,0 @@ -import { AuthResult, EPSS, OSV, Server } from "@/utils"; -import { CVSS30, CVSS31, CVSS40 } from '@pandatix/js-cvss'; -import { PrismaD1 } from '@prisma/adapter-d1'; -import { PrismaClient } from '@prisma/client'; - -export async function onRequestGet(context) { - const { - request, // same as existing Worker API - env, // same as existing Worker API - params, // if filename includes [id] or [[path]] - waitUntil, // same as ctx.waitUntil in existing Worker API - next, // used for middleware or to fetch assets - data, // arbitrary space for passing data between middlewares - } = context - try { - const adapter = new PrismaD1(env.d1db) - const prisma = new PrismaClient({ - adapter, - transactionOptions: { - maxWait: 1500, // default: 2000 - timeout: 2000, // default: 5000 - }, - }) - const verificationResult = await (new Server(request, prisma)).authenticate() - if (!verificationResult.isValid) { - return Response.json({ ok: false, result: verificationResult.message }) - } - const { findingKey } = params - const originalFinding = await prisma.findings.findUnique({ - where: { - id: parseInt(findingKey, 10), - }, - omit: { - memberEmail: true, - }, - include: { - triage: true, - spdx: { - include: { - repo: true - } - }, - cdx: { - include: { - repo: true - } - } - } - }) - const finding = { - ...originalFinding, - cwes: JSON.parse(originalFinding.cwes ?? '[]'), - aliases: JSON.parse(originalFinding.aliases ?? '[]'), - referencesJSON: JSON.parse(originalFinding.referencesJSON ?? '[]'), - } - - finding.fullName = finding.cdx?.repo?.fullName || finding.spdx?.repo?.fullName || 'Others' - const osv = new OSV() - const vuln = await osv.query(prisma, verificationResult.session.memberEmail, finding.detectionTitle) - finding.modifiedAt = (new Date(vuln.modified)).getTime() - finding.publishedAt = (new Date(vuln.published)).getTime() - finding.databaseReviewed = vuln?.database_specific?.github_reviewed ? 1 : 0 - finding.cve = vuln?.aliases?.filter(a => a.startsWith('CVE-')).pop() - finding.aliases = JSON.stringify(vuln?.aliases || []) - finding.cwes = JSON.stringify(vuln?.database_specific?.cwe_ids || []) - finding.packageEcosystem = vuln.affected.map(affected => affected.package.ecosystem).pop() - finding.sourceCodeUrl = vuln.affected.map(affected => affected.database_specific.source).pop() - finding.fixVersion = vuln.affected.map(affected => affected.ranges.pop()?.events.pop()?.fixed).pop() - finding.vulnerableVersionRange = vuln.affected.map(affected => affected.database_specific.last_known_affected_version_range).pop() - finding.fixAutomatable = !!finding.vulnerableVersionRange && !!finding.fixVersion ? 1 : 0 - finding.referencesJSON = JSON.stringify(vuln.references.map(reference => reference.url)) - const info = await prisma.findings.update({ - where: { - id: finding.id, - }, - data: { - modifiedAt: finding.modifiedAt, - publishedAt: finding.publishedAt, - databaseReviewed: finding.databaseReviewed, - cve: finding.cve, - aliases: finding.aliases, - cwes: finding.cwes, - packageEcosystem: finding.packageEcosystem, - sourceCodeUrl: finding.sourceCodeUrl, - fixVersion: finding.fixVersion, - vulnerableVersionRange: finding.vulnerableVersionRange, - fixAutomatable: finding.fixAutomatable, - referencesJSON: finding.referencesJSON, - } - }) - console.log(`Update ${finding.detectionTitle}`, info) - let scores - if (finding.cve) { - const epss = new EPSS() - scores = await epss.query(prisma, verificationResult.session.memberEmail, finding.cve) - } - let epssScore, epssPercentile; - if (scores?.epss) { - epssScore = parseFloat(scores.epss) - epssPercentile = parseFloat(scores.percentile) - } - const cvss4 = vuln?.severity?.filter(i => i.score.startsWith('CVSS:4/'))?.pop() - const cvss31 = vuln?.severity?.filter(i => i.score.startsWith('CVSS:3.1/'))?.pop() - const cvss3 = vuln?.severity?.filter(i => i.score.startsWith('CVSS:3/'))?.pop() - const cvssVector = !!cvss4 ? new CVSS40(cvss4.score) : !!cvss31 ? new CVSS31(cvss31.score) : cvss3 ? new CVSS30(cvss3.score) : null - // Decision - // Methodology - // Exploitation - // TechnicalImpact - // Automatable - // MissionWellbeingImpact - - const { searchParams } = new URL(request.url) - const seen = parseInt(searchParams.get('seen'), 10) || 0 - let { analysisState = 'in_triage', triageAutomated = 0, triagedAt = null, seenAt = null } = finding?.triage || {} - if ( - (cvssVector && ( - ['E:U', 'E:P', 'E:F', 'E:H'].some(substring => cvss3?.score?.includes(substring)) || - ['E:A', 'E:P', 'E:U'].some(substring => cvss4?.score?.includes(substring)) - )) || epssPercentile > 0.2 - ) { - analysisState = 'exploitable' - triageAutomated = 1 - if (!triagedAt) { - triagedAt = new Date().getTime() - } - } - if (seen === 1) { - seenAt = new Date().getTime() - } - if (!finding?.triage) { - finding.triage = { - findingKey: finding.id, - createdAt: new Date().getTime(), - lastObserved: new Date().getTime(), - } - } - finding.triage.analysisState = analysisState - finding.triage.triageAutomated = triageAutomated - finding.triage.triagedAt = triagedAt - finding.triage.cvssVector = !!cvss4 ? cvss4.score : !!cvss31 ? cvss31.score : cvss3 ? cvss3.score : null - finding.triage.cvssScore = !!cvss4 ? cvssVector.Score().toString() : !!cvss31 ? cvssVector.BaseScore().toString() : cvss3 ? cvssVector.BaseScore().toString() : null - if (epssPercentile) { - finding.triage.epssPercentile = epssPercentile.toString() - } - if (epssScore) { - finding.triage.epssScore = epssScore.toString() - } - finding.triage.seen = seen - finding.triage.seenAt = seenAt - const vexInfo = await prisma.triage_activity.upsert({ - where: { - findingKey: finding.id, - }, - update: finding.triage, - create: finding.triage, - }) - console.log(`Saved VEX ${finding.detectionTitle}`, vexInfo) - - return Response.json({ ok: true, finding }) - } catch (err) { - console.error(err) - return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) - } -} diff --git a/functions/spdx/results.js b/functions/spdx/results.js deleted file mode 100644 index d02b72a..0000000 --- a/functions/spdx/results.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Server } from "@/utils"; -import { PrismaD1 } from '@prisma/adapter-d1'; -import { PrismaClient } from '@prisma/client'; - -export async function onRequestGet(context) { - const { - request, // same as existing Worker API - env, // same as existing Worker API - params, // if filename includes [id] or [[path]] - waitUntil, // same as ctx.waitUntil in existing Worker API - next, // used for middleware or to fetch assets - data, // arbitrary space for passing data between middlewares - } = context - const adapter = new PrismaD1(env.d1db) - const prisma = new PrismaClient({ - adapter, - transactionOptions: { - maxWait: 1500, // default: 2000 - timeout: 2000, // default: 5000 - }, - }) - const verificationResult = await (new Server(request, prisma)).authenticate() - if (!verificationResult.isValid) { - return Response.json({ ok: false, result: verificationResult.message }) - } - const { searchParams } = new URL(request.url) - const take = parseInt(searchParams.get('take'), 10) || 50 - const skip = parseInt(searchParams.get('skip'), 10) || 0 - const spdx = await prisma.spdx.findMany({ - where: { - memberEmail: verificationResult.session.memberEmail, - }, - omit: { - memberEmail: true, - comment: true, - documentNamespace: true, - documentDescribes: true, - }, - take, - skip, - orderBy: { - createdAt: 'desc', - }, - }) - - return Response.json({ ok: true, spdx }) -} diff --git a/functions/v0.2.0/collection/[collectionId].js b/functions/tea/collection/[collectionId].js similarity index 94% rename from functions/v0.2.0/collection/[collectionId].js rename to functions/tea/collection/[collectionId].js index 622bcec..df42b3b 100644 --- a/functions/v0.2.0/collection/[collectionId].js +++ b/functions/tea/collection/[collectionId].js @@ -1,4 +1,3 @@ -import { Collection } from "@/tea"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; @@ -30,7 +29,7 @@ export async function onRequestGet(context) { }) params.collectionId // id assigned in the system to the specific collection as returned by collection element - // const member = await prisma.members.findFirst({ + // const member = await prisma.Member.findFirst({ // where: { // email: verificationResult.session.memberEmail, // }, diff --git a/functions/v0.2.0/leaf/[tei].js b/functions/tea/leaf/[tei].js similarity index 95% rename from functions/v0.2.0/leaf/[tei].js rename to functions/tea/leaf/[tei].js index c9187e8..298cb13 100644 --- a/functions/v0.2.0/leaf/[tei].js +++ b/functions/tea/leaf/[tei].js @@ -1,4 +1,4 @@ -import { Visibility, CollectionEl } from "@/tea"; +import { Visibility } from "@/tea"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; @@ -35,7 +35,7 @@ export async function onRequestGet(context) { return Response(null, { status: 422, statusText: `Invalid value provided: visibility=${visibility}` }) } - // const member = await prisma.members.findFirst({ + // const member = await prisma.Member.findFirst({ // where: { // email: verificationResult.session.memberEmail, // }, diff --git a/functions/v0.2.0/product/[tei].js b/functions/tea/product/[tei].js similarity index 95% rename from functions/v0.2.0/product/[tei].js rename to functions/tea/product/[tei].js index 1291b3d..27025f7 100644 --- a/functions/v0.2.0/product/[tei].js +++ b/functions/tea/product/[tei].js @@ -1,4 +1,4 @@ -import { Visibility, Product } from "@/tea"; +import { Visibility } from "@/tea"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; @@ -35,7 +35,7 @@ export async function onRequestGet(context) { return Response(null, { status: 422, statusText: `Invalid value provided: visibility=${visibility}` }) } - // const member = await prisma.members.findFirst({ + // const member = await prisma.Member.findFirst({ // where: { // email: verificationResult.session.memberEmail, // }, diff --git a/functions/history.js b/functions/v1/[analysisState]/issues.js similarity index 57% rename from functions/history.js rename to functions/v1/[analysisState]/issues.js index 1ce1554..13002f8 100644 --- a/functions/history.js +++ b/functions/v1/[analysisState]/issues.js @@ -25,16 +25,17 @@ export async function onRequestGet(context) { return Response.json({ ok: false, result: verificationResult.message }) } const { searchParams } = new URL(request.url) + const analysisState = searchParams.get('analysisState') || 'in_triage' const take = parseInt(searchParams.get('take'), 10) || 50 const skip = parseInt(searchParams.get('skip'), 10) || 0 - const findings = await prisma.findings.findMany({ + const findings = await prisma.Finding.findMany({ where: { - memberEmail: verificationResult.session.memberEmail, - NOT: { + orgId: verificationResult.session.orgId, + AND: { triage: { - analysisState: 'in_triage' + every: { analysisState } } - } + }, }, omit: { memberEmail: true, @@ -58,37 +59,16 @@ export async function onRequestGet(context) { createdAt: 'asc', } }) - const parsed = findings.map(result => ({ - ...result, - cwes: JSON.parse(result.cwes ?? '[]'), - aliases: JSON.parse(result.aliases ?? '[]'), - referencesJSON: JSON.parse(result.referencesJSON ?? '[]') - }) - ) - // const groupedByRepo = parsed.reduce((acc, result) => { - // const repoFullName = result.spdx?.repo?.fullName || 'Others' - // if (!acc[repoFullName]) { - // acc[repoFullName] = [] - // } - // result.fullName = repoFullName - // acc[repoFullName].push(result) - // return acc - // }, {}) - // // Sort results within each repo group by packageName + packageVersion - // for (const repoFullName in groupedByRepo) { - // groupedByRepo[repoFullName].sort((a, b) => { - // const aPackage = `${a.packageName}${a.packageVersion}` - // const bPackage = `${b.packageName}${b.packageVersion}` - // return aPackage.localeCompare(bPackage) - // }) - // } - const results = parsed.map(result => { - result.fullName = result.spdx?.repo?.fullName || 'Others' - return result + return Response.json({ + ok: true, findings: findings.map(finding => { + finding.references = JSON.parse(finding.referencesJSON) + delete finding.referencesJSON + finding.aliases = JSON.parse(finding.aliases) + finding.cwes = JSON.parse(finding.cwes) + return finding + }) }) - - return Response.json({ ok: true, results }) } catch (err) { console.error(err) return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) diff --git a/functions/vulncheck/integrate.js b/functions/v1/[source]/integration.js similarity index 53% rename from functions/vulncheck/integrate.js rename to functions/v1/[source]/integration.js index 14d7910..6a59541 100644 --- a/functions/vulncheck/integrate.js +++ b/functions/v1/[source]/integration.js @@ -12,6 +12,9 @@ export async function onRequestPost(context) { data, // arbitrary space for passing data between middlewares } = context try { + if (!['osv', 'first', 'vulncheck', 'github', 'mitre-cve'].includes((params?.source || '').toLowerCase())) { + return Response.json({ ok: false, error: { message: `Invalid log source` }, results: [] }) + } const adapter = new PrismaD1(env.d1db) const prisma = new PrismaClient({ adapter, @@ -26,28 +29,35 @@ export async function onRequestPost(context) { } const bodyStr = await ensureStrReqBody(request) const data = JSON.parse(bodyStr) - if (!data.apiKey.startsWith('vulncheck_')) { - return Response.json({ error: { message: `Invalid API Key provided, expected "vulncheck_" prefix.` } }) - } const where = { - memberEmail: verificationResult.session.memberEmail, - keyType: 'vulncheck', + orgId: verificationResult.session.orgId, + AND: { name: params.source }, } - const original = await prisma.member_keys.findFirst({ where }) - if (data.apiKey !== original?.secret) { - let info - if (original === null) { - const params = Object.assign({}, where) - params.secret = data.apiKey - info = await prisma.member_keys.create({ data: params }) - } else { - info = await prisma.member_keys.update({ where, data: { secret: data.apiKey } }) - } - + const original = await prisma.IntegrationConfig.findFirst({ where }) + if (original === null) { + const info = await prisma.IntegrationConfig.create({ + data: { + orgId: verificationResult.session.orgId, + name: params.source, + created: new Date().getTime(), + suspend: data?.suspend === undefined ? 0 : (data.suspend ? 1 : 0), + } + }) return Response.json({ ok: true, info }) } + if ((data?.suspend ? 1 : 0) === original.suspend) { + return Response.json({ ok: false, result: 'No Change' }) + } + const info = await prisma.IntegrationConfig.update({ + where: { + uuid: original.uuid + }, + data: { + suspend: data?.suspend === undefined ? original.suspend : (data.suspend ? 1 : 0), + } + }) + return Response.json({ ok: true, info }) - return Response.json({ ok: false, result: 'No Change' }) } catch (err) { console.error(err) return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) diff --git a/functions/[source]/log.js b/functions/v1/[source]/log.js similarity index 79% rename from functions/[source]/log.js rename to functions/v1/[source]/log.js index c434044..f6bcb65 100644 --- a/functions/[source]/log.js +++ b/functions/v1/[source]/log.js @@ -12,6 +12,9 @@ export async function onRequestGet(context) { data, // arbitrary space for passing data between middlewares } = context try { + if (!['osv', 'first', 'vulncheck', 'github', 'mitre-cve'].includes((params?.source || '').toLowerCase())) { + return Response.json({ ok: false, error: { message: `Invalid log source` }, results: [] }) + } const adapter = new PrismaD1(env.d1db) const prisma = new PrismaClient({ adapter, @@ -22,17 +25,14 @@ export async function onRequestGet(context) { }) const verificationResult = await (new Server(request, prisma)).authenticate() if (!verificationResult.isValid) { - return Response.json({ ok: false, result: verificationResult.message }) - } - if (!['osv', 'first', 'vulncheck', 'github'].includes((params?.source || '').toLowerCase())) { - return Response.json({ ok: false, error: { message: `Invalid log source` } }) + return Response.json({ ok: false, result: verificationResult.message, results: [] }) } const { searchParams } = new URL(request.url) const take = parseInt(searchParams.get('take'), 10) || 50 const skip = parseInt(searchParams.get('skip'), 10) || 0 - const results = await prisma.integration_usage_log.findMany({ + let results = await prisma.IntegrationUsageLog.findMany({ where: { - memberEmail: verificationResult.session.memberEmail, + orgId: verificationResult.session.orgId, source: params?.source, }, take, @@ -41,10 +41,13 @@ export async function onRequestGet(context) { createdAt: 'desc', }, }) + if (!results) { + results = [] + } return Response.json({ ok: true, results }) } catch (err) { console.error(err) - return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) + return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED, results: [] }) } } diff --git a/functions/analytics.js b/functions/v1/analytics.js similarity index 59% rename from functions/analytics.js rename to functions/v1/analytics.js index 64f2049..4374b8e 100644 --- a/functions/analytics.js +++ b/functions/v1/analytics.js @@ -26,9 +26,9 @@ export async function onRequestGet(context) { return Response.json({ ok: false, result: verificationResult.message }) } - const findings = await prisma.findings.findMany({ + const findings = await prisma.Finding.findMany({ where: { - memberEmail: verificationResult.session.memberEmail, + orgId: verificationResult.session.orgId, }, omit: { memberEmail: true, @@ -56,7 +56,7 @@ export async function onRequestGet(context) { month_to_date: filterFindingsByPeriod(findings, 'month_to_date'), year_to_date: filterFindingsByPeriod(findings, 'year_to_date'), publishedMonthly: calculateMonthlyCounts(findings, 'publishedAt'), - observedMonthly: calculateMonthlyCounts(findings, 'lastObserved'), + discoveredMonthly: calculateMonthlyCounts(findings, 'createdAt'), triagedMonthly: calculateMonthlyCounts(findings, 'triagedAt'), } }) @@ -110,40 +110,40 @@ function calculateMonthlyCounts(parsed, dateField) { function makeAnalysis(arr) { const data = { total_findings: arr.length, - triage_automated: arr.filter(f => f.triage.analysisState !== 'in_triage' && f.triage.triageAutomated === 1).length, - triaged: arr.filter(f => f.triage.analysisState !== 'in_triage').length, - queued: arr.filter(f => ['in_triage', 'exploitable'].includes(f.triage.analysisState)).length, - queued_unseen: arr.filter(f => ['in_triage', 'exploitable'].includes(f.triage.analysisState) && f.triage.seen === 0).length, - ssvc_act: arr.filter(f => f.triage.ssvc === ActionCISA.ACT).length, - ssvc_attend: arr.filter(f => f.triage.ssvc === ActionCISA.ATTEND).length, - ssvc_track: arr.filter(f => f.triage.ssvc === ActionCISA.TRACK).length, - ssvc_track_star: arr.filter(f => f.triage.ssvc === ActionCISA.TRACK_STAR).length, - ssvc_immediate: arr.filter(f => f.triage.ssvc === ActionFIRST.IMMEDIATE).length, - ssvc_oob: arr.filter(f => f.triage.ssvc === ActionFIRST.OUT_OF_BAND).length, - ssvc_scheduled: arr.filter(f => f.triage.ssvc === ActionFIRST.SCHEDULED).length, - in_triage: arr.filter(f => f.triage.analysisState === 'in_triage').length, - in_triage_unseen: arr.filter(f => f.triage.analysisState === 'in_triage' && f.triage.seen === 0).length, - resolved: arr.filter(f => f.triage.analysisState === 'resolved').length, - resolved_with_pedigree: arr.filter(f => f.triage.analysisState === 'resolved_with_pedigree').length, - resolved_all: arr.filter(f => ['resolved_with_pedigree', 'resolved'].includes(f.triage.analysisState)).length, - exploitable: arr.filter(f => f.triage.analysisState === 'exploitable').length, - exploitable_unseen: arr.filter(f => f.triage.analysisState === 'exploitable' && f.triage.seen === 0).length, - false_positive: arr.filter(f => f.triage.analysisState === 'false_positive').length, - not_affected: arr.filter(f => f.triage.analysisState === 'not_affected').length, - code_not_present: arr.filter(f => f.triage.analysisJustification === 'code_not_present').length, - code_not_reachable: arr.filter(f => f.triage.analysisJustification === 'code_not_reachable').length, - requires_configuration: arr.filter(f => f.triage.analysisJustification === 'requires_configuration').length, - requires_dependency: arr.filter(f => f.triage.analysisJustification === 'requires_dependency').length, - requires_environment: arr.filter(f => f.triage.analysisJustification === 'requires_environment').length, - protected_by_compiler: arr.filter(f => f.triage.analysisJustification === 'protected_by_compiler').length, - protected_at_runtime: arr.filter(f => f.triage.analysisJustification === 'protected_at_runtime').length, - protected_at_perimeter: arr.filter(f => f.triage.analysisJustification === 'protected_at_perimeter').length, - protected_by_mitigating_control: arr.filter(f => f.triage.analysisJustification === 'protected_by_mitigating_control').length, - can_not_fix: arr.filter(f => f.triage.analysisResponse === 'can_not_fix').length, - will_not_fix: arr.filter(f => f.triage.analysisResponse === 'will_not_fix').length, - update: arr.filter(f => f.triage.analysisResponse === 'update').length, - rollback: arr.filter(f => f.triage.analysisResponse === 'rollback').length, - workaround_available: arr.filter(f => f.triage.analysisResponse === 'workaround_available').length, + triage_automated: arr.filter(f => f.triage.some(t => t.analysisState !== 'in_triage' && t.triageAutomated === 1)).length, + triaged: arr.filter(f => f.triage.some(t => t.analysisState !== 'in_triage')).length, + queued: arr.filter(f => f.triage.some(t => ['in_triage', 'exploitable'].includes(t.analysisState))).length, + queued_unseen: arr.filter(f => f.triage.some(t => ['in_triage', 'exploitable'].includes(t.analysisState) && t.seen === 0)).length, + ssvc_act: arr.filter(f => f.triage.some(t => t.ssvc === ActionCISA.ACT)).length, + ssvc_attend: arr.filter(f => f.triage.some(t => t.ssvc === ActionCISA.ATTEND)).length, + ssvc_track: arr.filter(f => f.triage.some(t => t.ssvc === ActionCISA.TRACK)).length, + ssvc_track_star: arr.filter(f => f.triage.some(t => t.ssvc === ActionCISA.TRACK_STAR)).length, + ssvc_immediate: arr.filter(f => f.triage.some(t => t.ssvc === ActionFIRST.IMMEDIATE)).length, + ssvc_oob: arr.filter(f => f.triage.some(t => t.ssvc === ActionFIRST.OUT_OF_BAND)).length, + ssvc_scheduled: arr.filter(f => f.triage.some(t => t.ssvc === ActionFIRST.SCHEDULED)).length, + in_triage: arr.filter(f => f.triage.some(t => t.analysisState === 'in_triage')).length, + in_triage_unseen: arr.filter(f => f.triage.some(t => t.analysisState === 'in_triage' && t.seen === 0)).length, + resolved: arr.filter(f => f.triage.some(t => t.analysisState === 'resolved')).length, + resolved_with_pedigree: arr.filter(f => f.triage.some(t => t.analysisState === 'resolved_with_pedigree')).length, + resolved_all: arr.filter(f => f.triage.some(t => ['resolved_with_pedigree', 'resolved'].includes(t.analysisState))).length, + exploitable: arr.filter(f => f.triage.some(t => t.analysisState === 'exploitable')).length, + exploitable_unseen: arr.filter(f => f.triage.some(t => t.analysisState === 'exploitable' && t.seen === 0)).length, + false_positive: arr.filter(f => f.triage.some(t => t.analysisState === 'false_positive')).length, + not_affected: arr.filter(f => f.triage.some(t => t.analysisState === 'not_affected')).length, + code_not_present: arr.filter(f => f.triage.some(t => t.analysisJustification === 'code_not_present')).length, + code_not_reachable: arr.filter(f => f.triage.some(t => t.analysisJustification === 'code_not_reachable')).length, + requires_configuration: arr.filter(f => f.triage.some(t => t.analysisJustification === 'requires_configuration')).length, + requires_dependency: arr.filter(f => f.triage.some(t => t.analysisJustification === 'requires_dependency')).length, + requires_environment: arr.filter(f => f.triage.some(t => t.analysisJustification === 'requires_environment')).length, + protected_by_compiler: arr.filter(f => f.triage.some(t => t.analysisJustification === 'protected_by_compiler')).length, + protected_at_runtime: arr.filter(f => f.triage.some(t => t.analysisJustification === 'protected_at_runtime')).length, + protected_at_perimeter: arr.filter(f => f.triage.some(t => t.analysisJustification === 'protected_at_perimeter')).length, + protected_by_mitigating_control: arr.filter(f => f.triage.some(t => t.analysisJustification === 'protected_by_mitigating_control')).length, + can_not_fix: arr.filter(f => f.triage.some(t => t.analysisResponse === 'can_not_fix')).length, + will_not_fix: arr.filter(f => f.triage.some(t => t.analysisResponse === 'will_not_fix')).length, + update: arr.filter(f => f.triage.some(t => t.analysisResponse === 'update')).length, + rollback: arr.filter(f => f.triage.some(t => t.analysisResponse === 'rollback')).length, + workaround_available: arr.filter(f => f.triage.some(t => t.analysisResponse === 'workaround_available')).length, } data.unresolved_percentage = calcPercent(data, ['queued'], ['total_findings']) data.resolved_percentage = calcPercent(data, ['resolved', 'resolved_with_pedigree'], ['total_findings']) @@ -202,7 +202,7 @@ const filterFindingsByPeriod = (arr, period = 'current_week') => { throw new Error('Unsupported period') } - const filteredFindings = arr.filter(f => isWithinPeriod(f.triage.lastObserved, startDate, endDate)) + const filteredFindings = arr.filter(f => isWithinPeriod(f.createdAt, startDate, endDate)) return makeAnalysis(filteredFindings) } diff --git a/functions/v1/artifact/[uuid].js b/functions/v1/artifact/[uuid].js new file mode 100644 index 0000000..1aaa7ba --- /dev/null +++ b/functions/v1/artifact/[uuid].js @@ -0,0 +1,65 @@ +import { Server } from "@/utils"; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +export async function onRequestDelete(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const artifacts = await prisma.Artifact.findMany({ + where: { uuid: params.uuid }, + include: { + downloadLinks: true, + spdx: true, + cdx: true, + sarif: { + include: { + results: true, + } + }, + vex: true, + } + }) + for (const artifact of artifacts) { + if (artifact?.spdx?.spdxId) { + await prisma.SPDXInfo.delete({ where: { spdxId: artifact.spdx.spdxId } }) + } + if (artifact?.cdx?.cdxId) { + await prisma.CycloneDXInfo.delete({ where: { cdxId: artifact.cdx.cdxId } }) + } + if (artifact?.sarif?.results) { + for (const result of artifact.sarif.results) { + await prisma.SarifResults.delete({ where: { guid: result.guid } }) + } + } + if (artifact?.sarif?.reportId) { + await prisma.SARIFInfo.delete({ where: { reportId: artifact.sarif.reportId } }) + } + if (artifact?.vex?.uuid) { + await prisma.CycloneDXInfo.delete({ where: { cdxId: artifact.vex.uuid } }) + } + for (const link of artifact.downloadLinks) { + await prisma.Link.delete({ where: { id: link.id } }) + } + await prisma.Artifact.delete({ where: { uuid: artifact.uuid } }) + } + + return Response.json({ ok: true, uuid: params.uuid }) +} diff --git a/functions/v1/artifact/files.js b/functions/v1/artifact/files.js new file mode 100644 index 0000000..edad70f --- /dev/null +++ b/functions/v1/artifact/files.js @@ -0,0 +1,153 @@ +import { AuthResult, Server } from "@/utils"; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + try { + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + } + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { searchParams } = new URL(request.url) + const take = parseInt(searchParams.get('take'), 10) || 50 + const skip = parseInt(searchParams.get('skip'), 10) || 0 + const result = await prisma.Artifact.findMany({ + where: { + OR: [ + { + spdx: { + some: { + orgId: verificationResult.session.orgId, + }, + }, + }, + { + sarif: { + some: { + orgId: verificationResult.session.orgId, + }, + }, + }, + { + cdx: { + some: { + orgId: verificationResult.session.orgId, + }, + }, + }, + { + vex: { + some: { + finding: { + is: { + orgId: verificationResult.session.orgId, + }, + }, + }, + }, + + }, + ] + }, + select: { + uuid: true, + type: true, + date: true, + bomFormat: true, + downloadLinks: true, + spdx: { + select: { + name: true, + source: true, + repoName: true, + spdxVersion: true, + createdAt: true, + packagesCount: true, + }, + }, + sarif: { + select: { + source: true, + ref: true, + commitSha: true, + analysisKey: true, + fullName: true, + toolName: true, + toolVersion: true, + createdAt: true, + resultsCount: true, + }, + }, + cdx: { + select: { + name: true, + version: true, + source: true, + repoName: true, + cdxVersion: true, + createdAt: true, + dependenciesCount: true, + }, + }, + vex: { + select: { + lastObserved: true, + analysisState: true, + analysisJustification: true, + analysisResponse: true, + finding: { + select: { + source: true, + repoName: true, + detectionTitle: true, + } + } + }, + }, + }, + take, + skip, + orderBy: { + date: 'desc', + }, + }) + + const artifacts = result.map(artifact => { + artifact.spdx = artifact.spdx.sort((a, b) => b.createdAt - a.createdAt)?.pop() + artifact.sarif = artifact.sarif.sort((a, b) => b.createdAt - a.createdAt)?.pop() + artifact.cdx = artifact.cdx.sort((a, b) => b.createdAt - a.createdAt)?.pop() + const vex = artifact.vex.sort((a, b) => b.lastObserved - a.lastObserved)?.pop() + if (vex?.finding) { + vex.repoName = vex?.finding?.repoName + vex.source = vex?.finding?.source + vex.findingTitle = vex?.finding?.detectionTitle + delete vex.finding + } + artifact.vex = vex + artifact.downloadLink = artifact.downloadLinks.sort((a, b) => b.id - a.id)?.pop() + delete artifact.downloadLinks + return artifact + }) + + return Response.json({ ok: true, artifacts }) + } catch (err) { + console.error(err) + return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) + } +} diff --git a/functions/cdx/upload.js b/functions/v1/cdx.js similarity index 59% rename from functions/cdx/upload.js rename to functions/v1/cdx.js index f70ea48..5b33fe2 100644 --- a/functions/cdx/upload.js +++ b/functions/v1/cdx.js @@ -1,8 +1,65 @@ -import { AuthResult, hex, isCDX, OSV, Server, ensureStrReqBody } from "@/utils"; +import { AuthResult, ensureStrReqBody, hex, isCDX, OSV, saveArtifact, Server } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { searchParams } = new URL(request.url) + const take = parseInt(searchParams.get('take'), 10) || 50 + const skip = parseInt(searchParams.get('skip'), 10) || 0 + let cdx = await prisma.CycloneDXInfo.findMany({ + where: { + orgId: verificationResult.session.orgId, + }, + omit: { + memberEmail: true, + }, + include: { + repo: true, + artifact: { + include: { + downloadLinks: true + } + }, + }, + take, + skip, + orderBy: { + createdAt: 'desc', + }, + }) + cdx = cdx.map(item => { + let updatedItem = { ...item } + if (item.artifact && item.artifact.downloadLinks && item.artifact.downloadLinks.length) { + updatedItem.downloadLink = item.artifact.downloadLinks.filter(l => l.contentType === 'application/vnd.cyclonedx+json')?.pop()?.url + } + delete updatedItem.artifact + + return updatedItem + }) + return Response.json({ ok: true, cdx }) +} + export async function onRequestPost(context) { const { request, // same as existing Worker API @@ -34,12 +91,24 @@ export async function onRequestPost(context) { if (!isCDX(cdx)) { return Response.json({ ok: false, error: { message: 'CDX is missing necessary fields.' } }) } - // const cdxStr = JSON.stringify(cdx) //TODO: Add to TEA const componentsJSON = JSON.stringify(cdx.components) const cdxId = await hex(cdx.metadata?.component?.name + componentsJSON) + + const originalCdx = await prisma.CycloneDXInfo.findFirst({ + where: { + cdxId, + orgId: verificationResult.session.orgId, + } + }) + + const artifactUuid = originalCdx?.artifactUuid || cdx.serialNumber.startsWith('urn:uuid:') ? cdx.serialNumber.substring(9) : crypto.randomUUID() + const cdxStr = JSON.stringify(cdx) + const artifact = await saveArtifact(prisma, env.r2artifacts, cdxStr, artifactUuid, `cyclonedx`) const cdxData = { cdxId, + artifactUuid, source: 'upload', + orgId: verificationResult.session.orgId, memberEmail: verificationResult.session.memberEmail, cdxVersion: cdx.specVersion, serialNumber: cdx.serialNumber, @@ -51,7 +120,7 @@ export async function onRequestPost(context) { componentsCount: cdx.components?.length || 0, dependenciesCount: cdx.dependencies?.length || 0, } - const info = await prisma.cdx.upsert({ + const info = await prisma.CycloneDXInfo.upsert({ where: { cdxId, memberEmail: verificationResult.session.memberEmail, @@ -62,7 +131,7 @@ export async function onRequestPost(context) { }, create: cdxData }) - console.log(`/github/repos/cdx ${cdxId} kid=${verificationResult.session.kid}`, info) + console.log(`/upload/cdx ${cdxId} kid=${verificationResult.session.kid}`, info) files.push(cdxData) const osvQueries = cdx.components.map(component => { @@ -76,7 +145,7 @@ export async function onRequestPost(context) { }) const osv = new OSV() const queries = osvQueries.map(q => ({ package: { purl: q?.referenceLocator } })) - const results = await osv.queryBatch(prisma, verificationResult.session.memberEmail, queries) + const results = await osv.queryBatch(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, queries) let i = 0 for (const result of results) { const { referenceLocator, name, version, license } = osvQueries[i] @@ -87,6 +156,7 @@ export async function onRequestPost(context) { const findingId = await hex(`${vuln.id}${referenceLocator}`) const findingData = { findingId, + orgId: verificationResult.session.orgId, memberEmail: verificationResult.session.memberEmail, source: 'osv.dev', category: 'sca', @@ -97,54 +167,60 @@ export async function onRequestPost(context) { packageName: name, packageVersion: version, packageLicense: license, + malicious: vuln.id.startsWith("MAL-") ? 1 : 0, cdxId } - const originalFinding = await prisma.findings.findFirst({ + const originalFinding = await prisma.Finding.findFirst({ where: { findingId, AND: { - memberEmail: verificationResult.session.memberEmail + orgId: verificationResult.session.orgId }, } }) let finding; if (originalFinding) { - finding = await prisma.findings.update({ + finding = await prisma.Finding.update({ where: { - id: originalFinding.id, + uuid: originalFinding.uuid, }, data: { + cdxId, + packageLicense: findingData.packageLicense, + malicious: findingData.malicious, modifiedAt: findingData.modifiedAt }, }) } else { - finding = await prisma.findings.create({ data: findingData }) + finding = await prisma.Finding.create({ data: findingData }) } console.log(`findings SCA`, finding) + // TODO lookup EPSS const vexData = { - findingKey: finding.id, + findingUuid: finding.uuid, createdAt: (new Date()).getTime(), lastObserved: (new Date()).getTime(), seen: 0, analysisState: 'in_triage' } - const originalVex = await prisma.triage_activity.findUnique({ + const originalVex = await prisma.Triage.findFirst({ where: { - findingKey: finding.id, + findingUuid: finding.uuid, + analysisState: 'in_triage', } }) let vex; if (originalVex) { - vex = await prisma.triage_activity.update({ + vex = await prisma.Triage.update({ where: { - findingKey: finding.id, + uuid: originalVex.uuid, }, data: { lastObserved: vexData.lastObserved }, }) } else { - vex = await prisma.triage_activity.create({ data: vexData }) + vex = await prisma.Triage.create({ data: vexData }) } console.log(`findings VEX`, vex) } diff --git a/functions/github/[installation_id]/install/[code].js b/functions/v1/github/[installation_id]/install/[code].js similarity index 92% rename from functions/github/[installation_id]/install/[code].js rename to functions/v1/github/[installation_id]/install/[code].js index a1f3aa3..4b670a8 100644 --- a/functions/github/[installation_id]/install/[code].js +++ b/functions/v1/github/[installation_id]/install/[code].js @@ -83,7 +83,7 @@ export async function onRequestGet(context) { lastName = words.join(' ') || '' } if (content?.company) { - const originalOrg = await prisma.orgs.findFirst({ + const originalOrg = await prisma.Org.findFirst({ where: { name: content.company } @@ -91,7 +91,7 @@ export async function onRequestGet(context) { if (originalOrg?.uuid) { orgId = originalOrg.uuid } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: content.company, @@ -100,7 +100,7 @@ export async function onRequestGet(context) { console.log(`/github/install register orgId=${orgId}`, orgInfo) } } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: memberEmail.toLowerCase(), @@ -117,7 +117,7 @@ export async function onRequestGet(context) { firstName, lastName } - const memberInfo = await prisma.members.create({ + const memberInfo = await prisma.Member.create({ data: response.member }) console.log(`/github/install register email=${memberEmail}`, memberInfo) @@ -130,6 +130,7 @@ export async function onRequestGet(context) { const secret = await hex(crypto.getRandomValues(new Uint32Array(26)), 'SHA-1') response.session = { kid: token, + orgId: response.member.orgId, memberEmail: response.member.email, expiry, issued: created, @@ -137,7 +138,7 @@ export async function onRequestGet(context) { authn_ip, authn_ua } - const sessionInfo = await prisma.sessions.create({ + const sessionInfo = await prisma.Session.create({ data: response.session }) console.log(`/github/install session kid=${token}`, sessionInfo) @@ -151,8 +152,8 @@ export async function onRequestGet(context) { expires } try { - await prisma.github_apps.findUniqueOrThrow({ where: { login: appData.login } }) - const GHAppInfo = await prisma.github_apps.update({ + await prisma.GitHubApp.findUniqueOrThrow({ where: { login: appData.login } }) + const GHAppInfo = await prisma.GitHubApp.update({ where: { login: appData.login }, data: { accessToken: appData.accessToken, @@ -165,7 +166,7 @@ export async function onRequestGet(context) { } catch (_) { // No records to update OAuth token } - const GHAppInfo = await prisma.github_apps.create({ + const GHAppInfo = await prisma.GitHubApp.create({ data: appData }) console.log(`/github/install installationId=${params.installation_id}`, GHAppInfo) diff --git a/functions/github/[installation_id]/uninstall.js b/functions/v1/github/[installation_id]/uninstall.js similarity index 89% rename from functions/github/[installation_id]/uninstall.js rename to functions/v1/github/[installation_id]/uninstall.js index 4a2e8f3..4ab341e 100644 --- a/functions/github/[installation_id]/uninstall.js +++ b/functions/v1/github/[installation_id]/uninstall.js @@ -29,11 +29,11 @@ export async function onRequestGet(context) { memberEmail: verificationResult.session.memberEmail, installationId: parseInt(params.installation_id, 10), } - const app = await prisma.github_apps.findUniqueOrThrow({ where }) + const app = await prisma.GitHubApp.findUniqueOrThrow({ where }) const gh = new GitHub(app.accessToken) - const result = await gh.revokeToken(prisma, verificationResult.session.memberEmail) + const result = await gh.revokeToken(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail) if ([204, 401].includes(result.status)) { - const response = await prisma.github_apps.delete({ where }) + const response = await prisma.GitHubApp.delete({ where }) console.log(`/github/uninstall session kid=${verificationResult.session.token}`, response) return Response.json(response) diff --git a/functions/github/[patId]/remove.js b/functions/v1/github/[patId]/remove.js similarity index 93% rename from functions/github/[patId]/remove.js rename to functions/v1/github/[patId]/remove.js index a985590..8086031 100644 --- a/functions/github/[patId]/remove.js +++ b/functions/v1/github/[patId]/remove.js @@ -23,13 +23,13 @@ export async function onRequestDelete(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const patInfo = await prisma.github_pat.delete({ + const patInfo = await prisma.GitHubPAT.delete({ where: { keyId: parseInt(params.patId, 10), } }) console.log(`/github/[${params.patId}]/remove github_pat`, patInfo) - const tokenInfo = await prisma.member_keys.delete({ + const tokenInfo = await prisma.MemberKey.delete({ where: { id: parseInt(params.patId, 10), memberEmail: verificationResult.session.memberEmail, diff --git a/functions/github/pat.js b/functions/v1/github/pat.js similarity index 91% rename from functions/github/pat.js rename to functions/v1/github/pat.js index 33476a9..d698dca 100644 --- a/functions/github/pat.js +++ b/functions/v1/github/pat.js @@ -28,7 +28,7 @@ export async function onRequestPost(context) { if (!body.token.startsWith('github_pat_')) { return Response.json({ error: { message: `Invalid PAT provided, expected "github_pat_" prefix.` } }) } - const tokenInfo = await prisma.member_keys.upsert({ + const tokenInfo = await prisma.MemberKey.upsert({ where: { memberEmail_secret: { memberEmail: verificationResult.session.memberEmail, @@ -49,7 +49,7 @@ export async function onRequestPost(context) { delete tokenInfo.secret console.log(`/github/pat github_pat label=${body.label}`, tokenInfo) const gh = new GitHub(body.token) - const { content, error, tokenExpiry } = await gh.getUser(prisma, verificationResult.session.memberEmail) + const { content, error, tokenExpiry } = await gh.getUser(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail) if (error?.message) { return Response.json({ error }) } @@ -60,7 +60,7 @@ export async function onRequestPost(context) { created: content?.created_at ? (new Date(content.created_at)).getTime() : (new Date()).getTime(), avatarUrl: content?.avatar_url, } - const patInfo = await prisma.github_pat.upsert({ + const patInfo = await prisma.GitHubPAT.upsert({ where: { keyId: tokenInfo.githubPat.keyId, }, @@ -74,4 +74,4 @@ export async function onRequestPost(context) { return Response.json(tokenInfo) } -const mask = s => s.slice(0, 11) + s.slice(10).slice(4, s.length - 4).replace(/(.)/g, '*') + s.slice(s.length - 4) +const mask = s => s.slice(0, 11) + s.slice(10).slice(4, s.length - 4).slice(4, 12).replace(/(.)/g, '*') + s.slice(s.length - 4) diff --git a/functions/github/repos.js b/functions/v1/github/repos.js similarity index 85% rename from functions/github/repos.js rename to functions/v1/github/repos.js index 37381d0..8de44c9 100644 --- a/functions/github/repos.js +++ b/functions/v1/github/repos.js @@ -23,10 +23,18 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - + const githubIntegration = await prisma.IntegrationConfig.findFirst({ + where: { + orgId: verificationResult.session.orgId, + AND: { name: `github` }, + } + }) + if (!!githubIntegration?.suspend) { + return Response.json({ ok: false, error: { message: 'GitHub Disabled' } }) + } const githubApps = [] const gitRepos = [] - const installs = await prisma.github_apps.findMany({ + const installs = await prisma.GitHubApp.findMany({ where: { memberEmail: verificationResult.session.memberEmail, AND: { expires: { gte: (new Date()).getTime(), } } @@ -38,11 +46,11 @@ export async function onRequestGet(context) { throw new Error('github_apps invalid') } const gh = new GitHub(app.accessToken) - const { content, error } = await gh.getRepos(prisma, verificationResult.session.memberEmail) + const { content, error } = await gh.getRepos(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail) if (error?.message) { if ("Bad credentials" === error.message) { app.expires = (new Date()).getTime() - await prisma.github_apps.update({ + await prisma.GitHubApp.update({ where: { installationId: parseInt(app.installationId, 10), AND: { memberEmail: app.memberEmail, }, @@ -68,7 +76,7 @@ export async function onRequestGet(context) { }) } - const memberKeys = await prisma.member_keys.findMany({ + const memberKeys = await prisma.MemberKey.findMany({ where: { memberEmail: verificationResult.session.memberEmail, keyType: 'github_pat', @@ -76,7 +84,7 @@ export async function onRequestGet(context) { }) for (const memberKey of memberKeys) { const gh = new GitHub(memberKey.secret) - const { content, error } = await gh.getRepos(prisma, verificationResult.session.memberEmail) + const { content, error } = await gh.getRepos(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail) if (error?.message) { return Response.json({ error, app: { login: memberKey.keyLabel } }) } @@ -90,6 +98,7 @@ export async function onRequestGet(context) { } const store = async (prisma, session, repo) => { const create = { + orgId: session.orgId, fullName: repo.full_name, ghid: repo.id, source: "GitHub", @@ -108,13 +117,13 @@ const store = async (prisma, session, repo) => { avatarUrl: repo.owner.avatar_url, } const where = { - fullName_memberEmail: { + fullName_orgId: { fullName: create.fullName, - memberEmail: create.memberEmail, + orgId: session.orgId, } } try { - const info = await prisma.git_repos.upsert({ + const info = await prisma.GitRepo.upsert({ where, create, update: { diff --git a/functions/github/repos/[org]/[repo]/sarif.js b/functions/v1/github/repos/[org]/[repo]/sarif.js similarity index 82% rename from functions/github/repos/[org]/[repo]/sarif.js rename to functions/v1/github/repos/[org]/[repo]/sarif.js index bfa85b8..5aa16c6 100644 --- a/functions/github/repos/[org]/[repo]/sarif.js +++ b/functions/v1/github/repos/[org]/[repo]/sarif.js @@ -1,4 +1,4 @@ -import { GitHub, Server } from "@/utils"; +import { GitHub, Server, saveArtifact } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; @@ -23,15 +23,23 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } + const githubIntegration = await prisma.IntegrationConfig.findFirst({ + where: { + orgId: verificationResult.session.orgId, + AND: { name: `github` }, + } + }) + if (!!githubIntegration?.suspend) { + return Response.json({ ok: false, error: { message: 'GitHub Disabled' } }) + } const errors = [] - const githubApps = await prisma.github_apps.findMany({ + const githubApps = await prisma.GitHubApp.findMany({ where: { memberEmail: verificationResult.session.memberEmail, }, }) const repoName = `${params.org}/${params.repo}` const files = [] - const putOptions = { httpMetadata: { contentType: 'application/json', contentEncoding: 'utf8' } } for (const app of githubApps) { if (!app.accessToken) { console.error(`Invalid github_apps kid=${verificationResult.session.kid} installationId=${app.installationId}`) @@ -39,11 +47,11 @@ export async function onRequestGet(context) { } const gh = new GitHub(app.accessToken) - const { content, error } = await gh.getRepoSarif(prisma, verificationResult.session.memberEmail, repoName) + const { content, error } = await gh.getRepoSarif(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, repoName) if (error?.message) { if ("Bad credentials" === error.message) { app.expires = (new Date()).getTime() - await prisma.github_apps.update({ + await prisma.GitHubApp.update({ where: { installationId: parseInt(app.installationId, 10), AND: { memberEmail: app.memberEmail, }, @@ -58,16 +66,12 @@ export async function onRequestGet(context) { continue } for (const data of content) { - const objectPrefix = `github/${app.installationId}/repos/${repoName}/code-scanning/` - const reportInfo = await env.r2artefact.put(`${objectPrefix}${data.report.id}.json`, JSON.stringify(data.report), putOptions) - console.log(`${repoName}/code-scanning/${data.report.id}.json`, reportInfo) - const sarifInfo = await env.r2artefact.put(`${objectPrefix}${data.report.id}_${data.report.sarif_id}.json`, JSON.stringify(data.sarif), putOptions) - console.log(`${repoName}/code-scanning/${data.report.id}_${data.report.sarif_id}.json`, sarifInfo) + const artifact = await saveArtifact(prisma, env.r2artifacts, JSON.stringify(data.sarif), crypto.randomUUID(), `sarif`) files.push(await process(prisma, verificationResult.session, data, repoName)) } } - const memberKeys = await prisma.member_keys.findMany({ + const memberKeys = await prisma.MemberKey.findMany({ where: { memberEmail: verificationResult.session.memberEmail, keyType: 'github_pat', @@ -75,17 +79,13 @@ export async function onRequestGet(context) { }) for (const memberKey of memberKeys) { const gh = new GitHub(memberKey.secret) - const { content, error } = await gh.getRepoSarif(prisma, verificationResult.session.memberEmail, repoName) + const { content, error } = await gh.getRepoSarif(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, repoName) if (error?.message) { errors.push({ error, app: { login: memberKey.keyLabel } }) continue } for (const data of content) { - const objectPrefix = `github/pat_${memberKey.id}/repos/${repoName}/code-scanning/` - const reportInfo = await env.r2artefact.put(`${objectPrefix}${data.report.id}.json`, JSON.stringify(data.report), putOptions) - console.log(`${repoName}/code-scanning/${data.report.id}.json`, reportInfo) - const sarifInfo = await env.r2artefact.put(`${objectPrefix}${data.report.id}_${data.report.sarif_id}.json`, JSON.stringify(data.sarif), putOptions) - console.log(`${repoName}/code-scanning/${data.report.id}_${data.report.sarif_id}.json`, sarifInfo) + await saveArtifact(prisma, env.r2artifacts, JSON.stringify(data.sarif), data.report.sarif_id, `sarif`) files.push(await process(prisma, verificationResult.session, data, repoName)) } } @@ -95,9 +95,9 @@ export async function onRequestGet(context) { const process = async (prisma, session, data, fullName) => { const sarifId = data.report.sarif_id - const info = await prisma.sarif.upsert({ + const info = await prisma.SARIFInfo.upsert({ where: { - sarifId, + reportId: data.report.id.toString(), }, update: { commitSha: data.report.commit_sha, @@ -112,8 +112,10 @@ const process = async (prisma, session, data, fullName) => { create: { sarifId, reportId: data.report.id.toString(), + artifactUuid: sarifId, fullName, source: 'GitHub', + orgId: session.orgId, memberEmail: session.memberEmail, commitSha: data.report.commit_sha, ref: data.report.ref, @@ -172,7 +174,7 @@ const process = async (prisma, session, data, fullName) => { resultData.precision, resultData.tags ) - const reportInfo = await prisma.sarif_results.upsert({ + const reportInfo = await prisma.SarifResults.upsert({ where: { guid: resultData.guid, }, @@ -211,6 +213,7 @@ const process = async (prisma, session, data, fullName) => { const result = { sarifId, reportId: data.report.id.toString(), + artifactUuid: sarifId, fullName, memberEmail: session.memberEmail, commitSha: data.report.commit_sha, diff --git a/functions/github/repos/[org]/[repo]/spdx.js b/functions/v1/github/repos/[org]/[repo]/spdx.js similarity index 66% rename from functions/github/repos/[org]/[repo]/spdx.js rename to functions/v1/github/repos/[org]/[repo]/spdx.js index bc28d3b..78c180f 100644 --- a/functions/github/repos/[org]/[repo]/spdx.js +++ b/functions/v1/github/repos/[org]/[repo]/spdx.js @@ -1,4 +1,4 @@ -import { GitHub, hex, isSPDX, OSV, Server } from "@/utils"; +import { GitHub, hex, isSPDX, OSV, saveArtifact, Server } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; @@ -23,13 +23,21 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const putOptions = { httpMetadata: { contentType: 'application/json', contentEncoding: 'utf8' } } + const githubIntegration = await prisma.IntegrationConfig.findFirst({ + where: { + orgId: verificationResult.session.orgId, + AND: { name: `github` }, + } + }) + if (!!githubIntegration?.suspend) { + return Response.json({ ok: false, error: { message: 'GitHub Disabled' } }) + } const repoName = `${params.org}/${params.repo}` const errors = [] const files = [] let findings = [] - const githubApps = await prisma.github_apps.findMany({ + const githubApps = await prisma.GitHubApp.findMany({ where: { memberEmail: verificationResult.session.memberEmail, }, @@ -40,11 +48,11 @@ export async function onRequestGet(context) { throw new Error('github_apps invalid') } const gh = new GitHub(app.accessToken) - const { content, error } = await gh.getRepoSpdx(prisma, verificationResult.session.memberEmail, repoName) + const { content, error } = await gh.getRepoSpdx(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, repoName) if (error?.message) { if ("Bad credentials" === error.message) { app.expires = (new Date()).getTime() - await prisma.github_apps.update({ + await prisma.GitHubApp.update({ where: { installationId: parseInt(app.installationId, 10), AND: { memberEmail: app.memberEmail, }, @@ -65,13 +73,24 @@ export async function onRequestGet(context) { console.log('content', content) continue } - const { spdxId, spdxStr, findingIds } = await process(prisma, verificationResult.session, repoName, content) + const spdx = content.sbom + const spdxId = await makeId(spdx) + const originalSpdx = await prisma.SPDXInfo.findFirst({ + where: { + spdxId, + orgId: verificationResult.session.orgId, + } + }) + let artifact; + if (!originalSpdx) { + const spdxStr = JSON.stringify(spdx) + artifact = await saveArtifact(prisma, env.r2artifacts, spdxStr, crypto.randomUUID(), `spdx`) + } + const findingIds = await process(prisma, verificationResult.session, repoName, spdx, spdxId, originalSpdx?.artifactUuid || artifact?.uuid) findings = [...findings, ...findingIds] - const objectPrefix = `github/${app.installationId}/repos/${repoName}/sbom/` - console.log(`${repoName}/sbom/${spdxId}.json`, await env.r2artefact.put(`${objectPrefix}${spdxId}.json`, spdxStr, putOptions)) - files.push(content) + files.push({ spdx, errors }) } - const memberKeys = await prisma.member_keys.findMany({ + const memberKeys = await prisma.MemberKey.findMany({ where: { memberEmail: verificationResult.session.memberEmail, keyType: 'github_pat', @@ -79,7 +98,7 @@ export async function onRequestGet(context) { }) for (const memberKey of memberKeys) { const gh = new GitHub(memberKey.secret) - const { content, error } = await gh.getRepoSpdx(prisma, verificationResult.session.memberEmail, repoName) + const { content, error } = await gh.getRepoSpdx(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, repoName) if (error?.message) { errors.push({ error, app: { login: memberKey.keyLabel } }) continue @@ -91,24 +110,38 @@ export async function onRequestGet(context) { console.log('content', content) continue } - const { spdxId, spdxStr, findingIds } = await process(prisma, verificationResult.session, repoName, content) + const spdx = content.sbom + const spdxId = await makeId(spdx) + const originalSpdx = await prisma.SPDXInfo.findFirst({ + where: { + spdxId, + orgId: verificationResult.session.orgId, + } + }) + let artifact; + if (!originalSpdx) { + const spdxStr = JSON.stringify(spdx) + artifact = await saveArtifact(prisma, env.r2artifacts, spdxStr, crypto.randomUUID(), `spdx`) + } + const findingIds = await process(prisma, verificationResult.session, repoName, spdx, spdxId, originalSpdx?.artifactUuid || artifact?.uuid) findings = [...findings, ...findingIds] - const objectPrefix = `github/pat_${memberKey.id}/repos/${repoName}/sbom/` - console.log(`${repoName}/sbom/${spdxId}.json`, await env.r2artefact.put(`${objectPrefix}${spdxId}.json`, spdxStr, putOptions)) - files.push({ spdx: content, errors }) + files.push({ spdx, errors }) } return Response.json({ ok: true, files, findings }) } -const process = async (prisma, session, repoName, content) => { - const spdx = content.sbom +const makeId = async spdx => { const packages = JSON.stringify(spdx.packages) - const spdxStr = JSON.stringify(spdx) - const spdxId = await hex(spdx.name + packages) + return hex(spdx.name + packages) +} + +const process = async (prisma, session, repoName, spdx, spdxId, artifactUuid) => { const spdxData = { spdxId, + artifactUuid, source: 'GitHub', + orgId: session.orgId, memberEmail: session.memberEmail, repoName, spdxVersion: spdx.spdxVersion, @@ -123,13 +156,12 @@ const process = async (prisma, session, repoName, content) => { } const findingIds = [] - const info = await prisma.spdx.upsert({ + const info = await prisma.SPDXInfo.upsert({ where: { spdxId, - memberEmail: session.memberEmail, + orgId: session.orgId, }, update: { - createdAt: spdxData.createdAt, comment: spdxData.comment }, create: spdxData, @@ -149,7 +181,7 @@ const process = async (prisma, session, repoName, content) => { }).filter(q => q?.purl) const osv = new OSV() const queries = osvQueries.map(q => ({ package: { purl: q.purl } })) - const results = await osv.queryBatch(prisma, session.memberEmail, queries) + const results = await osv.queryBatch(prisma, session.orgId, session.memberEmail, queries) let i = 0 for (const result of results) { const { purl, name, version, license } = osvQueries[i] @@ -160,6 +192,7 @@ const process = async (prisma, session, repoName, content) => { const findingId = await hex(`${vuln.id}${purl}`) const findingData = { findingId, + orgId: session.orgId, memberEmail: session.memberEmail, source: 'osv.dev', category: 'sca', @@ -170,60 +203,63 @@ const process = async (prisma, session, repoName, content) => { packageName: name, packageVersion: version, packageLicense: license, + malicious: vuln.id.startsWith("MAL-") ? 1 : 0, spdxId } - const originalFinding = await prisma.findings.findFirst({ + const originalFinding = await prisma.Finding.findFirst({ where: { findingId, AND: { - memberEmail: session.memberEmail + orgId: session.orgId }, } }) let finding; if (originalFinding) { - finding = await prisma.findings.update({ + finding = await prisma.Finding.update({ where: { - id: originalFinding.id, + uuid: originalFinding.uuid, }, data: { + spdxId, modifiedAt: findingData.modifiedAt }, }) } else { - finding = await prisma.findings.create({ data: findingData }) + finding = await prisma.Finding.create({ data: findingData }) } - console.log(`findings SCA`, finding) - findingIds.push(finding.id) + // console.log(`findings SCA`, finding) + findingIds.push(finding.uuid) const vexData = { - findingKey: finding.id, + findingUuid: finding.uuid, createdAt: (new Date()).getTime(), lastObserved: (new Date()).getTime(), seen: 0, analysisState: 'in_triage', } - const originalVex = await prisma.triage_activity.findUnique({ + const originalVex = await prisma.Triage.findFirst({ where: { - findingKey: finding.id, + findingUuid: finding.uuid, + analysisState: 'in_triage', } }) let vex; if (originalVex) { - vex = await prisma.triage_activity.update({ + vex = await prisma.Triage.update({ where: { - findingKey: finding.id, + uuid: originalVex.uuid, }, data: { lastObserved: vexData.lastObserved }, }) } else { - vex = await prisma.triage_activity.create({ data: vexData }) + vex = await prisma.Triage.create({ data: vexData }) } - console.log(`findings VEX`, vex) + // console.log(`findings VEX`, vex) } i++ } - return { spdxId, spdxStr, findingIds } + return findingIds } diff --git a/functions/github/repos/cached.js b/functions/v1/github/repos/cached.js similarity index 89% rename from functions/github/repos/cached.js rename to functions/v1/github/repos/cached.js index 90e9e08..a3ccc25 100644 --- a/functions/github/repos/cached.js +++ b/functions/v1/github/repos/cached.js @@ -23,7 +23,7 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const githubApps = await prisma.github_apps.findMany({ + const githubApps = await prisma.GitHubApp.findMany({ where: { memberEmail: verificationResult.session.memberEmail, }, @@ -32,9 +32,9 @@ export async function onRequestGet(context) { accessToken: true, }, }) - const gitRepos = await prisma.git_repos.findMany({ + const gitRepos = await prisma.GitRepo.findMany({ where: { - memberEmail: verificationResult.session.memberEmail, + orgId: verificationResult.session.orgId, }, omit: { memberEmail: true, @@ -44,7 +44,7 @@ export async function onRequestGet(context) { createdAt: 'desc', }, }) - const patTokens = await prisma.member_keys.findMany({ + const patTokens = await prisma.MemberKey.findMany({ where: { memberEmail: verificationResult.session.memberEmail, keyType: 'github_pat', diff --git a/functions/github/webhook.js b/functions/v1/github/webhook.js similarity index 100% rename from functions/github/webhook.js rename to functions/v1/github/webhook.js diff --git a/functions/queue/sca.js b/functions/v1/history.js similarity index 76% rename from functions/queue/sca.js rename to functions/v1/history.js index f3f1a35..6c7cf20 100644 --- a/functions/queue/sca.js +++ b/functions/v1/history.js @@ -27,10 +27,14 @@ export async function onRequestGet(context) { const { searchParams } = new URL(request.url) const take = parseInt(searchParams.get('take'), 10) || 50 const skip = parseInt(searchParams.get('skip'), 10) || 0 - const sca = await prisma.findings.findMany({ + const findings = await prisma.Finding.findMany({ where: { - memberEmail: verificationResult.session.memberEmail, - category: 'sca', + orgId: verificationResult.session.orgId, + NOT: { + triage: { + every: { analysisState: 'in_triage', } + } + }, }, omit: { memberEmail: true, @@ -56,7 +60,13 @@ export async function onRequestGet(context) { }) return Response.json({ - ok: true, sca + ok: true, findings: findings.map(finding => { + finding.references = JSON.parse(finding.referencesJSON) + delete finding.referencesJSON + finding.aliases = JSON.parse(finding.aliases) + finding.cwes = JSON.parse(finding.cwes) + return finding + }) }) } catch (err) { console.error(err) diff --git a/functions/v1/issue/[uuid].js b/functions/v1/issue/[uuid].js new file mode 100644 index 0000000..265e744 --- /dev/null +++ b/functions/v1/issue/[uuid].js @@ -0,0 +1,427 @@ +import { AuthResult, EPSS, MitreCVE, OSV, Server, constructVersionRangeString } from "@/utils"; +import { CVSS30, CVSS31, CVSS40 } from '@pandatix/js-cvss'; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +// Helper function to process array fields +const processArrayField = (array, key) => { + if (!Array.isArray(array)) return '' + return Array.from(new Set(array.map(item => item[key]?.trim()).filter(Boolean))).join(',') +} + +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + try { + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { uuid } = params + const finding = await prisma.Finding.findUnique({ + where: { + uuid, + AND: { orgId: verificationResult.session.orgId } + }, + omit: { + memberEmail: true, + }, + include: { + triage: true, + spdx: { + include: { + repo: true + } + }, + cdx: { + include: { + repo: true + } + } + } + }) + if (!finding) { + return new Response(null, { status: 404 }) + } + const osvData = await new OSV().query(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, finding.detectionTitle) + finding.modifiedAt = (new Date(osvData.modified)).getTime() + finding.publishedAt = (new Date(osvData.published)).getTime() + finding.databaseReviewed = osvData?.database_specific?.github_reviewed ? 1 : 0 + finding.aliases = JSON.stringify(osvData?.aliases?.filter(a => a !== finding.cveId) || []) + finding.cwes = JSON.stringify(osvData?.database_specific?.cwe_ids || []) + finding.packageEcosystem = osvData.affected.map(affected => affected.package.ecosystem).pop() + finding.advisoryUrl = osvData.affected.map(affected => affected.database_specific.source).pop() + finding.fixVersion = osvData.affected.map(affected => affected.ranges.pop()?.events.pop()?.fixed).pop() + finding.vulnerableVersionRange = osvData.affected.map(affected => affected.database_specific.last_known_affected_version_range).pop() + finding.fixAutomatable = !!finding.vulnerableVersionRange && !!finding.fixVersion ? 1 : 0 + finding.malicious = osvData.id.startsWith("MAL-") ? 1 : 0 + finding.referencesJSON = JSON.stringify(osvData.references.map(reference => reference.url)) + + const cveId = finding.detectionTitle.startsWith('CVE-') ? finding.detectionTitle : osvData?.aliases?.filter(a => a.startsWith('CVE-')).pop() + let cvssVector + let cvssScore + let cvelistv5 + let cve + if (cveId) { + cve = await getCveData(prisma, env.r2artifacts, verificationResult, cveId) + } + if (cve?.fileLink?.url) { + const r2object = await env.r2artifacts.get(cve.fileLink.url) + if (r2object) { + cvelistv5 = JSON.parse(r2object) + } + } + if (cvelistv5) { + const { + cveMetadata, + containers: { cna, adp } + } = cvelistv5 + const cvssVector = findVectorString(cna.metrics) + if (cvssVector.startsWith('CVSS:4.0/')) { + cvssScore = new CVSS40(cvssVector).Score().toString() + } else if (cvssVector.startsWith('CVSS:3.1/')) { + cvssScore = new CVSS31(cvssVector).BaseScore().toString() + } else if (cvssVector.startsWith('CVSS:3.0/')) { + cvssScore = new CVSS30(cvssVector).BaseScore().toString() + } + if (cna?.timeline) { + finding.timelineJSON = JSON.stringify(cna.timeline.map(i => convertIsoDatesToTimestamps(i))) + } + // Extract CISA date + const cisaAdp = adp?.find(container => container.providerMetadata.shortName === 'CISA-ADP') + if (cisaAdp?.providerMetadata?.dateUpdated) { + finding.cisaDateAdded = new Date(cisaAdp.providerMetadata.dateUpdated).getTime() + } + // Get affected data from ADP and CNA + const adpAffected = adp.flatMap(container => container.affected || []) + const cnaAffected = cna.affected || [] + // Required properties we're looking for + const requiredProps = ['versions', 'vendor', 'product'] + // Find first valid affected data, preferring ADP over CNA + const primaryAffected = findFirstValidAffected(adpAffected, requiredProps) || + findFirstValidAffected(cnaAffected, requiredProps) || null + // Extract affected data ensuring valid values + const affectedData = { + versions: primaryAffected?.versions?.filter(v => isValidValue(v.version)) || [], + vendor: isValidValue(primaryAffected?.vendor) ? primaryAffected.vendor : null, + product: isValidValue(primaryAffected?.product) ? primaryAffected.product : null, + cpes: primaryAffected?.cpes?.filter(cpe => isValidValue(cpe))?.join('\n') + } + + if (cveMetadata?.datePublished) { + finding.publishedAt = new Date(cveMetadata.datePublished).getTime() + } + if (cveMetadata?.dateReserved) { + finding.createdAt = new Date(cveMetadata.dateReserved).getTime() + } + if (cveMetadata?.dateUpdated) { + finding.modifiedAt = new Date(cveMetadata.dateUpdated).getTime() + } + finding.vulnerableVersionRange = affectedData.versions.length > 0 ? constructVersionRangeString(affectedData.versions) : null + finding.cpe = affectedData?.cpes + finding.vendor = affectedData?.vendor + finding.product = affectedData?.product + } + const info = await prisma.Finding.update({ + where: { uuid }, + data: { + detectionTitle: finding.detectionTitle, + createdAt: finding.createdAt, + modifiedAt: finding.modifiedAt, + publishedAt: finding.publishedAt, + databaseReviewed: finding.databaseReviewed, + cisaDateAdded: finding.cisaDateAdded, + aliases: finding.aliases, + cwes: finding.cwes, + packageEcosystem: finding.packageEcosystem, + advisoryUrl: finding.advisoryUrl, + fixVersion: finding.fixVersion, + fixAutomatable: finding.fixAutomatable, + vulnerableVersionRange: finding.vulnerableVersionRange, + cpe: finding.cpe, + vendor: finding.vendor, + product: finding.product, + malicious: finding.malicious, + referencesJSON: finding.referencesJSON, + timelineJSON: finding.timelineJSON, + } + }) + // console.log(`Update ${finding.detectionTitle}`, info) + let scores + if (cveId) { + const epss = new EPSS() + scores = await epss.query(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, cveId) + } + let epssScore, epssPercentile; + if (scores?.epss) { + epssScore = parseFloat(scores.epss) + epssPercentile = parseFloat(scores.percentile) + } + const cvss = {} + if (!cvssVector) { + cvss.v4 = osvData?.severity?.filter(i => i.score.startsWith('CVSS:4/'))?.pop() + cvss.v31 = osvData?.severity?.filter(i => i.score.startsWith('CVSS:3.1/'))?.pop() + cvss.v3 = osvData?.severity?.filter(i => i.score.startsWith('CVSS:3/'))?.pop() + cvssVector = !!cvss.v4 ? cvss.v4.score : !!cvss.v31 ? cvss.v31.score : cvss.v3 ? cvss.v3.score : null + const vector = !!cvss.v4 ? new CVSS40(cvss.v4.score) : !!cvss.v31 ? new CVSS31(cvss.v31.score) : cvss.v3 ? new CVSS30(cvss.v3.score) : null + cvssScore = !!cvss.v4 ? vector.Score().toString() : !!cvss.v31 ? vector.BaseScore().toString() : cvss.v3 ? vector.BaseScore().toString() : null + } + // Decision + // Methodology + // Exploitation + // TechnicalImpact + // Automatable + // MissionWellbeingImpact + + const { searchParams } = new URL(request.url) + const seen = parseInt(searchParams.get('seen'), 10) || 0 + let { analysisState = 'in_triage', triageAutomated = 0, triagedAt = null, seenAt = null } = finding?.triage || {} + if ( + (cvssVector && ( + ['E:U', 'E:P', 'E:F', 'E:H'].some(substring => cvss.v3?.score?.includes(substring)) || + ['E:U', 'E:P', 'E:F', 'E:H'].some(substring => cvss.v31?.score?.includes(substring)) || + ['E:A', 'E:P', 'E:U'].some(substring => cvss.v4?.score?.includes(substring)) + )) || epssPercentile > 0.27 + ) { + analysisState = 'exploitable' + triageAutomated = 1 + if (!triagedAt) { + triagedAt = new Date().getTime() + } + } + if (seen === 1) { + seenAt = new Date().getTime() + } + const vexExist = finding.triage.some(t => t.analysisState === analysisState).length !== 0 + let vexData = finding.triage.filter(t => t.analysisState === analysisState).pop() + if (!vexExist) { + vexData.analysisState = analysisState + vexData.findingUuid = finding.uuid + vexData.createdAt = new Date().getTime() + vexData.lastObserved = new Date().getTime() + } + vexData.triageAutomated = triageAutomated + vexData.triagedAt = triagedAt + vexData.cvssVector = cvssVector + vexData.cvssScore = cvssScore + if (epssPercentile) { + vexData.epssPercentile = epssPercentile.toString() + } + if (epssScore) { + vexData.epssScore = epssScore.toString() + } + vexData.seen = seen + vexData.seenAt = seenAt + if (vexExist) { + const vexInfo = await prisma.Triage.update({ + where: { + uuid: vexData.uuid, + }, + data: vexData, + }) + // console.log(`Updated VEX ${finding.detectionTitle}`, vexInfo) + } else { + vexData = await prisma.Triage.create({ data: vexData }) + } + finding.triage = finding.triage.filter(f => f.uuid != vexData.uuid) + finding.triage.push(vexData) + + // expand JSON fields + if (finding.cwes) { + finding.cwes = JSON.parse(finding.cwes) + } + if (finding.aliases) { + finding.aliases = JSON.parse(finding.aliases) + } + if (finding.exploitsJSON) { + finding.exploits = JSON.parse(finding.exploitsJSON) + delete finding.exploitsJSON + } + if (finding.knownExploitsJSON) { + finding.knownExploits = JSON.parse(finding.knownExploitsJSON) + delete finding.knownExploitsJSON + } + if (finding.referencesJSON) { + finding.references = JSON.parse(finding.referencesJSON) + delete finding.referencesJSON + } + if (finding.timelineJSON) { + finding.timeline = JSON.parse(finding.timelineJSON) + delete finding.timelineJSON + } + return Response.json({ ok: true, finding }) + } catch (err) { + console.error(err) + return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) + } +} + +// Helper function to check if a value is valid (exists and not "n/a") +const isValidValue = (value) => { + return value != null && value !== "n/a" && value !== ""; +}; + +// Helper function to find first affected entry with valid required properties +const findFirstValidAffected = (affectedList = [], requiredProps = []) => { + return affectedList.find(affected => + requiredProps.every(prop => { + if (prop === 'versions') { + return Array.isArray(affected.versions) && + affected.versions.length > 0 && + affected.versions.some(v => isValidValue(v.version)); + } + if (prop === 'cpes') { + return Array.isArray(affected.cpes) && + affected.cpes.length > 0 && + affected.cpes.some(cpe => isValidValue(cpe)); + } + return isValidValue(affected[prop]); + }) + ); +}; + +// Helper function to find valid CVSS vector string with version preference +const findVectorString = (metrics = []) => { + const cvssVersions = ['cvssV4_0', 'cvssV3_1', 'cvssV3_0'] + + for (const version of cvssVersions) { + for (const metric of metrics) { + const vectorString = metric[version]?.vectorString + if (isValidValue(vectorString)) { + return vectorString + } + } + } + return null +} + +// Helper function to find valid CVSS vector string with version preference +const getCveData = async (prisma, r2adapter, verificationResult, cveId) => { + let cve = await prisma.CVEMetadata.findUnique({ + where: { cveId }, + include: { + fileLink: true, + adp: true, + cna: true, + } + }) + if (!cve) { + cve = await fetchCVE(prisma, r2adapter, verificationResult, cveId) + } + return cve +} + +const fetchCVE = async (prisma, r2adapter, verificationResult, cveId) => { + const cvelistv5 = await new MitreCVE().query(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, cveId) + const { + cveMetadata, + dataVersion, + containers: { cna, adp = [] } + } = cvelistv5 + // Create or connect CNA organization + await prisma.cVENumberingAuthrity.upsert({ + where: { orgId: cna.providerMetadata.orgId }, + create: { + orgId: cna.providerMetadata.orgId, + shortName: cna.providerMetadata.shortName + }, + update: {} + }) + + // Get affected data from ADP and CNA + const adpAffected = adp.flatMap(container => container.affected || []); + const cnaAffected = cna.affected || []; + + // Required properties we're looking for + const requiredProps = ['versions', 'vendor', 'product']; + + // Find first valid affected data, preferring ADP over CNA + const primaryAffected = findFirstValidAffected(adpAffected, requiredProps) || + findFirstValidAffected(cnaAffected, requiredProps) || + null; + + // Extract affected data ensuring valid values + const affectedData = { + versions: primaryAffected?.versions?.filter(v => isValidValue(v.version)) || [], + vendor: isValidValue(primaryAffected?.vendor) ? primaryAffected.vendor : null, + product: isValidValue(primaryAffected?.product) ? primaryAffected.product : null, + cpes: primaryAffected?.cpes?.filter(cpe => isValidValue(cpe)) || [] + } + + const vectorString = findVectorString(cna.metrics) + + // Create file link for the source + const [, year, number] = cveId.split('-') + const objectPath = `cvelistv5/${year}/${number.slice(0, -3) + "xxx"}/${cveId}.json` + const putOptions = { httpMetadata: { contentType: 'application/json', contentEncoding: 'utf8' } } + await r2adapter.put(objectPath, JSON.stringify(cvelistv5), putOptions) + const fileLink = await prisma.Link.create({ + data: { + url: `https://artifacts.vulnetix.app/${objectPath}`, + contentType: "PLAIN_JSON" + } + }) + const update = { + dataVersion, + state: cveMetadata.state, + datePublished: new Date(cveMetadata.datePublished).getTime(), + dateUpdated: cveMetadata?.dateUpdated ? new Date(cveMetadata.dateUpdated).getTime() : null, + dateReserved: cveMetadata?.dateReserved ? new Date(cveMetadata.dateReserved).getTime() : null, + vectorString, + title: cna?.title || 'Mitre CVE', + sourceAdvisoryRef: isValidValue(cna.source?.advisory) ? cna.source.advisory : null, + affectedVendor: affectedData.vendor, + affectedProduct: affectedData.product, + affectedVersionsJSON: affectedData.versions.length > 0 ? JSON.stringify(affectedData.versions) : null, + cpesJSON: affectedData.cpes.length > 0 ? JSON.stringify(affectedData.cpes) : null, + cnaOrgId: cna.providerMetadata.orgId, + fileLinkId: fileLink.id + } + // Create the main CVE record + const cve = await prisma.CVEMetadata.upsert({ + where: { cveId }, + create: { + cveId, + ...update + }, + update, + }) + + // Link ADP records + for (const adpContainer of adp) { + const { providerMetadata, title = '' } = adpContainer + await prisma.authorizedDataPublisher.upsert({ + where: { orgId: providerMetadata.orgId }, + create: { + orgId: providerMetadata.orgId, + shortName: providerMetadata.shortName, + title + }, + update: {} + }) + try { + // Create the relationship between CVE and ADP + await prisma.CVEADP.create({ + data: { + cveId, + adpId: providerMetadata.orgId + } + }) + } catch (e) { } + } + return cve +} diff --git a/functions/login/[email]/[hash].js b/functions/v1/login/[email]/[hash].js similarity index 93% rename from functions/login/[email]/[hash].js rename to functions/v1/login/[email]/[hash].js index 7fb62c9..c3b956a 100644 --- a/functions/login/[email]/[hash].js +++ b/functions/v1/login/[email]/[hash].js @@ -26,7 +26,7 @@ export async function onRequestGet(context) { }, }) - const member = await prisma.members.findFirst({ + const member = await prisma.Member.findFirst({ where: { email: params.email, }, @@ -44,6 +44,7 @@ export async function onRequestGet(context) { const secret = await hex(crypto.getRandomValues(new Uint32Array(26)), 'SHA-1') response.session = { kid: token, + orgId: member.orgId, memberEmail: member.email, expiry, issued, @@ -51,7 +52,7 @@ export async function onRequestGet(context) { authn_ip, authn_ua } - const sessionInfo = await prisma.sessions.create({ + const sessionInfo = await prisma.Session.create({ data: response.session }) console.log(`/login session kid=${token}`, sessionInfo) diff --git a/functions/login/github/[code].js b/functions/v1/login/github/[code].js similarity index 92% rename from functions/login/github/[code].js rename to functions/v1/login/github/[code].js index 10f6e23..c6c8d2f 100644 --- a/functions/login/github/[code].js +++ b/functions/v1/login/github/[code].js @@ -83,7 +83,7 @@ export async function onRequestGet(context) { lastName = words.join(' ') || '' } if (content?.company) { - const originalOrg = await prisma.orgs.findFirst({ + const originalOrg = await prisma.Org.findFirst({ where: { name: content.company } @@ -91,7 +91,7 @@ export async function onRequestGet(context) { if (originalOrg?.uuid) { orgId = originalOrg.uuid } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: content.company, @@ -100,7 +100,7 @@ export async function onRequestGet(context) { console.log(`/github/install register orgId=${orgId}`, orgInfo) } } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: memberEmail.toLowerCase(), @@ -117,7 +117,7 @@ export async function onRequestGet(context) { firstName, lastName } - const memberInfo = await prisma.members.create({ + const memberInfo = await prisma.Member.create({ data: response.member }) console.log(`/github/install register email=${memberEmail}`, memberInfo) @@ -130,6 +130,7 @@ export async function onRequestGet(context) { const secret = await hex(crypto.getRandomValues(new Uint32Array(26)), 'SHA-1') response.session = { kid: token, + orgId: response.member.orgId, memberEmail: response.member.email, expiry, issued: created, @@ -137,16 +138,16 @@ export async function onRequestGet(context) { authn_ip, authn_ua } - const sessionInfo = await prisma.sessions.create({ + const sessionInfo = await prisma.Session.create({ data: response.session }) console.log(`/github/install session kid=${token}`, sessionInfo) - const githubApp = await prisma.github_apps.findFirst({ + const githubApp = await prisma.GitHubApp.findFirst({ where: { memberEmail: response.member.email }, }) let installationId = githubApp?.installationId if (!installationId) { - const ghInstalls = await gh.getInstallations() + const ghInstalls = await gh.getInstallations(response.session.orgId, response.session.memberEmail) if (!ghInstalls?.ok || ghInstalls?.error?.message || !ghInstalls?.content?.installations || !ghInstalls.content?.installations?.length) { return Response.json({ ok: ghInstalls.ok, error: ghInstalls.error, result: `${ghInstalls.status} ${ghInstalls.statusText}` }) } @@ -158,7 +159,7 @@ export async function onRequestGet(context) { } } if (installationId) { - const GHAppInfo = await prisma.github_apps.upsert({ + const GHAppInfo = await prisma.GitHubApp.upsert({ where: { installationId: parseInt(installationId, 10), }, diff --git a/functions/me.js b/functions/v1/me.js similarity index 94% rename from functions/me.js rename to functions/v1/me.js index 0652724..50230fb 100644 --- a/functions/me.js +++ b/functions/v1/me.js @@ -24,7 +24,7 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const member = await prisma.members.findFirst({ + const member = await prisma.Member.findFirst({ where: { email: verificationResult.session.memberEmail, }, @@ -68,7 +68,7 @@ export async function onRequestPost(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const originalMember = await prisma.members.findFirst({ + const originalMember = await prisma.Member.findFirst({ where: { email: verificationResult.session.memberEmail, }, @@ -104,14 +104,14 @@ export async function onRequestPost(context) { member.alertType = parseInt(data.alertType, 10) } let updatedOrg = false - const originalOrg = await prisma.orgs.findFirst({ + const originalOrg = await prisma.Org.findFirst({ where: { uuid: originalMember.orgId, }, }) if (data?.orgName && originalOrg.name !== data.orgName) { //TODO: temp until organisations feature is finished - const orgInfo = await prisma.orgs.update({ + const orgInfo = await prisma.Org.update({ where: { uuid: originalMember.orgId, }, @@ -124,7 +124,7 @@ export async function onRequestPost(context) { } if (Object.keys(member).length > 0) { - const memberInfo = await prisma.members.update({ + const memberInfo = await prisma.Member.update({ where: { uuid: originalMember.uuid, }, diff --git a/functions/queue/sast.js b/functions/v1/new-issues.js similarity index 60% rename from functions/queue/sast.js rename to functions/v1/new-issues.js index bc76df2..3067a2d 100644 --- a/functions/queue/sast.js +++ b/functions/v1/new-issues.js @@ -27,23 +27,47 @@ export async function onRequestGet(context) { const { searchParams } = new URL(request.url) const take = parseInt(searchParams.get('take'), 10) || 50 const skip = parseInt(searchParams.get('skip'), 10) || 0 - const sast = await prisma.sarif_results.findMany({ + const findings = await prisma.Finding.findMany({ where: { - sarif: { - memberEmail: verificationResult.session.memberEmail, + orgId: verificationResult.session.orgId, + AND: { + triage: { + every: { seen: 0, analysisState: 'in_triage', } + } }, }, + omit: { + memberEmail: true, + }, include: { - sarif: true + triage: true, + spdx: { + include: { + repo: true + } + }, + cdx: { + include: { + repo: true + } + }, }, take, skip, orderBy: { - guid: 'asc', - }, + createdAt: 'asc', + } }) - return Response.json({ ok: true, sast }) + return Response.json({ + ok: true, findings: findings.map(finding => { + finding.references = JSON.parse(finding.referencesJSON) + delete finding.referencesJSON + finding.aliases = JSON.parse(finding.aliases) + finding.cwes = JSON.parse(finding.cwes) + return finding + }) + }) } catch (err) { console.error(err) return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) diff --git a/functions/v1/org/integrations.js b/functions/v1/org/integrations.js new file mode 100644 index 0000000..a416ee9 --- /dev/null +++ b/functions/v1/org/integrations.js @@ -0,0 +1,73 @@ +import { Server } from "@/utils"; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const githubApps = await prisma.GitHubApp.findMany({ + where: { + memberEmail: verificationResult.session.memberEmail, + }, + omit: { + memberEmail: true, + accessToken: true, + }, + }) + const patTokens = await prisma.MemberKey.findMany({ + where: { + memberEmail: verificationResult.session.memberEmail, + keyType: 'github_pat', + }, + include: { + githubPat: true, + }, + omit: { + memberEmail: true, + }, + }) + const integrations = await prisma.IntegrationConfig.findMany({ + where: { + orgId: verificationResult.session.orgId + } + }) + const result = { + ok: true, + githubApps, + patTokens: patTokens.map(i => { + i.secretMasked = mask(i.secret) + delete i.secret + return i + }) + } + for (const integration of integrations) { + if (integration?.configJSON) { + integration.config = JSON.parse(integration.configJSON) + } + if (integration.name === 'vulncheck') { + result.vulncheck_key = mask(integration?.config?.secret) + } + result[`${integration.name.replaceAll('-', '_')}_enabled`] = !integration?.suspend + } + + return Response.json(result) +} +const mask = s => s.slice(0, 11) + s.slice(10).slice(4, s.length - 4).slice(4, 12).replace(/(.)/g, '*') + s.slice(s.length - 4) diff --git a/functions/register/[org]/[email]/[hash].js b/functions/v1/register/[org]/[email]/[hash].js similarity index 89% rename from functions/register/[org]/[email]/[hash].js rename to functions/v1/register/[org]/[email]/[hash].js index 56684de..337cf22 100644 --- a/functions/register/[org]/[email]/[hash].js +++ b/functions/v1/register/[org]/[email]/[hash].js @@ -26,7 +26,7 @@ export async function onRequestGet(context) { ) { let orgId = crypto.randomUUID() if (params?.org) { - const originalOrg = await prisma.orgs.findFirst({ + const originalOrg = await prisma.Org.findFirst({ where: { name: params.org } @@ -34,7 +34,7 @@ export async function onRequestGet(context) { if (originalOrg?.uuid) { orgId = originalOrg.uuid } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: params.org, @@ -43,7 +43,7 @@ export async function onRequestGet(context) { console.log(`/register orgId=${orgId}`, orgInfo) } } else { - const orgInfo = await prisma.orgs.create({ + const orgInfo = await prisma.Org.create({ data: { uuid: orgId, name: params.email.toLowerCase(), @@ -57,7 +57,7 @@ export async function onRequestGet(context) { orgId, passwordHash: await pbkdf2(params.hash) } - const info = await prisma.members.create({ + const info = await prisma.Member.create({ data: member }) console.log(`/register email=${member.email}`, info) diff --git a/functions/sarif/upload.js b/functions/v1/sarif.js similarity index 66% rename from functions/sarif/upload.js rename to functions/v1/sarif.js index 93bbc3a..950771d 100644 --- a/functions/sarif/upload.js +++ b/functions/v1/sarif.js @@ -1,8 +1,68 @@ -import { Server, hex, isSARIF, ensureStrReqBody } from "@/utils"; +import { Server, ensureStrReqBody, hex, isSARIF, saveArtifact } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { searchParams } = new URL(request.url) + const take = parseInt(searchParams.get('take'), 10) || 50 + const skip = parseInt(searchParams.get('skip'), 10) || 0 + let sarif = await prisma.SARIFInfo.findMany({ + where: { + orgId: verificationResult.session.orgId, + }, + omit: { + memberEmail: true, + }, + include: { + results: true, + artifact: { + include: { + downloadLinks: true + } + }, + repo: true + }, + take, + skip, + orderBy: { + createdAt: 'desc', + }, + }) + sarif = sarif.map(item => { + let updatedItem = { ...item } + if (item.artifact && item.artifact.downloadLinks && item.artifact.downloadLinks.length) { + updatedItem.downloadLink = item.artifact.downloadLinks?.pop()?.url + // updatedItem.downloadLink = item.artifact.downloadLinks.filter(l => l.contentType === 'application/json')?.pop()?.url + } + // delete updatedItem.artifact + + return updatedItem + }) + + return Response.json({ ok: true, sarif }) +} + export async function onRequestPost(context) { const { request, // same as existing Worker API @@ -32,14 +92,16 @@ export async function onRequestPost(context) { if (!isSARIF(sarif)) { return Response.json({ ok: false, error: { message: 'SARIF is missing necessary fields.' } }) } - const sarifId = crypto.randomUUID() + const artifact = await saveArtifact(prisma, env.r2artifacts, JSON.stringify(sarif), crypto.randomUUID(), `sarif`) const createdAt = (new Date()).getTime() for (const run of sarif.runs) { const reportId = await hex(run.tool.driver.name + run.tool.driver.semanticVersion + JSON.stringify(run.results)) const sarifData = { - sarifId, + sarifId: artifact.uuid, + artifactUuid: artifact.uuid, reportId, source: 'upload', + orgId: verificationResult.session.orgId, memberEmail: verificationResult.session.memberEmail, createdAt, resultsCount: run.results.length, @@ -47,7 +109,7 @@ export async function onRequestPost(context) { toolName: run.tool.driver.name, toolVersion: run.tool.driver.semanticVersion, } - const info = await prisma.sarif.upsert({ + const info = await prisma.SARIFInfo.upsert({ where: { reportId, }, @@ -56,7 +118,7 @@ export async function onRequestPost(context) { }, create: sarifData, }) - console.log(`/sarif/upload ${sarifId} kid=${verificationResult.session.kid}`, info) + console.log(`/sarif/upload ${artifact.uuid} kid=${verificationResult.session.kid}`, info) sarifData.results = [] for (const result of run.results) { const locationsJSON = JSON.stringify(result.locations) @@ -99,7 +161,7 @@ export async function onRequestPost(context) { } } sarifData.results.push(resultData) - const reportInfo = await prisma.sarif_results.upsert({ + const reportInfo = await prisma.SarifResults.upsert({ where: { guid: resultData.guid, }, @@ -108,7 +170,7 @@ export async function onRequestPost(context) { }, create: resultData, }) - console.log(`/github/repos/sarif_results ${sarifId} kid=${verificationResult.session.kid}`, reportInfo) + // console.log(`/github/repos/sarif_results ${artifact.uuid} kid=${verificationResult.session.kid}`, reportInfo) } files.push(sarifData) } diff --git a/functions/sarif/results.js b/functions/v1/sarif/[reportId].js similarity index 53% rename from functions/sarif/results.js rename to functions/v1/sarif/[reportId].js index fb0d3f7..55922d7 100644 --- a/functions/sarif/results.js +++ b/functions/v1/sarif/[reportId].js @@ -2,7 +2,7 @@ import { Server } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; -export async function onRequestGet(context) { +export async function onRequestDelete(context) { const { request, // same as existing Worker API env, // same as existing Worker API @@ -23,23 +23,25 @@ export async function onRequestGet(context) { if (!verificationResult.isValid) { return Response.json({ ok: false, result: verificationResult.message }) } - const { searchParams } = new URL(request.url) - const take = parseInt(searchParams.get('take'), 10) || 50 - const skip = parseInt(searchParams.get('skip'), 10) || 0 - const sarif = await prisma.sarif.findMany({ - where: { - memberEmail: verificationResult.session.memberEmail, - }, + const sarif = await prisma.SARIFInfo.findFirst({ + where: { reportId: params.reportId }, include: { results: true, - repo: true - }, - take, - skip, - orderBy: { - createdAt: 'desc', - }, + artifact: { + include: { + downloadLinks: true + } + }, + } }) - - return Response.json({ ok: true, sarif }) + for (const link of sarif.artifact.downloadLinks) { + await prisma.Link.delete({ where: { id: link.id } }) + } + await prisma.Artifact.delete({ where: { uuid: sarif.artifact.uuid } }) + for (const result of sarif.results) { + await prisma.SarifResults.delete({ where: { guid: result.guid } }) + } + const sarifInfo = await prisma.SARIFInfo.delete({ where: { reportId: params.reportId } }) + console.log(`DELETE /sarif/[${params.reportId}]`, sarifInfo) + return Response.json({ ok: true, reportId: params.reportId, artifactUuid: sarif.artifact.uuid }) } diff --git a/functions/v1/search.js b/functions/v1/search.js new file mode 100644 index 0000000..c745a15 --- /dev/null +++ b/functions/v1/search.js @@ -0,0 +1,129 @@ +import { AuthResult, Server, parseSearchQuery } from "@/utils"; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + try { + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + log: [ + { + emit: "event", + level: "query", + }, + ], + }) + prisma.$on("query", async (e) => { + console.log(`${e.query} ${e.params}`) + }); + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { searchParams } = new URL(request.url) + const take = parseInt(searchParams.get('take'), 10) || 5 + const { inclusive, exclude, terms } = parseSearchQuery(searchParams.get('q')) + const findings = [] + const where = { orgId: verificationResult.session.orgId, OR: [], NOT: [] } + + for (const contains of terms) { + where.OR.push({ repoName: { contains } }) + where.OR.push({ purl: { contains } }) + where.OR.push({ aliases: { contains } }) + where.OR.push({ cwes: { contains } }) + where.OR.push({ detectionTitle: { contains } }) + } + const res = await prisma.Finding.findMany({ + where, + select: { + uuid: true, + repoName: true, + category: true, + modifiedAt: true, + detectionTitle: true, + purl: true, + aliases: true, + cwes: true, + spdx: { + select: { + name: true, + source: true, + repoName: true, + spdxVersion: true, + createdAt: true, + packagesCount: true, + artifact: { + select: { + uuid: true, + type: true, + downloadLinks: true, + bomFormat: true, + } + } + }, + }, + cdx: { + select: { + name: true, + version: true, + source: true, + repoName: true, + cdxVersion: true, + createdAt: true, + dependenciesCount: true, + artifact: { + select: { + uuid: true, + type: true, + downloadLinks: true, + bomFormat: true, + } + } + }, + }, + }, + take, + orderBy: { + modifiedAt: 'desc', + } + }) + for (const item of res || []) { + const jsonText = JSON.stringify(item) + let add = true + for (const excludes of exclude) { + if (jsonText.includes(excludes)) { + add = false + break + } + } + if (add && inclusive.every(str => jsonText.includes(str))) { + // expand JSON fields + if (item.cwes) { + item.cwes = JSON.parse(item.cwes) + } + if (item.aliases) { + item.aliases = JSON.parse(item.aliases) + } + findings.push(item) + } + } + + return Response.json({ ok: true, results: { findings } }) + } catch (err) { + console.error(err) + return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) + } +} diff --git a/functions/spdx/upload.js b/functions/v1/spdx.js similarity index 55% rename from functions/spdx/upload.js rename to functions/v1/spdx.js index 19b8466..16dc4ee 100644 --- a/functions/spdx/upload.js +++ b/functions/v1/spdx.js @@ -1,8 +1,91 @@ -import { AuthResult, OSV, Server, hex, isSPDX, ensureStrReqBody } from "@/utils"; +import { AuthResult, OSV, Server, ensureStrReqBody, hex, isSPDX, saveArtifact } from "@/utils"; import { PrismaD1 } from '@prisma/adapter-d1'; import { PrismaClient } from '@prisma/client'; +export async function onRequestGet(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const { searchParams } = new URL(request.url) + const take = parseInt(searchParams.get('take'), 10) || 50 + const skip = parseInt(searchParams.get('skip'), 10) || 0 + let spdx = await prisma.SPDXInfo.findMany({ + where: { + orgId: verificationResult.session.orgId, + }, + select: { + spdxId: true, + source: true, + repoName: true, + artifactUuid: true, + spdxVersion: true, + name: true, + createdAt: true, + toolName: true, + packagesCount: true, + artifact: { + select: { + downloadLinks: { + select: { + contentType: true, + url: true, + } + } + } + } + }, + take, + skip, + orderBy: { + createdAt: 'desc', + }, + }) + + const repos = await prisma.gitRepo.findMany({ + where: { + fullName: { in: spdx.map(s => s?.repoName).filter(s => !!s).filter((value, index, array) => array.indexOf(value) === index) }, + }, + select: { + avatarUrl: true, + fullName: true, + }, + }) + const repoMap = new Map(repos.map(repo => [repo.fullName, repo.avatarUrl])); + + spdx = spdx.map(item => { + let updatedItem = { ...item } + if (item.repoName && repoMap.has(item.repoName)) { + updatedItem.avatarUrl = repoMap.get(item.repoName) + } + if (item.artifact && item.artifact.downloadLinks && item.artifact.downloadLinks.length) { + updatedItem.downloadLink = item.artifact.downloadLinks.filter(l => l.contentType === 'application/spdx+json')?.pop()?.url + } + delete updatedItem.artifact + + return updatedItem + }) + + return Response.json({ ok: true, spdx }) +} + export async function onRequestPost(context) { const { request, // same as existing Worker API @@ -33,11 +116,21 @@ export async function onRequestPost(context) { if (!isSPDX(spdx)) { return Response.json({ ok: false, error: { message: 'SPDX is missing necessary fields.' } }) } + const spdxId = await makeId(spdx) + const originalSpdx = await prisma.SPDXInfo.findFirst({ + where: { + spdxId, + orgId: verificationResult.session.orgId, + } + }) const spdxStr = JSON.stringify(spdx) - const spdxId = await hex(spdxStr) + const artifact = await saveArtifact(prisma, env.r2artifacts, spdxStr, crypto.randomUUID(), `spdx`) + const artifactUuid = originalSpdx?.artifactUuid || artifact?.uuid const spdxData = { spdxId, + artifactUuid, source: 'upload', + orgId: verificationResult.session.orgId, memberEmail: verificationResult.session.memberEmail, repoName: '', spdxVersion: spdx.spdxVersion, @@ -50,10 +143,10 @@ export async function onRequestPost(context) { packagesCount: spdx.packages.length, comment: spdx.creationInfo?.comment || '', } - const info = await prisma.spdx.upsert({ + const info = await prisma.SPDXInfo.upsert({ where: { spdxId, - memberEmail: verificationResult.session.memberEmail, + orgId: verificationResult.session.orgId, }, update: { createdAt: spdxData.createdAt, @@ -77,7 +170,7 @@ export async function onRequestPost(context) { }).filter(q => q?.referenceLocator) const osv = new OSV() const queries = osvQueries.map(q => ({ package: { purl: q?.referenceLocator } })) - const results = await osv.queryBatch(prisma, verificationResult.session.memberEmail, queries) + const results = await osv.queryBatch(prisma, verificationResult.session.orgId, verificationResult.session.memberEmail, queries) let i = 0 for (const result of results) { const { referenceLocator, name, version, license } = osvQueries[i] @@ -88,6 +181,7 @@ export async function onRequestPost(context) { const findingId = await hex(`${vuln.id}${referenceLocator}`) const findingData = { findingId, + orgId: verificationResult.session.orgId, memberEmail: verificationResult.session.memberEmail, source: 'osv.dev', category: 'sca', @@ -98,54 +192,59 @@ export async function onRequestPost(context) { packageName: name, packageVersion: version, packageLicense: license, + malicious: vuln.id.startsWith("MAL-") ? 1 : 0, spdxId } - const originalFinding = await prisma.findings.findFirst({ + const originalFinding = await prisma.Finding.findFirst({ where: { findingId, AND: { - memberEmail: verificationResult.session.memberEmail + orgId: verificationResult.session.orgId }, } }) let finding; if (originalFinding) { - finding = await prisma.findings.update({ + finding = await prisma.Finding.update({ where: { - id: originalFinding.id, + uuid: originalFinding.uuid, }, data: { + spdxId, + packageLicense: findingData.packageLicense, + malicious: findingData.malicious, modifiedAt: findingData.modifiedAt }, }) } else { - finding = await prisma.findings.create({ data: findingData }) + finding = await prisma.Finding.create({ data: findingData }) } // console.log(`findings SCA`, finding) const vexData = { - findingKey: finding.id, + findingUuid: finding.uuid, createdAt: (new Date()).getTime(), lastObserved: (new Date()).getTime(), seen: 0, analysisState: 'in_triage' } - const originalVex = await prisma.triage_activity.findUnique({ + const originalVex = await prisma.Triage.findFirst({ where: { - findingKey: finding.id, + findingUuid: finding.uuid, + analysisState: 'in_triage', } }) let vex; if (originalVex) { - vex = await prisma.triage_activity.update({ + vex = await prisma.Triage.update({ where: { - findingKey: finding.id, + uuid: originalVex.uuid, }, data: { lastObserved: vexData.lastObserved }, }) } else { - vex = await prisma.triage_activity.create({ data: vexData }) + vex = await prisma.Triage.create({ data: vexData }) } // console.log(`findings VEX`, vex) } @@ -165,3 +264,8 @@ export async function onRequestPost(context) { return Response.json({ ok: true, files, error: { message: errors } }) } + +const makeId = async spdx => { + const packages = JSON.stringify(spdx.packages) + return hex(spdx.name + packages) +} diff --git a/functions/v1/vulncheck/integrate.js b/functions/v1/vulncheck/integrate.js new file mode 100644 index 0000000..8251de2 --- /dev/null +++ b/functions/v1/vulncheck/integrate.js @@ -0,0 +1,73 @@ +import { AuthResult, Server, ensureStrReqBody } from "@/utils"; +import { PrismaD1 } from '@prisma/adapter-d1'; +import { PrismaClient } from '@prisma/client'; + +export async function onRequestPost(context) { + const { + request, // same as existing Worker API + env, // same as existing Worker API + params, // if filename includes [id] or [[path]] + waitUntil, // same as ctx.waitUntil in existing Worker API + next, // used for middleware or to fetch assets + data, // arbitrary space for passing data between middlewares + } = context + try { + const adapter = new PrismaD1(env.d1db) + const prisma = new PrismaClient({ + adapter, + transactionOptions: { + maxWait: 1500, // default: 2000 + timeout: 2000, // default: 5000 + }, + }) + const verificationResult = await (new Server(request, prisma)).authenticate() + if (!verificationResult.isValid) { + return Response.json({ ok: false, result: verificationResult.message }) + } + const bodyStr = await ensureStrReqBody(request) + const data = JSON.parse(bodyStr) + if (data?.apiKey && !data.apiKey.startsWith('vulncheck_')) { + return Response.json({ error: { message: `Invalid API Key provided, expected "vulncheck_" prefix.` } }) + } + const where = { + orgId: verificationResult.session.orgId, + AND: { name: 'vulncheck' }, + } + const original = await prisma.IntegrationConfig.findFirst({ where }) + if (original === null) { + if (data?.apiKey === undefined) { + return Response.json({ ok: false, result: 'No Change' }) + } + const info = await prisma.IntegrationConfig.create({ + data: { + orgId: verificationResult.session.orgId, + name: 'vulncheck', + created: new Date().getTime(), + configJSON: JSON.stringify({ secret: data.apiKey }), + suspend: data?.suspend === undefined ? 0 : (data.suspend ? 1 : 0), + } + }) + return Response.json({ ok: true, info }) + } + if (original?.configJSON) { + original.config = JSON.parse(original.configJSON) + if (data?.apiKey === original.config.secret && (data?.suspend ? 1 : 0) === original.suspend) { + return Response.json({ ok: false, result: 'No Change' }) + } + } + const info = await prisma.IntegrationConfig.update({ + where: { + uuid: original.uuid + }, + data: { + configJSON: data?.apiKey === undefined || data.apiKey.includes('****') ? original.configJSON : JSON.stringify({ secret: data.apiKey }), + suspend: data?.suspend === undefined ? original.suspend : (data.suspend ? 1 : 0), + } + }) + return Response.json({ ok: true, info }) + + } catch (err) { + console.error(err) + return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) + } +} diff --git a/functions/vulncheck/log.js b/functions/vulncheck/log.js deleted file mode 100644 index c7468c4..0000000 --- a/functions/vulncheck/log.js +++ /dev/null @@ -1,55 +0,0 @@ -import { AuthResult, Server } from "@/utils"; -import { PrismaD1 } from '@prisma/adapter-d1'; -import { PrismaClient } from '@prisma/client'; - -export async function onRequestGet(context) { - const { - request, // same as existing Worker API - env, // same as existing Worker API - params, // if filename includes [id] or [[path]] - waitUntil, // same as ctx.waitUntil in existing Worker API - next, // used for middleware or to fetch assets - data, // arbitrary space for passing data between middlewares - } = context - try { - const adapter = new PrismaD1(env.d1db) - const prisma = new PrismaClient({ - adapter, - transactionOptions: { - maxWait: 1500, // default: 2000 - timeout: 2000, // default: 5000 - }, - }) - const verificationResult = await (new Server(request, prisma)).authenticate() - if (!verificationResult.isValid) { - return Response.json({ ok: false, result: verificationResult.message }) - } - const keyData = await prisma.member_keys.findFirst({ - where: { - memberEmail: verificationResult.session.memberEmail, - keyType: 'vulncheck', - } - }) - const _meta = {} - if (typeof keyData?.secret !== 'undefined') { - _meta['apiKey'] = mask(keyData.secret) - } - - const log = await prisma.integration_usage_log.findMany({ - where: { - memberEmail: verificationResult.session.memberEmail, - source: 'vulncheck', - }, - take: 1000, - orderBy: { - createdAt: 'desc', - }, - }) - - return Response.json({ ok: true, log, _meta }) - } catch (err) { - console.error(err) - return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED }) - } -} -const mask = s => s.slice(0, 10) + s.slice(10).slice(4, s.length - 4).replace(/(.)/g, '*') + s.slice(s.length - 4) diff --git a/jsconfig.json b/jsconfig.json index c79eea7..02a3011 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -19,7 +19,6 @@ "target": "esnext", "module": "esnext", "moduleResolution": "node", - "jsx": "preserve", "paths": { "@/*": [ "src/*" diff --git a/migrations/0001_init.sql b/migrations/0001_init.sql index 16f0d86..c430cdb 100644 --- a/migrations/0001_init.sql +++ b/migrations/0001_init.sql @@ -166,30 +166,9 @@ CREATE TABLE "triage_activity" ( "ssvc" TEXT, "remediation" TEXT, "analysisState" TEXT NOT NULL, - -- resolved - -- resolved_with_pedigree - -- exploitable - -- in_triage - -- false_positive - -- not_affected "analysisJustification" TEXT, - -- code_not_present - -- code_not_reachable - -- requires_configuration - -- requires_dependency - -- requires_environment - -- protected_by_compiler - -- protected_at_runtime - -- protected_at_perimeter - -- protected_by_mitigating_control "analysisResponse" TEXT, - -- ONE OR MORE OF: - -- can_not_fix - -- will_not_fix - -- update - -- rollback - -- workaround_available - "analysisDetail" TEXT -- entered by users + "analysisDetail" TEXT ); CREATE UNIQUE INDEX "sessions_kid_key" ON "sessions"("kid"); CREATE UNIQUE INDEX "members_email_key" ON "members"("email"); diff --git a/migrations/0009_tea_init.sql b/migrations/0009_tea_init.sql index 01a2562..e88349e 100644 --- a/migrations/0009_tea_init.sql +++ b/migrations/0009_tea_init.sql @@ -6,14 +6,12 @@ CREATE TABLE "Lifecycle" ( "leafUuid" TEXT, "productUuid" TEXT ); - CREATE TABLE "Link" ( "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "uri" TEXT NOT NULL, "content" TEXT NOT NULL, "artifactUuid" TEXT ); - CREATE TABLE "Artifact" ( "uuid" TEXT NOT NULL PRIMARY KEY, "displayIdentifier" TEXT NOT NULL, @@ -24,7 +22,6 @@ CREATE TABLE "Artifact" ( "inventoryTypes" TEXT NOT NULL, "collectionUuid" TEXT ); - CREATE TABLE "Identity" ( "id" TEXT NOT NULL PRIMARY KEY, "type" TEXT NOT NULL, @@ -32,13 +29,11 @@ CREATE TABLE "Identity" ( "artifactId" TEXT, "collectionUuid" TEXT ); - CREATE TABLE "Collection" ( "uuid" TEXT NOT NULL PRIMARY KEY, "version" TEXT, "created" INTEGER NOT NULL ); - CREATE TABLE "Leaf" ( "uuid" TEXT NOT NULL PRIMARY KEY, "name" TEXT NOT NULL, @@ -46,11 +41,8 @@ CREATE TABLE "Leaf" ( "version" TEXT NOT NULL, "productUuid" TEXT ); - CREATE TABLE "Product" ( "uuid" TEXT NOT NULL PRIMARY KEY, "name" TEXT NOT NULL ); - CREATE UNIQUE INDEX "Leaf_tei_key" ON "Leaf"("tei"); - diff --git a/migrations/0012_refactor_tables.sql b/migrations/0012_refactor_tables.sql new file mode 100644 index 0000000..75a00ca --- /dev/null +++ b/migrations/0012_refactor_tables.sql @@ -0,0 +1,336 @@ +DROP INDEX IF EXISTS "cdx_cdxId_key"; +DROP INDEX IF EXISTS "github_apps_installationId_key"; +DROP INDEX IF EXISTS "github_pat_keyId_key"; +DROP INDEX IF EXISTS "member_keys_memberEmail_secret_key"; +DROP INDEX IF EXISTS "members_email_key"; +DROP INDEX IF EXISTS "sarif_sarifId_key"; +DROP INDEX IF EXISTS "sarif_results_guid_key"; +DROP INDEX IF EXISTS "sessions_kid_key"; +DROP INDEX IF EXISTS "spdx_spdxId_key"; +DROP TABLE IF EXISTS "Org"; +CREATE TABLE "Org" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL +); +INSERT INTO "Org" ("uuid", "name") +SELECT "uuid", + "name" +FROM "orgs"; +DROP TABLE IF EXISTS "orgs"; +DROP TABLE IF EXISTS "Member"; +CREATE TABLE "Member" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "email" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "passwordHash" TEXT NOT NULL, + "avatarUrl" TEXT, + "firstName" TEXT, + "lastName" TEXT, + "alertNews" INTEGER NOT NULL DEFAULT 0, + "alertOverdue" INTEGER NOT NULL DEFAULT 0, + "alertFindings" INTEGER NOT NULL DEFAULT 0, + "alertType" INTEGER NOT NULL DEFAULT 0 +); +INSERT INTO "Member" ( + "uuid", + "email", + "orgId", + "passwordHash", + "avatarUrl", + "firstName", + "lastName", + "alertNews", + "alertOverdue", + "alertFindings", + "alertType" + ) +SELECT "uuid", + "email", + "orgId", + "passwordHash", + "avatarUrl", + "firstName", + "lastName", + "alertNews", + "alertOverdue", + "alertFindings", + "alertType" +FROM "members"; +DROP TABLE IF EXISTS "members"; +DROP TABLE IF EXISTS "MemberKey"; +CREATE TABLE "MemberKey" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "memberEmail" TEXT NOT NULL, + "keyLabel" TEXT, + "keyType" TEXT NOT NULL, + "secret" TEXT NOT NULL, + "suspend" INTEGER NOT NULL DEFAULT 0 +); +INSERT INTO "MemberKey" ( + "id", + "memberEmail", + "keyLabel", + "keyType", + "secret", + "suspend" + ) +SELECT "id", + "memberEmail", + "keyLabel", + "keyType", + "secret", + "suspend" +FROM "member_keys"; +DROP TABLE IF EXISTS "member_keys"; +DROP TABLE IF EXISTS "GitHubPAT"; +CREATE TABLE "GitHubPAT" ( + "keyId" INTEGER NOT NULL PRIMARY KEY, + "login" TEXT NOT NULL, + "expires" INTEGER NOT NULL, + "created" INTEGER NOT NULL, + "avatarUrl" TEXT +); +INSERT INTO "GitHubPAT" ( + "keyId", + "login", + "expires", + "created", + "avatarUrl" + ) +SELECT "keyId", + "login", + "expires", + "created", + "avatarUrl" +FROM "github_pat"; +DROP TABLE IF EXISTS "github_pat"; +DROP TABLE IF EXISTS "GitHubApp"; +CREATE TABLE "GitHubApp" ( + "installationId" INTEGER NOT NULL PRIMARY KEY, + "memberEmail" TEXT NOT NULL, + "accessToken" TEXT NOT NULL, + "login" TEXT, + "created" INTEGER NOT NULL, + "expires" INTEGER, + "avatarUrl" TEXT +); +INSERT INTO "GitHubApp" ( + "installationId", + "memberEmail", + "accessToken", + "login", + "created", + "expires", + "avatarUrl" + ) +SELECT "installationId", + "memberEmail", + "accessToken", + "login", + "created", + "expires", + "avatarUrl" +FROM "github_apps"; +DROP TABLE IF EXISTS "github_apps"; +DROP TABLE IF EXISTS "cdx"; +DROP TABLE IF EXISTS "findings"; +DROP TABLE IF EXISTS "git_repos"; +DROP TABLE IF EXISTS "integration_usage_log"; +DROP TABLE IF EXISTS "sarif"; +DROP TABLE IF EXISTS "sarif_results"; +DROP TABLE IF EXISTS "spdx"; +DROP TABLE IF EXISTS "triage_activity"; +DROP TABLE IF EXISTS "sessions"; +DROP TABLE IF EXISTS "Session"; +CREATE TABLE "Session" ( + "kid" TEXT NOT NULL PRIMARY KEY, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "expiry" INTEGER NOT NULL, + "issued" INTEGER NOT NULL, + "secret" TEXT, + "authn_ip" TEXT, + "authn_ua" TEXT +); +DROP TABLE IF EXISTS "GitRepo"; +CREATE TABLE "GitRepo" ( + "orgId" TEXT NOT NULL, + "fullName" TEXT NOT NULL, + "ghid" INTEGER, + "source" TEXT NOT NULL, + "createdAt" INTEGER NOT NULL, + "updatedAt" INTEGER NOT NULL, + "pushedAt" INTEGER NOT NULL, + "defaultBranch" TEXT NOT NULL, + "ownerId" INTEGER NOT NULL, + "memberEmail" TEXT NOT NULL, + "licenseSpdxId" TEXT, + "licenseName" TEXT, + "fork" INTEGER NOT NULL DEFAULT 0, + "template" INTEGER NOT NULL DEFAULT 0, + "archived" INTEGER NOT NULL DEFAULT 0, + "visibility" TEXT NOT NULL, + "avatarUrl" TEXT, + PRIMARY KEY ("fullName", "orgId") +); +DROP TABLE IF EXISTS "SARIFInfo"; +CREATE TABLE "SARIFInfo" ( + "reportId" TEXT NOT NULL PRIMARY KEY, + "sarifId" TEXT NOT NULL, + "artifactUuid" TEXT NOT NULL, + "fullName" TEXT, + "source" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "commitSha" TEXT, + "ref" TEXT, + "createdAt" INTEGER NOT NULL, + "resultsCount" INTEGER NOT NULL, + "rulesCount" INTEGER NOT NULL, + "toolName" TEXT, + "toolVersion" TEXT, + "analysisKey" TEXT, + "warning" TEXT +); +DROP TABLE IF EXISTS "SarifResults"; +CREATE TABLE "SarifResults" ( + "guid" TEXT NOT NULL PRIMARY KEY, + "reportId" TEXT NOT NULL, + "messageText" TEXT NOT NULL, + "ruleId" TEXT NOT NULL, + "locations" TEXT, + "automationDetailsId" TEXT, + "rulesetName" TEXT, + "level" TEXT, + "description" TEXT, + "helpMarkdown" TEXT, + "securitySeverity" TEXT, + "precision" TEXT, + "tags" TEXT +); +DROP TABLE IF EXISTS "CycloneDXInfo"; +CREATE TABLE "CycloneDXInfo" ( + "cdxId" TEXT NOT NULL PRIMARY KEY, + "source" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "artifactUuid" TEXT NOT NULL, + "repoName" TEXT, + "cdxVersion" TEXT NOT NULL, + "serialNumber" TEXT, + "name" TEXT, + "version" TEXT, + "createdAt" INTEGER NOT NULL, + "toolName" TEXT, + "externalReferencesCount" INTEGER NOT NULL, + "componentsCount" INTEGER NOT NULL, + "dependenciesCount" INTEGER NOT NULL +); +DROP TABLE IF EXISTS "SPDXInfo"; +CREATE TABLE "SPDXInfo" ( + "spdxId" TEXT NOT NULL PRIMARY KEY, + "source" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "artifactUuid" TEXT NOT NULL, + "repoName" TEXT, + "spdxVersion" TEXT NOT NULL, + "dataLicense" TEXT, + "name" TEXT, + "documentNamespace" TEXT, + "createdAt" INTEGER NOT NULL, + "toolName" TEXT, + "documentDescribes" TEXT, + "packagesCount" INTEGER NOT NULL, + "comment" TEXT +); +DROP TABLE IF EXISTS "IntegrationUsageLog"; +CREATE TABLE "IntegrationUsageLog" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "source" TEXT NOT NULL, + "request" TEXT NOT NULL, + "response" TEXT, + "statusCode" INTEGER NOT NULL, + "createdAt" INTEGER NOT NULL +); +DROP TABLE IF EXISTS "Finding"; +CREATE TABLE "Finding" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "findingId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "repoName" TEXT, + "source" TEXT NOT NULL, + "category" TEXT NOT NULL, + "createdAt" INTEGER NOT NULL, + "modifiedAt" INTEGER NOT NULL, + "publishedAt" INTEGER, + "detectionTitle" TEXT NOT NULL, + "purl" TEXT, + "cpe" TEXT, + "databaseReviewed" INTEGER, + "cve" TEXT, + "aliases" TEXT, + "cwes" TEXT, + "packageName" TEXT NOT NULL, + "packageVersion" TEXT, + "packageLicense" TEXT, + "vendor" TEXT, + "product" TEXT, + "packageEcosystem" TEXT, + "sourceCodeUrl" TEXT, + "exploitsJSON" TEXT, + "knownExploitsJSON" TEXT, + "cisaDateAdded" INTEGER, + "knownRansomwareCampaignUse" TEXT, + "fixVersion" TEXT, + "fixAutomatable" INTEGER, + "vulnerableVersionRange" TEXT, + "maliciousSource" TEXT, + "abandoned" INTEGER, + "squattedPackage" TEXT, + "referencesJSON" TEXT, + "spdxId" TEXT, + "cdxId" TEXT +); +DROP TABLE IF EXISTS "Triage"; +CREATE TABLE "Triage" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "findingUuid" TEXT NOT NULL, + "artifactUuid" TEXT, + "createdAt" INTEGER NOT NULL, + "triagedAt" INTEGER, + "lastObserved" INTEGER NOT NULL, + "seen" INTEGER NOT NULL, + "seenAt" INTEGER, + "cvssVector" TEXT, + "cvssScore" TEXT, + "epssPercentile" TEXT, + "epssScore" TEXT, + "ssvc" TEXT, + "remediation" TEXT, + "analysisState" TEXT NOT NULL, + "analysisJustification" TEXT, + "analysisResponse" TEXT, + "analysisDetail" TEXT, + "triageAutomated" INTEGER NOT NULL DEFAULT 0, + "memberEmail" TEXT +); +DROP TABLE IF EXISTS "Artifact"; +CREATE TABLE "Artifact" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "type" TEXT NOT NULL, + "date" INTEGER NOT NULL, + "bomFormat" TEXT NOT NULL +); +DROP TABLE IF EXISTS "Link"; +CREATE TABLE "Link" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "url" TEXT NOT NULL, + "contentType" TEXT NOT NULL, + "artifactUuid" TEXT +); +CREATE UNIQUE INDEX "Member_email_key" ON "Member"("email"); +CREATE UNIQUE INDEX "MemberKey_memberEmail_secret_key" ON "MemberKey"("memberEmail", "secret"); diff --git a/migrations/0013_integration_config.sql b/migrations/0013_integration_config.sql new file mode 100644 index 0000000..e6e3644 --- /dev/null +++ b/migrations/0013_integration_config.sql @@ -0,0 +1,9 @@ +CREATE TABLE "IntegrationConfig" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "orgId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "label" TEXT, + "created" INTEGER NOT NULL, + "suspend" INTEGER DEFAULT 0, + "configJSON" TEXT +); diff --git a/migrations/0014_add_timeline.sql b/migrations/0014_add_timeline.sql new file mode 100644 index 0000000..101904d --- /dev/null +++ b/migrations/0014_add_timeline.sql @@ -0,0 +1,5 @@ +ALTER TABLE Finding +ADD timelineJSON TEXT; +ALTER TABLE Finding DROP COLUMN maliciousSource; +ALTER TABLE Finding +ADD malicious INTEGER; diff --git a/migrations/0015_cve.sql b/migrations/0015_cve.sql new file mode 100644 index 0000000..bdb4b43 --- /dev/null +++ b/migrations/0015_cve.sql @@ -0,0 +1,150 @@ +CREATE TABLE "CVEMetadata" ( + "cveId" TEXT NOT NULL PRIMARY KEY, + "dataVersion" TEXT NOT NULL, + "state" TEXT NOT NULL, + "datePublished" INTEGER NOT NULL, + "dateUpdated" INTEGER, + "dateReserved" INTEGER, + "vectorString" TEXT, + "title" TEXT NOT NULL, + "sourceAdvisoryRef" TEXT, + "affectedVendor" TEXT, + "affectedProduct" TEXT, + "affectedVersionsJSON" TEXT, + "cpesJSON" TEXT, + "cnaOrgId" TEXT NOT NULL, + "fileLinkId" INTEGER NOT NULL +); +CREATE TABLE "CVENumberingAuthrity" ( + "orgId" TEXT NOT NULL PRIMARY KEY, + "shortName" TEXT NOT NULL +); +CREATE TABLE "CVEADP" ( + "cveId" TEXT NOT NULL, + "adpId" TEXT NOT NULL, + PRIMARY KEY ("cveId", "adpId") +); +CREATE TABLE "AuthorizedDataPublisher" ( + "orgId" TEXT NOT NULL PRIMARY KEY, + "shortName" TEXT NOT NULL, + "title" TEXT NOT NULL +); +CREATE TABLE "new_Finding" ( + "uuid" TEXT NOT NULL PRIMARY KEY, + "findingId" TEXT NOT NULL, + "orgId" TEXT NOT NULL, + "memberEmail" TEXT NOT NULL, + "repoName" TEXT, + "source" TEXT NOT NULL, + "category" TEXT NOT NULL, + "createdAt" INTEGER NOT NULL, + "modifiedAt" INTEGER NOT NULL, + "publishedAt" INTEGER, + "detectionTitle" TEXT NOT NULL, + "purl" TEXT, + "cpe" TEXT, + "databaseReviewed" INTEGER, + "aliases" TEXT, + "cwes" TEXT, + "packageName" TEXT NOT NULL, + "packageVersion" TEXT, + "packageLicense" TEXT, + "vendor" TEXT, + "product" TEXT, + "packageEcosystem" TEXT, + "advisoryUrl" TEXT, + "exploitsJSON" TEXT, + "knownExploitsJSON" TEXT, + "cisaDateAdded" INTEGER, + "knownRansomwareCampaignUse" TEXT, + "fixVersion" TEXT, + "fixAutomatable" INTEGER, + "vulnerableVersionRange" TEXT, + "malicious" INTEGER, + "abandoned" INTEGER, + "squattedPackage" TEXT, + "referencesJSON" TEXT, + "timelineJSON" TEXT, + "spdxId" TEXT, + "cdxId" TEXT +); +INSERT INTO "new_Finding" ( + "abandoned", + "aliases", + "category", + "cdxId", + "cisaDateAdded", + "cpe", + "createdAt", + "cwes", + "databaseReviewed", + "detectionTitle", + "exploitsJSON", + "findingId", + "fixAutomatable", + "fixVersion", + "knownExploitsJSON", + "knownRansomwareCampaignUse", + "malicious", + "memberEmail", + "modifiedAt", + "orgId", + "packageEcosystem", + "advisoryUrl", + "packageLicense", + "packageName", + "packageVersion", + "product", + "publishedAt", + "purl", + "referencesJSON", + "repoName", + "source", + "spdxId", + "squattedPackage", + "timelineJSON", + "uuid", + "vendor", + "vulnerableVersionRange" + ) +SELECT "abandoned", + "aliases", + "category", + "cdxId", + "cisaDateAdded", + "cpe", + "createdAt", + "cwes", + "databaseReviewed", + "detectionTitle", + "exploitsJSON", + "findingId", + "fixAutomatable", + "fixVersion", + "knownExploitsJSON", + "knownRansomwareCampaignUse", + "malicious", + "memberEmail", + "modifiedAt", + "orgId", + "packageEcosystem", + "sourceCodeUrl" as "advisoryUrl", + "packageLicense", + "packageName", + "packageVersion", + "product", + "publishedAt", + "purl", + "referencesJSON", + "repoName", + "source", + "spdxId", + "squattedPackage", + "timelineJSON", + "uuid", + "vendor", + "vulnerableVersionRange" +FROM "Finding"; +DROP TABLE "Finding"; +ALTER TABLE "new_Finding" + RENAME TO "Finding"; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index f5242ba..0000000 --- a/package-lock.json +++ /dev/null @@ -1,9763 +0,0 @@ -{ - "name": "vulnetix", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "vulnetix", - "version": "0.1.0", - "hasInstallScript": true, - "dependencies": { - "@casl/ability": "^6.2.0", - "@casl/vue": "^2.2.0", - "@floating-ui/dom": "1.2.8", - "@pandatix/js-cvss": "^0.4.4", - "@prisma/adapter-d1": "^5.15.1", - "@prisma/client": "^5.20.0", - "@vuelidate/core": "^2.0.3", - "@vuelidate/validators": "^2.0.4", - "@vueuse/core": "^10.1.2", - "@vueuse/math": "^10.1.2", - "apexcharts-clevision": "^3.28.5", - "axios": "^1.3.1", - "chart.js": "^4.1.2", - "crypto-es": "^2.1.0", - "eslint-import-resolver-alias": "^1.1.2", - "jwt-decode": "^3.1.2", - "pinia": "^2.1.3", - "prismjs": "^1.29.0", - "roboto-fontface": "^0.10.0", - "sass": "^1.59.3", - "semver": "^7.6.3", - "ssvc": "^0.1.1", - "unplugin-vue-define-options": "^1.3.5", - "vue": "^3.3.4", - "vue-chartjs": "^5.2.0", - "vue-flatpickr-component": "11.0.3", - "vue-i18n": "^9.2.2", - "vue-prism-component": "^2.0.0", - "vue-router": "^4.2.1", - "vue3-apexcharts": "^1.4.1", - "vue3-perfect-scrollbar": "^1.6.1", - "vuetify": "^3.6.0", - "webfontloader": "^1.6.28" - }, - "devDependencies": { - "@antfu/eslint-config-vue": "^0.3.3", - "@fullcalendar/core": "^6.1.8", - "@fullcalendar/daygrid": "^6.1.8", - "@fullcalendar/interaction": "^6.1.8", - "@fullcalendar/list": "^6.1.8", - "@fullcalendar/timegrid": "^6.1.8", - "@fullcalendar/vue3": "^6.1.8", - "@iconify-json/bx": "^1.1.6", - "@iconify-json/bxl": "^1.1.6", - "@iconify-json/bxs": "^1.1.6", - "@iconify-json/mdi": "^1.1.52", - "@iconify/tools": "^2.2.0", - "@iconify/utils": "^2.1.5", - "@iconify/vue": "4.1.1", - "@intlify/unplugin-vue-i18n": "^0.10.0", - "@vitejs/plugin-vue": "^4.2.3", - "@vitejs/plugin-vue-jsx": "^3.0.0", - "better-npm-audit": "^3.8.3", - "boxicons": "^2.1.4", - "eslint": "^8.41.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-promise": "^6.0.1", - "eslint-plugin-regex": "^1.10.0", - "eslint-plugin-sonarjs": "^0.19.0", - "eslint-plugin-unicorn": "^47.0.0", - "eslint-plugin-vue": "^9.13.0", - "postcss-html": "^1.5.0", - "prisma": "^5.20.0", - "stylelint": "14.15.0", - "stylelint-config-idiomatic-order": "^10.0.0", - "stylelint-config-standard-scss": "6.1.0", - "stylelint-use-logical-spec": "4.1.0", - "unplugin-auto-import": "^0.16.1", - "unplugin-vue-components": "^0.24.1", - "vite": "^4.3.8", - "vite-plugin-pages": "^0.30.1", - "vite-plugin-vue-layouts": "^0.8.0", - "vite-plugin-vuetify": "1.0.2", - "vue-shepherd": "^3.0.0", - "wrangler": "^3.60.2" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@antfu/eslint-config-basic": { - "version": "0.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-config-standard": "^14.1.1", - "eslint-plugin-html": "^6.1.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^4.0.1", - "eslint-plugin-unicorn": "^23.0.0" - }, - "peerDependencies": { - "eslint": ">=7.4.0" - } - }, - "node_modules/@antfu/eslint-config-basic/node_modules/ci-info": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@antfu/eslint-config-basic/node_modules/eslint-config-standard": { - "version": "14.1.1", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=6.2.2", - "eslint-plugin-import": ">=2.18.0", - "eslint-plugin-node": ">=9.1.0", - "eslint-plugin-promise": ">=4.2.1", - "eslint-plugin-standard": ">=4.0.0" - } - }, - "node_modules/@antfu/eslint-config-basic/node_modules/eslint-plugin-promise": { - "version": "4.3.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=6" - } - }, - "node_modules/@antfu/eslint-config-basic/node_modules/eslint-plugin-unicorn": { - "version": "23.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^2.0.0", - "clean-regexp": "^1.0.0", - "eslint-ast-utils": "^1.1.0", - "eslint-template-visitor": "^2.2.1", - "eslint-utils": "^2.1.0", - "import-modules": "^2.0.0", - "lodash": "^4.17.20", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.21", - "reserved-words": "^0.1.2", - "safe-regex": "^2.1.1", - "semver": "^7.3.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=7.11.0" - } - }, - "node_modules/@antfu/eslint-config-ts": { - "version": "0.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@antfu/eslint-config-basic": "^0.3.4", - "@typescript-eslint/eslint-plugin": "^4.5.0", - "@typescript-eslint/parser": "^4.5.0" - }, - "peerDependencies": { - "eslint": ">=7.4.0", - "typescript": ">=3.9" - } - }, - "node_modules/@antfu/eslint-config-vue": { - "version": "0.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@antfu/eslint-config-ts": "^0.3.4", - "eslint-plugin-vue": "7.1.0" - }, - "peerDependencies": { - "eslint": ">=7.4.0" - } - }, - "node_modules/@antfu/eslint-config-vue/node_modules/acorn": { - "version": "7.4.1", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@antfu/eslint-config-vue/node_modules/eslint-plugin-vue": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-utils": "^2.1.0", - "natural-compare": "^1.4.0", - "semver": "^7.3.2", - "vue-eslint-parser": "^7.1.1" - }, - "engines": { - "node": ">=8.10" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0" - } - }, - "node_modules/@antfu/eslint-config-vue/node_modules/espree": { - "version": "6.2.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@antfu/eslint-config-vue/node_modules/vue-eslint-parser": { - "version": "7.11.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.2.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8.10" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/@antfu/eslint-config-vue/node_modules/vue-eslint-parser/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@antfu/install-pkg": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "package-manager-detector": "^0.1.1", - "tinyexec": "^0.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@antfu/utils": { - "version": "0.7.10", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.25.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.25.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/eslint-parser": { - "version": "7.25.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/eslint-parser/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.4", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/jsesc": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.4", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.25.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.4", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.25.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.4", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.4", - "@babel/parser": "^7.25.4", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.4", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.25.4", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@casl/ability": { - "version": "6.7.1", - "license": "MIT", - "dependencies": { - "@ucast/mongo2js": "^1.3.0" - }, - "funding": { - "url": "https://github.com/stalniy/casl/blob/master/BACKERS.md" - } - }, - "node_modules/@casl/vue": { - "version": "2.2.2", - "license": "MIT", - "peerDependencies": { - "@casl/ability": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.1.0 || ^6.0.0", - "vue": "^3.0.0" - } - }, - "node_modules/@cloudflare/kv-asset-handler": { - "version": "0.3.4", - "dev": true, - "license": "MIT OR Apache-2.0", - "dependencies": { - "mime": "^3.0.0" - }, - "engines": { - "node": ">=16.13" - } - }, - "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20240821.1", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workers-shared": { - "version": "0.3.0", - "dev": true, - "license": "MIT OR Apache-2.0", - "engines": { - "node": ">=16.7.0" - } - }, - "node_modules/@cloudflare/workers-types": { - "version": "4.20240821.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240821.1.tgz", - "integrity": "sha512-icAkbnAqgVl6ef9lgLTom8na+kj2RBw2ViPAQ586hbdj0xZcnrjK7P46Eu08OU9D/lNDgN2sKU/sxhe2iK/gIg==", - "dev": true, - "license": "MIT OR Apache-2.0", - "optional": true, - "peer": true - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "2.2.0", - "dev": true, - "license": "CC0-1.0", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.10" - } - }, - "node_modules/@esbuild-plugins/node-globals-polyfill": { - "version": "0.2.3", - "dev": true, - "license": "ISC", - "peerDependencies": { - "esbuild": "*" - } - }, - "node_modules/@esbuild-plugins/node-modules-polyfill": { - "version": "0.2.2", - "dev": true, - "license": "ISC", - "dependencies": { - "escape-string-regexp": "^4.0.0", - "rollup-plugin-node-polyfills": "^0.2.1" - }, - "peerDependencies": { - "esbuild": "*" - } - }, - "node_modules/@esbuild-plugins/node-modules-polyfill/node_modules/escape-string-regexp": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.7", - "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.7" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.2.8", - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.2.6" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.7", - "license": "MIT" - }, - "node_modules/@fullcalendar/core": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "dependencies": { - "preact": "~10.12.1" - } - }, - "node_modules/@fullcalendar/daygrid": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@fullcalendar/core": "~6.1.15" - } - }, - "node_modules/@fullcalendar/interaction": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@fullcalendar/core": "~6.1.15" - } - }, - "node_modules/@fullcalendar/list": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@fullcalendar/core": "~6.1.15" - } - }, - "node_modules/@fullcalendar/timegrid": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@fullcalendar/daygrid": "~6.1.15" - }, - "peerDependencies": { - "@fullcalendar/core": "~6.1.15" - } - }, - "node_modules/@fullcalendar/vue3": { - "version": "6.1.15", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@fullcalendar/core": "~6.1.15", - "vue": "^3.0.11" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "license": "BSD-3-Clause" - }, - "node_modules/@iconify-json/bx": { - "version": "1.1.11", - "dev": true, - "license": "CC-BY-4.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify-json/bxl": { - "version": "1.1.11", - "dev": true, - "license": "CC-BY-4.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify-json/bxs": { - "version": "1.1.11", - "dev": true, - "license": "CC-BY-4.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify-json/mdi": { - "version": "1.1.68", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify/tools": { - "version": "2.2.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@iconify/types": "^2.0.0", - "@iconify/utils": "^2.1.4", - "@types/cheerio": "^0.22.31", - "@types/node-fetch": "^2.6.2", - "@types/tar": "^6.1.4", - "cheerio": "^1.0.0-rc.12", - "extract-zip": "^2.0.1", - "local-pkg": "^0.4.3", - "node-fetch": "^2.6.9", - "pathe": "^1.1.0", - "svgo": "^3.0.2", - "tar": "^6.1.13" - } - }, - "node_modules/@iconify/tools/node_modules/local-pkg": { - "version": "0.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@iconify/utils": { - "version": "2.1.31", - "dev": true, - "license": "MIT", - "dependencies": { - "@antfu/install-pkg": "^0.4.0", - "@antfu/utils": "^0.7.10", - "@iconify/types": "^2.0.0", - "debug": "^4.3.6", - "kolorist": "^1.8.0", - "local-pkg": "^0.5.0", - "mlly": "^1.7.1" - } - }, - "node_modules/@iconify/vue": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@iconify/types": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/cyberalien" - }, - "peerDependencies": { - "vue": ">=3" - } - }, - "node_modules/@intlify/bundle-utils": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@intlify/message-compiler": "9.3.0-beta.17", - "@intlify/shared": "9.3.0-beta.17", - "acorn": "^8.8.2", - "escodegen": "^2.0.0", - "estree-walker": "^2.0.2", - "jsonc-eslint-parser": "^1.0.1", - "magic-string": "^0.30.0", - "source-map": "0.6.1", - "yaml-eslint-parser": "^0.3.2" - }, - "engines": { - "node": ">= 12" - }, - "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - } - } - }, - "node_modules/@intlify/bundle-utils/node_modules/@intlify/message-compiler": { - "version": "9.3.0-beta.17", - "dev": true, - "license": "MIT", - "dependencies": { - "@intlify/shared": "9.3.0-beta.17", - "source-map": "0.6.1" - }, - "engines": { - "node": ">= 14" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/bundle-utils/node_modules/@intlify/shared": { - "version": "9.3.0-beta.17", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/core-base": { - "version": "9.14.0", - "license": "MIT", - "dependencies": { - "@intlify/message-compiler": "9.14.0", - "@intlify/shared": "9.14.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/message-compiler": { - "version": "9.14.0", - "license": "MIT", - "dependencies": { - "@intlify/shared": "9.14.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/shared": { - "version": "9.14.0", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@intlify/unplugin-vue-i18n": { - "version": "0.10.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@intlify/bundle-utils": "^5.4.0", - "@intlify/shared": "9.3.0-beta.17", - "@rollup/pluginutils": "^5.0.2", - "@vue/compiler-sfc": "^3.2.47", - "debug": "^4.3.3", - "fast-glob": "^3.2.12", - "js-yaml": "^4.1.0", - "json5": "^2.2.3", - "pathe": "^1.0.0", - "picocolors": "^1.0.0", - "source-map": "0.6.1", - "unplugin": "^1.1.0" - }, - "engines": { - "node": ">= 14.16" - }, - "peerDependencies": { - "petite-vue-i18n": "*", - "vue-i18n": "*", - "vue-i18n-bridge": "*" - }, - "peerDependenciesMeta": { - "petite-vue-i18n": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "vue-i18n-bridge": { - "optional": true - } - } - }, - "node_modules/@intlify/unplugin-vue-i18n/node_modules/@intlify/shared": { - "version": "9.3.0-beta.17", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@kurkle/color": { - "version": "0.3.2", - "license": "MIT" - }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-scope": "5.1.1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pandatix/js-cvss": { - "version": "0.4.4", - "license": "MIT" - }, - "node_modules/@prisma/adapter-d1": { - "version": "5.18.0", - "license": "Apache-2.0", - "dependencies": { - "@cloudflare/workers-types": "4.20240614.0", - "@prisma/driver-adapter-utils": "5.18.0" - } - }, - "node_modules/@prisma/adapter-d1/node_modules/@cloudflare/workers-types": { - "version": "4.20240614.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240614.0.tgz", - "integrity": "sha512-fnV3uXD1Hpq5EWnY7XYb+smPcjzIoUFiZpTSV/Tk8qKL3H+w6IqcngZwXQBZ/2U/DwYkDilXHW3FfPhnyD7FZA==", - "license": "MIT OR Apache-2.0" - }, - "node_modules/@prisma/client": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.20.0.tgz", - "integrity": "sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.13" - }, - "peerDependencies": { - "prisma": "*" - }, - "peerDependenciesMeta": { - "prisma": { - "optional": true - } - } - }, - "node_modules/@prisma/debug": { - "version": "5.18.0", - "license": "Apache-2.0" - }, - "node_modules/@prisma/driver-adapter-utils": { - "version": "5.18.0", - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.18.0" - } - }, - "node_modules/@prisma/engines": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.20.0.tgz", - "integrity": "sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==", - "devOptional": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.20.0", - "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "@prisma/fetch-engine": "5.20.0", - "@prisma/get-platform": "5.20.0" - } - }, - "node_modules/@prisma/engines-version": { - "version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz", - "integrity": "sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==", - "devOptional": true, - "license": "Apache-2.0" - }, - "node_modules/@prisma/engines/node_modules/@prisma/debug": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz", - "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==", - "devOptional": true, - "license": "Apache-2.0" - }, - "node_modules/@prisma/fetch-engine": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz", - "integrity": "sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.20.0", - "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "@prisma/get-platform": "5.20.0" - } - }, - "node_modules/@prisma/fetch-engine/node_modules/@prisma/debug": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz", - "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==", - "devOptional": true, - "license": "Apache-2.0" - }, - "node_modules/@prisma/get-platform": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz", - "integrity": "sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/debug": "5.20.0" - } - }, - "node_modules/@prisma/get-platform/node_modules/@prisma/debug": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz", - "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==", - "devOptional": true, - "license": "Apache-2.0" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/cheerio": { - "version": "0.22.35", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.5.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tar": { - "version": "6.1.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "minipass": "^4.0.0" - } - }, - "node_modules/@types/tar/node_modules/minipass": { - "version": "4.2.8", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.20", - "license": "MIT" - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, - "node_modules/@ucast/core": { - "version": "1.10.2", - "license": "Apache-2.0" - }, - "node_modules/@ucast/js": { - "version": "3.0.4", - "license": "Apache-2.0", - "dependencies": { - "@ucast/core": "^1.0.0" - } - }, - "node_modules/@ucast/mongo": { - "version": "2.4.3", - "license": "Apache-2.0", - "dependencies": { - "@ucast/core": "^1.4.1" - } - }, - "node_modules/@ucast/mongo2js": { - "version": "1.3.4", - "license": "Apache-2.0", - "dependencies": { - "@ucast/core": "^1.6.1", - "@ucast/js": "^3.0.0", - "@ucast/mongo": "^2.4.0" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "license": "ISC" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "4.6.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.0.0 || ^5.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vitejs/plugin-vue-jsx": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3", - "@vue/babel-plugin-jsx": "^1.1.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.0.0 || ^5.0.0", - "vue": "^3.0.0" - } - }, - "node_modules/@vue-macros/common": { - "version": "1.12.2", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.0", - "@rollup/pluginutils": "^5.1.0", - "@vue/compiler-sfc": "^3.4.34", - "ast-kit": "^1.0.1", - "local-pkg": "^0.5.0", - "magic-string-ast": "^0.6.2" - }, - "engines": { - "node": ">=16.14.0" - }, - "peerDependencies": { - "vue": "^2.7.0 || ^3.2.25" - }, - "peerDependenciesMeta": { - "vue": { - "optional": true - } - } - }, - "node_modules/@vue/babel-helper-vue-transform-on": { - "version": "1.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@vue/babel-plugin-jsx": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "~7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "@vue/babel-helper-vue-transform-on": "1.2.2", - "@vue/babel-plugin-resolve-type": "1.2.2", - "camelcase": "^6.3.0", - "html-tags": "^3.3.1", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - } - } - }, - "node_modules/@vue/babel-plugin-jsx/node_modules/camelcase": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vue/babel-plugin-resolve-type": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/helper-module-imports": "~7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/parser": "^7.23.9", - "@vue/compiler-sfc": "^3.4.15" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.38", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.4.38", - "@vue/shared": "3.4.38" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.38", - "@vue/compiler-dom": "3.4.38", - "@vue/compiler-ssr": "3.4.38", - "@vue/shared": "3.4.38", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.10", - "postcss": "^8.4.40", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.4.38", - "@vue/shared": "3.4.38" - } - }, - "node_modules/@vue/devtools-api": { - "version": "6.6.3", - "license": "MIT" - }, - "node_modules/@vue/reactivity": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.4.38" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.4.38", - "@vue/shared": "3.4.38" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.4.38", - "@vue/runtime-core": "3.4.38", - "@vue/shared": "3.4.38", - "csstype": "^3.1.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.4.38", - "@vue/shared": "3.4.38" - }, - "peerDependencies": { - "vue": "3.4.38" - } - }, - "node_modules/@vue/shared": { - "version": "3.4.38", - "license": "MIT" - }, - "node_modules/@vuelidate/core": { - "version": "2.0.3", - "license": "MIT", - "dependencies": { - "vue-demi": "^0.13.11" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^2.0.0 || >=3.0.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vuelidate/core/node_modules/vue-demi": { - "version": "0.13.11", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vuelidate/validators": { - "version": "2.0.4", - "license": "MIT", - "dependencies": { - "vue-demi": "^0.13.11" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^2.0.0 || >=3.0.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vuelidate/validators/node_modules/vue-demi": { - "version": "0.13.11", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vuetify/loader-shared": { - "version": "1.7.1", - "devOptional": true, - "license": "MIT", - "dependencies": { - "find-cache-dir": "^3.3.2", - "upath": "^2.0.1" - }, - "peerDependencies": { - "vue": "^3.0.0", - "vuetify": "^3.0.0-beta.4" - } - }, - "node_modules/@vueuse/core": { - "version": "10.11.1", - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.11.1", - "@vueuse/shared": "10.11.1", - "vue-demi": ">=0.14.8" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/math": { - "version": "10.11.1", - "license": "MIT", - "dependencies": { - "@vueuse/shared": "10.11.1", - "vue-demi": ">=0.14.8" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/metadata": { - "version": "10.11.1", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "10.11.1", - "license": "MIT", - "dependencies": { - "vue-demi": ">=0.14.8" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@webcomponents/webcomponentsjs": { - "version": "2.8.0", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@yr/monotone-cubic-spline": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", - "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==", - "license": "MIT", - "peer": true - }, - "node_modules/acorn": { - "version": "8.12.1", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/apexcharts": { - "version": "3.52.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.52.0.tgz", - "integrity": "sha512-7dg0ADKs8AA89iYMZMe2sFDG0XK5PfqllKV9N+i3hKHm3vEtdhwz8AlXGm+/b0nJ6jKiaXsqci5LfVxNhtB+dA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@yr/monotone-cubic-spline": "^1.0.3", - "svg.draggable.js": "^2.2.2", - "svg.easing.js": "^2.0.0", - "svg.filter.js": "^2.0.2", - "svg.pathmorphing.js": "^0.1.3", - "svg.resize.js": "^1.4.3", - "svg.select.js": "^3.0.1" - } - }, - "node_modules/apexcharts-clevision": { - "version": "3.28.5", - "license": "MIT", - "dependencies": { - "svg.draggable.js": "^2.2.2", - "svg.easing.js": "^2.0.0", - "svg.filter.js": "^2.0.2", - "svg.pathmorphing.js": "^0.1.3", - "svg.resize.js": "^1.4.3", - "svg.select.js": "^3.0.1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/as-table": { - "version": "1.0.55", - "dev": true, - "license": "MIT", - "dependencies": { - "printable-characters": "^1.0.42" - } - }, - "node_modules/ast-kit": { - "version": "1.1.0", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.3", - "pathe": "^1.1.2" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/ast-walker-scope": { - "version": "0.6.2", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.3", - "ast-kit": "^1.0.1" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.7.4", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "license": "MIT" - }, - "node_modules/better-npm-audit": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/better-npm-audit/-/better-npm-audit-3.8.3.tgz", - "integrity": "sha512-DY1VwwxUF/Bc5Rgh1kP0S8Jg63YyBICG+6/KGYjo9cqZ50jzF+bMSqez3yQ6Bvvf4vd9TRs/nw/GT/ZZEaLbvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^8.0.0", - "dayjs": "^1.10.6", - "lodash.get": "^4.4.2", - "semver": "^7.6.3", - "table": "^6.7.1" - }, - "bin": { - "better-npm-audit": "index.js" - }, - "engines": { - "node": ">= 8.12" - } - }, - "node_modules/better-npm-audit/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/blake3-wasm": { - "version": "2.1.5", - "dev": true, - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "license": "ISC" - }, - "node_modules/boxicons": { - "version": "2.1.4", - "dev": true, - "license": "(CC-BY-4.0 OR OFL-1.1 OR MIT)", - "dependencies": { - "@webcomponents/webcomponentsjs": "^2.0.2", - "prop-types": "^15.6.0", - "react": "^16.0.0", - "react-dom": "^16.0.0", - "react-interactive": "^0.8.1", - "react-router-dom": "^4.2.2" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys/node_modules/map-obj": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/capnp-ts": { - "version": "0.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.1", - "tslib": "^2.2.0" - } - }, - "node_modules/chart.js": { - "version": "4.4.4", - "license": "MIT", - "dependencies": { - "@kurkle/color": "^0.3.0" - }, - "engines": { - "pnpm": ">=8" - } - }, - "node_modules/cheerio": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=18.17" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cheerio/node_modules/htmlparser2": { - "version": "9.1.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/cheerio/node_modules/undici": { - "version": "6.19.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "7.2.0", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "devOptional": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.1.7", - "license": "MIT" - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cosmiconfig/node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-es": { - "version": "2.1.0", - "license": "MIT" - }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-functions-list": { - "version": "3.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12 || >=16" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "license": "MIT", - "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "license": "MIT", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/csstype": { - "version": "3.1.3", - "license": "MIT" - }, - "node_modules/data-uri-to-buffer": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/date-fns": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/kossnocorp" - } - }, - "node_modules/dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.6", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-equal/node_modules/isarray": { - "version": "2.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-hover": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-it": { - "version": "3.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-hover": "^1.0.3", - "detect-passive-events": "^1.0.5", - "detect-pointer": "^1.0.3", - "detect-touch-events": "^2.0.2" - } - }, - "node_modules/detect-passive-events": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-pointer": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-touch-events": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.13", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/encoding-sniffer": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.17.19", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.19", - "@esbuild/android-arm64": "0.17.19", - "@esbuild/android-x64": "0.17.19", - "@esbuild/darwin-arm64": "0.17.19", - "@esbuild/darwin-x64": "0.17.19", - "@esbuild/freebsd-arm64": "0.17.19", - "@esbuild/freebsd-x64": "0.17.19", - "@esbuild/linux-arm": "0.17.19", - "@esbuild/linux-arm64": "0.17.19", - "@esbuild/linux-ia32": "0.17.19", - "@esbuild/linux-loong64": "0.17.19", - "@esbuild/linux-mips64el": "0.17.19", - "@esbuild/linux-ppc64": "0.17.19", - "@esbuild/linux-riscv64": "0.17.19", - "@esbuild/linux-s390x": "0.17.19", - "@esbuild/linux-x64": "0.17.19", - "@esbuild/netbsd-x64": "0.17.19", - "@esbuild/openbsd-x64": "0.17.19", - "@esbuild/sunos-x64": "0.17.19", - "@esbuild/win32-arm64": "0.17.19", - "@esbuild/win32-ia32": "0.17.19", - "@esbuild/win32-x64": "0.17.19" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.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.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-ast-utils": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.get": "^4.4.2", - "lodash.zip": "^4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-import-resolver-alias": { - "version": "1.1.2", - "license": "MIT", - "engines": { - "node": ">= 4" - }, - "peerDependencies": { - "eslint-plugin-import": ">=1.4.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-html": { - "version": "6.2.0", - "dev": true, - "license": "ISC", - "dependencies": { - "htmlparser2": "^7.1.2" - } - }, - "node_modules/eslint-plugin-html/node_modules/dom-serializer": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/eslint-plugin-html/node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/eslint-plugin-html/node_modules/domhandler": { - "version": "4.3.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/eslint-plugin-html/node_modules/domutils": { - "version": "2.8.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/eslint-plugin-html/node_modules/entities": { - "version": "3.0.1", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/eslint-plugin-html/node_modules/htmlparser2": { - "version": "7.2.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.1.3", - "license": "MIT" - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "6.6.0", - "dev": true, - "license": "ISC", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-regex": { - "version": "1.10.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=4.0.0" - } - }, - "node_modules/eslint-plugin-sonarjs": { - "version": "0.19.0", - "dev": true, - "license": "LGPL-3.0", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-standard": { - "version": "4.1.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-unicorn": { - "version": "47.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.19.1", - "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^3.8.0", - "clean-regexp": "^1.0.0", - "esquery": "^1.5.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "lodash": "^4.17.21", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.24", - "regjsparser": "^0.10.0", - "safe-regex": "^2.1.1", - "semver": "^7.3.8", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=8.38.0" - } - }, - "node_modules/eslint-plugin-vue": { - "version": "9.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "globals": "^13.24.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-template-visitor": { - "version": "2.3.2", - "dev": true, - "license": "GPL-3.0-or-later OR MIT", - "dependencies": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "eslint-visitor-keys": "^2.0.0", - "esquery": "^1.3.1", - "multimap": "^1.1.0" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-template-visitor/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/doctrine": { - "version": "3.0.0", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima-extract-comments": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "esprima": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exit-hook": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/extract-comments": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "esprima-extract-comments": "^1.1.0", - "parse-code-context": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "devOptional": true, - "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatpickr": { - "version": "4.6.13", - "license": "MIT" - }, - "node_modules/flatted": { - "version": "3.3.1", - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-source": { - "version": "2.0.12", - "dev": true, - "license": "Unlicense", - "dependencies": { - "data-uri-to-buffer": "^2.0.0", - "source-map": "^0.6.1" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/global-modules": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/globjoin": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/gopd": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "license": "MIT" - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/history": { - "version": "4.10.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "2.5.5", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "dev": true, - "license": "ISC" - }, - "node_modules/html-tags": { - "version": "3.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immutable": { - "version": "4.3.7", - "license": "MIT" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/import-modules": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob/node_modules/is-extglob": { - "version": "2.1.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-eslint-parser": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^7.4.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^1.3.0", - "espree": "^6.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/acorn": { - "version": "7.4.1", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/espree": { - "version": "6.2.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/jsonc-eslint-parser/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/jwt-decode": { - "version": "3.1.2", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/known-css-properties": { - "version": "0.26.0", - "dev": true, - "license": "MIT" - }, - "node_modules/kolorist": { - "version": "1.8.0", - "dev": true, - "license": "MIT" - }, - "node_modules/levn": { - "version": "0.4.1", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "node_modules/local-pkg": { - "version": "0.5.0", - "license": "MIT", - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "license": "MIT" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "license": "MIT" - }, - "node_modules/lodash.zip": { - "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lru-cache/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/magic-string": { - "version": "0.30.11", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/magic-string-ast": { - "version": "0.6.2", - "license": "MIT", - "dependencies": { - "magic-string": "^0.30.10" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/map-obj": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mathml-tag-names": { - "version": "2.1.3", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "license": "CC0-1.0" - }, - "node_modules/meow": { - "version": "9.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/hosted-git-info": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/miniflare": { - "version": "3.20240821.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "acorn": "^8.8.0", - "acorn-walk": "^8.2.0", - "capnp-ts": "^0.7.0", - "exit-hook": "^2.2.1", - "glob-to-regexp": "^0.4.1", - "stoppable": "^1.1.0", - "undici": "^5.28.4", - "workerd": "1.20240821.1", - "ws": "^8.17.1", - "youch": "^3.2.2", - "zod": "^3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=16.13" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mlly": { - "version": "1.7.1", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "license": "MIT" - }, - "node_modules/multimap": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/mustache": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "bin": { - "mustache": "bin/mustache" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch-native": { - "version": "1.6.4", - "dev": true, - "license": "MIT" - }, - "node_modules/node-forge": { - "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-manager-detector": { - "version": "0.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-code-context": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "6.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "license": "MIT" - }, - "node_modules/pend": { - "version": "1.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/perfect-scrollbar": { - "version": "1.5.5", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.0.1", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinia": { - "version": "2.2.2", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^6.6.3", - "vue-demi": "^0.14.10" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "@vue/composition-api": "^1.4.0", - "typescript": ">=4.4.4", - "vue": "^2.6.14 || ^3.3.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-types": { - "version": "1.2.0", - "license": "MIT", - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.1", - "pathe": "^1.1.2" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.41", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-html": { - "version": "1.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "htmlparser2": "^8.0.0", - "js-tokens": "^9.0.0", - "postcss": "^8.4.0", - "postcss-safe-parser": "^6.0.0" - }, - "engines": { - "node": "^12 || >=14" - } - }, - "node_modules/postcss-html/node_modules/js-tokens": { - "version": "9.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", - "license": "MIT", - "dependencies": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-import/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "license": "ISC" - }, - "node_modules/postcss-import/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "license": "MIT", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-import/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "license": "MIT" - }, - "node_modules/postcss-media-query-parser": { - "version": "0.2.3", - "dev": true, - "license": "MIT" - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "license": "MIT", - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "license": "MIT", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "license": "MIT", - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sorting": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", - "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "postcss": "^8.4.20" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-svgo/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/postcss-svgo/node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "license": "MIT", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/postcss-svgo/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/postcss-svgo/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/postcss-svgo/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "license": "MIT", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "license": "MIT" - }, - "node_modules/preact": { - "version": "10.12.1", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/printable-characters": { - "version": "1.0.42", - "dev": true, - "license": "Unlicense" - }, - "node_modules/prisma": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz", - "integrity": "sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig==", - "devOptional": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@prisma/engines": "5.20.0" - }, - "bin": { - "prisma": "build/index.js" - }, - "engines": { - "node": ">=16.13" - }, - "optionalDependencies": { - "fsevents": "2.3.3" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react": { - "version": "16.14.0", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "16.14.0", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - }, - "peerDependencies": { - "react": "^16.14.0" - } - }, - "node_modules/react-interactive": { - "version": "0.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-it": "^3.0.3", - "object-assign": "^4.1.1", - "prop-types": "^15.6.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "dev": true, - "license": "MIT" - }, - "node_modules/react-router": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "history": "^4.7.2", - "hoist-non-react-statics": "^2.5.0", - "invariant": "^2.2.4", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.1", - "warning": "^4.0.1" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-dom": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "history": "^4.7.2", - "invariant": "^2.2.4", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.1", - "react-router": "^4.3.1", - "warning": "^4.0.1" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router/node_modules/path-to-regexp": { - "version": "1.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "dev": true, - "license": "MIT" - }, - "node_modules/regexp-tree": { - "version": "0.1.27", - "dev": true, - "license": "MIT", - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regjsparser": { - "version": "0.10.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reserved-words": { - "version": "0.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roboto-fontface": { - "version": "0.10.0", - "license": "Apache-2.0" - }, - "node_modules/rollup": { - "version": "3.29.4", - "devOptional": true, - "license": "MIT", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-inject": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - } - }, - "node_modules/rollup-plugin-inject/node_modules/estree-walker": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, - "node_modules/rollup-plugin-inject/node_modules/magic-string": { - "version": "0.25.9", - "dev": true, - "license": "MIT", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/rollup-plugin-node-polyfills": { - "version": "0.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "license": "MIT" - }, - "node_modules/safe-regex": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "regexp-tree": "~0.1.1" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/sass": { - "version": "1.77.8", - "license": "MIT", - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/scheduler": { - "version": "0.19.1", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/scule": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shepherd.js": { - "version": "11.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.5.1", - "deepmerge": "^4.3.1" - }, - "engines": { - "node": "16.* || >= 18" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/RobbieTheWagner" - } - }, - "node_modules/shepherd.js/node_modules/@floating-ui/dom": { - "version": "1.6.10", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.7" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "dev": true, - "license": "MIT" - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/ssvc": { - "version": "0.1.1", - "license": "MIT", - "dependencies": { - "ts-enum-util": "^4.1.0", - "zod": "^3.23.8" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "license": "MIT" - }, - "node_modules/stacktracey": { - "version": "2.1.8", - "dev": true, - "license": "Unlicense", - "dependencies": { - "as-table": "^1.0.36", - "get-source": "^2.0.12" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/stoppable": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4", - "npm": ">=6" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/style-search": { - "version": "0.1.0", - "dev": true, - "license": "ISC" - }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/stylelint": { - "version": "14.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/selector-specificity": "^2.0.2", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^7.1.0", - "css-functions-list": "^3.1.0", - "debug": "^4.3.4", - "fast-glob": "^3.2.12", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^6.0.1", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.2.0", - "ignore": "^5.2.0", - "import-lazy": "^4.0.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.26.0", - "mathml-tag-names": "^2.1.3", - "meow": "^9.0.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.19", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.10", - "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", - "svg-tags": "^1.0.0", - "table": "^6.8.1", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" - }, - "bin": { - "stylelint": "bin/stylelint.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" - } - }, - "node_modules/stylelint-config-idiomatic-order": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-idiomatic-order/-/stylelint-config-idiomatic-order-10.0.0.tgz", - "integrity": "sha512-gJjT1nwhgnHS52+mRn+5Iw6keZIPRN4W+vbzct9Elb+tWOo61jC/CzXzAJHvvOYQZqUYItfs2aQ8fU5hnCvuGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "stylelint-order": "^6.0.2" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "stylelint": ">=11" - } - }, - "node_modules/stylelint-config-recommended": { - "version": "9.0.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "stylelint": "^14.10.0" - } - }, - "node_modules/stylelint-config-recommended-scss": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-scss": "^4.0.2", - "stylelint-config-recommended": "^9.0.0", - "stylelint-scss": "^4.0.0" - }, - "peerDependencies": { - "postcss": "^8.3.3", - "stylelint": "^14.10.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - } - } - }, - "node_modules/stylelint-config-recommended-scss/node_modules/postcss-scss": { - "version": "4.0.9", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-scss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.4.29" - } - }, - "node_modules/stylelint-config-standard": { - "version": "29.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "stylelint-config-recommended": "^9.0.0" - }, - "peerDependencies": { - "stylelint": "^14.14.0" - } - }, - "node_modules/stylelint-config-standard-scss": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "stylelint-config-recommended-scss": "^8.0.0", - "stylelint-config-standard": "^29.0.0" - }, - "peerDependencies": { - "postcss": "^8.3.3", - "stylelint": "^14.14.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - } - } - }, - "node_modules/stylelint-order": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.4.tgz", - "integrity": "sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss": "^8.4.32", - "postcss-sorting": "^8.0.2" - }, - "peerDependencies": { - "stylelint": "^14.0.0 || ^15.0.0 || ^16.0.1" - } - }, - "node_modules/stylelint-scss": { - "version": "4.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "stylelint": "^14.5.1 || ^15.0.0" - } - }, - "node_modules/stylelint-use-logical-spec": { - "version": "4.1.0", - "dev": true, - "license": "CC0-1.0", - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "stylelint": ">=13" - } - }, - "node_modules/stylelint/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/stylelint/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sugarss": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", - "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==", - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "dev": true - }, - "node_modules/svg.draggable.js": { - "version": "2.2.2", - "license": "MIT", - "dependencies": { - "svg.js": "^2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.easing.js": { - "version": "2.0.0", - "license": "MIT", - "dependencies": { - "svg.js": ">=2.3.x" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.filter.js": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "svg.js": "^2.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.js": { - "version": "2.7.1", - "license": "MIT" - }, - "node_modules/svg.pathmorphing.js": { - "version": "0.1.3", - "license": "MIT", - "dependencies": { - "svg.js": "^2.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.resize.js": { - "version": "1.4.3", - "license": "MIT", - "dependencies": { - "svg.js": "^2.6.5", - "svg.select.js": "^2.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.resize.js/node_modules/svg.select.js": { - "version": "2.1.2", - "license": "MIT", - "dependencies": { - "svg.js": "^2.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.select.js": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "svg.js": "^2.6.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svgo": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/css-tree": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/svgo/node_modules/mdn-data": { - "version": "2.0.30", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/table": { - "version": "6.8.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.17.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "license": "MIT" - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "dev": true, - "license": "MIT" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-enum-util": { - "version": "4.1.0", - "license": "MIT" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "dev": true, - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "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" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "devOptional": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.4", - "license": "MIT" - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici": { - "version": "5.28.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "devOptional": true, - "license": "MIT" - }, - "node_modules/unenv": { - "name": "unenv-nightly", - "version": "1.10.0-1717606461.a117952", - "dev": true, - "license": "MIT", - "dependencies": { - "consola": "^3.2.3", - "defu": "^6.1.4", - "mime": "^3.0.0", - "node-fetch-native": "^1.6.4", - "pathe": "^1.1.2", - "ufo": "^1.5.3" - } - }, - "node_modules/unimport": { - "version": "3.11.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.1.0", - "acorn": "^8.12.1", - "escape-string-regexp": "^5.0.0", - "estree-walker": "^3.0.3", - "fast-glob": "^3.3.2", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.11", - "mlly": "^1.7.1", - "pathe": "^1.1.2", - "pkg-types": "^1.1.3", - "scule": "^1.3.0", - "strip-literal": "^2.1.0", - "unplugin": "^1.12.2" - } - }, - "node_modules/unimport/node_modules/escape-string-regexp": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unimport/node_modules/estree-walker": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/unplugin": { - "version": "1.12.2", - "license": "MIT", - "dependencies": { - "acorn": "^8.12.1", - "chokidar": "^3.6.0", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/unplugin-auto-import": { - "version": "0.16.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@antfu/utils": "^0.7.6", - "@rollup/pluginutils": "^5.0.5", - "fast-glob": "^3.3.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "minimatch": "^9.0.3", - "unimport": "^3.4.0", - "unplugin": "^1.5.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@nuxt/kit": "^3.2.2", - "@vueuse/core": "*" - }, - "peerDependenciesMeta": { - "@nuxt/kit": { - "optional": true - }, - "@vueuse/core": { - "optional": true - } - } - }, - "node_modules/unplugin-auto-import/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/unplugin-vue-components": { - "version": "0.24.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@antfu/utils": "^0.7.2", - "@rollup/pluginutils": "^5.0.2", - "chokidar": "^3.5.3", - "debug": "^4.3.4", - "fast-glob": "^3.2.12", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.0", - "minimatch": "^7.4.2", - "resolve": "^1.22.1", - "unplugin": "^1.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@babel/parser": "^7.15.8", - "@nuxt/kit": "^3.2.2", - "vue": "2 || 3" - }, - "peerDependenciesMeta": { - "@babel/parser": { - "optional": true - }, - "@nuxt/kit": { - "optional": true - } - } - }, - "node_modules/unplugin-vue-components/node_modules/local-pkg": { - "version": "0.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/unplugin-vue-components/node_modules/minimatch": { - "version": "7.4.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/unplugin-vue-define-options": { - "version": "1.4.9", - "license": "MIT", - "dependencies": { - "@vue-macros/common": "1.12.2", - "ast-walker-scope": "^0.6.1", - "unplugin": "^1.12.0" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/upath": { - "version": "2.0.1", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "license": "MIT" - }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/vite": { - "version": "4.5.3", - "devOptional": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-plugin-pages": { - "version": "0.30.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/debug": "^4.1.7", - "debug": "^4.3.4", - "deep-equal": "^2.2.1", - "extract-comments": "^1.1.0", - "fast-glob": "^3.2.12", - "json5": "^2.2.3", - "local-pkg": "^0.4.3", - "picocolors": "^1.0.0", - "yaml": "^2.2.2" - }, - "peerDependencies": { - "@vue/compiler-sfc": "^2.7.0 || ^3.0.0", - "vite": "^2.0.0 || ^3.0.0-0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "@vue/compiler-sfc": { - "optional": true - } - } - }, - "node_modules/vite-plugin-pages/node_modules/local-pkg": { - "version": "0.4.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/vite-plugin-pages/node_modules/yaml": { - "version": "2.5.0", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/vite-plugin-vue-layouts": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-sfc": "^3.2.31", - "debug": "^4.3.3", - "fast-glob": "^3.2.11" - }, - "peerDependencies": { - "vite": "^2.5.0 || ^3.0.0-0 || ^4.0.0", - "vue": "^2.6.12 || ^3.2.4", - "vue-router": "^3.5.1 || ^4.0.11" - } - }, - "node_modules/vite-plugin-vuetify": { - "version": "1.0.2", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@vuetify/loader-shared": "^1.7.1", - "debug": "^4.3.3", - "upath": "^2.0.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "vite": "^2.7.0 || ^3.0.0 || ^4.0.0", - "vuetify": "^3.0.0-beta.4" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.18.20", - "devOptional": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/vue": { - "version": "3.4.38", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.4.38", - "@vue/compiler-sfc": "3.4.38", - "@vue/runtime-dom": "3.4.38", - "@vue/server-renderer": "3.4.38", - "@vue/shared": "3.4.38" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vue-chartjs": { - "version": "5.3.1", - "license": "MIT", - "peerDependencies": { - "chart.js": "^4.1.1", - "vue": "^3.0.0-0 || ^2.7.0" - } - }, - "node_modules/vue-demi": { - "version": "0.14.10", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/vue-eslint-parser": { - "version": "9.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-flatpickr-component": { - "version": "11.0.3", - "license": "MIT", - "dependencies": { - "flatpickr": "^4.6.13" - }, - "engines": { - "node": ">=14.13.0" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, - "node_modules/vue-i18n": { - "version": "9.14.0", - "license": "MIT", - "dependencies": { - "@intlify/core-base": "9.14.0", - "@intlify/shared": "9.14.0", - "@vue/devtools-api": "^6.5.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/kazupon" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/vue-prism-component": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/vue-router": { - "version": "4.4.3", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^6.6.3" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, - "node_modules/vue-shepherd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shepherd.js": "^11.1.0" - }, - "peerDependencies": { - "vue": ">=3.0.0" - } - }, - "node_modules/vue3-apexcharts": { - "version": "1.5.3", - "license": "MIT", - "peerDependencies": { - "apexcharts": "> 3.0.0", - "vue": "> 3.0.0" - } - }, - "node_modules/vue3-perfect-scrollbar": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/vue3-perfect-scrollbar/-/vue3-perfect-scrollbar-1.6.1.tgz", - "integrity": "sha512-r9wfxlFwVyHXMPKG0PnR7fDfJPQ20KEVzKQfSU5by2WKYz2PwV0bTfyfejmEyZXsXL0O8VtSWtgxfPuFR2AGOg==", - "license": "MIT", - "dependencies": { - "cssnano": "^5.1.14", - "perfect-scrollbar": "^1.5.5", - "postcss-import": "^12.0.0" - } - }, - "node_modules/vuetify": { - "version": "3.7.0", - "license": "MIT", - "engines": { - "node": "^12.20 || >=14.13" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/johnleider" - }, - "peerDependencies": { - "typescript": ">=4.7", - "vite-plugin-vuetify": ">=1.0.0", - "vue": "^3.3.0", - "vue-i18n": "^9.0.0", - "webpack-plugin-vuetify": ">=2.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "vite-plugin-vuetify": { - "optional": true - }, - "vue-i18n": { - "optional": true - }, - "webpack-plugin-vuetify": { - "optional": true - } - } - }, - "node_modules/warning": { - "version": "4.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/webfontloader": { - "version": "1.6.28", - "license": "Apache-2.0" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-virtual-modules": { - "version": "0.6.2", - "license": "MIT" - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "license": "MIT", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerd": { - "version": "1.20240821.1", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20240821.1", - "@cloudflare/workerd-darwin-arm64": "1.20240821.1", - "@cloudflare/workerd-linux-64": "1.20240821.1", - "@cloudflare/workerd-linux-arm64": "1.20240821.1", - "@cloudflare/workerd-windows-64": "1.20240821.1" - } - }, - "node_modules/wrangler": { - "version": "3.72.2", - "dev": true, - "license": "MIT OR Apache-2.0", - "dependencies": { - "@cloudflare/kv-asset-handler": "0.3.4", - "@cloudflare/workers-shared": "0.3.0", - "@esbuild-plugins/node-globals-polyfill": "^0.2.3", - "@esbuild-plugins/node-modules-polyfill": "^0.2.2", - "blake3-wasm": "^2.1.5", - "chokidar": "^3.5.3", - "date-fns": "^3.6.0", - "esbuild": "0.17.19", - "miniflare": "3.20240821.0", - "nanoid": "^3.3.3", - "path-to-regexp": "^6.2.0", - "resolve": "^1.22.8", - "resolve.exports": "^2.0.2", - "selfsigned": "^2.0.1", - "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@1.10.0-1717606461.a117952", - "workerd": "1.20240821.1", - "xxhash-wasm": "^1.0.1" - }, - "bin": { - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" - }, - "engines": { - "node": ">=16.17.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@cloudflare/workers-types": "^4.20240821.1" - }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ws": { - "version": "8.18.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12" - } - }, - "node_modules/xxhash-wasm": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "1.10.2", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yaml-eslint-parser": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^1.3.0", - "lodash": "^4.17.20", - "yaml": "^1.10.0" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/youch": { - "version": "3.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "cookie": "^0.5.0", - "mustache": "^4.2.0", - "stacktracey": "^2.1.8" - } - }, - "node_modules/zod": { - "version": "3.23.8", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/package.json b/package.json index cde1de2..f2a5842 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "vite build", "watch": "vite build --watch", "preview": "wrangler pages dev ./dist", - "lint": "eslint . -c .eslintrc.js --fix --ext .ts,.js,.vue,.tsx,.jsx --ignore-path .gitignore", + "lint": "eslint . -c .eslintrc.js --fix --ext .ts,.js,.vue,.tsx --ignore-path .gitignore", "build:icons": "node src/@iconify/build-icons.js", "postinstall": "npm run build:icons", "deploy": "npm run build && wrangler pages deploy ./dist", @@ -19,7 +19,7 @@ "@floating-ui/dom": "1.2.8", "@pandatix/js-cvss": "^0.4.4", "@prisma/adapter-d1": "^5.15.1", - "@prisma/client": "^5.20.0", + "@prisma/client": "^5.21.1", "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "@vueuse/core": "^10.1.2", @@ -44,8 +44,7 @@ "vue-prism-component": "^2.0.0", "vue-router": "^4.2.1", "vue3-apexcharts": "^1.4.1", - "vue3-perfect-scrollbar": "^1.6.1", - "vuetify": "^3.6.0", + "vuetify": "^3.7.2", "webfontloader": "^1.6.28" }, "devDependencies": { @@ -65,7 +64,6 @@ "@iconify/vue": "4.1.1", "@intlify/unplugin-vue-i18n": "^0.10.0", "@vitejs/plugin-vue": "^4.2.3", - "@vitejs/plugin-vue-jsx": "^3.0.0", "better-npm-audit": "^3.8.3", "boxicons": "^2.1.4", "eslint": "^8.41.0", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 3e20668..d169bde 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,5 +1,3 @@ -// learn more about it in the docs: https://pris.ly/d/prisma-schema - generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters", "omitApi"] @@ -10,10 +8,12 @@ datasource db { url = env("DATABASE_URL") } -model sessions { - kid String @unique +model Session { + kid String @id + orgId String + org Org @relation(fields: [orgId], references: [uuid]) memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) expiry Int issued Int secret String? @@ -21,63 +21,82 @@ model sessions { authn_ua String? } -model orgs { - uuid String @id @default(uuid()) - name String - members members[] +model Org { + uuid String @id @default(uuid()) + name String + members Member[] + sessions Session[] + git_repos GitRepo[] + integrations IntegrationConfig[] + integration_usage_log IntegrationUsageLog[] + findings Finding[] + sarif SARIFInfo[] + cdx CycloneDXInfo[] + spdx SPDXInfo[] +} + +model IntegrationConfig { + uuid String @id @default(uuid()) + orgId String + org Org @relation(fields: [orgId], references: [uuid]) + name String + label String? + created Int + suspend Int? @default(0) + configJSON String? } -model members { - uuid String @id @default(uuid()) - email String @unique - orgId String? - org orgs? @relation(fields: [orgId], references: [uuid]) +model Member { + uuid String @id @default(uuid()) + email String @unique + orgId String + org Org @relation(fields: [orgId], references: [uuid]) passwordHash String avatarUrl String? firstName String? lastName String? - alertNews Int @default(0) - alertOverdue Int @default(0) - alertFindings Int @default(0) - alertType Int @default(0) - sarif sarif[] - github_apps github_apps[] - repos git_repos[] - member_keys member_keys[] - sessions sessions[] - spdx spdx[] - integration_usage_log integration_usage_log[] - findings findings[] - triage_activity triage_activity[] - cdx cdx[] + alertNews Int @default(0) + alertOverdue Int @default(0) + alertFindings Int @default(0) + alertType Int @default(0) + sarif SARIFInfo[] + github_apps GitHubApp[] + repos GitRepo[] + member_keys MemberKey[] + sessions Session[] + spdx SPDXInfo[] + integration_usage_log IntegrationUsageLog[] + findings Finding[] + triage_activity Triage[] + cdx CycloneDXInfo[] } -model member_keys { - id Int @id @default(autoincrement()) +model MemberKey { + id Int @id @default(autoincrement()) memberEmail String keyLabel String? keyType String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) secret String - suspend Int @default(0) - githubPat github_pat? + suspend Int @default(0) + githubPat GitHubPAT? @@unique([memberEmail, secret]) } -model github_pat { - keyId Int @unique - memberKey member_keys @relation(fields: [keyId], references: [id]) +model GitHubPAT { + keyId Int @id + memberKey MemberKey @relation(fields: [keyId], references: [id]) login String expires Int created Int avatarUrl String? } -model github_apps { - installationId Int @unique +model GitHubApp { + installationId Int @id memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) accessToken String login String? created Int @@ -85,8 +104,10 @@ model github_apps { avatarUrl String? } -model git_repos { +model GitRepo { fullName String + orgId String + org Org @relation(fields: [orgId], references: [uuid]) ghid Int? source String createdAt Int @@ -95,29 +116,34 @@ model git_repos { defaultBranch String ownerId Int memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) licenseSpdxId String? licenseName String? - fork Int @default(0) - template Int @default(0) - archived Int @default(0) + fork Int @default(0) + template Int @default(0) + archived Int @default(0) visibility String avatarUrl String? - sarif sarif[] - spdx spdx[] - cdx cdx[] + sarif SARIFInfo[] + spdx SPDXInfo[] + cdx CycloneDXInfo[] + Finding Finding[] - @@id([fullName, memberEmail]) + @@id([fullName, orgId]) } -model sarif { - sarifId String @unique - reportId String @id +model SARIFInfo { + reportId String @id + sarifId String fullName String? - repo git_repos? @relation(fields: [fullName, memberEmail], references: [fullName, memberEmail]) + repo GitRepo? @relation(fields: [fullName, orgId], references: [fullName, orgId]) + orgId String + org Org @relation(fields: [orgId], references: [uuid]) source String memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) + artifactUuid String + artifact Artifact @relation(fields: [artifactUuid], references: [uuid]) commitSha String? ref String? createdAt Int @@ -127,13 +153,13 @@ model sarif { toolVersion String? analysisKey String? warning String? - results sarif_results[] + results SarifResults[] } -model sarif_results { - guid String @unique +model SarifResults { + guid String @id reportId String - sarif sarif @relation(fields: [reportId], references: [reportId]) + sarif SARIFInfo @relation(fields: [reportId], references: [reportId]) messageText String ruleId String locations String? @@ -147,13 +173,17 @@ model sarif_results { tags String? } -model cdx { - cdxId String @unique +model CycloneDXInfo { + cdxId String @id source String memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) + orgId String + org Org @relation(fields: [orgId], references: [uuid]) repoName String? - repo git_repos? @relation(fields: [repoName, memberEmail], references: [fullName, memberEmail]) + repo GitRepo? @relation(fields: [repoName, orgId], references: [fullName, orgId]) + artifactUuid String + artifact Artifact @relation(fields: [artifactUuid], references: [uuid]) cdxVersion String serialNumber String? name String? @@ -164,16 +194,20 @@ model cdx { componentsCount Int dependenciesCount Int - findings findings[] + findings Finding[] } -model spdx { - spdxId String @unique +model SPDXInfo { + spdxId String @id source String memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) + orgId String + org Org @relation(fields: [orgId], references: [uuid]) repoName String? - repo git_repos? @relation(fields: [repoName, memberEmail], references: [fullName, memberEmail]) + repo GitRepo? @relation(fields: [repoName, orgId], references: [fullName, orgId]) + artifactUuid String + artifact Artifact @relation(fields: [artifactUuid], references: [uuid]) spdxVersion String dataLicense String? name String? @@ -183,25 +217,31 @@ model spdx { documentDescribes String? packagesCount Int comment String? - findings findings[] + findings Finding[] } -model integration_usage_log { +model IntegrationUsageLog { id Int @id @default(autoincrement()) + orgId String + org Org @relation(fields: [orgId], references: [uuid]) memberEmail String source String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) request String response String? statusCode Int createdAt Int } -model findings { - id Int @id @default(autoincrement()) +model Finding { + uuid String @id @default(uuid()) findingId String + orgId String + org Org @relation(fields: [orgId], references: [uuid]) memberEmail String - member members @relation(fields: [memberEmail], references: [email]) + member Member @relation(fields: [memberEmail], references: [email]) + repoName String? + repo GitRepo? @relation(fields: [repoName, memberEmail], references: [fullName, orgId]) source String category String createdAt Int @@ -211,7 +251,6 @@ model findings { purl String? cpe String? databaseReviewed Int? - cve String? aliases String? cwes String? packageName String @@ -220,7 +259,7 @@ model findings { vendor String? product String? packageEcosystem String? - sourceCodeUrl String? + advisoryUrl String? exploitsJSON String? knownExploitsJSON String? cisaDateAdded Int? @@ -228,20 +267,24 @@ model findings { fixVersion String? fixAutomatable Int? vulnerableVersionRange String? - maliciousSource String? + malicious Int? abandoned Int? squattedPackage String? referencesJSON String? + timelineJSON String? spdxId String? - spdx spdx? @relation(fields: [spdxId], references: [spdxId]) + spdx SPDXInfo? @relation(fields: [spdxId], references: [spdxId]) cdxId String? - cdx cdx? @relation(fields: [cdxId], references: [cdxId]) - triage triage_activity? @relation(fields: [id], references: [findingKey]) + cdx CycloneDXInfo? @relation(fields: [cdxId], references: [cdxId]) + triage Triage[] } -model triage_activity { - findingKey Int @id - finding findings? +model Triage { + uuid String @id @default(uuid()) + artifactUuid String? + artifact Artifact? @relation(fields: [artifactUuid], references: [uuid]) + findingUuid String + finding Finding @relation(fields: [findingUuid], references: [uuid]) createdAt Int triagedAt Int? lastObserved Int @@ -259,13 +302,56 @@ model triage_activity { analysisDetail String? triageAutomated Int @default(0) memberEmail String? - member members? @relation(fields: [memberEmail], references: [email]) + member Member? @relation(fields: [memberEmail], references: [email]) +} + +model CVEMetadata { + cveId String @id + dataVersion String + state String + datePublished Int + dateUpdated Int? + dateReserved Int? + vectorString String? + title String + sourceAdvisoryRef String? + affectedVendor String? + affectedProduct String? + affectedVersionsJSON String? + cpesJSON String? + cnaOrgId String + cna CVENumberingAuthrity @relation(fields: [cnaOrgId], references: [orgId]) + fileLinkId Int + fileLink Link @relation(fields: [fileLinkId], references: [id]) + adp CVEADP[] +} + +model CVENumberingAuthrity { + orgId String @id + shortName String + cves CVEMetadata[] +} + +model CVEADP { + cve CVEMetadata @relation(fields: [cveId], references: [cveId]) + cveId String + adp AuthorizedDataPublisher @relation(fields: [adpId], references: [orgId]) + adpId String + + @@id([cveId, adpId]) +} + +model AuthorizedDataPublisher { + orgId String @id + shortName String + title String + cves CVEADP[] } // model Lifecycle { -// uuid String @id @default(uuid()) -// event String // list enum String -// date DateTime +// uuid String @id @default(uuid()) +// event String // list enum String +// date DateTime // Collection Collection? @relation(fields: [collectionUuid], references: [uuid]) // collectionUuid String? // Leaf Leaf? @relation(fields: [leafUuid], references: [uuid]) @@ -274,27 +360,31 @@ model triage_activity { // productUuid String? // } -// model Link { -// id Int @id @default(autoincrement()) -// uri String -// content String // list enum String -// Artifact Artifact? @relation(fields: [artifactUuid], references: [uuid]) -// artifactUuid String? -// } +model Link { + id Int @id @default(autoincrement()) + url String + contentType String // OCI PLAIN_JSON OCTET_STREAM PLAIN_XML + artifact Artifact? @relation(fields: [artifactUuid], references: [uuid]) + artifactUuid String? + cves CVEMetadata[] +} -// model Artifact { -// uuid String @id @default(uuid()) -// displayIdentifier String -// type String // list enum String -// version String -// date Int -// bomFormat String -// downloadLinks Link[] -// inventoryTypes String // list enum String -// identities Identity[] -// Collection Collection? @relation(fields: [collectionUuid], references: [uuid]) -// collectionUuid String? -// } +model Artifact { + uuid String @id @default(uuid()) + // displayIdentifier String + type String // BOM ATTESTATION VDR VEX OTHER + date Int + bomFormat String + downloadLinks Link[] + // inventoryTypes String // SOFTWARE HARDWARE CRYPTOGRAPHY SERVICE VULNERABILITY + // identities Identity[] + // Collection Collection? @relation(fields: [collectionUuid], references: [uuid]) + // collectionUuid String? + sarif SARIFInfo[] + cdx CycloneDXInfo[] + spdx SPDXInfo[] + vex Triage[] +} // model Identity { // id String @id @default(cuid()) diff --git a/public/cve-logo.png b/public/cve-logo.png new file mode 100644 index 0000000..b6e3e03 Binary files /dev/null and b/public/cve-logo.png differ diff --git a/src/@core/components/AppBarSearch.vue b/src/@core/components/AppBarSearch.vue index 18ac3ee..5242b89 100644 --- a/src/@core/components/AppBarSearch.vue +++ b/src/@core/components/AppBarSearch.vue @@ -1,385 +1,379 @@ diff --git a/src/@core/components/AppSelect.vue b/src/@core/components/AppSelect.vue new file mode 100644 index 0000000..ee817f8 --- /dev/null +++ b/src/@core/components/AppSelect.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/@core/scss/base/_index.scss b/src/@core/scss/base/_index.scss index 9eb8a9c..3ce156b 100644 --- a/src/@core/scss/base/_index.scss +++ b/src/@core/scss/base/_index.scss @@ -26,6 +26,9 @@ a { color: rgb(var(--v-theme-primary)); text-decoration: none; + &.text-base { + color: rgb(var(--v-theme-on-background)); + } } // Vuetify 3 don't provide margin bottom style like vuetify 2 diff --git a/src/@core/scss/base/_utilities.scss b/src/@core/scss/base/_utilities.scss index ae2a042..5de9046 100644 --- a/src/@core/scss/base/_utilities.scss +++ b/src/@core/scss/base/_utilities.scss @@ -1,32 +1,9 @@ @use "@configured-variables" as variables; @use "@layouts/styles/mixins" as layoutsMixins; -// 👉 Demo spacers // TODO: Use vuetify SCSS variable here $card-spacer-content: 16px; -.demo-space-x { - display: flex; - flex-wrap: wrap; - align-items: center; - margin-block-start: -$card-spacer-content; - - & > * { - margin-block-start: $card-spacer-content; - margin-inline-end: $card-spacer-content; - } -} - -.demo-space-y { - & > * { - margin-block-end: $card-spacer-content; - - &:last-child { - margin-block-end: 0; - } - } -} - // 👉 Card match height .match-height.v-row { .v-card { diff --git a/src/@layouts/components/VerticalNav.vue b/src/@layouts/components/VerticalNav.vue index dce588c..396e2ac 100644 --- a/src/@layouts/components/VerticalNav.vue +++ b/src/@layouts/components/VerticalNav.vue @@ -1,6 +1,5 @@ diff --git a/src/layouts/components/UserProfile.vue b/src/layouts/components/UserProfile.vue index 56f8724..381d76a 100644 --- a/src/layouts/components/UserProfile.vue +++ b/src/layouts/components/UserProfile.vue @@ -108,8 +108,7 @@ onMounted(() => Member.ensureSession().then(controller.refresh)) - - +