diff --git a/lerna.json b/lerna.json index 4663f680..046983d5 100644 --- a/lerna.json +++ b/lerna.json @@ -1,7 +1,7 @@ { "useNx": false, "packages": ["libs/*", "apps/*"], - "version": "13.0.0", + "version": "14.0.0-pr76.14", "command": { "version": { "allowBranch": "*", diff --git a/libs/components/package.json b/libs/components/package.json index 0dcebe58..4ab49584 100644 --- a/libs/components/package.json +++ b/libs/components/package.json @@ -1,6 +1,6 @@ { "name": "@shiftcode/ngx-components", - "version": "13.0.0", + "version": "14.0.0-pr76.14", "repository": "https://github.com/shiftcode/sc-ng-commons-public", "license": "MIT", "author": "shiftcode GmbH ", @@ -14,14 +14,14 @@ "tslib": "^2.5.0" }, "peerDependencies": { - "@angular/animations": "^21.0.3", + "@angular/animations": "^21.0.0", "@angular/cdk": "^21.0.0", - "@angular/common": "^21.0.3", - "@angular/core": "^21.0.3", - "@angular/forms": "^21.0.3", - "@angular/router": "^21.0.3", - "@shiftcode/logger": "^3.0.0", - "@shiftcode/ngx-core": "^13.0.0 || ^13.0.0-pr63", + "@angular/common": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/forms": "^21.0.0", + "@angular/router": "^21.0.0", + "@shiftcode/logger": "^4.0.0 || ^4.0.0-pr250", + "@shiftcode/ngx-core": "^14.0.0 || ^14.0.0-pr76", "rxjs": "^6.5.3 || ^7.4.0" } } diff --git a/libs/core/package.json b/libs/core/package.json index ab530636..215a8e49 100644 --- a/libs/core/package.json +++ b/libs/core/package.json @@ -1,6 +1,6 @@ { "name": "@shiftcode/ngx-core", - "version": "13.0.0", + "version": "14.0.0-pr76.14", "repository": "https://github.com/shiftcode/sc-ng-commons-public", "license": "MIT", "author": "shiftcode GmbH ", @@ -14,11 +14,11 @@ "tslib": "^2.5.0" }, "peerDependencies": { - "@angular/common": "^21.0.3", - "@angular/core": "^21.0.3", - "@angular/platform-browser": "^21.0.3", - "@angular/router": "^21.0.3", - "@shiftcode/logger": "^3.0.0", + "@angular/common": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/router": "^21.0.0", + "@shiftcode/logger": "^4.0.0 || ^4.0.0-pr250", "@shiftcode/utilities": "^4.0.0", "rxjs": "^6.5.3 || ^7.4.0" } diff --git a/libs/core/src/lib/logger/console/console-log-transport.service.ts b/libs/core/src/lib/logger/browser-console/browser-console-log-transport.service.ts similarity index 61% rename from libs/core/src/lib/logger/console/console-log-transport.service.ts rename to libs/core/src/lib/logger/browser-console/browser-console-log-transport.service.ts index d7b1ee4f..ebeab7da 100644 --- a/libs/core/src/lib/logger/console/console-log-transport.service.ts +++ b/libs/core/src/lib/logger/browser-console/browser-console-log-transport.service.ts @@ -1,15 +1,22 @@ -/* eslint-disable no-console */ import { isPlatformServer } from '@angular/common' -import { inject, Injectable, PLATFORM_ID } from '@angular/core' +import { inject, Injectable, InjectionToken, PLATFORM_ID } from '@angular/core' import { LogLevel, LogTransport } from '@shiftcode/logger' -import { leadingZero } from '../helper/leading-zero.function' -import { CONSOLE_LOG_TRANSPORT_CONFIG } from './console-log-transport-config.injection-token' +import { loggingTimeFormat } from '../helper/logging-time-format.const' + +export interface BrowserConsoleLogTransportConfig { + logLevel: LogLevel +} + +export const BROWSER_CONSOLE_LOG_TRANSPORT_CONFIG = new InjectionToken( + 'BROWSER_CONSOLE_LOG_TRANSPORT_CONFIG', + { factory: () => ({ logLevel: LogLevel.DEBUG }) }, +) @Injectable({ providedIn: 'root' }) -export class ConsoleLogTransport extends LogTransport { +export class BrowserConsoleLogTransportService extends LogTransport { constructor() { - super(inject(CONSOLE_LOG_TRANSPORT_CONFIG).logLevel) + super(inject(BROWSER_CONSOLE_LOG_TRANSPORT_CONFIG).logLevel) if (isPlatformServer(inject(PLATFORM_ID))) { throw new Error('This log transport is only for client side use - consider using "NodeConsoleLogTransport"') } @@ -17,12 +24,8 @@ export class ConsoleLogTransport extends LogTransport { log(level: LogLevel, clazzName: string, color: string, timestamp: Date, args: any[]) { if (this.isLevelEnabled(level)) { - const now = [ - leadingZero(2, timestamp.getHours()), - leadingZero(2, timestamp.getMinutes()), - leadingZero(2, timestamp.getSeconds()), - leadingZero(3, timestamp.getMilliseconds()), - ].join(':') // 'HH:mm:ss:SSS' + const now = loggingTimeFormat.format(timestamp) + const firstArgument = args.splice(0, 1)[0] if (typeof firstArgument === 'string') { @@ -32,6 +35,7 @@ export class ConsoleLogTransport extends LogTransport { args.splice(0, 0, `%c${now} - ${clazzName} ::`, `color:${color}`, firstArgument) } + /* eslint-disable no-console */ switch (level) { case LogLevel.DEBUG: console.debug(...args) @@ -47,7 +51,10 @@ export class ConsoleLogTransport extends LogTransport { break case LogLevel.OFF: break + default: + return level // exhaustive check } + /* eslint-enable no-console */ } } } diff --git a/libs/core/src/lib/logger/browser-console/with-browser-console-transport.function.ts b/libs/core/src/lib/logger/browser-console/with-browser-console-transport.function.ts new file mode 100644 index 00000000..e5f0bb34 --- /dev/null +++ b/libs/core/src/lib/logger/browser-console/with-browser-console-transport.function.ts @@ -0,0 +1,23 @@ +import { LogTransport } from '@shiftcode/logger' + +import { ValueOrFactory } from '../helper/value-or-factory.type' +import { LoggerFeature } from '../logger-feature.type' +import { LoggerFeatureKind } from '../logger-feature-kind.enum' +import { + BROWSER_CONSOLE_LOG_TRANSPORT_CONFIG, + BrowserConsoleLogTransportConfig, + BrowserConsoleLogTransportService, +} from './browser-console-log-transport.service' + +export function withBrowserConsoleTransport(config: ValueOrFactory): LoggerFeature { + return { + kind: LoggerFeatureKind.TRANSPORT, + providers: [ + { + provide: BROWSER_CONSOLE_LOG_TRANSPORT_CONFIG, + ...(typeof config === 'function' ? { useFactory: config } : { useValue: config }), + }, + { provide: LogTransport, useClass: BrowserConsoleLogTransportService, multi: true }, + ], + } +} diff --git a/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-api.service.ts b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-api.service.ts new file mode 100644 index 00000000..a9558c5b --- /dev/null +++ b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-api.service.ts @@ -0,0 +1,99 @@ +// eslint-disable-next-line max-classes-per-file +import { inject, Injectable } from '@angular/core' +import { ContentType } from '@shiftcode/utilities' +import { CommonHttpHeader } from '@shiftcode/utilities' + +import { CLOUD_WATCH_LOG_V2_CONFIG } from './cloud-watch-log-config.injection-token' + +export interface LogStream { + logStreamName: string + creationTime: number + lastIngestionTime: number | null +} + +export interface LogEvent { + message: string + timestamp: number +} + +export interface WriteLogEvents { + logEvents: LogEvent[] +} + +export class HttpError extends Error { + override readonly name: string = 'HttpError' + + constructor( + readonly statusCode: number, + message: string, + ) { + super(`${statusCode} - ${message}`) + } +} + +export class HttpApiError extends HttpError { + override readonly name: string = 'HttpApiError' + + constructor( + statusCode: number, + readonly errorCode: string, + message: string, + ) { + super(statusCode, `${message} (${errorCode})`) + } +} + +enum ApiPath { + STREAMS = 'streams', + STREAM_LOGS = 'logs', +} + +@Injectable({ providedIn: 'root' }) +export class CloudWatchLogV2ApiService { + private readonly apiUrl = inject(CLOUD_WATCH_LOG_V2_CONFIG).apiUrl + + async createLogStream(logStreamName: string): Promise { + const resp = await fetch(new URL(ApiPath.STREAMS, this.apiUrl), { + method: 'POST', + headers: { [CommonHttpHeader.CONTENT_TYPE]: ContentType.JSON }, + body: JSON.stringify({ logStreamName }), + }) + await this.handleError(resp) + } + + async describeLogStream(logStreamName: string): Promise { + const result = await fetch(new URL(`${ApiPath.STREAMS}/${logStreamName}`, this.apiUrl), { + method: 'GET', + headers: { [CommonHttpHeader.CONTENT_TYPE]: ContentType.JSON }, + }) + await this.handleError(result) + return (await result.json()) as LogStream + } + + async writeLogs(logStreamName: string, logs: LogEvent[]): Promise { + // we do not use the sendBeacon API since it will fail with cors preflight and would require ugly workarounds + const resp = await fetch(new URL(`${ApiPath.STREAMS}/${logStreamName}/${ApiPath.STREAM_LOGS}`, this.apiUrl), { + method: 'POST', + headers: { [CommonHttpHeader.CONTENT_TYPE]: ContentType.JSON }, + body: JSON.stringify({ logEvents: logs } satisfies WriteLogEvents), + keepalive: true, // do not abort request on page unload + }) + await this.handleError(resp) + } + + private async handleError(resp: Response): Promise { + if (!resp.ok) { + const errorResponse: object = (await resp.json().catch(() => ({}))) ?? {} + if ( + 'message' in errorResponse && + typeof errorResponse.message === 'string' && + 'code' in errorResponse && + typeof errorResponse.code === 'string' + ) { + throw new HttpApiError(resp.status, errorResponse.code, errorResponse.message) + } else { + throw new HttpError(resp.status, 'unknown error') + } + } + } +} diff --git a/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-config.injection-token.ts b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-config.injection-token.ts new file mode 100644 index 00000000..cd04c0d8 --- /dev/null +++ b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-config.injection-token.ts @@ -0,0 +1,28 @@ +import { InjectionToken } from '@angular/core' +import { LogLevel } from '@shiftcode/logger' + +export interface CloudWatchLogV2Config { + logLevel: LogLevel + + /** + * the url of the CloudWatchApi Construct from @shiftcode/cdk-utils + */ + apiUrl: string + + /** milliseconds until logs are flushed to aws */ + flushInterval: number + + /** + * replacer function for JSON.stringify + * @default {@link jsonMapSetStringifyReplacer} + */ + jsonStringifyReplacer?: (key: string, value: any) => any + + /** + * max number of sub-threshold log events to buffer before dropping oldest. + * @default 100 + */ + bufferSize?: number +} + +export const CLOUD_WATCH_LOG_V2_CONFIG = new InjectionToken('CLOUD_WATCH_LOG_V2_CONFIG') diff --git a/libs/core/src/lib/logger/cloudwatch/cloud-watch-error-handler.service.ts b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-error-handler.service.ts similarity index 72% rename from libs/core/src/lib/logger/cloudwatch/cloud-watch-error-handler.service.ts rename to libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-error-handler.service.ts index 6eac6a9d..fde1ed38 100644 --- a/libs/core/src/lib/logger/cloudwatch/cloud-watch-error-handler.service.ts +++ b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-error-handler.service.ts @@ -1,19 +1,19 @@ import { ErrorHandler, inject, Injectable, Injector } from '@angular/core' import { LogLevel } from '@shiftcode/logger' -import { CloudWatchService } from './cloud-watch.service' +import { CloudWatchLogV2Service } from './cloud-watch-log.service' /** * Angular ErrorHandler to send uncaught Errors to AWS CloudWatch Logs - * requires the {@link CloudWatchService} + * requires the {@link CloudWatchLogV2Service} */ @Injectable({ providedIn: 'root' }) -export class CloudWatchErrorHandler extends ErrorHandler { +export class CloudWatchLogV2ErrorHandler extends ErrorHandler { private readonly injector = inject(Injector) override handleError(error: any): void { // prevent cyclic dependencies (eg. when CLOUD_WATCH_LOG_TRANSPORT_CONFIG needs config from httpClient request) - const cws = this.injector.get(CloudWatchService) + const cws = this.injector.get(CloudWatchLogV2Service) cws.addMessage(LogLevel.ERROR, 'BrowserJsException', new Date(), [error]) // call super.handleError to print error the angular way to the console diff --git a/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-transport.service.ts b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-transport.service.ts new file mode 100644 index 00000000..e047e88f --- /dev/null +++ b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log-transport.service.ts @@ -0,0 +1,26 @@ +import { inject, Injectable } from '@angular/core' +import { LogLevel, LogTransport } from '@shiftcode/logger' + +import { CloudWatchLogV2Service } from './cloud-watch-log.service' +import { CLOUD_WATCH_LOG_V2_CONFIG } from './cloud-watch-log-config.injection-token' + +/** + * The LogTransport implementation using {@link CloudWatchLogV2Service}. + * Delegates all logging logic to the CloudWatchLogger. + * Requires the {@link CLOUD_WATCH_LOG_V2_CONFIG} to be provided. + */ +@Injectable({ providedIn: 'root' }) +export class CloudWatchLogV2TransportService extends LogTransport { + private readonly cloudWatchLogger = inject(CloudWatchLogV2Service) + + constructor() { + super(inject(CLOUD_WATCH_LOG_V2_CONFIG).logLevel) + } + + log(level: LogLevel, clazzName: string, _color: string, timestamp: Date, args: unknown[]): void { + /** + * checking the log level is done in the {@link CloudWatchLogV2Service} in order to do the buffering of below-level logs. + */ + this.cloudWatchLogger.addMessage(level, clazzName, timestamp, args) + } +} diff --git a/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log.service.ts b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log.service.ts new file mode 100644 index 00000000..475248a1 --- /dev/null +++ b/libs/core/src/lib/logger/cloud-watch-log/cloud-watch-log.service.ts @@ -0,0 +1,153 @@ +/* eslint-disable */ +import { inject, Injectable } from '@angular/core' +import { + createJsonLogObjectData, + getJsonStringifyReplacer, + JsonLogObjectData, + LogLevel, + pushToRingBuffer, +} from '@shiftcode/logger' +import { jsonMapSetStringifyReplacer } from '@shiftcode/utilities' +import { buffer, catchError, defer, filter, first, mergeMap, Observable, of, Subject, timer } from 'rxjs' + +import { CloudWatchLogV2ApiService, HttpApiError, LogEvent } from './cloud-watch-log-api.service' +import { CLOUD_WATCH_LOG_V2_CONFIG } from './cloud-watch-log-config.injection-token' +import { LOG_REQUEST_INFO_FN } from '../log-request-info-fn.token' +import { ClientIdService } from '../../client-id/client-id.service' + +/** + * Service to send messages to the integration api for CloudWatch Logs + * requires the {@link CLOUD_WATCH_LOG_V2_CONFIG} to be provided + */ +@Injectable({ providedIn: 'root' }) +export class CloudWatchLogV2Service { + // max request per second per log stream + private static readonly CLOUD_WATCH_RATE_LIMIT = 1000 / 5 + + private readonly api = inject(CloudWatchLogV2ApiService) + private readonly logsSubject = new Subject() + private readonly clientId: string + + private readonly logRequestInfoFn = inject(LOG_REQUEST_INFO_FN, { optional: true }) + private readonly config = inject(CLOUD_WATCH_LOG_V2_CONFIG) + private readonly jsonStringifyReplacer = this.config.jsonStringifyReplacer || jsonMapSetStringifyReplacer + private readonly bufferSize = this.config.bufferSize || 100 + + /** Ring buffer for log events below the configured level, flushed on ERROR */ + private pendingBuffer: LogEvent[] = [] + + constructor() { + const clientIdService = inject(ClientIdService) + + this.clientId = clientIdService.clientId + + // no instantiation if LogLevel === OFF + if (this.config.logLevel !== LogLevel.OFF) { + // validation + if (this.config.flushInterval <= CloudWatchLogV2Service.CLOUD_WATCH_RATE_LIMIT) { + throw new Error( + `Flush interval must be greater than ${CloudWatchLogV2Service.CLOUD_WATCH_RATE_LIMIT}ms --> CloudWatch Rate Limit`, + ) + } + + const ready = this.getOrCreateLogStream(clientIdService) + this.setupLogStream(ready) + } + } + + /** + * add message to the queue to send to CloudWatch Service + * only send when {@link CloudWatchLogTransportConfig#logLevel} is not {@link LogLevel#OFF } + */ + addMessage(level: LogLevel, context: string, timestamp: Date, args: unknown[]) { + if (this.config.logLevel === LogLevel.OFF) { + return + } + // we use `structuredClone` to prevent potential mutations of the logEvent by reference + const logEvent = structuredClone(this.buildLogEvent(level, context, timestamp, args)) + + // if level is below threshold, buffer the event + if (level < this.config.logLevel) { + pushToRingBuffer(this.pendingBuffer, logEvent, this.bufferSize) + return + } + + // on ERROR: flush buffered events first, then clear buffer + if (level === LogLevel.ERROR) { + for (const bufferedEvent of this.pendingBuffer) { + this.logsSubject.next(bufferedEvent) + } + this.pendingBuffer = [] + } + + this.logsSubject.next(logEvent) + } + + private buildLogEvent(level: LogLevel, context: string, timestamp: Date, args: unknown[]): LogEvent { + // Clone args to avoid mutating the original array + let logData: JsonLogObjectData & { requestInfo?: unknown } = createJsonLogObjectData(level, context, timestamp, [ + ...args, + ]) + + if (this.logRequestInfoFn) { + logData.requestInfo = this.logRequestInfoFn() + } + + return { + message: JSON.stringify(logData, getJsonStringifyReplacer(this.jsonStringifyReplacer)), + // time it is sent. not the time of the log (that one is included in the message object) + timestamp: new Date().getTime(), + } + } + + private getOrCreateLogStream({ createdInThisSession, clientId }: ClientIdService): Observable { + // return observable to keep it cold + return defer(async () => { + // if the clientId was created in this session, no LogStream can exist of it. + if (createdInThisSession) { + await this.api.createLogStream(clientId) + return + } + try { + await this.api.describeLogStream(clientId) + } catch (error) { + if (error instanceof HttpApiError && error.statusCode === 404) { + await this.api.createLogStream(clientId) + return + } + throw error + } + }) + } + + private setupLogStream(ready$: Observable): void { + // actual log subscription + this.logsSubject + .pipe( + // buffer logs --> wait for ready$ to complete - then setup the time based interval scheduler + buffer( + ready$.pipe( + first(), + mergeMap(() => timer(0, this.config.flushInterval)), + ), + ), + + // only none empty arrays + filter((logEvents) => logEvents?.length > 0), + + // put logs to cloudwatch + mergeMap(this.putLogEvents), + ) + .subscribe({ error: console.error.bind(console) }) + } + + private readonly putLogEvents = (events: LogEvent[]): Observable => { + // outer observable only for retry logic -- see below + return defer(() => this.api.writeLogs(this.clientId, events)).pipe( + catchError((err) => { + console.warn('unable to put logs to CloudWatch --> we try again with the next batch', err) + return of(void 0) + }), + ) + } +} diff --git a/libs/core/src/lib/logger/cloud-watch-log/with-cloud-watch-log-transport.function.ts b/libs/core/src/lib/logger/cloud-watch-log/with-cloud-watch-log-transport.function.ts new file mode 100644 index 00000000..894ac447 --- /dev/null +++ b/libs/core/src/lib/logger/cloud-watch-log/with-cloud-watch-log-transport.function.ts @@ -0,0 +1,20 @@ +import { LogTransport } from '@shiftcode/logger' + +import { ValueOrFactory } from '../helper/value-or-factory.type' +import { LoggerFeature } from '../logger-feature.type' +import { LoggerFeatureKind } from '../logger-feature-kind.enum' +import { CLOUD_WATCH_LOG_V2_CONFIG, CloudWatchLogV2Config } from './cloud-watch-log-config.injection-token' +import { CloudWatchLogV2TransportService } from './cloud-watch-log-transport.service' + +export function withCloudWatchLogV2Transport(config: ValueOrFactory): LoggerFeature { + return { + kind: LoggerFeatureKind.TRANSPORT, + providers: [ + { + provide: CLOUD_WATCH_LOG_V2_CONFIG, + ...(typeof config === 'function' ? { useFactory: config } : { useValue: config }), + }, + { provide: LogTransport, useClass: CloudWatchLogV2TransportService, multi: true }, + ], + } +} diff --git a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.injection-token.ts b/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.injection-token.ts deleted file mode 100644 index ba3dad09..00000000 --- a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.injection-token.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { InjectionToken } from '@angular/core' - -import { CloudWatchLogTransportConfig } from './cloud-watch-log-transport-config.model' - -export const CLOUD_WATCH_LOG_TRANSPORT_CONFIG = new InjectionToken( - 'cloudWatchLogTransportConfig', -) diff --git a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.model.ts b/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.model.ts deleted file mode 100644 index 7714ec97..00000000 --- a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport-config.model.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LogLevel } from '@shiftcode/logger' - -export interface CloudWatchLogTransportConfig { - logLevel: LogLevel - logApiUrl: string - createLogStreamApiUrl: string - jsonStringifyReplacer?: (key: string, value: any) => any -} diff --git a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport.service.ts b/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport.service.ts deleted file mode 100644 index 9eab1890..00000000 --- a/libs/core/src/lib/logger/cloudwatch/cloud-watch-log-transport.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { inject, Injectable } from '@angular/core' -import { LogLevel, LogTransport } from '@shiftcode/logger' - -import { CloudWatchService } from './cloud-watch.service' -import { CLOUD_WATCH_LOG_TRANSPORT_CONFIG } from './cloud-watch-log-transport-config.injection-token' - -/** - * The LogTransport implementation using {@link CloudWatchService} - * requires the {@link CLOUD_WATCH_LOG_TRANSPORT_CONFIG} to be provided. - */ -@Injectable({ providedIn: 'root' }) -export class CloudWatchLogTransport extends LogTransport { - private readonly cloudWatchService = inject(CloudWatchService) - - constructor() { - super(inject(CLOUD_WATCH_LOG_TRANSPORT_CONFIG).logLevel) - } - - log(level: LogLevel, clazzName: string, color: string, timestamp: Date, args: any[]) { - // send to cloudwatch if level enabled - if (this.isLevelEnabled(level)) { - this.cloudWatchService.addMessage(level, clazzName, timestamp, args) - } - } -} diff --git a/libs/core/src/lib/logger/cloudwatch/cloud-watch.service.ts b/libs/core/src/lib/logger/cloudwatch/cloud-watch.service.ts deleted file mode 100644 index 4c7f74b7..00000000 --- a/libs/core/src/lib/logger/cloudwatch/cloud-watch.service.ts +++ /dev/null @@ -1,178 +0,0 @@ -/* eslint-disable no-console */ -import { HttpClient } from '@angular/common/http' -import { inject, Injectable } from '@angular/core' -import { createJsonLogObjectData, LogLevel } from '@shiftcode/logger' -import { jsonMapSetStringifyReplacer } from '@shiftcode/utilities' -import { - BehaviorSubject, - catchError, - concatMap, - filter, - map, - mergeMap, - Observable, - of, - retry, - shareReplay, - Subject, - take, - throwError, -} from 'rxjs' - -import { ClientIdService } from '../../client-id/client-id.service' -import { LOG_REQUEST_INFO_FN } from '../log-request-info-fn.token' -import { RemoteLogData } from '../remote/remote-log-data.model' -import { CLOUD_WATCH_LOG_TRANSPORT_CONFIG } from './cloud-watch-log-transport-config.injection-token' -import { isLogStreamNotFoundError } from './is-error.function' - -interface CloudWatchLogEvent { - logStreamName: string - timestamp: number - message: string -} - -/** - * Service to send messages to CloudWatch via APIGateway - * requires the {@link CLOUD_WATCH_LOG_TRANSPORT_CONFIG} to be provided - */ -@Injectable({ providedIn: 'root' }) -export class CloudWatchService { - private readonly httpClient = inject(HttpClient) - private readonly config = inject(CLOUD_WATCH_LOG_TRANSPORT_CONFIG) - private readonly logRequestInfoFn = inject(LOG_REQUEST_INFO_FN, { optional: true }) - - private readonly retrying$ = new BehaviorSubject(false) - private readonly logStream$ = new Observable() - private readonly logsSubject = new Subject() - private readonly clientId: string - private readonly jsonStringifyReplacer: (key: string, value: any) => any - - constructor() { - const clientIdService = inject(ClientIdService) - - this.clientId = clientIdService.clientId - this.jsonStringifyReplacer = this.config.jsonStringifyReplacer || jsonMapSetStringifyReplacer - // no instantiation if LogLevel === OFF - if (this.config.logLevel === LogLevel.OFF) { - return - } - this.logStream$ = of(void 0).pipe( - mergeMap(() => (clientIdService.createdInThisSession ? this.createLogStream() : of(void 0))), - shareReplay(1), - ) - this.setup() - } - - /** - * add message to the queue to send to CloudWatch Service - * only send when {@link CloudWatchLogTransportConfig#logLevel} is not {@link LogLevel#OFF } - */ - addMessage(level: LogLevel, context: string, dTimestamp: Date, args: any[]) { - // do nothing if LogLevel === OFF - if (this.config.logLevel === LogLevel.OFF) { - return - } - - const logDataObject: RemoteLogData = { - ...createJsonLogObjectData(level, context, dTimestamp, args), - } - if (this.logRequestInfoFn) { - logDataObject.requestInfo = this.logRequestInfoFn() - } - - this.logsSubject.next({ - message: JSON.stringify(logDataObject, this.jsonStringifyReplacer), - timestamp: dTimestamp.getTime(), - logStreamName: this.clientId, - }) - } - - private setup() { - // actual log subscription - this.logsSubject - .pipe( - // Ensure the log stream is created before processing log events - concatMap((logEvent) => - this.logStream$.pipe( - map(() => logEvent), // Pass the logEvent after the logStream is ready - ), - ), - // put logs to cloudwatch - mergeMap((logEvent) => this.putLogEvent(logEvent)), - ) - .subscribe({ error: console.error.bind(console) }) - } - - private readonly createLogStream = (): Observable => { - const logStream = { - logStreamName: this.clientId, - } - return this.httpClient - .post(this.config.createLogStreamApiUrl, logStream, { - headers: { - 'Content-Type': 'application/json', - }, - responseType: 'text', // prevent angular from parsing something - }) - .pipe( - map(() => void 0), - catchError((err) => { - console.error('log stream could not be created:', err) - return throwError(() => new Error('log stream could not be created')) - }), - ) - } - - private readonly putLogEvent = (logEvent: CloudWatchLogEvent): Observable => { - // outer observable only for retry logic -- see below - return of(logEvent).pipe( - // call to cloudwatch - mergeMap((logEvent) => this.waitForRetryCompletion().pipe(mergeMap(() => this.sendPutLogEvent(logEvent)))), - retry({ delay: (error) => this.handleRetry(error) }), - map(() => void 0), - // we catch and ignore all errors - catchError((err) => { - console.warn('unable to put logs to CloudWatch --> we try again with the next log event', err) - return of(void 0) - }), - ) - } - - private readonly sendPutLogEvent = (logEvent: CloudWatchLogEvent): Observable => { - return this.httpClient.post(this.config.logApiUrl, logEvent, { - headers: { - 'Content-Type': 'application/json', - }, - responseType: 'text', // prevent angular from parsing something - }) - } - - private waitForRetryCompletion(): Observable { - return this.retrying$.pipe( - filter((retrying) => !retrying), - take(1), - map(() => void 0), - ) - } - - private handleRetry(error: any): Observable { - if (isLogStreamNotFoundError(error)) { - if (!this.retrying$.value) { - this.retrying$.next(true) - return this.createLogStream().pipe( - map(() => { - this.retrying$.next(false) - return void 0 - }), - catchError((retryErr) => { - this.retrying$.next(false) - return throwError(() => retryErr) - }), - ) - } else { - return of(void 0) - } - } - return throwError(() => error) - } -} diff --git a/libs/core/src/lib/logger/cloudwatch/is-error.function.ts b/libs/core/src/lib/logger/cloudwatch/is-error.function.ts deleted file mode 100644 index 65b59cdb..00000000 --- a/libs/core/src/lib/logger/cloudwatch/is-error.function.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function isLogStreamNotFoundError(err: any): boolean { - if ('status' in err && 'error' in err && err.status === 400 && typeof err.error === 'string') { - try { - const parsed = JSON.parse(err.error) - return parsed?.error === 'ResourceNotFoundException' - } catch { - return false - } - } - return false -} diff --git a/libs/core/src/lib/logger/cloudwatch/with-cloudwatch-transport.function.ts b/libs/core/src/lib/logger/cloudwatch/with-cloudwatch-transport.function.ts deleted file mode 100644 index 03bfc06d..00000000 --- a/libs/core/src/lib/logger/cloudwatch/with-cloudwatch-transport.function.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { LogTransport } from '@shiftcode/logger' - -import { LoggerFeature } from '../logger-feature.type' -import { LoggerFeatureKind } from '../logger-feature-kind.enum' -import { CloudWatchLogTransport } from './cloud-watch-log-transport.service' -import { CLOUD_WATCH_LOG_TRANSPORT_CONFIG } from './cloud-watch-log-transport-config.injection-token' -import { CloudWatchLogTransportConfig } from './cloud-watch-log-transport-config.model' - -export function withCloudwatchTransport( - cloudWatchLogTransportConfigOrFactory: CloudWatchLogTransportConfig | (() => CloudWatchLogTransportConfig), -): LoggerFeature { - const configProvider = - typeof cloudWatchLogTransportConfigOrFactory === 'function' - ? { provide: CLOUD_WATCH_LOG_TRANSPORT_CONFIG, useFactory: cloudWatchLogTransportConfigOrFactory } - : { provide: CLOUD_WATCH_LOG_TRANSPORT_CONFIG, useValue: cloudWatchLogTransportConfigOrFactory } - - return { - kind: LoggerFeatureKind.TRANSPORT, - providers: [configProvider, { provide: LogTransport, useClass: CloudWatchLogTransport, multi: true }], - } -} diff --git a/libs/core/src/lib/logger/console-json/console-json-log-transport.service.ts b/libs/core/src/lib/logger/console-json/console-json-log-transport.service.ts new file mode 100644 index 00000000..2761d907 --- /dev/null +++ b/libs/core/src/lib/logger/console-json/console-json-log-transport.service.ts @@ -0,0 +1,17 @@ +import { inject, Injectable, InjectionToken } from '@angular/core' +import { LogLevel } from '@shiftcode/logger' +import { ConsoleJsonLogTransport, ConsoleJsonLogTransportConfig } from '@shiftcode/logger' + +export { ConsoleJsonLogTransportConfig } from '@shiftcode/logger' + +export const CONSOLE_JSON_LOG_TRANSPORT_CONFIG = new InjectionToken( + 'CONSOLE_JSON_LOG_TRANSPORT_CONFIG', + { factory: () => ({ logLevel: LogLevel.DEBUG }) }, +) + +@Injectable({ providedIn: 'root' }) +export class ConsoleJsonLogTransportService extends ConsoleJsonLogTransport { + constructor() { + super(inject(CONSOLE_JSON_LOG_TRANSPORT_CONFIG)) + } +} diff --git a/libs/core/src/lib/logger/console-json/with-console-json-log-transport.function.ts b/libs/core/src/lib/logger/console-json/with-console-json-log-transport.function.ts new file mode 100644 index 00000000..1dff1d8e --- /dev/null +++ b/libs/core/src/lib/logger/console-json/with-console-json-log-transport.function.ts @@ -0,0 +1,23 @@ +import { LogTransport } from '@shiftcode/logger' + +import { ValueOrFactory } from '../helper/value-or-factory.type' +import { LoggerFeature } from '../logger-feature.type' +import { LoggerFeatureKind } from '../logger-feature-kind.enum' +import { + CONSOLE_JSON_LOG_TRANSPORT_CONFIG, + ConsoleJsonLogTransportConfig, + ConsoleJsonLogTransportService, +} from './console-json-log-transport.service' + +export function withConsoleJsonLogTransport(config: ValueOrFactory): LoggerFeature { + return { + kind: LoggerFeatureKind.TRANSPORT, + providers: [ + { + provide: CONSOLE_JSON_LOG_TRANSPORT_CONFIG, + ...(typeof config === 'function' ? { useFactory: config } : { useValue: config }), + }, + { provide: LogTransport, useClass: ConsoleJsonLogTransportService, multi: true }, + ], + } +} diff --git a/libs/core/src/lib/logger/console/console-log-transport-config.injection-token.ts b/libs/core/src/lib/logger/console/console-log-transport-config.injection-token.ts deleted file mode 100644 index f014d9ac..00000000 --- a/libs/core/src/lib/logger/console/console-log-transport-config.injection-token.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { InjectionToken } from '@angular/core' - -import { ConsoleLogTransportConfig } from './console-log-transport-config' - -export const CONSOLE_LOG_TRANSPORT_CONFIG = new InjectionToken('consoleLogTransportConfig') diff --git a/libs/core/src/lib/logger/console/console-log-transport-config.ts b/libs/core/src/lib/logger/console/console-log-transport-config.ts deleted file mode 100644 index f6cf4f06..00000000 --- a/libs/core/src/lib/logger/console/console-log-transport-config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { LogLevel } from '@shiftcode/logger' - -export interface ConsoleLogTransportConfig { - logLevel: LogLevel -} diff --git a/libs/core/src/lib/logger/console/node-console-log-transport.service.ts b/libs/core/src/lib/logger/console/node-console-log-transport.service.ts deleted file mode 100644 index 9cedf5ae..00000000 --- a/libs/core/src/lib/logger/console/node-console-log-transport.service.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable no-console */ -import { isPlatformBrowser } from '@angular/common' -import { inject, Injectable, PLATFORM_ID } from '@angular/core' -import { LogLevel, LogTransport } from '@shiftcode/logger' -import { colorizeForConsole } from '@shiftcode/utilities' - -import { leadingZero } from '../helper/leading-zero.function' -import { CONSOLE_LOG_TRANSPORT_CONFIG } from './console-log-transport-config.injection-token' - -@Injectable({ providedIn: 'root' }) -export class NodeConsoleLogTransport extends LogTransport { - constructor() { - super(inject(CONSOLE_LOG_TRANSPORT_CONFIG).logLevel) - if (isPlatformBrowser(inject(PLATFORM_ID))) { - throw new Error('This log transport is only for server side use - consider using "ConsoleLogTransport"') - } - } - - log(level: LogLevel, clazzName: string, hexColor: string, timestamp: Date, args: any[]) { - if (this.isLevelEnabled(level)) { - const now = [ - leadingZero(2, timestamp.getHours()), - leadingZero(2, timestamp.getMinutes()), - leadingZero(2, timestamp.getSeconds()), - leadingZero(3, timestamp.getMilliseconds()), - ].join(':') // 'HH:mm:ss:SSS' - const firstArgument = args.splice(0, 1)[0] - - if (typeof firstArgument === 'string') { - // we have a string with potential message format - args.splice(0, 0, colorizeForConsole(`${now} - ${clazzName} :: ${firstArgument}`, hexColor)) - } else { - args.splice(0, 0, colorizeForConsole(`${now} - ${clazzName} ::`, hexColor), firstArgument) - } - - switch (level) { - case LogLevel.DEBUG: - console.debug(...args) - break - case LogLevel.ERROR: - console.error(...args) - break - case LogLevel.INFO: - console.info(...args) - break - case LogLevel.WARN: - console.warn(...args) - break - case LogLevel.OFF: - break - } - } - } -} diff --git a/libs/core/src/lib/logger/console/with-browser-console-transport.function.ts b/libs/core/src/lib/logger/console/with-browser-console-transport.function.ts deleted file mode 100644 index e2694160..00000000 --- a/libs/core/src/lib/logger/console/with-browser-console-transport.function.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { LogTransport } from '@shiftcode/logger' - -import { LoggerFeature } from '../logger-feature.type' -import { LoggerFeatureKind } from '../logger-feature-kind.enum' -import { ConsoleLogTransport } from './console-log-transport.service' -import { ConsoleLogTransportConfig } from './console-log-transport-config' -import { CONSOLE_LOG_TRANSPORT_CONFIG } from './console-log-transport-config.injection-token' - -export function withBrowserConsoleTransport( - consoleLoggerConfigOrFactory: ConsoleLogTransportConfig | (() => ConsoleLogTransportConfig), -): LoggerFeature { - const configProvider = - typeof consoleLoggerConfigOrFactory === 'function' - ? { provide: CONSOLE_LOG_TRANSPORT_CONFIG, useFactory: consoleLoggerConfigOrFactory } - : { provide: CONSOLE_LOG_TRANSPORT_CONFIG, useValue: consoleLoggerConfigOrFactory } - - return { - kind: LoggerFeatureKind.TRANSPORT, - providers: [configProvider, { provide: LogTransport, useClass: ConsoleLogTransport, multi: true }], - } -} diff --git a/libs/core/src/lib/logger/console/with-node-console-transport.function.ts b/libs/core/src/lib/logger/console/with-node-console-transport.function.ts deleted file mode 100644 index 33729321..00000000 --- a/libs/core/src/lib/logger/console/with-node-console-transport.function.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { LogTransport } from '@shiftcode/logger' - -import { LoggerFeature } from '../logger-feature.type' -import { LoggerFeatureKind } from '../logger-feature-kind.enum' -import { ConsoleLogTransportConfig } from './console-log-transport-config' -import { CONSOLE_LOG_TRANSPORT_CONFIG } from './console-log-transport-config.injection-token' -import { NodeConsoleLogTransport } from './node-console-log-transport.service' - -export function withNodeConsoleTransport( - consoleLoggerConfigOrFactory: ConsoleLogTransportConfig | (() => ConsoleLogTransportConfig), -): LoggerFeature { - const configProvider = - typeof consoleLoggerConfigOrFactory === 'function' - ? { provide: CONSOLE_LOG_TRANSPORT_CONFIG, useFactory: consoleLoggerConfigOrFactory } - : { provide: CONSOLE_LOG_TRANSPORT_CONFIG, useValue: consoleLoggerConfigOrFactory } - - return { - kind: LoggerFeatureKind.TRANSPORT, - providers: [configProvider, { provide: LogTransport, useClass: NodeConsoleLogTransport, multi: true }], - } -} diff --git a/libs/core/src/lib/logger/helper/logging-time-format.const.spec.ts b/libs/core/src/lib/logger/helper/logging-time-format.const.spec.ts new file mode 100644 index 00000000..0c5c9169 --- /dev/null +++ b/libs/core/src/lib/logger/helper/logging-time-format.const.spec.ts @@ -0,0 +1,18 @@ +import { loggingTimeFormat } from './logging-time-format.const' + +describe('timeFormat', () => { + it('should format time as HH:mm:ss.SSS', () => { + const timestamp = new Date('2024-01-15T14:30:45.123') + expect(loggingTimeFormat.format(timestamp)).toBe(`14:30:45.123`) + }) + + it('should format another time as HH:mm:ss.SSS', () => { + const timestamp = new Date('2024-01-01T23:59:59.999') + expect(loggingTimeFormat.format(timestamp)).toBe(`23:59:59.999`) + }) + + it('should format time with leading zeros as HH:mm:ss.SSS', () => { + const timestamp = new Date('2024-01-01T01:02:03.004') + expect(loggingTimeFormat.format(timestamp)).toBe(`01:02:03.004`) + }) +}) diff --git a/libs/core/src/lib/logger/helper/logging-time-format.const.ts b/libs/core/src/lib/logger/helper/logging-time-format.const.ts new file mode 100644 index 00000000..8f442380 --- /dev/null +++ b/libs/core/src/lib/logger/helper/logging-time-format.const.ts @@ -0,0 +1,10 @@ +/** + * Time formatter for logging timestamps in 'HH:MM:SS.sss' format. + */ +export const loggingTimeFormat = new Intl.DateTimeFormat('en-US', { + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + fractionalSecondDigits: 3, + hour12: false, +}) diff --git a/libs/core/src/lib/logger/helper/value-or-factory.type.ts b/libs/core/src/lib/logger/helper/value-or-factory.type.ts new file mode 100644 index 00000000..795035b4 --- /dev/null +++ b/libs/core/src/lib/logger/helper/value-or-factory.type.ts @@ -0,0 +1 @@ +export type ValueOrFactory = T | (() => T) diff --git a/libs/core/src/lib/logger/logger.service.spec.ts b/libs/core/src/lib/logger/logger.service.spec.ts index 3faba019..2b2c0ed4 100644 --- a/libs/core/src/lib/logger/logger.service.spec.ts +++ b/libs/core/src/lib/logger/logger.service.spec.ts @@ -2,7 +2,8 @@ import { Component, Directive, inject, Injectable, InjectionToken, PLATFORM_ID } import { TestBed } from '@angular/core/testing' import { By } from '@angular/platform-browser' import { Logger, LogLevel, LogTransport } from '@shiftcode/logger' -import { LoggerService } from '@shiftcode/ngx-core' + +import { LoggerService } from './logger.service' interface MockLogTransportConfig { logLevel: LogLevel diff --git a/libs/core/src/lib/logger/node-console/log-level-emoji.const.ts b/libs/core/src/lib/logger/node-console/log-level-emoji.const.ts new file mode 100644 index 00000000..7efad25e --- /dev/null +++ b/libs/core/src/lib/logger/node-console/log-level-emoji.const.ts @@ -0,0 +1,3 @@ +import { LogLevel } from '@shiftcode/logger' + +export const logLevelEmoji: Record = ['🐞', '💬', '💣', '🔥', ''] diff --git a/libs/core/src/lib/logger/node-console/node-console-log-transport.service.ts b/libs/core/src/lib/logger/node-console/node-console-log-transport.service.ts new file mode 100644 index 00000000..a4884626 --- /dev/null +++ b/libs/core/src/lib/logger/node-console/node-console-log-transport.service.ts @@ -0,0 +1,122 @@ +import { isPlatformBrowser } from '@angular/common' +import { inject, Injectable, InjectionToken, PLATFORM_ID } from '@angular/core' +import { getJsonStringifyReplacer, LogLevel, LogTransport } from '@shiftcode/logger' +import { colorizeForConsole, jsonMapSetStringifyReplacer } from '@shiftcode/utilities' + +import { loggingTimeFormat } from '../helper/logging-time-format.const' +import { logLevelEmoji } from './log-level-emoji.const' + +export interface NodeConsoleLogTransportConfig { + logLevel: LogLevel + + /** + * custom replacer function for JSON serialization, default to @shiftcode/utilities jsonMapSetStringifyReplacer + */ + jsonStringifyReplacer?: (key: string, value: unknown) => unknown + + /** max depth for object serialization, default is 5 */ + maxDepth?: number +} + +export const NODE_CONSOLE_LOG_TRANSPORT_CONFIG = new InjectionToken( + 'NODE_CONSOLE_LOG_TRANSPORT_CONFIG', + { factory: () => ({ logLevel: LogLevel.DEBUG }) }, +) + +// we do not extend the NodeConsoleLogTransport from @shiftcode/logger since it uses `node:utils` which would break ts here without further changes +@Injectable({ providedIn: 'root' }) +export class NodeConsoleLogTransportService extends LogTransport { + private readonly config: NodeConsoleLogTransportConfig + + constructor() { + const config = inject(NODE_CONSOLE_LOG_TRANSPORT_CONFIG) + super(config.logLevel) + this.config = config + + if (isPlatformBrowser(inject(PLATFORM_ID))) { + throw new Error('This log transport is only for server side use - consider using "ConsoleLogTransport"') + } + } + + log(level: LogLevel, clazzName: string, hexColor: string, timestamp: Date, args: any[]) { + if (this.isLevelEnabled(level)) { + return + } + + const now = loggingTimeFormat.format(timestamp) + // make sure to not alter the input args array + if (typeof args[0] === 'string') { + // if first arg is string, also colorize it + args = [ + logLevelEmoji[level], + colorizeForConsole(`${now} - ${clazzName} :: ${args[0]}`, hexColor), + ...args.slice(1).map(this.stringifyJson), + ] + } else { + args = [ + logLevelEmoji[level], + colorizeForConsole(`${now} - ${clazzName} ::`, hexColor), + ...args.map(this.stringifyJson), + ] + } + + /* eslint-disable no-console */ + switch (level) { + case LogLevel.DEBUG: + console.debug(...args) + break + case LogLevel.ERROR: + console.error(...args) + break + case LogLevel.INFO: + console.info(...args) + break + case LogLevel.WARN: + console.warn(...args) + break + case LogLevel.OFF: + break + default: + return level // exhaustive check + } + /* eslint-enable no-console */ + } + + private readonly stringifyJson = (data: unknown) => { + const maxDepth = this.config.maxDepth ?? 5 + const jsonStringifyReplacer = getJsonStringifyReplacer( + this.config.jsonStringifyReplacer ?? jsonMapSetStringifyReplacer, + ) + + const seen = new WeakMap() + let refCounter = 0 + const handleDepthAndCircularRefs = (value: unknown, depth: number = 0): unknown => { + if (depth > maxDepth) { + return '[max depth reached]' + } + + if (typeof value === 'object' && value !== null) { + if (seen.has(value)) { + return `[circular ref #${seen.get(value)}]` + } else { + seen.set(value, ++refCounter) + } + + if (Array.isArray(value)) { + return value.map((v) => handleDepthAndCircularRefs(v, depth + 1)) + } + + const result: any = {} + for (const [k, v] of Object.entries(value)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + result[k] = handleDepthAndCircularRefs(v, depth + 1) + } + return result + } + + return value + } + + return JSON.stringify(handleDepthAndCircularRefs(data), jsonStringifyReplacer) + } +} diff --git a/libs/core/src/lib/logger/node-console/with-node-console-transport.function.ts b/libs/core/src/lib/logger/node-console/with-node-console-transport.function.ts new file mode 100644 index 00000000..67dd09df --- /dev/null +++ b/libs/core/src/lib/logger/node-console/with-node-console-transport.function.ts @@ -0,0 +1,19 @@ +import { LogTransport } from '@shiftcode/logger' + +import { ValueOrFactory } from '../helper/value-or-factory.type' +import { LoggerFeature } from '../logger-feature.type' +import { LoggerFeatureKind } from '../logger-feature-kind.enum' +import { NODE_CONSOLE_LOG_TRANSPORT_CONFIG, NodeConsoleLogTransportService } from './node-console-log-transport.service' + +export function withNodeConsoleTransport(config: ValueOrFactory): LoggerFeature { + return { + kind: LoggerFeatureKind.TRANSPORT, + providers: [ + { + provide: NODE_CONSOLE_LOG_TRANSPORT_CONFIG, + ...(typeof config === 'function' ? { useFactory: config } : { useValue: config }), + }, + { provide: LogTransport, useClass: NodeConsoleLogTransportService, multi: true }, + ], + } +} diff --git a/libs/core/src/public-api.ts b/libs/core/src/public-api.ts index 8fbbc565..13782fac 100644 --- a/libs/core/src/public-api.ts +++ b/libs/core/src/public-api.ts @@ -19,22 +19,20 @@ export * from './lib/logger/logger.service' export * from './lib/logger/provide-logger' export * from './lib/logger/with-request-info-fn.function' -//cloudwatch logger -export * from './lib/logger/cloudwatch/cloud-watch.service' -export * from './lib/logger/cloudwatch/cloud-watch-error-handler.service' -export * from './lib/logger/cloudwatch/cloud-watch-log-transport.service' -export * from './lib/logger/cloudwatch/cloud-watch-log-transport-config.injection-token' -export * from './lib/logger/cloudwatch/cloud-watch-log-transport-config.model' -export * from './lib/logger/cloudwatch/is-error.function' -export * from './lib/logger/cloudwatch/with-cloudwatch-transport.function' +// CloudWatchLog (V2) +export * from './lib/logger/cloud-watch-log/cloud-watch-log.service' +export * from './lib/logger/cloud-watch-log/cloud-watch-log-config.injection-token' +export * from './lib/logger/cloud-watch-log/cloud-watch-log-error-handler.service' +export * from './lib/logger/cloud-watch-log/cloud-watch-log-transport.service' +export * from './lib/logger/cloud-watch-log/with-cloud-watch-log-transport.function' // console logger -export * from './lib/logger/console/console-log-transport.service' -export * from './lib/logger/console/console-log-transport-config' -export * from './lib/logger/console/console-log-transport-config.injection-token' -export * from './lib/logger/console/node-console-log-transport.service' -export * from './lib/logger/console/with-browser-console-transport.function' -export * from './lib/logger/console/with-node-console-transport.function' +export * from './lib/logger/browser-console/browser-console-log-transport.service' +export * from './lib/logger/browser-console/with-browser-console-transport.function' +export * from './lib/logger/console-json/console-json-log-transport.service' +export * from './lib/logger/console-json/with-console-json-log-transport.function' +export * from './lib/logger/node-console/node-console-log-transport.service' +export * from './lib/logger/node-console/with-node-console-transport.function' // remote logger export * from './lib/logger/remote/remote-log.service' diff --git a/package-lock.json b/package-lock.json index baaf1584..fb50c0fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,28 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@angular/animations": "~21.0.3", - "@angular/cdk": "~21.0.0", - "@angular/common": "~21.0.3", - "@angular/core": "~21.0.3", - "@angular/forms": "~21.0.3", - "@angular/platform-browser": "~21.0.3", - "@angular/router": "~21.0.3", - "@angular/ssr": "~21.0.2", - "@shiftcode/logger": "^3.0.0", + "@angular/animations": "~21.0.9", + "@angular/cdk": "~21.0.6", + "@angular/common": "~21.0.9", + "@angular/core": "~21.0.9", + "@angular/forms": "~21.0.9", + "@angular/platform-browser": "~21.0.9", + "@angular/router": "~21.0.9", + "@angular/ssr": "~21.0.6", + "@shiftcode/logger": "^4.0.0-pr250.9", "@shiftcode/utilities": "^4.0.0", "rxjs": "^6.5.3 || ^7.4.0", - "tslib": "^2.5.0" + "tslib": "^2.5.0", + "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "~21.0.2", - "@angular/build": "~21.0.2", - "@angular/cli": "~21.0.2", - "@angular/compiler": "~21.0.3", - "@angular/compiler-cli": "~21.0.3", - "@angular/platform-browser-dynamic": "~21.0.3", - "@angular/platform-server": "~21.0.3", + "@angular-devkit/build-angular": "~21.0.6", + "@angular/build": "~21.0.6", + "@angular/cli": "~21.0.6", + "@angular/compiler": "~21.0.9", + "@angular/compiler-cli": "~21.0.9", + "@angular/platform-browser-dynamic": "~21.0.9", + "@angular/platform-server": "~21.0.9", "@commitlint/cli": "^19.3.0", "@commitlint/config-angular": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", @@ -53,11 +54,10 @@ "ts-jest": "^29.4.5", "ts-node": "^10.9.2", "tslib": "^2.5.0", - "typescript": "5.9.3", - "zone.js": "~0.15.0" + "typescript": "5.9.3" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || ^24.0.0" + "node": "^22.12.0 || ^24.0.0" }, "optionalDependencies": { "@nx/nx-linux-x64-gnu": "^19.4.2", @@ -288,13 +288,13 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.2100.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2100.2.tgz", - "integrity": "sha512-zSMF82F2wb6b6mvqmDFQyGiKaeFGcgfpXAg7M+ihlJF+GG47H3pNEUzO8+Be5GPoAtpSv0VVoXBwURU2SOnV/Q==", + "version": "0.2100.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2100.6.tgz", + "integrity": "sha512-RsCXULyyNNElRHDObVeEBhEOaLK8QaKu+DaYVhfkOOKvVeDoEI0i+0JomzPhGDjazXPPYG8BPOTgSOvhlEeWSA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "21.0.2", + "@angular-devkit/core": "21.0.6", "rxjs": "7.8.2" }, "engines": { @@ -304,17 +304,17 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-21.0.2.tgz", - "integrity": "sha512-B+8xIGjGZz4q79jk7VJSiouN7+1lu8E5EhTi0pS3zhmMJ4iHTKVmZOozFXiTThQ3anix2uPa6sa6rr2t/FoiDQ==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-21.0.6.tgz", + "integrity": "sha512-1Xpfn8z1WZgBhs07NeK8M1OCPVSp5EnKX1BgkF2ay0l+BAz249voSNX+LQ99geJ1zvODU2f1TLGGdGDjKLvshw==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2100.2", - "@angular-devkit/build-webpack": "0.2100.2", - "@angular-devkit/core": "21.0.2", - "@angular/build": "21.0.2", + "@angular-devkit/architect": "0.2100.6", + "@angular-devkit/build-webpack": "0.2100.6", + "@angular-devkit/core": "21.0.6", + "@angular/build": "21.0.6", "@babel/core": "7.28.4", "@babel/generator": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", @@ -325,7 +325,7 @@ "@babel/preset-env": "7.28.3", "@babel/runtime": "7.28.4", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "21.0.2", + "@ngtools/webpack": "21.0.6", "ansi-colors": "4.1.3", "autoprefixer": "10.4.21", "babel-loader": "10.0.0", @@ -359,7 +359,7 @@ "tinyglobby": "0.2.15", "tree-kill": "1.2.2", "tslib": "2.8.1", - "webpack": "5.102.1", + "webpack": "5.104.0", "webpack-dev-middleware": "7.4.5", "webpack-dev-server": "5.2.2", "webpack-merge": "6.0.1", @@ -380,7 +380,7 @@ "@angular/platform-browser": "^21.0.0", "@angular/platform-server": "^21.0.0", "@angular/service-worker": "^21.0.0", - "@angular/ssr": "^21.0.2", + "@angular/ssr": "^21.0.6", "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^30.2.0", @@ -692,13 +692,13 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.2100.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2100.2.tgz", - "integrity": "sha512-YY70x6h/woHNETpqNc8ZO1/ywwFS5m3k8iUEXDb/R82cPeejjIr307be8AFZWLVE/tCZzLw0ltRwEy49Evn5+w==", + "version": "0.2100.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2100.6.tgz", + "integrity": "sha512-54XmhKUh8N5m5jXDF2bHEarkkL8xaGA7iN+Zpe6B7lzyEi2kW+tWApEGLreYx7aZLJvPmH2GXQNT5cU8DF0edQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2100.2", + "@angular-devkit/architect": "0.2100.6", "rxjs": "7.8.2" }, "engines": { @@ -712,9 +712,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.0.2.tgz", - "integrity": "sha512-ePttMRRua9kv7df6fu2i5jTVJr5bzqwrKBBEtdXnWqOrYLUnU0G6XIpyGYVM6SyqpTwkTPlVsXZo5e8Lq356tg==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.0.6.tgz", + "integrity": "sha512-quhQrvfbs1zzDev2T3PdyXDsTrthi9QjwegqR4HyDZKvYCWzmXLw9KjScqEWWUSKVLhG7GULrmb+tDsxRFG9lg==", "dev": true, "license": "MIT", "dependencies": { @@ -762,10 +762,230 @@ "node": ">= 12" } }, + "node_modules/@angular-devkit/schematics": { + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.0.6.tgz", + "integrity": "sha512-0Zg4IeBoAjPNtGQobZEH010l1jQThq2lMdQZfqhLj4a3XoVdhGdzo9Xcn+GcA/z0zXy+rtAiqRazsk9mW1VcRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.0.6", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.19", + "ora": "9.0.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ora": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", + "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.2.2", + "string-width": "^8.1.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@angular/animations": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.0.3.tgz", - "integrity": "sha512-iuf/ss/8nabJg4QgEVBQQ0LAiyjo+XYUjxcuvvUELKLVw6xc2W+3p4gsWJsBjyGeaYUfFtIg9atArzlt/XFU7g==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.0.9.tgz", + "integrity": "sha512-vKt+HT5louWK0/MMm/D7kLDmpG6/5OeG8FaF4WTHc2ZI7vn6V4UGgYNdfUZFTn6NWsK1I8tykL3+ExCCfn51eg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -774,18 +994,18 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "21.0.3" + "@angular/core": "21.0.9" } }, "node_modules/@angular/build": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.0.2.tgz", - "integrity": "sha512-5ZW4GZxAUXV7Vin+c42wKf6HhkYsexeUSb45K+f6aQVxLAwCEegJWwfQ6bReDw1ANDzXIA1Osh4zcsgOQ58EDw==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.0.6.tgz", + "integrity": "sha512-kn5c5LERVuY8x9eNveeN2m+hUw2doXobqxjFGB1M1YCDNHGT3DBX7DNG8aG0PoFGV6BSbb534ypRny4mhuFh2A==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2100.2", + "@angular-devkit/architect": "0.2100.6", "@babel/core": "7.28.4", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", @@ -828,7 +1048,7 @@ "@angular/platform-browser": "^21.0.0", "@angular/platform-server": "^21.0.0", "@angular/service-worker": "^21.0.0", - "@angular/ssr": "^21.0.2", + "@angular/ssr": "^21.0.6", "karma": "^6.4.0", "less": "^4.2.0", "ng-packagr": "^21.0.0", @@ -928,9 +1148,9 @@ "license": "MIT" }, "node_modules/@angular/build/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "dev": true, "license": "MIT" }, @@ -1068,9 +1288,9 @@ } }, "node_modules/@angular/cdk": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.0.0.tgz", - "integrity": "sha512-wCr5D3mEC+p69IMDC7vf8bWx18mfUNNRdsiK3XD0m1PqfeNfnCJb+Bnkks37MC/SU01uCNrAokRaTbWL6pk1Wg==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.0.6.tgz", + "integrity": "sha512-5Gw8mXtKXvcvDMWEciPLRYB6Ja5vsikLAidZsdCEIF6Bc51GmoqT5Tk/Ke+ciCd5Hq9Aco/IcHxT1RC3470lZg==", "license": "MIT", "dependencies": { "parse5": "^8.0.0", @@ -1107,19 +1327,19 @@ } }, "node_modules/@angular/cli": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.0.2.tgz", - "integrity": "sha512-SkyI0ZchUF0ZVBXSZDF4s4hMZs8AazLlI2PlpHSt+QXM+UX+1hhAp8F50WYOdOf1a+93VUzstI9um1CQgMHz2Q==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.0.6.tgz", + "integrity": "sha512-nBdSDwOCKB3T5STs4EPVsft73x4Ap9rZPQRJuGk5r5seS26nBsKFE/eeUShTIIqqM9tA/NRLSc080ugPKuHr2Q==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.2100.2", - "@angular-devkit/core": "21.0.2", - "@angular-devkit/schematics": "21.0.2", + "@angular-devkit/architect": "0.2100.6", + "@angular-devkit/core": "21.0.6", + "@angular-devkit/schematics": "21.0.6", "@inquirer/prompts": "7.9.0", "@listr2/prompt-adapter-inquirer": "3.0.5", - "@modelcontextprotocol/sdk": "1.24.0", - "@schematics/angular": "21.0.2", + "@modelcontextprotocol/sdk": "1.25.2", + "@schematics/angular": "21.0.6", "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.40.1", "ini": "5.0.0", @@ -1142,25 +1362,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/schematics": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.0.2.tgz", - "integrity": "sha512-mFKWTI56D5VmqyIonEK6myIdlGVJpxtxLW44uB1/jiVj7vUSnJCRFHSPH8syaIJ4/Y1B/T4kPTYCx/KEwnO/Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "21.0.2", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.19", - "ora": "9.0.0", - "rxjs": "7.8.2" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, "node_modules/@angular/cli/node_modules/@listr2/prompt-adapter-inquirer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.5.tgz", @@ -1333,19 +1534,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@angular/cli/node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -1356,35 +1544,6 @@ "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/cli/node_modules/cli-spinners": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", - "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@angular/cli/node_modules/cli-truncate": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", @@ -1499,32 +1658,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/cli/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@angular/cli/node_modules/jackspeak": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", @@ -1559,23 +1692,6 @@ "node": ">=20.0.0" } }, - "node_modules/@angular/cli/node_modules/log-symbols": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@angular/cli/node_modules/lru-cache": { "version": "11.2.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", @@ -1666,16 +1782,6 @@ "encoding": "^0.1.13" } }, - "node_modules/@angular/cli/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/@angular/cli/node_modules/node-gyp": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.1.0.tgz", @@ -1741,60 +1847,20 @@ "minipass-fetch": "^5.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^13.0.0", - "proc-log": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@angular/cli/node_modules/npm-registry-fetch/node_modules/proc-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.0.0.tgz", - "integrity": "sha512-KG/XsTDN901PNfPfAMmj6N/Ywg9tM+bHK8pAz+27fS4N4Pcr+4zoYBOcGSBu6ceXYNPxkLpa4ohtfxV1XcLAfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@angular/cli/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/cli/node_modules/ora": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", - "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.2.2", - "string-width": "^8.1.0", - "strip-ansi": "^7.1.2" + "proc-log": "^6.0.0" }, "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@angular/cli/node_modules/npm-registry-fetch/node_modules/proc-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.0.0.tgz", + "integrity": "sha512-KG/XsTDN901PNfPfAMmj6N/Ywg9tM+bHK8pAz+27fS4N4Pcr+4zoYBOcGSBu6ceXYNPxkLpa4ohtfxV1XcLAfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@angular/cli/node_modules/pacote": { @@ -1846,36 +1912,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@angular/cli/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/cli/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@angular/cli/node_modules/slice-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", @@ -2036,9 +2072,9 @@ } }, "node_modules/@angular/common": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.0.3.tgz", - "integrity": "sha512-y8U5jlaK5x3fhI7WOsuiwwNYghC5TBDfmqJdQ2YT4RFG0vB4b22RW5RY5GDbQ5La4AAcpcjoqb4zca8auLCe+g==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.0.9.tgz", + "integrity": "sha512-yU9D5qgZGGhlhaM9p0YZEcFSMq84sZHKUqOjL5a2+bxpT01gO1ZhoOGeyLccClgjaNALH23J9hCvmv05ufhXlw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -2047,14 +2083,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "21.0.3", + "@angular/core": "21.0.9", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.0.3.tgz", - "integrity": "sha512-s9IN4Won1lTmO2vUIIMc4zZHQ2A68pYr/BiieM6frYBhRAwtdyqZW0C5TTeRlFhHe+jMlOdbaJwF8OJrFT7drQ==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.0.9.tgz", + "integrity": "sha512-wQVaNWZM/iyIggJ6lExxnJG8ProqNp4fDNCinejnJbjiQVH7oLU57uAD153nqe6lHhz9oHVMtHx4qpPh1h/ptQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2065,9 +2101,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.0.3.tgz", - "integrity": "sha512-zb8Wl8Knsdp0nDvIljR9Y0T79OgzaJm45MvtTBTl7T9lw9kpJvVf09RfTLNtk7VS8ieDPZgDb2c6gpQRODIjjw==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.0.9.tgz", + "integrity": "sha512-yjXdY6PAw9HR3YcWGiGSwPw7sJmnW8ziCqP+5DKJkHDIAHmTWFyxffmWys+cZRDjRuk6GvBmyWemvEjNyfMVMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2088,7 +2124,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "21.0.3", + "@angular/compiler": "21.0.9", "typescript": ">=5.9 <6.0" }, "peerDependenciesMeta": { @@ -2233,9 +2269,9 @@ } }, "node_modules/@angular/core": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.0.3.tgz", - "integrity": "sha512-/7a2FyZp5cyjNiwuNLr889KA8DVKSTcTtZJpz57Z9DpmZhPscDOWQqLn9f8jeEwbWllvgrXJi8pKSa78r8JAwA==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.0.9.tgz", + "integrity": "sha512-3RAkc0esb5fuerAJcjgv+rdsaOQfjkWIRckyvDFecAFyeouYWn8x3pAp9rDI02PTMnup+qSgZOqPN1mG3BAjgg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -2244,7 +2280,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "21.0.3", + "@angular/compiler": "21.0.9", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0 || ~0.16.0" }, @@ -2258,28 +2294,28 @@ } }, "node_modules/@angular/forms": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.0.3.tgz", - "integrity": "sha512-W60auwyDmsglIlHAbP/eol0LyzQ6FCz8LHghNx2B4RjIpuIMyjBLBZfC0JHU0gyiKB/JfX8W4FdphvyT7I4sIw==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.0.9.tgz", + "integrity": "sha512-FyTkjXbdN+jJLhg1YlTtsmwtiyTMT/jWYFFWG9NIRvKTIMEJqkxl3pi8/idhsuzbZmvBVTQf6xOyAY1QnBWQig==", "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.0.0", "tslib": "^2.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "21.0.3", - "@angular/core": "21.0.3", - "@angular/platform-browser": "21.0.3", - "@standard-schema/spec": "^1.0.0", + "@angular/common": "21.0.9", + "@angular/core": "21.0.9", + "@angular/platform-browser": "21.0.9", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.0.3.tgz", - "integrity": "sha512-vWyornr4mRtB+25d9r15IXBVkKV3TW6rmYBakmPmf8uuYDwgm8fTrFDySFChitRISfvMzR7tGJiYRBQRRp1fSA==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.0.9.tgz", + "integrity": "sha512-NXOiDAlGXex8O1D6ZsHinZsloA/ngvSqcg/g2IzVUtxM/PRKYIyk6DeRnWXx1QCQmUVh96WbcAnFoF2PUj2Z8A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -2288,9 +2324,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/animations": "21.0.3", - "@angular/common": "21.0.3", - "@angular/core": "21.0.3" + "@angular/animations": "21.0.9", + "@angular/common": "21.0.9", + "@angular/core": "21.0.9" }, "peerDependenciesMeta": { "@angular/animations": { @@ -2299,9 +2335,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.0.3.tgz", - "integrity": "sha512-ln/bcWdIPukRQ0gV5xhxEeR4q+hrjL2+z2/4JJySPPngtFqhFkS9+c2jiwBLWPN3mFA1C3LvpBbnNa/VQkupVg==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.0.9.tgz", + "integrity": "sha512-rWHFG753jqKHED/AvsTGzKevqtWQVfxDKMqSYu/kUVysld1l9mti+kR2+tJ2mYM9xRXYXFoZHXVMXlbNVmnAPg==", "dev": true, "license": "MIT", "dependencies": { @@ -2311,16 +2347,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "21.0.3", - "@angular/compiler": "21.0.3", - "@angular/core": "21.0.3", - "@angular/platform-browser": "21.0.3" + "@angular/common": "21.0.9", + "@angular/compiler": "21.0.9", + "@angular/core": "21.0.9", + "@angular/platform-browser": "21.0.9" } }, "node_modules/@angular/platform-server": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-21.0.3.tgz", - "integrity": "sha512-gKWQwgQdAyKTq6yMlx7rzULfJ6hC4SJPtC+ZQ4uWPoyyJmbrqk72n6qrVnwcbDIJ8zT4Bbg+uvh9JDdJKl7XNA==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-21.0.9.tgz", + "integrity": "sha512-XQ7CQB0/2CuRbLcsa30fQlLUhDd444wZzj3g0oIeW6m/lYGWC723lq4yqrH7iHmBis8Pwmq5EfPZY/Kn0SLBhA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2331,17 +2367,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "21.0.3", - "@angular/compiler": "21.0.3", - "@angular/core": "21.0.3", - "@angular/platform-browser": "21.0.3", + "@angular/common": "21.0.9", + "@angular/compiler": "21.0.9", + "@angular/core": "21.0.9", + "@angular/platform-browser": "21.0.9", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/router": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.0.3.tgz", - "integrity": "sha512-TxqAmANV1NmBUMCGcl5U0dz6TKAV27Db4ItWmCX5bcYcNJnmB4F2/nX69swCdSbJtXhdvduMqtrF8RbSGO/IKg==", + "version": "21.0.9", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.0.9.tgz", + "integrity": "sha512-Zw4gow6QiwW8IcgTiekD4RtpDKTerWUKvgx9uPQboijmfXhBD+OGKmNCgTvDYQDJke1e84gFGklPfMN8LyjhFQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -2350,16 +2386,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "21.0.3", - "@angular/core": "21.0.3", - "@angular/platform-browser": "21.0.3", + "@angular/common": "21.0.9", + "@angular/core": "21.0.9", + "@angular/platform-browser": "21.0.9", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/ssr": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-21.0.2.tgz", - "integrity": "sha512-Co69EgQgn6qF7ZkUQY/vEN7yg9z9QDQ5UP5ZzcKC/V+v6K/BFyScnP9vcTVKb1kdd7WNnFQJUSzRZH1tKHMCWg==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-21.0.6.tgz", + "integrity": "sha512-UxZysYEds1AIBdysCegiH/FAmBgyFWtSBhIxGzkDQxpf07L+hMgK5PJKobWGrzcs76aNtsz5E5ienCYWJgCx4g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -5581,6 +5617,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -7757,9 +7806,9 @@ } }, "node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.65.0.tgz", + "integrity": "sha512-eBrIXd0/Ld3p9lpDDlMaMn6IEfWqtHMD+z61u0JrIiPzsV1r7m6xDZFRxJyvIFTEO+SWdYF9EiQbXZGd8BzPfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -7790,6 +7839,281 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.9.tgz", + "integrity": "sha512-BUkXXWL3I7VZ34cpmP7WSttmP5o+z+lxi3teYMnEcUOKBu7DhCFxCesOevw+UATUewMHRMUtsmFYxOxgV7SQwg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.9", + "@jsonjoy.com/fs-node-utils": "4.56.9", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.9.tgz", + "integrity": "sha512-g15wwrvRRsy73p/b93XltxMkARyh3efxZNkrKbiocUNaPnHF+iDXQ1IlBwsTi5zxijdCYOsmVuyEdBX87tLqlw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.9", + "@jsonjoy.com/fs-node-builtins": "4.56.9", + "@jsonjoy.com/fs-node-utils": "4.56.9", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.9.tgz", + "integrity": "sha512-YiI2iqVMi/Ro9BcqWWLQBv939gje748pC4t376M/goQoLaM0sItsj0bBTiQr4eXyLsLdGw10n/F/kH5/snBe7g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.56.9", + "@jsonjoy.com/fs-node-builtins": "4.56.9", + "@jsonjoy.com/fs-node-utils": "4.56.9", + "@jsonjoy.com/fs-print": "4.56.9", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.9.tgz", + "integrity": "sha512-q9MEsySAwyhgy1GT1FKfnKJ1a8bJmzbQnMGQA94F663C/wycrSgRrM33byzTAwn6FBRzMfTvABANkYvkOeYGhw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.9.tgz", + "integrity": "sha512-rOnn9FBLY+JWy0UDSXaYXY45j7FxfRJepRW5pZvNbdAzHYFZ0/M3OQ1+RfZsMYgWeMkaN9pGhOsIj/A7P9pAXA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.56.9", + "@jsonjoy.com/fs-node-builtins": "4.56.9", + "@jsonjoy.com/fs-node-utils": "4.56.9" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.9.tgz", + "integrity": "sha512-UMUirCu0jDPyJEsfllKX1SmK9E7ww2VltWiq2qBCy3ZcyHqDuHswPycrxLTwGrLJnGiHPW9f7LOniP7enl9jYQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.56.9" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.9.tgz", + "integrity": "sha512-Op6rXFnmhHHAClNvHFGx9zALHgZfyPdPBd0WIf/MBr4DEoShhAj0MZxg0jMO7foqleq2YSNNCNBMFGkmY43wAQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.56.9", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.9.tgz", + "integrity": "sha512-nMxEvDku2bCdCCNLkjd9hjPyUng8mLIfok8yAQ0zHNbZqeE44K5CSXnT0o3TGzv/zWynM49rUlF95ZjlNazFAQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.56.9", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.65.0.tgz", + "integrity": "sha512-Xrh7Fm/M0QAYpekSgmskdZYnFdSGnsxJ/tHaolA4bNwWdG9i65S8m83Meh7FOxyJyQAdo4d4J97NOomBLEfkDQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.65.0.tgz", + "integrity": "sha512-7MXcRYe7n3BG+fo3jicvjB0+6ypl2Y/bQp79Sp7KeSiiCgLqw4Oled6chVv07/xLVTdo3qa1CD0VCCnPaw+RGA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.65.0.tgz", + "integrity": "sha512-e0SG/6qUCnVhHa0rjDJHgnXnbsacooHVqQHxspjvlYQSkHm+66wkHw6Gql+3u/WxI/b1VsOdUi0M+fOtkgKGdQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.65.0", + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0", + "@jsonjoy.com/json-pointer": "17.65.0", + "@jsonjoy.com/util": "17.65.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.65.0.tgz", + "integrity": "sha512-uhTe+XhlIZpWOxgPcnO+iSCDgKKBpwkDVTyYiXX9VayGV8HSFVJM67M6pUE71zdnXF1W0Da21AvnhlmdwYPpow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.65.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.65.0.tgz", + "integrity": "sha512-cWiEHZccQORf96q2y6zU3wDeIVPeidmGqd9cNKJRYoVHTV0S1eHPy5JTbHpMnGfDvtvujQwQozOqgO9ABu6h0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.65.0", + "@jsonjoy.com/codegen": "17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@jsonjoy.com/json-pack": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", @@ -7817,6 +8141,23 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@jsonjoy.com/json-pointer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", @@ -7859,6 +8200,23 @@ "tslib": "2" } }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -8257,12 +8615,13 @@ ] }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.24.0.tgz", - "integrity": "sha512-D8h5KXY2vHFW8zTuxn2vuZGN0HGrQ5No6LkHwlEA9trVgNdPL3TF1dSqKA7Dny6BbBYKSW/rOBDXdC8KJAjUCg==", + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.2.tgz", + "integrity": "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==", "dev": true, "license": "MIT", "dependencies": { + "@hono/node-server": "^1.19.7", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -8273,6 +8632,7 @@ "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", @@ -8702,9 +9062,9 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz", - "integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", "dev": true, "license": "MIT", "optional": true, @@ -8712,12 +9072,16 @@ "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, "node_modules/@ngtools/webpack": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-21.0.2.tgz", - "integrity": "sha512-tpRTotMlPQuDvc0xeUMBkEWPGZ5GUek4nInTIbLvyVC5HtErDv+IDEK2CrY2rCVJGlClFVT7yIyalQf6WKTvhw==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-21.0.6.tgz", + "integrity": "sha512-zkYk1beMaEPpXxseYE6BgSGndtqxRNKikI5l8NK1uZ/xezy0YVtRBfD9xJVMGpbbkHWKHrGTciYYjKSg4ReZ5A==", "dev": true, "license": "MIT", "engines": { @@ -10737,274 +11101,54 @@ "x64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/wasm-node": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/wasm-node/-/wasm-node-4.53.3.tgz", - "integrity": "sha512-mB8z32H6kz4kVjn+tfTGcrXBae7rIeAvm/g6itsE3IqcXpjSRRvk1/EOWDEi5wL8NNmxXiH71t4jtNfr128zpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@schematics/angular": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.0.2.tgz", - "integrity": "sha512-JzFHwSNmagzmfBJVSfoJc2i4TqmlXv0iyrVke3vP2b+/CqOBhuDLQSkkdiC+8zI0qJFzgDHn2RlCd0WaIwLfiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "21.0.2", - "@angular-devkit/schematics": "21.0.2", - "jsonc-parser": "3.3.1" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.0.2.tgz", - "integrity": "sha512-mFKWTI56D5VmqyIonEK6myIdlGVJpxtxLW44uB1/jiVj7vUSnJCRFHSPH8syaIJ4/Y1B/T4kPTYCx/KEwnO/Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "21.0.2", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.19", - "ora": "9.0.0", - "rxjs": "7.8.2" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@schematics/angular/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@schematics/angular/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/cli-spinners": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", - "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/log-symbols": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/ora": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", - "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.2.2", - "string-width": "^8.1.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@schematics/angular/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@schematics/angular/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "node_modules/@rollup/wasm-node": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/wasm-node/-/wasm-node-4.53.3.tgz", + "integrity": "sha512-mB8z32H6kz4kVjn+tfTGcrXBae7rIeAvm/g6itsE3IqcXpjSRRvk1/EOWDEi5wL8NNmxXiH71t4jtNfr128zpw==", "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=20" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/@schematics/angular/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@schematics/angular": { + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.0.6.tgz", + "integrity": "sha512-9oh0RX+Cj2Pc8Aap/75qkcK2rmDZcyoTokiJG1m2b/I9MH1XmiFBdao1du2BA5GJtBRFizzXCoYf5v4LwxIP2w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "@angular-devkit/core": "21.0.6", + "@angular-devkit/schematics": "21.0.6", + "jsonc-parser": "3.3.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, "node_modules/@shiftcode/branch-utilities": { @@ -11361,15 +11505,15 @@ } }, "node_modules/@shiftcode/logger": { - "version": "3.0.0", - "resolved": "https://npm.pkg.github.com/download/@shiftcode/logger/3.0.0/da9b7d65a0545ebb5499b5f7ffd2e86ef90c6ce2", - "integrity": "sha512-UAUiG9iWHfXQbumY2y1Z0JjZoPJ+Ebq9FOd/+aFnp9zJrt7+zRTUPDdGj4sQ7vf8Hvis3dzRUdEmW4swgomxlg==", + "version": "4.0.0-pr250.9", + "resolved": "https://npm.pkg.github.com/download/@shiftcode/logger/4.0.0-pr250.9/a501a86d4854d1327dd432480e59af3877a68889", + "integrity": "sha512-kEqJQ8mBojPhH6LtAjjWFRaPEbLPgDa0SLvkc7+fX5CPi5p0re13V2+blIawpQ4J+qXM9T88Q8WqoloM3f/yjg==", "license": "UNLICENSED", "engines": { - "node": "^20.0.0 || ^22.0.0" + "node": "^22.0.0 || ^24.0.0" }, "peerDependencies": { - "@shiftcode/utilities": "^4.0.0 || ^4.0.0-pr45" + "@shiftcode/utilities": "^4.0.0" } }, "node_modules/@shiftcode/publish-helper": { @@ -11531,8 +11675,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@tsconfig/node10": { "version": "1.0.11", @@ -11753,9 +11896,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", "dev": true, "license": "MIT", "dependencies": { @@ -12866,16 +13009,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/accepts/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -13088,25 +13221,6 @@ } } }, - "node_modules/angular-eslint/node_modules/@angular-devkit/schematics": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.0.1.tgz", - "integrity": "sha512-3koB1xJNkqMg7g6JwH2rhQO268WjnPVA852lwoLW7wzSZRpJH0kHtZsnY9FYOC2kbmAGnCWWbnPLJ5/T1wemoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "21.0.1", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.19", - "ora": "9.0.0", - "rxjs": "7.8.2" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, "node_modules/angular-eslint/node_modules/@angular-eslint/builder": { "version": "21.0.1", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.0.1.tgz", @@ -13212,61 +13326,6 @@ "typescript": "*" } }, - "node_modules/angular-eslint/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/angular-eslint/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/angular-eslint/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/cli-spinners": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", - "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/angular-eslint/node_modules/eslint-scope": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.0.0.tgz", @@ -13274,193 +13333,47 @@ "dev": true, "license": "BSD-2-Clause", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/angular-eslint/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/angular-eslint/node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/log-symbols": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0", - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/ora": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", - "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.6.2", - "cli-cursor": "^5.0.0", - "cli-spinners": "^3.2.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.1.0", - "log-symbols": "^7.0.1", - "stdin-discarder": "^0.2.2", - "string-width": "^8.1.0", - "strip-ansi": "^7.1.2" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/angular-eslint/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/angular-eslint/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=14" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/angular-eslint/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "node_modules/angular-eslint/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "engines": { - "node": ">= 12" + "node": ">= 4" } }, - "node_modules/angular-eslint/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "node_modules/angular-eslint/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" - }, "engines": { - "node": ">=20" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/angular-eslint/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/angular-eslint/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">= 12" } }, "node_modules/ansi-colors": { @@ -14108,9 +14021,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.30", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.30.tgz", - "integrity": "sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==", + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz", + "integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -14251,9 +14164,9 @@ } }, "node_modules/body-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", - "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "dev": true, "license": "MIT", "dependencies": { @@ -14263,7 +14176,7 @@ "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", + "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, @@ -14294,9 +14207,9 @@ } }, "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { @@ -14359,9 +14272,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -14379,11 +14292,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -14695,9 +14608,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001756", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001756.tgz", - "integrity": "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==", + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "dev": true, "funding": [ { @@ -15155,6 +15068,16 @@ "dev": true, "license": "MIT" }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -15454,9 +15377,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "dev": true, "license": "MIT", "dependencies": { @@ -15465,6 +15388,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cosmiconfig": { @@ -16211,9 +16138,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.259", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.259.tgz", - "integrity": "sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==", + "version": "1.5.277", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.277.tgz", + "integrity": "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw==", "dev": true, "license": "ISC" }, @@ -16474,9 +16401,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -18699,6 +18626,17 @@ "node": ">= 0.4" } }, + "node_modules/hono": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.5.tgz", + "integrity": "sha512-WemPi9/WfyMwZs+ZUXdiwcCh9Y+m7L+8vki9MzDw3jJ+W9Lc+12HGsd368Qc1vZi1xwW8BWMMsnK5efYKPdt4g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/hosted-git-info": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", @@ -18789,9 +18727,9 @@ "license": "MIT" }, "node_modules/htmlparser2": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", - "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -18804,14 +18742,14 @@ "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.2.1", - "entities": "^6.0.0" + "domutils": "^3.2.2", + "entities": "^7.0.1" } }, "node_modules/htmlparser2/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -22621,6 +22559,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -23541,13 +23486,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/loader-utils": { @@ -23947,16 +23896,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/make-fetch-happen/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -24001,12 +23940,20 @@ } }, "node_modules/memfs": { - "version": "4.51.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.51.1.tgz", - "integrity": "sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==", + "version": "4.56.9", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.9.tgz", + "integrity": "sha512-Fo+xSG0MhtaPyEi7B2AEj4omBen3kb5RCeFKaM/YVsxgO8vkcpX0tkheRIoCGqXw9oAnFQRe1oWuR1xq4oE17A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@jsonjoy.com/fs-core": "4.56.9", + "@jsonjoy.com/fs-fsa": "4.56.9", + "@jsonjoy.com/fs-node": "4.56.9", + "@jsonjoy.com/fs-node-builtins": "4.56.9", + "@jsonjoy.com/fs-node-to-fsa": "4.56.9", + "@jsonjoy.com/fs-node-utils": "4.56.9", + "@jsonjoy.com/fs-print": "4.56.9", + "@jsonjoy.com/fs-snapshot": "^4.56.9", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", @@ -24017,6 +23964,9 @@ "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, "node_modules/meow": { @@ -24523,9 +24473,9 @@ "license": "MIT" }, "node_modules/msgpackr": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.5.tgz", - "integrity": "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==", + "version": "1.11.8", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.8.tgz", + "integrity": "sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==", "dev": true, "license": "MIT", "optional": true, @@ -24671,9 +24621,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, "license": "MIT", "engines": { @@ -25565,16 +25515,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/node-gyp/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/node-gyp/node_modules/p-map": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", @@ -26415,9 +26355,9 @@ } }, "node_modules/ordered-binary": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.0.tgz", - "integrity": "sha512-IQh2aMfMIDbPjI/8a3Edr+PiOpcsB7yo8NdW7aHWVaoR/pcDldunMvnnwbk/auPGqmKeAdxtZl7MHX/QmPwhvQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", "dev": true, "license": "MIT", "optional": true @@ -27535,9 +27475,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -27618,9 +27558,9 @@ } }, "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { @@ -28699,26 +28639,48 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/send/node_modules/mime-db": { @@ -28766,22 +28728,26 @@ } }, "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", "dev": true, "license": "MIT", "dependencies": { - "accepts": "~1.3.4", + "accepts": "~1.3.8", "batch": "0.6.1", "debug": "2.6.9", "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" }, "engines": { "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serve-index/node_modules/accepts": { @@ -28819,28 +28785,22 @@ } }, "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "license": "MIT", "dependencies": { "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.6" } }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true, - "license": "ISC" - }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -28858,13 +28818,6 @@ "node": ">= 0.6" } }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true, - "license": "ISC" - }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -28876,9 +28829,9 @@ } }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "dev": true, "license": "MIT", "dependencies": { @@ -28889,6 +28842,10 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/set-blocking": { @@ -29897,9 +29854,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -30869,9 +30826,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -31664,9 +31621,9 @@ } }, "node_modules/webpack": { - "version": "5.102.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", - "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", + "version": "5.104.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.0.tgz", + "integrity": "sha512-5DeICTX8BVgNp6afSPYXAFjskIgWGlygQH58bcozPOXgo2r/6xx39Y1+cULZ3gTxUYQP88jmwLj2anu4Xaq84g==", "dev": true, "license": "MIT", "dependencies": { @@ -31678,21 +31635,21 @@ "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.26.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.3", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.17.4", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.11", + "terser-webpack-plugin": "^5.3.16", "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, @@ -32164,9 +32121,9 @@ } }, "node_modules/webpack-dev-server/node_modules/send": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.1.tgz", - "integrity": "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "dev": true, "license": "MIT", "dependencies": { @@ -32176,35 +32133,18 @@ "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~2.0.2" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/webpack-dev-server/node_modules/send/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/webpack-dev-server/node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -32212,101 +32152,22 @@ "dev": true, "license": "MIT" }, - "node_modules/webpack-dev-server/node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/webpack-dev-server/node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", "dev": true, "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/webpack-dev-server/node_modules/serve-static/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/webpack-dev-server/node_modules/serve-static/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/webpack-dev-server/node_modules/serve-static/node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "send": "~0.19.1" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/webpack-dev-server/node_modules/serve-static/node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/webpack-dev-server/node_modules/serve-static/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/webpack-dev-server/node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -32953,9 +32814,9 @@ } }, "node_modules/zod-to-json-schema": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.0.tgz", - "integrity": "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==", + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", "dev": true, "license": "ISC", "peerDependencies": { @@ -32966,7 +32827,6 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.0.tgz", "integrity": "sha512-9oxn0IIjbCZkJ67L+LkhYWRyAy7axphb3VgE2MBDlOqnmHMPWGYMxJxBYFueFq/JGY2GMwS0rU+UCLunEmy5UA==", - "devOptional": true, "license": "MIT" } } diff --git a/package.json b/package.json index bacd629d..ecb3cb24 100644 --- a/package.json +++ b/package.json @@ -21,27 +21,28 @@ "watch": "ng build --watch --configuration development" }, "dependencies": { - "@angular/animations": "~21.0.3", - "@angular/cdk": "~21.0.0", - "@angular/common": "~21.0.3", - "@angular/core": "~21.0.3", - "@angular/forms": "~21.0.3", - "@angular/platform-browser": "~21.0.3", - "@angular/router": "~21.0.3", - "@angular/ssr": "~21.0.2", - "@shiftcode/logger": "^3.0.0", + "@angular/animations": "~21.0.9", + "@angular/cdk": "~21.0.6", + "@angular/common": "~21.0.9", + "@angular/core": "~21.0.9", + "@angular/forms": "~21.0.9", + "@angular/platform-browser": "~21.0.9", + "@angular/router": "~21.0.9", + "@angular/ssr": "~21.0.6", + "@shiftcode/logger": "^4.0.0-pr250.9", "@shiftcode/utilities": "^4.0.0", "rxjs": "^6.5.3 || ^7.4.0", - "tslib": "^2.5.0" + "tslib": "^2.5.0", + "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "~21.0.2", - "@angular/build": "~21.0.2", - "@angular/cli": "~21.0.2", - "@angular/compiler": "~21.0.3", - "@angular/compiler-cli": "~21.0.3", - "@angular/platform-browser-dynamic": "~21.0.3", - "@angular/platform-server": "~21.0.3", + "@angular-devkit/build-angular": "~21.0.6", + "@angular/build": "~21.0.6", + "@angular/cli": "~21.0.6", + "@angular/compiler": "~21.0.9", + "@angular/compiler-cli": "~21.0.9", + "@angular/platform-browser-dynamic": "~21.0.9", + "@angular/platform-server": "~21.0.9", "@commitlint/cli": "^19.3.0", "@commitlint/config-angular": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", @@ -65,14 +66,13 @@ "ts-jest": "^29.4.5", "ts-node": "^10.9.2", "tslib": "^2.5.0", - "typescript": "5.9.3", - "zone.js": "~0.15.0" + "typescript": "5.9.3" }, "optionalDependencies": { "@nx/nx-linux-x64-gnu": "^19.4.2", "@rollup/rollup-linux-x64-gnu": "^4.20.0" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || ^24.0.0" + "node": "^22.12.0 || ^24.0.0" } }