From 60d6755b2223bef0bf8622232542b20818bee3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Tue, 21 Jan 2025 17:58:11 +0900 Subject: [PATCH 01/34] =?UTF-8?q?=E2=9C=85=20test:=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=EB=90=9C=20StockService=EC=9D=98=20=EA=B5=AC=EC=A1=B0=EC=97=90?= =?UTF-8?q?=20=EB=A7=9E=EA=B2=8C=20stock.service.spec.ts=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 불필요한 typeorm 메서드 mocking 제거 - datasource 대신 repository를 mock해서 사용 --- .../backend/src/stock/stock.service.spec.ts | 138 +++++++----------- 1 file changed, 56 insertions(+), 82 deletions(-) diff --git a/packages/backend/src/stock/stock.service.spec.ts b/packages/backend/src/stock/stock.service.spec.ts index 95502e65..9ad54a33 100644 --- a/packages/backend/src/stock/stock.service.spec.ts +++ b/packages/backend/src/stock/stock.service.spec.ts @@ -1,83 +1,31 @@ import { plainToInstance } from 'class-transformer'; -import { anyString, anything, instance, mock, verify, when } from 'ts-mockito'; -import { - DataSource, - EntityManager, - Repository, - SelectQueryBuilder, -} from 'typeorm'; +import { anyNumber, anyString, instance, mock, verify, when } from 'ts-mockito'; import { Logger } from 'winston'; import { Stock } from './domain/stock.entity'; import { StockService } from './stock.service'; -import { UserStock } from '@/stock/domain/userStock.entity'; import { StockRankResponses, StocksResponse } from '@/stock/dto/stock.response'; import { User } from '@/user/domain/user.entity'; -import { - GainersSortStrategy, - LosersSortStrategy, - ViewsSortStrategy, -} from './strategy/StockSortStrategy'; +import { StockRepository } from './repository/stock.repository'; +import { UserStockRepository } from './repository/userStock.repository'; describe('StockService 테스트', () => { // mocked classes let mockLogger: Logger; - let mockDataSource: DataSource; - let mockManager: EntityManager; - let mockQueryBuilder: SelectQueryBuilder; - let mockRepository: Repository; - let mockViewsSortStrategy: ViewsSortStrategy; - let mockGainersSortStrategy: GainersSortStrategy; - let mockLosersSortStrategy: LosersSortStrategy; + let mockStockRepository: StockRepository; + let mockUserStockRepository: UserStockRepository; // test target let stockService: StockService; beforeEach(() => { - mockDataSource = mock(DataSource); - mockManager = mock(EntityManager); - mockQueryBuilder = mock(SelectQueryBuilder); - mockRepository = mock(Repository); - + mockStockRepository = mock(StockRepository); + mockUserStockRepository = mock(UserStockRepository); mockLogger = mock(Logger); - mockViewsSortStrategy = mock(ViewsSortStrategy); - mockGainersSortStrategy = mock(GainersSortStrategy); - mockLosersSortStrategy = mock(LosersSortStrategy); stockService = new StockService( - instance(mockDataSource), + instance(mockStockRepository), + instance(mockUserStockRepository), instance(mockLogger), - instance(mockViewsSortStrategy), - instance(mockGainersSortStrategy), - instance(mockLosersSortStrategy), - ); - - // stock service 내부에서 사용하는 typeorm 메서드 mocking - when(mockDataSource.transaction(anything())).thenCall(async (callback) => { - return await callback(instance(mockManager)); - }); - when(mockQueryBuilder.leftJoin(anything(), anything(), anything())) - .thenReturn(instance(mockQueryBuilder)) - .thenReturn(instance(mockQueryBuilder)); - when(mockQueryBuilder.select(anything())).thenReturn( - instance(mockQueryBuilder), - ); - when(mockQueryBuilder.orderBy(anything(), anything())).thenReturn( - instance(mockQueryBuilder), - ); - when(mockQueryBuilder.limit(anything())).thenReturn( - instance(mockQueryBuilder), - ); - when(mockRepository.createQueryBuilder(anyString())).thenReturn( - instance(mockQueryBuilder), - ); - when(mockDataSource.getRepository(anything())).thenReturn( - instance(mockRepository), - ); - when( - mockQueryBuilder.innerJoinAndSelect(anyString(), anyString()), - ).thenReturn(instance(mockQueryBuilder)); - when(mockQueryBuilder.where(anyString(), anything())).thenReturn( - instance(mockQueryBuilder), ); }); @@ -85,19 +33,19 @@ describe('StockService 테스트', () => { test('주식의 조회수를 증가시킨다.', async () => { // given const stockId = '005930'; - when(mockManager.exists(Stock, anything())).thenResolve(true); + when(mockStockRepository.existsById(anyString())).thenResolve(true); // when await stockService.increaseView(stockId); // then - verify(mockManager.exists(Stock, anything())).once(); - verify(mockManager.increment(Stock, anything(), 'views', 1)).once(); + verify(mockStockRepository.existsById(anyString())).once(); + verify(mockStockRepository.increaseView(anyString())).once(); }); test('존재하지 않는 주식의 조회수를 증가시키려 하면 예외가 발생한다.', async () => { // given - when(mockManager.exists(Stock, anything())).thenResolve(false); + when(mockStockRepository.existsById(anyString())).thenResolve(false); // when & then await expect(() => stockService.increaseView('1')).rejects.toThrow( @@ -111,22 +59,24 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - when(mockManager.exists(Stock, anything())).thenResolve(true); - when(mockManager.exists(UserStock, anything())).thenResolve(false); + when(mockStockRepository.existsById(anyString())).thenResolve(true); + when( + mockUserStockRepository.exists(anyNumber(), anyString()), + ).thenResolve(false); // when await stockService.createUserStock(userId, stockId); // then - verify(mockManager.exists(Stock, anything())).times(1); - verify(mockManager.exists(UserStock, anything())).times(1); - verify(mockManager.insert(UserStock, anything())).once(); + verify(mockStockRepository.existsById(anyString())).times(1); + verify(mockUserStockRepository.exists(anyNumber(), anyString())).times(1); + verify(mockUserStockRepository.create(anyNumber(), anyString())).once(); }); test('유저 주식을 추가할 때 존재하지 않는 주식이면 예외가 발생한다.', async () => { // given const userId = 1; - when(mockManager.exists(Stock, anything())).thenResolve(false); + when(mockStockRepository.existsById(anyString())).thenResolve(false); // when & then await expect(() => @@ -138,8 +88,10 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - when(mockManager.exists(Stock, anything())).thenResolve(true); - when(mockManager.exists(UserStock, anything())).thenResolve(true); + when(mockStockRepository.existsById(anyString())).thenResolve(true); + when( + mockUserStockRepository.exists(anyNumber(), anyString()), + ).thenResolve(true); // when & then await expect(async () => @@ -151,7 +103,12 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - when(mockManager.findOne(UserStock, anything())).thenResolve({ + when( + mockUserStockRepository.findByUserIdAndStockId( + anyNumber(), + anyString(), + ), + ).thenResolve({ id: 1, user: { id: userId } as User, stock: { id: stockId } as Stock, @@ -165,14 +122,24 @@ describe('StockService 테스트', () => { await stockService.deleteUserStock(userId, stockId); // then - verify(mockManager.findOne(UserStock, anything())).once(); - verify(mockManager.delete(UserStock, anything())).once(); + verify( + mockUserStockRepository.findByUserIdAndStockId( + anyNumber(), + anyString(), + ), + ).once(); + verify(mockUserStockRepository.delete(anyNumber())).once(); }); test('유저 주식을 삭제 시 존재하지 않는 유저 주식이면 예외가 발생한다.', async () => { // given const userId = 1; - when(mockManager.findOne(UserStock, anything())).thenResolve(null); + when( + mockUserStockRepository.findByUserIdAndStockId( + anyNumber(), + anyString(), + ), + ).thenResolve(null); // when & then await expect(() => @@ -185,7 +152,12 @@ describe('StockService 테스트', () => { const userId = 1; const stockId = '005930'; const notOwnerUserId = 2; - when(mockManager.findOne(UserStock, anything())).thenResolve({ + when( + mockUserStockRepository.findByUserIdAndStockId( + anyNumber(), + anyString(), + ), + ).thenResolve({ id: 1, user: { id: userId } as User, stock: { id: stockId } as Stock, @@ -205,7 +177,9 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - when(mockManager.exists(UserStock, anything())).thenResolve(true); + when( + mockUserStockRepository.exists(anyNumber(), anyString()), + ).thenResolve(true); // when const result = await stockService.isUserStockOwner(stockId, userId); @@ -250,7 +224,7 @@ describe('StockService 테스트', () => { test('주식 조회수 기준 상위 데이터를 반환한다.', async () => { //given const limit = 5; - when(mockQueryBuilder.getRawMany()).thenResolve(stockList); + when(mockStockRepository.findByTopViews(limit)).thenResolve(stockList); // when const queryResult = await stockService.getTopStocksByViews(limit); @@ -264,13 +238,13 @@ describe('StockService 테스트', () => { test('주식 상승률 기준 상위 데이터를 반환한다.', async () => { // given const limit = 20; - when(mockQueryBuilder.getRawMany()).thenResolve(stockList); + when(mockStockRepository.findByTopGainers(limit)).thenResolve(stockList); // when const queryResult = await stockService.getTopStocksByGainers(limit); // then - verify(mockQueryBuilder.getRawMany()).once(); + verify(mockStockRepository.findByTopGainers(anyNumber())).once(); expect(queryResult).toEqual(new StockRankResponses(stockList)); }); }); From 26ff1227bc48a3878160e581cdd5488b7d0e8ffd Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Wed, 22 Jan 2025 14:17:54 +0900 Subject: [PATCH 02/34] =?UTF-8?q?=E2=9C=A8=20feat:=20guest=EC=9D=98=20stat?= =?UTF-8?q?us=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20GuestStatu?= =?UTF-8?q?sGuard=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: #29 --- .../src/auth/tester/guard/guestStatusGuard.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 packages/backend/src/auth/tester/guard/guestStatusGuard.ts diff --git a/packages/backend/src/auth/tester/guard/guestStatusGuard.ts b/packages/backend/src/auth/tester/guard/guestStatusGuard.ts new file mode 100644 index 00000000..e66c6930 --- /dev/null +++ b/packages/backend/src/auth/tester/guard/guestStatusGuard.ts @@ -0,0 +1,12 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { Observable } from 'rxjs'; + +@Injectable() +export class GuestStatusGuard implements CanActivate { + canActivate( + context: ExecutionContext, + ): boolean | Promise | Observable { + const request = context.switchToHttp().getRequest(); + return !request.user; + } +} From c68ed2d68e2a22720e2aac8b30881a76a861f828 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Wed, 22 Jan 2025 14:29:26 +0900 Subject: [PATCH 03/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20guestSta?= =?UTF-8?q?tusGuard=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=A5=BC=20StatusGuar?= =?UTF-8?q?d=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: #29 --- .../{tester/guard/guestStatusGuard.ts => session/StatusGuard.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/backend/src/auth/{tester/guard/guestStatusGuard.ts => session/StatusGuard.ts} (100%) diff --git a/packages/backend/src/auth/tester/guard/guestStatusGuard.ts b/packages/backend/src/auth/session/StatusGuard.ts similarity index 100% rename from packages/backend/src/auth/tester/guard/guestStatusGuard.ts rename to packages/backend/src/auth/session/StatusGuard.ts From afa8e80c49b645f96913d85b19eb55c22057de71 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 23 Jan 2025 03:41:13 +0900 Subject: [PATCH 04/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20validate?= =?UTF-8?q?UserExists=ED=95=A8=EC=88=98=20=EC=86=8D=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 if문을 이용해 BadRequestException을 던지는 방식을 try-catch문으로 변경 --- packages/backend/src/user/user.service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/user/user.service.ts b/packages/backend/src/user/user.service.ts index d5c51eb8..7af57030 100644 --- a/packages/backend/src/user/user.service.ts +++ b/packages/backend/src/user/user.service.ts @@ -157,7 +157,6 @@ export class UserService { .select('MAX(user.oauthId)', 'max') .where('user.type = :oauthType', { oauthType }) .getRawOne(); - return result ? Number(result.max) : 1; } @@ -166,8 +165,10 @@ export class UserService { oauthId: string, manager: EntityManager, ) { - if (await manager.exists(User, { where: { oauthId, type } })) { - throw new BadRequestException('user already exists'); + try { + await manager.exists(User, { where: { oauthId, type } }); + } catch (err) { + throw new BadRequestException(err); } } } From abb39fec14e3f086e486d8ebc136167f4c4969e4 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 23 Jan 2025 04:38:22 +0900 Subject: [PATCH 05/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EA=B2=8C=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - oauthId 비교 로직에서 문자열 비교이던 부분을 숫자 비교가 되도록 변경했음 --- packages/backend/src/user/user.service.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/user/user.service.ts b/packages/backend/src/user/user.service.ts index 7af57030..a9bae6fc 100644 --- a/packages/backend/src/user/user.service.ts +++ b/packages/backend/src/user/user.service.ts @@ -18,7 +18,8 @@ type RegisterRequest = Required< @Injectable() export class UserService { - constructor(private readonly dataSource: DataSource) {} + constructor(private readonly dataSource: DataSource) { + } async register({ nickname, email, type, oauthId }: RegisterRequest) { return await this.dataSource.transaction(async (manager) => { @@ -154,9 +155,10 @@ export class UserService { private async getMaxOauthId(oauthType: OauthType) { const result = await this.dataSource.manager .createQueryBuilder(User, 'user') - .select('MAX(user.oauthId)', 'max') + .select('MAX(CAST(user.oauthId AS SIGNED))', 'max') .where('user.type = :oauthType', { oauthType }) .getRawOne(); + console.log(result.max); return result ? Number(result.max) : 1; } From 3dbe31aaffb5b12923703b54872f99c5a00ce4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Thu, 23 Jan 2025 12:34:56 +0900 Subject: [PATCH 06/34] =?UTF-8?q?=E2=9C=85=20test:=20stock=20service=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주식 정렬 전략 예외 케이스 추가 - mock된 repository에 대한 파라미터 입력값을 aynthing()에서 실제값으로 변경 - 테스트 분류화 개선 --- .../backend/src/stock/stock.service.spec.ts | 243 ++++++++++-------- 1 file changed, 141 insertions(+), 102 deletions(-) diff --git a/packages/backend/src/stock/stock.service.spec.ts b/packages/backend/src/stock/stock.service.spec.ts index 9ad54a33..46851cd6 100644 --- a/packages/backend/src/stock/stock.service.spec.ts +++ b/packages/backend/src/stock/stock.service.spec.ts @@ -1,9 +1,13 @@ import { plainToInstance } from 'class-transformer'; -import { anyNumber, anyString, instance, mock, verify, when } from 'ts-mockito'; +import { instance, mock, verify, when } from 'ts-mockito'; import { Logger } from 'winston'; import { Stock } from './domain/stock.entity'; import { StockService } from './stock.service'; -import { StockRankResponses, StocksResponse } from '@/stock/dto/stock.response'; +import { + StockRankResponses, + StockSearchResponse, + StocksResponse, +} from '@/stock/dto/stock.response'; import { User } from '@/user/domain/user.entity'; import { StockRepository } from './repository/stock.repository'; import { UserStockRepository } from './repository/userStock.repository'; @@ -33,54 +37,147 @@ describe('StockService 테스트', () => { test('주식의 조회수를 증가시킨다.', async () => { // given const stockId = '005930'; - when(mockStockRepository.existsById(anyString())).thenResolve(true); + when(mockStockRepository.existsById(stockId)).thenResolve(true); // when await stockService.increaseView(stockId); // then - verify(mockStockRepository.existsById(anyString())).once(); - verify(mockStockRepository.increaseView(anyString())).once(); + verify(mockStockRepository.existsById(stockId)).once(); + verify(mockStockRepository.increaseView(stockId)).once(); }); test('존재하지 않는 주식의 조회수를 증가시키려 하면 예외가 발생한다.', async () => { // given - when(mockStockRepository.existsById(anyString())).thenResolve(false); + const nonExistStock = '1'; + when(mockStockRepository.existsById(nonExistStock)).thenResolve(false); // when & then - await expect(() => stockService.increaseView('1')).rejects.toThrow( - 'stock not found', + await expect(() => + stockService.increaseView(nonExistStock), + ).rejects.toThrow('stock not found'); + }); + }); + + describe('주식 정렬 조회', () => { + const stockList = [ + { + id: '005930', + name: '삼성전자', + currentPrice: '100000.0', + changeRate: '2.5', + volume: '500000', + marketCap: '500000000000.00', + }, + { + id: 'A051910', + name: 'LG화학', + currentPrice: '75000.0', + changeRate: '-1.2', + volume: '300000', + marketCap: '20000000000.00', + }, + ]; + + test('주식 조회수 기준 상위 데이터를 반환한다.', async () => { + //given + const limit = 5; + const sortBy = 'views'; + when(mockStockRepository.findByTopViews(limit)).thenResolve(stockList); + + // when + const queryResult = await stockService.getTopStocks(sortBy, limit); + + // then + expect(queryResult).toStrictEqual( + plainToInstance(StocksResponse, queryResult), ); }); + + test('주식 상승률 기준 상위 데이터를 반환한다.', async () => { + // given + const limit = 20; + const sortBy = 'gainers'; + when(mockStockRepository.findByTopGainers(limit)).thenResolve(stockList); + + // when + const queryResult = await stockService.getTopStocks(sortBy, limit); + + // then + verify(mockStockRepository.findByTopGainers(limit)).once(); + expect(queryResult).toEqual(new StockRankResponses(stockList)); + }); + + test('주식 하락률 기준 상위 데이터를 반환한다.', async () => { + // given + const limit = 20; + const sortBy = 'losers'; + when(mockStockRepository.findByTopLosers(limit)).thenResolve(stockList); + + // when + const queryResult = await stockService.getTopStocks(sortBy, limit); + + // then + verify(mockStockRepository.findByTopLosers(limit)).once(); + expect(queryResult).toEqual(new StockRankResponses(stockList)); + }); + + test('주식 정렬 전략이 잘못된 요청은 예외가 발생한다.', async () => { + // given + const limit = 20; + const wrongSortBy = 'infinite'; + + // when & then + await expect(() => + stockService.getTopStocks(wrongSortBy, limit), + ).rejects.toThrow(`Unknown sort strategy: ${wrongSortBy}`); + }); + }); + + describe('주식 정보 조회', () => { + test('주식 이름으로 주식을 검색한다.', async () => { + // given + const stockName = '삼성'; + const mockStocks = [ + { id: '005930', name: '삼성전자', views: 3 } as Stock, + { id: '006400', name: '삼성SDI', views: 1 } as Stock, + ]; + when(mockStockRepository.findByName(stockName)).thenResolve(mockStocks); + + // when + const result = await stockService.searchStock(stockName); + + // then + expect(result).toEqual(new StockSearchResponse(mockStocks)); + }); }); - describe('유저 주식 관리', () => { + describe('유저 주식 추가', () => { test('유저 주식을 추가한다.', async () => { // given const userId = 1; const stockId = '005930'; - when(mockStockRepository.existsById(anyString())).thenResolve(true); - when( - mockUserStockRepository.exists(anyNumber(), anyString()), - ).thenResolve(false); + when(mockStockRepository.existsById(stockId)).thenResolve(true); + when(mockUserStockRepository.exists(userId, stockId)).thenResolve(false); // when await stockService.createUserStock(userId, stockId); // then - verify(mockStockRepository.existsById(anyString())).times(1); - verify(mockUserStockRepository.exists(anyNumber(), anyString())).times(1); - verify(mockUserStockRepository.create(anyNumber(), anyString())).once(); + verify(mockStockRepository.existsById(stockId)).once(); + verify(mockUserStockRepository.exists(userId, stockId)).once(); + verify(mockUserStockRepository.create(userId, stockId)).once(); }); test('유저 주식을 추가할 때 존재하지 않는 주식이면 예외가 발생한다.', async () => { // given const userId = 1; - when(mockStockRepository.existsById(anyString())).thenResolve(false); + const nonExistStock = 'A'; + when(mockStockRepository.existsById(nonExistStock)).thenResolve(false); // when & then await expect(() => - stockService.createUserStock(userId, 'A'), + stockService.createUserStock(userId, nonExistStock), ).rejects.toThrow('not exists stock'); }); @@ -88,62 +185,55 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - when(mockStockRepository.existsById(anyString())).thenResolve(true); - when( - mockUserStockRepository.exists(anyNumber(), anyString()), - ).thenResolve(true); + when(mockStockRepository.existsById(stockId)).thenResolve(true); + when(mockUserStockRepository.exists(userId, stockId)).thenResolve(true); // when & then await expect(async () => stockService.createUserStock(userId, stockId), ).rejects.toThrow('user stock already exists'); }); + }); + describe('유저 주식 삭제', () => { test('유저 주식을 삭제한다.', async () => { // given const userId = 1; const stockId = '005930'; - when( - mockUserStockRepository.findByUserIdAndStockId( - anyNumber(), - anyString(), - ), - ).thenResolve({ - id: 1, + const userStock = { + id: 10, user: { id: userId } as User, stock: { id: stockId } as Stock, date: { createdAt: new Date(), updatedAt: new Date(), }, - }); + }; + when( + mockUserStockRepository.findByUserIdAndStockId(userId, stockId), + ).thenResolve(userStock); // when await stockService.deleteUserStock(userId, stockId); // then verify( - mockUserStockRepository.findByUserIdAndStockId( - anyNumber(), - anyString(), - ), + mockUserStockRepository.findByUserIdAndStockId(userId, stockId), ).once(); - verify(mockUserStockRepository.delete(anyNumber())).once(); + verify(mockUserStockRepository.delete(userStock.id)).once(); }); test('유저 주식을 삭제 시 존재하지 않는 유저 주식이면 예외가 발생한다.', async () => { // given const userId = 1; + const nonUserStock = '005930'; when( - mockUserStockRepository.findByUserIdAndStockId( - anyNumber(), - anyString(), - ), + mockUserStockRepository.findByUserIdAndStockId(userId, nonUserStock), ).thenResolve(null); // when & then await expect(() => - stockService.deleteUserStock(userId, '13'), + stockService.deleteUserStock(userId, nonUserStock), ).rejects.toThrow('user stock not found'); }); @@ -151,35 +241,32 @@ describe('StockService 테스트', () => { // given const userId = 1; const stockId = '005930'; - const notOwnerUserId = 2; - when( - mockUserStockRepository.findByUserIdAndStockId( - anyNumber(), - anyString(), - ), - ).thenResolve({ - id: 1, - user: { id: userId } as User, + const userStock = { + id: 13, + user: { id: 2 } as User, stock: { id: stockId } as Stock, date: { createdAt: new Date(), updatedAt: new Date(), }, - }); + }; + when( + mockUserStockRepository.findByUserIdAndStockId(userId, stockId), + ).thenResolve(userStock); // when & then await expect(() => - stockService.deleteUserStock(notOwnerUserId, stockId), + stockService.deleteUserStock(userId, stockId), ).rejects.toThrow('you are not owner of user stock'); }); + }); + describe('유저 주식 조회', () => { test('소유 주식인지 확인한다.', async () => { // given const userId = 1; const stockId = '005930'; - when( - mockUserStockRepository.exists(anyNumber(), anyString()), - ).thenResolve(true); + when(mockUserStockRepository.exists(userId, stockId)).thenResolve(true); // when const result = await stockService.isUserStockOwner(stockId, userId); @@ -200,52 +287,4 @@ describe('StockService 테스트', () => { expect(result).toBe(false); }); }); - - describe('주식 검색', () => { - const stockList = [ - { - id: '005930', - name: '삼성전자', - currentPrice: '100000.0', - changeRate: '2.5', - volume: '500000', - marketCap: '500000000000.00', - }, - { - id: 'A051910', - name: 'LG화학', - currentPrice: '75000.0', - changeRate: '-1.2', - volume: '300000', - marketCap: '20000000000.00', - }, - ]; - - test('주식 조회수 기준 상위 데이터를 반환한다.', async () => { - //given - const limit = 5; - when(mockStockRepository.findByTopViews(limit)).thenResolve(stockList); - - // when - const queryResult = await stockService.getTopStocksByViews(limit); - - // then - expect(queryResult).toStrictEqual( - plainToInstance(StocksResponse, queryResult), - ); - }); - - test('주식 상승률 기준 상위 데이터를 반환한다.', async () => { - // given - const limit = 20; - when(mockStockRepository.findByTopGainers(limit)).thenResolve(stockList); - - // when - const queryResult = await stockService.getTopStocksByGainers(limit); - - // then - verify(mockStockRepository.findByTopGainers(anyNumber())).once(); - expect(queryResult).toEqual(new StockRankResponses(stockList)); - }); - }); }); From 6a62877b7f49b1f861c4bc1c73da4730621ef4fa Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 23 Jan 2025 13:21:11 +0900 Subject: [PATCH 07/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용하지 않는 guestStatusGuard.ts 파일 삭제 --- packages/backend/src/auth/session/StatusGuard.ts | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 packages/backend/src/auth/session/StatusGuard.ts diff --git a/packages/backend/src/auth/session/StatusGuard.ts b/packages/backend/src/auth/session/StatusGuard.ts deleted file mode 100644 index e66c6930..00000000 --- a/packages/backend/src/auth/session/StatusGuard.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; -import { Observable } from 'rxjs'; - -@Injectable() -export class GuestStatusGuard implements CanActivate { - canActivate( - context: ExecutionContext, - ): boolean | Promise | Observable { - const request = context.switchToHttp().getRequest(); - return !request.user; - } -} From 8ae933ab18673febbb6589cf6c42ce9432d2742a Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 23 Jan 2025 13:24:20 +0900 Subject: [PATCH 08/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20console.log=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/user/user.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend/src/user/user.service.ts b/packages/backend/src/user/user.service.ts index a9bae6fc..d246885f 100644 --- a/packages/backend/src/user/user.service.ts +++ b/packages/backend/src/user/user.service.ts @@ -158,7 +158,6 @@ export class UserService { .select('MAX(CAST(user.oauthId AS SIGNED))', 'max') .where('user.type = :oauthType', { oauthType }) .getRawOne(); - console.log(result.max); return result ? Number(result.max) : 1; } From 5192a81da649e0159aaf597c07705ae359867fa9 Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Tue, 4 Feb 2025 14:07:52 +0900 Subject: [PATCH 09/34] =?UTF-8?q?docs:=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EC=9A=94=EC=95=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/docs/serviceExplain.md | 170 ++++++++++++++++++++++++ packages/backend/serviceExplain.md | 0 2 files changed, 170 insertions(+) create mode 100644 packages/backend/docs/serviceExplain.md create mode 100644 packages/backend/serviceExplain.md diff --git a/packages/backend/docs/serviceExplain.md b/packages/backend/docs/serviceExplain.md new file mode 100644 index 00000000..d5ed935f --- /dev/null +++ b/packages/backend/docs/serviceExplain.md @@ -0,0 +1,170 @@ +# 서비스 설명서 + +## 1. 서비스 구조 + +### 1.1 StockService + +- **역할**: 주식 기본 정보 관리 +- **주요 기능**: + - 주식 검색 + - 인기 주식 순위 관리 + - 사용자 관심 주식 관리 + - 조회수 관리 +- **관련 테이블**: stock, user_stock + +### 1.2 StockDetailService + +- **역할**: 주식 상세 정보 관리 +- **주요 기능**: + - 시가총액, EPS, PER 정보 제공 + - 52주 최고가/최저가 정보 제공 +- **관련 테이블**: stock_detail + +### 1.3 KoreaStockInfoService + +- **역할**: 주식 마스터 데이터 수집 +- **실행 시간**: 매일 오전 9시, 자정 (월-금) +- **주요 기능**: + - KOSDAQ/KOSPI 마스터 데이터 다운로드 + - 주식 기본 정보 업데이트 +- **관련 테이블**: stock + +### 1.4 OpenapiLiveDataService + +- **역할**: 실시간 주가 데이터 수집 +- **실행 주기**: 1분 +- **주요 기능**: + - 실시간 가격 정보 수집 + - 거래량 데이터 수집 + - 등락률 계산 +- **관련 테이블**: stock_live_data + +## 2. 크론 작업 + +### 2.1 데이터 수집 + +| 작업 | 실행 시간 | 담당 서비스 | +| ------------------ | -------------------- | --------------------------- | +| 마스터 데이터 수집 | 09:00, 00:00 (월-금) | KoreaStockInfoService | +| 실시간 데이터 수집 | 매 1분 (09:00-15:30) | OpenapiLiveDataService | +| 일일 통계 집계 | 15:40 (장 마감 후) | StockDataAggregationService | + +### 2.2 데이터 정리 + +| 작업 | 실행 시간 | 설명 | +| ------------------ | ---------- | -------------------------- | +| 실시간 데이터 정리 | 00:00 매일 | 24시간 이상 된 데이터 삭제 | +| 캐시 정리 | 매시 정각 | 만료된 캐시 삭제 | +| 임시 파일 정리 | 03:00 매일 | 다운로드된 임시 파일 삭제 | + +## 3. API 상세 + +### 3.1 주식 정보 조회 + +GET /stock + +- 설명: 주식명으로 검색 +- 권한: 없음 +- 캐시: 1시간 +- 응답시간: < 100ms + +GET /stock/top + +- 설명: 인기/상승/하락 주식 조회 +- 권한: 없음 +- 캐시: 5분 +- 응답시간: < 200ms + +GET /stock/:stockId/detail + +- 설명: 주식 상세 정보 조회 +- 권한: 없음 +- 캐시: 60초 +- 응답시간: < 150ms + +### 3.2 사용자 기능 + +POST /stock/user + +- 설명: 관심 주식 추가 +- 권한: 로그인 필요 +- 제한: 최대 100개 + +DELETE /stock/user + +- 설명: 관심 주식 제거 +- 권한: 로그인 필요 +- 검증: 소유권 확인 + +## 4. 데이터베이스 상세 + +### 4.1 테이블 구조 + +stock + +- stock_id (PK): 종목코드 +- name: 종목명 +- views: 조회수 +- is_trading: 거래가능여부 +- group_code: 그룹코드 + +stock_detail + +- id (PK): Auto Increment +- stock_id (FK): 종목코드 +- market_cap: 시가총액 +- eps: EPS +- per: PER +- high_52w: 52주 최고가 +- low_52w: 52주 최저가 +- updated_at: 갱신일시 + +### 4.2 인덱스 전략 + +- **조회 성능 최적화**: + - stock_views_idx: (views DESC, name ASC) + - stock_detail_latest_idx: (stock_id, updated_at DESC) +- **검색 성능 최적화**: + - stock_name_idx: FULLTEXT(name) + +## 5. 캐싱 상세 + +### 5.1 API 캐시 + +| 엔드포인트 | 캐시 시간 | 키 패턴 | +| ----------------- | --------- | ---------------------------- | +| /stock/top | 5분 | `stock:top:{sortBy}:{limit}` | +| /stock/:id/detail | 60초 | `stock:detail:{stockId}` | +| /stock/index | 30초 | `stock:index` | + +### 5.2 데이터베이스 캐시 + +| 쿼리 종류 | 캐시 시간 | 갱신 조건 | +| ------------- | --------- | ---------- | +| 인기 검색어 | 1시간 | 수동 갱신 | +| 차트 데이터 | 1일 | 장 마감 후 | +| 종목 상세정보 | 60초 | 자동 갱신 | + +## 6. 에러 처리 + +### 6.1 에러 코드 + +| 코드 | 설명 | 대응 방안 | +| ---- | -------------- | -------------------------- | +| 400 | 잘못된 요청 | 요청 파라미터 검증 | +| 401 | 인증 필요 | 로그인 페이지로 리다이렉트 | +| 404 | 리소스 없음 | 사용자에게 메시지 표시 | +| 429 | 요청 횟수 초과 | 잠시 후 재시도 안내 | + +### 6.2 로깅 정책 + +- **에러 레벨**: + - ERROR: 서버 오류, 외부 API 실패 + - WARN: 비즈니스 규칙 위반 + - INFO: API 호출, 크론 작업 실행 +- **로그 포맷**: + - 시간 + - 요청 ID + - 사용자 ID + - 에러 메시지 + - 스택 트레이스 (ERROR 레벨만) diff --git a/packages/backend/serviceExplain.md b/packages/backend/serviceExplain.md new file mode 100644 index 00000000..e69de29b From 24713d638bf060f7acb4a9a4ff77ff130ffedbb3 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 16:03:53 +0900 Subject: [PATCH 10/34] =?UTF-8?q?=E2=9C=A8=20feat:=20news=201=EA=B0=9C?= =?UTF-8?q?=EC=9D=98=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=8B=B4=EC=9D=84=20?= =?UTF-8?q?newsItemDto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/newsItemDto.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/backend/src/crawling/dto/newsItemDto.ts diff --git a/packages/backend/src/crawling/dto/newsItemDto.ts b/packages/backend/src/crawling/dto/newsItemDto.ts new file mode 100644 index 00000000..fb152fdb --- /dev/null +++ b/packages/backend/src/crawling/dto/newsItemDto.ts @@ -0,0 +1,7 @@ +export class NewsItemDto { + title: string; + original_link: string; + link: string; + description: string; + pubDate: Date; +} From e98f79d1280f619edbe051829a9f8dafacbdd38e Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 16:04:47 +0900 Subject: [PATCH 11/34] =?UTF-8?q?=E2=9C=A8=20feat:=20news=EC=9D=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=8B=B4=EC=9D=84=20newsItemDto?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/newsInfoDto.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/backend/src/crawling/dto/newsInfoDto.ts diff --git a/packages/backend/src/crawling/dto/newsInfoDto.ts b/packages/backend/src/crawling/dto/newsInfoDto.ts new file mode 100644 index 00000000..03dd1e07 --- /dev/null +++ b/packages/backend/src/crawling/dto/newsInfoDto.ts @@ -0,0 +1,7 @@ +export class NewsInfoDto { + lastBuildDate: Date; + total: number; + start: number; + display: number; + items: NewsInfoDto[]; +} From 5465d7deb4f099bd2fd8411efe9cabd23613ab77 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 16:54:43 +0900 Subject: [PATCH 12/34] =?UTF-8?q?=E2=9C=A8=20feat:=20naver=20news=20API?= =?UTF-8?q?=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=EC=84=9C=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B0=9B=EC=95=84?= =?UTF-8?q?=EC=98=A4=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/newsInfoDto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/crawling/dto/newsInfoDto.ts b/packages/backend/src/crawling/dto/newsInfoDto.ts index 03dd1e07..3b4bff24 100644 --- a/packages/backend/src/crawling/dto/newsInfoDto.ts +++ b/packages/backend/src/crawling/dto/newsInfoDto.ts @@ -1,5 +1,5 @@ export class NewsInfoDto { - lastBuildDate: Date; + lastBuildDate: string; total: number; start: number; display: number; From 8bad100ee8edfdec6dc23b96048b404964f0bd11 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 17:08:18 +0900 Subject: [PATCH 13/34] =?UTF-8?q?=E2=9C=A8=20feat:=20naver=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EA=B2=80=EC=83=89=20API=EB=A1=9C=EB=B6=80=ED=84=B0?= =?UTF-8?q?=20=EB=B0=9B=EC=95=84=EC=98=A8=EC=A0=95=EB=B3=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20naver=20news=EB=A7=8C=20=ED=95=84=ED=84=B0=EB=A7=81?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/newsInfoDto.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/crawling/dto/newsInfoDto.ts b/packages/backend/src/crawling/dto/newsInfoDto.ts index 3b4bff24..089f645e 100644 --- a/packages/backend/src/crawling/dto/newsInfoDto.ts +++ b/packages/backend/src/crawling/dto/newsInfoDto.ts @@ -1,7 +1,9 @@ +import { NewsItemDto } from '@/crawling/dto/newsItemDto'; + export class NewsInfoDto { lastBuildDate: string; total: number; start: number; display: number; - items: NewsInfoDto[]; + items: NewsItemDto[]; } From d816d1b56d300ad2cf933e7b0d0cbc14d346abfb Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Tue, 4 Feb 2025 17:25:37 +0900 Subject: [PATCH 14/34] =?UTF-8?q?feat:=20=EC=A2=85=EB=AA=A9=EB=B3=84=20?= =?UTF-8?q?=EB=89=B4=EC=8A=A4=20=EC=93=B0=EA=B8=B0/=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/app.module.ts | 2 + .../src/news/domain/stockNews.entity.ts | 53 +++++++++++ .../backend/src/news/dto/stockNews.dto.ts | 49 +++++++++++ .../backend/src/news/stockNews.controller.ts | 34 +++++++ packages/backend/src/news/stockNews.module.ts | 14 +++ .../src/news/stockNews.service.spec.ts | 88 +++++++++++++++++++ .../backend/src/news/stockNews.service.ts | 40 +++++++++ .../backend/src/stock/domain/stock.entity.ts | 4 + 8 files changed, 284 insertions(+) create mode 100644 packages/backend/src/news/domain/stockNews.entity.ts create mode 100644 packages/backend/src/news/dto/stockNews.dto.ts create mode 100644 packages/backend/src/news/stockNews.controller.ts create mode 100644 packages/backend/src/news/stockNews.module.ts create mode 100644 packages/backend/src/news/stockNews.service.spec.ts create mode 100644 packages/backend/src/news/stockNews.service.ts diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts index 03c8b3c5..1ed0d15a 100644 --- a/packages/backend/src/app.module.ts +++ b/packages/backend/src/app.module.ts @@ -14,6 +14,7 @@ import { } from '@/configs/typeormConfig'; import { StockModule } from '@/stock/stock.module'; import { UserModule } from '@/user/user.module'; +import { StockNewsModule } from '@/news/stockNews.module'; @Module({ imports: [ @@ -31,6 +32,7 @@ import { UserModule } from '@/user/user.module'; AuthModule, ChatModule, SessionModule, + StockNewsModule, ], controllers: [], providers: [], diff --git a/packages/backend/src/news/domain/stockNews.entity.ts b/packages/backend/src/news/domain/stockNews.entity.ts new file mode 100644 index 00000000..2760eefa --- /dev/null +++ b/packages/backend/src/news/domain/stockNews.entity.ts @@ -0,0 +1,53 @@ +import { + Column, + CreateDateColumn, + Entity, + Index, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; +import { Stock } from '@/stock/domain/stock.entity'; + +@Entity('stock_news') +export class StockNews { + @PrimaryGeneratedColumn() + id: number; + + @Index() + @Column({ name: 'stock_id' }) + stockId: string; + + @Column({ name: 'stock_name', length: 100 }) + stockName: string; + + @Column({ type: 'text' }) + link: string; + + @Column({ type: 'varchar', length: 255 }) + title: string; + + @Column({ type: 'text' }) + summary: string; + + @Column({ name: 'positive_content', type: 'text', nullable: true }) + positiveContent: string; + + @Column({ name: 'negative_content', type: 'text', nullable: true }) + negativeContent: string; + + @CreateDateColumn({ name: 'created_at' }) + createdAt: Date; + + @UpdateDateColumn({ name: 'updated_at' }) + updatedAt: Date; + + @ManyToOne(() => Stock, (stock) => stock.news) + @JoinColumn({ name: 'stock_id' }) + stock: Stock; + + getLinks(): string[] { + return this.link.split(',').map(link => link.trim()); + } +} \ No newline at end of file diff --git a/packages/backend/src/news/dto/stockNews.dto.ts b/packages/backend/src/news/dto/stockNews.dto.ts new file mode 100644 index 00000000..62ddf578 --- /dev/null +++ b/packages/backend/src/news/dto/stockNews.dto.ts @@ -0,0 +1,49 @@ +import { IsString, MaxLength } from 'class-validator'; +import { StockNews } from '@/news/domain/stockNews.entity'; + +export class CreateStockNewsDto { + @IsString() + stock_id: string; + + @IsString() + stock_name: string; + + @IsString() + link: string; + + @IsString() + @MaxLength(255) + title: string; + + @IsString() + @MaxLength(400) + summary: string; + + @IsString() + positive_content: string; + + @IsString() + negative_content: string; +} + +export class StockNewsResponse { + constructor(stockNews: StockNews) { + this.stockId = stockNews.stockId; + this.stockName = stockNews.stockName; + this.link = stockNews.link; + this.title = stockNews.title; + this.summary = stockNews.summary; + this.positiveContent = stockNews.positiveContent; + this.negativeContent = stockNews.negativeContent; + this.createdAt = stockNews.createdAt; + } + + stockId: string; + stockName: string; + link: string; + title: string; + summary: string; + positiveContent: string; + negativeContent: string; + createdAt: Date; +} \ No newline at end of file diff --git a/packages/backend/src/news/stockNews.controller.ts b/packages/backend/src/news/stockNews.controller.ts new file mode 100644 index 00000000..563c11c8 --- /dev/null +++ b/packages/backend/src/news/stockNews.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Post, Body, Get, Param } from '@nestjs/common'; +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { StockNewsService } from '@/news/stockNews.service'; +import { CreateStockNewsDto, StockNewsResponse } from '@/news/dto/stockNews.dto'; + +@ApiTags('Stock News') +@Controller('stock/news') +export class StockNewsController { + constructor(private readonly stockNewsService: StockNewsService) {} + + @Post() + @ApiOperation({ summary: '주식 뉴스 정보 저장' }) + @ApiResponse({ status: 201, type: StockNewsResponse }) + async create(@Body() createStockNewsDto: CreateStockNewsDto) { + const stockNews = await this.stockNewsService.create(createStockNewsDto); + return new StockNewsResponse(stockNews); + } + + @Get(':stockId') + @ApiOperation({ summary: '종목별 뉴스 조회' }) + @ApiResponse({ status: 200, type: [StockNewsResponse] }) + async findByStockId(@Param('stockId') stockId: string) { + const newsList = await this.stockNewsService.findByStockId(stockId); + return newsList.map(news => new StockNewsResponse(news)); + } + + @Get(':stockId/latest') + @ApiOperation({ summary: '종목별 최신 뉴스 조회' }) + @ApiResponse({ status: 200, type: StockNewsResponse }) + async findLatestByStockId(@Param('stockId') stockId: string) { + const news = await this.stockNewsService.findLatestByStockId(stockId); + return news ? new StockNewsResponse(news) : null; + } +} \ No newline at end of file diff --git a/packages/backend/src/news/stockNews.module.ts b/packages/backend/src/news/stockNews.module.ts new file mode 100644 index 00000000..12d3b5a3 --- /dev/null +++ b/packages/backend/src/news/stockNews.module.ts @@ -0,0 +1,14 @@ +import { TypeOrmModule } from '@nestjs/typeorm'; +import { StockNews } from '@/news/domain/stockNews.entity'; +import { StockNewsController } from '@/news/stockNews.controller'; +import { Module } from '@nestjs/common'; +import { StockNewsService } from '@/news/stockNews.service'; + +@Module({ + imports: [TypeOrmModule.forFeature([StockNews])], + controllers: [StockNewsController], + providers: [StockNewsService], + exports: [StockNewsService], +}) + +export class StockNewsModule {} \ No newline at end of file diff --git a/packages/backend/src/news/stockNews.service.spec.ts b/packages/backend/src/news/stockNews.service.spec.ts new file mode 100644 index 00000000..9acd7303 --- /dev/null +++ b/packages/backend/src/news/stockNews.service.spec.ts @@ -0,0 +1,88 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { getRepositoryToken } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { StockNewsService } from '@/news/stockNews.service'; +import { StockNews } from '@/news/domain/stockNews.entity'; +import { CreateStockNewsDto } from '@/news/dto/stockNews.dto'; + + +describe('NewsService', () => { + let service: StockNewsService; + let repository: Repository; + + const mockNewsDto: CreateStockNewsDto = { + stock_id: '005930', + stock_name: '삼성전자', + link: 'http://news1.com,http://news2.com', + title: '삼성전자 실적 발표', + summary: '삼성전자가 2024년 1분기 실적을 발표했다...', + positive_content: '영업이익 증가', + negative_content: '시장 불확실성 존재', + }; + + const mockNews = { + id: 1, + ...mockNewsDto, + createdAt: new Date(), + updatedAt: new Date(), + getLinks: () => mockNewsDto.link.split(','), + }; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + StockNewsService, + { + provide: getRepositoryToken(StockNews), + useValue: { + save: jest.fn().mockResolvedValue(mockNews), + find: jest.fn().mockResolvedValue([mockNews]), + findOne: jest.fn().mockResolvedValue(mockNews), + }, + }, + ], + }).compile(); + + service = module.get(StockNewsService); + repository = module.get>(getRepositoryToken(StockNews)); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); + + describe('create', () => { + it('should create a news entry', async () => { + const result = await service.create(mockNewsDto); + + expect(repository.save).toHaveBeenCalled(); + expect(result).toEqual(mockNews); + }); + }); + + describe('findByStockId', () => { + it('should return an array of news for a stock', async () => { + const stockId = '005930'; + const result = await service.findByStockId(stockId); + + expect(repository.find).toHaveBeenCalledWith({ + where: { stockId }, + order: { createdAt: 'DESC' }, + }); + expect(result).toEqual([mockNews]); + }); + }); + + describe('findLatestByStockId', () => { + it('should return the latest news for a stock', async () => { + const stockId = '005930'; + const result = await service.findLatestByStockId(stockId); + + expect(repository.findOne).toHaveBeenCalledWith({ + where: { stockId }, + order: { createdAt: 'DESC' }, + }); + expect(result).toEqual(mockNews); + }); + }); +}); \ No newline at end of file diff --git a/packages/backend/src/news/stockNews.service.ts b/packages/backend/src/news/stockNews.service.ts new file mode 100644 index 00000000..3c4dd326 --- /dev/null +++ b/packages/backend/src/news/stockNews.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { StockNews } from '@/news/domain/stockNews.entity'; +import { CreateStockNewsDto } from '@/news/dto/stockNews.dto'; + +@Injectable() +export class StockNewsService { + constructor( + @InjectRepository(StockNews) + private readonly stockNewsRepository: Repository, + ) {} + + async create(dto: CreateStockNewsDto): Promise { + const stockNews = new StockNews(); + stockNews.stockId = dto.stock_id; + stockNews.stockName = dto.stock_name; + stockNews.link = dto.link; + stockNews.title = dto.title; + stockNews.summary = dto.summary; + stockNews.positiveContent = dto.positive_content; + stockNews.negativeContent = dto.negative_content; + + return await this.stockNewsRepository.save(stockNews); + } + + async findByStockId(stockId: string): Promise { + return await this.stockNewsRepository.find({ + where: { stockId }, + order: { createdAt: 'DESC' }, + }); + } + + async findLatestByStockId(stockId: string): Promise { + return await this.stockNewsRepository.findOne({ + where: { stockId }, + order: { createdAt: 'DESC' }, + }); + } +} \ No newline at end of file diff --git a/packages/backend/src/stock/domain/stock.entity.ts b/packages/backend/src/stock/domain/stock.entity.ts index 36e37c2f..46a41458 100644 --- a/packages/backend/src/stock/domain/stock.entity.ts +++ b/packages/backend/src/stock/domain/stock.entity.ts @@ -12,6 +12,7 @@ import { Like } from '@/chat/domain/like.entity'; import { DateEmbedded } from '@/common/dateEmbedded.entity'; import { FluctuationRankStock } from '@/stock/domain/FluctuationRankStock.entity'; import { UserStock } from '@/stock/domain/userStock.entity'; +import { StockNews } from '@/news/domain/stockNews.entity'; @Entity() export class Stock { @@ -58,6 +59,9 @@ export class Stock { @OneToOne(() => StockLiveData, (stockLiveData) => stockLiveData.stock) stockLive?: StockLiveData; + @OneToMany(() => StockNews, (news) => news.stock) + news?: StockNews[]; + @OneToMany( () => FluctuationRankStock, (fluctuationRankStock) => fluctuationRankStock.stock, From 49ae1b95238f06ee0ca438d8a8bb80914d469e58 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 17:53:15 +0900 Subject: [PATCH 15/34] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EB=A7=81=ED=95=9C=20=EB=89=B4=EC=8A=A4=20=EB=82=B4=EC=9A=A9?= =?UTF-8?q?=EC=9D=84=20=EB=8B=B4=EC=9D=84=20CrawlNewsItemDto=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/crawlNewsItem.dto.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/backend/src/crawling/dto/crawlNewsItem.dto.ts diff --git a/packages/backend/src/crawling/dto/crawlNewsItem.dto.ts b/packages/backend/src/crawling/dto/crawlNewsItem.dto.ts new file mode 100644 index 00000000..f796e49d --- /dev/null +++ b/packages/backend/src/crawling/dto/crawlNewsItem.dto.ts @@ -0,0 +1,6 @@ +export class CrawlNewsItemDto { + date: string; + title: string; + content: string; + url: string; +} From 1b046d379c351980551c9924199eb79c20064c3f Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Tue, 4 Feb 2025 17:55:06 +0900 Subject: [PATCH 16/34] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EB=A7=81=ED=95=A0=20=EC=A0=84=EC=B2=B4=20=EB=89=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EB=8B=B4=EC=9D=84=20DTO?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/dto/crawlingData.dto.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 packages/backend/src/crawling/dto/crawlingData.dto.ts diff --git a/packages/backend/src/crawling/dto/crawlingData.dto.ts b/packages/backend/src/crawling/dto/crawlingData.dto.ts new file mode 100644 index 00000000..216d5883 --- /dev/null +++ b/packages/backend/src/crawling/dto/crawlingData.dto.ts @@ -0,0 +1,4 @@ +export class CrawlingDataDto{ + stockName : string; + news : +} \ No newline at end of file From 00ac14e92e305f8b04ca0951522fcf1a72278fc5 Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Tue, 4 Feb 2025 18:06:06 +0900 Subject: [PATCH 17/34] =?UTF-8?q?feat:=20[FE]=20=EC=A2=85=EB=AA=A9?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=89=B4=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stock-detail/components/NewsButton.tsx | 121 ++++++++++++++++++ .../components/StockDetailHeader.tsx | 4 +- 2 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/pages/stock-detail/components/NewsButton.tsx diff --git a/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx b/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx new file mode 100644 index 00000000..389e061f --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx @@ -0,0 +1,121 @@ +import { useState } from 'react'; + +interface NewsButtonProps { + stockId: string; + stockName: string; +} + +export const NewsButton = ({ stockId, stockName }: NewsButtonProps) => { + const [isOpen, setIsOpen] = useState(false); + const [news, setNews] = useState([]); + + const handleClick = async () => { + try { + setIsOpen(true); + const response = await fetch(`http://localhost:3000/api/stock/news/${stockId}`); + const data = await response.json(); + setNews(data); + } catch (error) { + console.error('뉴스를 불러오는데 실패했습니다:', error); + } + }; + + return ( +
+ + + {isOpen && ( +
+
+
+

{stockName} 뉴스

+ +
+ +
+ {news.map((item, index) => ( +
+
{item.title}
+
{item.summary}
+ {item.positiveContent && ( +
+ 긍정: {item.positiveContent} +
+ )} + {item.negativeContent && ( +
+ 부정: {item.negativeContent} +
+ )} +
+ {item.link.split(',').map((link: string, i: number) => ( + + 뉴스 링크 {i + 1} + + ))} +
+
+ ))} +
+ + {news.length === 0 && ( +
+ 뉴스가 없습니다 +
+ )} +
+
+ )} +
+ ); +}; \ No newline at end of file diff --git a/packages/frontend/src/pages/stock-detail/components/StockDetailHeader.tsx b/packages/frontend/src/pages/stock-detail/components/StockDetailHeader.tsx index c050a89d..b45c0558 100644 --- a/packages/frontend/src/pages/stock-detail/components/StockDetailHeader.tsx +++ b/packages/frontend/src/pages/stock-detail/components/StockDetailHeader.tsx @@ -11,6 +11,7 @@ import { Modal } from '@/components/ui/modal'; import { UserStatus } from '@/constants/chatStatus'; import { modalMessage, ModalMessage } from '@/constants/modalMessage'; import { LoginContext } from '@/contexts/login'; +import { NewsButton } from './NewsButton'; interface StockDetailHeaderProps { stockId: string; @@ -68,8 +69,9 @@ export const StockDetailHeader = ({ }; return ( -
+

{stockName}

+ {isOpen && ( -
+

{stockName} 뉴스

From 58e0693fb57afc5a70c43e8b227d707cba5fc6fe Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Tue, 4 Feb 2025 19:42:14 +0900 Subject: [PATCH 19/34] =?UTF-8?q?chore:=20[FE]=20=EB=89=B4=EC=8A=A4?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=95=84=EC=9D=B4=EC=BD=98=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/components/NewsButton.tsx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx b/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx index a5501566..d5584f9c 100644 --- a/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx +++ b/packages/frontend/src/pages/stock-detail/components/NewsButton.tsx @@ -56,17 +56,11 @@ export const NewsButton = ({ stockId, stockName }: NewsButtonProps) => { - - 뉴스 보기 + AI 뉴스 보기 {isOpen && ( From 5686ab02e86ce190f7cac5c912e3c60ce45114b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Wed, 5 Feb 2025 00:11:44 +0900 Subject: [PATCH 20/34] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=89=B4=EC=8A=A4=20?= =?UTF-8?q?=ED=81=B4=EB=A1=A4=EB=A7=81=20=EC=83=98=ED=94=8C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 객체 형태로 저장 --- packages/backend/src/news/sample.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/backend/src/news/sample.ts diff --git a/packages/backend/src/news/sample.ts b/packages/backend/src/news/sample.ts new file mode 100644 index 00000000..278ffc31 --- /dev/null +++ b/packages/backend/src/news/sample.ts @@ -0,0 +1,23 @@ +export const SAMPLE_NEWS_SCRAP = { + "stock_name": "삼성전자", + "news": [ + { + "date": "2025.02.04", + "title": "[단독] 반도체산업계 새 수장에 송재혁 삼성전자 사장", + "content": "송재혁 삼성전자(005930) 반도체(DS)부문 CTO(최고기술책임자)가 한국반도체산업협회 차기 회장으로 내정됐다. 탁월한 기술 리더십을 발휘해온 송 사장이 국내 최대 산업별 업종 단체인 반도체협회에 새 바람을 불러 일으킬 것으로 기대된다. 업계에 따르면 최근 삼성전자 경영진은 반도체협회에 송 사장을 차기 협회장으로 추천하는 내용을 전달했다. 협회는 내부 절차를 거친 후 다음 달 정기총회에서 송 사장의 회장 선출을 최종 확정할 것으로 전해졌다. 반도체협회 회장은 1991년 김광호 초대 회장 이후 삼성전자와 SK하이닉스 최고위 경영진이 번갈아 가면서 맡아왔다. 한 업계 관계자는 젊은 송 사장이 글로벌 경쟁이 치열하고 기술 발전이 빠른 반도체업계의 특성을 고려해 발탁된 것으로 안다고 설명했다.", + "url": "https://n.news.naver.com/mnews/article/011/0004446447?sid=101" + }, + { + "date": "2025.02.04", + "title": "손정의 \"삼성전자와 스타게이트 잠재적 협력 논의\"", + "content": "손정의 소프트뱅크그룹 회장이 4일 이재용 삼성전자 회장, 샘 올트먼 오픈AI 최고경영자(CEO)과 만나기에 앞서 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 밝혔다. 손 회장에 앞서 올트먼 CEO은 이날 오전 최태원 SK그룹 회장을 만난 데 이어, 오후 2시께 서초사옥에 도착했다. 스타게이트 프로젝트는 소프트뱅크 그룹과 오픈AI, 오라클의 합작으로 추진되는 미국의 대규모 AI 데이터센터 설립 프로젝트로, 최소 5000억달러(718조원)를 투자하는 계획이다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'를 묻는 질문에 '구체적인 것은 아니고, 단지 잠재적 협력에 대한 논의'라고 밝혔다.", + "url": "https://n.news.naver.com/mnews/article/003/0013046414?sid=101" + }, + { + "date": "2025.02.04", + "title": "삼성 찾은 손정의 \"삼성·오픈AI와 스타게이트 협력 논의할 것\"", + "content": "손정의 소프트뱅크그룹 회장이 4일 '삼성전자·오픈AI와 3자 회의'에 대해 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 말했다. 손 회장은 이날 오후 2시40분께 서울 서초구 삼성전자 서초사옥에서 취재진과 만나 이같이 밝혔다. 이날 손 회장과 이재용 삼성전자 회장을 비롯한 삼성전자 경영진과 샘 올트먼 오픈AI 최고경영자(CEO)는 5천억달러(약 720조원) 규모의 AI 인프라 프로젝트인 '스타게이트'에 대한 심도 있는 논의를 나눌 것으로 예상된다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'에 대한 질문에 '특별한 것은 없고 잠재적 협업 논의만 있을 뿐'이라고 답했다.", + "url": "https://n.news.naver.com/mnews/article/001/0015191159?sid=101" + } + ] +} From f014547ad716af4807d90a5009ed9e1ed6ee810d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Wed, 5 Feb 2025 00:15:43 +0900 Subject: [PATCH 21/34] =?UTF-8?q?=E2=9C=A8=20feat:=20clova=20Studio=20API?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NewsClovaService 클래스 추가 - summarizeNews() 메서드로 요약 내용을 객체 형태로 반환 --- .../backend/src/news/newsClova.service.ts | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 packages/backend/src/news/newsClova.service.ts diff --git a/packages/backend/src/news/newsClova.service.ts b/packages/backend/src/news/newsClova.service.ts new file mode 100644 index 00000000..1bf8e1e4 --- /dev/null +++ b/packages/backend/src/news/newsClova.service.ts @@ -0,0 +1,73 @@ +import { Inject, Injectable } from '@nestjs/common'; +import axios from 'axios'; +import { Logger } from 'winston'; +import { SAMPLE_NEWS_SCRAP } from './sample'; + +@Injectable() +export class NewsClovaService { + private readonly CLOVA_API_URL = + 'https://clovastudio.stream.ntruss.com/testapp/v1/chat-completions/HCX-DASH-001'; + private readonly CLOVA_API_KEY = process.env.CLOVA_API_KEY; + + constructor(@Inject('winston') private readonly logger: Logger) {} + + // TODO: 뉴스 데이터를 넣어주는 파라미터 추가 + async summarizeNews() { + try { + const clovaResponse = await axios.post( + this.CLOVA_API_URL, + { + messages: [ + { + role: 'system', + content: this.getSystemPrompt(), + }, + { + role: 'user', + content: JSON.stringify(SAMPLE_NEWS_SCRAP), // TODO: 파라미터값으로 변경 + }, + ], + ...this.getParameters(), + }, + { + headers: this.getHeaders(), + }, + ); + + const content = JSON.parse(clovaResponse.data.result.message.content); + return content; + } catch (error) { + if (axios.isAxiosError(error)) { + this.logger.error( + `Failed to summarize news: status=${error.response?.status}, data=${error.response?.data}`, + ); + } else { + this.logger.error('Unknown Error', error); + } + } + } + + private getSystemPrompt() { + return '당신은 AI 기반 주식 분석 전문가입니다. 아래에 제공되는 JSON 형식의 뉴스 데이터를 분석하여, 종합적인 분석 결과를 도출해 주세요.\r\n\r\n입력 데이터는 다음과 같은 JSON 형식으로 제공됩니다:\r\n```json\r\n{\r\n "stock_name": "종목 이름",\r\n "news": [\r\n {\r\n "date": "기사 날짜",\r\n "title": "기사 제목",\r\n "content": "기사 내용",\r\n "url": "기사 링크"\r\n },\r\n ...\r\n ]\r\n}\r\n```\r\n\r\n분석해야 할 항목은 다음과 같습니다:\r\n\r\n1. **종목 정보:**\r\n - stock_name을 기반으로 해당 종목의 stock_id를 찾아 포함\r\n - 제공된 모든 뉴스의 url을 쉼표로 구분하여 link 필드에 포함\r\n\r\n2. **종합 분석:**\r\n - title: 전체 뉴스 내용을 관통하는 핵심 주제나 이슈를 간단한 제목으로 작성\r\n - summary: 모든 뉴스 기사의 주요 내용을 종합적으로 요약하여 작성 (400자 내외)\r\n\r\n3. **영향 분석:**\r\n - positive_content: 기업, 산업, 경제에 긍정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n - negative_content: 위험 요소나 부정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n\r\n출력은 다음과 같은 JSON 형식으로 제공해야 합니다:\r\n```json\r\n{\r\n "stock_id": "종목 번호",\r\n "stock_name": "종목 이름",\r\n "link": "기사 링크들",\r\n "title": "요약 타이틀",\r\n "summary": "요약 내용",\r\n "positive_content": "긍정적 측면",\r\n "negative_content": "부정적 측면"\r\n}\r\n```\r\n\r\n분석 시 주의사항:\r\n1. 모든 뉴스 기사의 내용을 종합적으로 고려하여 분석합니다.\r\n2. 긍정적/부정적 내용이 없는 경우 "해당사항 없음"으로 작성합니다.\r\n3. 요약과 분석은 객관적이고 사실에 기반하여 작성합니다.\r\n4. 특정 종목의 stock_id를 모르는 경우 빈 문자열("")을 반환합니다.'; + } + + private getParameters() { + return { + topP: 0.8, + topK: 0, + maxTokens: 500, + temperature: 0.5, + repeatPenalty: 5.0, + stopBefore: [], + includeAiFilters: true, + seed: 0, + }; + } + + private getHeaders() { + return { + Authorization: `Bearer ${this.CLOVA_API_KEY}`, + 'Content-Type': 'application/json', + }; + } +} From 1c69772eb3699ff660e1ed2eb76fca1a96c31461 Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Wed, 5 Feb 2025 13:48:25 +0900 Subject: [PATCH 22/34] =?UTF-8?q?chore:=20nullable=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기본값은 false --- packages/backend/src/news/domain/stockNews.entity.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/news/domain/stockNews.entity.ts b/packages/backend/src/news/domain/stockNews.entity.ts index 2760eefa..03a9f396 100644 --- a/packages/backend/src/news/domain/stockNews.entity.ts +++ b/packages/backend/src/news/domain/stockNews.entity.ts @@ -31,10 +31,10 @@ export class StockNews { @Column({ type: 'text' }) summary: string; - @Column({ name: 'positive_content', type: 'text', nullable: true }) + @Column({ name: 'positive_content', type: 'text' }) positiveContent: string; - @Column({ name: 'negative_content', type: 'text', nullable: true }) + @Column({ name: 'negative_content', type: 'text' }) negativeContent: string; @CreateDateColumn({ name: 'created_at' }) From f2501c6094dc738da90790338a969bf64aa38851 Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Wed, 5 Feb 2025 13:56:46 +0900 Subject: [PATCH 23/34] =?UTF-8?q?chore:=20createNews=20dto=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=EA=B8=B8=EC=9D=B4=20=EB=84=89=EB=84=89=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/news/dto/stockNews.dto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/news/dto/stockNews.dto.ts b/packages/backend/src/news/dto/stockNews.dto.ts index 62ddf578..fe95b01f 100644 --- a/packages/backend/src/news/dto/stockNews.dto.ts +++ b/packages/backend/src/news/dto/stockNews.dto.ts @@ -16,7 +16,7 @@ export class CreateStockNewsDto { title: string; @IsString() - @MaxLength(400) + @MaxLength(10000) summary: string; @IsString() From c2069fa70fe74f3510bddaba565f3d5aeb3147b5 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 6 Feb 2025 01:44:03 +0900 Subject: [PATCH 24/34] =?UTF-8?q?=E2=9C=A8=20feat:=20naver=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=EB=A5=BC=20=ED=81=AC=EB=A1=A4=EB=A7=81=20=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/crawling.ts | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 packages/backend/src/crawling/crawling.ts diff --git a/packages/backend/src/crawling/crawling.ts b/packages/backend/src/crawling/crawling.ts new file mode 100644 index 00000000..9b901f7c --- /dev/null +++ b/packages/backend/src/crawling/crawling.ts @@ -0,0 +1,34 @@ +import * as cheerio from 'cheerio'; +import { NewsItemDto } from '@/crawling/dto/newsItemDto'; + +export async function crawling(stock: string, news: NewsItemDto[]) { + return { + stockName: stock, + news: await Promise.all( + news.map(async (n) => { + const url = decodeURI(n.link); + return await fetch(url, { + method: 'GET', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', + 'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7', + }, + }).then(async (r) => { + const htmlString = await r.text(); + const $ = cheerio.load(htmlString); + + const date = $('span._ARTICLE_DATE_TIME').attr('data-date-time'); + const title = $('#title_area').text(); + const content = $('#dic_area').text(); + return { + date: date, + title: title, + content: content, + url: url, + }; + }); + }), + ), + }; +} From afd533834ccc11764d14fdbd6f8928fda4074fae Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 6 Feb 2025 02:45:37 +0900 Subject: [PATCH 25/34] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EB=A7=81=20=ED=95=A8=EC=88=98=20Service=20Layer=EB=A1=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 280 +++++++++++++++++- packages/backend/package.json | 1 + .../backend/src/crawling/crawling.service.ts | 68 +++++ packages/backend/src/crawling/crawling.ts | 5 + .../src/crawling/dto/crawlingData.dto.ts | 10 +- yarn.lock | 179 ++++++++++- 6 files changed, 525 insertions(+), 18 deletions(-) create mode 100644 packages/backend/src/crawling/crawling.service.ts diff --git a/package-lock.json b/package-lock.json index d2d8488f..b1a5a301 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6124,6 +6124,12 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -6500,6 +6506,73 @@ "node": ">= 16" } }, + "node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -7314,6 +7387,34 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/css.escape": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", @@ -8069,6 +8170,61 @@ "dev": true, "license": "MIT" }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -8254,6 +8410,31 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8347,7 +8528,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -10967,6 +11147,25 @@ "dev": true, "license": "MIT" }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, "node_modules/http_ece": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz", @@ -13940,6 +14139,18 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/oauth": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz", @@ -14320,6 +14531,30 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "license": "MIT" }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -17788,6 +18023,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", + "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -18317,6 +18561,39 @@ "node": ">=4.0" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -18651,6 +18928,7 @@ "@nestjs/websockets": "^10.4.8", "async-mutex": "^0.5.0", "axios": "^1.7.7", + "cheerio": "^1.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "dotenv": "^16.4.5", diff --git a/packages/backend/package.json b/packages/backend/package.json index d7b79ace..c69d9e70 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -33,6 +33,7 @@ "@nestjs/websockets": "^10.4.8", "async-mutex": "^0.5.0", "axios": "^1.7.7", + "cheerio": "^1.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "dotenv": "^16.4.5", diff --git a/packages/backend/src/crawling/crawling.service.ts b/packages/backend/src/crawling/crawling.service.ts new file mode 100644 index 00000000..29f477e0 --- /dev/null +++ b/packages/backend/src/crawling/crawling.service.ts @@ -0,0 +1,68 @@ +import { Inject, Injectable } from '@nestjs/common'; +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import { Logger } from 'winston'; +import { NewsInfoDto } from '@/crawling/dto/newsInfoDto'; +import { NewsItemDto } from '@/crawling/dto/newsItemDto'; + +@Injectable() +export class CrawlingService { + constructor(@Inject('winston') private readonly logger: Logger) {} + + async getNews(stockName: string) { + const encodedStockName = encodeURI(stockName); + const newsUrl = `${process.env.NAVER_NEWS_URL}?query=${encodedStockName}&display=25&sort=sim`; + try { + const res: NewsInfoDto = await axios(newsUrl, { + method: 'GET', + headers: { + 'X-Naver-Client-Id': process.env.NAVER_CLIENT_ID, + 'X-Naver-Client-Secret': process.env.NAVER_CLIENT_SECRET, + }, + }).then((r) => r.data); + return { + stock: stockName, + response: await this.extractNaverNews(res), + }; + } catch (err) { + //this.logger.error(err); + console.log(err); + } + } + + async extractNaverNews(newsData?: NewsInfoDto) { + return newsData!.items.filter((e) => e.link.includes('n.news.naver.com')); + } + + async crawling(stock: string, news: NewsItemDto[]) { + return { + stockName: stock, + news: await Promise.all( + news.map(async (n) => { + const url = decodeURI(n.link); + return await axios(url, { + method: 'GET', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', + 'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7', + }, + }).then(async (r) => { + const htmlString = await r.data; + const $ = cheerio.load(htmlString); + + const date = $('span._ARTICLE_DATE_TIME').attr('data-date-time'); + const title = $('#title_area').text(); + const content = $('#dic_area').text(); + return { + date: date, + title: title, + content: content, + url: url, + }; + }); + }), + ), + }; + } +} diff --git a/packages/backend/src/crawling/crawling.ts b/packages/backend/src/crawling/crawling.ts index 9b901f7c..636c6adc 100644 --- a/packages/backend/src/crawling/crawling.ts +++ b/packages/backend/src/crawling/crawling.ts @@ -1,4 +1,5 @@ import * as cheerio from 'cheerio'; +import { getNews } from './news.info'; import { NewsItemDto } from '@/crawling/dto/newsItemDto'; export async function crawling(stock: string, news: NewsItemDto[]) { @@ -32,3 +33,7 @@ export async function crawling(stock: string, news: NewsItemDto[]) { ), }; } + +getNews('삼성전자') + .then((r) => crawling(r!.stock, r!.response)) + .then((r) => console.log(r)); diff --git a/packages/backend/src/crawling/dto/crawlingData.dto.ts b/packages/backend/src/crawling/dto/crawlingData.dto.ts index 216d5883..7096dffd 100644 --- a/packages/backend/src/crawling/dto/crawlingData.dto.ts +++ b/packages/backend/src/crawling/dto/crawlingData.dto.ts @@ -1,4 +1,6 @@ -export class CrawlingDataDto{ - stockName : string; - news : -} \ No newline at end of file +import { CrawlNewsItemDto } from '@/crawling/dto/crawlNewsItem.dto'; + +export class CrawlingDataDto { + stockName: string; + news: CrawlNewsItemDto[]; +} diff --git a/yarn.lock b/yarn.lock index 4f444ea4..67b57443 100644 --- a/yarn.lock +++ b/yarn.lock @@ -554,15 +554,11 @@ enabled "2.0.x" kuler "^2.0.0" -"@esbuild/win32-x64@0.21.5": +"@esbuild/linux-x64@0.21.5": version "0.21.5" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" - integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== -"@esbuild/win32-x64@0.24.0": +"@esbuild/linux-x64@0.24.0": version "0.24.0" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz" - integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.1" @@ -1199,10 +1195,11 @@ estree-walker "^2.0.2" picomatch "^4.0.2" -"@rollup/rollup-win32-x64-msvc@4.24.4": +"@rollup/rollup-linux-x64-gnu@4.24.4": + version "4.24.4" + +"@rollup/rollup-linux-x64-musl@4.24.4": version "4.24.4" - resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz" - integrity sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg== "@rtsao/scc@^1.1.0": version "1.1.0" @@ -2843,7 +2840,7 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" -"backend@file:D:\\nest_project\\stock\\refactor-web40-juchumjuchum\\packages\\backend": +"backend@file:/home/refactor-web40-juchumjuchum/packages/backend": version "0.0.1" resolved "file:packages/backend" dependencies: @@ -2956,6 +2953,11 @@ body-parser@1.20.3: type-is "~1.6.18" unpipe "1.0.0" +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -3175,6 +3177,35 @@ check-error@^2.1.1: resolved "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz" integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz" + integrity sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.1.0" + encoding-sniffer "^0.2.0" + htmlparser2 "^9.1.0" + parse5 "^7.1.2" + parse5-htmlparser2-tree-adapter "^7.0.0" + parse5-parser-stream "^7.1.2" + undici "^6.19.5" + whatwg-mimetype "^4.0.0" + chokidar@^3.5.2, chokidar@^3.5.3, chokidar@3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" @@ -3414,7 +3445,12 @@ commander@^2.20.0: resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.0.0, commander@4.1.1: +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== @@ -3642,6 +3678,22 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + css.escape@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" @@ -3924,6 +3976,36 @@ dom-accessibility-api@^0.6.3: resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz" integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1, domutils@^3.1.0: + version "3.2.2" + resolved "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz" + integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" @@ -4020,6 +4102,14 @@ encodeurl@~2.0.0: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== +encoding-sniffer@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz" + integrity sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg== + dependencies: + iconv-lite "^0.6.3" + whatwg-encoding "^3.1.1" + encoding@^0.1.0, encoding@^0.1.12: version "0.1.13" resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" @@ -4074,7 +4164,7 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" -entities@^4.4.0: +entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== @@ -5081,7 +5171,7 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -"frontend@file:D:\\nest_project\\stock\\refactor-web40-juchumjuchum\\packages\\frontend": +"frontend@file:/home/refactor-web40-juchumjuchum/packages/frontend": version "0.0.0" resolved "file:packages/frontend" dependencies: @@ -5471,6 +5561,16 @@ html-escaper@^2.0.0: resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== +htmlparser2@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz" + integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.1.0" + entities "^4.5.0" + http_ece@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz" @@ -5555,6 +5655,13 @@ iconv-lite@^0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -7320,6 +7427,13 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + oauth@0.10.x: version "0.10.0" resolved "https://registry.npmjs.org/oauth/-/oauth-0.10.0.tgz" @@ -7557,6 +7671,21 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz" + integrity sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g== + dependencies: + domhandler "^5.0.3" + parse5 "^7.0.0" + +parse5-parser-stream@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz" + integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow== + dependencies: + parse5 "^7.0.0" + parse5@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz" @@ -7567,6 +7696,13 @@ parse5@^6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^7.0.0, parse5@^7.1.2: + version "7.2.1" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz" + integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ== + dependencies: + entities "^4.5.0" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" @@ -9451,6 +9587,11 @@ undici-types@~6.19.2, undici-types@~6.19.8: resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici@^6.19.5: + version "6.21.1" + resolved "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz" + integrity sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ== + unicorn-magic@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz" @@ -9678,6 +9819,18 @@ webpack@^5.0.0, webpack@^5.1.0, webpack@^5.11.0, webpack@5.94.0: watchpack "^2.4.1" webpack-sources "^3.2.3" +whatwg-encoding@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz" + integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz" + integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" From 78668fdc032a439db21251cf46181635667199ca Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 6 Feb 2025 02:49:45 +0900 Subject: [PATCH 26/34] =?UTF-8?q?=E2=9C=A8=20feat:=20news=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=B0=9B=EC=95=84=EC=98=A4=EB=8A=94=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/news.info.ts | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packages/backend/src/crawling/news.info.ts diff --git a/packages/backend/src/crawling/news.info.ts b/packages/backend/src/crawling/news.info.ts new file mode 100644 index 00000000..8e8467be --- /dev/null +++ b/packages/backend/src/crawling/news.info.ts @@ -0,0 +1,39 @@ +import { NewsInfoDto } from '@/crawling/dto/newsInfoDto'; + +const NAVER_CLIENT_ID: string = process.env.NAVER_CLIENT_ID + ? process.env.NAVER_CLIENT_ID + : ''; +const NAVER_CLIENT_SECRET: string = process.env.NAVER_CLIENT_SECRET + ? process.env.NAVER_CLIENT_SECRET + : ''; +const url: string = process.env.NAVER_NEWS_URL + ? process.env.NAVER_NEWS_URL + : ''; + + +export async function getNews(stockName: string) { + const encodedStockName = encodeURI(stockName); + const newsUrl = `${url}?query=${encodedStockName}&display=50&sort=sim`; + try { + const res: NewsInfoDto = await fetch(newsUrl, { + method: 'GET', + headers: { + 'X-Naver-Client-Id': NAVER_CLIENT_ID, + 'X-Naver-Client-Secret': NAVER_CLIENT_SECRET, + }, + }).then((res) => res.json()); + // 여기도 DTO를 만들어야할까? + return { + stock: stockName, + response: await extractNaverNews(res), + }; + } catch (err) { + console.log(err); + } + return; +} + +// 네이버 뉴스 API로부터 받아온 데이터에서 naver 뉴스들만 뽑아내기 +export async function extractNaverNews(newsData?: NewsInfoDto) { + return newsData!.items.filter((e) => e.link.includes('n.news.naver.com')); +} From c666bfe07226d69b49ee7bd0791038ff2efcd854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Thu, 6 Feb 2025 12:42:11 +0900 Subject: [PATCH 27/34] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=ED=81=B4=EB=A1=9C?= =?UTF-8?q?=EB=B0=94=20=EB=89=B4=EC=8A=A4=20=EC=9A=94=EC=95=BD=20=ED=94=84?= =?UTF-8?q?=EB=A1=AC=ED=94=84=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용 모델을 HDX-003으로 변경 - 출력을 JSON 형태로 받을 수 있게 프롬프트 수정 - 에러 로깅 메시지 수정 --- packages/backend/src/news/newsClova.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/news/newsClova.service.ts b/packages/backend/src/news/newsClova.service.ts index 1bf8e1e4..4f95480c 100644 --- a/packages/backend/src/news/newsClova.service.ts +++ b/packages/backend/src/news/newsClova.service.ts @@ -6,7 +6,7 @@ import { SAMPLE_NEWS_SCRAP } from './sample'; @Injectable() export class NewsClovaService { private readonly CLOVA_API_URL = - 'https://clovastudio.stream.ntruss.com/testapp/v1/chat-completions/HCX-DASH-001'; + 'https://clovastudio.stream.ntruss.com/testapp/v1/chat-completions/HCX-003'; private readonly CLOVA_API_KEY = process.env.CLOVA_API_KEY; constructor(@Inject('winston') private readonly logger: Logger) {} @@ -39,7 +39,7 @@ export class NewsClovaService { } catch (error) { if (axios.isAxiosError(error)) { this.logger.error( - `Failed to summarize news: status=${error.response?.status}, data=${error.response?.data}`, + `Failed to summarize news: status=${error.response?.data?.status?.code}, data=${error.response?.data?.status?.message}`, ); } else { this.logger.error('Unknown Error', error); @@ -48,7 +48,7 @@ export class NewsClovaService { } private getSystemPrompt() { - return '당신은 AI 기반 주식 분석 전문가입니다. 아래에 제공되는 JSON 형식의 뉴스 데이터를 분석하여, 종합적인 분석 결과를 도출해 주세요.\r\n\r\n입력 데이터는 다음과 같은 JSON 형식으로 제공됩니다:\r\n```json\r\n{\r\n "stock_name": "종목 이름",\r\n "news": [\r\n {\r\n "date": "기사 날짜",\r\n "title": "기사 제목",\r\n "content": "기사 내용",\r\n "url": "기사 링크"\r\n },\r\n ...\r\n ]\r\n}\r\n```\r\n\r\n분석해야 할 항목은 다음과 같습니다:\r\n\r\n1. **종목 정보:**\r\n - stock_name을 기반으로 해당 종목의 stock_id를 찾아 포함\r\n - 제공된 모든 뉴스의 url을 쉼표로 구분하여 link 필드에 포함\r\n\r\n2. **종합 분석:**\r\n - title: 전체 뉴스 내용을 관통하는 핵심 주제나 이슈를 간단한 제목으로 작성\r\n - summary: 모든 뉴스 기사의 주요 내용을 종합적으로 요약하여 작성 (400자 내외)\r\n\r\n3. **영향 분석:**\r\n - positive_content: 기업, 산업, 경제에 긍정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n - negative_content: 위험 요소나 부정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n\r\n출력은 다음과 같은 JSON 형식으로 제공해야 합니다:\r\n```json\r\n{\r\n "stock_id": "종목 번호",\r\n "stock_name": "종목 이름",\r\n "link": "기사 링크들",\r\n "title": "요약 타이틀",\r\n "summary": "요약 내용",\r\n "positive_content": "긍정적 측면",\r\n "negative_content": "부정적 측면"\r\n}\r\n```\r\n\r\n분석 시 주의사항:\r\n1. 모든 뉴스 기사의 내용을 종합적으로 고려하여 분석합니다.\r\n2. 긍정적/부정적 내용이 없는 경우 "해당사항 없음"으로 작성합니다.\r\n3. 요약과 분석은 객관적이고 사실에 기반하여 작성합니다.\r\n4. 특정 종목의 stock_id를 모르는 경우 빈 문자열("")을 반환합니다.'; + return '당신은 AI 기반 주식 분석 전문가입니다. 입력으로 주어지는 JSON 형식의 뉴스 데이터를 분석하여, JSON 형식으로 종합적인 분석 결과를 도출해 주세요.\r\n\r\n[입력 형식]\r\n{\r\n "stock_name": "종목 이름",\r\n "news": [\r\n {\r\n "date": "기사 날짜",\r\n "title": "기사 제목",\r\n "content": "기사 내용",\r\n "url": "기사 링크"\r\n },\r\n ...\r\n ]\r\n}\r\n\r\n[출력 형식]\r\n{\r\n "stock_id": "종목 번호",\r\n "stock_name": "종목 이름",\r\n "link": "기사 링크들",\r\n "title": "요약 타이틀",\r\n "summary": "요약 내용",\r\n "positive_content": "긍정적 측면",\r\n "negative_content": "부정적 측면"\r\n}\r\n\r\n[분석 지침]\r\n분석해야 할 항목은 다음과 같습니다:\r\n\r\n1. **종목 정보:**\r\n - stock_name을 기반으로 해당 종목의 stock_id를 찾아 포함\r\n - 제공된 모든 뉴스의 url을 쉼표로 구분하여 link 필드에 포함\r\n\r\n2. **종합 분석:**\r\n - title: 전체 뉴스 내용을 관통하는 핵심 주제나 이슈를 간단한 제목으로 작성\r\n - summary: 모든 뉴스 기사의 주요 내용을 종합적으로 요약하여 작성\r\n\r\n3. **영향 분석:**\r\n - positive_content: 기업, 산업, 경제에 긍정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n - negative_content: 위험 요소나 부정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n\r\n[제약 사항]\r\n1. 모든 뉴스 기사의 내용을 종합적으로 고려하여 분석합니다.\r\n2. positive_content 와 negative_content 내용이 없는 경우 "해당사항 없음"으로 작성합니다.\r\n3. 요약과 분석은 객관적이고 사실에 기반하여 작성합니다.\r\n4. 특정 종목의 stock_id를 모르는 경우 빈 문자열("")을 반환합니다.\r\n5. 반드시 JSON 형식으로 응답합니다.'; } private getParameters() { From e4042e436e1e2f06106d6b0e1ca7dc0916127421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Thu, 6 Feb 2025 12:43:55 +0900 Subject: [PATCH 28/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20?= =?UTF-8?q?=EB=89=B4=EC=8A=A4=20=EC=83=98=ED=94=8C=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존에 3개에서 10개로 뉴스 갯수 변경 --- packages/backend/src/news/sample.ts | 86 +++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/news/sample.ts b/packages/backend/src/news/sample.ts index 278ffc31..6ebfcb29 100644 --- a/packages/backend/src/news/sample.ts +++ b/packages/backend/src/news/sample.ts @@ -1,23 +1,75 @@ export const SAMPLE_NEWS_SCRAP = { - "stock_name": "삼성전자", - "news": [ + stock_name: '삼성전자', + news: [ { - "date": "2025.02.04", - "title": "[단독] 반도체산업계 새 수장에 송재혁 삼성전자 사장", - "content": "송재혁 삼성전자(005930) 반도체(DS)부문 CTO(최고기술책임자)가 한국반도체산업협회 차기 회장으로 내정됐다. 탁월한 기술 리더십을 발휘해온 송 사장이 국내 최대 산업별 업종 단체인 반도체협회에 새 바람을 불러 일으킬 것으로 기대된다. 업계에 따르면 최근 삼성전자 경영진은 반도체협회에 송 사장을 차기 협회장으로 추천하는 내용을 전달했다. 협회는 내부 절차를 거친 후 다음 달 정기총회에서 송 사장의 회장 선출을 최종 확정할 것으로 전해졌다. 반도체협회 회장은 1991년 김광호 초대 회장 이후 삼성전자와 SK하이닉스 최고위 경영진이 번갈아 가면서 맡아왔다. 한 업계 관계자는 젊은 송 사장이 글로벌 경쟁이 치열하고 기술 발전이 빠른 반도체업계의 특성을 고려해 발탁된 것으로 안다고 설명했다.", - "url": "https://n.news.naver.com/mnews/article/011/0004446447?sid=101" + date: '2025.02.04', + title: '[단독] 반도체산업계 새 수장에 송재혁 삼성전자 사장', + content: + '송재혁 삼성전자(005930) 반도체(DS)부문 CTO(최고기술책임자)가 한국반도체산업협회 차기 회장으로 내정됐다. 탁월한 기술 리더십을 발휘해온 송 사장이 국내 최대 산업별 업종 단체인 반도체협회에 새 바람을 불러 일으킬 것으로 기대된다. 업계에 따르면 최근 삼성전자 경영진은 반도체협회에 송 사장을 차기 협회장으로 추천하는 내용을 전달했다. 협회는 내부 절차를 거친 후 다음 달 정기총회에서 송 사장의 회장 선출을 최종 확정할 것으로 전해졌다. 반도체협회 회장은 1991년 김광호 초대 회장 이후 삼성전자와 SK하이닉스 최고위 경영진이 번갈아 가면서 맡아왔다. 한 업계 관계자는 젊은 송 사장이 글로벌 경쟁이 치열하고 기술 발전이 빠른 반도체업계의 특성을 고려해 발탁된 것으로 안다고 설명했다.', + url: 'https://n.news.naver.com/mnews/article/011/0004446447?sid=101', }, { - "date": "2025.02.04", - "title": "손정의 \"삼성전자와 스타게이트 잠재적 협력 논의\"", - "content": "손정의 소프트뱅크그룹 회장이 4일 이재용 삼성전자 회장, 샘 올트먼 오픈AI 최고경영자(CEO)과 만나기에 앞서 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 밝혔다. 손 회장에 앞서 올트먼 CEO은 이날 오전 최태원 SK그룹 회장을 만난 데 이어, 오후 2시께 서초사옥에 도착했다. 스타게이트 프로젝트는 소프트뱅크 그룹과 오픈AI, 오라클의 합작으로 추진되는 미국의 대규모 AI 데이터센터 설립 프로젝트로, 최소 5000억달러(718조원)를 투자하는 계획이다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'를 묻는 질문에 '구체적인 것은 아니고, 단지 잠재적 협력에 대한 논의'라고 밝혔다.", - "url": "https://n.news.naver.com/mnews/article/003/0013046414?sid=101" + date: '2025.02.04', + title: '손정의 "삼성전자와 스타게이트 잠재적 협력 논의"', + content: + "손정의 소프트뱅크그룹 회장이 4일 이재용 삼성전자 회장, 샘 올트먼 오픈AI 최고경영자(CEO)과 만나기에 앞서 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 밝혔다. 손 회장에 앞서 올트먼 CEO은 이날 오전 최태원 SK그룹 회장을 만난 데 이어, 오후 2시께 서초사옥에 도착했다. 스타게이트 프로젝트는 소프트뱅크 그룹과 오픈AI, 오라클의 합작으로 추진되는 미국의 대규모 AI 데이터센터 설립 프로젝트로, 최소 5000억달러(718조원)를 투자하는 계획이다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'를 묻는 질문에 '구체적인 것은 아니고, 단지 잠재적 협력에 대한 논의'라고 밝혔다.", + url: 'https://n.news.naver.com/mnews/article/003/0013046414?sid=101', }, { - "date": "2025.02.04", - "title": "삼성 찾은 손정의 \"삼성·오픈AI와 스타게이트 협력 논의할 것\"", - "content": "손정의 소프트뱅크그룹 회장이 4일 '삼성전자·오픈AI와 3자 회의'에 대해 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 말했다. 손 회장은 이날 오후 2시40분께 서울 서초구 삼성전자 서초사옥에서 취재진과 만나 이같이 밝혔다. 이날 손 회장과 이재용 삼성전자 회장을 비롯한 삼성전자 경영진과 샘 올트먼 오픈AI 최고경영자(CEO)는 5천억달러(약 720조원) 규모의 AI 인프라 프로젝트인 '스타게이트'에 대한 심도 있는 논의를 나눌 것으로 예상된다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'에 대한 질문에 '특별한 것은 없고 잠재적 협업 논의만 있을 뿐'이라고 답했다.", - "url": "https://n.news.naver.com/mnews/article/001/0015191159?sid=101" - } - ] -} + date: '2025.02.04', + title: '삼성 찾은 손정의 "삼성·오픈AI와 스타게이트 협력 논의할 것"', + content: + "손정의 소프트뱅크그룹 회장이 4일 '삼성전자·오픈AI와 3자 회의'에 대해 '스타게이트 업데이트와 삼성 그룹과 잠재적 협력에 대해 이야기할 것'이라고 말했다. 손 회장은 이날 오후 2시40분께 서울 서초구 삼성전자 서초사옥에서 취재진과 만나 이같이 밝혔다. 이날 손 회장과 이재용 삼성전자 회장을 비롯한 삼성전자 경영진과 샘 올트먼 오픈AI 최고경영자(CEO)는 5천억달러(약 720조원) 규모의 AI 인프라 프로젝트인 '스타게이트'에 대한 심도 있는 논의를 나눌 것으로 예상된다. 손 회장은 '이재용 회장에게 투자 요청을 할 것인지'에 대한 질문에 '특별한 것은 없고 잠재적 협업 논의만 있을 뿐'이라고 답했다.", + url: 'https://n.news.naver.com/mnews/article/001/0015191159?sid=101', + }, + { + date: '2025.02.04', + title: '삼성전자 서초사옥 도착한 손정의 회장', + content: + '(서울=뉴스1) 김성진 기자 = 손정의 소프트뱅크그룹 회장이 이재용 삼성전자 회장과 샘 올트먼 오픈AI 최고경영자(CEO)와의 회동을 위해 4일 서울 서초구 삼성전자 사옥에 도착하고 있다. 이 자리에서 손 회장과 올트먼 CEO는 이재용 회장에게 ‘스타게이트 프로젝트’에 대한 투자와 협업을 요청할 것으로 알려졌다. 2025.2.4/뉴스1', + url: 'https://n.news.naver.com/mnews/article/421/0008054585?sid=101', + }, + { + date: '2025.02.04', + title: '사법리스크 털어낸 이재용…"삼성전자 호재에 주목"', + content: + '[이데일리 이정현 기자] KB증권은 삼성전자(005930)에 대해 "불확실성 완화 국면에 진입했다"고 평가했다. 투자의견은 \'매수\', 목표가는 7만원을 \'유지\'했다. 김동원 KB증권 연구원은 4일 보고서에서 "이재용 회장의 사법 리스크가 일단락되며 경영 복귀가 현실화됨에 따라 지난 10년간 최고 경영자의 사법 리스크가 해소됐다"며 이같이 밝혔다. 이어 "2019년 이후 미등기임원인 이재용 회장은 올해 3월 주총에서 등기이사 복귀로 책임경영이 가능해질 것으로 전망되고, 삼성전자 중심의 그룹 컨트롤타워 재건도 빠르게 진행될 것"으로 예상했다. 삼성전자는 2016년 하만 인수합병 이후 이 회장의 사법 리스크로 대형 M&A 및 기업가치 제고 등의 조치가 10년간 전무한 상태다. 이 회장의 10년간 사법 리스크 종료는 향후 적극적 경영참여를 의미해 이 회장이 보유한 순현금 93조3000억원(시총 대비 27.5%)을 삼성전자 기업가치 제고에 적극 활용할 것으로 예상된다. 김 연구원은 "지난 11월 발표한 10조원 규모 자사주 외 추가적인 자사주 매입 및 소각, 대형 M&A 빅딜, 글로벌 업체와의 AI 분야 JV 설립 등이 가능한 시나리오로 추정된다"고 예상했다. 현재 삼성전자 주가는 PBR 0.85배로 모든 악재를 선 반영하고 있어 하락 위험은 제한적인 반면 향후 상승 여력은 높아질 것이란 KB증권의 판단이다. 이를 바탕으로 현 시점은 업사이드 리스크를 고려해야 할 것으로 판단했다. 김 연구원은 "4분기 실적 컨퍼런스 콜 이후 시장 컨센서스 실적 하향 조정이 일단락되어 향후 메모리와 파운드리 성과에 따라 실적 상향 가능성이 상존하고, 1분기 실적 저점 확인 후 2분기부터는 계단식 실적 개선이 예상된다"며 "올 상반기 중에 HBM3E 12단 품질 인증, HBM4 (1c nm) 개발 완료 및 파운드리 대형 수주 (2nm) 등이 주가 상승의 동력이 될 것으로 기대되는 만큼 지금은 다가올 호재에 주목할 때"라 말했다.', + url: 'https://n.news.naver.com/mnews/article/018/0005935540?sid=101', + }, + { + date: '2025.02.04', + title: '"사법 리스크 털었다"..삼성전자, 4% 강세 [특징주]', + content: + '[파이낸셜뉴스] 삼성전자가 장 초반 4% 넘게 급등하고 있다. 이재용 삼성전자 회장이 부당합병 및 분식회계 관련 2심에서 무죄를 선고받은 영향이다. 4일 오전 9시 47분 현재 삼성전자는 전 거래일 대비 4.31% 오른 5만3200원에 거래되고 있다. 전날 서울고법 형사13부는 자본시장법상 부정거래행위·시세조종, 업무상 배임 등 혐의로 기소된 이 회장에게 1심과 같은 전부 무죄를 선고했다. 삼성물산과 제일모직의 합병비율과 합병 시점 등 쟁점 사항에 대해 이 회장의 경영권 승계와 지배력 강화를 위해 합병이 부당하게 이뤄졌다고 판단하지 않았다. 증권가에서는 사법 리스크가 해소됨에 따라 이 회장의 경영 활동이 본격화될 것으로 전망했다. 김동원 KB증권 리서치센터장은 "이재용 회장의 사법 리스크가 일단락되며 경영 복귀가 현실화됨에 따라 삼성전자의 불확실성 완화 국면 진입이 전망된다"며 "이 회장은 보유한 순현금 93조3000억원을 삼성전자 기업가치 제고에 적극 활용할 것으로 예상된다"고 분석했다. 이어 "2019년 이후 미등기임원인 이재용 회장은 올해 3월 주총에서 등기이사 복귀로 책임경영이 가능해질 것으로 전망한다"며 "삼성전자 중심 그룹 컨트롤타워 재건도 빠르게 진행될 것으로 예상한다"고 언급했다.', + url: 'https://n.news.naver.com/mnews/article/014/0005303101?sid=101', + }, + { + date: '2025.02.04', + title: "사법리스크 해소·올트먼 회동 기대감에…삼성전자 4%대 '급등'", + content: + '삼성전자의 주가가 오르고 있다. 이재용 회장이 부당합병·회계부정 관련 항소심에서 무죄판결을 받은 영향으로 보인다. 이 회장은 샘 올트먼 오픈AI 최고경영자(CEO)도 만날 예정이다. 4일 오전 9시30분 현재 삼성전자는 전일 대비 2300원(4.51%) 오른 5만3300원에 거래되고 있다. 주가는 장중 5만3500원까지 오르기도 했다. 사법리스크 해소 기대감에 매수세가 몰린 것으로 풀이된다. 이 회장은 전날 서울고등법원에서 열린 제일모직·삼성물산 부당합병 회계부정 혐의 2심 선고공판에서 무죄를 선고받았다. 김동원 KB증권 연구원은 "이 회장의 사법 리스크가 일단락되며 경영 복귀가 현실화해 향후 삼성전자가 불확실성 완화 국면에 진입할 것으로 전망된다"며 "미등기임원인 이 회장은 올해 3월 주총에서 등기이사 복귀로 책임경영이 가능해질 것"이라고 내다봤다. 또 김 연구원은 삼성전자의 그룹 컨트롤타워가 빠르게 재건될 수 있다고 평가했다. 삼성전자가 2016년 하만(Harman) 인수·합병(M&A) 이후 멈췄던 기업가치 제고 활동에 다시 시동을 걸 수 있다는 취지다. 삼성전자가 보유한 순현금 93조3000억원을 기업가치 제고에 적극 활용할 것으로 봤다. 샘 올트먼 오픈AI CEO와의 회동도 투자심리에 영향을 준 것으로 보인다. 오픈AI는 이날 오전 서울 더플라자호텔에서 국내 기업 및 스타트업 개발자 100명을 대상으로 비공개 워크숍을 개최한다. 이 자리에서 올트먼 CEO는 전영현 삼성전자 디바이스솔루션(DS) 부문장(부회장)을 비롯한 삼성전자 경영진과 회동할 예정이다. 이 자리에 이재용 회장이 함께할 것으로 알려졌다.', + url: 'https://n.news.naver.com/mnews/article/015/0005089109?sid=101', + }, + { + date: '2025.02.04', + title: "'이재용 2심 무죄' 삼성전자, 사법리스크 해소에 4%대 급등", + content: + '이재용 삼성전자 회장의 사법 리스크가 해소되면서 삼성전자 주가가 4%대 강세를 보이고 있다. 4일 오전 9시 40분 현재 삼성전자는 전일 대비 2300원(4.50%) 오른 5만3300원에 거래되고 있다. 전날 서울고법 형사13부(백강진 김선희 이인수 부장판사)는 자본시장법상 부정거래행위·시세조종, 업무상 배임 등 혐의로 기소된 이 회장에게 1심과 같이 전부 무죄를 선고했다. 재판부는 검찰이 제출한 주요 증거의 증거능력을 인정하지 않았다. 또 부정거래 행위에 대한 검찰의 주장도 받아들이지 않았다. 회계부정 혐의와 관련해서도 재무제표 처리 재량을 벗어나지 않았다고 판단했다. 증권가에서는 이재용 회장의 사법 리스크가 일단락되면서 삼성전자의 자사주 추가 매입과 소각, 대형 인수·합병(M&A) 등 기업가치 제고 움직임이 본격화할 것으로 내다봤다. 김동원 KB증권 연구원은 "지난 10년간의 최고경영자의 사법 리스크 해소로 향후 삼성전자가 불확실성 완화 국면으로 진입할 것"이라며 "2019년 이후 미등기임원인 이재용 회장은 올해 3월 주주총회에서 등기이사 복귀로 책임경영이 가능해질 것으로 전망되고, 삼성전자 중심의 그룹 컨트롤타워 재건도 빠르게 진행될 것"이라고 말했다. 이어 "현재 삼성전자 주가는 모든 악재를 선반영하고 있어 하락 위험은 제한적인 반면 향후 상승 여력은 높아질 것"이라며 "1분기 실적 저점 확인 후 2분기부터는 계단식 실적 개선이 예상된다"고 덧붙였다. 이 회장과 챗GPT 개발사 오픈AI의 창업자인 샘 올트먼 최고경영자(CEO)와의 만남이 예정된 것도 호재로 작용한 것으로 보인다. 이날 이 회장은 삼성 서초사옥에서 올트먼 CEO를 만나 협력 방안을 모색할 것으로 알려졌다.', + url: 'https://n.news.naver.com/mnews/article/009/0005437839?sid=101', + }, + { + date: '2025.02.04', + title: "'이재용 회장 무죄 나오니, 주가 뛰네'…삼성전자 3%대 강세", + content: + '이재용 삼성전자 회장이 부당합병·회계부정 의혹 사건 항소심에서 무죄 판결을 받은 이후인 오늘(4일) 장 초반 삼성전자 주가가 3%대 강세를 보이고 있습니다. 오늘 오전 9시 15분 기준 삼성전자는 전장 대비 3.53% 오른 5만2천800원에 거래되고 있습니다. 주가는 개장 직후 1.18% 오른 것을 시작으로 강세를 키워가고 있습니다. 전날 서울고법은 부당합병·회계부정 혐의로 기소된 이 회장에게 1심과 같이 전부 무죄를 선고했습니다. 재판부는 검찰이 제출한 주요 증거의 증거 능력을 인정하지 않았고, 부정거래 행위에 대한 검찰의 주장도 받아들이지 않았습니다. 회계부정 역시 재무제표 처리 재량을 벗어나지 않았다고 판단했습니다. KB증권은 이날 보고서에서 이재용 회장의 사법 리스크 일단락에 따라 삼성전자의 자사주 추가 매입 및 소각, 대형 인수·합병(M&A) 등 기업가치 제고 움직임이 본격화할 것으로 기대했습니다. 삼성전자 주가는 현재 모든 악재를 선반영하고 있으며, 실적 역시 2분기부터 계단식 개선이 가능할 것으로 예상했습니다.', + url: 'https://n.news.naver.com/mnews/article/374/0000423483?sid=101', + }, + { + date: '2025.02.04', + title: "삼성·LG전자, 유럽 최대 전시회서 '혁신 디스플레이' 선봬", + content: + "[서울=뉴시스]이현주 기자 = 삼성전자와 LG전자가 4~7일(현지시간) 스페인 바르셀로나에서 열리는 유럽 최대 디스플레이 전시회 'ISE 2025'에서 혁신 디스플레이 신제품을 대거 선보인다. 삼성전자는 전시장 '피라 바르셀로나'에 1728㎡(약 522평) 규모 전시관을 마련하고 ▲초저전력 디스플레이 '삼성 컬러 이페이퍼' 4종 ▲AI 기능을 강화한 B2B(기업간거래) 통합 연결 플랫폼 스마트싱스 프로 ▲전자칠판 신제품, 고급 매장 및 빌딩 로비에 적합한 초대형 사이니지 등을 선보인다. '삼성 컬러 이페이퍼'는 디지털 종이에 잉크 기술을 적용하는 방식으로, 콘텐츠 유지 상태에서는 소비전력이 0.00와트(W)인 것이 특징이다. 화면 변경 시에도 기존 디지털 사이니지 대비 현저히 낮은 전력이 소모돼 에너지 비용을 줄일 수 있다. 13형(1600x1200), 25형(3200x1800), 32형 QHD(2560x1440) 해상도 3종과 75형 5K(5120x2880) 해상도의 아웃도어용 1종으로 구성됐다. AI 기능을 강화한 스마트싱스 프로와 AI 전자칠판 신제품도 공개했다. B2B 통합 연결 플랫폼인 '스마트싱스 프로'는 '인터렉티브 뷰' 기능을 통해 사용자가 등록한 평면도를 AI로 분석해 입체감 있는 3D 도면으로 제공한다. 사용자는 공간 지각에 용이한 3D 도면 위에 스마트싱스 프로와 연결된 기기를 맵핑해 쉽고 편리하게 기기를 관리할 수 있다. 안드로이드 15 운영 체제를 탑재한 2025년형 전자칠판 'WAFX-P'는 삼성 AI 어시스턴트와 함께 화면 속 이미지 검색 또는 텍스트 번역을 제공하는 '서클 투 서치'와 강의, 회의 내용을 요약해주는 'AI 요약' 등을 지원한다. 아울러 초대형 115형 4K 스마트 사이니지를 공개했다. 115형 QHFX 모델은 화면 내 이음새가 없어 매끄러운 시청 경험을 제공하며 최대 4분할까지 멀티뷰도 가능하다.", + url: 'https://n.news.naver.com/mnews/article/003/0013045074?sid=101', + }, + ], +}; From b7bcbb1c7eaf6139395dc9630a1887b3aa0a2d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Thu, 6 Feb 2025 12:53:33 +0900 Subject: [PATCH 29/34] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=ED=81=B4=EB=A1=9C?= =?UTF-8?q?=EB=B0=94=20=EC=9A=94=EC=95=BD=20=EC=9D=91=EB=8B=B5=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/news/newsClova.service.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/news/newsClova.service.ts b/packages/backend/src/news/newsClova.service.ts index 4f95480c..8911ba2f 100644 --- a/packages/backend/src/news/newsClova.service.ts +++ b/packages/backend/src/news/newsClova.service.ts @@ -34,7 +34,7 @@ export class NewsClovaService { }, ); - const content = JSON.parse(clovaResponse.data.result.message.content); + const content = this.verfiyClovaResponse(clovaResponse); return content; } catch (error) { if (axios.isAxiosError(error)) { @@ -70,4 +70,17 @@ export class NewsClovaService { 'Content-Type': 'application/json', }; } + + private verfiyClovaResponse(response: any) { + try { + const content = response.data.result.message.content; + this.logger.info(`Summarized news: ${content}`); + + const parsedContent = JSON.parse(content); + return parsedContent; + } catch (error) { + this.logger.error('Failed to parse clova response', error); + return null; + } + } } From d43403ea3e649d0d077fd66394f21c208869ac43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=91=90=EC=A2=85?= <2019102076@khu.ac.kr> Date: Thu, 6 Feb 2025 13:00:02 +0900 Subject: [PATCH 30/34] =?UTF-8?q?=F0=9F=90=9B=20fix:=20summarizeNews()=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EC=97=90=EC=84=9C=20DTO=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/news/newsClova.service.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/news/newsClova.service.ts b/packages/backend/src/news/newsClova.service.ts index 8911ba2f..49e21aa6 100644 --- a/packages/backend/src/news/newsClova.service.ts +++ b/packages/backend/src/news/newsClova.service.ts @@ -2,6 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import axios from 'axios'; import { Logger } from 'winston'; import { SAMPLE_NEWS_SCRAP } from './sample'; +import { CreateStockNewsDto } from './dto/stockNews.dto'; @Injectable() export class NewsClovaService { @@ -35,7 +36,20 @@ export class NewsClovaService { ); const content = this.verfiyClovaResponse(clovaResponse); - return content; + if (!content) { + return null; + } + + const summarizedNews = new CreateStockNewsDto(); + summarizedNews.stock_id = content.stock_id; + summarizedNews.stock_name = content.stock_name; + summarizedNews.link = content.link; + summarizedNews.title = content.title; + summarizedNews.summary = content.summary; + summarizedNews.positive_content = content.positive_content; + summarizedNews.negative_content = content.negative_content; + + return summarizedNews; } catch (error) { if (axios.isAxiosError(error)) { this.logger.error( From 5bd80edb8f647872e570623ebc9337ef7b8af411 Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 6 Feb 2025 13:33:16 +0900 Subject: [PATCH 31/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20getNews?= =?UTF-8?q?=ED=95=A8=EC=88=98=EB=AA=85=EC=9D=84=20getNewsLinks=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/crawling.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/crawling/crawling.service.ts b/packages/backend/src/crawling/crawling.service.ts index 29f477e0..a067fe97 100644 --- a/packages/backend/src/crawling/crawling.service.ts +++ b/packages/backend/src/crawling/crawling.service.ts @@ -9,7 +9,8 @@ import { NewsItemDto } from '@/crawling/dto/newsItemDto'; export class CrawlingService { constructor(@Inject('winston') private readonly logger: Logger) {} - async getNews(stockName: string) { + // naver news API이용해 뉴스 정보 얻어오기 + async getNewsLinks(stockName: string) { const encodedStockName = encodeURI(stockName); const newsUrl = `${process.env.NAVER_NEWS_URL}?query=${encodedStockName}&display=25&sort=sim`; try { @@ -34,6 +35,7 @@ export class CrawlingService { return newsData!.items.filter((e) => e.link.includes('n.news.naver.com')); } + // 얻어온 뉴스 정보들 중 naver news에 기사가 있는 사이트에서 제목, 본문, 생성 날짜등을 크롤링해오기 async crawling(stock: string, news: NewsItemDto[]) { return { stockName: stock, From 63fafacce113839edb2db0108c0489e76dfa966a Mon Sep 17 00:00:00 2001 From: KWAKMANBO Date: Thu, 6 Feb 2025 13:37:48 +0900 Subject: [PATCH 32/34] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20logger?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=20=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/crawling/crawling.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/crawling/crawling.service.ts b/packages/backend/src/crawling/crawling.service.ts index a067fe97..cb6e68d6 100644 --- a/packages/backend/src/crawling/crawling.service.ts +++ b/packages/backend/src/crawling/crawling.service.ts @@ -7,7 +7,8 @@ import { NewsItemDto } from '@/crawling/dto/newsItemDto'; @Injectable() export class CrawlingService { - constructor(@Inject('winston') private readonly logger: Logger) {} + constructor(@Inject('winston') private readonly logger: Logger) { + } // naver news API이용해 뉴스 정보 얻어오기 async getNewsLinks(stockName: string) { @@ -26,13 +27,12 @@ export class CrawlingService { response: await this.extractNaverNews(res), }; } catch (err) { - //this.logger.error(err); - console.log(err); + this.logger.error(err); } } - async extractNaverNews(newsData?: NewsInfoDto) { - return newsData!.items.filter((e) => e.link.includes('n.news.naver.com')); + async extractNaverNews(newsData: NewsInfoDto) { + return newsData.items.filter((e) => e.link.includes('n.news.naver.com')); } // 얻어온 뉴스 정보들 중 naver news에 기사가 있는 사이트에서 제목, 본문, 생성 날짜등을 크롤링해오기 From d71e523ea97d75f1d833b8278c2fa24e8f5e4b57 Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Thu, 6 Feb 2025 16:03:22 +0900 Subject: [PATCH 33/34] =?UTF-8?q?feat:=20=EC=A2=85=EB=AA=A9=EB=B3=84=20new?= =?UTF-8?q?s=20ai=20=EC=97=B0=EB=8F=99=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/main.ts | 12 +- .../src/news/StockNewsOrchestrationService.ts | 58 + .../backend/src/news/dto/crawlNewsItem.dto.ts | 6 + .../backend/src/news/dto/crawlingData.dto.ts | 6 + packages/backend/src/news/dto/newsInfoDto.ts | 9 + packages/backend/src/news/dto/newsItemDto.ts | 7 + .../backend/src/news/newsCrawling.service.ts | 71 + ...lova.service.ts => newsSummary.service.ts} | 15 +- .../backend/src/news/stockNews.controller.ts | 20 +- packages/backend/src/news/stockNews.module.ts | 14 +- ...e.spec.ts => stockNews.repository.spec.ts} | 0 ...ews.service.ts => stockNews.repository.ts} | 3 +- yarn.lock | 2016 ++++++----------- 13 files changed, 889 insertions(+), 1348 deletions(-) create mode 100644 packages/backend/src/news/StockNewsOrchestrationService.ts create mode 100644 packages/backend/src/news/dto/crawlNewsItem.dto.ts create mode 100644 packages/backend/src/news/dto/crawlingData.dto.ts create mode 100644 packages/backend/src/news/dto/newsInfoDto.ts create mode 100644 packages/backend/src/news/dto/newsItemDto.ts create mode 100644 packages/backend/src/news/newsCrawling.service.ts rename packages/backend/src/news/{newsClova.service.ts => newsSummary.service.ts} (92%) rename packages/backend/src/news/{stockNews.service.spec.ts => stockNews.repository.spec.ts} (100%) rename packages/backend/src/news/{stockNews.service.ts => stockNews.repository.ts} (95%) diff --git a/packages/backend/src/main.ts b/packages/backend/src/main.ts index 71405361..95a5b1b6 100644 --- a/packages/backend/src/main.ts +++ b/packages/backend/src/main.ts @@ -35,12 +35,12 @@ async function bootstrap() { // 4초 후 customQueryLogger 작동 // 서버 초기화 쿼리는 로그 찍을 필요 없음 - setTimeout(() => { - const dataSource = app.get(DataSource); - dataSource.setOptions({ - logger: new CustomQueryLogger() - }); - }, 4000); + // setTimeout(() => { + // const dataSource = app.get(DataSource); + // dataSource.setOptions({ + // logger: new CustomQueryLogger() + // }); + // }, 4000); app.setGlobalPrefix('api'); app.use(session({ ...sessionConfig, store })); diff --git a/packages/backend/src/news/StockNewsOrchestrationService.ts b/packages/backend/src/news/StockNewsOrchestrationService.ts new file mode 100644 index 00000000..cd167ce2 --- /dev/null +++ b/packages/backend/src/news/StockNewsOrchestrationService.ts @@ -0,0 +1,58 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { Logger } from 'winston'; +import { NewsCrawlingService } from '@/news/newsCrawling.service'; +import { NewsSummaryService } from '@/news/newsSummary.service'; +import { StockNewsRepository } from '@/news/stockNews.repository'; +import { CrawlingDataDto } from '@/news/dto/crawlingData.dto'; +import { Cron } from '@nestjs/schedule'; +import { CreateStockNewsDto } from '@/news/dto/stockNews.dto'; + +@Injectable() +export class StockNewsOrchestrationService { + constructor( + @Inject('winston') private readonly logger: Logger, + private readonly newsCrawlingService: NewsCrawlingService, + private readonly newsSummaryService: NewsSummaryService, + private readonly stockNewsRepository: StockNewsRepository, + ) {} + + @Cron('19 15 0 * * *') //오후 3시 19분 + public async orchestrateStockProcessing() { + const stockNameList = [ + '삼성전자', + // 'SK하이닉스', + // 'LG에너지솔루션', + // '삼성바이오로직스', + // '현대차', + // '기아', + // '셀트리온', + // 'NAVER', + // 'KB금융', + // 'HD현대중공업', + ]; + // 주식 데이터 크롤링 + for (const stockName of stockNameList) { + const stockDataList = + await this.newsCrawlingService.getNewsLinks(stockName); + + const stockNewsData: CrawlingDataDto = + await this.newsCrawlingService.crawling( + stockDataList!.stock, + stockDataList!.response, + ); + // 데이터 요약 + const summarizedData = + await this.newsSummaryService.summarizeNews(stockNewsData); + + console.log('summarizedData'); + console.log(summarizedData); + + // DB에 저장 + if (summarizedData) { + await this.stockNewsRepository.create(summarizedData); + } else { + this.logger.error('Failed to summarize news'); + } + } + } +} diff --git a/packages/backend/src/news/dto/crawlNewsItem.dto.ts b/packages/backend/src/news/dto/crawlNewsItem.dto.ts new file mode 100644 index 00000000..f796e49d --- /dev/null +++ b/packages/backend/src/news/dto/crawlNewsItem.dto.ts @@ -0,0 +1,6 @@ +export class CrawlNewsItemDto { + date: string; + title: string; + content: string; + url: string; +} diff --git a/packages/backend/src/news/dto/crawlingData.dto.ts b/packages/backend/src/news/dto/crawlingData.dto.ts new file mode 100644 index 00000000..6e99eb92 --- /dev/null +++ b/packages/backend/src/news/dto/crawlingData.dto.ts @@ -0,0 +1,6 @@ +import { CrawlNewsItemDto } from './crawlNewsItem.dto'; + +export class CrawlingDataDto { + stockName: string; + news: CrawlNewsItemDto[]; +} diff --git a/packages/backend/src/news/dto/newsInfoDto.ts b/packages/backend/src/news/dto/newsInfoDto.ts new file mode 100644 index 00000000..e0f68840 --- /dev/null +++ b/packages/backend/src/news/dto/newsInfoDto.ts @@ -0,0 +1,9 @@ +import { NewsItemDto } from './newsItemDto'; + +export class NewsInfoDto { + lastBuildDate: string; + total: number; + start: number; + display: number; + items: NewsItemDto[]; +} diff --git a/packages/backend/src/news/dto/newsItemDto.ts b/packages/backend/src/news/dto/newsItemDto.ts new file mode 100644 index 00000000..fb152fdb --- /dev/null +++ b/packages/backend/src/news/dto/newsItemDto.ts @@ -0,0 +1,7 @@ +export class NewsItemDto { + title: string; + original_link: string; + link: string; + description: string; + pubDate: Date; +} diff --git a/packages/backend/src/news/newsCrawling.service.ts b/packages/backend/src/news/newsCrawling.service.ts new file mode 100644 index 00000000..f384116e --- /dev/null +++ b/packages/backend/src/news/newsCrawling.service.ts @@ -0,0 +1,71 @@ +import { Inject, Injectable } from '@nestjs/common'; +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import { Logger } from 'winston'; +import { NewsInfoDto } from './dto/newsInfoDto'; +import { NewsItemDto } from './dto/newsItemDto'; +import { CrawlingDataDto } from '@/news/dto/crawlingData.dto'; + +@Injectable() +export class NewsCrawlingService { + constructor(@Inject('winston') private readonly logger: Logger) { + } + + // naver news API 이용해 뉴스 정보 얻어오기 + async getNewsLinks(stockName: string) { + const encodedStockName = encodeURI(stockName); + const newsUrl = `${process.env.NAVER_NEWS_URL}?query=${encodedStockName}&display=10&sort=sim`; + try { + const res: NewsInfoDto = await axios(newsUrl, { + method: 'GET', + headers: { + 'X-Naver-Client-Id': process.env.NAVER_CLIENT_ID, + 'X-Naver-Client-Secret': process.env.NAVER_CLIENT_SECRET, + }, + }).then((r) => r.data); + return { + stock: stockName, + response: await this.extractNaverNews(res), + }; + } catch (err) { + this.logger.error(err); + } + } + + async extractNaverNews(newsData: NewsInfoDto) { + return newsData.items.filter((e) => e.link.includes('n.news.naver.com')); + } + + // 얻어온 뉴스 정보들 중 naver news에 기사가 있는 사이트에서 제목, 본문, 생성 날짜등을 크롤링해오기 + async crawling(stock: string, news: NewsItemDto[]) { + return { + stockName: stock, + news: await Promise.all( + news.map(async (n) => { + const url = decodeURI(n.link); + return await axios(url, { + method: 'GET', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', + 'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7', + }, + }).then(async (r) => { + const htmlString = await r.data; + const $ = cheerio.load(htmlString); + + const date = $('span._ARTICLE_DATE_TIME').attr('data-date-time'); + const title = $('#title_area').text(); + const content = $('#dic_area').text(); + return { + date: date, + title: title, + content: content, + url: url, + }; + }); + }), + ), + } as CrawlingDataDto; + } +} diff --git a/packages/backend/src/news/newsClova.service.ts b/packages/backend/src/news/newsSummary.service.ts similarity index 92% rename from packages/backend/src/news/newsClova.service.ts rename to packages/backend/src/news/newsSummary.service.ts index 49e21aa6..64e5326d 100644 --- a/packages/backend/src/news/newsClova.service.ts +++ b/packages/backend/src/news/newsSummary.service.ts @@ -1,11 +1,12 @@ import { Inject, Injectable } from '@nestjs/common'; import axios from 'axios'; import { Logger } from 'winston'; -import { SAMPLE_NEWS_SCRAP } from './sample'; import { CreateStockNewsDto } from './dto/stockNews.dto'; +import { SAMPLE_NEWS_SCRAP } from './sample'; +import { CrawlingDataDto } from '@/news/dto/crawlingData.dto'; @Injectable() -export class NewsClovaService { +export class NewsSummaryService { private readonly CLOVA_API_URL = 'https://clovastudio.stream.ntruss.com/testapp/v1/chat-completions/HCX-003'; private readonly CLOVA_API_KEY = process.env.CLOVA_API_KEY; @@ -13,7 +14,7 @@ export class NewsClovaService { constructor(@Inject('winston') private readonly logger: Logger) {} // TODO: 뉴스 데이터를 넣어주는 파라미터 추가 - async summarizeNews() { + async summarizeNews(stockNewsData: CrawlingDataDto) { try { const clovaResponse = await axios.post( this.CLOVA_API_URL, @@ -25,7 +26,7 @@ export class NewsClovaService { }, { role: 'user', - content: JSON.stringify(SAMPLE_NEWS_SCRAP), // TODO: 파라미터값으로 변경 + content: JSON.stringify(stockNewsData), }, ], ...this.getParameters(), @@ -41,9 +42,9 @@ export class NewsClovaService { } const summarizedNews = new CreateStockNewsDto(); - summarizedNews.stock_id = content.stock_id; - summarizedNews.stock_name = content.stock_name; - summarizedNews.link = content.link; + summarizedNews.stock_id = content.stockId; + summarizedNews.stock_name = content.stockName; + summarizedNews.link = content.link.join(","); summarizedNews.title = content.title; summarizedNews.summary = content.summary; summarizedNews.positive_content = content.positive_content; diff --git a/packages/backend/src/news/stockNews.controller.ts b/packages/backend/src/news/stockNews.controller.ts index 563c11c8..942b1ac7 100644 --- a/packages/backend/src/news/stockNews.controller.ts +++ b/packages/backend/src/news/stockNews.controller.ts @@ -1,18 +1,21 @@ import { Controller, Post, Body, Get, Param } from '@nestjs/common'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { StockNewsService } from '@/news/stockNews.service'; import { CreateStockNewsDto, StockNewsResponse } from '@/news/dto/stockNews.dto'; +import { StockNewsRepository } from '@/news/stockNews.repository'; +import { StockNewsOrchestrationService } from '@/news/StockNewsOrchestrationService'; @ApiTags('Stock News') @Controller('stock/news') export class StockNewsController { - constructor(private readonly stockNewsService: StockNewsService) {} + constructor( + private readonly stockNewsRepository: StockNewsRepository, + private readonly stockNewsOrchestrationService: StockNewsOrchestrationService) {} @Post() @ApiOperation({ summary: '주식 뉴스 정보 저장' }) @ApiResponse({ status: 201, type: StockNewsResponse }) async create(@Body() createStockNewsDto: CreateStockNewsDto) { - const stockNews = await this.stockNewsService.create(createStockNewsDto); + const stockNews = await this.stockNewsRepository.create(createStockNewsDto); return new StockNewsResponse(stockNews); } @@ -20,15 +23,20 @@ export class StockNewsController { @ApiOperation({ summary: '종목별 뉴스 조회' }) @ApiResponse({ status: 200, type: [StockNewsResponse] }) async findByStockId(@Param('stockId') stockId: string) { - const newsList = await this.stockNewsService.findByStockId(stockId); - return newsList.map(news => new StockNewsResponse(news)); + const newsList = await this.stockNewsRepository.findByStockId(stockId); + return newsList.map((news) => new StockNewsResponse(news)); } @Get(':stockId/latest') @ApiOperation({ summary: '종목별 최신 뉴스 조회' }) @ApiResponse({ status: 200, type: StockNewsResponse }) async findLatestByStockId(@Param('stockId') stockId: string) { - const news = await this.stockNewsService.findLatestByStockId(stockId); + const news = await this.stockNewsRepository.findLatestByStockId(stockId); return news ? new StockNewsResponse(news) : null; } + + @Post('test') + async testAI(){ + await this.stockNewsOrchestrationService.orchestrateStockProcessing(); + } } \ No newline at end of file diff --git a/packages/backend/src/news/stockNews.module.ts b/packages/backend/src/news/stockNews.module.ts index 12d3b5a3..393b3d12 100644 --- a/packages/backend/src/news/stockNews.module.ts +++ b/packages/backend/src/news/stockNews.module.ts @@ -1,14 +1,16 @@ +import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { StockNews } from '@/news/domain/stockNews.entity'; import { StockNewsController } from '@/news/stockNews.controller'; -import { Module } from '@nestjs/common'; -import { StockNewsService } from '@/news/stockNews.service'; +import { StockNewsRepository } from '@/news/stockNews.repository'; +import { NewsCrawlingService } from '@/news/newsCrawling.service'; +import { StockNewsOrchestrationService } from '@/news/StockNewsOrchestrationService'; +import { NewsSummaryService } from '@/news/newsSummary.service'; @Module({ imports: [TypeOrmModule.forFeature([StockNews])], controllers: [StockNewsController], - providers: [StockNewsService], - exports: [StockNewsService], + providers: [StockNewsRepository, NewsCrawlingService, StockNewsOrchestrationService, NewsSummaryService], + exports: [], }) - -export class StockNewsModule {} \ No newline at end of file +export class StockNewsModule {} diff --git a/packages/backend/src/news/stockNews.service.spec.ts b/packages/backend/src/news/stockNews.repository.spec.ts similarity index 100% rename from packages/backend/src/news/stockNews.service.spec.ts rename to packages/backend/src/news/stockNews.repository.spec.ts diff --git a/packages/backend/src/news/stockNews.service.ts b/packages/backend/src/news/stockNews.repository.ts similarity index 95% rename from packages/backend/src/news/stockNews.service.ts rename to packages/backend/src/news/stockNews.repository.ts index 3c4dd326..49fa64d7 100644 --- a/packages/backend/src/news/stockNews.service.ts +++ b/packages/backend/src/news/stockNews.repository.ts @@ -5,13 +5,14 @@ import { StockNews } from '@/news/domain/stockNews.entity'; import { CreateStockNewsDto } from '@/news/dto/stockNews.dto'; @Injectable() -export class StockNewsService { +export class StockNewsRepository { constructor( @InjectRepository(StockNews) private readonly stockNewsRepository: Repository, ) {} async create(dto: CreateStockNewsDto): Promise { + console.log(dto); const stockNews = new StockNews(); stockNews.stockId = dto.stock_id; stockNews.stockName = dto.stock_name; diff --git a/yarn.lock b/yarn.lock index 67b57443..1ecd02e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -92,7 +92,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz" integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": version "7.26.0" resolved "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz" integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== @@ -373,16 +373,16 @@ react-confetti "^6.1.0" strip-ansi "^7.1.0" -"@colors/colors@^1.6.0", "@colors/colors@1.6.0": - version "1.6.0" - resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz" - integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== - "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + "@commitlint/cli@^19.5.0": version "19.5.0" resolved "https://registry.npmjs.org/@commitlint/cli/-/cli-19.5.0.tgz" @@ -455,7 +455,7 @@ "@commitlint/rules" "^19.5.0" "@commitlint/types" "^19.5.0" -"@commitlint/load@^19.5.0", "@commitlint/load@>6.1.1": +"@commitlint/load@>6.1.1", "@commitlint/load@^19.5.0": version "19.5.0" resolved "https://registry.npmjs.org/@commitlint/load/-/load-19.5.0.tgz" integrity sha512-INOUhkL/qaKqwcTUvCE8iIUf5XHsEPCLY9looJ/ipzi7jtGhgmtH7OOFiNvwYgH7mA8osUWOUDV8t4E2HAi4xA== @@ -554,11 +554,240 @@ enabled "2.0.x" kuler "^2.0.0" +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + "@esbuild/linux-x64@0.21.5": version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== "@esbuild/linux-x64@0.24.0": version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.1" @@ -616,16 +845,16 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@^9.13.0", "@eslint/js@9.14.0": - version "9.14.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz" - integrity sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg== - "@eslint/js@8.57.1": version "8.57.1" resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.14.0", "@eslint/js@^9.13.0": + version "9.14.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz" + integrity sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg== + "@eslint/object-schema@^2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz" @@ -638,11 +867,6 @@ dependencies: levn "^0.4.1" -"@gar/promisify@^1.0.1": - version "1.1.3" - resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - "@humanfs/core@^0.19.1": version "0.19.1" resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz" @@ -872,7 +1096,7 @@ jest-haste-map "^29.7.0" slash "^3.0.0" -"@jest/transform@^29.0.0", "@jest/transform@^29.7.0": +"@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== @@ -893,7 +1117,7 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^29.0.0", "@jest/types@^29.6.3": +"@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== @@ -947,14 +1171,6 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" @@ -963,6 +1179,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@ljharb/through@^2.3.12": version "2.3.13" resolved "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz" @@ -1012,14 +1236,14 @@ webpack "5.94.0" webpack-node-externals "3.0.0" -"@nestjs/common@^10.0.0", "@nestjs/common@^5.0.0 || ^6.6.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/common@^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/common@^9.0.0 || ^10.0.0": +"@nestjs/common@^10.0.0": version "10.4.6" resolved "https://registry.npmjs.org/@nestjs/common/-/common-10.4.6.tgz" integrity sha512-KkezkZvU9poWaNq4L+lNvx+386hpOxPJkfXBBeSMrcqBOx8kVr36TGN2uYkF4Ta4zNu1KbCjmZbc0rhHSg296g== dependencies: + uid "2.0.2" iterare "1.2.1" tslib "2.7.0" - uid "2.0.2" "@nestjs/config@^3.3.0": version "3.3.0" @@ -1030,17 +1254,17 @@ dotenv-expand "10.0.0" lodash "4.17.21" -"@nestjs/core@^10.0.0", "@nestjs/core@^8.0.0 || ^9.0.0 || ^10.0.0", "@nestjs/core@^9.0.0 || ^10.0.0": +"@nestjs/core@^10.0.0": version "10.4.6" resolved "https://registry.npmjs.org/@nestjs/core/-/core-10.4.6.tgz" integrity sha512-zXVPxCNRfO6gAy0yvEDjUxE/8gfZICJFpsl2lZAUH31bPb6m+tXuhUq2mVCTEltyMYQ+DYtRe+fEYM2v152N1g== dependencies: + uid "2.0.2" "@nuxtjs/opencollective" "0.3.2" fast-safe-stringify "2.1.1" iterare "1.2.1" path-to-regexp "3.3.0" tslib "2.7.0" - uid "2.0.2" "@nestjs/mapped-types@2.0.6": version "2.0.6" @@ -1063,7 +1287,7 @@ multer "1.4.4-lts.1" tslib "2.7.0" -"@nestjs/platform-socket.io@^10.0.0", "@nestjs/platform-socket.io@^10.4.8": +"@nestjs/platform-socket.io@^10.4.8": version "10.4.8" resolved "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-10.4.8.tgz" integrity sha512-KzCL+P037HiaW3iODueJ/vw5a8bSr6uIturgGSuRz6c8WR+SfqKC6jNXw0JTW5NVqEqX8tOunEVXoI3MFnWz/w== @@ -1116,7 +1340,7 @@ dependencies: uuid "9.0.1" -"@nestjs/websockets@^10.0.0", "@nestjs/websockets@^10.4.8": +"@nestjs/websockets@^10.4.8": version "10.4.8" resolved "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.8.tgz" integrity sha512-IpObWsZvjjUxmBuIF/AkcyXrFFzwNYNsw2reZXHy7C31wJsYAjwr6rHMSRGyqsxfqTA2DqjCczorewM6BAEXig== @@ -1133,7 +1357,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1146,22 +1370,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - "@nuxtjs/opencollective@0.3.2": version "0.3.2" resolved "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz" @@ -1195,11 +1403,95 @@ estree-walker "^2.0.2" picomatch "^4.0.2" +"@rollup/rollup-android-arm-eabi@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz#c460b54c50d42f27f8254c435a4f3b3e01910bc8" + integrity sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw== + +"@rollup/rollup-android-arm64@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.4.tgz#96e01f3a04675d8d5973ab8d3fd6bc3be21fa5e1" + integrity sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA== + +"@rollup/rollup-darwin-arm64@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz#9b2ec23b17b47cbb2f771b81f86ede3ac6730bce" + integrity sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ== + +"@rollup/rollup-darwin-x64@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.4.tgz#f30e4ee6929e048190cf10e0daa8e8ae035b6e46" + integrity sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg== + +"@rollup/rollup-freebsd-arm64@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.4.tgz#c54b2373ec5bcf71f08c4519c7ae80a0b6c8e03b" + integrity sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw== + +"@rollup/rollup-freebsd-x64@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.4.tgz#3bc53aa29d5a34c28ba8e00def76aa612368458e" + integrity sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.4.tgz#c85aedd1710c9e267ee86b6d1ce355ecf7d9e8d9" + integrity sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA== + +"@rollup/rollup-linux-arm-musleabihf@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.4.tgz#e77313408bf13995aecde281aec0cceb08747e42" + integrity sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw== + +"@rollup/rollup-linux-arm64-gnu@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.4.tgz#633f632397b3662108cfaa1abca2a80b85f51102" + integrity sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg== + +"@rollup/rollup-linux-arm64-musl@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.4.tgz#63edd72b29c4cced93e16113a68e1be9fef88907" + integrity sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.4.tgz#a9418a4173df80848c0d47df0426a0bf183c4e75" + integrity sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA== + +"@rollup/rollup-linux-riscv64-gnu@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.4.tgz#bc9c195db036a27e5e3339b02f51526b4ce1e988" + integrity sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw== + +"@rollup/rollup-linux-s390x-gnu@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.4.tgz#1651fdf8144ae89326c01da5d52c60be63e71a82" + integrity sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ== + "@rollup/rollup-linux-x64-gnu@4.24.4": version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.4.tgz#e473de5e4acb95fcf930a35cbb7d3e8080e57a6f" + integrity sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA== "@rollup/rollup-linux-x64-musl@4.24.4": version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.4.tgz#0af12dd2578c29af4037f0c834b4321429dd5b01" + integrity sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q== + +"@rollup/rollup-win32-arm64-msvc@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.4.tgz#e48e78cdd45313b977c1390f4bfde7ab79be8871" + integrity sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA== + +"@rollup/rollup-win32-ia32-msvc@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.4.tgz#a3fc8536d243fe161c796acb93eba43c250f311c" + integrity sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg== + +"@rollup/rollup-win32-x64-msvc@4.24.4": + version "4.24.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz#e2a9d1fd56524103a6cc8a54404d9d3ebc73c454" + integrity sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg== "@rtsao/scc@^1.1.0": version "1.1.0" @@ -1360,7 +1652,7 @@ "@storybook/icons" "^1.2.12" ts-dedent "^2.0.0" -"@storybook/builder-vite@^8.4.3", "@storybook/builder-vite@8.4.3": +"@storybook/builder-vite@8.4.3", "@storybook/builder-vite@^8.4.3": version "8.4.3" resolved "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.4.3.tgz" integrity sha512-kLM2vPKOo/yAavYmQgt0qO8kU/vDYuHRq3/AH9g4AvU155u9NeY5u5p8V4KtEHIDxWNmIOD2C09nDkk7DA22sw== @@ -1538,7 +1830,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@*", "@svgr/core@^8.1.0": +"@svgr/core@^8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -1584,14 +1876,14 @@ dependencies: "@tanstack/query-devtools" "5.61.4" -"@tanstack/react-query@^5.59.19", "@tanstack/react-query@^5.62.0": +"@tanstack/react-query@^5.59.19": version "5.59.19" resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.19.tgz" integrity sha512-xLRfyFyQOFcLltKCds0LijfC6/HQJrrTTnZB8ciyn74LIkVAm++vZJ6eUVG20RmJtdP8REdy7vSOYW4M3//XLA== dependencies: "@tanstack/query-core" "5.59.17" -"@testing-library/dom@>=7.21.4", "@testing-library/dom@10.4.0": +"@testing-library/dom@10.4.0": version "10.4.0" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz" integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ== @@ -1623,11 +1915,6 @@ resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz" integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz" @@ -1730,7 +2017,7 @@ resolved "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz" integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== -"@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6", "@types/estree@1.0.6": +"@types/estree@1.0.6", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6": version "1.0.6" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -1844,20 +2131,13 @@ resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== -"@types/node@*", "@types/node@^18.0.0 || >=20.0.0", "@types/node@^22.8.7": +"@types/node@*", "@types/node@^22.8.7": version "22.8.7" resolved "https://registry.npmjs.org/@types/node/-/node-22.8.7.tgz" integrity sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q== dependencies: undici-types "~6.19.8" -"@types/node@^20.3.1": - version "20.17.6" - resolved "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz" - integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ== - dependencies: - undici-types "~6.19.2" - "@types/node@>=10.0.0": version "22.9.0" resolved "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz" @@ -1865,6 +2145,13 @@ dependencies: undici-types "~6.19.8" +"@types/node@^20.3.1": + version "20.17.6" + resolved "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz" + integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ== + dependencies: + undici-types "~6.19.2" + "@types/oauth@*": version "0.9.6" resolved "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.6.tgz" @@ -1936,7 +2223,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.3.12", "@types/react@>=16": +"@types/react@*", "@types/react@^18.3.12": version "18.3.12" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz" integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw== @@ -2037,7 +2324,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^8.0.0", "@typescript-eslint/eslint-plugin@8.12.2": +"@typescript-eslint/eslint-plugin@8.12.2", "@typescript-eslint/eslint-plugin@^8.0.0": version "8.12.2" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz" integrity sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw== @@ -2052,7 +2339,7 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^8.0.0", "@typescript-eslint/parser@^8.0.0 || ^8.0.0-alpha.0", "@typescript-eslint/parser@8.12.2": +"@typescript-eslint/parser@8.12.2", "@typescript-eslint/parser@^8.0.0": version "8.12.2" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.12.2.tgz" integrity sha512-MrvlXNfGPLH3Z+r7Tk+Z5moZAc0dzdVjTgUgwsdGweH7lydysQsnSww3nAmsq8blFuRD5VRlAr9YdEFw3e6PBw== @@ -2127,16 +2414,6 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@^8.8.1": - version "8.14.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz" - integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.14.0" - "@typescript-eslint/types" "8.14.0" - "@typescript-eslint/typescript-estree" "8.14.0" - "@typescript-eslint/utils@8.12.2": version "8.12.2" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz" @@ -2147,6 +2424,16 @@ "@typescript-eslint/types" "8.12.2" "@typescript-eslint/typescript-estree" "8.12.2" +"@typescript-eslint/utils@^8.8.1": + version "8.14.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz" + integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.14.0" + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/typescript-estree" "8.14.0" + "@typescript-eslint/visitor-keys@8.12.2": version "8.12.2" resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz" @@ -2210,15 +2497,6 @@ dependencies: tinyspy "^3.0.0" -"@vitest/utils@^2.1.1": - version "2.1.5" - resolved "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.5.tgz" - integrity sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg== - dependencies: - "@vitest/pretty-format" "2.1.5" - loupe "^3.1.2" - tinyrainbow "^1.2.0" - "@vitest/utils@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz" @@ -2229,7 +2507,16 @@ loupe "^3.1.1" tinyrainbow "^1.2.0" -"@webassemblyjs/ast@^1.12.1", "@webassemblyjs/ast@1.12.1": +"@vitest/utils@^2.1.1": + version "2.1.5" + resolved "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.5.tgz" + integrity sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg== + dependencies: + "@vitest/pretty-format" "2.1.5" + loupe "^3.1.2" + tinyrainbow "^1.2.0" + +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz" integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== @@ -2330,7 +2617,7 @@ "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@^1.12.1", "@webassemblyjs/wasm-parser@1.12.1": +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz" integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== @@ -2360,10 +2647,13 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" @@ -2390,18 +2680,11 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.11.0, acorn@^8.14.0, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: version "8.14.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== -agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@^7.0.2: version "7.1.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" @@ -2409,28 +2692,6 @@ agent-base@^7.0.2: dependencies: debug "^4.3.4" -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.1.3: - version "4.6.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz" - integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv-formats@2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" @@ -2443,7 +2704,17 @@ ajv-keywords@^3.5.2: resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: +ajv@8.12.0: + version "8.12.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2453,7 +2724,7 @@ ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0: +ajv@^8.0.0, ajv@^8.11.0: version "8.17.1" resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== @@ -2463,26 +2734,6 @@ ajv@^8.0.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ajv@^8.11.0: - version "8.17.1" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" - integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ajv@8.12.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ansi-colors@4.1.3: version "4.1.3" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" @@ -2567,19 +2818,6 @@ append-field@^1.0.0: resolved "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz" integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - arg@^4.1.0: version "4.1.3" resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" @@ -2602,11 +2840,6 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.0.0: - version "5.3.2" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz" - integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== - aria-query@5.3.0: version "5.3.0" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz" @@ -2614,6 +2847,11 @@ aria-query@5.3.0: dependencies: dequal "^2.0.3" +aria-query@^5.0.0: + version "5.3.2" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz" + integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== + array-buffer-byte-length@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" @@ -2777,7 +3015,7 @@ axios@^1.7.7: form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-jest@^29.0.0, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -2840,43 +3078,6 @@ babel-preset-jest@^29.6.3: babel-plugin-jest-hoist "^29.6.3" babel-preset-current-node-syntax "^1.0.0" -"backend@file:/home/refactor-web40-juchumjuchum/packages/backend": - version "0.0.1" - resolved "file:packages/backend" - dependencies: - "@nestjs/common" "^10.0.0" - "@nestjs/config" "^3.3.0" - "@nestjs/core" "^10.0.0" - "@nestjs/passport" "^10.0.3" - "@nestjs/platform-express" "^10.0.0" - "@nestjs/platform-socket.io" "^10.4.8" - "@nestjs/schedule" "^4.1.1" - "@nestjs/swagger" "^8.0.5" - "@nestjs/typeorm" "^10.0.2" - "@nestjs/websockets" "^10.4.8" - async-mutex "^0.5.0" - axios "^1.7.7" - class-transformer "^0.5.1" - class-validator "^0.14.1" - dotenv "^16.4.5" - express-session "^1.18.1" - mysql2 "^3.11.4" - nest-winston "^1.9.7" - passport "^0.7.0" - passport-google-oauth20 "^2.0.0" - passport-local "^1.0.0" - reflect-metadata "^0.2.0" - rxjs "^7.8.1" - socket.io "^4.8.1" - sql-formatter "^15.4.9" - sql-highlight "^6.0.0" - typeorm "^0.3.20" - unzipper "^0.12.3" - web-push "^3.6.7" - winston "^3.17.0" - winston-daily-rotate-file "^5.0.0" - ws "^8.18.0" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -2887,7 +3088,7 @@ base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base64id@~2.0.0, base64id@2.0.0: +base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== @@ -2909,14 +3110,7 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bl@^4.0.3, bl@^4.1.0: +bl@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -2985,7 +3179,7 @@ browser-assert@^1.2.1: resolved "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz" integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== -browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0, "browserslist@>= 4.21.0": +browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: version "4.24.2" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz" integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== @@ -3047,30 +3241,6 @@ bytes@3.1.2: resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^15.2.0: - version "15.3.0" - resolved "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - cachedir@2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz" @@ -3123,16 +3293,15 @@ chai@^5.1.1: loupe "^3.1.0" pathval "^2.0.0" -chalk@^2.4.1: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== +chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" + ansi-styles "^4.1.0" + supports-color "^7.1.0" -chalk@^2.4.2: +chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3149,14 +3318,6 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2, chalk@4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^5.3.0: version "5.3.0" resolved "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz" @@ -3206,7 +3367,7 @@ cheerio@^1.0.0: undici "^6.19.5" whatwg-mimetype "^4.0.0" -chokidar@^3.5.2, chokidar@^3.5.3, chokidar@3.6.0: +chokidar@3.6.0, chokidar@^3.5.3: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -3221,16 +3382,6 @@ chokidar@^3.5.2, chokidar@^3.5.3, chokidar@3.6.0: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - chromatic@^11.15.0: version "11.18.1" resolved "https://registry.npmjs.org/chromatic/-/chromatic-11.18.1.tgz" @@ -3251,12 +3402,12 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz" integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== -class-transformer@*, "class-transformer@^0.4.0 || ^0.5.0", class-transformer@^0.5.1: +class-transformer@^0.5.1: version "0.5.1" resolved "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz" integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== -class-validator@*, "class-validator@^0.13.0 || ^0.14.0", class-validator@^0.14.1: +class-validator@^0.14.1: version "0.14.1" resolved "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz" integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ== @@ -3272,11 +3423,6 @@ class-variance-authority@^0.7.0: dependencies: clsx "2.0.0" -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz" @@ -3355,16 +3501,16 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== -clsx@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" - integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== - clsx@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== +clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + co@^4.6.0: version "4.6.0" resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" @@ -3389,16 +3535,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.6.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -3407,11 +3553,6 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - color@^3.1.3: version "3.2.1" resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" @@ -3435,25 +3576,15 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^4.0.0: +commander@4.1.1, commander@^4.0.0: version "4.1.1" resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^2.19.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== comment-json@4.2.5: version "4.2.5" @@ -3519,11 +3650,6 @@ consola@^2.15.0: resolved "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz" integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - content-disposition@0.5.4: version "0.5.4" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" @@ -3560,8 +3686,8 @@ conventional-commits-parser@^5.0.0: resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz" integrity sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA== dependencies: - is-text-path "^2.0.0" JSONStream "^1.3.5" + is-text-path "^2.0.0" meow "^12.0.1" split2 "^4.0.0" @@ -3580,16 +3706,16 @@ cookie-signature@1.0.7: resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz" integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -cookie@~0.7.2, cookie@0.7.2: - version "0.7.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz" - integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== - cookie@0.7.1: version "0.7.1" resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@0.7.2, cookie@~0.7.2: + version "0.7.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + cookiejar@^2.1.4: version "2.1.4" resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz" @@ -3600,7 +3726,7 @@ core-util-is@^1.0.3, core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cors@~2.8.5, cors@2.8.5: +cors@2.8.5, cors@~2.8.5: version "2.8.5" resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -3635,14 +3761,6 @@ cosmiconfig@^9.0.0: js-yaml "^4.1.0" parse-json "^5.2.0" -cosmiconfig@>=8.2: - version "9.0.0" - dependencies: - env-paths "^2.2.1" - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - create-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" @@ -3709,7 +3827,7 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -cz-conventional-changelog@^3.3.0, cz-conventional-changelog@3.3.0: +cz-conventional-changelog@3.3.0, cz-conventional-changelog@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz" integrity sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw== @@ -3781,54 +3899,42 @@ dayjs@^1.11.13, dayjs@^1.11.9: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: - ms "^2.1.1" + ms "2.0.0" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4, debug@4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: ms "^2.1.3" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" +dedent@0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== dedent@^1.0.0: version "1.5.3" resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz" integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== -dedent@0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - deep-eql@^5.0.1: version "5.0.2" resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz" integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - deep-is@^0.1.3: version "0.1.4" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" @@ -3874,17 +3980,12 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - denque@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz" integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== -depd@~2.0.0, depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -3909,11 +4010,6 @@ detect-indent@6.1.0: resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== -detect-libc@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" @@ -4026,7 +4122,7 @@ dotenv-expand@10.0.0: resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz" integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== -dotenv@^16.0.3, dotenv@^16.4.5, dotenv@16.4.5: +dotenv@16.4.5, dotenv@^16.0.3, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== @@ -4110,20 +4206,6 @@ encoding-sniffer@^0.2.0: iconv-lite "^0.6.3" whatwg-encoding "^3.1.1" -encoding@^0.1.0, encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - engine.io-client@~6.6.1: version "6.6.2" resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.2.tgz" @@ -4169,16 +4251,11 @@ entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -env-paths@^2.2.0, env-paths@^2.2.1: +env-paths@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" @@ -4294,7 +4371,7 @@ esbuild-register@^3.5.0: dependencies: debug "^4.3.4" -"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0", "esbuild@>=0.12 <1": +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0": version "0.24.0" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz" integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== @@ -4378,7 +4455,7 @@ escape-string-regexp@^4.0.0: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-prettier@*, eslint-config-prettier@^9.0.0: +eslint-config-prettier@^9.0.0: version "9.1.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== @@ -4451,6 +4528,14 @@ eslint-plugin-storybook@^0.11.0: "@typescript-eslint/utils" "^8.8.1" ts-dedent "^2.2.0" +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" @@ -4467,14 +4552,6 @@ eslint-scope@^8.2.0: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" @@ -4485,7 +4562,7 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^8.57.1, eslint@>=7.0.0, eslint@>=8.0.0: +eslint@^8.57.1: version "8.57.1" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz" integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== @@ -4529,45 +4606,6 @@ eslint-visitor-keys@^4.2.0: strip-ansi "^6.0.1" text-table "^0.2.0" -"eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0": - version "9.14.0" - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.18.0" - "@eslint/core" "^0.7.0" - "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.14.0" - "@eslint/plugin-kit" "^0.2.0" - "@humanfs/node" "^0.16.6" - "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.4.0" - "@types/estree" "^1.0.6" - "@types/json-schema" "^7.0.15" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - escape-string-regexp "^4.0.0" - eslint-scope "^8.2.0" - eslint-visitor-keys "^4.2.0" - espree "^10.3.0" - esquery "^1.5.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^8.0.0" - find-up "^5.0.0" - glob-parent "^6.0.2" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - json-stable-stringify-without-jsonify "^1.0.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - text-table "^0.2.0" - eslint@^9.13.0: version "9.14.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz" @@ -4609,103 +4647,16 @@ eslint@^9.13.0: optionator "^0.9.3" text-table "^0.2.0" -eslint@>=6: - version "9.14.0" +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.18.0" - "@eslint/core" "^0.7.0" - "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.14.0" - "@eslint/plugin-kit" "^0.2.0" - "@humanfs/node" "^0.16.6" - "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.4.0" - "@types/estree" "^1.0.6" - "@types/json-schema" "^7.0.15" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - escape-string-regexp "^4.0.0" - eslint-scope "^8.2.0" + acorn "^8.14.0" + acorn-jsx "^5.3.2" eslint-visitor-keys "^4.2.0" - espree "^10.3.0" - esquery "^1.5.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^8.0.0" - find-up "^5.0.0" - glob-parent "^6.0.2" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - json-stable-stringify-without-jsonify "^1.0.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - text-table "^0.2.0" - -eslint@>=7: - version "9.14.0" - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.18.0" - "@eslint/core" "^0.7.0" - "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.14.0" - "@eslint/plugin-kit" "^0.2.0" - "@humanfs/node" "^0.16.6" - "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.4.0" - "@types/estree" "^1.0.6" - "@types/json-schema" "^7.0.15" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - escape-string-regexp "^4.0.0" - eslint-scope "^8.2.0" - eslint-visitor-keys "^4.2.0" - espree "^10.3.0" - esquery "^1.5.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^8.0.0" - find-up "^5.0.0" - glob-parent "^6.0.2" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - json-stable-stringify-without-jsonify "^1.0.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - text-table "^0.2.0" - -espree@^10.0.1, espree@^10.3.0: - version "10.3.0" - resolved "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz" - integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== - dependencies: - acorn "^8.14.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^4.2.0" - -espree@^9.6.0: - version "9.6.1" - resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" -espree@^9.6.1: +espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== @@ -4790,11 +4741,6 @@ exit@^0.1.2: resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz" @@ -4899,7 +4845,7 @@ fast-glob@^3.3.0, fast-glob@^3.3.2: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -4909,7 +4855,7 @@ fast-levenshtein@^2.0.6: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fast-safe-stringify@^2.1.1, fast-safe-stringify@2.1.1: +fast-safe-stringify@2.1.1, fast-safe-stringify@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== @@ -4973,11 +4919,6 @@ file-stream-rotator@^0.6.1: dependencies: moment "^2.29.1" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - filelist@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" @@ -5030,15 +4971,7 @@ find-root@1.1.0: resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -5171,29 +5104,15 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -"frontend@file:/home/refactor-web40-juchumjuchum/packages/frontend": - version "0.0.0" - resolved "file:packages/frontend" - dependencies: - "@tanstack/react-query" "^5.59.19" - axios "^1.7.7" - class-variance-authority "^0.7.0" - clsx "^2.1.1" - dayjs "^1.11.13" - lightweight-charts "^4.2.1" - react "^18.3.1" - react-dom "^18.3.1" - react-error-boundary "^4.1.2" - react-lottie-player "^2.1.0" - react-router-dom "^6.28.0" - socket.io-client "^4.8.1" - tailwind-merge "^2.5.4" - zod "^3.23.8" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-extra@9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs-extra@^10.0.0: version "10.1.0" @@ -5213,23 +5132,6 @@ fs-extra@^11.2.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - fs-monkey@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz" @@ -5240,6 +5142,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -5260,20 +5167,6 @@ functions-have-names@^1.2.3: resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - generate-function@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz" @@ -5335,12 +5228,7 @@ git-raw-commits@^4.0.0: meow "^12.0.1" split2 "^4.0.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -5354,13 +5242,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - glob-promise@^4.2.0: version "4.2.2" resolved "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz" @@ -5373,10 +5254,10 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^10.3.10: - version "10.4.5" - resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== +glob@10.4.2: + version "10.4.2" + resolved "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz" + integrity sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w== dependencies: foreground-child "^3.1.0" jackspeak "^3.1.2" @@ -5385,7 +5266,7 @@ glob@^10.3.10: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@7.2.3: +glob@7.2.3, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -5397,10 +5278,10 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@7.2.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@10.4.2: - version "10.4.2" - resolved "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz" - integrity sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w== +glob@^10.3.10: + version "10.4.5" + resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== dependencies: foreground-child "^3.1.0" jackspeak "^3.1.2" @@ -5473,7 +5354,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -5527,11 +5408,6 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -5571,16 +5447,6 @@ htmlparser2@^9.1.0: domutils "^3.1.0" entities "^4.5.0" -http_ece@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz" - integrity sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA== - -http-cache-semantics@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -5592,22 +5458,10 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" +http_ece@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/http_ece/-/http_ece-1.2.0.tgz" + integrity sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA== https-proxy-agent@^7.0.0: version "7.0.5" @@ -5622,40 +5476,19 @@ human-signals@^2.1.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - husky@^8.0.0: version "8.0.3" resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== -iconv-lite@^0.4.24, iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -iconv-lite@0.6.3: +iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -5703,11 +5536,6 @@ indent-string@^4.0.0: resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -5716,44 +5544,20 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.4: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - ini@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz" integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== -inquirer@^6.3.1: - version "6.5.2" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== inquirer@8.2.5: version "8.2.5" @@ -5818,6 +5622,25 @@ inquirer@9.2.15: strip-ansi "^6.0.1" wrap-ansi "^6.2.0" +inquirer@^6.3.1: + version "6.5.2" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + internal-slot@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz" @@ -5827,14 +5650,6 @@ internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" -ip-address@^9.0.5: - version "9.0.5" - resolved "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz" - integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== - dependencies: - jsbn "1.1.0" - sprintf-js "^1.1.3" - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" @@ -5958,11 +5773,6 @@ is-interactive@^1.0.0: resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - is-negative-zero@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" @@ -6368,7 +6178,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -6521,7 +6331,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.0.0, jest@^29.5.0: +jest@^29.5.0: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -6531,7 +6341,7 @@ jest@^29.0.0, jest@^29.5.0: import-local "^3.0.2" jest-cli "^29.7.0" -jiti@*, jiti@^1.21.0, jiti@^1.21.6: +jiti@^1.21.0, jiti@^1.21.6: version "1.21.6" resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== @@ -6541,6 +6351,13 @@ jiti@*, jiti@^1.21.0, jiti@^1.21.6: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" @@ -6549,18 +6366,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.1.0, js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsbn@1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz" - integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== - jsdoc-type-pratt-parser@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz" @@ -6632,14 +6437,6 @@ jsonparse@^1.2.0: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - jwa@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz" @@ -6795,7 +6592,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.17.12, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.5, lodash@4.17.21: +lodash@4.17.21, lodash@^4.17.12, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.5: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6866,13 +6663,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - lru-cache@^7.14.1: version "7.18.3" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" @@ -6893,6 +6683,13 @@ lz-string@^1.5.0: resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz" integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== +magic-string@0.30.8: + version "0.30.8" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz" + integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + magic-string@^0.27.0: version "0.27.0" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz" @@ -6907,13 +6704,6 @@ magic-string@^0.30.0: dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" -magic-string@0.30.8: - version "0.30.8" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz" - integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - make-dir@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" @@ -6926,28 +6716,6 @@ make-error@^1.1.1, make-error@^1.3.6: resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - makeerror@1.0.12: version "1.0.12" resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" @@ -6994,16 +6762,16 @@ merge-stream@^2.0.0: resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz" - integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== - merge2@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +merge@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz" + integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== + methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" @@ -7049,11 +6817,6 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" @@ -7085,106 +6848,21 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - minimist@1.2.7: version "1.2.7" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^3.1.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^3.1.1: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^3.1.3: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: version "7.1.2" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -minizlib@^2.0.0, minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - mkdirp@^0.5.1, mkdirp@^0.5.4: version "0.5.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" @@ -7192,16 +6870,6 @@ mkdirp@^0.5.1, mkdirp@^0.5.4: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - mkdirp@^2.1.3: version "2.1.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz" @@ -7217,16 +6885,16 @@ moo@^0.5.0: resolved "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz" integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q== -ms@^2.0.0, ms@^2.1.1, ms@^2.1.3, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +ms@2.1.3, ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multer@1.4.4-lts.1: version "1.4.4-lts.1" resolved "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz" @@ -7255,7 +6923,7 @@ mute-stream@1.0.0: resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -"mysql2@^2.2.5 || ^3.0.1", mysql2@^3.11.4: +mysql2@^3.11.4: version "3.11.4" resolved "https://registry.npmjs.org/mysql2/-/mysql2-3.11.4.tgz" integrity sha512-Z2o3tY4Z8EvSRDwknaC40MdZ3+m0sKbpnXrShQLdxPrAvcNli7jLrD2Zd2IzsRMw4eK9Yle500FDmlkIqp+krg== @@ -7291,11 +6959,6 @@ nanoid@^3.3.7: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -7311,7 +6974,7 @@ nearley@^2.20.1: railroad-diagrams "^1.0.0" randexp "0.4.6" -negotiator@^0.6.2, negotiator@0.6.3: +negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -7336,23 +6999,11 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-abi@^3.3.0: - version "3.72.0" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.72.0.tgz" - integrity sha512-a28z9xAQXvDh40lVCknWCP5zYTZt6Av8HZqZ63U5OWxTcP20e3oOIy8yHkYfctQM2adR8ru1GxWCkS0gS+WYKA== - dependencies: - semver "^7.3.5" - node-abort-controller@^3.0.1: version "3.1.1" resolved "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz" integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== -node-addon-api@^7.0.0: - version "7.1.1" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz" - integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== - node-emoji@1.11.0: version "1.11.0" resolved "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz" @@ -7367,22 +7018,6 @@ node-fetch@^2.6.1: dependencies: whatwg-url "^5.0.0" -node-gyp@8.x: - version "8.4.1" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" @@ -7393,13 +7028,6 @@ node-releases@^2.0.18: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -7417,16 +7045,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - nth-check@^2.0.1: version "2.1.1" resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" @@ -7444,7 +7062,7 @@ object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-hash@^3.0.0, object-hash@3.0.0: +object-hash@3.0.0, object-hash@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== @@ -7509,7 +7127,7 @@ on-headers@~1.0.2: resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -7558,7 +7176,7 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" -ora@^5.4.1, ora@5.4.1: +ora@5.4.1, ora@^5.4.1: version "5.4.1" resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -7625,13 +7243,6 @@ p-locate@^6.0.0: dependencies: p-limit "^4.0.0" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" @@ -7738,7 +7349,7 @@ passport-strategy@1.x.x: resolved "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz" integrity sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA== -"passport@^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0", passport@^0.7.0: +passport@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz" integrity sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ== @@ -7810,6 +7421,11 @@ picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== +picomatch@4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz" + integrity sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" @@ -7820,11 +7436,6 @@ picomatch@^4.0.2: resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz" integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== -picomatch@4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz" - integrity sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg== - pify@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" @@ -7903,7 +7514,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.43, postcss@^8.4.47, postcss@>=8.0.9: +postcss@^8.4.23, postcss@^8.4.43, postcss@^8.4.47: version "8.4.47" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz" integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== @@ -7912,24 +7523,6 @@ postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.2 picocolors "^1.1.0" source-map-js "^1.2.1" -prebuild-install@^7.1.1: - version "7.1.2" - resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz" - integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -7947,7 +7540,7 @@ prettier-plugin-tailwindcss@^0.6.8: resolved "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.8.tgz" integrity sha512-dGu3kdm7SXPkiW4nzeWKCl3uoImdd5CTZEJGxyypEPL37Wj0HT2pLqjrvSei1nTeuQfO4PUfjeW5cTUNRLZ4sA== -"prettier@^2 || ^3", prettier@^3.0, prettier@^3.3.3, prettier@>=3.0.0: +prettier@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz" integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== @@ -7980,19 +7573,6 @@ process@^0.11.10: resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - prompts@^2.0.1: version "2.4.2" resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" @@ -8014,14 +7594,6 @@ proxy-from-env@^1.1.0: resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pump@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz" - integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^2.1.0: version "2.3.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" @@ -8032,7 +7604,7 @@ pure-rand@^6.0.0: resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -qs@^6.11.0, qs@6.13.0: +qs@6.13.0, qs@^6.11.0: version "6.13.0" resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz" integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== @@ -8084,16 +7656,6 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - react-confetti@^6.1.0: version "6.1.0" resolved "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz" @@ -8122,7 +7684,7 @@ react-docgen@^7.0.0: resolve "^1.22.1" strip-indent "^4.0.0" -"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", react-dom@^18.3.1, react-dom@>=16.8: +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -8176,7 +7738,7 @@ react-router@6.28.0: dependencies: "@remix-run/router" "1.21.0" -"react@^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.3.0 || ^17.0.1 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react@^18 || ^19", react@^18.3.1, react@>=16, react@>=16.13.1, react@>=16.8: +"react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -8190,7 +7752,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^2.0.2: +readable-stream@^2.0.2, readable-stream@^2.2.2: version "2.3.8" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -8203,20 +7765,7 @@ readable-stream@^2.0.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^2.2.2: - version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: +readable-stream@^3.4.0, readable-stream@^3.6.2: version "3.6.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -8251,7 +7800,7 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -"reflect-metadata@^0.1.12 || ^0.2.0", "reflect-metadata@^0.1.13 || ^0.2.0", reflect-metadata@^0.2.0, reflect-metadata@^0.2.1: +reflect-metadata@^0.2.0, reflect-metadata@^0.2.1: version "0.2.2" resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== @@ -8346,11 +7895,6 @@ ret@~0.1.10: resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" @@ -8375,7 +7919,7 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" -rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^4.20.0: +rollup@^4.20.0: version "4.24.4" resolved "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz" integrity sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA== @@ -8419,6 +7963,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +rxjs@7.8.1, rxjs@^7.5.5, rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + rxjs@^6.4.0: version "6.6.7" resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" @@ -8426,13 +7977,6 @@ rxjs@^6.4.0: dependencies: tslib "^1.9.0" -rxjs@^7.1.0, rxjs@^7.2.0, rxjs@^7.5.5, rxjs@^7.8.1, rxjs@7.8.1: - version "7.8.1" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - safe-array-concat@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz" @@ -8443,7 +7987,7 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -8467,7 +8011,7 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz" integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== -safer-buffer@^2.1.0, "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8488,12 +8032,7 @@ schema-utils@^3.1.1, schema-utils@^3.2.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -8544,11 +8083,6 @@ serve-static@1.16.2: parseurl "~1.3.3" send "0.19.0" -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" @@ -8616,20 +8150,6 @@ signal-exit@^4.0.1: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" - integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== - dependencies: - decompress-response "^6.0.0" - once "^1.3.1" - simple-concat "^1.0.0" - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" @@ -8647,11 +8167,6 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - snake-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" @@ -8686,10 +8201,10 @@ socket.io-parser@~4.2.4: "@socket.io/component-emitter" "~3.1.0" debug "~4.3.1" -socket.io@^4.8.1: - version "4.8.1" - resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz" - integrity sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg== +socket.io@4.8.0: + version "4.8.0" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz" + integrity sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA== dependencies: accepts "~1.3.4" base64id "~2.0.0" @@ -8699,10 +8214,10 @@ socket.io@^4.8.1: socket.io-adapter "~2.5.2" socket.io-parser "~4.2.4" -socket.io@4.8.0: - version "4.8.0" - resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz" - integrity sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA== +socket.io@^4.8.1: + version "4.8.1" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz" + integrity sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg== dependencies: accepts "~1.3.4" base64id "~2.0.0" @@ -8712,36 +8227,11 @@ socket.io@4.8.0: socket.io-adapter "~2.5.2" socket.io-parser "~4.2.4" -socks-proxy-agent@^6.0.0: - version "6.2.1" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz" - integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.8.3" - resolved "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz" - integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== - dependencies: - ip-address "^9.0.5" - smart-buffer "^4.2.0" - source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -source-map-support@^0.5.21, source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" @@ -8750,31 +8240,29 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map-support@^0.5.21, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" -source-map@^0.7.4: +source-map@0.7.4, source-map@^0.7.4: version "0.7.4" resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== -source-map@0.7.4: - version "0.7.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== split2@^4.0.0: version "4.2.0" resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== -sprintf-js@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz" - integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" @@ -8794,30 +8282,11 @@ sql-highlight@^6.0.0: resolved "https://registry.npmjs.org/sql-highlight/-/sql-highlight-6.0.0.tgz" integrity sha512-+fLpbAbWkQ+d0JEchJT/NrRRXbYRNbG15gFpANx73EwxQB1PRjj+k/OI0GTU0J63g8ikGkJECQp9z8XEJZvPRw== -sqlite3@^5.0.3: - version "5.1.7" - resolved "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz" - integrity sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog== - dependencies: - bindings "^1.5.0" - node-addon-api "^7.0.0" - prebuild-install "^7.1.1" - tar "^6.1.11" - optionalDependencies: - node-gyp "8.x" - sqlstring@^2.3.2: version "2.3.3" resolved "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz" integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== -ssri@^8.0.0, ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - stack-trace@0.0.x: version "0.0.10" resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" @@ -8835,7 +8304,7 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"storybook@^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0", storybook@^8.4.3, storybook@8.4.3: +storybook@8.4.3: version "8.4.3" resolved "https://registry.npmjs.org/storybook/-/storybook-8.4.3.tgz" integrity sha512-n+6ME+APinsx0zjNTmx3SntJ4iCgoTK7TsxUC8+op/rUAA8hNbD+/NT7Qx/F5peHNchVeVFGtebPDAHU9g1M/Q== @@ -8847,20 +8316,6 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - string-length@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -8878,15 +8333,6 @@ string-length@^4.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", 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" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^2.1.0: version "2.1.1" resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" @@ -8895,6 +8341,15 @@ string-width@^2.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.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" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + 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" @@ -8932,6 +8387,20 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -8960,35 +8429,23 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" -strip-ansi@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" +strip-bom@4.0.0, strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-bom@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" @@ -9008,16 +8465,11 @@ strip-indent@^4.0.0: dependencies: min-indent "^1.0.1" -strip-json-comments@^3.1.1, strip-json-comments@3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - sucrase@^3.32.0: version "3.35.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz" @@ -9143,39 +8595,6 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar-fs@^2.0.0: - version "2.1.2" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz" - integrity sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.2.1" - resolved "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - temp@^0.9.0: version "0.9.4" resolved "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz" @@ -9195,7 +8614,7 @@ terser-webpack-plugin@^5.3.10: serialize-javascript "^6.0.1" terser "^5.26.0" -terser@^5.26.0, terser@^5.4.0: +terser@^5.26.0: version "5.36.0" resolved "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz" integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w== @@ -9243,7 +8662,7 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -through@^2.3.6, "through@>=2.2.7 <3": +"through@>=2.2.7 <3", through@^2.3.6: version "2.3.8" resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -9355,7 +8774,7 @@ ts-mockito@^2.6.1: dependencies: lodash "^4.17.5" -ts-node@^10.7.0, ts-node@^10.9.1, ts-node@>=9.0.0: +ts-node@^10.9.1: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -9383,6 +8802,15 @@ tsconfig-paths-webpack-plugin@4.1.0: enhanced-resolve "^5.7.0" tsconfig-paths "^4.1.2" +tsconfig-paths@4.2.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + tsconfig-paths@^3.15.0: version "3.15.0" resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" @@ -9393,14 +8821,10 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0, tsconfig-paths@4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslib@^1.9.0: version "1.14.1" @@ -9412,18 +8836,6 @@ tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0, tslib@^2.6 resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tslib@2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz" - integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - tween-functions@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz" @@ -9513,7 +8925,7 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typeorm@^0.3.0, typeorm@^0.3.20: +typeorm@^0.3.20: version "0.3.20" resolved "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz" integrity sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q== @@ -9543,16 +8955,16 @@ typescript-eslint@^8.11.0: "@typescript-eslint/parser" "8.12.2" "@typescript-eslint/utils" "8.12.2" -typescript@*, typescript@^5.1.3, typescript@^5.6.3, "typescript@>= 4.2.x", "typescript@>= 4.3.x", typescript@>=2.7, typescript@>=4, typescript@>=4.2.0, "typescript@>=4.3 <6", typescript@>=4.8.2, typescript@>=4.9.5, typescript@~5.6.2: - version "5.6.3" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz" - integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== - -typescript@>3.6.0, typescript@5.3.3: +typescript@5.3.3: version "5.3.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@^5.1.3, typescript@^5.6.3, typescript@~5.6.2: + version "5.6.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== + uid-safe@~2.1.5: version "2.1.5" resolved "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz" @@ -9560,6 +8972,11 @@ uid-safe@~2.1.5: dependencies: random-bytes "~1.0.0" +uid2@0.0.x: + version "0.0.4" + resolved "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz" + integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA== + uid@2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz" @@ -9567,11 +8984,6 @@ uid@2.0.2: dependencies: "@lukeed/csprng" "^1.0.0" -uid2@0.0.x: - version "0.0.4" - resolved "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz" - integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" @@ -9597,26 +9009,12 @@ unicorn-magic@^0.1.0: resolved "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz" integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - universalify@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -9678,21 +9076,21 @@ util@^0.12.5: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -utils-merge@^1.0.1, utils-merge@1.0.1, utils-merge@1.x.x: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^9.0.0, uuid@9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - uuid@10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz" integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== +uuid@9.0.1, uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" @@ -9726,7 +9124,7 @@ vite-plugin-svgr@^4.3.0: "@svgr/core" "^8.1.0" "@svgr/plugin-jsx" "^8.1.0" -"vite@^3.0.0 || ^4.0.0 || ^5.0.0", "vite@^4.0.0 || ^5.0.0", "vite@^4.2.0 || ^5.0.0", vite@^5.4.10, vite@>=2.6.0: +vite@^5.4.10: version "5.4.10" resolved "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz" integrity sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ== @@ -9780,7 +9178,7 @@ webpack-node-externals@3.0.0: resolved "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz" integrity sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ== -webpack-sources@^3, webpack-sources@^3.2.3: +webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== @@ -9790,7 +9188,7 @@ webpack-virtual-modules@^0.6.2: resolved "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz" integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== -webpack@^5.0.0, webpack@^5.1.0, webpack@^5.11.0, webpack@5.94.0: +webpack@5.94.0: version "5.94.0" resolved "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz" integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== @@ -9868,20 +9266,13 @@ which@^1.2.14: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - winston-daily-rotate-file@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-5.0.0.tgz" @@ -9901,7 +9292,7 @@ winston-transport@^4.7.0, winston-transport@^4.9.0: readable-stream "^3.6.2" triple-beam "^1.3.0" -winston@^3, winston@^3.0.0, winston@^3.17.0: +winston@^3.17.0: version "3.17.0" resolved "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz" integrity sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw== @@ -9932,16 +9323,7 @@ word-wrap@^1.0.3, word-wrap@^1.2.3, word-wrap@^1.2.5: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.2.0: +wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== @@ -9981,12 +9363,7 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.18.0: - version "8.18.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== - -ws@^8.2.3: +ws@^8.18.0, ws@^8.2.3: version "8.18.0" resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== @@ -10016,26 +9393,21 @@ yallist@^3.0.2: resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^2.3.4: version "2.6.0" resolved "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz" integrity sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ== +yargs-parser@21.1.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.1.1, yargs-parser@21.1.1: - version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - yargs@^16.0.0: version "16.2.0" resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" From 3286d2fb5ed32ab595bee2680e04b036281aaf8e Mon Sep 17 00:00:00 2001 From: DongHoonYu96 Date: Thu, 6 Feb 2025 16:18:26 +0900 Subject: [PATCH 34/34] =?UTF-8?q?chore:=20=EC=A3=BC=EC=8B=9D=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=20=EC=9A=94=EC=95=BD=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/news/StockNewsOrchestrationService.ts | 18 +++++++++--------- .../backend/src/news/newsSummary.service.ts | 12 +++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/backend/src/news/StockNewsOrchestrationService.ts b/packages/backend/src/news/StockNewsOrchestrationService.ts index cd167ce2..edf45eeb 100644 --- a/packages/backend/src/news/StockNewsOrchestrationService.ts +++ b/packages/backend/src/news/StockNewsOrchestrationService.ts @@ -20,15 +20,15 @@ export class StockNewsOrchestrationService { public async orchestrateStockProcessing() { const stockNameList = [ '삼성전자', - // 'SK하이닉스', - // 'LG에너지솔루션', - // '삼성바이오로직스', - // '현대차', - // '기아', - // '셀트리온', - // 'NAVER', - // 'KB금융', - // 'HD현대중공업', + 'SK하이닉스', + 'LG에너지솔루션', + '삼성바이오로직스', + '현대차', + '기아', + '셀트리온', + 'NAVER', + 'KB금융', + 'HD현대중공업', ]; // 주식 데이터 크롤링 for (const stockName of stockNameList) { diff --git a/packages/backend/src/news/newsSummary.service.ts b/packages/backend/src/news/newsSummary.service.ts index 64e5326d..0d103194 100644 --- a/packages/backend/src/news/newsSummary.service.ts +++ b/packages/backend/src/news/newsSummary.service.ts @@ -44,7 +44,7 @@ export class NewsSummaryService { const summarizedNews = new CreateStockNewsDto(); summarizedNews.stock_id = content.stockId; summarizedNews.stock_name = content.stockName; - summarizedNews.link = content.link.join(","); + summarizedNews.link = this.formatLinks(content?.link); summarizedNews.title = content.title; summarizedNews.summary = content.summary; summarizedNews.positive_content = content.positive_content; @@ -62,6 +62,16 @@ export class NewsSummaryService { } } + private formatLinks(links: unknown): string { + if (Array.isArray(links)) { + return links.join(","); + } + if (typeof links === 'string') { + return links; + } + return ""; + } + private getSystemPrompt() { return '당신은 AI 기반 주식 분석 전문가입니다. 입력으로 주어지는 JSON 형식의 뉴스 데이터를 분석하여, JSON 형식으로 종합적인 분석 결과를 도출해 주세요.\r\n\r\n[입력 형식]\r\n{\r\n "stock_name": "종목 이름",\r\n "news": [\r\n {\r\n "date": "기사 날짜",\r\n "title": "기사 제목",\r\n "content": "기사 내용",\r\n "url": "기사 링크"\r\n },\r\n ...\r\n ]\r\n}\r\n\r\n[출력 형식]\r\n{\r\n "stock_id": "종목 번호",\r\n "stock_name": "종목 이름",\r\n "link": "기사 링크들",\r\n "title": "요약 타이틀",\r\n "summary": "요약 내용",\r\n "positive_content": "긍정적 측면",\r\n "negative_content": "부정적 측면"\r\n}\r\n\r\n[분석 지침]\r\n분석해야 할 항목은 다음과 같습니다:\r\n\r\n1. **종목 정보:**\r\n - stock_name을 기반으로 해당 종목의 stock_id를 찾아 포함\r\n - 제공된 모든 뉴스의 url을 쉼표로 구분하여 link 필드에 포함\r\n\r\n2. **종합 분석:**\r\n - title: 전체 뉴스 내용을 관통하는 핵심 주제나 이슈를 간단한 제목으로 작성\r\n - summary: 모든 뉴스 기사의 주요 내용을 종합적으로 요약하여 작성\r\n\r\n3. **영향 분석:**\r\n - positive_content: 기업, 산업, 경제에 긍정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n - negative_content: 위험 요소나 부정적 영향을 줄 수 있는 요소들을 분석하여 작성\r\n\r\n[제약 사항]\r\n1. 모든 뉴스 기사의 내용을 종합적으로 고려하여 분석합니다.\r\n2. positive_content 와 negative_content 내용이 없는 경우 "해당사항 없음"으로 작성합니다.\r\n3. 요약과 분석은 객관적이고 사실에 기반하여 작성합니다.\r\n4. 특정 종목의 stock_id를 모르는 경우 빈 문자열("")을 반환합니다.\r\n5. 반드시 JSON 형식으로 응답합니다.'; }