From 64ac506eb44baa3f8c4ffaefba49c648aaf0fff4 Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Wed, 29 Jul 2026 17:04:22 +0200 Subject: [PATCH 1/2] chore: add nestjs linter Signed-off-by: William Phetsinorath Change-Id: I84bd2176629df04db896da1095598a636a6a6964 --- apps/server-nestjs/eslint.config.mjs | 10 +- apps/server-nestjs/package.json | 1 + .../src/modules/argocd/argocd.module.ts | 2 +- .../modules/environment/environment.module.ts | 2 +- .../src/modules/healthz/healthz.module.ts | 6 +- .../auth/keycloak-jwt/keycloak-jwt.module.ts | 2 +- .../keycloak-secret-provider.module.ts | 2 +- .../infrastructure/infrastructure.module.ts | 4 +- .../permission/permission.module.ts | 4 +- .../permission/project/project.module.ts | 4 +- .../permission/user/user.module.ts | 4 +- .../src/modules/nexus/nexus.module.ts | 6 +- .../src/modules/plugin/plugin.module.ts | 2 +- .../project-bulk/project-bulk.module.ts | 4 +- .../project-secrets/project-secrets.module.ts | 2 +- .../src/modules/project/project.module.ts | 2 +- .../src/modules/registry/registry.module.ts | 4 +- .../service-chain/service-chain.module.ts | 2 +- .../src/modules/sonarqube/sonarqube.module.ts | 4 +- .../src/modules/vault/vault.module.ts | 4 +- pnpm-lock.yaml | 544 +++++++++++++----- pnpm-workspace.yaml | 1 + 22 files changed, 455 insertions(+), 161 deletions(-) diff --git a/apps/server-nestjs/eslint.config.mjs b/apps/server-nestjs/eslint.config.mjs index 5a664d2b58..51fc348b8d 100644 --- a/apps/server-nestjs/eslint.config.mjs +++ b/apps/server-nestjs/eslint.config.mjs @@ -1,3 +1,11 @@ import eslintConfigBase from '@cpn-console/eslint-config' +import nestjsTyped from '@darraghor/eslint-plugin-nestjs-typed' -export default eslintConfigBase +export default eslintConfigBase.append({ + plugins: { + '@darraghor/nestjs-typed': nestjsTyped, + }, + rules: { + '@darraghor/nestjs-typed/sort-module-metadata-arrays': 'error', + }, +}).append(nestjsTyped.configs.flatNoSwagger) diff --git a/apps/server-nestjs/package.json b/apps/server-nestjs/package.json index 79126d32e2..3fa2d14223 100644 --- a/apps/server-nestjs/package.json +++ b/apps/server-nestjs/package.json @@ -85,6 +85,7 @@ "@cpn-console/eslint-config": "workspace:^", "@cpn-console/test-utils": "workspace:^", "@cpn-console/ts-config": "workspace:^", + "@darraghor/eslint-plugin-nestjs-typed": "catalog:tools", "@eslint/eslintrc": "catalog:tools", "@eslint/js": "catalog:tools", "@faker-js/faker": "catalog:test", diff --git a/apps/server-nestjs/src/modules/argocd/argocd.module.ts b/apps/server-nestjs/src/modules/argocd/argocd.module.ts index ad51bf62dd..9dcd832d00 100644 --- a/apps/server-nestjs/src/modules/argocd/argocd.module.ts +++ b/apps/server-nestjs/src/modules/argocd/argocd.module.ts @@ -11,7 +11,7 @@ import { ArgoCDService } from './argocd.service' @Module({ imports: [ConfigurationModule, DatabaseModule, GitlabModule, TerminusModule, VaultModule], - providers: [ArgoCDHealthService, ArgoCDPluginService, ArgoCDService, ArgoCDDatastoreService], + providers: [ArgoCDDatastoreService, ArgoCDHealthService, ArgoCDPluginService, ArgoCDService], exports: [ArgoCDHealthService, ArgoCDPluginService, ArgoCDService], }) export class ArgoCDModule {} diff --git a/apps/server-nestjs/src/modules/environment/environment.module.ts b/apps/server-nestjs/src/modules/environment/environment.module.ts index a9c4f597d4..a61a690d24 100644 --- a/apps/server-nestjs/src/modules/environment/environment.module.ts +++ b/apps/server-nestjs/src/modules/environment/environment.module.ts @@ -11,8 +11,8 @@ import { EnvironmentService } from './environment.service' controllers: [EnvironmentController], providers: [ EnvironmentDatastoreService, - EnvironmentValidationService, EnvironmentService, + EnvironmentValidationService, ], }) export class EnvironmentModule {} diff --git a/apps/server-nestjs/src/modules/healthz/healthz.module.ts b/apps/server-nestjs/src/modules/healthz/healthz.module.ts index 50141664e4..91fa2739b0 100644 --- a/apps/server-nestjs/src/modules/healthz/healthz.module.ts +++ b/apps/server-nestjs/src/modules/healthz/healthz.module.ts @@ -15,15 +15,15 @@ import { HealthzService } from './healthz.service' @Module({ imports: [ - TerminusModule, - DatabaseModule, - KeycloakModule, ConditionalModule.registerWhen(ArgoCDModule, 'USE_ARGOCD'), ConditionalModule.registerWhen(GitlabModule, 'USE_GITLAB'), ConditionalModule.registerWhen(NexusModule, 'USE_NEXUS'), ConditionalModule.registerWhen(RegistryModule, 'USE_HARBOR'), ConditionalModule.registerWhen(ServiceChainModule, optIn('USE_SERVICE_CHAIN')), ConditionalModule.registerWhen(VaultModule, 'USE_VAULT'), + DatabaseModule, + KeycloakModule, + TerminusModule, ], controllers: [HealthzController], providers: [HealthzService], diff --git a/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-jwt/keycloak-jwt.module.ts b/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-jwt/keycloak-jwt.module.ts index 985a16aa0f..ac229c5cd8 100644 --- a/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-jwt/keycloak-jwt.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-jwt/keycloak-jwt.module.ts @@ -29,6 +29,6 @@ import { KeycloakJwtService } from './keycloak-jwt.service' }), ], providers: [KeycloakJwtService], - exports: [KeycloakJwtService, JwtModule], + exports: [JwtModule, KeycloakJwtService], }) export class KeycloakJwtModule {} diff --git a/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-secret-provider/keycloak-secret-provider.module.ts b/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-secret-provider/keycloak-secret-provider.module.ts index bdc7422816..d18b1093ad 100644 --- a/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-secret-provider/keycloak-secret-provider.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/auth/keycloak-secret-provider/keycloak-secret-provider.module.ts @@ -4,7 +4,7 @@ import { ConfigurationModule } from '../../configuration/configuration.module' import { KeycloakSecretProviderService } from './keycloak-secret-provider.service' @Module({ - imports: [ConfigurationModule, CacheModule.register()], + imports: [CacheModule.register(), ConfigurationModule], providers: [KeycloakSecretProviderService], exports: [KeycloakSecretProviderService], }) diff --git a/apps/server-nestjs/src/modules/infrastructure/infrastructure.module.ts b/apps/server-nestjs/src/modules/infrastructure/infrastructure.module.ts index e29dae241f..0f9bb288ae 100644 --- a/apps/server-nestjs/src/modules/infrastructure/infrastructure.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/infrastructure.module.ts @@ -8,7 +8,7 @@ import { PermissionModule } from './permission/permission.module' @Module({ providers: [], - imports: [AuthModule, DatabaseModule, ConfigurationModule, EventsModule, LoggerModule, PermissionModule], - exports: [AuthModule, DatabaseModule, ConfigurationModule, EventsModule, LoggerModule, PermissionModule], + imports: [AuthModule, ConfigurationModule, DatabaseModule, EventsModule, LoggerModule, PermissionModule], + exports: [AuthModule, ConfigurationModule, DatabaseModule, EventsModule, LoggerModule, PermissionModule], }) export class InfrastructureModule {} diff --git a/apps/server-nestjs/src/modules/infrastructure/permission/permission.module.ts b/apps/server-nestjs/src/modules/infrastructure/permission/permission.module.ts index c2f926a351..479df8bbe5 100644 --- a/apps/server-nestjs/src/modules/infrastructure/permission/permission.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/permission/permission.module.ts @@ -3,7 +3,7 @@ import { ProjectPermissionModule } from './project/project.module' import { UserPermissionModule } from './user/user.module' @Module({ - imports: [UserPermissionModule, ProjectPermissionModule], - exports: [UserPermissionModule, ProjectPermissionModule], + imports: [ProjectPermissionModule, UserPermissionModule], + exports: [ProjectPermissionModule, UserPermissionModule], }) export class PermissionModule {} diff --git a/apps/server-nestjs/src/modules/infrastructure/permission/project/project.module.ts b/apps/server-nestjs/src/modules/infrastructure/permission/project/project.module.ts index 6561dd78dd..401676d4bb 100644 --- a/apps/server-nestjs/src/modules/infrastructure/permission/project/project.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/permission/project/project.module.ts @@ -14,14 +14,14 @@ import { ProjectPermissionService } from './project.service' providers: [ ProjectGuard, ProjectPermissionLoaderService, - ProjectPermissionService, ProjectPermissionPolicy, + ProjectPermissionService, ], exports: [ ProjectGuard, ProjectPermissionLoaderService, - ProjectPermissionService, ProjectPermissionPolicy, + ProjectPermissionService, ], }) export class ProjectPermissionModule {} diff --git a/apps/server-nestjs/src/modules/infrastructure/permission/user/user.module.ts b/apps/server-nestjs/src/modules/infrastructure/permission/user/user.module.ts index 613821ed2a..5ae8805c85 100644 --- a/apps/server-nestjs/src/modules/infrastructure/permission/user/user.module.ts +++ b/apps/server-nestjs/src/modules/infrastructure/permission/user/user.module.ts @@ -12,13 +12,13 @@ import { UserPermissionService } from './user.service' ], providers: [ UserGuard, - UserPermissionService, UserPermissionPolicy, + UserPermissionService, ], exports: [ UserGuard, - UserPermissionService, UserPermissionPolicy, + UserPermissionService, ], }) export class UserPermissionModule {} diff --git a/apps/server-nestjs/src/modules/nexus/nexus.module.ts b/apps/server-nestjs/src/modules/nexus/nexus.module.ts index 14d706232d..37e3e36b02 100644 --- a/apps/server-nestjs/src/modules/nexus/nexus.module.ts +++ b/apps/server-nestjs/src/modules/nexus/nexus.module.ts @@ -13,12 +13,12 @@ import { NexusService } from './nexus.service' @Module({ imports: [ConfigurationModule, DatabaseModule, TerminusModule, VaultModule], providers: [ + NexusClientService, + NexusDatastoreService, NexusHealthService, + NexusHttpClientService, NexusPluginService, NexusService, - NexusDatastoreService, - NexusHttpClientService, - NexusClientService, ], exports: [NexusClientService, NexusHealthService, NexusPluginService, NexusService], }) diff --git a/apps/server-nestjs/src/modules/plugin/plugin.module.ts b/apps/server-nestjs/src/modules/plugin/plugin.module.ts index f2aeee1a67..105f2d0fe7 100644 --- a/apps/server-nestjs/src/modules/plugin/plugin.module.ts +++ b/apps/server-nestjs/src/modules/plugin/plugin.module.ts @@ -15,12 +15,12 @@ import { PluginService } from './plugin.service' imports: [ ConditionalModule.registerWhen(ArgoCDModule, 'USE_ARGOCD'), ConditionalModule.registerWhen(GitlabModule, 'USE_GITLAB'), - KeycloakModule, ConditionalModule.registerWhen(NexusModule, 'USE_NEXUS'), ConditionalModule.registerWhen(RegistryModule, 'USE_HARBOR'), ConditionalModule.registerWhen(ServiceChainModule, optIn('USE_SERVICE_CHAIN')), ConditionalModule.registerWhen(SonarqubeModule, 'USE_SONARQUBE'), ConditionalModule.registerWhen(VaultModule, 'USE_VAULT'), + KeycloakModule, ], providers: [PluginService], exports: [PluginService], diff --git a/apps/server-nestjs/src/modules/project-bulk/project-bulk.module.ts b/apps/server-nestjs/src/modules/project-bulk/project-bulk.module.ts index fbb1d9bf76..af4501a3ef 100644 --- a/apps/server-nestjs/src/modules/project-bulk/project-bulk.module.ts +++ b/apps/server-nestjs/src/modules/project-bulk/project-bulk.module.ts @@ -13,9 +13,9 @@ import { ProjectBulkService } from './project-bulk.service' AuthModule, DatabaseModule, EventsModule, - UserPermissionModule, - ProjectModule, ProjectHooksModule, + ProjectModule, + UserPermissionModule, ], controllers: [ProjectBulkController], providers: [ProjectBulkService], diff --git a/apps/server-nestjs/src/modules/project-secrets/project-secrets.module.ts b/apps/server-nestjs/src/modules/project-secrets/project-secrets.module.ts index 1d3e2ef1f0..84c29ffaa2 100644 --- a/apps/server-nestjs/src/modules/project-secrets/project-secrets.module.ts +++ b/apps/server-nestjs/src/modules/project-secrets/project-secrets.module.ts @@ -9,7 +9,7 @@ import { ProjectSecretsController } from './project-secrets.controller' import { ProjectSecretsService } from './project-secrets.service' @Module({ - imports: [AuthModule, ConfigurationModule, DatabaseModule, ProjectPermissionModule, ConditionalModule.registerWhen(VaultModule, 'USE_VAULT')], + imports: [AuthModule, ConditionalModule.registerWhen(VaultModule, 'USE_VAULT'), ConfigurationModule, DatabaseModule, ProjectPermissionModule], controllers: [ProjectSecretsController], providers: [ProjectSecretsService], exports: [ProjectSecretsService], diff --git a/apps/server-nestjs/src/modules/project/project.module.ts b/apps/server-nestjs/src/modules/project/project.module.ts index 19e7f0b594..c9117fe7ed 100644 --- a/apps/server-nestjs/src/modules/project/project.module.ts +++ b/apps/server-nestjs/src/modules/project/project.module.ts @@ -17,9 +17,9 @@ import { ProjectService } from './project.service' ConfigurationModule, DatabaseModule, EventsModule, + LogModule, ProjectPermissionModule, UserPermissionModule, - LogModule, ], controllers: [ProjectController], providers: [ProjectService], diff --git a/apps/server-nestjs/src/modules/registry/registry.module.ts b/apps/server-nestjs/src/modules/registry/registry.module.ts index b205b1babb..b461bcde5a 100644 --- a/apps/server-nestjs/src/modules/registry/registry.module.ts +++ b/apps/server-nestjs/src/modules/registry/registry.module.ts @@ -12,8 +12,8 @@ import { RegistryPluginService } from './registry-plugin.service' import { RegistryService } from './registry.service' @Module({ - imports: [ConfigurationModule, DatabaseModule, TerminusModule, VaultModule, CacheModule.register()], - providers: [RegistryHealthService, RegistryPluginService, RegistryService, RegistryDatastoreService, RegistryHttpClientService, RegistryClientService], + imports: [CacheModule.register(), ConfigurationModule, DatabaseModule, TerminusModule, VaultModule], + providers: [RegistryClientService, RegistryDatastoreService, RegistryHealthService, RegistryHttpClientService, RegistryPluginService, RegistryService], exports: [RegistryHealthService, RegistryPluginService, RegistryService], }) export class RegistryModule {} diff --git a/apps/server-nestjs/src/modules/service-chain/service-chain.module.ts b/apps/server-nestjs/src/modules/service-chain/service-chain.module.ts index 58103a0409..3664aee98c 100644 --- a/apps/server-nestjs/src/modules/service-chain/service-chain.module.ts +++ b/apps/server-nestjs/src/modules/service-chain/service-chain.module.ts @@ -21,6 +21,6 @@ import { ServiceChainService } from './service-chain.service' ], controllers: [ServiceChainController], providers: [OpenCdsClientService, ServiceChainHealthService, ServiceChainService], - exports: [ServiceChainService, ServiceChainHealthService], + exports: [ServiceChainHealthService, ServiceChainService], }) export class ServiceChainModule {} diff --git a/apps/server-nestjs/src/modules/sonarqube/sonarqube.module.ts b/apps/server-nestjs/src/modules/sonarqube/sonarqube.module.ts index 17499fdda4..f7c44a6780 100644 --- a/apps/server-nestjs/src/modules/sonarqube/sonarqube.module.ts +++ b/apps/server-nestjs/src/modules/sonarqube/sonarqube.module.ts @@ -13,10 +13,10 @@ import { SonarqubeService } from './sonarqube.service' @Module({ imports: [ConfigurationModule, DatabaseModule, TerminusModule, VaultModule], providers: [ - SonarqubeHealthService, - SonarqubeHttpClientService, SonarqubeClientService, SonarqubeDatastoreService, + SonarqubeHealthService, + SonarqubeHttpClientService, SonarqubePluginService, SonarqubeService, ], diff --git a/apps/server-nestjs/src/modules/vault/vault.module.ts b/apps/server-nestjs/src/modules/vault/vault.module.ts index 0b1d8281ea..893c960db2 100644 --- a/apps/server-nestjs/src/modules/vault/vault.module.ts +++ b/apps/server-nestjs/src/modules/vault/vault.module.ts @@ -12,12 +12,12 @@ import { VaultService } from './vault.service' @Module({ imports: [ConfigurationModule, DatabaseModule, TerminusModule], providers: [ + VaultClientService, + VaultDatastoreService, VaultHealthService, VaultHttpClientService, - VaultClientService, VaultPluginService, VaultService, - VaultDatastoreService, ], exports: [VaultClientService, VaultHealthService, VaultPluginService, VaultService], }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4265e63be7..207480b3f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -305,6 +305,9 @@ catalogs: '@commitlint/config-conventional': specifier: ^20.5.3 version: 20.5.3 + '@darraghor/eslint-plugin-nestjs-typed': + specifier: ^7.2.9 + version: 7.2.9 '@eslint/eslintrc': specifier: ^3.3.5 version: 3.3.5 @@ -391,7 +394,7 @@ importers: version: link:packages/eslintconfig eslint: specifier: catalog:tools - version: 10.5.0(jiti@2.6.1) + version: 10.5.0(jiti@2.6.1)(supports-color@5.5.0) husky: specifier: catalog:tools version: 9.1.7 @@ -494,7 +497,7 @@ importers: version: 4.1.5(vitest@4.1.5) '@vue/eslint-config-typescript': specifier: catalog:tools - version: 14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + version: 14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) chalk: specifier: catalog:tools version: 5.6.2 @@ -506,22 +509,22 @@ importers: version: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))) jsdom: specifier: catalog:test - version: 25.0.1 + version: 25.0.1(supports-color@5.5.0) rimraf: specifier: catalog:tools version: 6.1.3 stylelint: specifier: catalog:tools - version: 17.11.0(typescript@5.9.3) + version: 17.11.0(supports-color@5.5.0)(typescript@5.9.3) stylelint-config-html: specifier: catalog:tools - version: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) + version: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) stylelint-config-recommended-vue: specifier: catalog:tools - version: 1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) + version: 1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) stylelint-config-standard: specifier: catalog:tools - version: 40.0.0(stylelint@17.11.0(typescript@5.9.3)) + version: 40.0.0(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) typescript: specifier: catalog:build version: 5.9.3 @@ -533,7 +536,7 @@ importers: version: 0.18.6(rollup@2.80.0) unplugin-vue-components: specifier: catalog:build - version: 0.27.5(@babel/parser@7.29.7)(rollup@2.80.0)(vue@3.5.30(typescript@5.9.3)) + version: 0.27.5(@babel/parser@7.29.7)(rollup@2.80.0)(supports-color@5.5.0)(vue@3.5.30(typescript@5.9.3)) vite: specifier: catalog:build version: 7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0) @@ -542,13 +545,13 @@ importers: version: 6.0.0(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.48.0)(yaml@2.9.0) vite-plugin-pwa: specifier: catalog:build - version: 1.2.0(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) + version: 1.2.0(supports-color@5.5.0)(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) vitest: specifier: catalog:test version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1)(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) vue-eslint-parser: specifier: catalog:tools - version: 10.4.0(eslint@10.5.0(jiti@2.6.1)) + version: 10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) vue-tsc: specifier: catalog:build version: 2.2.12(typescript@5.9.3) @@ -596,13 +599,13 @@ importers: version: 13.0.2 '@fastify/otel': specifier: catalog:runtime - version: 0.18.1(@opentelemetry/api@1.9.1) + version: 0.18.1(@opentelemetry/api@1.9.1)(supports-color@5.5.0) '@fastify/session': specifier: catalog:runtime version: 11.1.1 '@fastify/swagger': specifier: catalog:runtime - version: 9.7.0 + version: 9.7.0(supports-color@5.5.0) '@fastify/swagger-ui': specifier: catalog:runtime version: 5.2.6 @@ -774,34 +777,34 @@ importers: version: 2.7.2 '@nestjs/cache-manager': specifier: catalog:runtime - version: 3.1.3(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2) + version: 3.1.3(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2) '@nestjs/common': specifier: catalog:runtime - version: 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) '@nestjs/config': specifier: catalog:runtime - version: 4.0.3(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + version: 4.0.3(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(rxjs@7.8.2) '@nestjs/core': specifier: catalog:runtime - version: 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/event-emitter': specifier: catalog:runtime - version: 3.0.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 3.0.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16) '@nestjs/jwt': specifier: catalog:runtime - version: 11.0.2(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2)) + version: 11.0.2(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0)) '@nestjs/platform-fastify': specifier: catalog:runtime - version: 11.1.27(@fastify/static@9.1.3)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 11.1.27(@fastify/static@9.1.3)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16) '@nestjs/schedule': specifier: catalog:runtime - version: 6.1.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + version: 6.1.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16) '@nestjs/swagger': specifier: catalog:runtime - version: 11.4.1(@fastify/static@9.1.3)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(reflect-metadata@0.2.2) + version: 11.4.1(@fastify/static@9.1.3)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(class-validator@0.15.1)(reflect-metadata@0.2.2) '@nestjs/terminus': specifier: catalog:runtime - version: 11.1.1(@grpc/grpc-js@1.14.3)(@grpc/proto-loader@0.8.0)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@prisma/client@6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3))(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.1(@grpc/grpc-js@1.14.3)(@grpc/proto-loader@0.8.0)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(@prisma/client@6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3))(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: catalog:otel version: 1.9.1 @@ -858,7 +861,7 @@ importers: version: 4.2.0 nestjs-pino: specifier: catalog:runtime - version: 4.6.0(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.3.1)(rxjs@7.8.2) + version: 4.6.0(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(pino-http@11.0.0)(pino@10.3.1)(rxjs@7.8.2) prisma: specifier: catalog:runtime version: 6.19.2(magicast@0.3.5)(typescript@5.9.3) @@ -890,9 +893,12 @@ importers: '@cpn-console/ts-config': specifier: workspace:^ version: link:../../packages/tsconfig + '@darraghor/eslint-plugin-nestjs-typed': + specifier: catalog:tools + version: 7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) '@eslint/eslintrc': specifier: catalog:tools - version: 3.3.5 + version: 3.3.5(supports-color@5.5.0) '@eslint/js': specifier: catalog:tools version: 9.39.4 @@ -907,7 +913,7 @@ importers: version: 11.0.9(chokidar@4.0.3)(typescript@5.9.3) '@nestjs/testing': specifier: catalog:build - version: 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16) + version: 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16) '@types/node': specifier: catalog:types version: 24.12.0 @@ -952,7 +958,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: catalog:tools - version: 8.2.0(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3))(@typescript-eslint/utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5) + version: 8.2.0(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3))(@typescript-eslint/utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)(vitest@4.1.5) eslint: specifier: catalog:tools version: 10.5.0(jiti@2.6.1) @@ -2328,6 +2334,14 @@ packages: peerDependencies: postcss-selector-parser: ^7.1.1 + '@darraghor/eslint-plugin-nestjs-typed@7.2.9': + resolution: {integrity: sha512-/l3/RCb8ik2CbIIAOOdsva7fOlfMvojIfyVyHAdLXZJ3yuSJEBdRoRWCBdbcr38IT9p/CmiZMjLsFiTBOr1GJg==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 + class-validator: '*' + eslint: '>=9.18.0' + '@e18e/eslint-plugin@0.3.0': resolution: {integrity: sha512-hHgfpxsrZ2UYHcicA+tGZnmk19uJTaye9VH79O+XS8R4ona2Hx3xjhXghclNW58uXMk3xXlbYEOMr8thsoBmWg==} peerDependencies: @@ -4405,6 +4419,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/validator@13.15.10': + resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} + '@typescript-eslint/eslint-plugin@8.57.0': resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4447,6 +4464,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.65.0': + resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/rule-tester@8.57.0': resolution: {integrity: sha512-qs4OapXmAIj3so85/20lQG1WrBSSvDE/3b42Orl3lpZkaOlNXtbfKzL+9EPaY5wSEgdlhKEpympAMFHPG9i72Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4461,6 +4484,10 @@ packages: resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.65.0': + resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.57.0': resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4473,6 +4500,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/tsconfig-utils@8.65.0': + resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.57.0': resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4487,6 +4520,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.65.0': + resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/types@8.57.0': resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4499,6 +4539,10 @@ packages: resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.65.0': + resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.57.0': resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4511,6 +4555,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/typescript-estree@8.65.0': + resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.57.0': resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4525,6 +4575,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.65.0': + resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.57.0': resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4533,6 +4590,10 @@ packages: resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.65.0': + resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unocss/cli@66.6.6': resolution: {integrity: sha512-78SY8j4hAVelK+vP/adsDGaSjEITasYLFECJLHWxUJSzK+G9UIc5wtL/u4jA+zKvwVkHcDvbkcO5K6wwwpAixg==} engines: {node: '>=14'} @@ -5213,6 +5274,9 @@ packages: cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + class-validator@0.15.1: + resolution: {integrity: sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -5474,6 +5538,14 @@ packages: de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -5753,6 +5825,27 @@ packages: peerDependencies: eslint: '*' + eslint-module-utils@2.14.0: + resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + eslint-plugin-antfu@3.2.2: resolution: {integrity: sha512-Qzixht2Dmd/pMbb5EnKqw2V8TiWHbotPlsORO8a+IzCLFwE0RxK8a9k4DCTFPzBwyxJzH+0m2Mn8IUGeGQkyUw==} peerDependencies: @@ -6900,6 +6993,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.13.9: + resolution: {integrity: sha512-VNS5vWMM7r0P66BYv+TQJATxExEgLxN+34hfHDVhDkUsGAE4cRg0shCNSLTXNKm7nIUscC7AfB51TjxEeF7msQ==} + lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} @@ -8937,6 +9033,10 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true + validator@13.15.35: + resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -9466,7 +9566,7 @@ snapshots: transitivePeerDependencies: - chokidar - '@antfu/eslint-config@8.2.0(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3))(@typescript-eslint/utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5)': + '@antfu/eslint-config@8.2.0(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3))(@typescript-eslint/utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@vue/compiler-sfc@3.5.30)(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)(vitest@4.1.5)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 1.3.0 @@ -9474,9 +9574,9 @@ snapshots: '@eslint-community/eslint-plugin-eslint-comments': 4.7.1(eslint@10.5.0(jiti@2.6.1)) '@eslint/markdown': 8.0.1 '@stylistic/eslint-plugin': 5.10.0(eslint@10.5.0(jiti@2.6.1)) - '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) - '@vitest/eslint-plugin': 1.6.17(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5) + '@vitest/eslint-plugin': 1.6.17(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5) ansis: 4.2.0 cac: 7.0.0 eslint: 10.5.0(jiti@2.6.1) @@ -9484,26 +9584,26 @@ snapshots: eslint-flat-config-utils: 3.2.0 eslint-merge-processors: 2.0.0(eslint@10.5.0(jiti@2.6.1)) eslint-plugin-antfu: 3.2.2(eslint@10.5.0(jiti@2.6.1)) - eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3))(@typescript-eslint/utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)) + eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3))(@typescript-eslint/utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)) eslint-plugin-import-lite: 0.6.0(eslint@10.5.0(jiti@2.6.1)) - eslint-plugin-jsdoc: 62.9.0(eslint@10.5.0(jiti@2.6.1)) + eslint-plugin-jsdoc: 62.9.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) eslint-plugin-jsonc: 3.1.2(eslint@10.5.0(jiti@2.6.1)) eslint-plugin-n: 17.24.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-no-only-tests: 3.3.0 eslint-plugin-perfectionist: 5.9.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-pnpm: 1.6.0(eslint@10.5.0(jiti@2.6.1)) eslint-plugin-regexp: 3.1.0(eslint@10.5.0(jiti@2.6.1)) - eslint-plugin-toml: 1.3.1(eslint@10.5.0(jiti@2.6.1)) + eslint-plugin-toml: 1.3.1(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) eslint-plugin-unicorn: 64.0.0(eslint@10.5.0(jiti@2.6.1)) - eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)) + eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)) eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))) - eslint-plugin-yml: 3.3.1(eslint@10.5.0(jiti@2.6.1)) + eslint-plugin-yml: 3.3.1(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.30)(eslint@10.5.0(jiti@2.6.1)) globals: 17.6.0 local-pkg: 1.1.2 parse-gitignore: 2.0.0 toml-eslint-parser: 1.0.3 - vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) yaml-eslint-parser: 2.0.0 transitivePeerDependencies: - '@eslint/json' @@ -10422,6 +10522,25 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 + '@darraghor/eslint-plugin-nestjs-typed@7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/type-utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + class-validator: 0.15.1 + eslint: 10.5.0(jiti@2.6.1) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)) + glob: 13.0.6 + reflect-metadata: 0.2.2 + ts-api-utils: 2.5.0(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-node + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + '@e18e/eslint-plugin@0.3.0(eslint@10.5.0(jiti@2.6.1))': dependencies: eslint-plugin-depend: 1.5.0(eslint@10.5.0(jiti@2.6.1)) @@ -10546,6 +10665,11 @@ snapshots: eslint: 10.5.0(jiti@2.6.1) ignore: 7.0.5 + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.6.1)(supports-color@5.5.0))': + dependencies: + eslint: 10.5.0(jiti@2.6.1)(supports-color@5.5.0) + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.6.1))': dependencies: eslint: 10.5.0(jiti@2.6.1) @@ -10559,7 +10683,7 @@ snapshots: optionalDependencies: eslint: 10.5.0(jiti@2.6.1) - '@eslint/config-array@0.23.5': + '@eslint/config-array@0.23.5(supports-color@5.5.0)': dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3(supports-color@5.5.0) @@ -10579,7 +10703,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.5': + '@eslint/eslintrc@3.3.5(supports-color@5.5.0)': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@5.5.0) @@ -10675,11 +10799,11 @@ snapshots: dependencies: dequal: 2.0.3 - '@fastify/otel@0.18.1(@opentelemetry/api@1.9.1)': + '@fastify/otel@0.18.1(@opentelemetry/api@1.9.1)(supports-color@5.5.0)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1)(supports-color@5.5.0) '@opentelemetry/semantic-conventions': 1.41.1 minimatch: 10.2.5 transitivePeerDependencies: @@ -10720,10 +10844,10 @@ snapshots: rfdc: 1.4.1 yaml: 2.9.0 - '@fastify/swagger@9.7.0': + '@fastify/swagger@9.7.0(supports-color@5.5.0)': dependencies: fastify-plugin: 5.1.0 - json-schema-resolver: 3.0.0 + json-schema-resolver: 3.0.0(supports-color@5.5.0) openapi-types: 12.1.3 rfdc: 1.4.1 yaml: 2.9.0 @@ -11078,10 +11202,10 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true - '@nestjs/cache-manager@3.1.3(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)': + '@nestjs/cache-manager@3.1.3(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) cache-manager: 7.2.8 keyv: 5.6.0 rxjs: 7.8.2 @@ -11121,29 +11245,31 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0)': dependencies: - file-type: 21.3.0 + file-type: 21.3.0(supports-color@5.5.0) iterare: 1.2.1 load-esm: 1.0.3 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 + optionalDependencies: + class-validator: 0.15.1 transitivePeerDependencies: - supports-color - '@nestjs/config@4.0.3(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@nestjs/config@4.0.3(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) dotenv: 17.2.3 dotenv-expand: 12.0.3 lodash: 4.17.23 rxjs: 7.8.2 - '@nestjs/core@11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -11153,29 +11279,31 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16) - '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) eventemitter2: 6.4.9 - '@nestjs/jwt@11.0.2(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))': + '@nestjs/jwt@11.0.2(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) '@types/jsonwebtoken': 9.0.10 jsonwebtoken: 9.0.3 - '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(class-validator@0.15.1)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) reflect-metadata: 0.2.2 + optionalDependencies: + class-validator: 0.15.1 - '@nestjs/platform-express@11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/platform-express@11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.6 express: 5.2.1 multer: 2.1.1 @@ -11185,12 +11313,12 @@ snapshots: - supports-color optional: true - '@nestjs/platform-fastify@11.1.27(@fastify/static@9.1.3)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/platform-fastify@11.1.27(@fastify/static@9.1.3)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)': dependencies: '@fastify/cors': 11.2.0 '@fastify/formbody': 8.0.2 - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) fast-querystring: 1.1.2 fastify: 5.8.5 fastify-plugin: 6.0.0 @@ -11202,10 +11330,10 @@ snapshots: optionalDependencies: '@fastify/static': 9.1.3 - '@nestjs/schedule@6.1.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)': + '@nestjs/schedule@6.1.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': @@ -11219,12 +11347,12 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.4.1(@fastify/static@9.1.3)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(reflect-metadata@0.2.2)': + '@nestjs/swagger@11.4.1(@fastify/static@9.1.3)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(class-validator@0.15.1)(reflect-metadata@0.2.2)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(class-validator@0.15.1)(reflect-metadata@0.2.2) js-yaml: 4.1.1 lodash: 4.18.1 path-to-regexp: 8.4.2 @@ -11232,11 +11360,12 @@ snapshots: swagger-ui-dist: 5.32.4 optionalDependencies: '@fastify/static': 9.1.3 + class-validator: 0.15.1 - '@nestjs/terminus@11.1.1(@grpc/grpc-js@1.14.3)(@grpc/proto-loader@0.8.0)(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@prisma/client@6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3))(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/terminus@11.1.1(@grpc/grpc-js@1.14.3)(@grpc/proto-loader@0.8.0)(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(@prisma/client@6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3))(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) boxen: 5.1.2 check-disk-space: 3.4.0 reflect-metadata: 0.2.2 @@ -11246,13 +11375,13 @@ snapshots: '@grpc/proto-loader': 0.8.0 '@prisma/client': 6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3) - '@nestjs/testing@11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16)': + '@nestjs/testing@11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16)': dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) + '@nestjs/core': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/platform-express@11.1.16)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16) + '@nestjs/platform-express': 11.1.16(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(@nestjs/core@11.1.16) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -11866,7 +11995,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/api-logs': 0.212.0 import-in-the-middle: 2.0.6 - require-in-the-middle: 8.0.1 + require-in-the-middle: 8.0.1(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -11875,16 +12004,16 @@ snapshots: '@opentelemetry/api': 1.9.1 '@opentelemetry/api-logs': 0.213.0 import-in-the-middle: 3.0.0 - require-in-the-middle: 8.0.1 + require-in-the-middle: 8.0.1(supports-color@5.5.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)(supports-color@5.5.0)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/api-logs': 0.214.0 import-in-the-middle: 3.0.0 - require-in-the-middle: 8.0.1 + require-in-the-middle: 8.0.1(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -12431,7 +12560,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@tokenizer/inflate@0.4.1': + '@tokenizer/inflate@0.4.1(supports-color@5.5.0)': dependencies: debug: 4.4.3(supports-color@5.5.0) token-types: 6.1.2 @@ -12597,6 +12726,8 @@ snapshots: '@types/unist@3.0.3': {} + '@types/validator@13.15.10': {} + '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -12613,12 +12744,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.59.2 - '@typescript-eslint/type-utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) '@typescript-eslint/utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.59.2 eslint: 10.5.0(jiti@2.6.1) @@ -12671,6 +12802,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.65.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3) + '@typescript-eslint/types': 8.65.0 + debug: 4.4.3(supports-color@5.5.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/parser': 8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) @@ -12695,6 +12835,11 @@ snapshots: '@typescript-eslint/types': 8.59.2 '@typescript-eslint/visitor-keys': 8.59.2 + '@typescript-eslint/scope-manager@8.65.0': + dependencies: + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 + '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 @@ -12703,6 +12848,10 @@ snapshots: dependencies: typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils@8.65.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + '@typescript-eslint/type-utils@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.0 @@ -12715,7 +12864,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.59.2 '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) @@ -12727,12 +12876,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3(supports-color@5.5.0) + eslint: 10.5.0(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@8.57.0': {} '@typescript-eslint/types@8.59.2': {} '@typescript-eslint/types@8.61.1': {} + '@typescript-eslint/types@8.65.0': {} + '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) @@ -12763,6 +12926,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.65.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 + debug: 4.4.3(supports-color@5.5.0) + minimatch: 10.2.5 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.6.1)) @@ -12785,6 +12963,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) + eslint: 10.5.0(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.57.0': dependencies: '@typescript-eslint/types': 8.57.0 @@ -12795,6 +12984,11 @@ snapshots: '@typescript-eslint/types': 8.59.2 eslint-visitor-keys: 5.0.1 + '@typescript-eslint/visitor-keys@8.65.0': + dependencies: + '@typescript-eslint/types': 8.65.0 + eslint-visitor-keys: 5.0.1 + '@unocss/cli@66.6.6': dependencies: '@jridgewell/remapping': 2.3.5 @@ -12958,15 +13152,15 @@ snapshots: obug: 2.1.3 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1)(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) + vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1(supports-color@5.5.0))(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) - '@vitest/eslint-plugin@1.6.17(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5)': + '@vitest/eslint-plugin@1.6.17(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)(vitest@4.1.5)': dependencies: '@typescript-eslint/scope-manager': 8.59.2 '@typescript-eslint/utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) eslint: 10.5.0(jiti@2.6.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) typescript: 5.9.3 vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1)(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@8.0.11(@types/node@24.12.0)(esbuild@0.27.3)(jiti@2.6.1)(terser@5.48.0)(yaml@2.9.0)) transitivePeerDependencies: @@ -13072,14 +13266,14 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + '@vue/eslint-config-typescript@14.7.0(eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) eslint: 10.5.0(jiti@2.6.1) eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))) fast-glob: 3.3.3 typescript-eslint: 8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) - vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -13646,6 +13840,12 @@ snapshots: cjs-module-lexer@2.2.0: {} + class-validator@0.15.1: + dependencies: + '@types/validator': 13.15.10 + libphonenumber-js: 1.13.9 + validator: 13.15.35 + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -13882,6 +14082,10 @@ snapshots: de-indent@1.0.2: {} + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 @@ -14204,16 +14408,25 @@ snapshots: dependencies: eslint: 10.5.0(jiti@2.6.1) + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + eslint: 10.5.0(jiti@2.6.1) + transitivePeerDependencies: + - supports-color + eslint-plugin-antfu@3.2.2(eslint@10.5.0(jiti@2.6.1)): dependencies: eslint: 10.5.0(jiti@2.6.1) - eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3))(@typescript-eslint/utils@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)): + eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3))(@typescript-eslint/utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)): dependencies: '@es-joy/jsdoccomment': 0.84.0 '@typescript-eslint/rule-tester': 8.57.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) eslint: 10.5.0(jiti@2.6.1) eslint-plugin-depend@1.5.0(eslint@10.5.0(jiti@2.6.1)): @@ -14234,7 +14447,7 @@ snapshots: dependencies: eslint: 10.5.0(jiti@2.6.1) - eslint-plugin-jsdoc@62.9.0(eslint@10.5.0(jiti@2.6.1)): + eslint-plugin-jsdoc@62.9.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0): dependencies: '@es-joy/jsdoccomment': 0.86.0 '@es-joy/resolve.exports': 1.2.0 @@ -14317,7 +14530,7 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-toml@1.3.1(eslint@10.5.0(jiti@2.6.1)): + eslint-plugin-toml@1.3.1(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0): dependencies: '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.6.1 @@ -14348,11 +14561,11 @@ snapshots: semver: 7.8.5 strip-indent: 4.1.1 - eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)): + eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1)): dependencies: eslint: 10.5.0(jiti@2.6.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1)))(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.5.0(jiti@2.6.1))(vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))): dependencies: @@ -14362,13 +14575,13 @@ snapshots: nth-check: 2.1.1 postcss-selector-parser: 7.1.1 semver: 7.8.5 - vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1)) + vue-eslint-parser: 10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0) xml-name-validator: 4.0.0 optionalDependencies: '@stylistic/eslint-plugin': 5.10.0(eslint@10.5.0(jiti@2.6.1)) '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) - eslint-plugin-yml@3.3.1(eslint@10.5.0(jiti@2.6.1)): + eslint-plugin-yml@3.3.1(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0): dependencies: '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.6.1 @@ -14409,7 +14622,44 @@ snapshots: dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.5 + '@eslint/config-array': 0.23.5(supports-color@5.5.0) + '@eslint/config-helpers': 0.6.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.2 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@5.5.0) + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + eslint@10.5.0(jiti@2.6.1)(supports-color@5.5.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.6.1)(supports-color@5.5.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5(supports-color@5.5.0) '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.2 @@ -14664,9 +14914,9 @@ snapshots: dependencies: flat-cache: 4.0.1 - file-type@21.3.0: + file-type@21.3.0(supports-color@5.5.0): dependencies: - '@tokenizer/inflate': 0.4.1 + '@tokenizer/inflate': 0.4.1(supports-color@5.5.0) strtok3: 10.3.4 token-types: 6.1.2 uint8array-extras: 1.5.0 @@ -14820,7 +15070,7 @@ snapshots: gaxios@7.1.4: dependencies: extend: 3.0.2 - https-proxy-agent: 7.0.6 + https-proxy-agent: 7.0.6(supports-color@5.5.0) node-fetch: 3.3.2 transitivePeerDependencies: - supports-color @@ -15072,7 +15322,7 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 - http-proxy-agent@7.0.2: + http-proxy-agent@7.0.2(supports-color@5.5.0): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@5.5.0) @@ -15081,7 +15331,7 @@ snapshots: http2-client@1.3.5: {} - https-proxy-agent@7.0.6: + https-proxy-agent@7.0.6(supports-color@5.5.0): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@5.5.0) @@ -15386,15 +15636,15 @@ snapshots: jsdoc-type-pratt-parser@7.2.0: {} - jsdom@25.0.1: + jsdom@25.0.1(supports-color@5.5.0): dependencies: cssstyle: 4.6.0 data-urls: 5.0.0 decimal.js: 10.6.0 form-data: 4.0.6 html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + http-proxy-agent: 7.0.2(supports-color@5.5.0) + https-proxy-agent: 7.0.6(supports-color@5.5.0) is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.24 parse5: 7.3.0 @@ -15433,7 +15683,7 @@ snapshots: dependencies: dequal: 2.0.3 - json-schema-resolver@3.0.0: + json-schema-resolver@3.0.0(supports-color@5.5.0): dependencies: debug: 4.4.3(supports-color@5.5.0) fast-uri: 3.1.2 @@ -15528,6 +15778,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.13.9: {} + lie@3.3.0: dependencies: immediate: 3.0.6 @@ -16214,9 +16466,9 @@ snapshots: neo-async@2.6.2: {} - nestjs-pino@4.6.0(@nestjs/common@11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.3.1)(rxjs@7.8.2): + nestjs-pino@4.6.0(@nestjs/common@11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0))(pino-http@11.0.0)(pino@10.3.1)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.16(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.16(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@5.5.0) pino: 10.3.1 pino-http: 11.0.0 rxjs: 7.8.2 @@ -16871,7 +17123,7 @@ snapshots: require-from-string@2.0.2: {} - require-in-the-middle@8.0.1: + require-in-the-middle@8.0.1(supports-color@5.5.0): dependencies: debug: 4.4.3(supports-color@5.5.0) module-details-from-path: 1.0.4 @@ -17390,29 +17642,29 @@ snapshots: dependencies: '@tokenizer/token': 0.3.0 - stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-html@1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.0(supports-color@5.5.0)(typescript@5.9.3) - stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-recommended-vue@1.6.1(postcss-html@1.8.1)(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)): dependencies: postcss-html: 1.8.1 semver: 7.8.5 - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(typescript@5.9.3)) - stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.0(supports-color@5.5.0)(typescript@5.9.3) + stylelint-config-html: 1.1.0(postcss-html@1.8.1)(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) + stylelint-config-recommended: 18.0.0(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) - stylelint-config-recommended@18.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-recommended@18.0.0(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) + stylelint: 17.11.0(supports-color@5.5.0)(typescript@5.9.3) - stylelint-config-standard@40.0.0(stylelint@17.11.0(typescript@5.9.3)): + stylelint-config-standard@40.0.0(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)): dependencies: - stylelint: 17.11.0(typescript@5.9.3) - stylelint-config-recommended: 18.0.0(stylelint@17.11.0(typescript@5.9.3)) + stylelint: 17.11.0(supports-color@5.5.0)(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3)) - stylelint@17.11.0(typescript@5.9.3): + stylelint@17.11.0(supports-color@5.5.0)(typescript@5.9.3): dependencies: '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) @@ -17918,7 +18170,7 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.4 - unplugin-vue-components@0.27.5(@babel/parser@7.29.7)(rollup@2.80.0)(vue@3.5.30(typescript@5.9.3)): + unplugin-vue-components@0.27.5(@babel/parser@7.29.7)(rollup@2.80.0)(supports-color@5.5.0)(vue@3.5.30(typescript@5.9.3)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.4.0(rollup@2.80.0) @@ -17971,6 +18223,8 @@ snapshots: uuid@9.0.1: {} + validator@13.15.35: {} + vary@1.1.2: optional: true @@ -17995,7 +18249,7 @@ snapshots: - tsx - yaml - vite-plugin-pwa@1.2.0(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): + vite-plugin-pwa@1.2.0(supports-color@5.5.0)(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0): dependencies: debug: 4.4.3(supports-color@5.5.0) pretty-bytes: 6.1.1 @@ -18043,6 +18297,36 @@ snapshots: typescript: 5.9.3 vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1)(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) + vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1(supports-color@5.5.0))(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.5 + '@vitest/mocker': 4.1.5(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.5 + '@vitest/runner': 4.1.5 + '@vitest/snapshot': 4.1.5 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@types/node': 24.12.0 + '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) + jsdom: 25.0.1(supports-color@5.5.0) + transitivePeerDependencies: + - msw + vitest@4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(@vitest/coverage-v8@4.1.5)(jsdom@25.0.1)(msw@2.12.10(@types/node@24.12.0)(typescript@5.9.3))(vite@7.3.3(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.5 @@ -18069,7 +18353,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@types/node': 24.12.0 '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) - jsdom: 25.0.1 + jsdom: 25.0.1(supports-color@5.5.0) transitivePeerDependencies: - msw @@ -18099,7 +18383,7 @@ snapshots: '@opentelemetry/api': 1.9.1 '@types/node': 24.12.0 '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) - jsdom: 25.0.1 + jsdom: 25.0.1(supports-color@5.5.0) transitivePeerDependencies: - msw @@ -18109,7 +18393,7 @@ snapshots: dependencies: vue: 3.5.30(typescript@5.9.3) - vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1)): + vue-eslint-parser@10.4.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0): dependencies: debug: 4.4.3(supports-color@5.5.0) eslint: 10.5.0(jiti@2.6.1) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 326f9575e1..15d16d7d52 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -150,6 +150,7 @@ catalogs: chalk: ^5.6.2 eslint: ^10.5.0 eslint-plugin-vue: ^10.8.0 + '@darraghor/eslint-plugin-nestjs-typed': ^7.2.9 husky: ^9.1.7 js-yaml: ^4.1.0 lint-staged: ^16.4.0 From 83409538a8f8a6d72db53254db68e253c708cfb6 Mon Sep 17 00:00:00 2001 From: William Phetsinorath Date: Wed, 29 Jul 2026 17:04:22 +0200 Subject: [PATCH 2/2] chore: stricter typescript Signed-off-by: William Phetsinorath Change-Id: Iad8890849080d90dad5c64f320afa7466a6a6964 --- apps/client/src/components/ClusterForm.vue | 4 +- .../src/components/ProjectClustersInfos.vue | 2 +- .../src/components/ProjectSecretsButton.vue | 2 +- apps/client/src/components/ServicesConfig.vue | 4 +- apps/client/src/components/TeamCt.vue | 2 +- apps/client/src/stores/admin-role.ts | 10 +-- apps/client/src/stores/admin-token.ts | 6 +- apps/client/src/stores/cluster.ts | 14 ++--- apps/client/src/stores/log.ts | 4 +- apps/client/src/stores/plugins.ts | 4 +- apps/client/src/stores/project.ts | 17 ++--- apps/client/src/stores/service-chain.ts | 6 +- apps/client/src/stores/services-monitor.ts | 4 +- apps/client/src/stores/stage.ts | 10 +-- apps/client/src/stores/system-settings.ts | 4 +- apps/client/src/stores/token.ts | 6 +- apps/client/src/stores/user.ts | 2 +- apps/client/src/stores/users.ts | 6 +- apps/client/src/stores/zone.ts | 8 +-- apps/client/src/utils/func.ts | 5 +- apps/client/src/utils/project-utils.ts | 62 +++++++++---------- apps/client/src/views/ProjectDashboard.vue | 7 ++- apps/client/src/views/admin/ListClusters.vue | 2 +- apps/client/src/views/admin/ListPlugins.vue | 2 +- apps/client/src/views/admin/ListProjects.vue | 2 +- apps/client/src/views/admin/ListUser.vue | 4 +- apps/client/tsconfig.json | 26 ++------ .../modules/gitlab/gitlab-client.service.ts | 17 ++--- .../configuration/configuration.service.ts | 14 ++--- .../database/database.service.ts | 8 +-- .../project-services.utils.ts | 10 +-- .../src/modules/project/project.utils.ts | 10 +-- .../src/modules/registry/registry.service.ts | 14 ++--- apps/server-nestjs/tsconfig.eslint.json | 19 ++++++ apps/server-nestjs/tsconfig.json | 26 +++----- apps/server/src/connect.ts | 3 +- apps/server/src/init/db/index.ts | 4 +- apps/server/src/init/db/utils.ts | 6 +- apps/server/src/prepare-app.ts | 16 +++-- .../src/resources/admin-role/business.ts | 3 +- .../src/resources/admin-role/queries.ts | 8 +-- apps/server/src/resources/cluster/queries.ts | 34 +++++----- .../src/resources/environment/business.ts | 2 +- .../src/resources/environment/queries.ts | 14 ++--- apps/server/src/resources/log/queries.ts | 8 +-- .../src/resources/project-member/queries.ts | 6 +- .../src/resources/project-role/business.ts | 3 +- .../src/resources/project-role/queries.ts | 10 +-- .../src/resources/project-service/business.ts | 4 +- .../src/resources/project-service/queries.ts | 2 +- apps/server/src/resources/project/business.ts | 19 +++--- apps/server/src/resources/project/queries.ts | 38 ++++++------ .../src/resources/repository/queries.ts | 14 ++--- .../src/resources/service-chain/queries.ts | 4 +- apps/server/src/resources/stage/queries.ts | 20 +++--- .../src/resources/system/settings/business.ts | 4 +- .../src/resources/system/settings/queries.ts | 4 +- apps/server/src/resources/user/queries.ts | 12 ++-- apps/server/src/resources/zone/queries.ts | 4 +- apps/server/src/server.spec.ts | 2 +- apps/server/src/telemetry.ts | 2 +- apps/server/src/utils/business.ts | 6 +- apps/server/src/utils/controller.ts | 2 +- apps/server/src/utils/hook-wrapper.spec.ts | 6 +- apps/server/src/utils/hook-wrapper.ts | 20 +++--- apps/server/src/utils/proxy.spec.ts | 4 +- apps/server/src/utils/proxy.ts | 23 ++++--- apps/server/tsconfig.eslint.json | 19 ++++++ apps/server/tsconfig.json | 1 - packages/eslintconfig/src/index.js | 10 ++- packages/hooks/src/config.ts | 2 +- packages/hooks/src/hooks/hook.ts | 26 +++++--- packages/hooks/src/index.ts | 2 +- packages/hooks/src/services.ts | 12 ++-- .../hooks/src/utils/plugin-result-handler.ts | 4 +- packages/hooks/src/utils/utils.ts | 12 ++-- packages/logger/src/index.ts | 1 + packages/logger/tsconfig.eslint.json | 3 + packages/shared/src/schemas/repository.ts | 12 ++-- packages/shared/src/utils/functions.ts | 20 +++--- packages/shared/src/utils/permissions.ts | 15 ++--- packages/shared/src/utils/plugins.ts | 6 +- packages/shared/src/utils/roles.ts | 2 +- packages/shared/src/utils/schemas.ts | 16 ++--- packages/shared/tsconfig.eslint.json | 5 +- packages/shared/tsconfig.vitest.json | 7 +++ .../test-utils/src/utils/random-project.ts | 6 +- packages/tsconfig/package.json | 4 ++ packages/tsconfig/tsconfig.base.json | 43 +++++-------- playwright/tsconfig.json | 28 +-------- plugins/keycloak/src/functions.ts | 12 ++-- pnpm-lock.yaml | 40 +++++++++--- pnpm-workspace.yaml | 3 + tsconfig.json | 5 ++ 94 files changed, 510 insertions(+), 456 deletions(-) create mode 100644 apps/server-nestjs/tsconfig.eslint.json create mode 100644 apps/server/tsconfig.eslint.json create mode 100644 packages/shared/tsconfig.vitest.json create mode 100644 tsconfig.json diff --git a/apps/client/src/components/ClusterForm.vue b/apps/client/src/components/ClusterForm.vue index 81f51ebcaf..dac6e0b88f 100644 --- a/apps/client/src/components/ClusterForm.vue +++ b/apps/client/src/components/ClusterForm.vue @@ -73,7 +73,7 @@ const clusterToDelete = ref('') const isDeletingCluster = ref(false) if (!localCluster.value.zoneId && props.allZones.length) { - localCluster.value.zoneId = props.allZones[0].id + localCluster.value.zoneId = props.allZones[0]!.id } const schema = computed(() => { @@ -113,7 +113,7 @@ function updateKubeconfig(files: FileList) { snackbarStore.setMessage('Pas de current-context. Choisissez un contexte.') } } - reader.readAsText(files[0]) + reader.readAsText(files[0]!) } catch (error) { // @ts-ignore kConfigError.value = error?.message diff --git a/apps/client/src/components/ProjectClustersInfos.vue b/apps/client/src/components/ProjectClustersInfos.vue index d7af0874ed..ce7277a681 100644 --- a/apps/client/src/components/ProjectClustersInfos.vue +++ b/apps/client/src/components/ProjectClustersInfos.vue @@ -34,7 +34,7 @@ onMounted(async () => {
- : {{ zoneStore.zonesById[cluster.zoneId].label }} + : {{ zoneStore.zonesById[cluster.zoneId]?.label }}
{ if (!curr.section) curr.section = 'default' if (curr.section in acc.items) { - acc.items[curr.section].push(curr as PluginConfigItem) + acc.items[curr.section]!.push(curr as PluginConfigItem) } else { acc.items[curr.section] = [curr as PluginConfigItem] acc.sectionNumber++ @@ -55,7 +55,7 @@ const updated = ref({}) function update(data: { value: string, key: string, plugin: string }) { if (!updated.value[data.plugin]) updated.value[data.plugin] = {} - updated.value[data.plugin][data.key] = data.value + updated.value[data.plugin]![data.key] = data.value } function getItemsToShowLength(items: PluginConfigItem[] | (PluginConfigItem & { value: any })[] | undefined, scope: PermissionTarget): number | undefined { diff --git a/apps/client/src/components/TeamCt.vue b/apps/client/src/components/TeamCt.vue index d850569e77..381036f2be 100644 --- a/apps/client/src/components/TeamCt.vue +++ b/apps/client/src/components/TeamCt.vue @@ -62,7 +62,7 @@ const retrieveUsersToAdd = pDebounce(async (letters: LettersQuery['letters']) => if (letters.length < 3) return // Ne pas relancer de requête à chaque lettre ajoutée si aucun user ne correspond aux premières lettres données if (lettersNotMatching.value && letters.includes(lettersNotMatching.value) && !usersToAdd.value?.length) return - usersToAdd.value = await projectStore.projectsBySlug[props.project.slug].Members.getCandidateUsers(letters) + usersToAdd.value = await projectStore.projectsBySlug[props.project.slug]?.Members.getCandidateUsers(letters) // Stockage des lettres qui ne renvoient aucun résultat if (!usersToAdd.value?.length) { lettersNotMatching.value = letters diff --git a/apps/client/src/stores/admin-role.ts b/apps/client/src/stores/admin-role.ts index fa70004e0f..7bfb6e75be 100644 --- a/apps/client/src/stores/admin-role.ts +++ b/apps/client/src/stores/admin-role.ts @@ -12,14 +12,14 @@ export const useAdminRoleStore = defineStore('adminRole', () => { const countMembersRoles = async () => { memberCounts.value - = await apiClient.AdminRoles.adminRoleMemberCounts().then((res: any) => + = await apiClient.AdminRoles.adminRoleMemberCounts().then((res) => extractData(res, 200), ) return memberCounts.value } const listRoles = async () => { - roles.value = await apiClient.AdminRoles.listAdminRoles().then((response: any) => + roles.value = await apiClient.AdminRoles.listAdminRoles().then((response) => extractData(response, 200), ) if (AdminAuthorized.ListRoles(userStore.adminPerms)) { @@ -31,12 +31,12 @@ export const useAdminRoleStore = defineStore('adminRole', () => { const createRole = async () => { roles.value = await apiClient.AdminRoles.createAdminRole({ body: { name: 'Nouveau rôle' }, - }).then((res: any) => extractData(res, 201)) + }).then((res) => extractData(res, 201)) } const deleteRole = async (roleId: AdminRole['id']) => { await apiClient.AdminRoles.deleteAdminRole({ params: { roleId } }).then( - (res: any) => extractData(res, 204), + (res) => extractData(res, 204), ) await listRoles() } @@ -46,7 +46,7 @@ export const useAdminRoleStore = defineStore('adminRole', () => { ) => { roles.value = await apiClient.AdminRoles.patchAdminRoles({ body, - }).then((res: any) => extractData(res, 200)) + }).then((res) => extractData(res, 200)) } return { diff --git a/apps/client/src/stores/admin-token.ts b/apps/client/src/stores/admin-token.ts index 3b76dc2fe8..a6b4d15f07 100644 --- a/apps/client/src/stores/admin-token.ts +++ b/apps/client/src/stores/admin-token.ts @@ -7,21 +7,21 @@ export const useAdminTokenStore = defineStore('adminToken', () => { query: typeof adminTokenContract.listAdminTokens.query._type = {}, ) => { return apiClient.AdminTokens.listAdminTokens({ query }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) } const createToken = async ( body: typeof adminTokenContract.createAdminToken.body._type, ) => { - return apiClient.AdminTokens.createAdminToken({ body }).then((res: any) => + return apiClient.AdminTokens.createAdminToken({ body }).then((res) => extractData(res, 201), ) } const deleteToken = async (tokenId: AdminToken['id']) => { await apiClient.AdminTokens.deleteAdminToken({ params: { tokenId } }).then( - (res: any) => extractData(res, 204), + (res) => extractData(res, 204), ) } diff --git a/apps/client/src/stores/cluster.ts b/apps/client/src/stores/cluster.ts index 3f94777f2b..3bd9e26b68 100644 --- a/apps/client/src/stores/cluster.ts +++ b/apps/client/src/stores/cluster.ts @@ -13,28 +13,28 @@ export const useClusterStore = defineStore('cluster', () => { const getClusters = async () => { clusters.value = await apiClient.Clusters.listClusters().then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) return clusters.value } const getClusterDetails = async (clusterId: Cluster['id']) => apiClient.Clusters.getClusterDetails({ params: { clusterId } }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) const getClusterUsage = async (clusterId: Cluster['id']) => apiClient.Clusters.getClusterUsage({ params: { clusterId } }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) const getClusterAssociatedEnvironments = (clusterId: Cluster['id']) => apiClient.Clusters.getClusterEnvironments({ params: { clusterId } }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) const addCluster = (cluster: CreateClusterBody) => - apiClient.Clusters.createCluster({ body: cluster }).then((response: any) => + apiClient.Clusters.createCluster({ body: cluster }).then((response) => extractData(response, 201), ) @@ -43,12 +43,12 @@ export const useClusterStore = defineStore('cluster', () => { ...body }: UpdateClusterBody & { id: Cluster['id'] }) => apiClient.Clusters.updateCluster({ body, params: { clusterId: id } }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) const deleteCluster = (clusterId: Cluster['id']) => apiClient.Clusters.deleteCluster({ params: { clusterId } }).then( - (response: any) => extractData(response, 204), + (response) => extractData(response, 204), ) return { diff --git a/apps/client/src/stores/log.ts b/apps/client/src/stores/log.ts index 3b1266cc48..ef8dee8453 100644 --- a/apps/client/src/stores/log.ts +++ b/apps/client/src/stores/log.ts @@ -10,14 +10,14 @@ export const useLogStore = defineStore('log', () => { const getAllLogs = async ({ offset, limit }: GetLogsQuery = { offset: 0, limit: 100 }) => { const res = await apiClient.Logs.getLogs({ query: { offset, limit, clean: false } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) count.value = res.total logs.value = res.logs as Log[] } const listLogs = async ({ offset, limit, clean, projectId }: GetLogsQuery = { offset: 0, limit: 10 }) => { return apiClient.Logs.getLogs({ query: { offset, limit, clean, projectId } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) } return { diff --git a/apps/client/src/stores/plugins.ts b/apps/client/src/stores/plugins.ts index 99dd9f7abd..f70ed31eaa 100644 --- a/apps/client/src/stores/plugins.ts +++ b/apps/client/src/stores/plugins.ts @@ -6,10 +6,10 @@ export const usePluginsConfigStore = defineStore('plugins', () => { const services: ProjectService[] = [] const getPluginsConfig = () => apiClient.SystemPlugin.getPluginsConfig() - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) const updatePluginsConfig = (body: PluginsUpdateBody) => apiClient.SystemPlugin.updatePluginsConfig({ body }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return { services, diff --git a/apps/client/src/stores/project.ts b/apps/client/src/stores/project.ts index 44e59d56a8..57cf003766 100644 --- a/apps/client/src/stores/project.ts +++ b/apps/client/src/stores/project.ts @@ -38,7 +38,7 @@ export const useProjectStore = defineStore('project', () => { const updateStore = async (projectsRecieved: ProjectV2[]) => { return projectsRecieved.map((project) => { if (project.slug in projectsBySlug.value) { - return projectsBySlug.value[project.slug].Commands.updateData(project) + return projectsBySlug.value[project.slug]!.Commands.updateData(project) } const newProject = new Project(project) projectsBySlug.value[project.slug] = newProject @@ -49,13 +49,13 @@ export const useProjectStore = defineStore('project', () => { const selectFromStore = (slugs: ProjectV2['slug'][]) => { return slugs .filter(slug => slug in projectsBySlug.value) - .map(slug => projectsBySlug.value[slug]) + .map(slug => projectsBySlug.value[slug]!) } const getProject = async (projectId: ProjectV2['id']) => { const res = await apiClient.Projects.getProject({ params: { projectId }, - }).then((response: any) => extractData(response, 200)) + }).then((response) => extractData(response, 200)) return (await updateStore([res]))[0] } @@ -66,16 +66,17 @@ export const useProjectStore = defineStore('project', () => { }, ) => { const res = await apiClient.Projects.listProjects({ query }).then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) await updateStore(res) - return selectFromStore(res.map((project: any) => project.slug)) + const slugs = res.map((project) => project.slug as ProjectV2['slug']) + return selectFromStore(slugs) } const listMyProjects = pDebounce(async () => { const res = await apiClient.Projects.listProjects({ query: { filter: 'member', statusNotIn: 'archived' }, - }).then((response: any) => extractData(response, 200)) + }).then((response) => extractData(response, 200)) for (const storedProject of myProjects.value) { if ( !res.some((responseProject: any) => responseProject.id === storedProject.id) @@ -89,14 +90,14 @@ export const useProjectStore = defineStore('project', () => { const createProject = async (body: CreateProjectBody) => { const project = await apiClient.Projects.createProject({ body }).then( - (response: any) => extractData(response, 201), + (response) => extractData(response, 201), ) projectsBySlug.value[project.slug] = new Project(project) return project } const generateProjectsData = () => - apiClient.Projects.getProjectsData().then((response: any) => + apiClient.Projects.getProjectsData().then((response) => extractData(response, 200), ) diff --git a/apps/client/src/stores/service-chain.ts b/apps/client/src/stores/service-chain.ts index 802a594e0d..3932be22ec 100644 --- a/apps/client/src/stores/service-chain.ts +++ b/apps/client/src/stores/service-chain.ts @@ -17,7 +17,7 @@ export const useServiceChainStore = defineStore('serviceChain', () => { const getServiceChainsList = async () => { serviceChains.value - = await apiClient.ServiceChains.listServiceChains().then((response: any) => + = await apiClient.ServiceChains.listServiceChains().then((response) => extractData(response, 200), ) return serviceChains.value @@ -26,14 +26,14 @@ export const useServiceChainStore = defineStore('serviceChain', () => { const getServiceChainDetails = async (serviceChainId: ServiceChain['id']) => apiClient.ServiceChains.getServiceChainDetails({ params: { serviceChainId }, - }).then((response: any) => + }).then((response) => ServiceChainDetailsSchema.parse(extractData(response, 200)), ) const getServiceChainFlows = async (serviceChainId: ServiceChain['id']) => apiClient.ServiceChains.getServiceChainFlows({ params: { serviceChainId }, - }).then((response: any) => + }).then((response) => ServiceChainFlowsSchema.parse(extractData(response, 200)), ) diff --git a/apps/client/src/stores/services-monitor.ts b/apps/client/src/stores/services-monitor.ts index d810ef328b..2534b47e8d 100644 --- a/apps/client/src/stores/services-monitor.ts +++ b/apps/client/src/stores/services-monitor.ts @@ -87,7 +87,7 @@ export const useServiceStore = defineStore('serviceMonitor', () => { services.value = await (displayCause.value ? apiClient.Services.getCompleteServiceHealth() : apiClient.Services.getServiceHealth()) - .then((res: any) => extractData(res, 200)) + .then((res) => extractData(res, 200)) callStastus.value = 'ok' } catch { callStastus.value = 'error' @@ -96,7 +96,7 @@ export const useServiceStore = defineStore('serviceMonitor', () => { const refreshServicesHealth = async () => { await apiClient.Services.refreshServiceHealth() - .then((res: any) => extractData(res, 200)) + .then((res) => extractData(res, 200)) return checkServicesHealth() } diff --git a/apps/client/src/stores/stage.ts b/apps/client/src/stores/stage.ts index de6d3824bf..37583cf723 100644 --- a/apps/client/src/stores/stage.ts +++ b/apps/client/src/stores/stage.ts @@ -13,25 +13,25 @@ export const useStageStore = defineStore('stage', () => { const getAllStages = async () => { stages.value = await apiClient.Stages.listStages() - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return stages.value } const getStageAssociatedEnvironments = (stageId: string) => apiClient.Stages.getStageEnvironments({ params: { stageId } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) const addStage = (body: CreateStageBody) => apiClient.Stages.createStage({ body }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) const updateStage = (stageId: string, body: UpdateStageBody) => apiClient.Stages.updateStage({ params: { stageId }, body }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) const deleteStage = (stageId: string) => apiClient.Stages.deleteStage({ params: { stageId } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return { stages, diff --git a/apps/client/src/stores/system-settings.ts b/apps/client/src/stores/system-settings.ts index 8eebac262e..5dd422bf0a 100644 --- a/apps/client/src/stores/system-settings.ts +++ b/apps/client/src/stores/system-settings.ts @@ -15,12 +15,12 @@ export const useSystemSettingsStore = defineStore('systemSettings', () => { const listSystemSettings = async (query: typeof systemSettingsContract.listSystemSettings.query._type = {}) => { systemSettings.value = await apiClient.SystemSettings.listSystemSettings(query) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) } const upsertSystemSetting = async (newSystemSetting: UpsertSystemSettingBody) => { const res = await apiClient.SystemSettings.upsertSystemSetting({ body: newSystemSetting }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) systemSettings.value = systemSettings.value .toSpliced(systemSettings.value .findIndex(systemSetting => systemSetting.key === res.key), 1, res) diff --git a/apps/client/src/stores/token.ts b/apps/client/src/stores/token.ts index d19b832333..20d1f63209 100644 --- a/apps/client/src/stores/token.ts +++ b/apps/client/src/stores/token.ts @@ -8,7 +8,7 @@ import { apiClient, extractData } from '../api/xhr-client.js' export const useTokenStore = defineStore('token', () => { const listPersonalAccessTokens = async () => { return apiClient.PersonalAccessTokens.listPersonalAccessTokens().then( - (response: any) => extractData(response, 200), + (response) => extractData(response, 200), ) } @@ -17,7 +17,7 @@ export const useTokenStore = defineStore('token', () => { ) => { return apiClient.PersonalAccessTokens.createPersonalAccessToken({ body, - }).then((res: any) => extractData(res, 201)) + }).then((res) => extractData(res, 201)) } const deletePersonalAccessToken = async ( @@ -25,7 +25,7 @@ export const useTokenStore = defineStore('token', () => { ) => { await apiClient.PersonalAccessTokens.deletePersonalAccessToken({ params: { tokenId }, - }).then((res: any) => extractData(res, 204)) + }).then((res) => extractData(res, 204)) } return { diff --git a/apps/client/src/stores/user.ts b/apps/client/src/stores/user.ts index f860e6d037..baed6e8b81 100644 --- a/apps/client/src/stores/user.ts +++ b/apps/client/src/stores/user.ts @@ -27,7 +27,7 @@ export const useUserStore = defineStore('user', () => { userProfile.value = getUserProfile() await systemSettingsStore.listSystemSettings().catch(() => undefined) await apiClient.Users.auth() - .then((res: any) => apiAuthInfos.value = extractData(res, 200)) + .then((res) => apiAuthInfos.value = extractData(res, 200)) } const setIsLoggedIn = async () => { diff --git a/apps/client/src/stores/users.ts b/apps/client/src/stores/users.ts index 4bacc644da..bef344176d 100644 --- a/apps/client/src/stores/users.ts +++ b/apps/client/src/stores/users.ts @@ -5,15 +5,15 @@ import { apiClient, extractData } from '@/api/xhr-client.js' export const useUsersStore = defineStore('users', () => { const listUsers = async (query: typeof userContract.getAllUsers.query._input) => apiClient.Users.getAllUsers({ query }) - .then((res: any) => extractData(res, 200)) + .then((res) => extractData(res, 200)) const listMatchingUsers = async (query: typeof userContract.getMatchingUsers.query._type) => apiClient.Users.getMatchingUsers({ query }) - .then((res: any) => extractData(res, 200)) + .then((res) => extractData(res, 200)) const patchUsers = async (body: typeof userContract.patchUsers.body._type) => apiClient.Users.patchUsers({ body }) - .then((res: any) => extractData(res, 200)) + .then((res) => extractData(res, 200)) return { listUsers, diff --git a/apps/client/src/stores/zone.ts b/apps/client/src/stores/zone.ts index 0c81a3e0f1..3052b5590c 100644 --- a/apps/client/src/stores/zone.ts +++ b/apps/client/src/stores/zone.ts @@ -13,21 +13,21 @@ export const useZoneStore = defineStore('zone', () => { const getAllZones = async () => { zones.value = await apiClient.Zones.listZones() - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return zones.value } const createZone = (body: CreateZoneBody) => apiClient.Zones.createZone({ body }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) const updateZone = (zoneId: Zone['id'], data: UpdateZoneBody) => apiClient.Zones.updateZone({ body: data, params: { zoneId } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) const deleteZone = (zoneId: Zone['id']) => apiClient.Zones.deleteZone({ params: { zoneId } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return { zones, diff --git a/apps/client/src/utils/func.ts b/apps/client/src/utils/func.ts index 159a7c8dcf..93fda83ea2 100644 --- a/apps/client/src/utils/func.ts +++ b/apps/client/src/utils/func.ts @@ -82,7 +82,7 @@ export function toKebabCase(value: string) { */ export function localeParseFloat(s: string): number { // Remove thousand separators, and put a point where the decimal separator occurs - const delocalizedInput = s.replaceAll(THOUSANDS_SEPARATOR, '').replaceAll(DECIMAL_SEPARATOR, '.') + const delocalizedInput = s.replaceAll(THOUSANDS_SEPARATOR ?? '', '').replaceAll(DECIMAL_SEPARATOR ?? '.', '.') // Now it can be parsed return Number.parseFloat(delocalizedInput) } @@ -101,7 +101,8 @@ export function swapItems(items: T[], index: number, direction: -1 | 1): T[] const reordered = [...items] const moved = reordered[index] - reordered[index] = reordered[target] + if (!moved) return items + reordered[index] = reordered[target]! reordered[target] = moved return reordered } diff --git a/apps/client/src/utils/project-utils.ts b/apps/client/src/utils/project-utils.ts index e45746f660..c9c412bae6 100644 --- a/apps/client/src/utils/project-utils.ts +++ b/apps/client/src/utils/project-utils.ts @@ -150,7 +150,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('update') try { const project = await apiClient.Projects.updateProject({ body: data, params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) .finally(() => callback()) return this.Commands.updateData(project) } finally { @@ -167,7 +167,7 @@ export class Project implements ProjectV2 { }, refresh: async () => { const project = await apiClient.Projects.getProject({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) this.Commands.updateData(project) await Promise.all([ this.Repositories.list(), @@ -179,7 +179,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('update') try { await apiClient.Projects.replayHooksForProject({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return this.Commands.refresh() } finally { callback() @@ -189,7 +189,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('delete') try { await apiClient.Projects.archiveProject({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) this.status = 'archived' } catch { await this.Commands.refresh() @@ -202,14 +202,14 @@ export class Project implements ProjectV2 { Members = { list: async () => { this.members = await apiClient.ProjectsMembers.listMembers({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.members }, create: async (email: string) => { const callback = this.addOperation('teamManagement') try { await apiClient.ProjectsMembers.addMember({ params: { projectId: this.id }, body: { email } }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) return this.Members.list() } finally { callback() } }, @@ -217,7 +217,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('teamManagement') try { await apiClient.ProjectsMembers.removeMember({ params: { projectId: this.id, userId } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.Members.list() } finally { callback() } }, @@ -225,20 +225,20 @@ export class Project implements ProjectV2 { const callback = this.addOperation('teamManagement') try { await apiClient.ProjectsMembers.patchMembers({ params: { projectId: this.id }, body }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.Members.list() } finally { callback() } }, getCandidateUsers: async (letters: string) => { return apiClient.Users.getMatchingUsers({ query: { letters, notInProjectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) }, } Deployments = { list: async () => { this.deployments.value = await apiClient.Deployments.listDeployments({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.deployments.value }, create: async (deploymentData: Omit) => { @@ -248,7 +248,7 @@ export class Project implements ProjectV2 { params: { projectId: this.id }, body: { ...deploymentData, projectId: this.id }, }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) } finally { callback() } }, update: async (id: Deployment['id'], deployment: UpdateDeploymentBody) => { @@ -258,7 +258,7 @@ export class Project implements ProjectV2 { params: { projectId: this.id, deploymentId: id }, body: deployment, }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) } finally { callback() } }, delete: async (deploymentId: Deployment['id']) => { @@ -267,7 +267,7 @@ export class Project implements ProjectV2 { await apiClient.Deployments.deleteDeployment({ params: { projectId: this.id, deploymentId }, }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) } finally { callback() } }, } @@ -275,14 +275,14 @@ export class Project implements ProjectV2 { Environments = { list: async () => { this.environments.value = await apiClient.Environments.listEnvironments({ query: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.environments.value }, create: async (envData: Omit) => { const callback = this.addOperation('envManagement') try { await apiClient.Environments.createEnvironment({ body: { ...envData, projectId: this.id } }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) return this.Environments.list() } finally { callback() } }, @@ -290,7 +290,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('envManagement') try { await apiClient.Environments.updateEnvironment({ body: environment, params: { environmentId: id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) await this.Environments.list() return this.environments } finally { callback() } @@ -299,7 +299,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('envManagement') try { await apiClient.Environments.deleteEnvironment({ params: { environmentId } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) await this.Environments.list() return this.environments } finally { callback() } @@ -309,7 +309,7 @@ export class Project implements ProjectV2 { Repositories = { list: async () => { this.repositories.value = await apiClient.Repositories.listRepositories({ query: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.repositories.value }, sync: async (repositoryId: Repo['id'], { branchName, syncAllBranches = false }: { branchName?: string, syncAllBranches?: boolean }) => { @@ -319,14 +319,14 @@ export class Project implements ProjectV2 { params: { repositoryId }, body: { branchName, syncAllBranches }, }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) } finally { callback() } }, create: async (repoData: Omit) => { const callback = this.addOperation('repoManagement') try { await apiClient.Repositories.createRepository({ body: { ...repoData, projectId: this.id } }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) return this.Repositories.list() } finally { callback() } }, @@ -334,7 +334,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('repoManagement') try { await apiClient.Repositories.updateRepository({ body: { ...repoData, projectId: this.id }, params: { repositoryId: id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.Repositories.list() } finally { callback() } }, @@ -342,7 +342,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('repoManagement') try { await apiClient.Repositories.deleteRepository({ params: { repositoryId } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return this.Repositories.list() } finally { callback() } }, @@ -351,11 +351,11 @@ export class Project implements ProjectV2 { Roles = { countMembers: async () => { return apiClient.ProjectsRoles.projectRoleMemberCounts({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) }, list: async () => { this.roles = await apiClient.ProjectsRoles.listProjectRoles({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) this.computePerms() return this.roles }, @@ -363,14 +363,14 @@ export class Project implements ProjectV2 { const callback = this.addOperation('roleManagement') try { this.roles = await apiClient.ProjectsRoles.patchProjectRoles({ body, params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) this.computePerms() return this.roles } finally { callback() } }, create: async (body: typeof projectRoleContract.createProjectRole.body._type) => { this.roles = await apiClient.ProjectsRoles.createProjectRole({ body, params: { projectId: this.id } }) - .then((response: any) => extractData(response, 201)) + .then((response) => extractData(response, 201)) this.computePerms() return this.roles }, @@ -378,7 +378,7 @@ export class Project implements ProjectV2 { const callback = this.addOperation('roleManagement') try { await apiClient.ProjectsRoles.deleteProjectRole({ params: { projectId: this.id, roleId } }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) this.computePerms() return this.Roles.list() } finally { callback() } @@ -388,18 +388,18 @@ export class Project implements ProjectV2 { Services = { getSecrets: async () => { return apiClient.Projects.getProjectSecrets({ params: { projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) }, list: async (permissionTarget: PermissionTarget = 'user') => { this.services = await apiClient.ProjectServices.getServices({ params: { projectId: this.id }, query: { permissionTarget } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) return this.services }, update: async (body: PluginsUpdateBody) => { const callback = this.addOperation('saveServices') try { await apiClient.ProjectServices.updateProjectServices({ params: { projectId: this.id }, body }) - .then((response: any) => extractData(response, 204)) + .then((response) => extractData(response, 204)) return this.Services.list() } finally { callback() } }, @@ -408,7 +408,7 @@ export class Project implements ProjectV2 { Logs = { list: async ({ offset, limit, clean }: GetLogsQuery = { offset: 0, limit: 10 }) => { return apiClient.Logs.getLogs({ query: { offset, limit, clean, projectId: this.id } }) - .then((response: any) => extractData(response, 200)) + .then((response) => extractData(response, 200)) }, } } diff --git a/apps/client/src/views/ProjectDashboard.vue b/apps/client/src/views/ProjectDashboard.vue index d411ed7e78..93ca32c77e 100644 --- a/apps/client/src/views/ProjectDashboard.vue +++ b/apps/client/src/views/ProjectDashboard.vue @@ -137,6 +137,7 @@ const saveProjectState = ref({ const currentRoute = useRoute() async function refreshMembers() { + if (!project.value) return await project.value.Members.list() teamId.value = getRandomId('team') } @@ -153,7 +154,7 @@ watch(currentRoute, () => { }) watch(activeTab, (tabIndex) => { - const tabId = tabTitles[tabIndex].tabId + const tabId = tabTitles[tabIndex]?.tabId if (tabId) { router.replace({ query: { @@ -165,6 +166,7 @@ watch(activeTab, (tabIndex) => { }) async function saveProject() { + if (!project.value) return saveProjectState.value.isProcessing = true await project.value.Commands.update({ description: project.value.description, @@ -175,7 +177,7 @@ async function saveProject() { prodMemory: project.value.prodMemory, prodCpu: project.value.prodCpu, prodGpu: project.value.prodGpu, - }).finally(() => project.value.Commands.refresh()) + }).finally(() => project.value?.Commands.refresh()) saveProjectState.value.isProcessing = false } @@ -203,6 +205,7 @@ async function saveProject() { " @update:model-value=" (desc: string | undefined) => { + if (!project) return project.description = desc; } " diff --git a/apps/client/src/views/admin/ListClusters.vue b/apps/client/src/views/admin/ListClusters.vue index 7074ceee8a..752bf201b0 100644 --- a/apps/client/src/views/admin/ListClusters.vue +++ b/apps/client/src/views/admin/ListClusters.vue @@ -136,7 +136,7 @@ const headers = [ diff --git a/apps/client/src/views/admin/ListPlugins.vue b/apps/client/src/views/admin/ListPlugins.vue index 250e3938ec..41c1004039 100644 --- a/apps/client/src/views/admin/ListPlugins.vue +++ b/apps/client/src/views/admin/ListPlugins.vue @@ -55,7 +55,7 @@ onBeforeMount(() => { function update(data: { value: string, key: string, plugin: string }) { if (!updated.value[data.plugin]) updated.value[data.plugin] = {} - updated.value[data.plugin][data.key] = data.value + updated.value[data.plugin]![data.key] = data.value } const servicesWrapableLength = computed(() => services.value.filter(({ wrapable }) => wrapable).length) diff --git a/apps/client/src/views/admin/ListProjects.vue b/apps/client/src/views/admin/ListProjects.vue index 171f4ea557..e218ff0082 100644 --- a/apps/client/src/views/admin/ListProjects.vue +++ b/apps/client/src/views/admin/ListProjects.vue @@ -125,7 +125,7 @@ async function validateBulkAction() { action: selectedAction.value, projectIds: selectedProjects.value.map(({ id }) => id), }, - }).then((res: any) => extractData(res, 202)) + }).then((res) => extractData(res, 202)) selectedProjectIds.value = [] snackbarStore.setMessage('Traitement en cours, en fonction du nombre de projets cela peut prendre plusieurs minutes, veuillez rafraichir dans quelques instants') } diff --git a/apps/client/src/views/admin/ListUser.vue b/apps/client/src/views/admin/ListUser.vue index 6fd88db2d3..c4d0b50ae3 100644 --- a/apps/client/src/views/admin/ListUser.vue +++ b/apps/client/src/views/admin/ListUser.vue @@ -203,8 +203,8 @@ onBeforeMount(async () => { :style="`background-color: ${user.bgColor};`" > {{ - user.firstName[0].toUpperCase() - + user.lastName[0].toUpperCase() + (user.firstName[0] ?? '').toUpperCase() + + (user.lastName[0] ?? '').toUpperCase() }}
diff --git a/apps/client/tsconfig.json b/apps/client/tsconfig.json index 7f8a3442bf..837cf8df83 100644 --- a/apps/client/tsconfig.json +++ b/apps/client/tsconfig.json @@ -3,21 +3,14 @@ "@cpn-console/ts-config/tsconfig.base.json" ], "compilerOptions": { - "incremental": true, - // Module - "target": "ESNext", - - "jsx": "preserve", - "lib": ["DOM", "ESNext"], - // Base "baseUrl": "./", "rootDir": "./src", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], "module": "Preserve", "moduleResolution": "Bundler", "paths": { - "@/*": [ - "src/*" - ] + "@/*": ["src/*"] }, "resolveJsonModule": true, "types": [ @@ -28,15 +21,6 @@ ], "allowImportingTsExtensions": false, "allowJs": true, - "strict": true, - "strictNullChecks": true, - "alwaysStrict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noPropertyAccessFromIndexSignature": false, - "noUnusedLocals": true, - "noUnusedParameters": true, - "useUnknownInCatchVariables": true, "declaration": true, "declarationDir": "./types", "emitDeclarationOnly": false, @@ -44,9 +28,7 @@ "outDir": "./dist", "sourceMap": true, "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "skipLibCheck": true + "isolatedModules": true }, "vueCompilerOptions": {}, "include": [ diff --git a/apps/server-nestjs/src/modules/gitlab/gitlab-client.service.ts b/apps/server-nestjs/src/modules/gitlab/gitlab-client.service.ts index 53841d8d13..b7a649302e 100644 --- a/apps/server-nestjs/src/modules/gitlab/gitlab-client.service.ts +++ b/apps/server-nestjs/src/modules/gitlab/gitlab-client.service.ts @@ -127,11 +127,14 @@ export class GitlabClientService { async createGroup(path: string) { this.logger.log(`Creating a GitLab group at path ${path}`) const created = await this.client.Groups.create(path, path) - if (this.config.projectRootDir && created.full_path === this.config.projectRootDir) { - await this.setManagedRootGroupAttributes(created.id) - } - if (this.config.projectRootDir && created.full_path === `${this.config.projectRootDir}/${INFRA_GROUP_PATH}`) { - await this.setManagedInfraGroupAttributes(created.id) + const rootDir = this.config.projectRootDir + if (rootDir) { + if (created.full_path === rootDir) { + await this.setManagedRootGroupAttributes(created.id) + } + if (created.full_path === `${rootDir}/${INFRA_GROUP_PATH}`) { + await this.setManagedInfraGroupAttributes(created.id) + } } return created } @@ -340,7 +343,7 @@ export class GitlabClientService { } async deleteGroup(group: CondensedGroupSchemaWith<'id' | 'full_path'>): Promise { - this.logger.verbose(`Deleting GitLab group ${group.full_path} (groupId=${group.id})`) + this.logger.verbose(`Deleting GitLab group ${group.full_path} (groupId=${Number(group.id)})`) await this.client.Groups.remove(group.id) } @@ -513,7 +516,7 @@ export class GitlabClientService { this.logger.debug(`Pagination start (page=${page})`) while (page !== null) { - if (options?.maxPages && pagesFetched >= options.maxPages) { + if (options?.maxPages != null && pagesFetched >= options.maxPages) { page = null continue } diff --git a/apps/server-nestjs/src/modules/infrastructure/configuration/configuration.service.ts b/apps/server-nestjs/src/modules/infrastructure/configuration/configuration.service.ts index 67d925fc11..c39e19b8be 100644 --- a/apps/server-nestjs/src/modules/infrastructure/configuration/configuration.service.ts +++ b/apps/server-nestjs/src/modules/infrastructure/configuration/configuration.service.ts @@ -13,9 +13,9 @@ export class ConfigurationService { isDevSetup = process.env.DEV_SETUP === 'true' // app - host = process.env.SERVER_HOST ?? 'localhost' + host = process.env.SERVER_HOST ?? '' port = process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 0 // dynamically allocate an available ephemeral port - appVersion = this.isProd ? (process.env.APP_VERSION ?? 'unknown') : 'dev' + appVersion = this.isProd ? (process.env.APP_VERSION ?? '') : 'dev' // db dbUrl = process.env.DB_URL @@ -47,7 +47,7 @@ export class ConfigurationService { contactEmail = process.env.CONTACT_EMAIL - ?? 'cloudpinative-relations@interieur.gouv.fr' + ?? '' // argocd argoNamespace = process.env.ARGO_NAMESPACE ?? 'argocd' @@ -171,9 +171,7 @@ export class ConfigurationService { } NODE_ENV - = process.env.NODE_ENV === 'test' - ? 'test' - : process.env.NODE_ENV === 'development' - ? 'development' - : 'production' + = process.env.NODE_ENV != null + ? process.env.NODE_ENV + : 'production' } diff --git a/apps/server-nestjs/src/modules/infrastructure/database/database.service.ts b/apps/server-nestjs/src/modules/infrastructure/database/database.service.ts index 695a2daf5a..8d2fdb66a5 100644 --- a/apps/server-nestjs/src/modules/infrastructure/database/database.service.ts +++ b/apps/server-nestjs/src/modules/infrastructure/database/database.service.ts @@ -43,7 +43,7 @@ export class DatabaseService { if (triesLeft > 0) { this.loggerService.error(error) this.loggerService.log( - `Could not connect to Postgres: ${error.message}`, + `Could not connect to Postgres: ${error instanceof Error ? error.message : String(error)}`, ) this.loggerService.log(`Retrying (${triesLeft} tries left)`) await setTimeout(this.DELAY_BEFORE_RETRY) @@ -51,11 +51,11 @@ export class DatabaseService { } this.loggerService.log( - `Could not connect to Postgres: ${error.message}`, + `Could not connect to Postgres: ${error instanceof Error ? error.message : String(error)}`, ) this.loggerService.log('Out of retries') - error.message = `Out of retries, last error: ${error.message}` - throw error + const outOfRetriesError = new Error(`Out of retries, last error: ${error instanceof Error ? error.message : String(error)}`) + throw outOfRetriesError } } diff --git a/apps/server-nestjs/src/modules/project-services/project-services.utils.ts b/apps/server-nestjs/src/modules/project-services/project-services.utils.ts index c5961851e1..4d00c47a59 100644 --- a/apps/server-nestjs/src/modules/project-services/project-services.utils.ts +++ b/apps/server-nestjs/src/modules/project-services/project-services.utils.ts @@ -52,10 +52,10 @@ interface ServiceManifestParams { } export function populateServiceManifest({ service, data, select, permissionTarget }: ServiceManifestParams): Partial { - const manifest = structuredClone(service.config) + const manifest = structuredClone(service.config) as PluginConfig const selected: Partial = {} - for (const [scope] of Object.entries(select).filter(([_scope, bool]) => bool)) { + for (const [scope] of Object.entries(select).filter(([_scope, bool]) => bool === true)) { if (!manifest?.[scope]) continue selected[scope] = manifest[scope].filter(item => item.permissions[permissionTarget].read || item.permissions[permissionTarget].write).map((item) => { const row = data[scope]?.find(candidate => candidate.pluginName === service.name && candidate.key === item.key) @@ -71,6 +71,7 @@ export function populateServiceManifest({ service, data, select, permissionTarge return selected } +interface ServiceUrlResponse { title?: string; description?: string; to: string } export function normalizeServiceUrls(toResponse: unknown): ServiceUrl[] { if (Array.isArray(toResponse)) { return toResponse.map(res => ({ name: res.title ?? '', description: res.description ?? '', to: res.to })) @@ -80,8 +81,9 @@ export function normalizeServiceUrls(toResponse: unknown): ServiceUrl[] { return [{ to: toResponse, name: '' }] } - if (toResponse) { - return [{ name: (toResponse as { title?: string }).title ?? '', to: (toResponse as { to: string }).to }] + if (toResponse != null && typeof toResponse === 'object') { + const resp = toResponse as { title?: string; to: string } + return [{ name: resp.title ?? '', to: resp.to }] } return [] diff --git a/apps/server-nestjs/src/modules/project/project.utils.ts b/apps/server-nestjs/src/modules/project/project.utils.ts index bb50d21fdf..24a020e2a2 100644 --- a/apps/server-nestjs/src/modules/project/project.utils.ts +++ b/apps/server-nestjs/src/modules/project/project.utils.ts @@ -132,10 +132,10 @@ export function generateProjectWhereInput(opts: { const { status, statusIn, statusNotIn, filter = 'member', ...rest } = opts.query const whereAnd: Prisma.ProjectWhereInput[] = [] - if (rest.id) whereAnd.push({ id: rest.id }) + if (rest.id != null) whereAnd.push({ id: rest.id }) if (rest.locked !== undefined) whereAnd.push({ locked: rest.locked }) - if (rest.name) whereAnd.push({ name: rest.name }) - if (rest.description) whereAnd.push({ description: { contains: rest.description } }) + if (rest.name != null) whereAnd.push({ name: rest.name }) + if (rest.description != null) whereAnd.push({ description: { contains: rest.description } }) const statusWhere = parseEnumWhereFilter({ enumValues: projectStatus, @@ -148,14 +148,14 @@ export function generateProjectWhereInput(opts: { if (rest.lastSuccessProvisionningVersion) { if (rest.lastSuccessProvisionningVersion === 'outdated') { whereAnd.push({ lastSuccessProvisionningVersion: { not: opts.appVersion } }) - } else if (rest.lastSuccessProvisionningVersion === 'last') { + } else if (rest.lastSuccessProvisionningVersion === 'last' && opts.appVersion != null) { whereAnd.push({ lastSuccessProvisionningVersion: { equals: opts.appVersion } }) } else { whereAnd.push({ lastSuccessProvisionningVersion: rest.lastSuccessProvisionningVersion }) } } - if (rest.search) { + if (rest.search != null) { whereAnd.push({ OR: [ { name: { contains: rest.search } }, diff --git a/apps/server-nestjs/src/modules/registry/registry.service.ts b/apps/server-nestjs/src/modules/registry/registry.service.ts index cd675f32da..a88f7c8c8a 100644 --- a/apps/server-nestjs/src/modules/registry/registry.service.ts +++ b/apps/server-nestjs/src/modules/registry/registry.service.ts @@ -83,7 +83,7 @@ export class RegistryService { const created = await this.client.createRobot( generateRobotPermissions(project, robotName, access), ) - if (created.status >= 300 || !created.data) { + if (created.status != null && (created.status >= 300 || !created.data)) { throw new Error(`Harbor create robot failed (${created.status})`) } return created.data @@ -103,7 +103,7 @@ export class RegistryService { 'project.slug': project.slug, 'registry.robot.name': robotName, }) - if (!this.config.projectRootDir) { + if (this.config.projectRootDir == null) { throw new Error('PROJECTS_ROOT_DIR is required') } const relativeVaultPath = `REGISTRY/${robotName}` @@ -122,7 +122,7 @@ export class RegistryService { 'registry.robot.secret.expiring': expiring, }) - if (vaultRobotSecret?.data?.HOST === this.host && !expiring) { + if (vaultRobotSecret && !expiring && vaultRobotSecret.data.HOST === this.host) { span?.setAttribute('vault.secret.reused', true) return vaultRobotSecret.data } @@ -188,14 +188,14 @@ export class RegistryService { span?.setAttribute('project.slug', project.slug) const members = await this.client.getGroupMembers(project.slug) - if (members.status !== 200 || !members.data) { + if (members.status != null && members.status !== 200 || !members.data) { throw new Error(`Harbor list members failed (${members.status})`) } const membersByName = new Map() for (const member of members.data) { const name = member?.entity_name - if (name) membersByName.set(name, member) + if (name != null) membersByName.set(name, member) } const byGroupName = await this.generateAccessLevelMapping(project) @@ -322,7 +322,7 @@ export class RegistryService { this.logger.log(`Handling project upsert for ${project.slug}`) const quotaConfigRaw = getPluginConfig(project, REGISTRY_CONFIG_KEY_QUOTA_HARD_LIMIT) const publishConfig = getPluginConfig(project, REGISTRY_CONFIG_KEY_PUBLISH_PROJECT_ROBOT) - const parsedQuota = quotaConfigRaw ? parseBytes(String(quotaConfigRaw)) : undefined + const parsedQuota = quotaConfigRaw != null ? parseBytes(String(quotaConfigRaw)) : undefined const storageLimitBytes = parsedQuota ?? -1 const publishProjectRobot = specificallyEnabled(publishConfig) await this.ensureProject(project, { storageLimitBytes, publishProjectRobot }) @@ -483,7 +483,7 @@ function generateRetentionPolicy( const rawCount = Number(options.harborRuleCount) let count: number - if (Number.isFinite(rawCount) && rawCount > 0) { + if (rawCount != null && Number.isFinite(rawCount) && rawCount > 0) { count = rawCount } else if (template === 'always') { count = 1 diff --git a/apps/server-nestjs/tsconfig.eslint.json b/apps/server-nestjs/tsconfig.eslint.json new file mode 100644 index 0000000000..5d2d3b5fc8 --- /dev/null +++ b/apps/server-nestjs/tsconfig.eslint.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "." + }, + "include": [ + "./**/*.ts", + "./**/*.js", + "./**/*.cjs", + "./**/*.mjs" + ], + "exclude": [ + "./node_modules", + "./dist", + "./types", + "./coverage", + "./**/*.d.ts" + ] +} diff --git a/apps/server-nestjs/tsconfig.json b/apps/server-nestjs/tsconfig.json index 48b6403d6f..e12e44ce8b 100644 --- a/apps/server-nestjs/tsconfig.json +++ b/apps/server-nestjs/tsconfig.json @@ -1,25 +1,17 @@ { + "extends": [ + "@cpn-console/ts-config/tsconfig.base.json" + ], "compilerOptions": { - "incremental": true, - "target": "ES2023", + "baseUrl": ".", + "rootDir": ".", + "module": "NodeNext", + "moduleResolution": "NodeNext", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "baseUrl": "./", - "module": "nodenext", - "moduleResolution": "nodenext", - "resolvePackageJsonExports": true, - "strictBindCallApply": false, - "strictNullChecks": true, - "noFallthroughCasesInSwitch": false, - "noImplicitAny": false, - "declaration": true, + "declarationDir": "./dist", "outDir": "./dist", "removeComments": true, - "sourceMap": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "skipLibCheck": true + "allowSyntheticDefaultImports": true } } diff --git a/apps/server/src/connect.ts b/apps/server/src/connect.ts index 31d608a66e..cefb56906f 100644 --- a/apps/server/src/connect.ts +++ b/apps/server/src/connect.ts @@ -46,8 +46,7 @@ export async function getConnection(triesLeft = 5): Promise { } logger.error({ err }, 'Out of retries connecting to Postgres') - err.message = `Out of retries connecting to Postgres, last error: ${err.message}` - throw err + throw new Error(`Out of retries connecting to Postgres, last error: ${err instanceof Error ? err.message : String(err)}`) } } diff --git a/apps/server/src/init/db/index.ts b/apps/server/src/init/db/index.ts index fe37b33281..97829c39b0 100644 --- a/apps/server/src/init/db/index.ts +++ b/apps/server/src/init/db/index.ts @@ -16,7 +16,7 @@ export async function initDb(data: Imports) { const dataStringified = JSON.stringify(data) const dataParsed = JSON.parse(dataStringified, (key, value) => { try { - if (['permissions', 'everyonePerms'].includes(key)) { + if (typeof key === 'string' && ['permissions', 'everyonePerms'].includes(key)) { return BigInt(value.slice(0, value.length - 1)) } } catch { @@ -38,7 +38,7 @@ export async function initDb(data: Imports) { for (const [modelKey, rows] of dataParsed.associations) { for (const row of rows) { const idKey = 'id' - const connectKeys = Object.keys(row).filter(key => key !== idKey) + const connectKeys = Object.keys(row).filter((key): key is string => typeof key === 'string' && key !== idKey) const dataConnects = connectKeys.reduce((acc, curr) => { acc[curr] = { connect: row[curr] } return acc diff --git a/apps/server/src/init/db/utils.ts b/apps/server/src/init/db/utils.ts index e4b941089f..16b8c2251b 100644 --- a/apps/server/src/init/db/utils.ts +++ b/apps/server/src/init/db/utils.ts @@ -49,7 +49,7 @@ function sort() { || (relationField.isRequired && !field.isRequired) ) { const moveRes = moveBefore(ModelsOrder, model, field.type) - if (moveRes) { + if (moveRes !== false) { hasChanged = true ModelsOrder = moveRes } @@ -72,11 +72,11 @@ sort() // special case to study const logUserCase = moveBefore(ModelsOrder, 'User', 'Log') -if (logUserCase) { +if (logUserCase !== false) { ModelsOrder = logUserCase } const logProjectCase = moveBefore(ModelsOrder, 'Project', 'Log') -if (logProjectCase) { +if (logProjectCase !== false) { ModelsOrder = logProjectCase } diff --git a/apps/server/src/prepare-app.ts b/apps/server/src/prepare-app.ts index 000734714b..c7c27cd3c3 100644 --- a/apps/server/src/prepare-app.ts +++ b/apps/server/src/prepare-app.ts @@ -1,6 +1,3 @@ -import { rm } from 'node:fs/promises' -import { dirname, resolve } from 'node:path' -import { fileURLToPath } from 'node:url' import { logger } from '@cpn-console/logger' import app from './app.js' import { getConnection } from './connect.js' @@ -10,8 +7,9 @@ import { isCI, isDev, isDevSetup, isInt, isProd, isTest, port } from './utils/en async function initializeDB(path: string) { logger.info('Starting init DB...') - const { data } = await import(path) - await initDb(data) + const dataModule = await import(path) + const data = dataModule.data ?? dataModule.default + await initDb(data as Record) logger.info('initDb invoked successfully') } @@ -24,7 +22,7 @@ export async function startServer(defaultPort: number = (port ? +port : 8080)) { throw error } - initPm() + void initPm() logger.info('Reading init database file') @@ -41,7 +39,7 @@ export async function startServer(defaultPort: number = (port ? +port : 8080)) { logger.info(`Successfully deleted '${dataPath}'`) } } catch (err) { - if (err?.code === 'ERR_MODULE_NOT_FOUND' || err?.message?.includes('Failed to load') || err?.message?.includes('Cannot find module')) { + if (err instanceof Error && (err.code === 'ERR_MODULE_NOT_FOUND' || /Failed to load|Cannot find module/.test(err.message))) { logger.info('No initDb file, skipping') } else { logger.warn({ err }, 'Init DB failed') @@ -66,7 +64,7 @@ export async function getPreparedApp() { throw error } - initPm() + void initPm() logger.info('Reading init database file') @@ -83,7 +81,7 @@ export async function getPreparedApp() { logger.info(`Successfully deleted '${dataPath}'`) } } catch (err) { - if (err?.code === 'ERR_MODULE_NOT_FOUND' || err?.message?.includes('Failed to load') || err?.message?.includes('Cannot find module')) { + if (err instanceof Error && (err.code === 'ERR_MODULE_NOT_FOUND' || /Failed to load|Cannot find module/.test(err.message))) { logger.info('No initDb file, skipping') } else { logger.warn({ err }, 'Init DB failed') diff --git a/apps/server/src/resources/admin-role/business.ts b/apps/server/src/resources/admin-role/business.ts index f81fd65b75..370e87a9e7 100644 --- a/apps/server/src/resources/admin-role/business.ts +++ b/apps/server/src/resources/admin-role/business.ts @@ -78,8 +78,9 @@ export async function countRolesMembers() { }) const rolesCounts: Record = Object.fromEntries(roles.map(role => [role.id, 0])) // {role uuid: 0} for (const { adminRoleIds } of users) { + if (!adminRoleIds) continue for (const roleId of adminRoleIds) { - rolesCounts[roleId]++ + rolesCounts[roleId]!++ } } return rolesCounts diff --git a/apps/server/src/resources/admin-role/queries.ts b/apps/server/src/resources/admin-role/queries.ts index 9c29eb0b36..f12920b6db 100644 --- a/apps/server/src/resources/admin-role/queries.ts +++ b/apps/server/src/resources/admin-role/queries.ts @@ -4,9 +4,9 @@ import type { } from '@prisma/client' import prisma from '@/prisma.js' -export const listAdminRoles = () => prisma.adminRole.findMany({ orderBy: { position: 'asc' } }) +export const listAdminRoles = async () => prisma.adminRole.findMany({ orderBy: { position: 'asc' } }) -export function createAdminRole(data: Pick) { +export async function createAdminRole(data: Pick) { return prisma.adminRole.create({ data: { name: data.name, @@ -17,14 +17,14 @@ export function createAdminRole(data: Pick) { +export async function updateAdminRole(id: AdminRole['id'], data: Pick) { return prisma.adminRole.updateMany({ where: { id }, data, }) } -export function deleteAdminRole(id: AdminRole['id']) { +export async function deleteAdminRole(id: AdminRole['id']) { return prisma.adminRole.delete({ where: { id, diff --git a/apps/server/src/resources/cluster/queries.ts b/apps/server/src/resources/cluster/queries.ts index f66e1fc0bc..7995edb6d5 100644 --- a/apps/server/src/resources/cluster/queries.ts +++ b/apps/server/src/resources/cluster/queries.ts @@ -65,21 +65,21 @@ export async function updateProjectClusterHistory(projectId: Project['id'], clus ]) } -export function getClusterById(id: Cluster['id']) { +export async function getClusterById(id: Cluster['id']) { return prisma.cluster.findUnique({ where: { id }, include: { kubeconfig: true }, }) } -export function getClusterByIdOrThrow(id: Cluster['id']) { +export async function getClusterByIdOrThrow(id: Cluster['id']) { return prisma.cluster.findUniqueOrThrow({ where: { id }, include: { kubeconfig: true, zone: true }, }) } -export function getClusterEnvironments(clusterId: Cluster['id']) { +export async function getClusterEnvironments(clusterId: Cluster['id']) { return prisma.environment.findMany({ where: { clusterId }, select: { @@ -99,7 +99,7 @@ export function getClusterEnvironments(clusterId: Cluster['id']) { }) } -export function getClusterDetails(id: Cluster['id']) { +export async function getClusterDetails(id: Cluster['id']) { return prisma.cluster.findUniqueOrThrow({ where: { id }, select: { @@ -125,7 +125,7 @@ export function getClusterDetails(id: Cluster['id']) { }) } -export function getClustersByIds(clusterIds: Cluster['id'][]) { +export async function getClustersByIds(clusterIds: Cluster['id'][]) { return prisma.cluster.findMany({ where: { id: { in: clusterIds }, @@ -134,7 +134,7 @@ export function getClustersByIds(clusterIds: Cluster['id'][]) { }) } -export function getPublicClusters() { +export async function getPublicClusters() { return prisma.cluster.findMany({ where: { privacy: 'public' }, include: { zone: true }, @@ -151,11 +151,11 @@ export async function getClusterNamesByZoneId(zoneId: string) { return clusterNames.map(({ label }) => label) } -export function getClusterByLabel(label: Cluster['label']) { +export async function getClusterByLabel(label: Cluster['label']) { return prisma.cluster.findUnique({ where: { label } }) } -export function getClusterByEnvironmentId(id: Environment['id']) { +export async function getClusterByEnvironmentId(id: Environment['id']) { return prisma.cluster.findMany({ where: { environments: { @@ -166,7 +166,7 @@ export function getClusterByEnvironmentId(id: Environment['id']) { }) } -export function getClustersWithProjectIdAndConfig() { +export async function getClustersWithProjectIdAndConfig() { return prisma.cluster.findMany({ select: { id: true, @@ -196,7 +196,7 @@ export function getClustersWithProjectIdAndConfig() { }) } -export function listClusters(where: Prisma.ClusterWhereInput) { +export async function listClusters(where: Prisma.ClusterWhereInput) { return prisma.cluster.findMany({ where, select: { @@ -228,7 +228,7 @@ export async function listStagesByClusterId(id: Cluster['id']) { }))?.stages } -export function createCluster(data: Omit, kubeconfig: Pick, zoneId: string) { +export async function createCluster(data: Omit, kubeconfig: Pick, zoneId: string) { return prisma.cluster.create({ data: { ...data, @@ -241,7 +241,7 @@ export function createCluster(data: Omit>, kubeconfig: Pick) { +export async function updateCluster(id: Cluster['id'], data: Partial>, kubeconfig: Pick) { return prisma.cluster.update({ where: { id }, data: { @@ -254,7 +254,7 @@ export function updateCluster(id: Cluster['id'], data: Partial[0]['create']) { +export async function _createLog(data: Parameters[0]['create']) { return prisma.log.upsert({ where: { id: data.id, diff --git a/apps/server/src/resources/project-member/queries.ts b/apps/server/src/resources/project-member/queries.ts index a4ceb00df1..ec81474f37 100644 --- a/apps/server/src/resources/project-member/queries.ts +++ b/apps/server/src/resources/project-member/queries.ts @@ -6,9 +6,9 @@ import type { import prisma from '@/prisma.js' -export const listMembers = (projectId: Project['id']) => prisma.projectMembers.findMany({ where: { projectId }, include: { user: true } }) +export const listMembers = async (projectId: Project['id']) => prisma.projectMembers.findMany({ where: { projectId }, include: { user: true } }) -export function upsertMember(data: Prisma.ProjectMembersUncheckedCreateInput) { +export async function upsertMember(data: Prisma.ProjectMembersUncheckedCreateInput) { return prisma.projectMembers.upsert({ where: { projectId_userId: { @@ -24,7 +24,7 @@ export function upsertMember(data: Prisma.ProjectMembersUncheckedCreateInput) { }) } -export function deleteMember(data: Prisma.ProjectMembersWhereUniqueInput['projectId_userId']) { +export async function deleteMember(data: Prisma.ProjectMembersWhereUniqueInput['projectId_userId']) { return prisma.projectMembers.delete({ where: { projectId_userId: data, diff --git a/apps/server/src/resources/project-role/business.ts b/apps/server/src/resources/project-role/business.ts index 52bd8966b3..3ea6b27e00 100644 --- a/apps/server/src/resources/project-role/business.ts +++ b/apps/server/src/resources/project-role/business.ts @@ -102,8 +102,9 @@ export async function countRolesMembers(projectId: Project['id']) { const members = await listMembers(projectId) const rolesCounts: Record = Object.fromEntries(roles.map(role => [role.id, 0])) // {role uuid: 0} for (const { roleIds } of members) { + if (!roleIds) continue for (const roleId of roleIds) { - rolesCounts[roleId]++ + rolesCounts[roleId]!++ } } return rolesCounts diff --git a/apps/server/src/resources/project-role/queries.ts b/apps/server/src/resources/project-role/queries.ts index 3e2aa4a0fa..0cd8055d06 100644 --- a/apps/server/src/resources/project-role/queries.ts +++ b/apps/server/src/resources/project-role/queries.ts @@ -6,11 +6,11 @@ import type { import prisma from '@/prisma.js' -export const getRole = (id: ProjectRole['id']) => prisma.projectRole.findUnique({ where: { id } }) +export const getRole = async (id: ProjectRole['id']) => prisma.projectRole.findUnique({ where: { id } }) -export const listRoles = (projectId: Project['id']) => prisma.projectRole.findMany({ where: { projectId }, orderBy: { position: 'asc' } }) +export const listRoles = async (projectId: Project['id']) => prisma.projectRole.findMany({ where: { projectId }, orderBy: { position: 'asc' } }) -export function createRole(data: Pick) { +export async function createRole(data: Pick) { return prisma.projectRole.create({ data: { name: data.name, @@ -23,7 +23,7 @@ export function createRole(data: Pick) { +export async function updateRole(id: ProjectRole['id'], data: Pick) { return prisma.projectRole.update({ where: { id }, data, @@ -56,4 +56,4 @@ export async function deleteRole(id: ProjectRole['id']) { } } -export const getProjectRoleById = (id: ProjectRole['id']) => prisma.projectRole.findUnique({ where: { id }, include: { project: true } }) +export const getProjectRoleById = async (id: ProjectRole['id']) => prisma.projectRole.findUnique({ where: { id }, include: { project: true } }) diff --git a/apps/server/src/resources/project-service/business.ts b/apps/server/src/resources/project-service/business.ts index bce70064ef..5e15b657a4 100644 --- a/apps/server/src/resources/project-service/business.ts +++ b/apps/server/src/resources/project-service/business.ts @@ -26,8 +26,8 @@ export type ConfigRecords = { export function dbToObj(records: Omit[]): PluginsUpdateBody { const obj: PluginsUpdateBody = {} for (const record of records) { - if (!obj[record.pluginName]) obj[record.pluginName] = {} - obj[record.pluginName][record.key] = record.value + const plugin = obj[record.pluginName] ??= {} + plugin[record.key] = record.value } return obj } diff --git a/apps/server/src/resources/project-service/queries.ts b/apps/server/src/resources/project-service/queries.ts index cf353614b2..3062bb42f8 100644 --- a/apps/server/src/resources/project-service/queries.ts +++ b/apps/server/src/resources/project-service/queries.ts @@ -3,7 +3,7 @@ import type { ConfigRecords } from './business.js' import prisma from '@/prisma.js' // CONFIG -export function getProjectStore(projectId: Project['id']) { +export async function getProjectStore(projectId: Project['id']) { return prisma.projectPlugin.findMany({ where: { projectId }, select: { diff --git a/apps/server/src/resources/project/business.ts b/apps/server/src/resources/project/business.ts index b27f16bf64..41f5f7a5ce 100644 --- a/apps/server/src/resources/project/business.ts +++ b/apps/server/src/resources/project/business.ts @@ -1,5 +1,6 @@ import type { projectContract } from '@cpn-console/shared' import type { Project, User } from '@prisma/client' +import type { PluginResult } from '@cpn-console/hooks' import type { UserDetails } from '@/types/index.js' import type { ErrorResType } from '@/utils/errors.js' import { servicesInfos } from '@cpn-console/hooks' @@ -62,10 +63,8 @@ export async function getProjectSecrets(projectId: string) { return Object.fromEntries( Object.entries(hookReply.results) - // @ts-ignore - .filter(([_key, value]) => Object.keys(value.secrets).length) - // @ts-ignore - .map(([key, value]) => [servicesInfos[key]?.title, value.secrets]), + .filter(([_key, value]) => value != null && typeof value === 'object' && Object.keys((value as PluginResult).store?.secrets ?? {}).length) + .map(([key, value]) => [servicesInfos[key]?.title, (value as PluginResult).store?.secrets ?? {}]), ) } @@ -274,19 +273,19 @@ export async function bulkActionProject(data: typeof projectContract.bulkActionP where: { status: { not: 'archived' } }, })).map(({ id }) => id) } - bulkExector(data.projectIds + await bulkExector(data.projectIds .map((projectId) => { if (data.action === 'archive') { - return () => archiveProject(projectId, requestor, requestId) + return async () => archiveProject(projectId, requestor, requestId) } if (data.action === 'lock') { - return () => updateProject({ locked: true }, projectId, requestor, requestId) + return async () => updateProject({ locked: true }, projectId, requestor, requestId) } if (data.action === 'unlock') { - return () => updateProject({ locked: false }, projectId, requestor, requestId) + return async () => updateProject({ locked: false }, projectId, requestor, requestId) } if (data.action === 'replay') { - return () => replayHooks({ projectId, userId: requestor.id, requestId }) + return async () => replayHooks({ projectId, userId: requestor.id, requestId }) } // should never been called return async () => {} @@ -301,6 +300,6 @@ export function chunk(arr: T[], size: number): T[][] { async function bulkExector(toExecute: Array<() => Promise>) { const toExecuteChunked = chunk(toExecute, parallelBulkLimit) for (const chunkToExecute of toExecuteChunked) { - await Promise.allSettled(chunkToExecute.map(fn => fn())) + await Promise.allSettled(chunkToExecute.map(async fn => fn())) } } diff --git a/apps/server/src/resources/project/queries.ts b/apps/server/src/resources/project/queries.ts index 5957b15478..2c60e2be88 100644 --- a/apps/server/src/resources/project/queries.ts +++ b/apps/server/src/resources/project/queries.ts @@ -13,7 +13,7 @@ import { appVersion } from '@/utils/env.js' import { uuid } from '@/utils/queries-tools.js' type ProjectUpdate = Partial> -export function updateProject(id: Project['id'], data: ProjectUpdate) { +export async function updateProject(id: Project['id'], data: ProjectUpdate) { return prisma.project.update({ where: { id }, data, @@ -83,7 +83,7 @@ export async function listProjects({ }) } -export function getProjectOrThrow(id: Project['id'] | Project['slug']) { +export async function getProjectOrThrow(id: Project['id'] | Project['slug']) { return prisma.project.findFirstOrThrow({ where: uuid.test(id) ? { id } @@ -97,7 +97,7 @@ export function getProjectOrThrow(id: Project['id'] | Project['slug']) { }) } -export function getProjectInfosByIdOrThrow(projectId: Project['id']) { +export async function getProjectInfosByIdOrThrow(projectId: Project['id']) { return prisma.project.findUniqueOrThrow({ where: { id: projectId, @@ -109,7 +109,7 @@ export function getProjectInfosByIdOrThrow(projectId: Project['id']) { }) } -export function getProjectMembers(projectId: Project['id']) { +export async function getProjectMembers(projectId: Project['id']) { return prisma.projectMembers.findMany({ where: { projectId, @@ -118,7 +118,7 @@ export function getProjectMembers(projectId: Project['id']) { }) } -export function getProjectById(id: Project['id']) { +export async function getProjectById(id: Project['id']) { return prisma.project.findUnique({ where: { id } }) } @@ -129,21 +129,21 @@ export const baseProjectIncludes = { owner: true, } as const -export function getProjectInfos(id: Project['id']) { +export async function getProjectInfos(id: Project['id']) { return prisma.project.findUnique({ where: { id }, include: baseProjectIncludes, }) } -export function getProjectInfosOrThrow(id: Project['id']) { +export async function getProjectInfosOrThrow(id: Project['id']) { return prisma.project.findUniqueOrThrow({ where: { id }, include: baseProjectIncludes, }) } -export function getProjectInfosAndRepos(id: Project['id']) { +export async function getProjectInfosAndRepos(id: Project['id']) { return prisma.project.findUniqueOrThrow({ where: { id }, include: { @@ -153,7 +153,7 @@ export function getProjectInfosAndRepos(id: Project['id']) { }) } -export function getSlugs(slugPrefix: string) { +export async function getSlugs(slugPrefix: string) { return prisma.project.findMany({ where: { slug: { startsWith: slugPrefix }, @@ -161,7 +161,7 @@ export function getSlugs(slugPrefix: string) { }) } -export function getAllProjectsDataForExport() { +export async function getAllProjectsDataForExport() { return prisma.project.findMany({ select: { name: true, @@ -182,7 +182,7 @@ export function getAllProjectsDataForExport() { }) } -export function getRolesByProjectId(projectId: Project['id']) { +export async function getRolesByProjectId(projectId: Project['id']) { return prisma.projectRole.findMany({ where: { projectId }, }) @@ -208,7 +208,7 @@ const clusterInfosSelect = { }, }, } -export function getHookProjectInfos(id: Project['id']) { +export async function getHookProjectInfos(id: Project['id']) { return prisma.project.findUniqueOrThrow({ where: { id }, include: { @@ -251,7 +251,7 @@ interface CreateProjectParams { prodMemory: number } -export function initializeProject(params: CreateProjectParams) { +export async function initializeProject(params: CreateProjectParams) { return prisma.project.create({ data: { description: params.description ?? '', @@ -302,14 +302,14 @@ export function initializeProject(params: CreateProjectParams) { } // UPDATE -export function lockProject(id: Project['id']) { +export async function lockProject(id: Project['id']) { return prisma.project.update({ where: { id }, data: { locked: true }, }) } -export function updateProjectCreated(id: Project['id']) { +export async function updateProjectCreated(id: Project['id']) { return prisma.project.update({ where: { id }, data: { @@ -320,7 +320,7 @@ export function updateProjectCreated(id: Project['id']) { }) } -export function updateProjectFailed(id: Project['id']) { +export async function updateProjectFailed(id: Project['id']) { return prisma.project.update({ where: { id }, data: { status: ProjectStatus.failed }, @@ -328,7 +328,7 @@ export function updateProjectFailed(id: Project['id']) { }) } -export function updateProjectWarning(id: Project['id']) { +export async function updateProjectWarning(id: Project['id']) { return prisma.project.update({ where: { id }, data: { status: ProjectStatus.warning }, @@ -336,7 +336,7 @@ export function updateProjectWarning(id: Project['id']) { }) } -export function addUserToProject({ project, user }: { project: Project, user: User }) { +export async function addUserToProject({ project, user }: { project: Project, user: User }) { return prisma.projectMembers.create({ data: { userId: user.id, @@ -345,7 +345,7 @@ export function addUserToProject({ project, user }: { project: Project, user: Us }) } -export function removeUserFromProject({ projectId, userId }: { projectId: Project['id'], userId: User['id'] }) { +export async function removeUserFromProject({ projectId, userId }: { projectId: Project['id'], userId: User['id'] }) { return prisma.projectMembers.delete({ where: { projectId_userId: { diff --git a/apps/server/src/resources/repository/queries.ts b/apps/server/src/resources/repository/queries.ts index 277e7af602..33d9ec561d 100644 --- a/apps/server/src/resources/repository/queries.ts +++ b/apps/server/src/resources/repository/queries.ts @@ -2,11 +2,11 @@ import type { Project, Repository } from '@prisma/client' import prisma from '@/prisma.js' // SELECT -export function getRepositoryById(id: Repository['id']) { +export async function getRepositoryById(id: Repository['id']) { return prisma.repository.findUniqueOrThrow({ where: { id } }) } -export function getProjectRepositories(projectId: Project['id']) { +export async function getProjectRepositories(projectId: Project['id']) { return prisma.repository.findMany({ where: { projectId } }) } @@ -14,7 +14,7 @@ export function getProjectRepositories(projectId: Project['id']) { type RepositoryCreate = Pick & Partial> -export function initializeRepository({ projectId, internalRepoName, externalRepoUrl, isInfra, isPrivate, externalUserName, deployRevision, deployPath, helmValuesFiles }: RepositoryCreate) { +export async function initializeRepository({ projectId, internalRepoName, externalRepoUrl, isInfra, isPrivate, externalUserName, deployRevision, deployPath, helmValuesFiles }: RepositoryCreate) { return prisma.repository.create({ data: { projectId, @@ -30,7 +30,7 @@ export function initializeRepository({ projectId, internalRepoName, externalRepo }) } -export function getHookRepository(id: Repository['id']) { +export async function getHookRepository(id: Repository['id']) { return prisma.repository.findUniqueOrThrow({ where: { id, @@ -42,7 +42,7 @@ export function getHookRepository(id: Repository['id']) { } // UPDATE -export function updateRepository(id: Repository['id'], infos: Partial) { +export async function updateRepository(id: Repository['id'], infos: Partial) { return prisma.repository.update({ where: { id }, data: { ...infos } }) } @@ -53,10 +53,10 @@ export async function deleteRepository(id: Repository['id']) { return prisma.repository.delete({ where: { id } }) } -export function deleteAllRepositoryForProject(id: Project['id']) { +export async function deleteAllRepositoryForProject(id: Project['id']) { return prisma.repository.deleteMany({ where: { projectId: id } }) } -export function _createRepository(data: Parameters[0]['create']) { +export async function _createRepository(data: Parameters[0]['create']) { return prisma.repository.upsert({ create: data, update: data, where: { id: data.id } }) } diff --git a/apps/server/src/resources/service-chain/queries.ts b/apps/server/src/resources/service-chain/queries.ts index 0207266c8a..b63f967b94 100644 --- a/apps/server/src/resources/service-chain/queries.ts +++ b/apps/server/src/resources/service-chain/queries.ts @@ -45,11 +45,11 @@ export async function getServiceChainDetails( } export async function retryServiceChain(serviceChainId: ServiceChain['id']) { - return await getClient().post(`/requests/${serviceChainId}/retry`) + return getClient().post(`/requests/${serviceChainId}/retry`) } export async function validateServiceChain(validationId: string) { - return await getClient().post(`/validate/${validationId}`) + return getClient().post(`/validate/${validationId}`) } export async function getServiceChainFlows(serviceChainId: ServiceChain['id']) { diff --git a/apps/server/src/resources/stage/queries.ts b/apps/server/src/resources/stage/queries.ts index 98d526600a..c5d202f936 100644 --- a/apps/server/src/resources/stage/queries.ts +++ b/apps/server/src/resources/stage/queries.ts @@ -1,7 +1,7 @@ import type { Cluster, Stage } from '@prisma/client' import prisma from '@/prisma.js' -export function listStages() { +export async function listStages() { return prisma.stage.findMany({ include: { clusters: true, @@ -17,7 +17,7 @@ export async function getAllStageIds() { })).map(({ id }) => id) } -export function getStageById(id: Stage['id']) { +export async function getStageById(id: Stage['id']) { return prisma.stage.findUnique({ where: { id }, include: { @@ -26,7 +26,7 @@ export function getStageById(id: Stage['id']) { }) } -export function getStageByIdOrThrow(id: Stage['id']) { +export async function getStageByIdOrThrow(id: Stage['id']) { return prisma.stage.findUniqueOrThrow({ where: { id }, include: { @@ -35,7 +35,7 @@ export function getStageByIdOrThrow(id: Stage['id']) { }) } -export function getStageAssociatedEnvironmentById(id: Stage['id']) { +export async function getStageAssociatedEnvironmentById(id: Stage['id']) { return prisma.environment.findMany({ where: { stageId: id, @@ -58,7 +58,7 @@ export function getStageAssociatedEnvironmentById(id: Stage['id']) { }) } -export function getStageAssociatedEnvironmentLengthById(id: Stage['id']) { +export async function getStageAssociatedEnvironmentLengthById(id: Stage['id']) { return prisma.environment.count({ where: { stageId: id, @@ -66,13 +66,13 @@ export function getStageAssociatedEnvironmentLengthById(id: Stage['id']) { }) } -export function getStageByName(name: Stage['name']) { +export async function getStageByName(name: Stage['name']) { return prisma.stage.findUnique({ where: { name }, }) } -export function linkStageToClusters(id: Stage['id'], clusterIds: Cluster['id'][]) { +export async function linkStageToClusters(id: Stage['id'], clusterIds: Cluster['id'][]) { return prisma.stage.update({ where: { id, @@ -85,7 +85,7 @@ export function linkStageToClusters(id: Stage['id'], clusterIds: Cluster['id'][] }) } -export function createStage({ name }: { name: Stage['name'] }) { +export async function createStage({ name }: { name: Stage['name'] }) { return prisma.stage.create({ data: { name, @@ -93,7 +93,7 @@ export function createStage({ name }: { name: Stage['name'] }) { }) } -export function updateStageName(id: Stage['id'], name: Stage['name']) { +export async function updateStageName(id: Stage['id'], name: Stage['name']) { return prisma.stage.update({ where: { id, @@ -104,7 +104,7 @@ export function updateStageName(id: Stage['id'], name: Stage['name']) { }) } -export function deleteStage(id: Stage['id']) { +export async function deleteStage(id: Stage['id']) { return prisma.stage.delete({ where: { id }, }) diff --git a/apps/server/src/resources/system/settings/business.ts b/apps/server/src/resources/system/settings/business.ts index 5e562353b0..2eae92d594 100644 --- a/apps/server/src/resources/system/settings/business.ts +++ b/apps/server/src/resources/system/settings/business.ts @@ -4,6 +4,6 @@ import { upsertSystemSetting as upsertSystemSettingQuery, } from './queries.js' -export const getSystemSettings = (key?: string) => getSystemSettingsQuery({ key }) +export const getSystemSettings = async (key?: string) => getSystemSettingsQuery({ key }) -export const upsertSystemSetting = (newSystemSetting: UpsertSystemSettingBody) => upsertSystemSettingQuery(newSystemSetting) +export const upsertSystemSetting = async (newSystemSetting: UpsertSystemSettingBody) => upsertSystemSettingQuery(newSystemSetting) diff --git a/apps/server/src/resources/system/settings/queries.ts b/apps/server/src/resources/system/settings/queries.ts index c64cb3b74c..ffa1f2692a 100644 --- a/apps/server/src/resources/system/settings/queries.ts +++ b/apps/server/src/resources/system/settings/queries.ts @@ -1,7 +1,7 @@ import type { Prisma, SystemSetting } from '@prisma/client' import prisma from '@/prisma.js' -export function upsertSystemSetting(newSystemSetting: SystemSetting) { +export async function upsertSystemSetting(newSystemSetting: SystemSetting) { return prisma.systemSetting.upsert({ create: { ...newSystemSetting, @@ -15,4 +15,4 @@ export function upsertSystemSetting(newSystemSetting: SystemSetting) { }) } -export const getSystemSettings = (where?: Prisma.SystemSettingWhereInput) => prisma.systemSetting.findMany({ where }) +export const getSystemSettings = async (where?: Prisma.SystemSettingWhereInput) => prisma.systemSetting.findMany({ where }) diff --git a/apps/server/src/resources/user/queries.ts b/apps/server/src/resources/user/queries.ts index 1e33a8128b..4906bfbf87 100644 --- a/apps/server/src/resources/user/queries.ts +++ b/apps/server/src/resources/user/queries.ts @@ -4,7 +4,7 @@ import prisma from '@/prisma.js' type UserCreate = Omit // SELECT -export const getUsers = (where?: Prisma.UserWhereInput) => prisma.user.findMany({ where }) +export const getUsers = async (where?: Prisma.UserWhereInput) => prisma.user.findMany({ where }) export async function getUserInfos(id: User['id']) { return prisma.user.findMany({ @@ -15,24 +15,24 @@ export async function getUserInfos(id: User['id']) { }) } -export function getMatchingUsers(where: Prisma.UserWhereInput) { +export async function getMatchingUsers(where: Prisma.UserWhereInput) { return prisma.user.findMany({ where, take: 5, }) } -export function getUserById(id: User['id']) { +export async function getUserById(id: User['id']) { return prisma.user.findUnique({ where: { id } }) } -export function getUserOrThrow(id: User['id']) { +export async function getUserOrThrow(id: User['id']) { return prisma.user.findUniqueOrThrow({ where: { id }, }) } -export function getUserByEmail(email: User['email']) { +export async function getUserByEmail(email: User['email']) { return prisma.user.findUnique({ where: { email } }) } @@ -55,6 +55,6 @@ export async function updateUserById({ id, email, firstName, lastName }: UserCre } // TECH -export function _createUser(data: Prisma.UserCreateInput) { +export async function _createUser(data: Prisma.UserCreateInput) { return prisma.user.upsert({ where: { id: data.id }, create: data, update: data }) } diff --git a/apps/server/src/resources/zone/queries.ts b/apps/server/src/resources/zone/queries.ts index 1390bb153a..1d1f75a085 100644 --- a/apps/server/src/resources/zone/queries.ts +++ b/apps/server/src/resources/zone/queries.ts @@ -1,13 +1,13 @@ import type { Cluster, Zone } from '@prisma/client' import prisma from '@/prisma.js' -export function getZoneByIdOrThrow(id: Zone['id']) { +export async function getZoneByIdOrThrow(id: Zone['id']) { return prisma.zone.findUniqueOrThrow({ where: { id }, }) } -export function linkZoneToClusters(zoneId: Zone['id'], clusterIds: Cluster['id'][]) { +export async function linkZoneToClusters(zoneId: Zone['id'], clusterIds: Cluster['id'][]) { return prisma.zone.update({ where: { id: zoneId, diff --git a/apps/server/src/server.spec.ts b/apps/server/src/server.spec.ts index 5dc093888a..d44dcfc7ea 100644 --- a/apps/server/src/server.spec.ts +++ b/apps/server/src/server.spec.ts @@ -15,7 +15,7 @@ vi.mock('./prepare-app.js', () => { close: vi.fn(async () => {}), } return { - getPreparedApp: () => Promise.resolve(app), + getPreparedApp: async () => Promise.resolve(app), } }) vi.spyOn(logger, 'warn') diff --git a/apps/server/src/telemetry.ts b/apps/server/src/telemetry.ts index 65b59dddab..24ca764b1f 100644 --- a/apps/server/src/telemetry.ts +++ b/apps/server/src/telemetry.ts @@ -22,5 +22,5 @@ const sdk = new NodeSDK({ sdk.start() process.once('beforeExit', () => { - sdk.shutdown() + void sdk.shutdown() }) diff --git a/apps/server/src/utils/business.ts b/apps/server/src/utils/business.ts index 10fe3ced2f..22f8ab43ad 100644 --- a/apps/server/src/utils/business.ts +++ b/apps/server/src/utils/business.ts @@ -11,11 +11,11 @@ export class Result { ) {} static succeed(value: T): Success { - return new Result(true, value) as Success + return new Result(true, value) } - static fail(message: string): Failure { - return new Result(false, message) as Failure + static fail(message: string): Result { + return new Result(false, message) } get isSuccess(): boolean { diff --git a/apps/server/src/utils/controller.ts b/apps/server/src/utils/controller.ts index 57ab7865af..74a742b8d8 100644 --- a/apps/server/src/utils/controller.ts +++ b/apps/server/src/utils/controller.ts @@ -83,7 +83,7 @@ export async function authUser(req: FastifyRequest, projectUnique: ProjectUnique export async function authUser(req: FastifyRequest, projectUnique?: ProjectUniqueFinder): Promise { let adminPermissions: bigint = 0n let tokenId: string | undefined - const reqUser: UserTrial = req.session.user as unknown as UserTrial + const reqUser = req.session.user as UserTrial satisfies UserTrial let user: UserDetails | undefined if (req.session.user) { diff --git a/apps/server/src/utils/hook-wrapper.spec.ts b/apps/server/src/utils/hook-wrapper.spec.ts index c2f4e3ebcc..b89f68d72b 100644 --- a/apps/server/src/utils/hook-wrapper.spec.ts +++ b/apps/server/src/utils/hook-wrapper.spec.ts @@ -1,4 +1,4 @@ -import type { KubeCluster, KubeUser, Project as ProjectPayload, Store } from '@cpn-console/hooks' +import type { Project as ProjectPayload, Store } from '@cpn-console/hooks' import type { ProjectInfos, ReposCreds } from './hook-wrapper.ts' import { describe, expect, it } from 'vitest' import { transformToHookProject } from './hook-wrapper.ts' @@ -215,8 +215,8 @@ describe('transformToHookProject', () => { // Assert sur la transformation des clusters expect(result.clusters).toEqual([associatedCluster, nonAssociatedCluster].map(({ kubeconfig, ...cluster }) => ({ - user: kubeconfig.user as unknown as KubeUser, - cluster: kubeconfig.cluster as unknown as KubeCluster, + user: kubeconfig.user, + cluster: kubeconfig.cluster, ...cluster, privacy: cluster.privacy, }))) diff --git a/apps/server/src/utils/hook-wrapper.ts b/apps/server/src/utils/hook-wrapper.ts index 0df3d89a4b..f7abd77472 100644 --- a/apps/server/src/utils/hook-wrapper.ts +++ b/apps/server/src/utils/hook-wrapper.ts @@ -146,17 +146,17 @@ async function manageProjectStatus(projectId: Project['id'], hookReply: HookResu const cluster = { upsert: async (clusterId: Cluster['id'], previousZoneId: Cluster['zoneId']) => { const cluster = await getClusterByIdOrThrow(clusterId) - const clusterObject = cluster as unknown as ClusterObject + const clusterObject = cluster as unknown as ClusterObject satisfies ClusterObject const store = dbToObj(await getAdminPlugin()) if (cluster.zoneId !== previousZoneId) { // Upsert on the old zone to remove cluster const previousClusterObject = { ...cluster, - } as unknown as ClusterObject + } as unknown as ClusterObject satisfies ClusterObject previousClusterObject.zone = await getZoneByIdOrThrow(previousZoneId) previousClusterObject.zone.clusterNames = await getClusterNamesByZoneId(previousZoneId) const hookResult = await hooks.upsertCluster.execute({ - ...cluster.kubeconfig as unknown as Pick, + ...cluster.kubeconfig as unknown as Pick satisfies Pick, ...previousClusterObject, }, store) if (hookResult.failed) { @@ -165,18 +165,18 @@ const cluster = { } clusterObject.zone.clusterNames = await getClusterNamesByZoneId(cluster.zoneId) return hooks.upsertCluster.execute({ - ...cluster.kubeconfig as unknown as Pick, + ...cluster.kubeconfig as unknown as Pick satisfies Pick, ...clusterObject, }, store) }, delete: async (clusterId: Cluster['id']) => { const cluster = await getClusterByIdOrThrow(clusterId) - const clusterObject = cluster as unknown as ClusterObject + const clusterObject = cluster as unknown as ClusterObject satisfies ClusterObject const clusterNames = await getClusterNamesByZoneId(cluster.zoneId) clusterObject.zone.clusterNames = clusterNames.filter(c => c !== cluster.label) const store = dbToObj(await getAdminPlugin()) return hooks.deleteCluster.execute({ - ...cluster.kubeconfig as unknown as ClusterObject, + ...cluster.kubeconfig as unknown as ClusterObject satisfies ClusterObject, ...clusterObject, }, store) }, @@ -214,7 +214,7 @@ const projectMember = { firstName: member.user.firstName, lastName: member.user.lastName, email: member.user.email, - type: member.user.type as 'human' | 'bot' | 'ghost', + type: member.user.type, createdAt: member.user.createdAt.toISOString(), updatedAt: member.user.updatedAt.toISOString(), lastLogin: member.user.lastLogin?.toISOString(), @@ -249,7 +249,7 @@ const projectMember = { firstName: member.user.firstName, lastName: member.user.lastName, email: member.user.email, - type: member.user.type as 'human' | 'bot' | 'ghost', + type: member.user.type, createdAt: member.user.createdAt.toISOString(), updatedAt: member.user.updatedAt.toISOString(), lastLogin: member.user.lastLogin?.toISOString(), @@ -365,8 +365,8 @@ export const hook = { function formatClusterInfos({ kubeconfig, ...cluster }: Omit & { kubeconfig: Kubeconfig, zone: Pick }) { return { - user: kubeconfig.user as unknown as KubeUser, - cluster: kubeconfig.cluster as unknown as KubeCluster, + user: kubeconfig.user as unknown as KubeUser satisfies KubeUser, + cluster: kubeconfig.cluster as unknown as KubeCluster satisfies KubeCluster, ...cluster, privacy: cluster.privacy, } diff --git a/apps/server/src/utils/proxy.spec.ts b/apps/server/src/utils/proxy.spec.ts index 7fdc203833..9f32a0cee2 100644 --- a/apps/server/src/utils/proxy.spec.ts +++ b/apps/server/src/utils/proxy.spec.ts @@ -97,7 +97,7 @@ describe('test calls with ID passed', () => { it('calling method with exclusion in progress', async () => { const proxied = genericProxy(target, { fetchData: ['otherMethod'] }) // Simuler une exécution en cours pour la méthode exclue - proxied.otherMethod('456') + void proxied.otherMethod('456') // Maintenant, tenter d'appeler fetchData pour le même ID devrait échouer await expect(proxied.fetchData('456')).rejects.toThrow( @@ -148,7 +148,7 @@ describe('test calls with ID passed', () => { // Tentative de définir une nouvelle propriété sur le proxy const setAttempt = () => { - proxied.fetchData = () => new Promise(resolve => resolve('illegal')) + proxied.fetchData = async () => new Promise(resolve => resolve('illegal')) } // Vérification que la tentative de set est rejetée diff --git a/apps/server/src/utils/proxy.ts b/apps/server/src/utils/proxy.ts index ef915a7d15..535de60a8a 100644 --- a/apps/server/src/utils/proxy.ts +++ b/apps/server/src/utils/proxy.ts @@ -14,13 +14,13 @@ export function genericProxy(proxied: T, excludes: Excludes = {}): T { get({ methods, tracker }, property: string) { if (!(property in methods)) return return async (...args) => { - const id = args[0] as string + const id = args[0] as string | undefined - if (!id && args.length > 0) { + if (id != null && args.length > 0) { throw new Error('ID is required when args are provided') } - if (!id) { + if (id == null) { if (tracker[property] instanceof Promise) { return tracker[property] } @@ -29,37 +29,36 @@ export function genericProxy(proxied: T, excludes: Excludes = {}): T { tracker[property] = p p.then(() => { delete tracker[property] - }) + }).catch(() => {}) } return p } - if (!tracker[property]) { + if (tracker[property] == null) { tracker[property] = {} } for (const testExclude of excludes[property] ?? []) { - // @ts-ignore - if (tracker?.[testExclude]?.[id]?.currentExec) { + if (tracker[testExclude]?.[id]?.currentExec) { throw new Error(`${String(testExclude)} in progress on ${id}, can't ${String(property)}`) } } if (id in tracker[property]) { - if (args[1]) { + if (args[1] != null) { tracker[property][id].nextArgs = { ...(tracker[property][id].nextArgs ?? {}), ...args[1], } } - if (tracker[property][id].currentExec) { + if (tracker[property][id].currentExec != null) { return new Promise((resolve) => { - tracker[property][id].currentExec.then(() => { + tracker[property][id].currentExec!.then(() => { resolve(tracker[property][id].currentExec ?? methods[property](id, tracker[property][id].nextArgs)) }) }) } } - const p = methods[property](...args) + const p = methods[property](...(args as [string, ...unknown[]])) tracker[property][id] = { currentExec: p, nextArgs: undefined, @@ -67,7 +66,7 @@ export function genericProxy(proxied: T, excludes: Excludes = {}): T { tracker[property][id].currentExec = p p.then(() => { tracker[property][id].currentExec = undefined - }) + }).catch(() => {}) return p } }, diff --git a/apps/server/tsconfig.eslint.json b/apps/server/tsconfig.eslint.json new file mode 100644 index 0000000000..96e186b94b --- /dev/null +++ b/apps/server/tsconfig.eslint.json @@ -0,0 +1,19 @@ +{ + "extends": ["./tsconfig.json"], + "compilerOptions": { + "rootDir": "." + }, + "include": [ + "./**/*.ts", + "./**/*.js", + "./**/*.cjs", + "./**/*.mjs" + ], + "exclude": [ + "./node_modules", + "./dist", + "./types", + "./coverage", + "./**/*.d.ts" + ] +} diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index a3397898ca..e40e0fa2ad 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -8,7 +8,6 @@ "paths": { "@/*": ["src/*"] }, - "useUnknownInCatchVariables": false, "declarationDir": "./types", "outDir": "./dist", "plugins": [{ "transform": "typescript-transform-paths" }] diff --git a/packages/eslintconfig/src/index.js b/packages/eslintconfig/src/index.js index 79867556e6..ec45ab313d 100644 --- a/packages/eslintconfig/src/index.js +++ b/packages/eslintconfig/src/index.js @@ -16,7 +16,15 @@ export default antfu( 'ts/ban-ts-comment': 'off', }, }, - typescript: true, + typescript: { + tsconfigPath: 'tsconfig.json', + parserOptions: { + tsconfigRootDir: process.cwd(), + projectService: { + allowDefaultProject: ['*.js', '*.cjs', '*.mjs'], + }, + }, + }, vue: true, yaml: { overrides: { diff --git a/packages/hooks/src/config.ts b/packages/hooks/src/config.ts index ab1a702bf9..413fd8e881 100644 --- a/packages/hooks/src/config.ts +++ b/packages/hooks/src/config.ts @@ -23,7 +23,7 @@ export const editStrippersGenerator = pluginConfig.transform((arg) => { } } - for (const item of arg.global || []) { + for (const item of arg.global ?? []) { if (item.permissions.admin.write) { const zAny = atomicValidators[item.kind].optional() global = global.merge(z.object({ [item.key]: zAny })) diff --git a/packages/hooks/src/hooks/hook.ts b/packages/hooks/src/hooks/hook.ts index 1377d9abcc..be18ea8363 100644 --- a/packages/hooks/src/hooks/hook.ts +++ b/packages/hooks/src/hooks/hook.ts @@ -8,6 +8,7 @@ export type PluginResultStore = Record export interface PluginResult { status: { result: 'OK', message?: string } | { result: 'KO' | 'WARNING', message: string } store?: PluginResultStore + executionTime?: Record [key: string]: any } @@ -52,13 +53,13 @@ function generateMessageResume(payload: HookPayload( const result = settled.status === 'fulfilled' ? handleFulfilledStepResult(settled.value, name, stepName, payload) : handleRejectedStepResult(settled.reason, name, stepName, payload) - return { ...result, executionTime: payload.results[name].executionTime } + return result } export async function executeStep(step: HookStep, payload: HookPayload, stepName: string) { const names = Object.keys(step) const fns = names.map(async (name) => { - if (payload.results[name]?.executionTime) { - payload.results[name].executionTime[stepName] = Date.now() + const existingResult = payload.results[name] + if (existingResult !== undefined) { + if (existingResult.executionTime !== undefined) { + existingResult.executionTime[stepName] = Date.now() + } else { + existingResult.executionTime = { [stepName]: Date.now() } + } } else { payload.results[name] = { status: { result: 'OK' }, executionTime: { [stepName]: Date.now() }, } } - const fnResult = await step[name](payload) - payload.results[name].executionTime[stepName] = Date.now() - payload.results[name].executionTime[stepName] + const fnResult = await step[name]!(payload) + const resultEntry = payload.results[name]! + resultEntry.executionTime = resultEntry.executionTime ?? {} + resultEntry.executionTime[stepName] = Date.now() - (resultEntry.executionTime[stepName] ?? 0) return fnResult }) const results = await Promise.allSettled(fns) names.forEach((name, index) => { - payload.results[name] = handleStepResult(results[index], name, stepName, payload) + payload.results[name] = handleStepResult(results[index]!, name, stepName, payload) }) return payload } @@ -164,7 +172,7 @@ export function createHook(unique = false) { const executeSteps = ['pre', 'main', 'post'] as const for (const step of executeSteps) { payload = await executeStep(steps[step], payload, step) - if (payload.failed) { + if (payload.failed === true) { payload = await executeStep(steps.revert, payload, 'revert') break } diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index ad4af3bca8..6012d503e1 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -63,7 +63,7 @@ function pluginManager(options: PluginManagerOptions): PluginManager { plugin.monitor.monitorFn = async (instance: Monitor) => instance.lastStatus } if (plugin.monitor) - plugin.monitor.refresh() + void plugin.monitor.refresh() servicesInfos[plugin.infos.name] = { ...plugin.infos, monitor: plugin.monitor, diff --git a/packages/hooks/src/services.ts b/packages/hooks/src/services.ts index dce8693564..39cf9d7149 100644 --- a/packages/hooks/src/services.ts +++ b/packages/hooks/src/services.ts @@ -31,10 +31,12 @@ export const services = { return [...acc, { ...serviceInfos.monitor.lastStatus, name: serviceInfos.title }] }, [] as Array) }, - refreshStatus: (): Array> => { - // @ts-ignore obligé d'ignore TS ne comprend pas l'interet du filter - return Object.values(servicesInfos) - .filter(servicesInfos => servicesInfos.monitor) - .map(serviceInfos => serviceInfos.monitor?.refresh()) + refreshStatus: async (): Promise => { + const results = await Promise.all( + Object.values(servicesInfos) + .filter(serviceInfos => serviceInfos.monitor) + .map(async serviceInfos => serviceInfos.monitor!.refresh()), + ) + return results }, } diff --git a/packages/hooks/src/utils/plugin-result-handler.ts b/packages/hooks/src/utils/plugin-result-handler.ts index a90261aede..1e703ccaef 100644 --- a/packages/hooks/src/utils/plugin-result-handler.ts +++ b/packages/hooks/src/utils/plugin-result-handler.ts @@ -8,12 +8,12 @@ export class PluginResultBuilder { public store: PluginResultStore = {} constructor(okMessage: string | undefined) { - if (okMessage) { + if (okMessage != null && okMessage !== '') { this.okMessages.push(okMessage) } } - addExtra(key: string, value: any) { + addExtra(key: string, value: unknown) { this.extras[key] = value return this } diff --git a/packages/hooks/src/utils/utils.ts b/packages/hooks/src/utils/utils.ts index 65d03954c2..fd8faa10da 100644 --- a/packages/hooks/src/utils/utils.ts +++ b/packages/hooks/src/utils/utils.ts @@ -7,7 +7,7 @@ export function objectEntries>(obj: Obj): ([ return Object.entries(obj) as ([keyof Obj, Obj[keyof Obj]])[] } export function objectKeys>(obj: Obj): (keyof Obj)[] { - return Object.keys(obj) as (keyof Obj)[] + return Object.keys(obj) } export function objectValues>(obj: Obj): (Obj[keyof Obj])[] { return Object.values(obj) as (Obj[keyof Obj])[] @@ -21,11 +21,11 @@ export type DeclareModuleGenerator value ? [ENABLED, DEFAULT].includes(value) : true -export const disabledOrDefaultOrNullish = (value?: string): boolean | undefined => value ? [DISABLED, DEFAULT].includes(value) : true -export const specificallyDisabled = (value?: string): boolean | undefined => value ? value === DISABLED : undefined -export const specificallyEnabled = (value?: string): boolean | undefined => value ? value === ENABLED : undefined -export const defaultOrNullish = (value?: string): boolean | undefined => value ? DEFAULT === value : true +export const enabledOrDefaultOrNullish = (value?: string): boolean | undefined => value != null && [ENABLED, DEFAULT].includes(value) +export const disabledOrDefaultOrNullish = (value?: string): boolean | undefined => value != null && [DISABLED, DEFAULT].includes(value) +export const specificallyDisabled = (value?: string): boolean | undefined => value != null && value === DISABLED +export const specificallyEnabled = (value?: string): boolean | undefined => value != null && value === ENABLED +export const defaultOrNullish = (value?: string): boolean | undefined => value != null && DEFAULT === value export const okStatus = { status: { result: 'OK' } } as const diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index cf2a6e2397..d7cf6e8a19 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -44,6 +44,7 @@ const redact: LoggerOptions['redact'] = { export function getLoggerOptions(env: Env, level: LogLevel): LoggerOptions { switch (env) { case 'development': + case 'test': return { transport: { target: 'pino-pretty', diff --git a/packages/logger/tsconfig.eslint.json b/packages/logger/tsconfig.eslint.json index 982c60cf77..5d2d3b5fc8 100644 --- a/packages/logger/tsconfig.eslint.json +++ b/packages/logger/tsconfig.eslint.json @@ -1,5 +1,8 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "." + }, "include": [ "./**/*.ts", "./**/*.js", diff --git a/packages/shared/src/schemas/repository.ts b/packages/shared/src/schemas/repository.ts index 85675b9123..0d5cb16d5c 100644 --- a/packages/shared/src/schemas/repository.ts +++ b/packages/shared/src/schemas/repository.ts @@ -41,15 +41,15 @@ export const UpdateRepoFormSchema = RepoFormSchema .refine( ({ isPrivate, externalToken, externalUserName }) => { if (isPrivate) { - if (!externalToken && !externalUserName) return false - return true + if ((externalToken != null && externalToken !== '') || (externalUserName != null && externalUserName !== '')) return true + return false } return true }, { message: missingCredentials, path: ['credentials'] }, ) .refine(({ isStandalone, externalRepoUrl }) => { - if (!isStandalone && !externalRepoUrl) { + if (!isStandalone && (externalRepoUrl == null || externalRepoUrl === '')) { return false } return true @@ -59,13 +59,13 @@ export const CreateRepoFormSchema = RepoFormSchema .omit({ id: true, projectId: true }) .refine(({ isPrivate, externalToken, externalUserName }) => { if (isPrivate) { - if (!externalToken && !externalUserName) return false - return true + if ((externalToken != null && externalToken !== '') || (externalUserName != null && externalUserName !== '')) return true + return false } return true }, { message: missingCredentials, path: ['credentials'] }) .refine(({ isStandalone, externalRepoUrl }) => { - if (!isStandalone && !externalRepoUrl) { + if (!isStandalone && (externalRepoUrl == null || externalRepoUrl === '')) { return false } return true diff --git a/packages/shared/src/utils/functions.ts b/packages/shared/src/utils/functions.ts index f38778f36d..43a97376f1 100644 --- a/packages/shared/src/utils/functions.ts +++ b/packages/shared/src/utils/functions.ts @@ -108,7 +108,8 @@ function excludeCircular(value: unknown, keys: string[], inPath: WeakSet if ('toJSON' in value && typeof value.toJSON === 'function') { try { - const serialized = value.toJSON() + const toJSON = value as { toJSON: () => unknown } + const serialized: unknown = toJSON.toJSON() const out = excludeCircular(serialized, keys, inPath, inArray) inPath.delete(value) return out @@ -118,9 +119,11 @@ function excludeCircular(value: unknown, keys: string[], inPath: WeakSet } } - const proto = Object.getPrototypeOf(value) + const proto = Object.getPrototypeOf(value) as object | null if (proto !== Object.prototype && proto !== null) { - const ctorName = (value as any)?.constructor?.name + const ctorName = typeof proto === 'object' && proto !== null && 'constructor' in proto + ? (proto as { constructor?: { name?: unknown } }).constructor?.name + : undefined const tag = typeof ctorName === 'string' && ctorName.length ? ctorName : 'Object' try { const s = String(value) @@ -134,6 +137,9 @@ function excludeCircular(value: unknown, keys: string[], inPath: WeakSet } const obj = value as Record + if (typeof obj !== 'object' || obj === null) { + return String(value) + } const newObj: Record = {} for (const [k, v] of Object.entries(obj)) { if (keys.includes(k)) continue @@ -160,7 +166,7 @@ export function objectEntries>(obj: Obj): ([ return Object.entries(obj) as ([keyof Obj, Obj[keyof Obj]])[] } export function objectKeys>(obj: Obj): (keyof Obj)[] { - return Object.keys(obj) as (keyof Obj)[] + return Object.keys(obj) } export function objectValues>(obj: Obj): (Obj[keyof Obj])[] { return Object.values(obj) as (Obj[keyof Obj])[] @@ -168,7 +174,7 @@ export function objectValues>(obj: Obj): (Ob export function requiredEnv(envName: string): string { const envValue = process.env[envName] - if (envValue) return envValue + if (envValue !== undefined) return envValue throw new Error(`env: ${envName} is not defined !`) } @@ -282,8 +288,8 @@ const uuidTranslator = shortUUID(shortUUID.constants.uuid25Base36, { consistentLength: false, }) -export const compressUUID = uuidTranslator.fromUUID -export const expandUUID = uuidTranslator.toUUID +export const compressUUID = uuidTranslator.fromUUID.bind(uuidTranslator) +export const expandUUID = uuidTranslator.toUUID.bind(uuidTranslator) export function generateNamespaceName(projectId: string, envId: string) { return `${compressUUID(envId)}--${compressUUID(projectId)}` diff --git a/packages/shared/src/utils/permissions.ts b/packages/shared/src/utils/permissions.ts index 040fbf55d1..5eaf9d72e6 100644 --- a/packages/shared/src/utils/permissions.ts +++ b/packages/shared/src/utils/permissions.ts @@ -20,23 +20,24 @@ import { logger as baseLogger } from '@cpn-console/logger' const logger = baseLogger.child({ scope: 'utils:permissions' }) export function getPermsByUserRoles(userRoles: string[] | undefined, rolesById: ResourceById<{ id: string, permissions: bigint | string }>, basePerms?: bigint | string) { - if (!userRoles) { - return basePerms ? BigInt(basePerms) : 0n + if (userRoles === undefined) { + return basePerms != null ? BigInt(basePerms) : 0n } return userRoles.reduce((acc, curr) => { - if (!rolesById[curr]) { + const role = rolesById[curr] + if (role === undefined) { logger.warn(`Role ${curr} not found in rolesById`) return acc } - return acc | BigInt(rolesById[curr].permissions) - }, basePerms ? BigInt(basePerms) : 0n) + return acc | BigInt(role.permissions) + }, basePerms != null ? BigInt(basePerms) : 0n) } function permissionsParser(a: Record) { const valuesRegistered = [] as bigint[] for (const [k, v] of Object.entries(a)) { if (typeof v !== 'bigint') - throw new Error(`${k} has a invalid value: ${v}, which is not a bigint`) + throw new Error(`${k} has a invalid value: ${String(v)}, which is not a bigint`) if (valuesRegistered.includes(v)) throw new Error(`${k} has a duplicated value: ${v}`) valuesRegistered.push(v) @@ -93,7 +94,7 @@ permissionsParser(PROJECT_PERMS) interface ProjectAuthorizedParams { adminPermissions?: bigint | string | null, projectPermissions?: bigint | string } -export const toBigInt = (value?: bigint | number | string | undefined | null) => value ? BigInt(value) : 0n +export const toBigInt = (value?: bigint | number | string | undefined | null) => value != null ? BigInt(value) : 0n export const AdminAuthorized = { Manage: (perms?: bigint | string | null) => !!(toBigInt(perms) & ADMIN_PERMS.MANAGE), diff --git a/packages/shared/src/utils/plugins.ts b/packages/shared/src/utils/plugins.ts index fd907ad899..15fffea4f3 100644 --- a/packages/shared/src/utils/plugins.ts +++ b/packages/shared/src/utils/plugins.ts @@ -20,7 +20,7 @@ export class Monitor { constructor(callback: (instance: Monitor) => Promise, interval: number = 5 * 60 * 1000) { this.intervalTime = interval - this.monitorFn = () => { + this.monitorFn = async () => { this.lastStatus.cause = undefined return callback(this) } @@ -36,7 +36,9 @@ export class Monitor { async refresh() { if (this.intervalID) clearInterval(this.intervalID) - this.intervalID = setInterval(() => this.monitorFn(this), this.intervalTime) + this.intervalID = setInterval(() => { + void this.monitorFn(this) + }, this.intervalTime) return this.monitorFn(this) } } diff --git a/packages/shared/src/utils/roles.ts b/packages/shared/src/utils/roles.ts index 3512475e8e..fff51b06a3 100644 --- a/packages/shared/src/utils/roles.ts +++ b/packages/shared/src/utils/roles.ts @@ -9,7 +9,7 @@ export function isSystemRoleType(type: string | null | undefined) { } export function getBaseRoleType(type: string | null | undefined) { - if (!type) return undefined + if (type == null) return undefined return isSystemRoleType(type) ? type.slice(`${SYSTEM_ROLE_TYPE}:`.length) : type } diff --git a/packages/shared/src/utils/schemas.ts b/packages/shared/src/utils/schemas.ts index 7330fa943e..e69bbf186b 100644 --- a/packages/shared/src/utils/schemas.ts +++ b/packages/shared/src/utils/schemas.ts @@ -1,20 +1,16 @@ // import Joi from 'joi' -import type { SafeParseReturnType, ZodError, ZodObject } from 'zod' +import type { SafeParseReturnType, ZodError, ZodObject, ZodRawShape } from 'zod' import { fromZodError } from 'zod-validation-error' export type SharedZodError = ZodError export type SharedSafeParseReturnType = SafeParseReturnType export const parseZodError = (zodError: ZodError) => fromZodError(zodError).toString() -export function instanciateSchema, V extends boolean>(schema: T, value: V): Record { - const keys = schema.keyof()._def.values - // @ts-ignore +export function instanciateSchema, V extends boolean>(schema: T, value: V): Record { + const keys = Object.keys(schema.shape) if (keys.length) { - // @ts-ignore - const entries = schema.keyof()._def.values?.map(key => [key, value]) - // @ts-ignore - return Object.fromEntries(entries) + const entries = keys.map(key => [key, value]) + return Object.fromEntries(entries) as Record } - // @ts-ignore - return {} + return {} as Record } diff --git a/packages/shared/tsconfig.eslint.json b/packages/shared/tsconfig.eslint.json index 982c60cf77..5ff8d9ddce 100644 --- a/packages/shared/tsconfig.eslint.json +++ b/packages/shared/tsconfig.eslint.json @@ -1,5 +1,8 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "." + }, "include": [ "./**/*.ts", "./**/*.js", @@ -7,8 +10,6 @@ "./**/*.mjs" ], "exclude": [ - "./node_modules", - "./dist", "./types", "./coverage", "./**/*.d.ts" diff --git a/packages/shared/tsconfig.vitest.json b/packages/shared/tsconfig.vitest.json new file mode 100644 index 0000000000..18f5db455e --- /dev/null +++ b/packages/shared/tsconfig.vitest.json @@ -0,0 +1,7 @@ +{ + "extends": ["./tsconfig.base.json"], + "compilerOptions": { + "strictNullChecks": true + }, + "include": ["./vitest.config.ts"] +} diff --git a/packages/test-utils/src/utils/random-project.ts b/packages/test-utils/src/utils/random-project.ts index 73dcdf40bb..9ff429195f 100644 --- a/packages/test-utils/src/utils/random-project.ts +++ b/packages/test-utils/src/utils/random-project.ts @@ -27,7 +27,7 @@ export function createRandomDbSetup({ nbUsers = 1, nbRepo = 3, envs = basicStage ...getRandomRole(user.id, project.id), user, })) - project.roles[0].role = projectRoles[0] + project.roles[0]!.role = projectRoles[0] const ownerId = project.roles.find(role => role.role === 'owner')?.userId // @ts-ignore @@ -43,7 +43,7 @@ export function createRandomDbSetup({ nbUsers = 1, nbRepo = 3, envs = basicStage const zones = [getRandomZone()] // Create cluster - const clusters = [getRandomCluster({ projectIds: [project.id], zoneId: zones[0].id })] + const clusters = [getRandomCluster({ projectIds: [project.id], zoneId: zones[0]!.id })] // @ts-ignore project.clusters = clusters @@ -59,7 +59,7 @@ export function createRandomDbSetup({ nbUsers = 1, nbRepo = 3, envs = basicStage // Create environment project.environments = envs - .map(env => getRandomEnv(env, project.id, stages[0].id, clusters[0].id)) + .map(env => getRandomEnv(env, project.id, stages[0]!.id, clusters[0]!.id)) // Create permissions project.environments.forEach((env) => { diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json index f90b7b4aee..a65d466aee 100644 --- a/packages/tsconfig/package.json +++ b/packages/tsconfig/package.json @@ -12,5 +12,9 @@ "registry": "https://registry.npmjs.org/", "access": "public", "tag": "latest" + }, + "devDependencies": { + "@tsconfig/node24": "catalog:", + "@tsconfig/strictest": "catalog:" } } \ No newline at end of file diff --git a/packages/tsconfig/tsconfig.base.json b/packages/tsconfig/tsconfig.base.json index 6a08a00241..c90fffa428 100644 --- a/packages/tsconfig/tsconfig.base.json +++ b/packages/tsconfig/tsconfig.base.json @@ -1,43 +1,34 @@ { + "extends": ["@tsconfig/node24", "@tsconfig/strictest"], "compilerOptions": { - "incremental": true, - // Module - "target": "ESNext", - "jsx": "preserve", - "lib": ["ESNext"], - "module": "NodeNext", "moduleResolution": "NodeNext", - - // Base - "paths": { - "@/*": [ - "src/*" - ] - }, - "resolveJsonModule": true, - - "allowImportingTsExtensions": false, - "allowJs": true, - // Best practices - "strict": true, "strictNullChecks": true, "alwaysStrict": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, - "noPropertyAccessFromIndexSignature": false, "noUnusedLocals": true, "noUnusedParameters": true, - // Some stricter flags - "useUnknownInCatchVariables": false, + "useUnknownInCatchVariables": true, + "noUncheckedIndexedAccess": true, "declaration": true, - "emitDeclarationOnly": false, - // Output + "declarationDir": "./types", "noEmit": false, "sourceMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, - "skipLibCheck": true + "skipLibCheck": true, + "paths": { + "@/*": ["src/*"] + }, + "resolveJsonModule": true, + "allowImportingTsExtensions": false, + "allowJs": true, + "jsx": "preserve", + "lib": ["ESNext"], + "target": "ESNext", + "module": "NodeNext", + "incremental": true } -} +} \ No newline at end of file diff --git a/playwright/tsconfig.json b/playwright/tsconfig.json index f9908dab99..03aeb4bb16 100644 --- a/playwright/tsconfig.json +++ b/playwright/tsconfig.json @@ -1,40 +1,14 @@ { "extends": ["@cpn-console/ts-config/tsconfig.base.json"], "compilerOptions": { - "incremental": true, - // Module - "target": "ESNext", - - "jsx": "preserve", - "lib": ["DOM", "ESNext"], - // Base "baseUrl": "./", "rootDir": "./", "module": "Preserve", "moduleResolution": "Bundler", "resolveJsonModule": true, "types": ["node"], - "allowImportingTsExtensions": false, - "allowJs": true, - "strict": true, - "strictNullChecks": true, - "alwaysStrict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noPropertyAccessFromIndexSignature": false, - "noUnusedLocals": true, - "noUnusedParameters": true, - "useUnknownInCatchVariables": true, - "declaration": true, "declarationDir": "./types", - "emitDeclarationOnly": false, - "noEmit": false, - "outDir": "./dist", - "sourceMap": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "skipLibCheck": true + "outDir": "./dist" }, "include": ["./playwright.config.ts", "./config/**/*.ts", "./e2e-tests/**/*.ts", "./helpers/**/*.ts", "./integration-tests/**/*.ts"], "exclude": [] diff --git a/plugins/keycloak/src/functions.ts b/plugins/keycloak/src/functions.ts index 9bf08d971d..17ca34ddf0 100644 --- a/plugins/keycloak/src/functions.ts +++ b/plugins/keycloak/src/functions.ts @@ -177,15 +177,16 @@ export const upsertZone: StepCall = async ({ args: zone, apis }) => } const result = await kcClient.clients.find({ clientId, max: 1 }) let outcome: 'updated' | 'created' - if (result.length > 0 && result[0].id) { - await kcClient.clients.update({ id: result[0].id }, client) + const existing = result[0]! + if (existing.id) { + await kcClient.clients.update({ id: existing.id }, client) outcome = 'updated' } else { const password = generateRandomPassword(30) await apis.vault.write({ clientSecret: password }, 'keycloak') await kcClient.clients.create({ secret: password, - ...client, + ...existing, }) outcome = 'created' } @@ -214,8 +215,9 @@ export const deleteZone: StepCall = async ({ args: zone }) => { const kcClient = await getkcClient() const clientId = getClientZoneId(zone) const result = await kcClient.clients.find({ clientId, max: 1 }) - if (result.length > 0 && result[0].id) { - await kcClient.clients.del({ id: result[0].id }) + const existing = result[0]! + if (existing.id) { + await kcClient.clients.del({ id: existing.id }) logger.info({ action: 'deleteZone', zoneSlug, clientId, outcome: 'deleted' }, 'Hook done') return { status: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 207480b3f4..ac8f25f4eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,6 +67,13 @@ catalogs: workbox-window: specifier: ^7.4.0 version: 7.4.0 + default: + '@tsconfig/node24': + specifier: ^24.0.4 + version: 24.0.4 + '@tsconfig/strictest': + specifier: ^2.0.8 + version: 2.0.8 otel: '@opentelemetry/api': specifier: ^1.9.0 @@ -895,7 +902,7 @@ importers: version: link:../../packages/tsconfig '@darraghor/eslint-plugin-nestjs-typed': specifier: catalog:tools - version: 7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + version: 7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) '@eslint/eslintrc': specifier: catalog:tools version: 3.3.5(supports-color@5.5.0) @@ -1117,7 +1124,14 @@ importers: specifier: catalog:build version: 5.9.3 - packages/tsconfig: {} + packages/tsconfig: + devDependencies: + '@tsconfig/node24': + specifier: 'catalog:' + version: 24.0.4 + '@tsconfig/strictest': + specifier: 'catalog:' + version: 2.0.8 playwright: devDependencies: @@ -4305,6 +4319,12 @@ packages: '@ts-rest/core': ~3.52.0 zod: ^3.22.3 + '@tsconfig/node24@24.0.4': + resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==} + + '@tsconfig/strictest@2.0.8': + resolution: {integrity: sha512-XnQ7vNz5HRN0r88GYf1J9JJjqtZPiHt2woGJOo2dYqyHGGcd6OLGqSlBB6p1j9mpzja6Oe5BoPqWmeDx6X9rLw==} + '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} @@ -10522,11 +10542,11 @@ snapshots: dependencies: postcss-selector-parser: 7.1.1 - '@darraghor/eslint-plugin-nestjs-typed@7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + '@darraghor/eslint-plugin-nestjs-typed@7.2.9(@typescript-eslint/parser@8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3))(class-validator@0.15.1)(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/parser': 8.59.2(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.65.0 - '@typescript-eslint/type-utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3) '@typescript-eslint/utils': 8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3) class-validator: 0.15.1 eslint: 10.5.0(jiti@2.6.1) @@ -12542,7 +12562,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.6.1)) - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/types': 8.65.0 eslint: 10.5.0(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -12588,6 +12608,10 @@ snapshots: openapi3-ts: 2.0.2 zod: 3.25.76 + '@tsconfig/node24@24.0.4': {} + + '@tsconfig/strictest@2.0.8': {} + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 @@ -12795,8 +12819,8 @@ snapshots: '@typescript-eslint/project-service@8.59.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3) + '@typescript-eslint/types': 8.65.0 debug: 4.4.3(supports-color@5.5.0) typescript: 5.9.3 transitivePeerDependencies: @@ -12876,7 +12900,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.65.0(eslint@10.5.0(jiti@2.6.1))(supports-color@5.5.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.65.0 '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 15d16d7d52..d7622d17d4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -164,3 +164,6 @@ catalogs: stylelint-config-standard: ^40.0.0 typescript-eslint: ^8.57.0 vue-eslint-parser: ^10.4.0 +catalog: + '@tsconfig/node24': ^24.0.4 + '@tsconfig/strictest': ^2.0.8 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..8105bc0606 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": ["@cpn-console/ts-config/tsconfig.base.json"], + "include": ["**/*.ts", "**/*.js"], + "exclude": ["node_modules", "dist", "types", "coverage"] +}