From 867921f486b955c9139ec183e80e376237522df9 Mon Sep 17 00:00:00 2001 From: josuemc Date: Fri, 4 Sep 2026 16:28:36 -0300 Subject: [PATCH 1/5] =?UTF-8?q?Feat:=20Cadastrar,=20Renomear=20e=20Remover?= =?UTF-8?q?=20tipos=20de=20vegeta=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vegetacao/BuscaVegetacaoController.ts | 41 ++++++++++ .../vegetacao/CadastraVegetacaoController.ts | 48 ++++++++++++ .../vegetacao/RemoveVegetacaoController.ts | 52 +++++++++++++ .../vegetacao/RenomeiaVegetacaoController.ts | 63 +++++++++++++++ src/application/vegetacao/index.ts | 41 +++++++++- .../vegetacao/BuscaVegetacaoPorIdUseCase.ts | 20 +++++ .../vegetacao/CadastraVegetacaoUseCase.ts | 20 +++++ .../vegetacao/RemoveVegetacaoUseCase.ts | 19 +++++ .../vegetacao/RenomeiaVegetacaoUseCase.ts | 20 +++++ src/domain/vegetacao/VegetacaoCollection.ts | 3 + .../VegetacaoCollectionKnexAdapter.ts | 77 +++++++++++++++++++ src/library/http/error/ConflictError.ts | 7 ++ .../vegetacao/busca-vegetacoes.test.ts | 50 ++++++++++++ .../vegetacao/cadastra-vegetacoes.test.ts | 57 ++++++++++++++ .../vegetacao/lista-vegetacoes.test.ts | 41 +--------- .../vegetacao/remove-vegetacoes.test.ts | 57 ++++++++++++++ .../vegetacao/renomeia-vegetacoes.test.ts | 46 +++++++++++ 17 files changed, 621 insertions(+), 41 deletions(-) create mode 100644 src/application/vegetacao/BuscaVegetacaoController.ts create mode 100644 src/application/vegetacao/CadastraVegetacaoController.ts create mode 100644 src/application/vegetacao/RemoveVegetacaoController.ts create mode 100644 src/application/vegetacao/RenomeiaVegetacaoController.ts create mode 100644 src/domain/vegetacao/BuscaVegetacaoPorIdUseCase.ts create mode 100644 src/domain/vegetacao/CadastraVegetacaoUseCase.ts create mode 100644 src/domain/vegetacao/RemoveVegetacaoUseCase.ts create mode 100644 src/domain/vegetacao/RenomeiaVegetacaoUseCase.ts create mode 100644 src/library/http/error/ConflictError.ts create mode 100644 test/integration/vegetacao/busca-vegetacoes.test.ts create mode 100644 test/integration/vegetacao/cadastra-vegetacoes.test.ts create mode 100644 test/integration/vegetacao/remove-vegetacoes.test.ts create mode 100644 test/integration/vegetacao/renomeia-vegetacoes.test.ts diff --git a/src/application/vegetacao/BuscaVegetacaoController.ts b/src/application/vegetacao/BuscaVegetacaoController.ts new file mode 100644 index 00000000..a59aca03 --- /dev/null +++ b/src/application/vegetacao/BuscaVegetacaoController.ts @@ -0,0 +1,41 @@ +import { BuscaVegetacaoPorIdUseCase } from '@/domain/vegetacao/BuscaVegetacaoPorIdUseCase' +import { + HttpRequest, HttpResponse, StatusCode +} from '@/library/http/common' +import { BadRequestError } from '@/library/http/error/BadRequestError' +import { HttpError } from '@/library/http/error/HttpError' +import { InternalServerError } from '@/library/http/error/InternalServerError' +import { NotFoundError } from '@/library/http/error/NotFoundError' +import { NextHandler, RequestHandler } from '@/library/http/Server' + +interface Dependencies { + buscaVegetacaoPorIdUseCase: BuscaVegetacaoPorIdUseCase +} + +export class BuscaVegetacaoController implements RequestHandler { + private readonly buscaVegetacaoPorIdUseCase: BuscaVegetacaoPorIdUseCase + + constructor(dependencies: Dependencies) { + this.buscaVegetacaoPorIdUseCase = dependencies.buscaVegetacaoPorIdUseCase + } + + async handle(request: HttpRequest, _next: NextHandler): Promise { + const { vegetacaoId } = request.params as { vegetacaoId?: string } + + if (vegetacaoId === undefined || vegetacaoId === null || vegetacaoId === '' || !/^\d+$/.test(vegetacaoId)) { + return new BadRequestError({ message: 'vegetacaoId inválido' }) + } + + const result = await this.buscaVegetacaoPorIdUseCase.execute({ id: Number(vegetacaoId) }) + + if (result.left()) { + return new InternalServerError({ message: result.value.message }) + } + + if (!result.value) { + return new NotFoundError({ message: 'Vegetação não encontrada' }) + } + + return { statusCode: StatusCode.Ok, body: result.value } + } +} diff --git a/src/application/vegetacao/CadastraVegetacaoController.ts b/src/application/vegetacao/CadastraVegetacaoController.ts new file mode 100644 index 00000000..86337edc --- /dev/null +++ b/src/application/vegetacao/CadastraVegetacaoController.ts @@ -0,0 +1,48 @@ +import { CadastraVegetacaoUseCase } from '@/domain/vegetacao/CadastraVegetacaoUseCase' +import { Vegetacao } from '@/domain/vegetacao/Vegetacao' +import { + HttpRequest, HttpResponse, StatusCode +} from '@/library/http/common' +import { BadRequestError } from '@/library/http/error/BadRequestError' +import { ConflictError } from '@/library/http/error/ConflictError' +import { HttpError } from '@/library/http/error/HttpError' +import { InternalServerError } from '@/library/http/error/InternalServerError' +import { NextHandler, RequestHandler } from '@/library/http/Server' + +interface Dependencies { + cadastraVegetacaoUseCase: CadastraVegetacaoUseCase +} + +export class CadastraVegetacaoController implements RequestHandler { + private readonly cadastraVegetacaoUseCase: CadastraVegetacaoUseCase + + constructor(dependencies: Dependencies) { + this.cadastraVegetacaoUseCase = dependencies.cadastraVegetacaoUseCase + } + + async handle(request: HttpRequest, _next: NextHandler): Promise { + const { nome } = request.body as { nome?: string } + + if (typeof nome !== 'string' || !nome.trim()) { + return new BadRequestError({ message: 'Nome da vegetação não pode ser vazio' }) + } + + const normalized = nome.trim() + const created = Vegetacao.create({ id: 0, nome: normalized }) + if (created.left()) { + return new BadRequestError({ message: created.value.message }) + } + + const result = await this.cadastraVegetacaoUseCase.execute({ nome: normalized }) + + if (result.left()) { + const message = result.value.message.toLowerCase() + if (message.includes('duplicate') || message.includes('unique') || message.includes('already') || message.includes('exist')) { + return new ConflictError({ message: 'Já existe uma vegetação com esse nome' }) + } + return new InternalServerError({ message: result.value.message }) + } + + return { statusCode: StatusCode.Created, body: result.value } + } +} diff --git a/src/application/vegetacao/RemoveVegetacaoController.ts b/src/application/vegetacao/RemoveVegetacaoController.ts new file mode 100644 index 00000000..ae02e9e2 --- /dev/null +++ b/src/application/vegetacao/RemoveVegetacaoController.ts @@ -0,0 +1,52 @@ +import { RemoveVegetacaoUseCase } from '@/domain/vegetacao/RemoveVegetacaoUseCase' +import { + HttpRequest, HttpResponse, StatusCode +} from '@/library/http/common' +import { BadRequestError } from '@/library/http/error/BadRequestError' +import { ConflictError } from '@/library/http/error/ConflictError' +import { HttpError } from '@/library/http/error/HttpError' +import { InternalServerError } from '@/library/http/error/InternalServerError' +import { NotFoundError } from '@/library/http/error/NotFoundError' +import { NextHandler, RequestHandler } from '@/library/http/Server' + +interface Dependencies { + removeVegetacaoUseCase: RemoveVegetacaoUseCase +} + +export class RemoveVegetacaoController implements RequestHandler { + private readonly removeVegetacaoUseCase: RemoveVegetacaoUseCase + + constructor(dependencies: Dependencies) { + this.removeVegetacaoUseCase = dependencies.removeVegetacaoUseCase + } + + async handle(request: HttpRequest, _next: NextHandler): Promise { + const { vegetacaoId } = request.params as { vegetacaoId?: string } + + if ( + vegetacaoId === undefined + || vegetacaoId === null + || vegetacaoId === '' + || Number.isNaN(Number(vegetacaoId)) + || Number(vegetacaoId) <= 0 + ) { + return new BadRequestError({ message: 'vegetacaoId inválido' }) + } + + const result = await this.removeVegetacaoUseCase.execute({ id: Number(vegetacaoId) }) + + if (result.left()) { + const message = result.value.message.toLowerCase() + if (message.includes('foreign') || message.includes('integrity') || message.includes('constraint') || message.includes('in use') || message.includes('referenc')) { + return new ConflictError({ message: 'Vegetação está em uso e não pode ser removida' }) + } + return new InternalServerError({ message: result.value.message }) + } + + if (!result.value) { + return new NotFoundError({ message: 'Vegetação não encontrada' }) + } + + return { statusCode: StatusCode.NoContent, body: undefined } + } +} diff --git a/src/application/vegetacao/RenomeiaVegetacaoController.ts b/src/application/vegetacao/RenomeiaVegetacaoController.ts new file mode 100644 index 00000000..3b642646 --- /dev/null +++ b/src/application/vegetacao/RenomeiaVegetacaoController.ts @@ -0,0 +1,63 @@ +import { RenomeiaVegetacaoUseCase } from '@/domain/vegetacao/RenomeiaVegetacaoUseCase' +import { Vegetacao } from '@/domain/vegetacao/Vegetacao' +import { + HttpRequest, HttpResponse, StatusCode +} from '@/library/http/common' +import { BadRequestError } from '@/library/http/error/BadRequestError' +import { HttpError } from '@/library/http/error/HttpError' +import { InternalServerError } from '@/library/http/error/InternalServerError' +import { NotFoundError } from '@/library/http/error/NotFoundError' +import { NextHandler, RequestHandler } from '@/library/http/Server' + +interface Dependencies { + renomeiaVegetacaoUseCase: RenomeiaVegetacaoUseCase +} + +export class RenomeiaVegetacaoController implements RequestHandler { + private readonly renomeiaVegetacaoUseCase: RenomeiaVegetacaoUseCase + + constructor(dependencies: Dependencies) { + this.renomeiaVegetacaoUseCase = dependencies.renomeiaVegetacaoUseCase + } + + async handle(request: HttpRequest, _next: NextHandler): Promise { + const { vegetacaoId } = request.params as { vegetacaoId?: string } + const { nome } = request.body as { nome?: string } + + if ( + vegetacaoId === undefined + || vegetacaoId === null + || vegetacaoId === '' + || Number.isNaN(Number(vegetacaoId)) + || Number(vegetacaoId) <= 0 + ) { + return new BadRequestError({ message: 'vegetacaoId inválido' }) + } + + if (typeof nome !== 'string' || !nome.trim()) { + return new BadRequestError({ message: 'Nome da vegetação não pode ser vazio' }) + } + + const parsedId = Number(vegetacaoId) + const created = Vegetacao.create({ id: parsedId, nome: nome.trim() }) + if (created.left()) { + return new BadRequestError({ message: created.value.message }) + } + + const result = await this.renomeiaVegetacaoUseCase.execute({ id: parsedId, nome: nome.trim() }) + + if (result.left()) { + const message = result.value.message.toLowerCase() + if (message.includes('duplicate') || message.includes('unique') || message.includes('already') || message.includes('exist')) { + return new BadRequestError({ message: 'Já existe uma vegetação com esse nome' }) + } + return new InternalServerError({ message: result.value.message }) + } + + if (!result.value) { + return new NotFoundError({ message: 'Vegetação não encontrada' }) + } + + return { statusCode: StatusCode.Ok, body: result.value } + } +} diff --git a/src/application/vegetacao/index.ts b/src/application/vegetacao/index.ts index e591fe33..d895337b 100644 --- a/src/application/vegetacao/index.ts +++ b/src/application/vegetacao/index.ts @@ -1,18 +1,33 @@ import { type Knex } from 'knex' -import { BuscarVegetacaoPorIdUseCase } from '@/domain/vegetacao/BuscarVegetacaoPorIdUseCase' +import { BuscaVegetacaoPorIdUseCase } from '@/domain/vegetacao/BuscaVegetacaoPorIdUseCase' +import { CadastraVegetacaoUseCase } from '@/domain/vegetacao/CadastraVegetacaoUseCase' import { ListaVegetacoesUseCase } from '@/domain/vegetacao/ListaVegetacoesUseCase' +import { RemoveVegetacaoUseCase } from '@/domain/vegetacao/RemoveVegetacaoUseCase' +import { RenomeiaVegetacaoUseCase } from '@/domain/vegetacao/RenomeiaVegetacaoUseCase' import { VegetacaoCollectionKnexAdapter } from '@/infrastructure/VegetacaoCollectionKnexAdapter' import { Method } from '@/library/http/common' import { Route } from '@/library/http/Router' -import { BuscarVegetacaoController } from './BuscarVegetacaoController' +import { BuscaVegetacaoController } from './BuscaVegetacaoController' +import { CadastraVegetacaoController } from './CadastraVegetacaoController' import { ListaVegetacoesController } from './ListaVegetacoesController' +import { RemoveVegetacaoController } from './RemoveVegetacaoController' +import { RenomeiaVegetacaoController } from './RenomeiaVegetacaoController' export function routes(knex: Knex): Route[] { const vegetacaoCollection = new VegetacaoCollectionKnexAdapter({ knex }) return [ + { + handlers: [ + new CadastraVegetacaoController({ + cadastraVegetacaoUseCase: new CadastraVegetacaoUseCase({ vegetacaoCollection }) + }) + ], + method: Method.Post, + path: '/v2/vegetacoes' + }, { handlers: [ new ListaVegetacoesController({ @@ -24,12 +39,30 @@ export function routes(knex: Knex): Route[] { }, { handlers: [ - new BuscarVegetacaoController({ - buscarVegetacaoPorIdUseCase: new BuscarVegetacaoPorIdUseCase({ vegetacaoCollection }) + new BuscaVegetacaoController({ + buscaVegetacaoPorIdUseCase: new BuscaVegetacaoPorIdUseCase({ vegetacaoCollection }) }) ], method: Method.Get, path: '/v2/vegetacoes/:vegetacaoId' + }, + { + handlers: [ + new RenomeiaVegetacaoController({ + renomeiaVegetacaoUseCase: new RenomeiaVegetacaoUseCase({ vegetacaoCollection }) + }) + ], + method: Method.Put, + path: '/v2/vegetacoes/:vegetacaoId' + }, + { + handlers: [ + new RemoveVegetacaoController({ + removeVegetacaoUseCase: new RemoveVegetacaoUseCase({ vegetacaoCollection }) + }) + ], + method: Method.Delete, + path: '/v2/vegetacoes/:vegetacaoId' } ] } diff --git a/src/domain/vegetacao/BuscaVegetacaoPorIdUseCase.ts b/src/domain/vegetacao/BuscaVegetacaoPorIdUseCase.ts new file mode 100644 index 00000000..65c95b75 --- /dev/null +++ b/src/domain/vegetacao/BuscaVegetacaoPorIdUseCase.ts @@ -0,0 +1,20 @@ +import { Either } from '@/library/either/Either' + +import { Attributes } from './Vegetacao' +import { VegetacaoCollection } from './VegetacaoCollection' + +interface Dependencies { + vegetacaoCollection: VegetacaoCollection +} + +export class BuscaVegetacaoPorIdUseCase { + private readonly vegetacaoCollection: VegetacaoCollection + + constructor(dependencies: Dependencies) { + this.vegetacaoCollection = dependencies.vegetacaoCollection + } + + execute({ id }: { id: number }): Promise> { + return this.vegetacaoCollection.findById(id) + } +} diff --git a/src/domain/vegetacao/CadastraVegetacaoUseCase.ts b/src/domain/vegetacao/CadastraVegetacaoUseCase.ts new file mode 100644 index 00000000..577dc56d --- /dev/null +++ b/src/domain/vegetacao/CadastraVegetacaoUseCase.ts @@ -0,0 +1,20 @@ +import { Either } from '@/library/either/Either' + +import { Attributes } from './Vegetacao' +import { VegetacaoCollection } from './VegetacaoCollection' + +interface Dependencies { + vegetacaoCollection: VegetacaoCollection +} + +export class CadastraVegetacaoUseCase { + private readonly vegetacaoCollection: VegetacaoCollection + + constructor(dependencies: Dependencies) { + this.vegetacaoCollection = dependencies.vegetacaoCollection + } + + execute({ nome }: { nome: string }): Promise> { + return this.vegetacaoCollection.create({ nome }) + } +} diff --git a/src/domain/vegetacao/RemoveVegetacaoUseCase.ts b/src/domain/vegetacao/RemoveVegetacaoUseCase.ts new file mode 100644 index 00000000..9577e2f9 --- /dev/null +++ b/src/domain/vegetacao/RemoveVegetacaoUseCase.ts @@ -0,0 +1,19 @@ +import { Either } from '@/library/either/Either' + +import { VegetacaoCollection } from './VegetacaoCollection' + +interface Dependencies { + vegetacaoCollection: VegetacaoCollection +} + +export class RemoveVegetacaoUseCase { + private readonly vegetacaoCollection: VegetacaoCollection + + constructor(dependencies: Dependencies) { + this.vegetacaoCollection = dependencies.vegetacaoCollection + } + + execute({ id }: { id: number }): Promise> { + return this.vegetacaoCollection.delete(id) + } +} diff --git a/src/domain/vegetacao/RenomeiaVegetacaoUseCase.ts b/src/domain/vegetacao/RenomeiaVegetacaoUseCase.ts new file mode 100644 index 00000000..6954cf9e --- /dev/null +++ b/src/domain/vegetacao/RenomeiaVegetacaoUseCase.ts @@ -0,0 +1,20 @@ +import { Either } from '@/library/either/Either' + +import { Attributes } from './Vegetacao' +import { VegetacaoCollection } from './VegetacaoCollection' + +interface Dependencies { + vegetacaoCollection: VegetacaoCollection +} + +export class RenomeiaVegetacaoUseCase { + private readonly vegetacaoCollection: VegetacaoCollection + + constructor(dependencies: Dependencies) { + this.vegetacaoCollection = dependencies.vegetacaoCollection + } + + execute({ id, nome }: { id: number; nome: string }): Promise> { + return this.vegetacaoCollection.update(id, { nome }) + } +} diff --git a/src/domain/vegetacao/VegetacaoCollection.ts b/src/domain/vegetacao/VegetacaoCollection.ts index 13ab350d..ccd1baa5 100644 --- a/src/domain/vegetacao/VegetacaoCollection.ts +++ b/src/domain/vegetacao/VegetacaoCollection.ts @@ -15,4 +15,7 @@ export interface VegetacaoFilters { export interface VegetacaoCollection { findAll(filters: VegetacaoFilters): Promise> findById(id: number): Promise> + create(data: Pick): Promise> + update(id: number, data: Pick): Promise> + delete(id: number): Promise> } diff --git a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts index 42de847d..7c8af272 100644 --- a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts +++ b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts @@ -17,6 +17,24 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { this.knex = dependencies.knex } + private async findByNome(nome: string, excludeId?: number): Promise> { + try { + const query = this.knex('vegetacoes') + .select(['id', 'nome']) + .whereRaw('LOWER(nome) = LOWER(?)', [nome]) + + if (excludeId !== undefined) { + query.andWhereNot({ id: excludeId }) + } + + const vegetacao = await query.first() + return Either.right(vegetacao ?? null) + } catch (error) { + const cause = error instanceof Error ? error : new Error(String(error)) + return Either.left(new CollectionError({ message: cause.message, cause })) + } + } + async findAll(filters: VegetacaoFilters): Promise> { try { const query = this.knex('vegetacoes') @@ -43,4 +61,63 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.left(new CollectionError({ message: 'Failed to find vegetação', cause: error })) } } + + async create(data: Pick): Promise> { + const nome = data.nome.trim() + + const existing = await this.findByNome(nome) + if (existing.left()) { + return Either.left(existing.value) + } + + if (existing.value) { + return Either.left(new CollectionError({ message: 'Já existe uma vegetação com esse nome' })) + } + + try { + const [vegetacao] = await this.knex('vegetacoes') + .insert({ nome }) + .returning(['id', 'nome']) as Attributes[] + + return Either.right(vegetacao) + } catch (error) { + const cause = error instanceof Error ? error : new Error(String(error)) + return Either.left(new CollectionError({ message: cause.message, cause })) + } + } + + async update(id: number, data: Pick): Promise> { + const nome = data.nome.trim() + + const existing = await this.findByNome(nome, id) + if (existing.left()) { + return Either.left(existing.value) + } + + if (existing.value) { + return Either.left(new CollectionError({ message: 'Já existe uma vegetação com esse nome' })) + } + + try { + const [vegetacao] = await this.knex('vegetacoes') + .where({ id }) + .update({ nome }) + .returning(['id', 'nome']) as Attributes[] + + return Either.right(vegetacao ?? null) + } catch (error) { + const cause = error instanceof Error ? error : new Error(String(error)) + return Either.left(new CollectionError({ message: cause.message, cause })) + } + } + + async delete(id: number): Promise> { + try { + const deleted = await this.knex('vegetacoes').where({ id }).delete() + return Either.right(deleted > 0) + } catch (error) { + const cause = error instanceof Error ? error : new Error(String(error)) + return Either.left(new CollectionError({ message: cause.message, cause })) + } + } } diff --git a/src/library/http/error/ConflictError.ts b/src/library/http/error/ConflictError.ts new file mode 100644 index 00000000..b8a99193 --- /dev/null +++ b/src/library/http/error/ConflictError.ts @@ -0,0 +1,7 @@ +import { HttpError } from './HttpError' + +export class ConflictError extends HttpError { + constructor(params: { message: string; report?: unknown; cause?: unknown }) { + super({ ...params, statusCode: 409 }) + } +} diff --git a/test/integration/vegetacao/busca-vegetacoes.test.ts b/test/integration/vegetacao/busca-vegetacoes.test.ts new file mode 100644 index 00000000..37a2cb67 --- /dev/null +++ b/test/integration/vegetacao/busca-vegetacoes.test.ts @@ -0,0 +1,50 @@ +import { + afterAll, describe, expect, test +} from 'vitest' + +import { createTestApp } from '../setup/app-factory' + +type Vegetacao = { id: number; nome: string } + +const returning = ['id', 'nome'] as const + +describe('GET /api/v2/vegetacoes/:vegetacaoId', () => { + const { agent, knex } = createTestApp() + + afterAll(() => knex.destroy()) + + test('retorna o registro encontrado', async () => { + const nome = `XVEG_BUSCA_${Date.now()}` + const [vegetacao] = await knex('vegetacoes') + .insert({ nome }) + .returning(returning) + + try { + const response = await agent.get(`/api/v2/vegetacoes/${vegetacao.id}`).expect(200) + expect(response.body).toEqual({ id: vegetacao.id, nome: vegetacao.nome }) + } finally { + await knex('vegetacoes').where({ id: vegetacao.id }).delete() + } + }) + + test('retorna 404 para id inexistente', async () => { + const response = await agent.get('/api/v2/vegetacoes/999999').expect(404) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/não encontrad[ao]|not found/i) + }) + + test('retorna 400 para id inválido', async () => { + const response = await agent.get('/api/v2/vegetacoes/abc').expect(400) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/inválido|invalid/i) + }) + + test('retorna 400 para id inválido', async () => { + const response = await agent.get('/api/v2/vegetacoes/-12').expect(400) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/inválido|invalid/i) + }) +}) diff --git a/test/integration/vegetacao/cadastra-vegetacoes.test.ts b/test/integration/vegetacao/cadastra-vegetacoes.test.ts new file mode 100644 index 00000000..f93fc304 --- /dev/null +++ b/test/integration/vegetacao/cadastra-vegetacoes.test.ts @@ -0,0 +1,57 @@ +import { + afterAll, + describe, + expect, + test +} from 'vitest' + +import { createTestApp } from '../setup/app-factory' + +type Vegetacao = { id: number; nome: string } + +describe('POST /api/v2/vegetacoes', () => { + const { agent, knex } = createTestApp() + + afterAll(() => knex.destroy()) + + test('cadastra uma vegetação com sucesso', async () => { + const prefix = `CADVEG-${Date.now()}` + const nome = `${prefix} Mata Atlântica` + + try { + const response = await agent.post('/api/v2/vegetacoes').send({ nome }).expect(201) + const body = response.body as Vegetacao + + expect(body).toMatchObject({ nome }) + expect(Number(body.id)).toBeGreaterThan(0) + + await knex('vegetacoes').where({ id: Number(body.id) }).delete() + } catch (error) { + await knex('vegetacoes').where('nome', 'like', `${prefix}%`).delete() + throw error + } + }) + + test('retorna 400 quando o nome está vazio', async () => { + const response = await agent.post('/api/v2/vegetacoes').send({ nome: ' ' }).expect(400) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/vazio|empty|obrigat/i) + }) + + test('retorna 400 para nome duplicado', async () => { + const prefix = `DUPVEG-${Date.now()}` + const nome = `${prefix} Cerrado` + + await knex('vegetacoes').insert({ nome }) + + try { + const response = await agent.post('/api/v2/vegetacoes').send({ nome }).expect(409) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/já existe|duplic|exist/i) + } finally { + await knex('vegetacoes').where({ nome }).delete() + } + }) +}) diff --git a/test/integration/vegetacao/lista-vegetacoes.test.ts b/test/integration/vegetacao/lista-vegetacoes.test.ts index 9f64d264..0a98c69f 100644 --- a/test/integration/vegetacao/lista-vegetacoes.test.ts +++ b/test/integration/vegetacao/lista-vegetacoes.test.ts @@ -14,7 +14,7 @@ describe('GET /api/v2/vegetacoes', () => { afterAll(() => knex.destroy()) test('retorna a lista ordenada por id decrescente como padrão dentro do prefixo do teste', async () => { - const prefix = 'XVEG' + const prefix = `XVEG_LISTA_${Date.now()}` const nomes = [ `${prefix} Mata Atlântica`, `${prefix} Restinga`, @@ -35,7 +35,7 @@ describe('GET /api/v2/vegetacoes', () => { }) test('filtra por nome sem diferenciar maiúsculas e minúsculas', async () => { - const prefix = 'XVEG' + const prefix = `XVEG_FILTRO_${Date.now()}` const nomes = [ `${prefix} Floresta`, `${prefix} Cerrado`, @@ -54,7 +54,7 @@ describe('GET /api/v2/vegetacoes', () => { }) test('aceita ordenação customizada por nome e id', async () => { - const prefix = 'XVEG' + const prefix = `XVEG_ORDEM_${Date.now()}` const nomes = [ `${prefix} Z`, `${prefix} A`, @@ -76,7 +76,7 @@ describe('GET /api/v2/vegetacoes', () => { }) test('retorna 400 quando a ordenação é inválida', async () => { - const prefix = 'XVEG' + const prefix = `XVEG_ORDEM_INVALIDA_${Date.now()}` const nomes = [ `${prefix} Z`, `${prefix} A`, @@ -94,36 +94,3 @@ describe('GET /api/v2/vegetacoes', () => { } }) }) - -describe('GET /api/v2/vegetacoes/:vegetacaoId', () => { - const { agent, knex } = createTestApp() - - afterAll(() => knex.destroy()) - - test('retorna o registro encontrado', async () => { - const [vegetacao] = await knex('vegetacoes') - .insert({ nome: 'XVEG Vegetação Encontrada' }) - .returning(returning) - - try { - const response = await agent.get(`/api/v2/vegetacoes/${vegetacao.id}`).expect(200) - expect(response.body).toEqual({ id: vegetacao.id, nome: vegetacao.nome }) - } finally { - await knex('vegetacoes').where({ id: vegetacao.id }).delete() - } - }) - - test('retorna 404 para id inexistente', async () => { - const response = await agent.get('/api/v2/vegetacoes/999999').expect(404) - const body = response.body as { error: { message: string } } - - expect(body.error.message).toMatch(/não encontrad[ao]|not found/i) - }) - - test('retorna 400 para id inválido', async () => { - const response = await agent.get('/api/v2/vegetacoes/abc').expect(400) - const body = response.body as { error: { message: string } } - - expect(body.error.message).toMatch(/inválido|invalid/i) - }) -}) diff --git a/test/integration/vegetacao/remove-vegetacoes.test.ts b/test/integration/vegetacao/remove-vegetacoes.test.ts new file mode 100644 index 00000000..2019f562 --- /dev/null +++ b/test/integration/vegetacao/remove-vegetacoes.test.ts @@ -0,0 +1,57 @@ +import { + afterAll, + describe, + expect, + test +} from 'vitest' + +import { createTestApp } from '../setup/app-factory' + +type Vegetacao = { id: number; nome: string } + +describe('DELETE /api/v2/vegetacoes/:vegetacaoId', () => { + const { agent, knex } = createTestApp() + + afterAll(() => knex.destroy()) + + test('remove uma vegetação sem dependências', async () => { + const prefix = `DELVEG-${Date.now()}` + const [vegetacao] = await knex('vegetacoes') + .insert({ nome: `${prefix} Removível` }) + .returning(['id', 'nome']) as Vegetacao[] + + try { + await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).expect(204) + const found = await knex('vegetacoes').where({ id: vegetacao.id }).first() + expect(found).toBeUndefined() + } finally { + await knex('vegetacoes').where('nome', 'like', `${prefix}%`).delete() + } + }) + + test('retorna 409 quando a vegetação está em uso em um tombo', async () => { + const prefix = `USEVEG-${Date.now()}` + const [vegetacao] = await knex('vegetacoes') + .insert({ nome: `${prefix} Em Uso` }) + .returning(['id', 'nome']) as Vegetacao[] + + try { + await knex('tombos').insert({ + hcf: 9000000000 + Date.now(), + vegetacao_id: vegetacao.id, + ativo: true, + rascunho: false, + created_at: new Date(), + updated_at: new Date() + }) + + const response = await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).expect(409) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/em uso|in use|uso/i) + } finally { + await knex('tombos').where({ vegetacao_id: vegetacao.id }).delete() + await knex('vegetacoes').where({ id: vegetacao.id }).delete() + } + }) +}) diff --git a/test/integration/vegetacao/renomeia-vegetacoes.test.ts b/test/integration/vegetacao/renomeia-vegetacoes.test.ts new file mode 100644 index 00000000..149be45a --- /dev/null +++ b/test/integration/vegetacao/renomeia-vegetacoes.test.ts @@ -0,0 +1,46 @@ +import { + afterAll, + describe, + expect, + test +} from 'vitest' + +import { createTestApp } from '../setup/app-factory' + +type Vegetacao = { id: number; nome: string } + +describe('PUT /api/v2/vegetacoes/:vegetacaoId', () => { + const { agent, knex } = createTestApp() + + afterAll(() => knex.destroy()) + + test('atualiza uma vegetação existente', async () => { + const prefix = `UPDVEG-${Date.now()}` + const [vegetacao] = await knex('vegetacoes') + .insert({ nome: `${prefix} Antiga` }) + .returning(['id', 'nome']) as Vegetacao[] + + try { + const response = await agent.put(`/api/v2/vegetacoes/${vegetacao.id}`).send({ nome: `${prefix} Nova` }).expect(200) + const body = response.body as Vegetacao + + expect(body).toEqual({ id: vegetacao.id, nome: `${prefix} Nova` }) + } finally { + await knex('vegetacoes').where({ id: vegetacao.id }).delete() + } + }) + + test('retorna 404 para id inexistente', async () => { + const response = await agent.put('/api/v2/vegetacoes/999999').send({ nome: 'Qualquer' }).expect(404) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/não encontrad|not found/i) + }) + + test('retorna 400 para id inválido', async () => { + const response = await agent.put('/api/v2/vegetacoes/abc').send({ nome: 'Qualquer' }).expect(400) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/inválido|invalid/i) + }) +}) From 5e8c7aa7776879e1e339ca85a288dc8c548eb632 Mon Sep 17 00:00:00 2001 From: josuemc Date: Wed, 9 Sep 2026 21:01:52 -0300 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20corre=C3=A7=C3=B5es=20e=20adi=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vegetacao/CadastraVegetacaoController.ts | 3 +- .../vegetacao/RemoveVegetacaoController.ts | 3 +- .../vegetacao/RenomeiaVegetacaoController.ts | 6 +-- .../vegetacao/RequireVegetacaoWriteAccess.ts | 44 +++++++++++++++++++ src/application/vegetacao/index.ts | 5 +++ .../VegetacaoCollectionKnexAdapter.ts | 42 +++++++++++++++++- src/library/http/error/ForbiddenError.ts | 7 +++ test/integration/setup/schema.sql | 3 ++ .../vegetacao/busca-vegetacoes.test.ts | 2 +- .../vegetacao/cadastra-vegetacoes.test.ts | 16 ++++--- .../vegetacao/remove-vegetacoes.test.ts | 10 ++++- .../vegetacao/renomeia-vegetacoes.test.ts | 32 ++++++++++++-- 12 files changed, 153 insertions(+), 20 deletions(-) create mode 100644 src/application/vegetacao/RequireVegetacaoWriteAccess.ts create mode 100644 src/library/http/error/ForbiddenError.ts diff --git a/src/application/vegetacao/CadastraVegetacaoController.ts b/src/application/vegetacao/CadastraVegetacaoController.ts index 86337edc..1ee5d59c 100644 --- a/src/application/vegetacao/CadastraVegetacaoController.ts +++ b/src/application/vegetacao/CadastraVegetacaoController.ts @@ -36,8 +36,7 @@ export class CadastraVegetacaoController implements RequestHandler { const result = await this.cadastraVegetacaoUseCase.execute({ nome: normalized }) if (result.left()) { - const message = result.value.message.toLowerCase() - if (message.includes('duplicate') || message.includes('unique') || message.includes('already') || message.includes('exist')) { + if (result.value.message === 'Já existe uma vegetação com esse nome') { return new ConflictError({ message: 'Já existe uma vegetação com esse nome' }) } return new InternalServerError({ message: result.value.message }) diff --git a/src/application/vegetacao/RemoveVegetacaoController.ts b/src/application/vegetacao/RemoveVegetacaoController.ts index ae02e9e2..dcfa9508 100644 --- a/src/application/vegetacao/RemoveVegetacaoController.ts +++ b/src/application/vegetacao/RemoveVegetacaoController.ts @@ -36,8 +36,7 @@ export class RemoveVegetacaoController implements RequestHandler { const result = await this.removeVegetacaoUseCase.execute({ id: Number(vegetacaoId) }) if (result.left()) { - const message = result.value.message.toLowerCase() - if (message.includes('foreign') || message.includes('integrity') || message.includes('constraint') || message.includes('in use') || message.includes('referenc')) { + if (result.value.message === 'Vegetação está em uso e não pode ser removida') { return new ConflictError({ message: 'Vegetação está em uso e não pode ser removida' }) } return new InternalServerError({ message: result.value.message }) diff --git a/src/application/vegetacao/RenomeiaVegetacaoController.ts b/src/application/vegetacao/RenomeiaVegetacaoController.ts index 3b642646..ae7e44dd 100644 --- a/src/application/vegetacao/RenomeiaVegetacaoController.ts +++ b/src/application/vegetacao/RenomeiaVegetacaoController.ts @@ -4,6 +4,7 @@ import { HttpRequest, HttpResponse, StatusCode } from '@/library/http/common' import { BadRequestError } from '@/library/http/error/BadRequestError' +import { ConflictError } from '@/library/http/error/ConflictError' import { HttpError } from '@/library/http/error/HttpError' import { InternalServerError } from '@/library/http/error/InternalServerError' import { NotFoundError } from '@/library/http/error/NotFoundError' @@ -47,9 +48,8 @@ export class RenomeiaVegetacaoController implements RequestHandler { const result = await this.renomeiaVegetacaoUseCase.execute({ id: parsedId, nome: nome.trim() }) if (result.left()) { - const message = result.value.message.toLowerCase() - if (message.includes('duplicate') || message.includes('unique') || message.includes('already') || message.includes('exist')) { - return new BadRequestError({ message: 'Já existe uma vegetação com esse nome' }) + if (result.value.message === 'Já existe uma vegetação com esse nome') { + return new ConflictError({ message: 'Já existe uma vegetação com esse nome' }) } return new InternalServerError({ message: result.value.message }) } diff --git a/src/application/vegetacao/RequireVegetacaoWriteAccess.ts b/src/application/vegetacao/RequireVegetacaoWriteAccess.ts new file mode 100644 index 00000000..461f7873 --- /dev/null +++ b/src/application/vegetacao/RequireVegetacaoWriteAccess.ts @@ -0,0 +1,44 @@ +import jwt from 'jsonwebtoken' + +import { + HttpRequest, + HttpResponse +} from '@/library/http/common' +import { ForbiddenError } from '@/library/http/error/ForbiddenError' +import { HttpError } from '@/library/http/error/HttpError' +import { UnauthorizedError } from '@/library/http/error/UnauthorizedError' +import { NextHandler, RequestHandler } from '@/library/http/Server' + +const ALLOWED_TIPOS_USUARIOS = new Set([1, 2]) + +export class RequireVegetacaoWriteAccess implements RequestHandler { + async handle(request: HttpRequest, next: NextHandler): Promise { + const authorization = request.headers.Authorization ?? request.headers.authorization + + if (!authorization || typeof authorization !== 'string' || !authorization.startsWith('Bearer ')) { + return new ForbiddenError({ message: 'Token de autenticação obrigatório' }) + } + + const token = authorization.slice('Bearer '.length).trim() + if (!token) { + return new ForbiddenError({ message: 'Token de autenticação obrigatório' }) + } + + try { + const payload = jwt.verify(token, process.env.JWT_SECRET ?? 'test-secret') as { tipo_usuario_id?: unknown } + const tipoUsuarioId = Number(payload.tipo_usuario_id) + + if (!Number.isInteger(tipoUsuarioId) || !ALLOWED_TIPOS_USUARIOS.has(tipoUsuarioId)) { + return new ForbiddenError({ message: 'Usuário sem permissão para alterar vegetações' }) + } + + return next() + } catch (error) { + if (error instanceof Error && error.name === 'TokenExpiredError') { + return new UnauthorizedError({ message: 'Token expirado' }) + } + + return new UnauthorizedError({ message: 'Token de autenticação inválido' }) + } + } +} diff --git a/src/application/vegetacao/index.ts b/src/application/vegetacao/index.ts index d895337b..3892349a 100644 --- a/src/application/vegetacao/index.ts +++ b/src/application/vegetacao/index.ts @@ -14,13 +14,16 @@ import { CadastraVegetacaoController } from './CadastraVegetacaoController' import { ListaVegetacoesController } from './ListaVegetacoesController' import { RemoveVegetacaoController } from './RemoveVegetacaoController' import { RenomeiaVegetacaoController } from './RenomeiaVegetacaoController' +import { RequireVegetacaoWriteAccess } from './RequireVegetacaoWriteAccess' export function routes(knex: Knex): Route[] { const vegetacaoCollection = new VegetacaoCollectionKnexAdapter({ knex }) + const requireVegetacaoWriteAccess = new RequireVegetacaoWriteAccess() return [ { handlers: [ + requireVegetacaoWriteAccess, new CadastraVegetacaoController({ cadastraVegetacaoUseCase: new CadastraVegetacaoUseCase({ vegetacaoCollection }) }) @@ -48,6 +51,7 @@ export function routes(knex: Knex): Route[] { }, { handlers: [ + requireVegetacaoWriteAccess, new RenomeiaVegetacaoController({ renomeiaVegetacaoUseCase: new RenomeiaVegetacaoUseCase({ vegetacaoCollection }) }) @@ -57,6 +61,7 @@ export function routes(knex: Knex): Route[] { }, { handlers: [ + requireVegetacaoWriteAccess, new RemoveVegetacaoController({ removeVegetacaoUseCase: new RemoveVegetacaoUseCase({ vegetacaoCollection }) }) diff --git a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts index 7c8af272..fa095562 100644 --- a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts +++ b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts @@ -6,6 +6,32 @@ import { Either } from '@/library/either/Either' import { CollectionError } from './error/CollectionError' +const DUPLICATE_VEGETACAO_MESSAGE = 'Já existe uma vegetação com esse nome' +const VEGETACAO_IN_USE_MESSAGE = 'Vegetação está em uso e não pode ser removida' + +function isDuplicateVegetacaoError(error: unknown): boolean { + const code = typeof error === 'object' && error !== null && 'code' in error ? String((error as { code?: unknown }).code) : '' + const details = typeof error === 'object' && error !== null && 'detail' in error ? String((error as { detail?: unknown }).detail) : '' + const message = typeof error === 'object' && error !== null && 'message' in error ? String((error as { message?: unknown }).message) : '' + const constraint = typeof error === 'object' && error !== null && 'constraint' in error ? String((error as { constraint?: unknown }).constraint) : '' + + return code === '23505' + || (constraint.toLowerCase().includes('vegetacoes') && constraint.toLowerCase().includes('nome')) + || details.toLowerCase().includes('already exists') + || message.toLowerCase().includes('duplicate key value violates unique constraint') +} + +function isVegetacaoInUseError(error: unknown): boolean { + const code = typeof error === 'object' && error !== null && 'code' in error ? String((error as { code?: unknown }).code) : '' + const message = typeof error === 'object' && error !== null && 'message' in error ? String((error as { message?: unknown }).message) : '' + const constraint = typeof error === 'object' && error !== null && 'constraint' in error ? String((error as { constraint?: unknown }).constraint) : '' + + return code === '23503' + || message.toLowerCase().includes('violates foreign key constraint') + || message.toLowerCase().includes('is still referenced from table') + || constraint.toLowerCase().includes('vegetacao') +} + interface Dependencies { knex: Knex } @@ -71,7 +97,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { } if (existing.value) { - return Either.left(new CollectionError({ message: 'Já existe uma vegetação com esse nome' })) + return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE })) } try { @@ -81,6 +107,10 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.right(vegetacao) } catch (error) { + if (isDuplicateVegetacaoError(error)) { + return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE, cause: error })) + } + const cause = error instanceof Error ? error : new Error(String(error)) return Either.left(new CollectionError({ message: cause.message, cause })) } @@ -95,7 +125,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { } if (existing.value) { - return Either.left(new CollectionError({ message: 'Já existe uma vegetação com esse nome' })) + return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE })) } try { @@ -106,6 +136,10 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.right(vegetacao ?? null) } catch (error) { + if (isDuplicateVegetacaoError(error)) { + return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE, cause: error })) + } + const cause = error instanceof Error ? error : new Error(String(error)) return Either.left(new CollectionError({ message: cause.message, cause })) } @@ -116,6 +150,10 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { const deleted = await this.knex('vegetacoes').where({ id }).delete() return Either.right(deleted > 0) } catch (error) { + if (isVegetacaoInUseError(error)) { + return Either.left(new CollectionError({ message: VEGETACAO_IN_USE_MESSAGE, cause: error })) + } + const cause = error instanceof Error ? error : new Error(String(error)) return Either.left(new CollectionError({ message: cause.message, cause })) } diff --git a/src/library/http/error/ForbiddenError.ts b/src/library/http/error/ForbiddenError.ts new file mode 100644 index 00000000..2c0b43da --- /dev/null +++ b/src/library/http/error/ForbiddenError.ts @@ -0,0 +1,7 @@ +import { HttpError } from './HttpError' + +export class ForbiddenError extends HttpError { + constructor(params: { message: string; report?: unknown; cause?: unknown }) { + super({ ...params, statusCode: 403 }) + } +} diff --git a/test/integration/setup/schema.sql b/test/integration/setup/schema.sql index 99ab6f08..9513ab60 100644 --- a/test/integration/setup/schema.sql +++ b/test/integration/setup/schema.sql @@ -1467,6 +1467,9 @@ CREATE TABLE public.vegetacoes ( updated_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL ); +CREATE UNIQUE INDEX vegetacoes_nome_unique + ON public.vegetacoes (LOWER(nome)); + -- -- TOC entry 291 (class 1259 OID 31265) diff --git a/test/integration/vegetacao/busca-vegetacoes.test.ts b/test/integration/vegetacao/busca-vegetacoes.test.ts index 37a2cb67..6625b8ab 100644 --- a/test/integration/vegetacao/busca-vegetacoes.test.ts +++ b/test/integration/vegetacao/busca-vegetacoes.test.ts @@ -41,7 +41,7 @@ describe('GET /api/v2/vegetacoes/:vegetacaoId', () => { expect(body.error.message).toMatch(/inválido|invalid/i) }) - test('retorna 400 para id inválido', async () => { + test('retorna 400 para id negativo', async () => { const response = await agent.get('/api/v2/vegetacoes/-12').expect(400) const body = response.body as { error: { message: string } } diff --git a/test/integration/vegetacao/cadastra-vegetacoes.test.ts b/test/integration/vegetacao/cadastra-vegetacoes.test.ts index f93fc304..186d2364 100644 --- a/test/integration/vegetacao/cadastra-vegetacoes.test.ts +++ b/test/integration/vegetacao/cadastra-vegetacoes.test.ts @@ -1,3 +1,4 @@ +import jwt from 'jsonwebtoken' import { afterAll, describe, @@ -9,6 +10,11 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } +const buildAuthHeader = () => { + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + return { Authorization: `Bearer ${token}` } +} + describe('POST /api/v2/vegetacoes', () => { const { agent, knex } = createTestApp() @@ -19,7 +25,7 @@ describe('POST /api/v2/vegetacoes', () => { const nome = `${prefix} Mata Atlântica` try { - const response = await agent.post('/api/v2/vegetacoes').send({ nome }).expect(201) + const response = await agent.post('/api/v2/vegetacoes').set(buildAuthHeader()).send({ nome }).expect(201) const body = response.body as Vegetacao expect(body).toMatchObject({ nome }) @@ -33,23 +39,23 @@ describe('POST /api/v2/vegetacoes', () => { }) test('retorna 400 quando o nome está vazio', async () => { - const response = await agent.post('/api/v2/vegetacoes').send({ nome: ' ' }).expect(400) + const response = await agent.post('/api/v2/vegetacoes').set(buildAuthHeader()).send({ nome: ' ' }).expect(400) const body = response.body as { error: { message: string } } expect(body.error.message).toMatch(/vazio|empty|obrigat/i) }) - test('retorna 400 para nome duplicado', async () => { + test('retorna 409 para nome duplicado', async () => { const prefix = `DUPVEG-${Date.now()}` const nome = `${prefix} Cerrado` await knex('vegetacoes').insert({ nome }) try { - const response = await agent.post('/api/v2/vegetacoes').send({ nome }).expect(409) + const response = await agent.post('/api/v2/vegetacoes').set(buildAuthHeader()).send({ nome }).expect(409) const body = response.body as { error: { message: string } } - expect(body.error.message).toMatch(/já existe|duplic|exist/i) + expect(body.error.message).toMatch(/já existe|duplic/i) } finally { await knex('vegetacoes').where({ nome }).delete() } diff --git a/test/integration/vegetacao/remove-vegetacoes.test.ts b/test/integration/vegetacao/remove-vegetacoes.test.ts index 2019f562..9ca0e98c 100644 --- a/test/integration/vegetacao/remove-vegetacoes.test.ts +++ b/test/integration/vegetacao/remove-vegetacoes.test.ts @@ -1,3 +1,4 @@ +import jwt from 'jsonwebtoken' import { afterAll, describe, @@ -9,6 +10,11 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } +const buildAuthHeader = () => { + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + return { Authorization: `Bearer ${token}` } +} + describe('DELETE /api/v2/vegetacoes/:vegetacaoId', () => { const { agent, knex } = createTestApp() @@ -21,7 +27,7 @@ describe('DELETE /api/v2/vegetacoes/:vegetacaoId', () => { .returning(['id', 'nome']) as Vegetacao[] try { - await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).expect(204) + await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).set(buildAuthHeader()).expect(204) const found = await knex('vegetacoes').where({ id: vegetacao.id }).first() expect(found).toBeUndefined() } finally { @@ -45,7 +51,7 @@ describe('DELETE /api/v2/vegetacoes/:vegetacaoId', () => { updated_at: new Date() }) - const response = await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).expect(409) + const response = await agent.delete(`/api/v2/vegetacoes/${vegetacao.id}`).set(buildAuthHeader()).expect(409) const body = response.body as { error: { message: string } } expect(body.error.message).toMatch(/em uso|in use|uso/i) diff --git a/test/integration/vegetacao/renomeia-vegetacoes.test.ts b/test/integration/vegetacao/renomeia-vegetacoes.test.ts index 149be45a..82571585 100644 --- a/test/integration/vegetacao/renomeia-vegetacoes.test.ts +++ b/test/integration/vegetacao/renomeia-vegetacoes.test.ts @@ -1,3 +1,4 @@ +import jwt from 'jsonwebtoken' import { afterAll, describe, @@ -9,6 +10,11 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } +const buildAuthHeader = () => { + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + return { Authorization: `Bearer ${token}` } +} + describe('PUT /api/v2/vegetacoes/:vegetacaoId', () => { const { agent, knex } = createTestApp() @@ -21,7 +27,7 @@ describe('PUT /api/v2/vegetacoes/:vegetacaoId', () => { .returning(['id', 'nome']) as Vegetacao[] try { - const response = await agent.put(`/api/v2/vegetacoes/${vegetacao.id}`).send({ nome: `${prefix} Nova` }).expect(200) + const response = await agent.put(`/api/v2/vegetacoes/${vegetacao.id}`).set(buildAuthHeader()).send({ nome: `${prefix} Nova` }).expect(200) const body = response.body as Vegetacao expect(body).toEqual({ id: vegetacao.id, nome: `${prefix} Nova` }) @@ -31,16 +37,36 @@ describe('PUT /api/v2/vegetacoes/:vegetacaoId', () => { }) test('retorna 404 para id inexistente', async () => { - const response = await agent.put('/api/v2/vegetacoes/999999').send({ nome: 'Qualquer' }).expect(404) + const response = await agent.put('/api/v2/vegetacoes/999999').set(buildAuthHeader()).send({ nome: 'Qualquer' }).expect(404) const body = response.body as { error: { message: string } } expect(body.error.message).toMatch(/não encontrad|not found/i) }) test('retorna 400 para id inválido', async () => { - const response = await agent.put('/api/v2/vegetacoes/abc').send({ nome: 'Qualquer' }).expect(400) + const response = await agent.put('/api/v2/vegetacoes/abc').set(buildAuthHeader()).send({ nome: 'Qualquer' }).expect(400) const body = response.body as { error: { message: string } } expect(body.error.message).toMatch(/inválido|invalid/i) }) + + test('retorna 409 para nome duplicado', async () => { + const prefix = `DUPUPD-${Date.now()}` + const [original] = await knex('vegetacoes') + .insert({ nome: `${prefix} Original` }) + .returning(['id', 'nome']) as Vegetacao[] + + const [other] = await knex('vegetacoes') + .insert({ nome: `${prefix} Outro` }) + .returning(['id', 'nome']) as Vegetacao[] + + try { + const response = await agent.put(`/api/v2/vegetacoes/${other.id}`).set(buildAuthHeader()).send({ nome: original.nome }).expect(409) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/já existe|duplic/i) + } finally { + await knex('vegetacoes').whereIn('id', [original.id, other.id]).delete() + } + }) }) From a8db3378ad8f18e8e8828969196a088393a25754 Mon Sep 17 00:00:00 2001 From: josuemc Date: Wed, 9 Sep 2026 21:08:09 -0300 Subject: [PATCH 3/5] fix: add jsonwebtoken types --- package.json | 3 +- yarn.lock | 998 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 599 insertions(+), 402 deletions(-) diff --git a/package.json b/package.json index 2f353c7c..e6d3c08f 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "@stylistic/eslint-plugin": "5.5.0", "@types/cors": "2.8.19", "@types/express": "5.0.5", + "@types/jsonwebtoken": "^9.0.10", "@types/morgan": "1.9.10", "@types/pg": "^8.16.0", "@types/react": "19.2.2", @@ -84,8 +85,8 @@ "globals": "16.5.0", "husky": "9.1.7", "npm-run-all": "4.1.5", - "tsx": "4.21.0", "supertest": "7.2.2", + "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.46.3", "vitest": "4.0.7" diff --git a/yarn.lock b/yarn.lock index c60eea79..00e1fbfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -54,16 +54,16 @@ integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg== "@babel/parser@^7.25.4": - version "7.29.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334" - integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg== + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.8.tgz#9653716a2f10c677b98fbc63d4bfb000c302cf17" + integrity sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA== dependencies: - "@babel/types" "^7.29.7" + "@babel/types" "^7.29.8" -"@babel/types@^7.25.4", "@babel/types@^7.29.7": - version "7.29.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92" - integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA== +"@babel/types@^7.25.4", "@babel/types@^7.29.8": + version "7.29.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.8.tgz#1229eef31d85156d70fa3f4cd859376d0eaf6863" + integrity sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg== dependencies: "@babel/helper-string-parser" "^7.29.7" "@babel/helper-validator-identifier" "^7.29.7" @@ -80,9 +80,14 @@ "@esbuild/aix-ppc64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz#7a289c158e29cbf59ea0afc83cc80f06d1c89402" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz#7a289c158e29cbf59ea0afc83cc80f06d1c89402" integrity sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA== +"@esbuild/aix-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz#bf6e10303bcf2e7c686975fa52f937ec2728d8bc" + integrity sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ== + "@esbuild/android-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz#f78cb8a3121fc205a53285adb24972db385d185d" @@ -90,9 +95,14 @@ "@esbuild/android-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz#b8828d9edfa3a92660644eb8de6e4f3c203d7b17" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz#b8828d9edfa3a92660644eb8de6e4f3c203d7b17" integrity sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw== +"@esbuild/android-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz#0c6246bc8d2c4d172aac2db3fb1190d72bd65504" + integrity sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A== + "@esbuild/android-arm@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.7.tgz#593e10a1450bbfcac6cb321f61f468453bac209d" @@ -100,9 +110,14 @@ "@esbuild/android-arm@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz#5ec1847605e05b5dbe5df90db9ff7e3e4c58dca7" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.0.tgz#5ec1847605e05b5dbe5df90db9ff7e3e4c58dca7" integrity sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ== +"@esbuild/android-arm@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.2.tgz#2d84ece6a4e2684d92be26ee13d42757d831c381" + integrity sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg== + "@esbuild/android-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.7.tgz#453143d073326033d2d22caf9e48de4bae274b07" @@ -110,9 +125,14 @@ "@esbuild/android-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz#390642175b88ef82bad4cce03f8ab13fe9b1912e" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.0.tgz#390642175b88ef82bad4cce03f8ab13fe9b1912e" integrity sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA== +"@esbuild/android-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.2.tgz#fc38d4d6358d8dc1cf53f09f7589fe436eb64801" + integrity sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q== + "@esbuild/darwin-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz#6f23000fb9b40b7e04b7d0606c0693bd0632f322" @@ -120,9 +140,14 @@ "@esbuild/darwin-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz#ae45325960d5950cd6951e4f97396f4e1ff7d8d3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz#ae45325960d5950cd6951e4f97396f4e1ff7d8d3" integrity sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q== +"@esbuild/darwin-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz#f83afeeac1d7dac01c7a2fd012b3e451a0591fcc" + integrity sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw== + "@esbuild/darwin-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz#27393dd18bb1263c663979c5f1576e00c2d024be" @@ -130,9 +155,14 @@ "@esbuild/darwin-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz#c079247d589b6b99449659d94f06951b84bff2e4" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz#c079247d589b6b99449659d94f06951b84bff2e4" integrity sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ== +"@esbuild/darwin-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz#510147c055a795588dbbe14fd6b1b8ad0a2f30de" + integrity sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw== + "@esbuild/freebsd-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz#22e4638fa502d1c0027077324c97640e3adf3a62" @@ -140,9 +170,14 @@ "@esbuild/freebsd-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz#45c456215a486593c94900297202dc11c880a37a" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz#45c456215a486593c94900297202dc11c880a37a" integrity sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q== +"@esbuild/freebsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz#093b9200ecf0b115ba4e5e248a7485c9c5f8bd5e" + integrity sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw== + "@esbuild/freebsd-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz#9224b8e4fea924ce2194e3efc3e9aebf822192d6" @@ -150,9 +185,14 @@ "@esbuild/freebsd-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz#0399494c1c85e4388e9b7040bd60d48f2a5b0d2c" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz#0399494c1c85e4388e9b7040bd60d48f2a5b0d2c" integrity sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw== +"@esbuild/freebsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz#0be22b6df925d213e841ea87123af5df80b0faf7" + integrity sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg== + "@esbuild/linux-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz#4f5d1c27527d817b35684ae21419e57c2bda0966" @@ -160,9 +200,14 @@ "@esbuild/linux-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz#d6d9f09ef0de54116bf459a4d53cac7e0952fe39" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz#d6d9f09ef0de54116bf459a4d53cac7e0952fe39" integrity sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A== +"@esbuild/linux-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz#1bdbc651cda9ba9995c53ed9c71ceaa65094762d" + integrity sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug== + "@esbuild/linux-arm@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz#b9e9d070c8c1c0449cf12b20eac37d70a4595921" @@ -170,9 +215,14 @@ "@esbuild/linux-arm@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz#7b42ffa84c288ae94fdc431c1b28a89e3c3b9278" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz#7b42ffa84c288ae94fdc431c1b28a89e3c3b9278" integrity sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw== +"@esbuild/linux-arm@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz#beb12ad72b84f72d28488cc1b8ee9f7eb141d753" + integrity sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w== + "@esbuild/linux-ia32@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz#3f80fb696aa96051a94047f35c85b08b21c36f9e" @@ -180,9 +230,14 @@ "@esbuild/linux-ia32@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz#deb15d112ed8dd605346b6b953d23a21ff81253f" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz#deb15d112ed8dd605346b6b953d23a21ff81253f" integrity sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ== +"@esbuild/linux-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz#b81f9d55529b45c206a46a138214b1aa6879696b" + integrity sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ== + "@esbuild/linux-loong64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz#9be1f2c28210b13ebb4156221bba356fe1675205" @@ -190,9 +245,14 @@ "@esbuild/linux-loong64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz#81fb89d07eecc79b157dea61033757726fce0ca4" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz#81fb89d07eecc79b157dea61033757726fce0ca4" integrity sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg== +"@esbuild/linux-loong64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz#598667241a04c99b76ed6ef940ac50038c419f98" + integrity sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ== + "@esbuild/linux-mips64el@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz#4ab5ee67a3dfcbcb5e8fd7883dae6e735b1163b8" @@ -200,9 +260,14 @@ "@esbuild/linux-mips64el@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz#d0e42691b3ff7af9fb2217b70fc01f343bdb62bb" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz#d0e42691b3ff7af9fb2217b70fc01f343bdb62bb" integrity sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w== +"@esbuild/linux-mips64el@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz#1c51eb9cea903f53d97b5af3b1841db70f5596ca" + integrity sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA== + "@esbuild/linux-ppc64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz#dac78c689f6499459c4321e5c15032c12307e7ea" @@ -210,9 +275,14 @@ "@esbuild/linux-ppc64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz#389f3e5e98f17d477c467cc87136e1a076eead87" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz#389f3e5e98f17d477c467cc87136e1a076eead87" integrity sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg== +"@esbuild/linux-ppc64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz#63dd61f17ceb31a81227f413feac8a71bc2c51f2" + integrity sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ== + "@esbuild/linux-riscv64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz#050f7d3b355c3a98308e935bc4d6325da91b0027" @@ -220,9 +290,14 @@ "@esbuild/linux-riscv64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz#763bd60d59b242be12da1e67d5729f3024c605fa" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz#763bd60d59b242be12da1e67d5729f3024c605fa" integrity sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ== +"@esbuild/linux-riscv64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz#3763b08fde5cf25ab1facb8e7752edfe45fbfc27" + integrity sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA== + "@esbuild/linux-s390x@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz#d61f715ce61d43fe5844ad0d8f463f88cbe4fef6" @@ -230,9 +305,14 @@ "@esbuild/linux-s390x@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz#aac6061634872e4677de693bce8030d73b1fd055" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz#aac6061634872e4677de693bce8030d73b1fd055" integrity sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q== +"@esbuild/linux-s390x@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz#1a137ff293a82906eb3176385bd7e8e0e5cfb7cb" + integrity sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg== + "@esbuild/linux-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz#ca8e1aa478fc8209257bf3ac8f79c4dc2982f32a" @@ -240,9 +320,14 @@ "@esbuild/linux-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz#4f2917747188fe77632bcec65b2d84b422419779" integrity sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ== +"@esbuild/linux-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz#268b36211c146ca54f8fe12c578a8d6ef8979485" + integrity sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ== + "@esbuild/netbsd-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz#1650f2c1b948deeb3ef948f2fc30614723c09690" @@ -250,9 +335,14 @@ "@esbuild/netbsd-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz#814df0ae57a0c386814491b8397eeba82094a947" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz#814df0ae57a0c386814491b8397eeba82094a947" integrity sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw== +"@esbuild/netbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz#22571ad951d62bb6accc82d8d1fad5c8c1ac0ba1" + integrity sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw== + "@esbuild/netbsd-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz#65772ab342c4b3319bf0705a211050aac1b6e320" @@ -260,9 +350,14 @@ "@esbuild/netbsd-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz#e01bdf7e60fa1a08e46d46d960b0d9bb8ac210af" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz#e01bdf7e60fa1a08e46d46d960b0d9bb8ac210af" integrity sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw== +"@esbuild/netbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz#42fcc57297eb0a0ca3f5fc475291f4c1a3f7c0de" + integrity sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw== + "@esbuild/openbsd-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz#37ed7cfa66549d7955852fce37d0c3de4e715ea1" @@ -270,9 +365,14 @@ "@esbuild/openbsd-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz#4a15c36aacca68d2d5a4c90b710c06759f4c1ffa" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz#4a15c36aacca68d2d5a4c90b710c06759f4c1ffa" integrity sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g== +"@esbuild/openbsd-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz#9eb32af104ac3dacf4edca01f596664aab0c73ef" + integrity sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ== + "@esbuild/openbsd-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz#01bf3d385855ef50cb33db7c4b52f957c34cd179" @@ -280,9 +380,14 @@ "@esbuild/openbsd-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz#475e6101498a8ecce3008d7c388111d7a27c17bd" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz#475e6101498a8ecce3008d7c388111d7a27c17bd" integrity sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA== +"@esbuild/openbsd-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz#febed2402d6088225e91f20fb4ce2522ad0a4efd" + integrity sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw== + "@esbuild/openharmony-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz#6c1f94b34086599aabda4eac8f638294b9877410" @@ -290,9 +395,14 @@ "@esbuild/openharmony-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz#cfdc3957f0b7a69f1bde129aad17fcc2f6fa033e" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz#cfdc3957f0b7a69f1bde129aad17fcc2f6fa033e" integrity sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w== +"@esbuild/openharmony-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz#85641c3d466428bfbccea5f21c26836663fef5ce" + integrity sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q== + "@esbuild/sunos-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz#4b0dd17ae0a6941d2d0fd35a906392517071a90d" @@ -300,9 +410,14 @@ "@esbuild/sunos-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz#a013c856fecacd1c3aec985c8afe1d1cb017497d" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz#a013c856fecacd1c3aec985c8afe1d1cb017497d" integrity sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw== +"@esbuild/sunos-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz#a736f9d8962481045fc4c3e54f5479f22c870fb4" + integrity sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g== + "@esbuild/win32-arm64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz#34193ab5565d6ff68ca928ac04be75102ccb2e77" @@ -310,9 +425,14 @@ "@esbuild/win32-arm64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz#eae05e0f35271cad3898b43168d3e9a3bbaf47e5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz#eae05e0f35271cad3898b43168d3e9a3bbaf47e5" integrity sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA== +"@esbuild/win32-arm64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz#ee5ab40fad186201b652a33f8a5eb149e9e42532" + integrity sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ== + "@esbuild/win32-ia32@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz#eb67f0e4482515d8c1894ede631c327a4da9fc4d" @@ -320,9 +440,14 @@ "@esbuild/win32-ia32@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz#06161ebc5bf75c08d69feb3c6b22560515913998" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz#06161ebc5bf75c08d69feb3c6b22560515913998" integrity sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA== +"@esbuild/win32-ia32@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz#c40d28a6d99a127da6711f2afd74b11cb63b06a7" + integrity sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA== + "@esbuild/win32-x64@0.27.7": version "0.27.7" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz#8fe30b3088b89b4873c3a6cc87597ae3920c0a8b" @@ -330,13 +455,18 @@ "@esbuild/win32-x64@0.28.0": version "0.28.0" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz#04d90d5752b4ce65d2b6ac25eba08ff7624fe07c" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz#04d90d5752b4ce65d2b6ac25eba08ff7624fe07c" integrity sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw== +"@esbuild/win32-x64@0.28.2": + version "0.28.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz#b21affb804cc167c133d95f45b3a1dc1323b9a87" + integrity sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g== + "@eslint-community/eslint-utils@^4.7.0", "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.0": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" - integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== + version "4.10.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz#8911bd72b2c3640a543609e0400b8c4d2e7e7cb6" + integrity sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg== dependencies: eslint-visitor-keys "^3.4.3" @@ -369,9 +499,9 @@ "@types/json-schema" "^7.0.15" "@eslint/eslintrc@^3.3.1": - version "3.3.5" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.5.tgz#c131793cfc1a7b96f24a83e0a8bbd4b881558c60" - integrity sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg== + version "3.3.7" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.7.tgz#76d3dedec4a30ea32df797bf8a0085c1311b7316" + integrity sha512-F42g89Qd5oAWtp0k0nnSrjziAKza7w8SVT4mStc18LZMaRb4J1HQAHLCalEtDCxrTuksx7NU9qsmeLwpOfPqWw== dependencies: ajv "^6.14.0" debug "^4.3.2" @@ -379,7 +509,7 @@ globals "^14.0.0" ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^4.1.1" + js-yaml "^4.3.2" minimatch "^3.1.5" strip-json-comments "^3.1.1" @@ -456,7 +586,7 @@ "@isaacs/cliui@^8.0.2": version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== dependencies: string-width "^5.1.2" @@ -472,9 +602,9 @@ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.5": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz#f4c663e862f06dc98ca4d453862c46902789a18d" + integrity sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw== "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.31": version "0.3.31" @@ -489,6 +619,11 @@ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== +"@napi-rs/lzma-linux-x64-gnu@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz#e57d4306966078662038094fb38eb9146dc3aea9" + integrity sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ== + "@noble/hashes@^1.1.5": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" @@ -524,7 +659,7 @@ "@pkgjs/parseargs@^0.11.0": version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@puppeteer/browsers@2.10.13": @@ -540,130 +675,130 @@ tar-fs "^3.1.1" yargs "^17.7.2" -"@rollup/rollup-android-arm-eabi@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz#634b0258cc501bef2353cee09a887b434826e81f" - integrity sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ== - -"@rollup/rollup-android-arm64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz#d7804ff9c31c2b8e7c51d966fedac65a4c828578" - integrity sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA== - -"@rollup/rollup-darwin-arm64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz#f26d03228e48c8bd55ff6be847242308dbfdb50d" - integrity sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw== - -"@rollup/rollup-darwin-x64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz#6e9037ccfc806a749aa044b063256a26ad32339d" - integrity sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w== - -"@rollup/rollup-freebsd-arm64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz#ff448605b36cc4736a6fea89bd0eb74653f09cbc" - integrity sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ== - -"@rollup/rollup-freebsd-x64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz#a30fe00a8651b577966022d1db1fb1bd6776105e" - integrity sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ== - -"@rollup/rollup-linux-arm-gnueabihf@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz#0ba85b63893eb17e11052bd21fe2809afc475a82" - integrity sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ== - -"@rollup/rollup-linux-arm-musleabihf@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz#982bf23fcfe4e8e13002912d4073f56a2eea2a39" - integrity sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA== - -"@rollup/rollup-linux-arm64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz#c94d1e8bd116ea2b569aab37dd04a6ccab74f1ab" - integrity sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g== - -"@rollup/rollup-linux-arm64-musl@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz#a7d79014ba3c5dd2d140309730365d413976db24" - integrity sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw== - -"@rollup/rollup-linux-loong64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz#5dd943c58bda55d8b269426bd60a47dd9c27776e" - integrity sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg== - -"@rollup/rollup-linux-loong64-musl@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz#08b1b9d362c64847306fea979b935e93a2590c4e" - integrity sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA== - -"@rollup/rollup-linux-ppc64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz#1c5de568966d11091281b22bc764ee7adf92667b" - integrity sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w== - -"@rollup/rollup-linux-ppc64-musl@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz#4dde1c9b941748ea49e07cfc96c64b18236225cd" - integrity sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg== - -"@rollup/rollup-linux-riscv64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz#21dd1014033b970dd23189d1d4d3cdab45de7f9a" - integrity sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg== - -"@rollup/rollup-linux-riscv64-musl@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz#4664e0bae205a3a18eb6407c10054c4b8dd7f381" - integrity sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg== - -"@rollup/rollup-linux-s390x-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz#b05a6b3af6a0d3c9b9f7be9c253eb4f101a67848" - integrity sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA== - -"@rollup/rollup-linux-x64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz#85dda72aa08cdc256f80f46d881b2a988bb0cce2" - integrity sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg== - -"@rollup/rollup-linux-x64-musl@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz#d79f5be62a484b58a8ec4d5ae23acf7b0eb1a8ff" - integrity sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw== - -"@rollup/rollup-openbsd-x64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz#8ebafe0d66cde1c8ab0a867cd9dcea89e22ee7b1" - integrity sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg== - -"@rollup/rollup-openharmony-arm64@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz#105537bcfcb2fd82796518184e995ae4396bb792" - integrity sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg== - -"@rollup/rollup-win32-arm64-msvc@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz#08ebcfc01b5b3b106ae074bae3692e94a63b5125" - integrity sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw== - -"@rollup/rollup-win32-ia32-msvc@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz#493005cb0fcab009e866ccdbad3c97c512c2bf4b" - integrity sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw== - -"@rollup/rollup-win32-x64-gnu@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz#47b40294def035268329d5ffd5364347bf726e5f" - integrity sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA== - -"@rollup/rollup-win32-x64-msvc@4.62.0": - version "4.62.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz#6850434fdb691e9b2408ded9b65ea357bf83636d" - integrity sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA== +"@rollup/rollup-android-arm-eabi@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.1.tgz#d03ba6ea54f9ec80688d153763cd325a2d2a5af6" + integrity sha512-UZ8sUxPTiHWYX9QNdJedb1kDZSpS1t/VPWBWGSgqHNi9w3Cu6IXvu2mzbhiTiPvtrqgTQJ+zqiAq2iPIPilpaQ== + +"@rollup/rollup-android-arm64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.1.tgz#db5e36aa8a955b4b5e0b024d671230edc5cdc191" + integrity sha512-cQ4nFQABN5cDvDpbvJ7bMStCpnaVxynZrRMfUJYgxcIk9Sh54FIO1vtfkg0B69REjER77ioZ/ov+eAApx/KmLQ== + +"@rollup/rollup-darwin-arm64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.1.tgz#1ed1c43922e7b9b5d020ef65d8402e3c81edc86e" + integrity sha512-FQNqd1lRy/0QhDk3xeRIkSBiCpXCiDnZO3YLVdcDKN1UBiKToNftCzcXYNLshmPDUMlu2TdeS8tGcsU6f3YF1Q== + +"@rollup/rollup-darwin-x64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.1.tgz#0a86e782bf7a546e74f531e395e24fdb45c83527" + integrity sha512-pvD16V939D3CloK0+qikpGaxiPrDUXTe7Y5cWOMkMSy7m1cawa8EGy/kXYi/G/cKAC4HDAbSnzCIk1WmsoOKXg== + +"@rollup/rollup-freebsd-arm64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.1.tgz#82fa51c540185b5063c8b3c63aac79b15f2801ad" + integrity sha512-pcFGeL2345VwdTnJhA6zLbew+YgWB0qBG2+dMtXjCicf6+rm6kO6cOoh5VnTe0ZMrMRgRyuHmCJxZWrIdzYuOw== + +"@rollup/rollup-freebsd-x64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.1.tgz#df1d73b567fd62e0cf21c9b57dff7f44bfd69638" + integrity sha512-mRJlqSRulVzcKq/LKA6ICSIc3K/l4fzlVn/gePn2nXIHy8seRi5z/eeRE0d/XMBxcMldiXtQTSpRj0tkkC3g8Q== + +"@rollup/rollup-linux-arm-gnueabihf@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.1.tgz#a585ba0418027a5b567693db3982e5e57544a4c7" + integrity sha512-YDUNvVM85TI3g/1OpnqKP1h4NeW/j64DfWMf+G3M809xNk1bJSnpFp4sh83NpmVE5DXnkh8ULor4LTVZKoYLHw== + +"@rollup/rollup-linux-arm-musleabihf@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.1.tgz#1326f0db22b690a92efd8eaa06e92268dc7d1bb6" + integrity sha512-7Mcn71p9ZuQFAj+h+dhQXy/yeLePRS2yKRnmW1DijA9thKO5qap0GNOIQK4yQ6iP3SU0Mrb/yWo8h8vgRba8lw== + +"@rollup/rollup-linux-arm64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.1.tgz#9491939f7cc43a5b26a877417faeafe69bac79ac" + integrity sha512-4YiLQTX6U4CSl0L9cluep9A9W6UmTfqBDc2/CH6wlu54pl4E7Jn3cOD8oxzvBDEGk/JMKgJ47C8g+radF7mwvg== + +"@rollup/rollup-linux-arm64-musl@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.1.tgz#a53d93dac32acc671324af1153930ab5a04d8639" + integrity sha512-2ra8F7w8OquwZN9z2/fKFnli69wa8PLwaVzRMIPGb13ByMJwC28Fbp8YcVGoUhlYMTt7j5j9bNgpysrN2UM+vw== + +"@rollup/rollup-linux-loong64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.1.tgz#db6e06173efc870be49a2df692d0c0607417a679" + integrity sha512-Sy20ncyhjmBP0Ml+UvQbimjlk6VFgjW5uNP+qqwHB00mTE8Bl2C1TuHTlRwK2YoXeZbee5lP2XevBWVkAQAtSQ== + +"@rollup/rollup-linux-loong64-musl@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.1.tgz#a60734a3de407bcf4bfe44d0b64222c0b9fb30bc" + integrity sha512-noITLp8oNjYliPnGWmLyelIHwULGqbHloQHGw1rtxbWhTuWooRpnZarZQJ1y9EUC4szuCusCc+HEpUtxpIwYvA== + +"@rollup/rollup-linux-ppc64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.1.tgz#28a67e15d7ba8630ef044980a39626e0627d6e73" + integrity sha512-hlxxXd+F1mWiAcaFR7Sv9ZQT6m6UfI8+Vy/kFJzztq2pDMU/0wZ9sish0iszNZvsQDo8Gc0i5yuFEOz5dDf6fA== + +"@rollup/rollup-linux-ppc64-musl@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.1.tgz#77bb553a514942af54070756763dbb44c9c6cb2b" + integrity sha512-EF7OpqQTQ/BvGqLzUi4rEHuagCV9MugAUXSHemwPW5vxZ75RR+jxO/2j95Ph2dalMpFHSVECjRoioHZgA9zOYA== + +"@rollup/rollup-linux-riscv64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.1.tgz#ef9f31b917e3b310eac5b86d3b6626df7e543e3d" + integrity sha512-wQO3JesW9PRkwlabQ27y7sPfVOOTLRG73I4F2UYHG5PXun3J9U3y+b7ezVKSYbsvSKGQ1k1cq8Qlun4C9kLt3w== + +"@rollup/rollup-linux-riscv64-musl@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.1.tgz#68cf61a2fc02171d1fa62568b73c1d942f82e80c" + integrity sha512-ouAGwhO6wHRXdnOVCOsB0tRFkA7nhNB2Nwax6oECXN0YiN8EYUTBAOudADOB1PI+yDL61TeNx/u7MVCzksNbkQ== + +"@rollup/rollup-linux-s390x-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.1.tgz#92d393ca47da0d03d1c1cffb3d7340f26c3a53d2" + integrity sha512-q2R38Sn+1J8RxhfJ+T54wSWmyKXWec+9jgDfqO2AtArEqHO5R2aeayp5H5OYLr5UYDVGsVaZPEFUooMhYCdz5A== + +"@rollup/rollup-linux-x64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.1.tgz#f6e5c5c51f96ae298617fa26da54675acd60e3bc" + integrity sha512-gfI5T24WLLuFfSKw7Go/zDXjAAV0fny0swTaDv+WjK7vqcw4cRhFfdsyKL1n+ukI+ooBxn3bVQnyrn06WpI50w== + +"@rollup/rollup-linux-x64-musl@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.1.tgz#227a949c481909c781d8a39c280f75553cdd16bc" + integrity sha512-4h6XqthmB4Hspji84wvgk+ElodTsGj+dbZqHJHHtKxj4mYq0ANSEEPX9ys3moJueqsRjwpaJYH7874Itwnj2ow== + +"@rollup/rollup-openbsd-x64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.1.tgz#f57241ebdb73d3bc236e7b1252988408b2139c13" + integrity sha512-dlfCOa87o1VAYegLQ9EKilx2JCeRofiyPGhTCmqnuXZ6bMPiycO1rq1+sKoulAp7pGLIsTIw+1x5R+zgh5LhhA== + +"@rollup/rollup-openharmony-arm64@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.1.tgz#3a9ffe5af71e8316dd2716b57dd64287a8c1fa0b" + integrity sha512-cjkLbOlfcm3QGhMM1J5zaZjsw1GggbN6rw9UTSSRrPrR1KkcXnN7Uq9rPw34xImQ9VOY9GN+6u2Zj80B9ptkcw== + +"@rollup/rollup-win32-arm64-msvc@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.1.tgz#7d4a40396ae79ebc1e3636c1d566c7d1838b800c" + integrity sha512-Li1KdUnWGE4N3e1F/B4RTB1ms+nG4WBgjByO46pkeBVX/2UBsY53xf5vK9WygVmnH3RwncIST7lkSdLSY6P9lg== + +"@rollup/rollup-win32-ia32-msvc@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.1.tgz#f234ab80141da45ebe85727f714eb20de2e72c2a" + integrity sha512-t4ZYOSoLTgwhuFMrmTMLx/+i1DQVK7HYqMc6kY46EApwi8X0nIVphzdNoThU3xt6n+N5urG1/gxBdCaKDLavfg== + +"@rollup/rollup-win32-x64-gnu@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.1.tgz#5d5a664c23c8ff0526b9abd703b50ffe09703c2a" + integrity sha512-RgroPfMmKlD1RzSDxvwgcPiy2HNQKoYV7OmwIXDsk73uKW5t6B/V8KIy27SMv/FNXFo/oSBtWc9J0X7t91ezZg== + +"@rollup/rollup-win32-x64-msvc@4.63.1": + version "4.63.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.1.tgz#cd19d691330cbd52ebb13620acb6cf7140b95e80" + integrity sha512-at8QVep6S3h5Y6gSbdGU06bRY5WJkf6WUduM9YtvYMbYhB1MOFfUgc6kehitQXzOtMSaT70q7f9ydPhpqu821w== "@scarf/scarf@=1.4.0": version "1.4.0" @@ -722,7 +857,7 @@ "@types/cors@2.8.19": version "2.8.19" - resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" integrity sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg== dependencies: "@types/node" "*" @@ -734,20 +869,29 @@ "@types/estree@1.0.9", "@types/estree@^1.0.0", "@types/estree@^1.0.6": version "1.0.9" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24" integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg== "@types/express-serve-static-core@^5.0.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz#1a77faffee9572d39124933259be2523837d7eaa" - integrity sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A== + version "5.1.3" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz#9d34c88c0c9ee62b9a6e4d9f8ab8d7e29688e6b4" + integrity sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/send" "*" -"@types/express@*", "@types/express@5.0.5": +"@types/express@*": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.6.tgz#2d724b2c990dcb8c8444063f3580a903f6d500cc" + integrity sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^5.0.0" + "@types/serve-static" "^2" + +"@types/express@5.0.5": version "5.0.5" resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.5.tgz#3ba069177caa34ab96585ca23b3984d752300cdc" integrity sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ== @@ -776,6 +920,14 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== +"@types/jsonwebtoken@^9.0.10": + version "9.0.10" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz#a7932a47177dcd4283b6146f3bd5c26d82647f09" + integrity sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA== + dependencies: + "@types/ms" "*" + "@types/node" "*" + "@types/methods@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547" @@ -788,22 +940,27 @@ "@types/morgan@1.9.10": version "1.9.10" - resolved "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz#725c15d95a5e6150237524cd713bc2d68f9edf1a" + resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.10.tgz#725c15d95a5e6150237524cd713bc2d68f9edf1a" integrity sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA== dependencies: "@types/node" "*" +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + "@types/node@*": - version "25.9.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-25.9.3.tgz#11dfe7a33e68fa5c560f0aa76cc5595621ef26b9" - integrity sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg== + version "22.20.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.20.2.tgz#daae777b5f5965a587f50cc80d5364c2ddf27e36" + integrity sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw== dependencies: - undici-types ">=7.24.0 <7.24.7" + undici-types "~6.21.0" "@types/pg@^8.16.0": - version "8.20.0" - resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.20.0.tgz#8bd03d3ac6b19143a8de7d66a9d13da32cd91526" - integrity sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow== + version "8.23.1" + resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.23.1.tgz#7e712ce02cf44ad100862127f10f52e9c6b9d227" + integrity sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A== dependencies: "@types/node" "*" pg-protocol "*" @@ -846,7 +1003,15 @@ "@types/mime" "^1" "@types/node" "*" -"@types/serve-static@*", "@types/serve-static@^1": +"@types/serve-static@*", "@types/serve-static@^2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-2.2.0.tgz#d4a447503ead0d1671132d1ab6bd58b805d8de6a" + integrity sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + +"@types/serve-static@^1": version "1.15.10" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== @@ -856,9 +1021,9 @@ "@types/send" "<1" "@types/superagent@^8.1.0", "@types/superagent@^8.1.7": - version "8.1.10" - resolved "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.10.tgz#aa1f600eeee83a7b129e06f8e7fec78fb0ac980a" - integrity sha512-nbt4IWXABhW0jGmmpRzCFNlbmwCTzZ2gTUsNIr+X+ItdqPms+PAJZbWsNzpS2USqXjcoNLQcO6nXo60zcPQiIg== + version "8.1.11" + resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-8.1.11.tgz#14da75aa2f916dcdd6fb2a90a8fb24a9a1a86d08" + integrity sha512-KA7srSW/HENDtOw9DOqaFLgWuMqN9WgjEw62lh9dpvRaZDkhdOkazASd7X7i2eMUYLHa1U37ZttnePsH5zTDHw== dependencies: "@types/cookiejar" "^2.1.5" "@types/methods" "^1.1.4" @@ -867,7 +1032,7 @@ "@types/supertest@7.2.0": version "7.2.0" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.0.tgz#9620bc998d3e26bcbedba7d31da8fe4c82fc1620" + resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-7.2.0.tgz#9620bc998d3e26bcbedba7d31da8fe4c82fc1620" integrity sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw== dependencies: "@types/methods" "^1.1.4" @@ -875,7 +1040,7 @@ "@types/swagger-ui-express@^4.1.8": version "4.1.8" - resolved "https://registry.npmjs.org/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz" + resolved "https://registry.yarnpkg.com/@types/swagger-ui-express/-/swagger-ui-express-4.1.8.tgz#3c0e0bf2543c7efb500eaa081bfde6d92f88096c" integrity sha512-AhZV8/EIreHFmBV5wAs0gzJUNq9JbbSXgJLQubCC0jtIo6prnI9MIRRxnU4MZX9RB9yXxF1V4R7jtLl/Wcj31g== dependencies: "@types/express" "*" @@ -937,9 +1102,9 @@ integrity sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA== "@typescript-eslint/tsconfig-utils@^8.46.3": - version "8.61.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz#ca88080e0cf191d49516d7f300b67aa090d2254f" - integrity sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg== + version "8.70.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.0.tgz#f583ca72159c4fd8e775c153da3241de6b77974f" + integrity sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw== "@typescript-eslint/type-utils@8.46.3": version "8.46.3" @@ -958,9 +1123,9 @@ integrity sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA== "@typescript-eslint/types@^8.46.1", "@typescript-eslint/types@^8.46.3": - version "8.61.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.61.1.tgz#0c51f518e4e6848371a1c988e859d59eb7522d5a" - integrity sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA== + version "8.70.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.70.0.tgz#9ee52888cdeca604fe9436935219b967fa7f6053" + integrity sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ== "@typescript-eslint/typescript-estree@8.46.3": version "8.46.3" @@ -1085,9 +1250,9 @@ acorn-jsx@^5.3.2: integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn@^8.15.0: - version "8.17.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.17.0.tgz#1785adb84faf8d8add10369b93826fc2bd08f1fe" - integrity sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg== + version "8.18.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.18.0.tgz#4faf01b2d6d326bfeed97aea1f52220b5f4c1940" + integrity sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ== agent-base@^7.1.0, agent-base@^7.1.2: version "7.1.4" @@ -1110,9 +1275,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.2.2: - version "6.2.2" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" - integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== + version "6.3.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.3.0.tgz#247c8e7b70a1a43b10ce14c0226fcbf58e8815d5" + integrity sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ== ansi-styles@^3.2.1: version "3.2.1" @@ -1130,7 +1295,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: ansi-styles@^6.1.0: version "6.2.3" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== append-field@^1.0.0: @@ -1254,14 +1419,14 @@ balanced-match@^1.0.0: integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== bare-events@^2.5.4, bare-events@^2.7.0: - version "2.9.1" - resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.9.1.tgz#5c86616966343bcb03a1b3155feab253eadbf349" - integrity sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg== + version "2.9.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.9.2.tgz#01d377b64c3c7167b28b52da7add3221aecf2d7f" + integrity sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA== bare-fs@^4.0.1, bare-fs@^4.5.5: - version "4.7.2" - resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-4.7.2.tgz#0f59b317e5bdbec6a1489b519a06a203cd3fe035" - integrity sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg== + version "4.8.1" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-4.8.1.tgz#1a946560b45844dc37120c00330eae7c8a1c44cf" + integrity sha512-N1nnXdHZAOSstz0XiHikGS4HGMH4CnSwhqWdGQQMqqdvp4Jybm9sE3R1WVnpWVd4SFkc8ryPDBLViNLwiEqECg== dependencies: bare-events "^2.5.4" bare-path "^3.0.0" @@ -1269,31 +1434,24 @@ bare-fs@^4.0.1, bare-fs@^4.5.5: bare-url "^2.2.2" fast-fifo "^1.3.2" -bare-os@^3.0.1: - version "3.9.1" - resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-3.9.1.tgz#660228ca7ffc47a72e96b6047cdd9d8342994e2f" - integrity sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ== - bare-path@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-3.0.1.tgz#c12c81b527936b650e87c5d00264d59ef458082c" - integrity sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ== - dependencies: - bare-os "^3.0.1" + version "3.1.2" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-3.1.2.tgz#67261bc74a9ba0105ba139b8638f218c09e8d82e" + integrity sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw== bare-stream@^2.6.4: - version "2.13.3" - resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.13.3.tgz#f6186c7cbb4bbf53a4560f35e48b16373ba51ce6" - integrity sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ== + version "2.13.4" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.13.4.tgz#61d448a268d1efd992103aae6bd729332f278ac0" + integrity sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA== dependencies: b4a "^1.8.1" streamx "^2.25.0" teex "^1.0.1" bare-url@^2.2.2: - version "2.4.5" - resolved "https://registry.yarnpkg.com/bare-url/-/bare-url-2.4.5.tgz#50d205f8f2724eec60fd091ba9cebd675fca63aa" - integrity sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ== + version "2.5.4" + resolved "https://registry.yarnpkg.com/bare-url/-/bare-url-2.5.4.tgz#10ab50f39b50335e2aa7672d5941043dbfc7749e" + integrity sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g== dependencies: bare-path "^3.0.0" @@ -1360,17 +1518,17 @@ body-parser@^2.2.0: type-is "^2.1.0" brace-expansion@^1.1.7: - version "1.1.15" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.15.tgz#a6d90d54067236e5f42570a3b7378d594d9b7738" - integrity sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg== + version "1.1.18" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.18.tgz#3ce74d89885136be1535341f8c3d4425c29a5cab" + integrity sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" brace-expansion@^2.0.2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.1.tgz#c68b1c4111c76aae3a6fba55d496cee10c39dad8" - integrity sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA== + version "2.1.4" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.4.tgz#589dab11c0018d0366be64cd8bf12c8dbecc8326" + integrity sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg== dependencies: balanced-match "^1.0.0" @@ -1607,10 +1765,10 @@ content-type@^1.0.5: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -content-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.0.0.tgz#2fb3ede69dffa0af78ca7c4ce7589680638b56df" - integrity sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ== +content-type@^2.0.0, content-type@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.1.0.tgz#d9389c43c0a8cf6a355db464d21e07092a40493a" + integrity sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag== convert-hrtime@^5.0.0: version "5.0.0" @@ -1845,7 +2003,7 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1: eastasianwidth@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecc-jsbn@~0.1.1: @@ -1880,7 +2038,7 @@ emoji-regex@^8.0.0: emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encodeurl@^2.0.0: @@ -2010,11 +2168,12 @@ es-set-tostringtag@^2.1.0: hasown "^2.0.2" es-to-primitive@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.1.tgz#abd6ef5b12d7c25bcd9eb3a7ef63e568b451ba4a" - integrity sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g== + version "1.3.4" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.4.tgz#0c854291cf0d7b439d6b9e5771ea837ffaf1f991" + integrity sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw== dependencies: es-abstract-get "^1.0.0" + es-define-property "^1.0.1" es-errors "^1.3.0" is-callable "^1.2.7" is-date-object "^1.1.0" @@ -2022,7 +2181,7 @@ es-to-primitive@^1.3.0: esbuild@0.28.0: version "0.28.0" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.0.tgz#5dee347ffb3e3874212a35a69836b077b1ce6d96" integrity sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw== optionalDependencies: "@esbuild/aix-ppc64" "0.28.0" @@ -2052,9 +2211,41 @@ esbuild@0.28.0: "@esbuild/win32-ia32" "0.28.0" "@esbuild/win32-x64" "0.28.0" -esbuild@^0.27.0, esbuild@~0.27.0: +"esbuild@^0.27.0 || ^0.28.0": + version "0.28.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.2.tgz#0f43bd1bad955b72d24e2261e3abe5957ccf0816" + integrity sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.28.2" + "@esbuild/android-arm" "0.28.2" + "@esbuild/android-arm64" "0.28.2" + "@esbuild/android-x64" "0.28.2" + "@esbuild/darwin-arm64" "0.28.2" + "@esbuild/darwin-x64" "0.28.2" + "@esbuild/freebsd-arm64" "0.28.2" + "@esbuild/freebsd-x64" "0.28.2" + "@esbuild/linux-arm" "0.28.2" + "@esbuild/linux-arm64" "0.28.2" + "@esbuild/linux-ia32" "0.28.2" + "@esbuild/linux-loong64" "0.28.2" + "@esbuild/linux-mips64el" "0.28.2" + "@esbuild/linux-ppc64" "0.28.2" + "@esbuild/linux-riscv64" "0.28.2" + "@esbuild/linux-s390x" "0.28.2" + "@esbuild/linux-x64" "0.28.2" + "@esbuild/netbsd-arm64" "0.28.2" + "@esbuild/netbsd-x64" "0.28.2" + "@esbuild/openbsd-arm64" "0.28.2" + "@esbuild/openbsd-x64" "0.28.2" + "@esbuild/openharmony-arm64" "0.28.2" + "@esbuild/sunos-x64" "0.28.2" + "@esbuild/win32-arm64" "0.28.2" + "@esbuild/win32-ia32" "0.28.2" + "@esbuild/win32-x64" "0.28.2" + +esbuild@~0.27.0: version "0.27.7" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.7.tgz#bcadce22b2f3fd76f257e3a64f83a64986fea11f" integrity sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w== optionalDependencies: "@esbuild/aix-ppc64" "0.27.7" @@ -2241,9 +2432,9 @@ events-universal@^1.0.0: bare-events "^2.7.0" expect-type@^1.2.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.3.0.tgz#0d58ed361877a31bbc4dd6cf71bbfef7faf6bd68" - integrity sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.4.0.tgz#24edf7f0cc69a44d008567ba4594ab96f3c3a3d6" + integrity sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA== express-rate-limit@8.2.1: version "8.2.1" @@ -2364,9 +2555,9 @@ fast-safe-stringify@^2.1.1: integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== fastq@^1.6.0: - version "1.20.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" - integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== + version "1.20.3" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.3.tgz#7ab8731e647b56abcfeee997dae333ca3ee1d04d" + integrity sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw== dependencies: reusify "^1.0.4" @@ -2425,9 +2616,9 @@ flat-cache@^4.0.0: keyv "^4.5.4" flatted@^3.2.9: - version "3.4.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726" - integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA== + version "3.4.4" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.4.tgz#aeeca2a506303f0cee61c59e6c9f2a88d2f29fc6" + integrity sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q== follow-redirects@^1.15.6: version "1.16.0" @@ -2443,7 +2634,7 @@ for-each@^0.3.3, for-each@^0.3.5: foreground-child@^3.1.0: version "3.3.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== dependencies: cross-spawn "^7.0.6" @@ -2500,7 +2691,7 @@ fs.realpath@^1.0.0: fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: @@ -2601,9 +2792,9 @@ get-symbol-description@^1.1.0: get-intrinsic "^1.2.6" get-tsconfig@^4.7.5: - version "4.14.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.14.0.tgz#985d85c52a9903864280ccc2448d413fbf1efed8" - integrity sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA== + version "4.14.3" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.14.3.tgz#7bcc9f3ab5fb6d30ad0a301898c859d34164dcd9" + integrity sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA== dependencies: resolve-pkg-maps "^1.0.0" @@ -2644,7 +2835,7 @@ glob-parent@^6.0.2: glob@10.5.0: version "10.5.0" - resolved "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== dependencies: foreground-child "^3.1.0" @@ -2824,9 +3015,9 @@ iconv-lite@^0.6.3: safer-buffer ">= 2.1.2 < 3.0.0" iconv-lite@^0.7.0, iconv-lite@^0.7.2, iconv-lite@~0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" - integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + version "0.7.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.3.tgz#84ee12f963e7de50bc01a13e160a078b3b0f415f" + integrity sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" @@ -2836,9 +3027,9 @@ ignore@^5.2.0: integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== ignore@^7.0.0: - version "7.0.5" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" - integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== + version "7.0.9" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.9.tgz#475b2197ade916edab05ade35c691518e8543382" + integrity sha512-brTTsvFRt5C1gGHtPst/281UjPD5t9fBqbgoMPlVWy11ZLTPfu7HxK4ZYqO9H7o/yC9rSTCI85EaQ4OoY12qYw== import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.1" @@ -2891,9 +3082,9 @@ ip-address@10.0.1: integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== ip-address@^10.1.1: - version "10.2.0" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.2.0.tgz#805fc178b20c518bd4c8548b24fe30892d7f3206" - integrity sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA== + version "10.7.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.7.0.tgz#9713429f16787ede8f642f6255b41fb515c825d9" + integrity sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA== ip-regex@^5.0.0: version "5.0.0" @@ -3186,7 +3377,7 @@ istanbul-reports@^3.2.0: jackspeak@^3.1.2: version "3.4.3" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== dependencies: "@isaacs/cliui" "^8.0.2" @@ -3203,10 +3394,10 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^4.1.0, js-yaml@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.2.0.tgz#2bd9e85682dd91bd469afb809d816043b3d49524" - integrity sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw== +js-yaml@^4.1.0, js-yaml@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.2.tgz#8e44fb14a2643c59726bb15787b5f1512cb3d3fb" + integrity sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA== dependencies: argparse "^2.0.1" @@ -3456,9 +3647,9 @@ lru-cache@^7.14.1: integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== lru.min@^1.0.0, lru.min@^1.1.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.4.tgz#6ea1737a8c1ba2300cc87ad46910a4bdffa0117b" - integrity sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA== + version "1.1.5" + resolved "https://registry.yarnpkg.com/lru.min/-/lru.min-1.1.5.tgz#bd32483f4e342261d0eb011b06d2219e6b5ef818" + integrity sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA== magic-string@^0.30.19: version "0.30.21" @@ -3494,9 +3685,9 @@ media-typer@0.3.0: integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== media-typer@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" - integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.1.tgz#6f035400dfe3ab9d5607bc77546ce30cc2f9c6b8" + integrity sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ== memorystream@^0.3.1: version "0.3.1" @@ -3664,10 +3855,10 @@ named-placeholders@^1.1.3: dependencies: lru.min "^1.1.0" -nanoid@^3.3.12: - version "3.3.12" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05" - integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== +nanoid@^3.3.18: + version "3.3.18" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.18.tgz#f66a2de1199ffde0fcf21c8a5f13106b1c081913" + integrity sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w== natural-compare@^1.4.0: version "1.4.0" @@ -3675,9 +3866,11 @@ natural-compare@^1.4.0: integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" - integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.1.0.tgz#16e003d0db4ac24fd9df168edf871625deeae3df" + integrity sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg== + dependencies: + content-type "^2.1.0" netmask@^2.0.2: version "2.1.1" @@ -3690,9 +3883,9 @@ nice-try@^1.0.4: integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-addon-api@^8.3.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.8.0.tgz#b742be05007b37ebc1741bbaf370d22bf25d208a" - integrity sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA== + version "8.9.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.9.2.tgz#db7ac94a13ffd9b55e6cb04584bd5ef8e1d74b18" + integrity sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg== node-gyp-build@^4.8.4: version "4.8.4" @@ -3800,11 +3993,12 @@ optionator@^0.9.3: word-wrap "^1.2.5" own-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" - integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.2.tgz#31448ec1f781ecb1447f6f6aa0d6534222af59de" + integrity sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg== dependencies: - get-intrinsic "^1.2.6" + call-bound "^1.0.4" + get-intrinsic "^1.3.0" object-keys "^1.1.1" safe-push-apply "^1.0.0" @@ -3816,9 +4010,9 @@ p-limit@^3.0.2: yocto-queue "^0.1.0" p-limit@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-7.3.0.tgz#821398d91491c6b6a1340ecd09cdc402a9c8d0ee" - integrity sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw== + version "7.3.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-7.3.2.tgz#accbb6255c23b8b4fd6802a1bcb3062d94469021" + integrity sha512-Ll0w3fU24vYpXoZmjjZIee6bJQDgG0oAyo1PdmFYI8UDwJJddaHAypxIH9avUu+t+lSsAwKVsb1jDCMIIChliw== dependencies: yocto-queue "^1.2.1" @@ -3956,10 +4150,10 @@ pg-connection-string@2.6.2: resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== -pg-connection-string@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.13.0.tgz#8678113465a5af3cc977dcb51eadc847b27aa2de" - integrity sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig== +pg-connection-string@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.14.0.tgz#abc26ee4f37c56c0f3ae0fcf0b0653cc4e1c0fd9" + integrity sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg== pg-int8@1.0.1: version "1.0.1" @@ -3971,10 +4165,10 @@ pg-pool@^3.14.0: resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.14.0.tgz#f35ae4eb846780cad71af24099b3edfa9781ad90" integrity sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw== -pg-protocol@*, pg-protocol@^1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.14.0.tgz#c1f045b74274b007078c687147141f785f59b8de" - integrity sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA== +pg-protocol@*, pg-protocol@^1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.16.0.tgz#cffb008826561ee9770a8a15dc21f269d731b305" + integrity sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg== pg-types@2.2.0, pg-types@^2.2.0: version "2.2.0" @@ -3988,13 +4182,13 @@ pg-types@2.2.0, pg-types@^2.2.0: postgres-interval "^1.1.0" pg@^8.16.3: - version "8.21.0" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.21.0.tgz#d7fa2118d960cec5cc7d2b24525f9850dd5932b0" - integrity sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA== + version "8.23.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.23.0.tgz#5c2026d32bd0cb4fbd9196bac1ecf5ae66607180" + integrity sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg== dependencies: - pg-connection-string "^2.13.0" + pg-connection-string "^2.14.0" pg-pool "^3.14.0" - pg-protocol "^1.14.0" + pg-protocol "^1.16.0" pg-types "2.2.0" pgpass "1.0.5" optionalDependencies: @@ -4018,9 +4212,9 @@ picomatch@^2.3.1: integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== picomatch@^4.0.3, picomatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" - integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== + version "4.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.7.tgz#6313360034ccb36b3dc61ecbdff78121f90fe21f" + integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA== pidtree@^0.3.0: version "0.3.1" @@ -4038,11 +4232,11 @@ possible-typed-array-names@^1.0.0, possible-typed-array-names@^1.1.0: integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== postcss@^8.5.6: - version "8.5.15" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.15.tgz#d1eaf677a324e9ec02196da2d3fecf4a0b9a735c" - integrity sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A== + version "8.5.28" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.28.tgz#da4563a99a06e62d6c1cd1acae363224bcaed6e9" + integrity sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A== dependencies: - nanoid "^3.3.12" + nanoid "^3.3.18" picocolors "^1.1.1" source-map-js "^1.2.1" @@ -4156,11 +4350,12 @@ q@1.5.1: integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== qs@^6.12.1, qs@^6.14.0, qs@^6.14.1, qs@^6.15.2: - version "6.15.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.2.tgz#fd55426d710403ddccc45e0f9eab16db7727ece9" - integrity sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw== + version "6.16.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.16.0.tgz#c22c723a28a920f3aacdce8289fabd43eccb79fd" + integrity sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA== dependencies: - side-channel "^1.1.0" + es-define-property "^1.0.1" + side-channel "^1.1.1" qs@~6.5.2: version "6.5.5" @@ -4173,9 +4368,9 @@ queue-microtask@^1.2.2: integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== range-parser@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.3.0.tgz#d7f19be812bb62721472b45d3be219ef09572b47" + integrity sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw== raw-body@^3.0.0, raw-body@^3.0.2: version "3.0.2" @@ -4320,37 +4515,38 @@ reusify@^1.0.4: integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rollup@^4.43.0: - version "4.62.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.62.0.tgz#f68956c966f3c4a51dafbafc5d5388553244191b" - integrity sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA== + version "4.63.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.63.1.tgz#a9b96d5b2558d034babb12ad8b67a043bc870ac4" + integrity sha512-3Df9jsstwhccuEfmAMi9l8XUh/GOkVObmFTU7CCVBysEbcOZLl84jCtaAZMcPiMz2EGKsATzQcU+Xr3n/wU6cg== dependencies: "@types/estree" "1.0.9" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.62.0" - "@rollup/rollup-android-arm64" "4.62.0" - "@rollup/rollup-darwin-arm64" "4.62.0" - "@rollup/rollup-darwin-x64" "4.62.0" - "@rollup/rollup-freebsd-arm64" "4.62.0" - "@rollup/rollup-freebsd-x64" "4.62.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.62.0" - "@rollup/rollup-linux-arm-musleabihf" "4.62.0" - "@rollup/rollup-linux-arm64-gnu" "4.62.0" - "@rollup/rollup-linux-arm64-musl" "4.62.0" - "@rollup/rollup-linux-loong64-gnu" "4.62.0" - "@rollup/rollup-linux-loong64-musl" "4.62.0" - "@rollup/rollup-linux-ppc64-gnu" "4.62.0" - "@rollup/rollup-linux-ppc64-musl" "4.62.0" - "@rollup/rollup-linux-riscv64-gnu" "4.62.0" - "@rollup/rollup-linux-riscv64-musl" "4.62.0" - "@rollup/rollup-linux-s390x-gnu" "4.62.0" - "@rollup/rollup-linux-x64-gnu" "4.62.0" - "@rollup/rollup-linux-x64-musl" "4.62.0" - "@rollup/rollup-openbsd-x64" "4.62.0" - "@rollup/rollup-openharmony-arm64" "4.62.0" - "@rollup/rollup-win32-arm64-msvc" "4.62.0" - "@rollup/rollup-win32-ia32-msvc" "4.62.0" - "@rollup/rollup-win32-x64-gnu" "4.62.0" - "@rollup/rollup-win32-x64-msvc" "4.62.0" + "@napi-rs/lzma-linux-x64-gnu" "1.5.1" + "@rollup/rollup-android-arm-eabi" "4.63.1" + "@rollup/rollup-android-arm64" "4.63.1" + "@rollup/rollup-darwin-arm64" "4.63.1" + "@rollup/rollup-darwin-x64" "4.63.1" + "@rollup/rollup-freebsd-arm64" "4.63.1" + "@rollup/rollup-freebsd-x64" "4.63.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.63.1" + "@rollup/rollup-linux-arm-musleabihf" "4.63.1" + "@rollup/rollup-linux-arm64-gnu" "4.63.1" + "@rollup/rollup-linux-arm64-musl" "4.63.1" + "@rollup/rollup-linux-loong64-gnu" "4.63.1" + "@rollup/rollup-linux-loong64-musl" "4.63.1" + "@rollup/rollup-linux-ppc64-gnu" "4.63.1" + "@rollup/rollup-linux-ppc64-musl" "4.63.1" + "@rollup/rollup-linux-riscv64-gnu" "4.63.1" + "@rollup/rollup-linux-riscv64-musl" "4.63.1" + "@rollup/rollup-linux-s390x-gnu" "4.63.1" + "@rollup/rollup-linux-x64-gnu" "4.63.1" + "@rollup/rollup-linux-x64-musl" "4.63.1" + "@rollup/rollup-openbsd-x64" "4.63.1" + "@rollup/rollup-openharmony-arm64" "4.63.1" + "@rollup/rollup-win32-arm64-msvc" "4.63.1" + "@rollup/rollup-win32-ia32-msvc" "4.63.1" + "@rollup/rollup-win32-x64-gnu" "4.63.1" + "@rollup/rollup-win32-x64-msvc" "4.63.1" fsevents "~2.3.2" router@^2.2.0: @@ -4425,9 +4621,9 @@ scheduler@^0.27.0: integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.7.3: - version "7.8.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.4.tgz#c73eceebae0616934be8dff28a7fd70757c8e696" - integrity sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA== + version "7.8.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.5.tgz#39b646037dd50c14fb451e7e4cac58ed8b863f69" + integrity sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA== send@^1.1.0, send@^1.2.0: version "1.2.1" @@ -4545,9 +4741,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.6.1: - version "1.8.4" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.4.tgz#2edd9a4dcefc96649e2e2cb12f637b1f1d92a190" - integrity sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ== + version "1.10.0" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.10.0.tgz#482033e192e4f5c07151521ffa03400ec71b1b0f" + integrity sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA== shimmer@^1.1.0: version "1.2.1" @@ -4583,7 +4779,7 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.1.0: +side-channel@^1.1.0, side-channel@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.1.tgz#ea02c62e05dc4bea67d4442f0fb71ee192f8e0ab" integrity sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ== @@ -4601,7 +4797,7 @@ siginfo@^2.0.0: signal-exit@^4.0.1: version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== smart-buffer@^4.2.0: @@ -4619,9 +4815,9 @@ socks-proxy-agent@^8.0.5: socks "^2.8.3" socks@^2.8.3: - version "2.8.9" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.9.tgz#aa5f130ca0f88a43fa44faf4869c50d22aa27752" - integrity sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw== + version "2.8.10" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.10.tgz#23aab4dccc1fdae110aaf4fa51cd190552432dc5" + integrity sha512-e0VyvkVTwVYViNovRkZ9aodhxVlyoMn7eJhVUPxZ+eK9P/7CBkxvvsBOHqFPEH416726W8tLXXXjKwqgTErrCQ== dependencies: ip-address "^10.1.1" smart-buffer "^4.2.0" @@ -4716,9 +4912,9 @@ streamsearch@^1.1.0: integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== streamx@^2.12.5, streamx@^2.15.0, streamx@^2.25.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.28.0.tgz#035ab56057b7ed2211b51d532e6973f0f99fbf11" - integrity sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw== + version "2.28.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.28.1.tgz#376cd42a089505a69bec0efdb5189aa45586141f" + integrity sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA== dependencies: events-universal "^1.0.0" fast-fifo "^1.3.2" @@ -4735,7 +4931,7 @@ streamx@^2.12.5, streamx@^2.15.0, streamx@^2.25.0: string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -4744,7 +4940,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: eastasianwidth "^0.2.0" @@ -4810,14 +5006,14 @@ string_decoder@^1.1.1: strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@^7.0.1: version "7.2.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.2.0.tgz#d22a269522836a627af8d04b5c3fd2c7fa3e32e3" integrity sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w== dependencies: ansi-regex "^6.2.2" @@ -4858,7 +5054,7 @@ superagent@^10.0.0, superagent@^10.3.0: supertest@7.2.2: version "7.2.2" - resolved "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz#dac3ee25a2aa59942a7f641e50c838a7c8819204" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-7.2.2.tgz#dac3ee25a2aa59942a7f641e50c838a7c8819204" integrity sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA== dependencies: cookie-signature "^1.2.2" @@ -4904,9 +5100,9 @@ swagger-parser@^10.0.3: "@apidevtools/swagger-parser" "10.0.3" swagger-ui-dist@>=5.0.0: - version "5.32.6" - resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.32.6.tgz#4a6a56786915ea4bfea43f00ff17890df8124d4c" - integrity sha512-75ttZNaYCLoFPnozPZcTUU6mS3wKT8l7WLjU5zJSHFeJa23i5vtnze6IiCl4jDMPeQTXVXIgovq4M11NNfQvSA== + version "5.32.15" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.32.15.tgz#0bbaa62695104dbf2db06ad9bbbaaa127d830614" + integrity sha512-TSFER+rFQlf1nzk6WvKkMaHTxAPQ3eAAxigFThnxQedSREanfZgSbJFayZVs/ULnSbNdrJOb99vLD6xpb3R3eg== dependencies: "@scarf/scarf" "=1.4.0" @@ -4918,9 +5114,9 @@ swagger-ui-express@5.0.1: swagger-ui-dist ">=5.0.0" tar-fs@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.2.tgz#114b012f54796f31e62f3e57792820a80b83ae6e" - integrity sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw== + version "3.1.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.3.tgz#05668cc68a30741c3813f9c16593b8dec7dcbcd1" + integrity sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ== dependencies: pump "^3.0.0" tar-stream "^3.1.5" @@ -4929,9 +5125,9 @@ tar-fs@^3.1.1: bare-path "^3.0.0" tar-stream@^3.1.5: - version "3.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.2.0.tgz#0d0064d9b67ea3c9f5abde155e35faab0df37591" - integrity sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg== + version "3.2.1" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.2.1.tgz#952d72f7aba68ce5cb802ef2e0b19f1bd989140d" + integrity sha512-nqsEO8zLZJvrOMdEwkA0QdCLFbetHMn95Zqu4fKwX+hkaTWJPZZOrxx/PwtxoK0MMGQmBQNRW3CPs8IFYQz4cQ== dependencies: b4a "^1.6.4" bare-fs "^4.5.5" @@ -4939,9 +5135,9 @@ tar-stream@^3.1.5: streamx "^2.15.0" tarn@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" - integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.1.2.tgz#d2922d34a232c8b027605f3873a9c55318ce4f34" + integrity sha512-3RTvqKZcK/17jnJ8rMKFXbyNogywTs1z0gVPPwFsJGX46rkmUHOdIaSQ/aVO1rS7nH+soiXiWk7rvUXxndm8Dg== teex@^1.0.1: version "1.0.1" @@ -5008,9 +5204,9 @@ tinyglobby@^0.2.15: picomatch "^4.0.4" tinyrainbow@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.0.tgz#1d8a623893f95cf0a2ddb9e5d11150e191409421" - integrity sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-3.1.1.tgz#c0168387d3d8d70b6b3c2c0936de5fee738cea20" + integrity sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw== to-regex-range@^5.0.1: version "5.0.1" @@ -5049,7 +5245,7 @@ tslib@^2.0.1: tsx@4.21.0: version "4.21.0" - resolved "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.21.0.tgz#32aa6cf17481e336f756195e6fe04dae3e6308b1" integrity sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw== dependencies: esbuild "~0.27.0" @@ -5173,10 +5369,10 @@ unbox-primitive@^1.1.0: has-symbols "^1.1.0" which-boxed-primitive "^1.1.1" -"undici-types@>=7.24.0 <7.24.7": - version "7.24.6" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.24.6.tgz#61275b485d7fd4e9d269c7cf04ec2873c9cc0f91" - integrity sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg== +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== unpipe@~1.0.0: version "1.0.0" @@ -5238,11 +5434,11 @@ verror@1.10.0: extsprintf "^1.2.0" "vite@^6.0.0 || ^7.0.0": - version "7.3.5" - resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.5.tgz#90c2d0b7b94a224e7e7dcf22d2912ff0b5291165" - integrity sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww== + version "7.3.6" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.6.tgz#0547a395e68d3746e9a505f1fd4469fe09b49cc4" + integrity sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg== dependencies: - esbuild "^0.27.0" + esbuild "^0.27.0 || ^0.28.0" fdir "^6.5.0" picomatch "^4.0.3" postcss "^8.5.6" @@ -5387,7 +5583,7 @@ word-wrap@^1.2.5: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -5396,7 +5592,7 @@ wrap-ansi@^7.0.0: wrap-ansi@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: ansi-styles "^6.1.0" @@ -5409,9 +5605,9 @@ wrappy@1: integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== ws@^8.18.3: - version "8.21.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951" - integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g== + version "8.21.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.3.tgz#660b4faddb6a3e575c86e078126919961f4de4fc" + integrity sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw== xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" @@ -5434,9 +5630,9 @@ yargs-parser@^21.1.1: integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + version "17.7.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.3.tgz#779dffe6bcafec596a7172e983289a588647faaa" + integrity sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g== dependencies: cliui "^8.0.1" escalade "^3.1.1" From b334e25f030e0adf5308183ef314eb39c1308b7a Mon Sep 17 00:00:00 2001 From: josuemc Date: Wed, 16 Sep 2026 17:04:47 -0300 Subject: [PATCH 4/5] =?UTF-8?q?Corre=C3=A7=C3=B5es=20da=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ess.ts => RequerAcessoEscritaVegetacao.ts} | 9 ++- src/application/vegetacao/index.ts | 10 +-- ...0_adiciona_unique_index_vegetacoes_nome.ts | 25 ++++++ .../VegetacaoCollectionKnexAdapter.ts | 79 +++++++++++++++---- .../vegetacao/cadastra-vegetacoes.test.ts | 29 ++++++- .../vegetacao/remove-vegetacoes.test.ts | 2 +- .../vegetacao/renomeia-vegetacoes.test.ts | 2 +- 7 files changed, 128 insertions(+), 28 deletions(-) rename src/application/vegetacao/{RequireVegetacaoWriteAccess.ts => RequerAcessoEscritaVegetacao.ts} (83%) create mode 100644 src/database/migration/20260916120000_adiciona_unique_index_vegetacoes_nome.ts diff --git a/src/application/vegetacao/RequireVegetacaoWriteAccess.ts b/src/application/vegetacao/RequerAcessoEscritaVegetacao.ts similarity index 83% rename from src/application/vegetacao/RequireVegetacaoWriteAccess.ts rename to src/application/vegetacao/RequerAcessoEscritaVegetacao.ts index 461f7873..9807cbfc 100644 --- a/src/application/vegetacao/RequireVegetacaoWriteAccess.ts +++ b/src/application/vegetacao/RequerAcessoEscritaVegetacao.ts @@ -1,5 +1,6 @@ import jwt from 'jsonwebtoken' +import { secret } from '@/config/security' import { HttpRequest, HttpResponse @@ -11,7 +12,7 @@ import { NextHandler, RequestHandler } from '@/library/http/Server' const ALLOWED_TIPOS_USUARIOS = new Set([1, 2]) -export class RequireVegetacaoWriteAccess implements RequestHandler { +export class ExigePermissaoEscritaVegetacao implements RequestHandler { async handle(request: HttpRequest, next: NextHandler): Promise { const authorization = request.headers.Authorization ?? request.headers.authorization @@ -25,7 +26,11 @@ export class RequireVegetacaoWriteAccess implements RequestHandler { } try { - const payload = jwt.verify(token, process.env.JWT_SECRET ?? 'test-secret') as { tipo_usuario_id?: unknown } + if (!secret) { + return new UnauthorizedError({ message: 'Token de autenticação inválido' }) + } + + const payload = jwt.verify(token, secret) as { tipo_usuario_id?: unknown } const tipoUsuarioId = Number(payload.tipo_usuario_id) if (!Number.isInteger(tipoUsuarioId) || !ALLOWED_TIPOS_USUARIOS.has(tipoUsuarioId)) { diff --git a/src/application/vegetacao/index.ts b/src/application/vegetacao/index.ts index 3892349a..f2147efe 100644 --- a/src/application/vegetacao/index.ts +++ b/src/application/vegetacao/index.ts @@ -14,16 +14,16 @@ import { CadastraVegetacaoController } from './CadastraVegetacaoController' import { ListaVegetacoesController } from './ListaVegetacoesController' import { RemoveVegetacaoController } from './RemoveVegetacaoController' import { RenomeiaVegetacaoController } from './RenomeiaVegetacaoController' -import { RequireVegetacaoWriteAccess } from './RequireVegetacaoWriteAccess' +import { ExigePermissaoEscritaVegetacao } from './RequerAcessoEscritaVegetacao' export function routes(knex: Knex): Route[] { const vegetacaoCollection = new VegetacaoCollectionKnexAdapter({ knex }) - const requireVegetacaoWriteAccess = new RequireVegetacaoWriteAccess() + const exigePermissaoEscritaVegetacao = new ExigePermissaoEscritaVegetacao() return [ { handlers: [ - requireVegetacaoWriteAccess, + exigePermissaoEscritaVegetacao, new CadastraVegetacaoController({ cadastraVegetacaoUseCase: new CadastraVegetacaoUseCase({ vegetacaoCollection }) }) @@ -51,7 +51,7 @@ export function routes(knex: Knex): Route[] { }, { handlers: [ - requireVegetacaoWriteAccess, + exigePermissaoEscritaVegetacao, new RenomeiaVegetacaoController({ renomeiaVegetacaoUseCase: new RenomeiaVegetacaoUseCase({ vegetacaoCollection }) }) @@ -61,7 +61,7 @@ export function routes(knex: Knex): Route[] { }, { handlers: [ - requireVegetacaoWriteAccess, + exigePermissaoEscritaVegetacao, new RemoveVegetacaoController({ removeVegetacaoUseCase: new RemoveVegetacaoUseCase({ vegetacaoCollection }) }) diff --git a/src/database/migration/20260916120000_adiciona_unique_index_vegetacoes_nome.ts b/src/database/migration/20260916120000_adiciona_unique_index_vegetacoes_nome.ts new file mode 100644 index 00000000..a505b65f --- /dev/null +++ b/src/database/migration/20260916120000_adiciona_unique_index_vegetacoes_nome.ts @@ -0,0 +1,25 @@ +import { Knex } from 'knex' + +export async function run(knex: Knex): Promise { + const tableExists = await knex.schema.hasTable('vegetacoes') + + if (!tableExists) { + return + } + + const indexExists = await knex.raw(` + SELECT 1 + FROM pg_indexes + WHERE schemaname = current_schema() + AND tablename = 'vegetacoes' + AND indexname = 'vegetacoes_nome_unique' + LIMIT 1 + `) + + if (indexExists.rowCount === 0 || indexExists.rows?.length === 0) { + await knex.raw(` + CREATE UNIQUE INDEX IF NOT EXISTS vegetacoes_nome_unique + ON vegetacoes (LOWER(nome)) + `) + } +} diff --git a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts index fa095562..e4fe5e25 100644 --- a/src/infrastructure/VegetacaoCollectionKnexAdapter.ts +++ b/src/infrastructure/VegetacaoCollectionKnexAdapter.ts @@ -9,26 +9,75 @@ import { CollectionError } from './error/CollectionError' const DUPLICATE_VEGETACAO_MESSAGE = 'Já existe uma vegetação com esse nome' const VEGETACAO_IN_USE_MESSAGE = 'Vegetação está em uso e não pode ser removida' +function normalizeErrorString(value: unknown): string { + if (value === undefined || value === null) { + return '' + } + + if (typeof value === 'string') { + return value.toLowerCase() + } + + if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') { + return String(value).toLowerCase() + } + + return Object.prototype.toString.call(value).toLowerCase() +} + function isDuplicateVegetacaoError(error: unknown): boolean { - const code = typeof error === 'object' && error !== null && 'code' in error ? String((error as { code?: unknown }).code) : '' - const details = typeof error === 'object' && error !== null && 'detail' in error ? String((error as { detail?: unknown }).detail) : '' - const message = typeof error === 'object' && error !== null && 'message' in error ? String((error as { message?: unknown }).message) : '' - const constraint = typeof error === 'object' && error !== null && 'constraint' in error ? String((error as { constraint?: unknown }).constraint) : '' + const code = typeof error === 'object' && error !== null && 'code' in error + ? String((error as { code?: unknown }).code) + : '' + const details = typeof error === 'object' && error !== null && 'detail' in error + ? String((error as { detail?: unknown }).detail) + : '' + const message = typeof error === 'object' && error !== null && 'message' in error + ? String((error as { message?: unknown }).message) + : '' + const constraint = typeof error === 'object' && error !== null && 'constraint' in error + ? String((error as { constraint?: unknown }).constraint) + : '' + const normalized = [ + code, + details, + message, + constraint + ].map(normalizeErrorString).join(' ') return code === '23505' + || code === 'ER_DUP_ENTRY' || (constraint.toLowerCase().includes('vegetacoes') && constraint.toLowerCase().includes('nome')) || details.toLowerCase().includes('already exists') || message.toLowerCase().includes('duplicate key value violates unique constraint') + || message.toLowerCase().includes('duplicate entry') + || normalized.includes('unique constraint') + || normalized.includes('already exists') } function isVegetacaoInUseError(error: unknown): boolean { - const code = typeof error === 'object' && error !== null && 'code' in error ? String((error as { code?: unknown }).code) : '' - const message = typeof error === 'object' && error !== null && 'message' in error ? String((error as { message?: unknown }).message) : '' - const constraint = typeof error === 'object' && error !== null && 'constraint' in error ? String((error as { constraint?: unknown }).constraint) : '' + const code = typeof error === 'object' && error !== null && 'code' in error + ? String((error as { code?: unknown }).code) + : '' + const message = typeof error === 'object' && error !== null && 'message' in error + ? String((error as { message?: unknown }).message) + : '' + const constraint = typeof error === 'object' && error !== null && 'constraint' in error + ? String((error as { constraint?: unknown }).constraint) + : '' + const normalized = [ + code, + message, + constraint + ].map(normalizeErrorString).join(' ') return code === '23503' - || message.toLowerCase().includes('violates foreign key constraint') - || message.toLowerCase().includes('is still referenced from table') + || code === 'ER_ROW_IS_REFERENCED_2' + || normalized.includes('violates foreign key constraint') + || normalized.includes('is still referenced from table') + || normalized.includes('cannot delete or update a parent row') + || normalized.includes('foreign key constraint fails') + || normalized.includes('still referenced') || constraint.toLowerCase().includes('vegetacao') } @@ -56,8 +105,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { const vegetacao = await query.first() return Either.right(vegetacao ?? null) } catch (error) { - const cause = error instanceof Error ? error : new Error(String(error)) - return Either.left(new CollectionError({ message: cause.message, cause })) + return Either.left(new CollectionError({ message: 'Erro ao buscar vegetação por nome', cause: error })) } } @@ -111,8 +159,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE, cause: error })) } - const cause = error instanceof Error ? error : new Error(String(error)) - return Either.left(new CollectionError({ message: cause.message, cause })) + return Either.left(new CollectionError({ message: 'Erro ao criar vegetação', cause: error })) } } @@ -140,8 +187,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.left(new CollectionError({ message: DUPLICATE_VEGETACAO_MESSAGE, cause: error })) } - const cause = error instanceof Error ? error : new Error(String(error)) - return Either.left(new CollectionError({ message: cause.message, cause })) + return Either.left(new CollectionError({ message: 'Erro ao atualizar vegetação', cause: error })) } } @@ -154,8 +200,7 @@ export class VegetacaoCollectionKnexAdapter implements VegetacaoCollection { return Either.left(new CollectionError({ message: VEGETACAO_IN_USE_MESSAGE, cause: error })) } - const cause = error instanceof Error ? error : new Error(String(error)) - return Either.left(new CollectionError({ message: cause.message, cause })) + return Either.left(new CollectionError({ message: 'Erro ao remover vegetação', cause: error })) } } } diff --git a/test/integration/vegetacao/cadastra-vegetacoes.test.ts b/test/integration/vegetacao/cadastra-vegetacoes.test.ts index 186d2364..a26e79fc 100644 --- a/test/integration/vegetacao/cadastra-vegetacoes.test.ts +++ b/test/integration/vegetacao/cadastra-vegetacoes.test.ts @@ -3,7 +3,8 @@ import { afterAll, describe, expect, - test + test, + vi } from 'vitest' import { createTestApp } from '../setup/app-factory' @@ -11,7 +12,7 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } const buildAuthHeader = () => { - const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET as string) return { Authorization: `Bearer ${token}` } } @@ -38,6 +39,30 @@ describe('POST /api/v2/vegetacoes', () => { } }) + test('rejeita token assinado com segredo de teste quando o JWT_SECRET não está configurado', async () => { + const originalSecret = process.env.JWT_SECRET + vi.resetModules() + delete process.env.JWT_SECRET + + try { + const { createTestApp } = await import('../setup/app-factory') + const { agent: isolatedAgent, knex: isolatedKnex } = createTestApp() + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, 'test-secret') + const response = await isolatedAgent.post('/api/v2/vegetacoes').set({ Authorization: `Bearer ${token}` }).send({ nome: 'NOME SEM SECRET' }).expect(401) + const body = response.body as { error: { message: string } } + + expect(body.error.message).toMatch(/token de autenticação inválido|token expirado|invalid/i) + await isolatedKnex.destroy() + } finally { + if (originalSecret === undefined) { + delete process.env.JWT_SECRET + } else { + process.env.JWT_SECRET = originalSecret + } + vi.resetModules() + } + }) + test('retorna 400 quando o nome está vazio', async () => { const response = await agent.post('/api/v2/vegetacoes').set(buildAuthHeader()).send({ nome: ' ' }).expect(400) const body = response.body as { error: { message: string } } diff --git a/test/integration/vegetacao/remove-vegetacoes.test.ts b/test/integration/vegetacao/remove-vegetacoes.test.ts index 9ca0e98c..4d4d333b 100644 --- a/test/integration/vegetacao/remove-vegetacoes.test.ts +++ b/test/integration/vegetacao/remove-vegetacoes.test.ts @@ -11,7 +11,7 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } const buildAuthHeader = () => { - const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET as string) return { Authorization: `Bearer ${token}` } } diff --git a/test/integration/vegetacao/renomeia-vegetacoes.test.ts b/test/integration/vegetacao/renomeia-vegetacoes.test.ts index 82571585..397f3f1a 100644 --- a/test/integration/vegetacao/renomeia-vegetacoes.test.ts +++ b/test/integration/vegetacao/renomeia-vegetacoes.test.ts @@ -11,7 +11,7 @@ import { createTestApp } from '../setup/app-factory' type Vegetacao = { id: number; nome: string } const buildAuthHeader = () => { - const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET ?? 'test-secret') + const token = jwt.sign({ id: 1, tipo_usuario_id: 1 }, process.env.JWT_SECRET as string) return { Authorization: `Bearer ${token}` } } From a14b7efa03646e876f81c19fc00f63541294ff4a Mon Sep 17 00:00:00 2001 From: josuemc Date: Wed, 16 Sep 2026 17:10:10 -0300 Subject: [PATCH 5/5] =?UTF-8?q?corre=C3=A7=C3=B5es=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/integration/setup/load-env.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/integration/setup/load-env.ts b/test/integration/setup/load-env.ts index a80f0212..934114e6 100644 --- a/test/integration/setup/load-env.ts +++ b/test/integration/setup/load-env.ts @@ -8,4 +8,6 @@ try { // In CI, environment variables are injected directly into the process } +process.env.JWT_SECRET ??= 'test-secret' + mkdirSync(path.resolve(process.cwd(), 'uploads'), { recursive: true })