diff --git a/app/controllers/configurations_v1_controller.ts b/app/controllers/configurations_v1_controller.ts index ac8513f..b3d3105 100644 --- a/app/controllers/configurations_v1_controller.ts +++ b/app/controllers/configurations_v1_controller.ts @@ -6,7 +6,10 @@ import ConfigurationService, { } from '#services/configuration_service' import ConfigurationEngine from '#services/configuration_engine' import ConfigurationModel from '#models/configuration' -import { createConfigurationValidator, updateConfigurationValidator } from '#validators/configuration' +import { + createConfigurationValidator, + updateConfigurationValidator, +} from '#validators/configuration' import logger from '@adonisjs/core/services/logger' /** @@ -43,7 +46,8 @@ export default class ConfigurationsController { perPage: Number(request.input('perPage', 20)), tag: request.input('tag'), name: request.input('name') || undefined, - enabled: request.input('enabled') !== undefined ? request.input('enabled') === 'true' : undefined, + enabled: + request.input('enabled') !== undefined ? request.input('enabled') === 'true' : undefined, productClass: request.input('productClass'), } @@ -93,11 +97,21 @@ export default class ConfigurationsController { */ async store({ request, response }: HttpContext) { try { - const data = await request.validateUsing(createConfigurationValidator) as CreateConfigurationDto + const data = (await request.validateUsing( + createConfigurationValidator + )) as CreateConfigurationDto // Check for overlaps - const overlapResult = await this.configService.detectOverlap(data.criteria || {}, data.priority) - if (overlapResult && overlapResult.overlappingConfigurations && overlapResult.overlappingConfigurations.length > 0 && !request.input('ignoreOverlap')) { + const overlapResult = await this.configService.detectOverlap( + data.criteria || {}, + data.priority + ) + if ( + overlapResult && + overlapResult.overlappingConfigurations && + overlapResult.overlappingConfigurations.length > 0 && + !request.input('ignoreOverlap') + ) { return response.status(409).json({ message: 'Configuration overlaps with existing ones', overlaps: overlapResult.overlappingConfigurations, @@ -122,7 +136,9 @@ export default class ConfigurationsController { */ async update({ params, request, response }: HttpContext) { try { - const data = await request.validateUsing(updateConfigurationValidator) as UpdateConfigurationDto + const data = (await request.validateUsing( + updateConfigurationValidator + )) as UpdateConfigurationDto // Check for overlaps if priority changed if (data.priority) { @@ -131,13 +147,18 @@ export default class ConfigurationsController { data.priority, params.id ) - if (overlapResult && overlapResult.overlappingConfigurations && overlapResult.overlappingConfigurations.length > 0 && !request.input('ignoreOverlap')) { - return response.status(409).json({ - message: 'Configuration overlaps with existing ones', - overlaps: overlapResult.overlappingConfigurations, - }) + if ( + overlapResult && + overlapResult.overlappingConfigurations && + overlapResult.overlappingConfigurations.length > 0 && + !request.input('ignoreOverlap') + ) { + return response.status(409).json({ + message: 'Configuration overlaps with existing ones', + overlaps: overlapResult.overlappingConfigurations, + }) + } } - } // Update configuration const config = await this.configService.update(params.id, data) @@ -147,7 +168,10 @@ export default class ConfigurationsController { return response.ok(config) } catch (error: any) { - logger.error({ error: error.message, id: params.id }, '[ConfigAPI] Update configuration failed') + logger.error( + { error: error.message, id: params.id }, + '[ConfigAPI] Update configuration failed' + ) if (error.field) { return response.status(422).json({ message: error.message, field: error.field }) } @@ -164,7 +188,10 @@ export default class ConfigurationsController { await this.configService.delete(params.id) return response.status(204).send(null) } catch (error: any) { - logger.error({ error: error.message, id: params.id }, '[ConfigAPI] Delete configuration failed') + logger.error( + { error: error.message, id: params.id }, + '[ConfigAPI] Delete configuration failed' + ) return response.status(500).json({ message: 'Failed to delete configuration' }) } } @@ -182,7 +209,10 @@ export default class ConfigurationsController { } return response.ok(config) } catch (error: any) { - logger.error({ error: error.message, id: params.id }, '[ConfigAPI] Toggle configuration failed') + logger.error( + { error: error.message, id: params.id }, + '[ConfigAPI] Toggle configuration failed' + ) return response.status(500).json({ message: 'Failed to toggle configuration' }) } } diff --git a/app/controllers/cwmp_controller.ts b/app/controllers/cwmp_controller.ts index 03a2f48..bcd7c31 100644 --- a/app/controllers/cwmp_controller.ts +++ b/app/controllers/cwmp_controller.ts @@ -1,17 +1,17 @@ import type { HttpContext } from '@adonisjs/core/http' -import { CWMPMessageBuilder } from '../protocol/common/cwmp_message_builder.js' -import { StateMachineManager } from '../services/cwmp/state_machine_manager.js' -import { Device, detectDataModelFromParams } from '../domain/device/device.js' -import { DeviceId } from '../domain/device/device_id.js' -import { DeviceParameter, DeviceProperty } from '../domain/device/device_parameter.js' -import DeviceModel from '../models/device.js' -import { getDeviceHashIdentifier } from '../utils/device_utils.js' -import { getReferenceEngine } from '../services/references/reference_engine.js' -import { normalizeEventCode } from '../utils/cwmp-events.js' +import { CWMPMessageBuilder } from '#protocol/common/cwmp_message_builder' +import { StateMachineManager } from '#services/cwmp/state_machine_manager' +import { Device, detectDataModelFromParams } from '#domain/device/device' +import { DeviceId } from '#domain/device/device_id' +import { DeviceParameter, DeviceProperty } from '#domain/device/device_parameter' +import DeviceModel from '#models/device' +import { getDeviceHashIdentifier } from '#utils/device_utils' +import { getReferenceEngine } from '#services/references/reference_engine' +import { normalizeEventCode } from '#utils/cwmp-events' import logger from '@adonisjs/core/services/logger' -import type { Inform, CwmpMessage, ParameterValueStruct } from '../protocol/tr069_types.js' -import { ParameterType } from '../domain/shared/types.js' -import { FaultCodeType } from '../protocol/tr069_types.js' +import type { Inform, CwmpMessage, ParameterValueStruct } from '#protocol/tr069_types' +import { ParameterType } from '#domain/shared/types' +import { FaultCodeType } from '#protocol/tr069_types' export default class CwmpController { private static managerInitialized = false diff --git a/app/controllers/devices_controller.ts b/app/controllers/devices_controller.ts index 84a75e1..002e634 100644 --- a/app/controllers/devices_controller.ts +++ b/app/controllers/devices_controller.ts @@ -1,7 +1,7 @@ import type { HttpContext } from '@adonisjs/core/http' import DeviceService from '#services/device_service' -import { PaginationData } from '#services/device_service' -import { CommandType } from '../domain/commands/command.js' +import { type PaginationData } from '#services/device_service' +import { type CommandType } from '#domain/commands/command' import DeviceModel from '#models/device' export default class DevicesController { @@ -77,10 +77,14 @@ export default class DevicesController { const parts: string[] = [] if (pager.first) { - parts.push(`<${baseUrl}?offset=${pager.first.offset}&limit=${pager.first.limit}>; rel="first"`) + parts.push( + `<${baseUrl}?offset=${pager.first.offset}&limit=${pager.first.limit}>; rel="first"` + ) } if (pager.previous) { - parts.push(`<${baseUrl}?offset=${pager.previous.offset}&limit=${pager.previous.limit}>; rel="prev"`) + parts.push( + `<${baseUrl}?offset=${pager.previous.offset}&limit=${pager.previous.limit}>; rel="prev"` + ) } if (pager.next) { parts.push(`<${baseUrl}?offset=${pager.next.offset}&limit=${pager.next.limit}>; rel="next"`) diff --git a/app/controllers/exchange_controller.ts b/app/controllers/exchange_controller.ts index 7cee719..d5159a8 100644 --- a/app/controllers/exchange_controller.ts +++ b/app/controllers/exchange_controller.ts @@ -247,7 +247,10 @@ export default class ExchangeController { // Track SSE stream setup time const setupDurationMs = performance.now() - startTime - ExchangeMetricsService.getInstance().recordApiResponseTime('GET /exchanges/stream', setupDurationMs) + ExchangeMetricsService.getInstance().recordApiResponseTime( + 'GET /exchanges/stream', + setupDurationMs + ) const listener = (exchange: any) => { if (closed) return @@ -333,10 +336,7 @@ export default class ExchangeController { * * Requirement 6.9: Event id equals the exchange's sequenceNumber */ - private sendSSEEvent( - res: import('node:http').ServerResponse, - exchange: any - ): void { + private sendSSEEvent(res: import('node:http').ServerResponse, exchange: any): void { const data = JSON.stringify(exchange) res.write(`id: ${exchange.sequenceNumber}\ndata: ${data}\n\n`) } @@ -347,7 +347,7 @@ export default class ExchangeController { */ private isValidIso8601(value: string): boolean { const date = new Date(value) - if (isNaN(date.getTime())) { + if (Number.isNaN(date.getTime())) { return false } diff --git a/app/controllers/firmware_catalog_controller.ts b/app/controllers/firmware_catalog_controller.ts index 9f903e8..d95bd74 100644 --- a/app/controllers/firmware_catalog_controller.ts +++ b/app/controllers/firmware_catalog_controller.ts @@ -3,7 +3,11 @@ import FirmwareCatalogService, { type CreateFirmwareEntryDto, type CreateMigrationRouteDto, } from '#services/firmware_catalog_service' -import { createFirmwareEntryValidator, updateFirmwareEntryValidator, createMigrationRouteValidator } from '#validators/firmware_catalog' +import { + createFirmwareEntryValidator, + updateFirmwareEntryValidator, + createMigrationRouteValidator, +} from '#validators/firmware_catalog' import logger from '@adonisjs/core/services/logger' /** @@ -105,7 +109,9 @@ export default class FirmwareCatalogController { */ async createEntry({ request, response }: HttpContext) { try { - const data = await request.validateUsing(createFirmwareEntryValidator) as CreateFirmwareEntryDto + const data = (await request.validateUsing( + createFirmwareEntryValidator + )) as CreateFirmwareEntryDto const entry = await this.catalogService.createEntry(data) return response.status(201).json(entry) @@ -135,7 +141,9 @@ export default class FirmwareCatalogController { */ async createRoute({ request, response }: HttpContext) { try { - const data = await request.validateUsing(createMigrationRouteValidator) as CreateMigrationRouteDto + const data = (await request.validateUsing( + createMigrationRouteValidator + )) as CreateMigrationRouteDto const route = await this.catalogService.createMigrationRoute(data) return response.status(201).json(route) diff --git a/app/controllers/pages_controller.ts b/app/controllers/pages_controller.ts index b1b96e6..da6227c 100644 --- a/app/controllers/pages_controller.ts +++ b/app/controllers/pages_controller.ts @@ -33,11 +33,25 @@ export default class PagesController { // Predefined model paths for the "Get Model" modal // Detect data model from device properties to suggest the right root - const isTr181 = (device as any).dataModel === 'tr-181' || + const isTr181 = + (device as any).dataModel === 'tr-181' || (device as any).properties?.some((p: any) => p.name?.startsWith('Device.')) const modelPaths = isTr181 - ? ['Device.', 'Device.DeviceInfo.', 'Device.IP.', 'Device.WiFi.', 'Device.ManagementServer.', 'Device.Hosts.'] - : ['InternetGatewayDevice.', 'InternetGatewayDevice.DeviceInfo.', 'InternetGatewayDevice.LANDevice.', 'InternetGatewayDevice.WANDevice.', 'InternetGatewayDevice.ManagementServer.'] + ? [ + 'Device.', + 'Device.DeviceInfo.', + 'Device.IP.', + 'Device.WiFi.', + 'Device.ManagementServer.', + 'Device.Hosts.', + ] + : [ + 'InternetGatewayDevice.', + 'InternetGatewayDevice.DeviceInfo.', + 'InternetGatewayDevice.LANDevice.', + 'InternetGatewayDevice.WANDevice.', + 'InternetGatewayDevice.ManagementServer.', + ] return (inertia as any).render('DeviceDetail', { device, commands, modelPaths }) } diff --git a/app/controllers/references_controller.ts b/app/controllers/references_controller.ts index 39e2fb4..5284809 100644 --- a/app/controllers/references_controller.ts +++ b/app/controllers/references_controller.ts @@ -1,6 +1,6 @@ import type { HttpContext } from '@adonisjs/core/http' import DeviceModel from '#models/device' -import { getReferenceEngine } from '../services/references/reference_engine.js' +import { getReferenceEngine } from '#services/references/reference_engine' export default class ReferencesController { /** @@ -24,7 +24,9 @@ export default class ReferencesController { } const ref = (device.references || []).find((r: any) => r.provider === params.provider) if (!ref) { - return response.status(404).json({ message: `No reference from provider '${params.provider}'` }) + return response + .status(404) + .json({ message: `No reference from provider '${params.provider}'` }) } return response.json(ref) } @@ -51,7 +53,10 @@ export default class ReferencesController { (r: any) => !results.some((nr) => nr.provider === r.provider) ) const merged = [...existing, ...results] - await DeviceModel.updateOne({ identifier: params.identifier }, { $set: { references: merged, updatedAt: new Date() } }) + await DeviceModel.updateOne( + { identifier: params.identifier }, + { $set: { references: merged, updatedAt: new Date() } } + ) } return response.json({ resolved: results.length, references: results }) @@ -72,7 +77,9 @@ export default class ReferencesController { const result = await engine.resolveOne(params.provider, device, context) if (!result) { - return response.status(404).json({ message: `Provider '${params.provider}' not found or cannot resolve` }) + return response + .status(404) + .json({ message: `Provider '${params.provider}' not found or cannot resolve` }) } // Merge into device references diff --git a/app/domain/commands/command.ts b/app/domain/commands/command.ts index c31174c..6047b08 100644 --- a/app/domain/commands/command.ts +++ b/app/domain/commands/command.ts @@ -1,6 +1,6 @@ -import { DeviceId } from '../device/device_id.js' -import { ModeType } from '../shared/mode.js' -import { ObjectId } from 'mongodb' +import { type DeviceId } from '#domain/device/device_id' +import { type ModeType } from '#domain/shared/mode' +import { type ObjectId } from 'mongodb' export type CommandId = string @@ -136,7 +136,9 @@ export class Command { } public isCompleted(): boolean { - return [CommandStatus.COMPLETED, CommandStatus.FAILED, CommandStatus.CANCELLED].includes(this._status) + return [CommandStatus.COMPLETED, CommandStatus.FAILED, CommandStatus.CANCELLED].includes( + this._status + ) } public hasExpired(timeoutMinutes: number = 30): boolean { diff --git a/app/domain/configuration/configuration_version.ts b/app/domain/configuration/configuration_version.ts index 9a50a9e..b9dbb29 100644 --- a/app/domain/configuration/configuration_version.ts +++ b/app/domain/configuration/configuration_version.ts @@ -1,4 +1,4 @@ -import { Configuration } from './configuration.js' +import { type Configuration } from '#domain/configuration/configuration' export interface ConfigurationVersion { configurationIdentifier: string diff --git a/app/domain/device/device.ts b/app/domain/device/device.ts index c933951..2f32214 100644 --- a/app/domain/device/device.ts +++ b/app/domain/device/device.ts @@ -1,13 +1,13 @@ -import { type DeviceId } from './device_id.js' +import { type DeviceId } from '#domain/device/device_id' import { DeviceParameter, DeviceProperty, type ParameterSnapshot, type PropertySnapshot, -} from './device_parameter.js' -import { ParameterType } from '../shared/types.js' +} from '#domain/device/device_parameter' +import { ParameterType } from '#domain/shared/types' import { createHash } from 'node:crypto' -import type { ParameterValueStruct, ParameterInfoStruct } from '../../protocol/tr069_types.js' +import type { ParameterValueStruct, ParameterInfoStruct } from '#protocol/tr069_types' export type GpnStatus = 'supported' | 'unsupported' | 'unknown' diff --git a/app/domain/device/device_id.ts b/app/domain/device/device_id.ts index 15192d0..c45ecd1 100644 --- a/app/domain/device/device_id.ts +++ b/app/domain/device/device_id.ts @@ -30,7 +30,12 @@ export class DeviceId { ) } - public static fromInform(informData: { Manufacturer?: string; OUI?: string; ProductClass?: string; SerialNumber?: string }): DeviceId { + public static fromInform(informData: { + Manufacturer?: string + OUI?: string + ProductClass?: string + SerialNumber?: string + }): DeviceId { return new DeviceId( String(informData?.Manufacturer ?? ''), String(informData?.OUI ?? ''), diff --git a/app/domain/device/device_parameter.ts b/app/domain/device/device_parameter.ts index 8987502..37c1efa 100644 --- a/app/domain/device/device_parameter.ts +++ b/app/domain/device/device_parameter.ts @@ -1,4 +1,4 @@ -import { ParameterType } from '../shared/types.js' +import { ParameterType } from '#domain/shared/types' export interface ParameterSnapshot { name: string diff --git a/app/domain/device/device_record.ts b/app/domain/device/device_record.ts index dbbaaf1..25df7c1 100644 --- a/app/domain/device/device_record.ts +++ b/app/domain/device/device_record.ts @@ -1,7 +1,7 @@ -import { type DeviceId } from './device_id.js' -import { type PropertySnapshot, type ParameterSnapshot } from './device_parameter.js' -import { type DeviceComplianceInfo } from '../configuration/compliance.js' -import { type DataModel, type GpnStatus, type GpnCircuitBreaker } from './device.js' +import { type DeviceId } from '#domain/device/device_id' +import { type PropertySnapshot, type ParameterSnapshot } from '#domain/device/device_parameter' +import { type DeviceComplianceInfo } from '#domain/configuration/compliance' +import { type DataModel, type GpnStatus, type GpnCircuitBreaker } from '#domain/device/device' import type { DeviceReference } from '#services/references/types' export interface DeviceRecord { diff --git a/app/exceptions/index.ts b/app/exceptions/index.ts index 7e4a148..0f824b3 100644 --- a/app/exceptions/index.ts +++ b/app/exceptions/index.ts @@ -1,21 +1,6 @@ import { Exception } from '@adonisjs/core/exceptions' -export class NotFoundException extends Exception { - static status = 404 - static code = 'E_NOT_FOUND' -} - export class BadRequestException extends Exception { static status = 400 static code = 'E_BAD_REQUEST' } - -export class UnprocessableEntityException extends Exception { - static status = 422 - static code = 'E_UNPROCESSABLE' -} - -export class DatabaseException extends Exception { - static status = 503 - static code = 'E_DATABASE_ERROR' -} diff --git a/app/middleware/cwmp_middleware.ts b/app/middleware/cwmp_middleware.ts index 6824904..bbbcd1c 100644 --- a/app/middleware/cwmp_middleware.ts +++ b/app/middleware/cwmp_middleware.ts @@ -1,7 +1,7 @@ import type { HttpContext } from '@adonisjs/core/http' import type { NextFn } from '@adonisjs/core/types/http' -import { parseSoapXml, extractCwmpMessage } from '../protocol/soap.js' -import type { SoapEnvelope, CwmpMessage } from '../protocol/tr069_types.js' +import { parseSoapXml, extractCwmpMessage } from '#protocol/soap' +import type { SoapEnvelope, CwmpMessage } from '#protocol/tr069_types' /** * CWMP Middleware diff --git a/app/middleware/inertia_middleware.ts b/app/middleware/inertia_middleware.ts index 477966d..53ae7c2 100644 --- a/app/middleware/inertia_middleware.ts +++ b/app/middleware/inertia_middleware.ts @@ -3,6 +3,10 @@ import type { HttpContext } from '@adonisjs/core/http' import type { NextFn } from '@adonisjs/core/types/http' export default class InertiaMiddleware extends BaseInertiaMiddleware { + /** + * Implements BaseInertiaMiddleware's abstract `share` method. + * Invoked internally by @adonisjs/inertia — not called directly from this codebase. + */ async share(ctx: HttpContext) { return { errors: ctx.session?.flashMessages.get('errors'), @@ -13,6 +17,11 @@ export default class InertiaMiddleware extends BaseInertiaMiddleware { } } + /** + * Standard AdonisJS middleware entrypoint. + * Invoked dynamically by AdonisJS via the named middleware loader in start/kernel.ts — + * not called directly from this codebase. + */ async handle(ctx: HttpContext, next: NextFn) { await this.init(ctx) await next() diff --git a/app/models/command.ts b/app/models/command.ts index b558008..f720b88 100644 --- a/app/models/command.ts +++ b/app/models/command.ts @@ -1,6 +1,6 @@ import { BaseModel } from '#database/base_model' -import { CommandRecord, CommandStatus } from '../domain/commands/command.js' -import { ModeType } from '../domain/shared/mode.js' +import { type CommandRecord, CommandStatus } from '#domain/commands/command' +import { type ModeType } from '#domain/shared/mode' import { ObjectId } from 'mongodb' export default class CommandModel extends BaseModel { @@ -8,14 +8,19 @@ export default class CommandModel extends BaseModel { static async findByDevice(deviceIdentifier: string): Promise { const collection = this.getCollection() - return collection.find({ deviceIdentifier }).sort({ createdAt: -1 }).toArray() as unknown as Promise + return (await collection + .find({ deviceIdentifier }) + .sort({ createdAt: -1 }) + .toArray()) as unknown as Promise } static async findPending(deviceIdentifier: string, mode?: ModeType): Promise { const filter: any = { deviceIdentifier, status: CommandStatus.PENDING } if (mode) filter.mode = mode const collection = this.getCollection() - return collection.find(filter).sort({ priority: 1 }).toArray() as unknown as Promise + return collection.find(filter).sort({ priority: 1 }).toArray() as unknown as Promise< + CommandRecord[] + > } static async createCommand(command: Omit): Promise { diff --git a/app/models/configuration.ts b/app/models/configuration.ts index d88ace6..fc6fe44 100644 --- a/app/models/configuration.ts +++ b/app/models/configuration.ts @@ -1,6 +1,6 @@ import { BaseModel } from '#database/base_model' -import { Configuration } from '../domain/configuration/configuration.js' -import { Filter, Sort } from 'mongodb' +import { type Configuration } from '#domain/configuration/configuration' +import { type Filter, type Sort } from 'mongodb' export default class ConfigurationModel extends BaseModel { static collectionName = 'configurations' @@ -11,7 +11,9 @@ export default class ConfigurationModel extends BaseModel { static async findAllEnabled(sort: Sort = { priority: -1 }): Promise { const collection = this.getCollection() - return collection.find({ enabled: true }).sort(sort).toArray() as unknown as Promise + return (await collection.find({ enabled: true }).sort(sort).toArray()) as unknown as Promise< + Configuration[] + > } static async paginateConfigurations( @@ -19,7 +21,13 @@ export default class ConfigurationModel extends BaseModel { perPage: number, filter: Filter = {}, sort: Sort = { priority: -1 } - ): Promise<{ data: Configuration[]; total: number; page: number; perPage: number; lastPage: number }> { + ): Promise<{ + data: Configuration[] + total: number + page: number + perPage: number + lastPage: number + }> { return this.paginate(page, perPage, filter, sort) } @@ -28,7 +36,7 @@ export default class ConfigurationModel extends BaseModel { if (existing) { throw new Error(`Configuration with identifier '${data.identifier}' already exists`) } - return this.create(data) as Promise + return (await this.create(data)) as Configuration } static async distinctTags(): Promise { diff --git a/app/models/configuration_version.ts b/app/models/configuration_version.ts index fc4768b..db7fac4 100644 --- a/app/models/configuration_version.ts +++ b/app/models/configuration_version.ts @@ -1,26 +1,20 @@ import { BaseModel } from '#database/base_model' -import { type ConfigurationVersion } from '../domain/configuration/configuration_version.js' -import { Sort } from 'mongodb' +import { type ConfigurationVersion } from '#domain/configuration/configuration_version' export default class ConfigurationVersionModel extends BaseModel { static collectionName = 'configuration_versions' - static async findByConfigurationIdentifier( - configurationIdentifier: string, - sort: Sort = { versionNumber: -1 } - ): Promise { - const collection = this.getCollection() - return collection - .find({ configurationIdentifier }) - .sort(sort) - .toArray() as unknown as Promise - } - static async paginateVersions( configurationIdentifier: string, page: number, perPage: number - ): Promise<{ data: ConfigurationVersion[]; total: number; page: number; perPage: number; lastPage: number }> { + ): Promise<{ + data: ConfigurationVersion[] + total: number + page: number + perPage: number + lastPage: number + }> { return this.paginate(page, perPage, { configurationIdentifier }, { versionNumber: -1 }) } diff --git a/app/models/device.ts b/app/models/device.ts index 9708ea5..e73ec91 100644 --- a/app/models/device.ts +++ b/app/models/device.ts @@ -1,8 +1,8 @@ import { BaseModel } from '#database/base_model' -import { DeviceRecord } from '../domain/device/device_record.js' -import { DeviceId } from '../domain/device/device_id.js' -import { DeviceComplianceInfo } from '../domain/configuration/compliance.js' -import { Filter, Sort } from 'mongodb' +import { type DeviceRecord } from '#domain/device/device_record' +import { type DeviceId } from '#domain/device/device_id' +import { type DeviceComplianceInfo } from '#domain/configuration/compliance' +import { type Filter, type Sort } from 'mongodb' export default class DeviceModel extends BaseModel { static collectionName = 'devices' @@ -87,10 +87,7 @@ export default class DeviceModel extends BaseModel { await this.updateOne({ identifier }, { compliance }) } - static async updateProvisioningCode( - identifier: string, - provisioningCode: string - ): Promise { + static async updateProvisioningCode(identifier: string, provisioningCode: string): Promise { await this.updateOne({ identifier }, { provisioningCode }) } @@ -102,7 +99,7 @@ export default class DeviceModel extends BaseModel { $set: { 'compliance.status': 'pending', 'compliance.lastError': null, - updatedAt: new Date(), + 'updatedAt': new Date(), }, } ) diff --git a/app/models/exchange.ts b/app/models/exchange.ts index 4662432..b683929 100644 --- a/app/models/exchange.ts +++ b/app/models/exchange.ts @@ -45,19 +45,19 @@ export default class ExchangeModel extends BaseModel { // When using `latest` or `before`, we want the most recent messages. // Query in descending order then reverse to return in ascending order. if (options?.latest || options?.before) { - const results = await collection + const results = (await collection .find(filter) .sort({ timestamp: -1 }) .limit(limit) - .toArray() as unknown as CwmpExchange[] + .toArray()) as unknown as CwmpExchange[] return results.reverse() } - return collection + return (await collection .find(filter) .sort({ timestamp: 1 }) .limit(limit) - .toArray() as unknown as Promise + .toArray()) as unknown as CwmpExchange[] } /** diff --git a/app/models/firmware_entry.ts b/app/models/firmware_entry.ts index 9307b10..cb00779 100644 --- a/app/models/firmware_entry.ts +++ b/app/models/firmware_entry.ts @@ -1,5 +1,5 @@ import { BaseModel } from '#database/base_model' -import { FirmwareEntry } from '../domain/firmware/firmware_catalog.js' +import { type FirmwareEntry } from '#domain/firmware/firmware_catalog' export default class FirmwareEntryModel extends BaseModel { static collectionName = 'firmware_entries' diff --git a/app/models/migration_route.ts b/app/models/migration_route.ts index 6c26387..0a2c63b 100644 --- a/app/models/migration_route.ts +++ b/app/models/migration_route.ts @@ -1,12 +1,12 @@ import { BaseModel } from '#database/base_model' -import { MigrationRoute } from '../domain/firmware/firmware_catalog.js' -import { Sort } from 'mongodb' +import { type MigrationRoute } from '#domain/firmware/firmware_catalog' +import { type Sort } from 'mongodb' export default class MigrationRouteModel extends BaseModel { static collectionName = 'migration_routes' static async findByIdentifier(identifier: string): Promise { - return this.findOne({ identifier }) as Promise + return (await this.findOne({ identifier })) as Promise } static async findByProductClass( @@ -14,7 +14,9 @@ export default class MigrationRouteModel extends BaseModel { sort: Sort = { priority: -1 } ): Promise { const collection = this.getCollection() - return collection.find({ productClass }).sort(sort).toArray() as unknown as Promise + return (await collection.find({ productClass }).sort(sort).toArray()) as unknown as Promise< + MigrationRoute[] + > } static async createIfNotExists(data: Partial): Promise { @@ -22,7 +24,7 @@ export default class MigrationRouteModel extends BaseModel { if (existing) { throw new Error(`Migration route with identifier '${data.identifier}' already exists`) } - return this.create(data) as Promise + return (await this.create(data)) as Promise } static async deleteByIdentifier(identifier: string): Promise { diff --git a/app/protocol/common/cwmp_message_builder.ts b/app/protocol/common/cwmp_message_builder.ts index 514bf47..4a996bb 100644 --- a/app/protocol/common/cwmp_message_builder.ts +++ b/app/protocol/common/cwmp_message_builder.ts @@ -21,20 +21,20 @@ import { SetParameterValues, TransferCompleteResponse, Upload, -} from '../cwmp-1-0.js' +} from '#protocol/cwmp-1-0' import { CwmpID, NAMESPACES, SoapEnvelope, type SoapEnvelopeAttribute, SoapEnvelopeHeader, -} from '../soap_envelope.js' +} from '#protocol/soap_envelope' import type { DownloadTaskPayload, UploadTaskPayload, SetParameterValuesTaskPayload, SetParameterAttributesTaskPayload, -} from '../tr069_types.js' +} from '#protocol/tr069_types' function generateCwmpID(): string { return randomBytes(4).toString('hex') diff --git a/app/protocol/cwmp-1-0.ts b/app/protocol/cwmp-1-0.ts index 622d79c..8d0bc83 100644 --- a/app/protocol/cwmp-1-0.ts +++ b/app/protocol/cwmp-1-0.ts @@ -3,140 +3,198 @@ export class Cwmp_1_0 { [key: string]: any public '@class' = '.Cwmp_1_0' - public ID?: ID - public HoldRequests?: HoldRequests - public Fault?: Fault - public GetRPCMethods?: GetRPCMethods - public GetRPCMethodsResponse?: GetRPCMethodsResponse - public SetParameterValues?: SetParameterValues - public SetParameterValuesResponse?: SetParameterValuesResponse - public GetParameterValues?: GetParameterValues - public GetParameterValuesResponse?: GetParameterValuesResponse - public GetParameterNames?: GetParameterNames - public GetParameterNamesResponse?: GetParameterNamesResponse - public SetParameterAttributes?: SetParameterAttributes - public SetParameterAttributesResponse?: SetParameterAttributesResponse - public GetParameterAttributes?: GetParameterAttributes - public GetParameterAttributesResponse?: GetParameterAttributesResponse - public AddObject?: AddObject - public AddObjectResponse?: AddObjectResponse - public DeleteObject?: DeleteObject - public DeleteObjectResponse?: DeleteObjectResponse - public Download?: Download - public DownloadResponse?: DownloadResponse - public Reboot?: Reboot - public RebootResponse?: RebootResponse - public GetQueuedTransfers?: GetQueuedTransfers - public GetQueuedTransfersResponse?: GetQueuedTransfersResponse - public ScheduleInform?: ScheduleInform - public ScheduleInformResponse?: ScheduleInformResponse - public SetVouchers?: SetVouchers - public SetVouchersResponse?: SetVouchersResponse - public GetOptions?: GetOptions - public GetOptionsResponse?: GetOptionsResponse - public Upload?: Upload - public UploadResponse?: UploadResponse - public FactoryReset?: FactoryReset - public FactoryResetResponse?: FactoryResetResponse - public Inform?: Inform - public InformResponse?: InformResponse - public TransferComplete?: TransferComplete - public TransferCompleteResponse?: TransferCompleteResponse - public Kicked?: Kicked - public KickedResponse?: KickedResponse - public RequestDownload?: RequestDownload - public RequestDownloadResponse?: RequestDownloadResponse + public 'ID'?: ID + public 'HoldRequests'?: HoldRequests + public 'Fault'?: Fault + public 'GetRPCMethods'?: GetRPCMethods + public 'GetRPCMethodsResponse'?: GetRPCMethodsResponse + public 'SetParameterValues'?: SetParameterValues + public 'SetParameterValuesResponse'?: SetParameterValuesResponse + public 'GetParameterValues'?: GetParameterValues + public 'GetParameterValuesResponse'?: GetParameterValuesResponse + public 'GetParameterNames'?: GetParameterNames + public 'GetParameterNamesResponse'?: GetParameterNamesResponse + public 'SetParameterAttributes'?: SetParameterAttributes + public 'SetParameterAttributesResponse'?: SetParameterAttributesResponse + public 'GetParameterAttributes'?: GetParameterAttributes + public 'GetParameterAttributesResponse'?: GetParameterAttributesResponse + public 'AddObject'?: AddObject + public 'AddObjectResponse'?: AddObjectResponse + public 'DeleteObject'?: DeleteObject + public 'DeleteObjectResponse'?: DeleteObjectResponse + public 'Download'?: Download + public 'DownloadResponse'?: DownloadResponse + public 'Reboot'?: Reboot + public 'RebootResponse'?: RebootResponse + public 'GetQueuedTransfers'?: GetQueuedTransfers + public 'GetQueuedTransfersResponse'?: GetQueuedTransfersResponse + public 'ScheduleInform'?: ScheduleInform + public 'ScheduleInformResponse'?: ScheduleInformResponse + public 'SetVouchers'?: SetVouchers + public 'SetVouchersResponse'?: SetVouchersResponse + public 'GetOptions'?: GetOptions + public 'GetOptionsResponse'?: GetOptionsResponse + public 'Upload'?: Upload + public 'UploadResponse'?: UploadResponse + public 'FactoryReset'?: FactoryReset + public 'FactoryResetResponse'?: FactoryResetResponse + public 'Inform'?: Inform + public 'InformResponse'?: InformResponse + public 'TransferComplete'?: TransferComplete + public 'TransferCompleteResponse'?: TransferCompleteResponse + public 'Kicked'?: Kicked + public 'KickedResponse'?: KickedResponse + public 'RequestDownload'?: RequestDownload + public 'RequestDownloadResponse'?: RequestDownloadResponse - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ID = props.ID ? new ID(props.ID) : undefined this.HoldRequests = props.HoldRequests ? new HoldRequests(props.HoldRequests) : undefined this.Fault = props.Fault ? new Fault(props.Fault) : undefined this.GetRPCMethods = props.GetRPCMethods ? new GetRPCMethods(props.GetRPCMethods) : undefined - this.GetRPCMethodsResponse = props.GetRPCMethodsResponse ? new GetRPCMethodsResponse(props.GetRPCMethodsResponse) : undefined - this.SetParameterValues = props.SetParameterValues ? new SetParameterValues(props.SetParameterValues) : undefined - this.SetParameterValuesResponse = props.SetParameterValuesResponse ? new SetParameterValuesResponse(props.SetParameterValuesResponse) : undefined - this.GetParameterValues = props.GetParameterValues ? new GetParameterValues(props.GetParameterValues) : undefined - this.GetParameterValuesResponse = props.GetParameterValuesResponse ? new GetParameterValuesResponse(props.GetParameterValuesResponse) : undefined - this.GetParameterNames = props.GetParameterNames ? new GetParameterNames(props.GetParameterNames) : undefined - this.GetParameterNamesResponse = props.GetParameterNamesResponse ? new GetParameterNamesResponse(props.GetParameterNamesResponse) : undefined - this.SetParameterAttributes = props.SetParameterAttributes ? new SetParameterAttributes(props.SetParameterAttributes) : undefined - this.SetParameterAttributesResponse = props.SetParameterAttributesResponse ? new SetParameterAttributesResponse(props.SetParameterAttributesResponse) : undefined - this.GetParameterAttributes = props.GetParameterAttributes ? new GetParameterAttributes(props.GetParameterAttributes) : undefined - this.GetParameterAttributesResponse = props.GetParameterAttributesResponse ? new GetParameterAttributesResponse(props.GetParameterAttributesResponse) : undefined + this.GetRPCMethodsResponse = props.GetRPCMethodsResponse + ? new GetRPCMethodsResponse(props.GetRPCMethodsResponse) + : undefined + this.SetParameterValues = props.SetParameterValues + ? new SetParameterValues(props.SetParameterValues) + : undefined + this.SetParameterValuesResponse = props.SetParameterValuesResponse + ? new SetParameterValuesResponse(props.SetParameterValuesResponse) + : undefined + this.GetParameterValues = props.GetParameterValues + ? new GetParameterValues(props.GetParameterValues) + : undefined + this.GetParameterValuesResponse = props.GetParameterValuesResponse + ? new GetParameterValuesResponse(props.GetParameterValuesResponse) + : undefined + this.GetParameterNames = props.GetParameterNames + ? new GetParameterNames(props.GetParameterNames) + : undefined + this.GetParameterNamesResponse = props.GetParameterNamesResponse + ? new GetParameterNamesResponse(props.GetParameterNamesResponse) + : undefined + this.SetParameterAttributes = props.SetParameterAttributes + ? new SetParameterAttributes(props.SetParameterAttributes) + : undefined + this.SetParameterAttributesResponse = props.SetParameterAttributesResponse + ? new SetParameterAttributesResponse(props.SetParameterAttributesResponse) + : undefined + this.GetParameterAttributes = props.GetParameterAttributes + ? new GetParameterAttributes(props.GetParameterAttributes) + : undefined + this.GetParameterAttributesResponse = props.GetParameterAttributesResponse + ? new GetParameterAttributesResponse(props.GetParameterAttributesResponse) + : undefined this.AddObject = props.AddObject ? new AddObject(props.AddObject) : undefined - this.AddObjectResponse = props.AddObjectResponse ? new AddObjectResponse(props.AddObjectResponse) : undefined + this.AddObjectResponse = props.AddObjectResponse + ? new AddObjectResponse(props.AddObjectResponse) + : undefined this.DeleteObject = props.DeleteObject ? new DeleteObject(props.DeleteObject) : undefined - this.DeleteObjectResponse = props.DeleteObjectResponse ? new DeleteObjectResponse(props.DeleteObjectResponse) : undefined + this.DeleteObjectResponse = props.DeleteObjectResponse + ? new DeleteObjectResponse(props.DeleteObjectResponse) + : undefined this.Download = props.Download ? new Download(props.Download) : undefined - this.DownloadResponse = props.DownloadResponse ? new DownloadResponse(props.DownloadResponse) : undefined + this.DownloadResponse = props.DownloadResponse + ? new DownloadResponse(props.DownloadResponse) + : undefined this.Reboot = props.Reboot ? new Reboot(props.Reboot) : undefined - this.RebootResponse = props.RebootResponse ? new RebootResponse(props.RebootResponse) : undefined - this.GetQueuedTransfers = props.GetQueuedTransfers ? new GetQueuedTransfers(props.GetQueuedTransfers) : undefined - this.GetQueuedTransfersResponse = props.GetQueuedTransfersResponse ? new GetQueuedTransfersResponse(props.GetQueuedTransfersResponse) : undefined - this.ScheduleInform = props.ScheduleInform ? new ScheduleInform(props.ScheduleInform) : undefined - this.ScheduleInformResponse = props.ScheduleInformResponse ? new ScheduleInformResponse(props.ScheduleInformResponse) : undefined + this.RebootResponse = props.RebootResponse + ? new RebootResponse(props.RebootResponse) + : undefined + this.GetQueuedTransfers = props.GetQueuedTransfers + ? new GetQueuedTransfers(props.GetQueuedTransfers) + : undefined + this.GetQueuedTransfersResponse = props.GetQueuedTransfersResponse + ? new GetQueuedTransfersResponse(props.GetQueuedTransfersResponse) + : undefined + this.ScheduleInform = props.ScheduleInform + ? new ScheduleInform(props.ScheduleInform) + : undefined + this.ScheduleInformResponse = props.ScheduleInformResponse + ? new ScheduleInformResponse(props.ScheduleInformResponse) + : undefined this.SetVouchers = props.SetVouchers ? new SetVouchers(props.SetVouchers) : undefined - this.SetVouchersResponse = props.SetVouchersResponse ? new SetVouchersResponse(props.SetVouchersResponse) : undefined + this.SetVouchersResponse = props.SetVouchersResponse + ? new SetVouchersResponse(props.SetVouchersResponse) + : undefined this.GetOptions = props.GetOptions ? new GetOptions(props.GetOptions) : undefined - this.GetOptionsResponse = props.GetOptionsResponse ? new GetOptionsResponse(props.GetOptionsResponse) : undefined + this.GetOptionsResponse = props.GetOptionsResponse + ? new GetOptionsResponse(props.GetOptionsResponse) + : undefined this.Upload = props.Upload ? new Upload(props.Upload) : undefined - this.UploadResponse = props.UploadResponse ? new UploadResponse(props.UploadResponse) : undefined + this.UploadResponse = props.UploadResponse + ? new UploadResponse(props.UploadResponse) + : undefined this.FactoryReset = props.FactoryReset ? new FactoryReset(props.FactoryReset) : undefined - this.FactoryResetResponse = props.FactoryResetResponse ? new FactoryResetResponse(props.FactoryResetResponse) : undefined + this.FactoryResetResponse = props.FactoryResetResponse + ? new FactoryResetResponse(props.FactoryResetResponse) + : undefined this.Inform = props.Inform ? new Inform(props.Inform) : undefined - this.InformResponse = props.InformResponse ? new InformResponse(props.InformResponse) : undefined - this.TransferComplete = props.TransferComplete ? new TransferComplete(props.TransferComplete) : undefined - this.TransferCompleteResponse = props.TransferCompleteResponse ? new TransferCompleteResponse(props.TransferCompleteResponse) : undefined + this.InformResponse = props.InformResponse + ? new InformResponse(props.InformResponse) + : undefined + this.TransferComplete = props.TransferComplete + ? new TransferComplete(props.TransferComplete) + : undefined + this.TransferCompleteResponse = props.TransferCompleteResponse + ? new TransferCompleteResponse(props.TransferCompleteResponse) + : undefined this.Kicked = props.Kicked ? new Kicked(props.Kicked) : undefined - this.KickedResponse = props.KickedResponse ? new KickedResponse(props.KickedResponse) : undefined - this.RequestDownload = props.RequestDownload ? new RequestDownload(props.RequestDownload) : undefined - this.RequestDownloadResponse = props.RequestDownloadResponse ? new RequestDownloadResponse(props.RequestDownloadResponse) : undefined + this.KickedResponse = props.KickedResponse + ? new KickedResponse(props.KickedResponse) + : undefined + this.RequestDownload = props.RequestDownload + ? new RequestDownload(props.RequestDownload) + : undefined + this.RequestDownloadResponse = props.RequestDownloadResponse + ? new RequestDownloadResponse(props.RequestDownloadResponse) + : undefined } } export class ID { public '@class' = '.ID' - public MustUnderstand: string = '1' - public _: string // Content textuel de l'élément ID + public 'MustUnderstand': string = '1' + public '_': string // Content textuel de l'élément ID - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MustUnderstand = props.MustUnderstand || '1' this._ = props._ || props.value || '' } - getXml(): string { + 'getXml'(): string { return `${this._}` } } export class HoldRequests { public '@class' = '.HoldRequests' - public MustUnderstand: string = '1' - public _: boolean // Contenu boolean de l'élément HoldRequests + public 'MustUnderstand': string = '1' + public '_': boolean // Contenu boolean de l'élément HoldRequests - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MustUnderstand = props.MustUnderstand || '1' - this._ = props._ !== undefined ? props._ : (props.value !== undefined ? props.value : false) + this._ = props._ !== undefined ? props._ : props.value !== undefined ? props.value : false } - getXml(): string { + 'getXml'(): string { return `${this._}` } } export class Fault { public '@class' = '.SoapFault' - public Faultcode: string - public Faultstring: string - public Detail?: FaultDetail + public 'Faultcode': string + public 'Faultstring': string + public 'Detail'?: FaultDetail - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Faultcode = props.Faultcode || 'Server' this.Faultstring = props.Faultstring || 'Internal Error' this.Detail = props?.Detail } - getXml() { + 'getXml'() { return ` ${this.Faultcode} ${this.Faultstring} @@ -150,24 +208,33 @@ export class Fault { export class FaultDetail { public '@class' = '.FaultDetail' - public Fault: FaultStruct + public 'Fault': FaultStruct - constructor(props: any) { + 'constructor'(props: any) { this.Fault = new FaultStruct(props.Fault) } - getXml() { - return '' + '' + this.Fault.FaultCode + '' + '' + this.Fault.FaultString + '' + '' + 'getXml'() { + return ( + '' + + '' + + this.Fault.FaultCode + + '' + + '' + + this.Fault.FaultString + + '' + + '' + ) } } export class SetParameterValuesFault { public '@class' = '.SetParameterValuesFault' - public ParameterName: string - public FaultCode: number | string - public FaultString: string + public 'ParameterName': string + public 'FaultCode': number | string + public 'FaultString': string - constructor(props: any) { + 'constructor'(props: any) { this.ParameterName = props.ParameterName || '' this.FaultCode = props?.FaultCode || '' this.FaultString = props?.FaultString || '' @@ -176,19 +243,19 @@ export class SetParameterValuesFault { export class MethodList { public '@class' = '.MethodList' - public String?: string[] + public 'String'?: string[] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.String = props.String } } export class FaultStruct { public '@class' = '.FaultStruct' - public FaultCode: number - public FaultString: string + public 'FaultCode': number + public 'FaultString': string - constructor(props: { FaultCode: number; FaultString: string }) { + 'constructor'(props: { FaultCode: number; FaultString: string }) { this.FaultCode = props.FaultCode this.FaultString = props.FaultString || '' } @@ -196,12 +263,12 @@ export class FaultStruct { export class DeviceIdStruct { public '@class' = '.DeviceIdStruct' - public Manufacturer: string - public OUI: string - public ProductClass: string - public SerialNumber: string + public 'Manufacturer': string + public 'OUI': string + public 'ProductClass': string + public 'SerialNumber': string - constructor(props: any) { + 'constructor'(props: any) { this.Manufacturer = props?.Manufacturer || '' this.OUI = props?.OUI || '' this.ProductClass = props?.ProductClass || '' @@ -211,12 +278,14 @@ export class DeviceIdStruct { export class EventStruct { public '@class' = '.EventStruct' - public EventCode?: EventCode - public CommandKey: string + public 'EventCode'?: EventCode + public 'CommandKey': string - constructor(props: any) { - const key = (Object.keys(EventCode) as Array).find((key) => EventCode[key] === props?.EventCode) - this.EventCode = key ? EventCode[key] : undefined + 'constructor'(props: any) { + const matchedKey = (Object.keys(EventCode) as Array).find( + (key) => EventCode[key] === props?.EventCode + ) + this.EventCode = matchedKey ? EventCode[matchedKey] : undefined this.CommandKey = props?.CommandKey || '' } } @@ -242,9 +311,9 @@ export enum EventCode { export class Event { public '@class' = '.EventList' - public EventStruct: EventStruct[] + public 'EventStruct': EventStruct[] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.EventStruct = (props.EventStruct || []).map((item: any) => new EventStruct(item)) } } @@ -252,29 +321,29 @@ export class Event { export class GetRPCMethods { public '@class' = '.GetRPCMethods' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class GetRPCMethodsResponse { public '@class' = '.GetRPCMethodsResponse' - public MethodList?: MethodList + public 'MethodList'?: MethodList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MethodList = props.MethodList ? new MethodList(props.MethodList) : undefined } } export class SetParameterValues { public '@class' = '.SetParameterValues' - public ParameterValueList: ParameterValueList = new ParameterValueList({}) - public ParameterKey?: string + public 'ParameterValueList': ParameterValueList = new ParameterValueList({}) + public 'ParameterKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ParameterValueList = new ParameterValueList(props.ParameterValueList || {}) this.ParameterKey = props.ParameterKey } - getXml(): string { + 'getXml'(): string { const parameterValueStructXml = this.ParameterValueList?.ParameterValueStruct.map((param) => { return ` @@ -297,49 +366,57 @@ export class SetParameterValues { export class SetParameterValuesResponse { public '@class' = '.SetParameterValuesResponse' - public Status?: number + public 'Status'?: number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Status = props.Status } } export class GetParameterValues { public '@class' = '.GetParameterValues' - public ParameterNames: string[] = [] + public 'ParameterNames': string[] = [] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ParameterNames = props.ParameterNames || [] } - getXml() { + 'getXml'() { const parameterCount = this.ParameterNames.length const parameterStrings = this.ParameterNames.map((p) => ` ${p}`).join('\n') - return [``, ` `, parameterStrings, ` `, ``].join('\n') + return [ + ``, + ` `, + parameterStrings, + ` `, + ``, + ].join('\n') } } export class GetParameterValuesResponse { public '@class' = '.GetParameterValuesResponse' - public ParameterList?: ParameterValueList + public 'ParameterList'?: ParameterValueList - constructor(props: any = {}) { - this.ParameterList = props.ParameterList ? new ParameterValueList(props.ParameterList) : undefined + 'constructor'(props: any = {}) { + this.ParameterList = props.ParameterList + ? new ParameterValueList(props.ParameterList) + : undefined } } export class GetParameterNames { public '@class' = '.GetParameterNames' - public ParameterPath?: string - public NextLevel: boolean = false + public 'ParameterPath'?: string + public 'NextLevel': boolean = false - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ParameterPath = props.ParameterPath this.NextLevel = props.NextLevel || false } - getXml() { + 'getXml'() { return ` ${this.ParameterPath || ''} ${this.NextLevel ? 1 : 0} @@ -349,22 +426,26 @@ export class GetParameterNames { export class GetParameterNamesResponse { public '@class' = '.GetParameterNamesResponse' - public ParameterList?: ParameterInfoList + public 'ParameterList'?: ParameterInfoList - constructor(props: any = {}) { - this.ParameterList = props.ParameterList ? new ParameterInfoList(props.ParameterList) : undefined + 'constructor'(props: any = {}) { + this.ParameterList = props.ParameterList + ? new ParameterInfoList(props.ParameterList) + : undefined } } export class SetParameterAttributes { public '@class' = '.SetParameterAttributes' - public ParameterList?: SetParameterAttributesList + public 'ParameterList'?: SetParameterAttributesList - constructor(props: any = {}) { - this.ParameterList = props.ParameterList ? new SetParameterAttributesList(props.ParameterList) : undefined + 'constructor'(props: any = {}) { + this.ParameterList = props.ParameterList + ? new SetParameterAttributesList(props.ParameterList) + : undefined } - getXml(): string { + 'getXml'(): string { const parameterAttributesXml = this.ParameterList?.SetParameterAttributesStruct?.map((attr) => { return ` @@ -387,19 +468,21 @@ export class SetParameterAttributes { export class SetParameterAttributesResponse { public '@class' = '.SetParameterAttributesResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class GetParameterAttributes { public '@class' = '.GetParameterAttributes' - public ParameterNames: string[] = [] + public 'ParameterNames': string[] = [] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ParameterNames = props.ParameterNames || [] } - getXml(): string { - const parameterNamesXml = this.ParameterNames.map((name) => `${name}`).join('') + 'getXml'(): string { + const parameterNamesXml = this.ParameterNames.map( + (name) => `${name}` + ).join('') return ` ${parameterNamesXml} @@ -410,19 +493,21 @@ export class GetParameterAttributes { export class GetParameterAttributesResponse { public '@class' = '.GetParameterAttributesResponse' - public ParameterList?: ParameterAttributeList + public 'ParameterList'?: ParameterAttributeList - constructor(props: any = {}) { - this.ParameterList = props.ParameterList ? new ParameterAttributeList(props.ParameterList) : undefined + 'constructor'(props: any = {}) { + this.ParameterList = props.ParameterList + ? new ParameterAttributeList(props.ParameterList) + : undefined } } export class AddObject { public '@class' = '.AddObject' - public ObjectName?: string - public ParameterKey?: string + public 'ObjectName'?: string + public 'ParameterKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ObjectName = props.ObjectName this.ParameterKey = props.ParameterKey } @@ -430,10 +515,10 @@ export class AddObject { export class AddObjectResponse { public '@class' = '.AddObjectResponse' - public InstanceNumber?: number - public Status?: number + public 'InstanceNumber'?: number + public 'Status'?: number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.InstanceNumber = props.InstanceNumber this.Status = props.Status } @@ -441,10 +526,10 @@ export class AddObjectResponse { export class DeleteObject { public '@class' = '.DeleteObject' - public ObjectName?: string - public ParameterKey?: string + public 'ObjectName'?: string + public 'ParameterKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.ObjectName = props.ObjectName this.ParameterKey = props.ParameterKey } @@ -452,27 +537,27 @@ export class DeleteObject { export class DeleteObjectResponse { public '@class' = '.DeleteObjectResponse' - public Status?: number + public 'Status'?: number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Status = props.Status } } export class Download { public '@class' = '.Download' - public CommandKey?: string - public FileType?: string - public URL?: string - public Username?: string - public Password?: string - public FileSize?: number - public TargetFileName?: string - public DelaySeconds?: number - public SuccessURL?: string - public FailureURL?: string + public 'CommandKey'?: string + public 'FileType'?: string + public 'URL'?: string + public 'Username'?: string + public 'Password'?: string + public 'FileSize'?: number + public 'TargetFileName'?: string + public 'DelaySeconds'?: number + public 'SuccessURL'?: string + public 'FailureURL'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey this.FileType = props.FileType this.URL = props.URL @@ -485,7 +570,7 @@ export class Download { this.FailureURL = props.FailureURL } - getXml() { + 'getXml'() { const parts = [ ``, this.CommandKey ? `${this.CommandKey}` : '', @@ -506,11 +591,11 @@ export class Download { export class DownloadResponse { public '@class' = '.DownloadResponse' - public Status?: number - public StartTime?: Date - public CompleteTime?: Date + public 'Status'?: number + public 'StartTime'?: Date + public 'CompleteTime'?: Date - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Status = props.Status this.StartTime = props.StartTime ? new Date(props.StartTime) : undefined this.CompleteTime = props.CompleteTime ? new Date(props.CompleteTime) : undefined @@ -519,13 +604,13 @@ export class DownloadResponse { export class Reboot { public '@class' = '.Reboot' - public CommandKey?: string + public 'CommandKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey } - getXml() { + 'getXml'() { return ` ${this.CommandKey || 'RebootCommandKey'} ` @@ -535,35 +620,35 @@ export class Reboot { export class RebootResponse { public '@class' = '.RebootResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class GetQueuedTransfers { public '@class' = '.GetQueuedTransfers' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class GetQueuedTransfersResponse { public '@class' = '.GetQueuedTransfersResponse' - public TransferList?: TransferList + public 'TransferList'?: TransferList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.TransferList = props.TransferList ? new TransferList(props.TransferList) : undefined } } export class ScheduleInform { public '@class' = '.ScheduleInform' - public DelaySeconds?: number - public CommandKey?: string + public 'DelaySeconds'?: number + public 'CommandKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.DelaySeconds = props.DelaySeconds this.CommandKey = props.CommandKey } - getXml() { + 'getXml'() { return ` ${this.DelaySeconds || 0} ${this.CommandKey || 'ScheduleInformCommandKey'} @@ -574,14 +659,14 @@ export class ScheduleInform { export class ScheduleInformResponse { public '@class' = '.ScheduleInformResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class SetVouchers { public '@class' = '.SetVouchers' - public VoucherList?: VoucherList + public 'VoucherList'?: VoucherList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.VoucherList = props.VoucherList ? new VoucherList(props.VoucherList) : undefined } } @@ -589,37 +674,37 @@ export class SetVouchers { export class SetVouchersResponse { public '@class' = '.SetVouchersResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export class GetOptions { public '@class' = '.GetOptions' - public OptionName?: string + public 'OptionName'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.OptionName = props.OptionName } } export class GetOptionsResponse { public '@class' = '.GetOptionsResponse' - public OptionList?: OptionList + public 'OptionList'?: OptionList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.OptionList = props.OptionList ? new OptionList(props.OptionList) : undefined } } export class Upload { public '@class' = '.Upload' - public CommandKey?: string - public FileType?: string - public URL?: string - public Username?: string - public Password?: string - public DelaySeconds?: number + public 'CommandKey'?: string + public 'FileType'?: string + public 'URL'?: string + public 'Username'?: string + public 'Password'?: string + public 'DelaySeconds'?: number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey this.FileType = props.FileType this.URL = props.URL @@ -628,7 +713,7 @@ export class Upload { this.DelaySeconds = props.DelaySeconds } - getXml() { + 'getXml'() { const parts = [ ``, this.CommandKey ? `${this.CommandKey}` : '', @@ -645,11 +730,11 @@ export class Upload { export class UploadResponse { public '@class' = '.UploadResponse' - public Status?: number - public StartTime?: Date - public CompleteTime?: Date + public 'Status'?: number + public 'StartTime'?: Date + public 'CompleteTime'?: Date - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Status = props.Status this.StartTime = props.StartTime ? new Date(props.StartTime) : undefined this.CompleteTime = props.CompleteTime ? new Date(props.CompleteTime) : undefined @@ -659,9 +744,9 @@ export class UploadResponse { export class FactoryReset { public '@class' = '.FactoryReset' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } @@ -669,15 +754,15 @@ export class FactoryReset { export class FactoryResetResponse { public '@class' = '.FactoryResetResponse' - constructor(props: any) {} + 'constructor'(props: any) {} } export class ParameterValueStruct { public '@class' = '.ParameterValueStruct' - public Name: string - public Value?: ValueObject + public 'Name': string + public 'Value'?: ValueObject - constructor(props: any) { + 'constructor'(props: any) { this.Name = props?.Name || '' this.Value = new ValueObject(props?.Value) } @@ -685,10 +770,10 @@ export class ParameterValueStruct { export class ValueObject { public '@class' = '.ValueObject' - public $?: ValueObjectAttribute - public _?: any + public '$'?: ValueObjectAttribute + public '_'?: any - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.$ = props.$ ? new ValueObjectAttribute(props.$) : undefined this._ = props._ } @@ -696,21 +781,23 @@ export class ValueObject { export class ValueObjectAttribute { public '@class' = '.ValueObjectAttribute' - public Type: string + public 'Type': string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Type = props.Type } } export class ParameterValueList { public '@class' = '.ParameterValueList' - public $: ParameterValueAttribute - public ParameterValueStruct: ParameterValueStruct[] = [] + public '$': ParameterValueAttribute + public 'ParameterValueStruct': ParameterValueStruct[] = [] - constructor(props: any) { + 'constructor'(props: any) { this.$ = new ParameterValueAttribute(props?.$) - this.ParameterValueStruct = (props.ParameterValueStruct || []).map((item: any) => new ParameterValueStruct(item)) + this.ParameterValueStruct = (props.ParameterValueStruct || []).map( + (item: any) => new ParameterValueStruct(item) + ) } } @@ -724,10 +811,10 @@ export class ParameterValueAttribute { export class ParameterInfoStruct { public '@class' = '.ParameterInfoStruct' - public Name: string = '' - public Writable: boolean = false + public 'Name': string = '' + public 'Writable': boolean = false - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Name = props.Name || '' const writableValue = props.Writable if (typeof writableValue === 'boolean') { @@ -744,40 +831,42 @@ export class ParameterInfoStruct { export class ParameterInfoList { public '@class' = '.ParameterInfoList' - public ParameterInfoStruct: ParameterInfoStruct[] = [] + public 'ParameterInfoStruct': ParameterInfoStruct[] = [] - constructor(props: any) { - this.ParameterInfoStruct = (props?.ParameterInfoStruct || []).map((item: any) => new ParameterInfoStruct(item)) + 'constructor'(props: any) { + this.ParameterInfoStruct = (props?.ParameterInfoStruct || []).map( + (item: any) => new ParameterInfoStruct(item) + ) } } export class ParameterNames { public '@class' = '.ParameterNames' - public string?: string[] + public 'string'?: string[] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.string = props.string } } export class AccessList { public '@class' = '.AccessList' - public string?: string[] + public 'string'?: string[] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.string = props.string } } export class SetParameterAttributesStruct { public '@class' = '.SetParameterAttributesStruct' - public Name?: string - public NotificationChange?: boolean - public Notification?: number - public AccessListChange?: boolean - public AccessList?: AccessList + public 'Name'?: string + public 'NotificationChange'?: boolean + public 'Notification'?: number + public 'AccessListChange'?: boolean + public 'AccessList'?: AccessList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Name = props.Name this.NotificationChange = props.NotificationChange || false this.Notification = props.Notification || 1 @@ -788,20 +877,22 @@ export class SetParameterAttributesStruct { export class SetParameterAttributesList { public '@class' = '.SetParameterAttributesList' - public SetParameterAttributesStruct?: SetParameterAttributesStruct[] + public 'SetParameterAttributesStruct'?: SetParameterAttributesStruct[] - constructor(props: any = {}) { - this.SetParameterAttributesStruct = (props.SetParameterAttributesStruct || []).map((item: any) => new SetParameterAttributesStruct(item)) + 'constructor'(props: any = {}) { + this.SetParameterAttributesStruct = (props.SetParameterAttributesStruct || []).map( + (item: any) => new SetParameterAttributesStruct(item) + ) } } export class ParameterAttributeStruct { public '@class' = '.ParameterAttributeStruct' - public Name?: string - public Notification?: number - public AccessList?: AccessList + public 'Name'?: string + public 'Notification'?: number + public 'AccessList'?: AccessList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Name = props.Name this.Notification = props.Notification this.AccessList = props.AccessList ? new AccessList(props.AccessList) : undefined @@ -810,19 +901,21 @@ export class ParameterAttributeStruct { export class ParameterAttributeList { public '@class' = '.ParameterAttributeList' - public ParameterAttributeStruct: ParameterAttributeStruct[] = [] + public 'ParameterAttributeStruct': ParameterAttributeStruct[] = [] - constructor(props: any = {}) { - this.ParameterAttributeStruct = (props.ParameterAttributeStruct || []).map((item: any) => new ParameterAttributeStruct(item)) + 'constructor'(props: any = {}) { + this.ParameterAttributeStruct = (props.ParameterAttributeStruct || []).map( + (item: any) => new ParameterAttributeStruct(item) + ) } } export class QueuedTransferStruct { public '@class' = '.QueuedTransferStruct' - public CommandKey: string - public State: number + public 'CommandKey': string + public 'State': number - constructor(props: any) { + 'constructor'(props: any) { this.CommandKey = props.CommandKey || '' this.State = props.State || 0 } @@ -830,58 +923,66 @@ export class QueuedTransferStruct { export class TransferList { public '@class' = '.TransferList' - public QueuedTransferStruct: QueuedTransferStruct[] = [] + public 'QueuedTransferStruct': QueuedTransferStruct[] = [] - constructor(props: any) { - this.QueuedTransferStruct = (props?.QueuedTransferStruct || []).map((item: any) => new QueuedTransferStruct(item)) + 'constructor'(props: any) { + this.QueuedTransferStruct = (props?.QueuedTransferStruct || []).map( + (item: any) => new QueuedTransferStruct(item) + ) } } export class VoucherList { public '@class' = '.VoucherList' - public Base64: string[] = [] + public 'Base64': string[] = [] - constructor(props: any) { + 'constructor'(props: any) { this.Base64 = props?.Base64 || [] } } export class OptionStruct { public '@class' = '.OptionStruct' - public OptionName: string - public VoucherSN: number - public State: number - public Mode: number - public StartDate: Date - public ExpirationDate: Date - public IsTransferable: number + public 'OptionName': string + public 'VoucherSN': number + public 'State': number + public 'Mode': number + public 'StartDate': Date + public 'ExpirationDate': Date + public 'IsTransferable': number - constructor(props: any) { + 'constructor'(props: any) { this.OptionName = props?.OptionName || '' this.VoucherSN = props?.VoucherSN || 0 this.State = props?.State || 0 this.Mode = props?.Mode - this.StartDate = props?.StartDate && !isNaN(Date.parse(props?.StartDate)) ? new Date(props?.StartDate) : new Date() - this.ExpirationDate = props?.ExpirationDate && !isNaN(Date.parse(props?.ExpirationDate)) ? new Date(props?.ExpirationDate) : new Date() + this.StartDate = + props?.StartDate && !Number.isNaN(Date.parse(props?.StartDate)) + ? new Date(props?.StartDate) + : new Date() + this.ExpirationDate = + props?.ExpirationDate && !Number.isNaN(Date.parse(props?.ExpirationDate)) + ? new Date(props?.ExpirationDate) + : new Date() this.IsTransferable = props?.IsTransferable || 1 } } export class OptionList { public '@class' = '.OptionList' - public OptionStruct: OptionStruct[] = [] + public 'OptionStruct': OptionStruct[] = [] - constructor(props: any) { + 'constructor'(props: any) { this.OptionStruct = (props?.OptionStruct || []).map((item: any) => new OptionStruct(item)) } } export class ArgStruct { public '@class' = '.ArgStruct' - public Name: string - public Value: string + public 'Name': string + public 'Value': string - constructor(props: any) { + 'constructor'(props: any) { this.Name = props?.Name || '' this.Value = props?.Value || '' } @@ -889,9 +990,9 @@ export class ArgStruct { export class FileTypeArg { public '@class' = '.FileTypeArg' - public ArgStruct: ArgStruct[] = [] + public 'ArgStruct': ArgStruct[] = [] - constructor(props: any) { + 'constructor'(props: any) { this.ArgStruct = (props?.ArgStruct || []).map((item: any) => new ArgStruct(item)) } } @@ -906,43 +1007,48 @@ class ParameterListAttribute { class ParameterList { public '@class' = '.ParameterList' - public $?: ParameterListAttribute - public ParameterValueStruct: Array = [] + public '$'?: ParameterListAttribute + public 'ParameterValueStruct': Array = [] - constructor(props: any) { + 'constructor'(props: any) { this.$ = props?.$ ? new ParameterListAttribute(props?.$) : undefined - this.ParameterValueStruct = (props?.ParameterValueStruct || []).map((parameter: any) => new ParameterValueStruct(parameter)) + this.ParameterValueStruct = (props?.ParameterValueStruct || []).map( + (parameter: any) => new ParameterValueStruct(parameter) + ) } } export class Inform { public '@class' = '.Inform' - public DeviceId: DeviceIdStruct - public Event: Event - public MaxEnvelopes: number - public CurrentTime: Date - public RetryCount: number - public ParameterList: ParameterList + public 'DeviceId': DeviceIdStruct + public 'Event': Event + public 'MaxEnvelopes': number + public 'CurrentTime': Date + public 'RetryCount': number + public 'ParameterList': ParameterList - constructor(props: any) { + 'constructor'(props: any) { this.DeviceId = new DeviceIdStruct(props?.DeviceId) this.Event = new Event(props?.Event) - this.MaxEnvelopes = parseInt(props?.MaxEnvelopes) || 0 - this.CurrentTime = props?.CurrentTime && !isNaN(Date.parse(props?.CurrentTime)) ? new Date(props?.CurrentTime) : new Date() - this.RetryCount = parseInt(props?.RetryCount) || 0 + this.MaxEnvelopes = Number.parseInt(props?.MaxEnvelopes) || 0 + this.CurrentTime = + props?.CurrentTime && !Number.isNaN(Date.parse(props?.CurrentTime)) + ? new Date(props?.CurrentTime) + : new Date() + this.RetryCount = Number.parseInt(props?.RetryCount) || 0 this.ParameterList = new ParameterList(props?.ParameterList) } } export class InformResponse { public '@class' = '.InformResponse' - public MaxEnvelopes: number + public 'MaxEnvelopes': number - constructor(props: any) { + 'constructor'(props: any) { this.MaxEnvelopes = props?.MaxEnvelopes || 0 } - getXml() { + 'getXml'() { return ` ${this.MaxEnvelopes} @@ -953,12 +1059,12 @@ export class InformResponse { export class TransferComplete { public '@class' = '.TransferComplete' - public CommandKey?: CommandKeyType - public FaultStruct?: FaultStruct - public StartTime?: Date - public CompleteTime?: Date + public 'CommandKey'?: CommandKeyType + public 'FaultStruct'?: FaultStruct + public 'StartTime'?: Date + public 'CompleteTime'?: Date - constructor(props: any) { + 'constructor'(props: any) { this.CommandKey = props?.CommandKey this.FaultStruct = props?.FaultStruct ? new FaultStruct(props.FaultStruct) : undefined this.StartTime = props?.StartTime ? new Date(props.StartTime) : undefined @@ -969,21 +1075,21 @@ export class TransferComplete { export class TransferCompleteResponse { public '@class' = '.TransferCompleteResponse' - constructor(props: any) {} + 'constructor'(props: any) {} - getXml() { + 'getXml'() { return '' } } export class Kicked { public '@class' = '.Kicked' - public Command?: string - public Referer?: string - public Arg?: string - public Next?: string + public 'Command'?: string + public 'Referer'?: string + public 'Arg'?: string + public 'Next'?: string - constructor(props: any) { + 'constructor'(props: any) { this.Command = props?.Command this.Referer = props?.Referer this.Arg = props?.Arg @@ -993,19 +1099,19 @@ export class Kicked { export class KickedResponse { public '@class' = '.KickedResponse' - public NextURL?: string + public 'NextURL'?: string - constructor(props: any) { + 'constructor'(props: any) { this.NextURL = props?.NextURL } } export class RequestDownload { public '@class' = '.RequestDownload' - public FileType?: string - public FileTypeArg?: FileTypeArg + public 'FileType'?: string + public 'FileTypeArg'?: FileTypeArg - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.FileType = props.FileType this.FileTypeArg = props.FileTypeArg ? new FileTypeArg(props.FileTypeArg) : undefined } @@ -1014,7 +1120,7 @@ export class RequestDownload { export class RequestDownloadResponse { public '@class' = '.RequestDownloadResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} } export type CommandKeyType = string diff --git a/app/protocol/cwmp-1-1.ts b/app/protocol/cwmp-1-1.ts index f15bdc4..c262d95 100644 --- a/app/protocol/cwmp-1-1.ts +++ b/app/protocol/cwmp-1-1.ts @@ -1,9 +1,9 @@ // @ts-nocheck — fichier copié de cwmp-connector (papaye) -import { Cwmp_1_0, FaultCodeType } from './cwmp-1-0.js' +import { Cwmp_1_0, FaultCodeType } from '#protocol/cwmp-1-0' /** * CWMP Version 1.1 Protocol Classes - * + * * This version extends CWMP 1.0 with additional features: * - Additional fault codes (9014-9019) * - New event code: "10 AUTONOMOUS TRANSFER COMPLETE" @@ -12,17 +12,25 @@ import { Cwmp_1_0, FaultCodeType } from './cwmp-1-0.js' */ export class Cwmp_1_1 extends Cwmp_1_0 { public '@class' = '.Cwmp_1_1' - public GetAllQueuedTransfers?: GetAllQueuedTransfers - public GetAllQueuedTransfersResponse?: GetAllQueuedTransfersResponse - public AutonomousTransferComplete?: AutonomousTransferComplete - public AutonomousTransferCompleteResponse?: AutonomousTransferCompleteResponse + public 'GetAllQueuedTransfers'?: GetAllQueuedTransfers + public 'GetAllQueuedTransfersResponse'?: GetAllQueuedTransfersResponse + public 'AutonomousTransferComplete'?: AutonomousTransferComplete + public 'AutonomousTransferCompleteResponse'?: AutonomousTransferCompleteResponse - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) - this.GetAllQueuedTransfers = props.GetAllQueuedTransfers ? new GetAllQueuedTransfers(props.GetAllQueuedTransfers) : undefined - this.GetAllQueuedTransfersResponse = props.GetAllQueuedTransfersResponse ? new GetAllQueuedTransfersResponse(props.GetAllQueuedTransfersResponse) : undefined - this.AutonomousTransferComplete = props.AutonomousTransferComplete ? new AutonomousTransferComplete(props.AutonomousTransferComplete) : undefined - this.AutonomousTransferCompleteResponse = props.AutonomousTransferCompleteResponse ? new AutonomousTransferCompleteResponse(props.AutonomousTransferCompleteResponse) : undefined + this.GetAllQueuedTransfers = props.GetAllQueuedTransfers + ? new GetAllQueuedTransfers(props.GetAllQueuedTransfers) + : undefined + this.GetAllQueuedTransfersResponse = props.GetAllQueuedTransfersResponse + ? new GetAllQueuedTransfersResponse(props.GetAllQueuedTransfersResponse) + : undefined + this.AutonomousTransferComplete = props.AutonomousTransferComplete + ? new AutonomousTransferComplete(props.AutonomousTransferComplete) + : undefined + this.AutonomousTransferCompleteResponse = props.AutonomousTransferCompleteResponse + ? new AutonomousTransferCompleteResponse(props.AutonomousTransferCompleteResponse) + : undefined } } @@ -100,14 +108,14 @@ export enum EventCode_1_1 { export class AllQueuedTransferStruct { public '@class' = '.AllQueuedTransferStruct' - public CommandKey: string - public State: number - public IsDownload: boolean - public FileType: string - public FileSize: number - public TargetFileName: string + public 'CommandKey': string + public 'State': number + public 'IsDownload': boolean + public 'FileType': string + public 'FileSize': number + public 'TargetFileName': string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey || '' this.State = props.State || 1 this.IsDownload = props.IsDownload || false @@ -119,32 +127,34 @@ export class AllQueuedTransferStruct { export class AllTransferList { public '@class' = '.AllTransferList' - public AllQueuedTransferStruct: AllQueuedTransferStruct[] = [] + public 'AllQueuedTransferStruct': AllQueuedTransferStruct[] = [] - constructor(props: any = {}) { - this.AllQueuedTransferStruct = (props.AllQueuedTransferStruct || []).map((item: any) => new AllQueuedTransferStruct(item)) + 'constructor'(props: any = {}) { + this.AllQueuedTransferStruct = (props.AllQueuedTransferStruct || []).map( + (item: any) => new AllQueuedTransferStruct(item) + ) } } export class GetAllQueuedTransfers { public '@class' = '.GetAllQueuedTransfers' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } export class GetAllQueuedTransfersResponse { public '@class' = '.GetAllQueuedTransfersResponse' - public TransferList?: AllTransferList + public 'TransferList'?: AllTransferList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.TransferList = props.TransferList ? new AllTransferList(props.TransferList) : undefined } - getXml() { + 'getXml'() { const items = this.TransferList?.AllQueuedTransferStruct || [] const listXml = items .map( @@ -170,17 +180,17 @@ export class GetAllQueuedTransfersResponse { export class AutonomousTransferComplete { public '@class' = '.AutonomousTransferComplete' - public AnnounceURL: string - public TransferURL: string - public IsDownload: boolean - public FileType: string - public FileSize: number - public TargetFileName: string - public FaultStruct: any // Reusing FaultStruct from base - public StartTime: Date - public CompleteTime: Date + public 'AnnounceURL': string + public 'TransferURL': string + public 'IsDownload': boolean + public 'FileType': string + public 'FileSize': number + public 'TargetFileName': string + public 'FaultStruct': any // Reusing FaultStruct from base + public 'StartTime': Date + public 'CompleteTime': Date - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.AnnounceURL = props.AnnounceURL || '' this.TransferURL = props.TransferURL || '' this.IsDownload = props.IsDownload || false @@ -192,7 +202,7 @@ export class AutonomousTransferComplete { this.CompleteTime = props.CompleteTime ? new Date(props.CompleteTime) : new Date() } - getXml() { + 'getXml'() { const fault = this.FaultStruct ? `${this.FaultStruct.FaultCode ?? 0}${this.FaultStruct.FaultString || ''}` : '' @@ -213,9 +223,9 @@ export class AutonomousTransferComplete { export class AutonomousTransferCompleteResponse { public '@class' = '.AutonomousTransferCompleteResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return '' } -} \ No newline at end of file +} diff --git a/app/protocol/cwmp-1-2.ts b/app/protocol/cwmp-1-2.ts index 07ae356..966024e 100644 --- a/app/protocol/cwmp-1-2.ts +++ b/app/protocol/cwmp-1-2.ts @@ -1,6 +1,9 @@ // @ts-nocheck — fichier copié de cwmp-connector (papaye) -import { Cwmp_1_0, FaultStruct } from './cwmp-1-0.js' -import { Cwmp_1_1, AutonomousTransferComplete as AutonomousTransferComplete_1_1 } from './cwmp-1-1.js' +import { Cwmp_1_0, FaultStruct } from '#protocol/cwmp-1-0' +import { + Cwmp_1_1, + AutonomousTransferComplete as AutonomousTransferComplete_1_1, +} from '#protocol/cwmp-1-1' /** * CWMP Version 1.2 Protocol Classes @@ -17,35 +20,55 @@ export class Cwmp_1_2 extends Cwmp_1_1 { public '@class' = '.Cwmp_1_2' // New RPCs - public ScheduleDownload?: ScheduleDownload - public ScheduleDownloadResponse?: ScheduleDownloadResponse - public CancelTransfer?: CancelTransfer - public CancelTransferResponse?: CancelTransferResponse - public ChangeDUState?: ChangeDUState - public ChangeDUStateResponse?: ChangeDUStateResponse - public DUStateChangeComplete?: DUStateChangeComplete - public DUStateChangeCompleteResponse?: DUStateChangeCompleteResponse - public AutonomousDUStateChangeComplete?: AutonomousDUStateChangeComplete - public AutonomousDUStateChangeCompleteResponse?: AutonomousDUStateChangeCompleteResponse + public 'ScheduleDownload'?: ScheduleDownload + public 'ScheduleDownloadResponse'?: ScheduleDownloadResponse + public 'CancelTransfer'?: CancelTransfer + public 'CancelTransferResponse'?: CancelTransferResponse + public 'ChangeDUState'?: ChangeDUState + public 'ChangeDUStateResponse'?: ChangeDUStateResponse + public 'DUStateChangeComplete'?: DUStateChangeComplete + public 'DUStateChangeCompleteResponse'?: DUStateChangeCompleteResponse + public 'AutonomousDUStateChangeComplete'?: AutonomousDUStateChangeComplete + public 'AutonomousDUStateChangeCompleteResponse'?: AutonomousDUStateChangeCompleteResponse // Override AutonomousTransferComplete to use TransferCompleteFaultStruct - public AutonomousTransferComplete?: AutonomousTransferComplete + public 'AutonomousTransferComplete'?: AutonomousTransferComplete - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) - this.ScheduleDownload = props.ScheduleDownload ? new ScheduleDownload(props.ScheduleDownload) : undefined - this.ScheduleDownloadResponse = props.ScheduleDownloadResponse ? new ScheduleDownloadResponse(props.ScheduleDownloadResponse) : undefined - this.CancelTransfer = props.CancelTransfer ? new CancelTransfer(props.CancelTransfer) : undefined - this.CancelTransferResponse = props.CancelTransferResponse ? new CancelTransferResponse(props.CancelTransferResponse) : undefined + this.ScheduleDownload = props.ScheduleDownload + ? new ScheduleDownload(props.ScheduleDownload) + : undefined + this.ScheduleDownloadResponse = props.ScheduleDownloadResponse + ? new ScheduleDownloadResponse(props.ScheduleDownloadResponse) + : undefined + this.CancelTransfer = props.CancelTransfer + ? new CancelTransfer(props.CancelTransfer) + : undefined + this.CancelTransferResponse = props.CancelTransferResponse + ? new CancelTransferResponse(props.CancelTransferResponse) + : undefined this.ChangeDUState = props.ChangeDUState ? new ChangeDUState(props.ChangeDUState) : undefined - this.ChangeDUStateResponse = props.ChangeDUStateResponse ? new ChangeDUStateResponse(props.ChangeDUStateResponse) : undefined - this.DUStateChangeComplete = props.DUStateChangeComplete ? new DUStateChangeComplete(props.DUStateChangeComplete) : undefined - this.DUStateChangeCompleteResponse = props.DUStateChangeCompleteResponse ? new DUStateChangeCompleteResponse(props.DUStateChangeCompleteResponse) : undefined - this.AutonomousDUStateChangeComplete = props.AutonomousDUStateChangeComplete ? new AutonomousDUStateChangeComplete(props.AutonomousDUStateChangeComplete) : undefined - this.AutonomousDUStateChangeCompleteResponse = props.AutonomousDUStateChangeCompleteResponse ? new AutonomousDUStateChangeCompleteResponse(props.AutonomousDUStateChangeCompleteResponse) : undefined + this.ChangeDUStateResponse = props.ChangeDUStateResponse + ? new ChangeDUStateResponse(props.ChangeDUStateResponse) + : undefined + this.DUStateChangeComplete = props.DUStateChangeComplete + ? new DUStateChangeComplete(props.DUStateChangeComplete) + : undefined + this.DUStateChangeCompleteResponse = props.DUStateChangeCompleteResponse + ? new DUStateChangeCompleteResponse(props.DUStateChangeCompleteResponse) + : undefined + this.AutonomousDUStateChangeComplete = props.AutonomousDUStateChangeComplete + ? new AutonomousDUStateChangeComplete(props.AutonomousDUStateChangeComplete) + : undefined + this.AutonomousDUStateChangeCompleteResponse = props.AutonomousDUStateChangeCompleteResponse + ? new AutonomousDUStateChangeCompleteResponse(props.AutonomousDUStateChangeCompleteResponse) + : undefined // Override from 1.1 when provided - this.AutonomousTransferComplete = props.AutonomousTransferComplete ? new AutonomousTransferComplete(props.AutonomousTransferComplete) : this.AutonomousTransferComplete + this.AutonomousTransferComplete = props.AutonomousTransferComplete + ? new AutonomousTransferComplete(props.AutonomousTransferComplete) + : this.AutonomousTransferComplete } } @@ -77,13 +100,13 @@ export enum EventCode_1_2 { // Time window types used by ScheduleDownload export class TimeWindowStruct { public '@class' = '.TimeWindowStruct' - public WindowStart: number - public WindowEnd: number - public WindowMode: string - public UserMessage: string - public MaxRetries: number + public 'WindowStart': number + public 'WindowEnd': number + public 'WindowMode': string + public 'UserMessage': string + public 'MaxRetries': number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.WindowStart = props.WindowStart ?? 0 this.WindowEnd = props.WindowEnd ?? 0 this.WindowMode = props.WindowMode ?? '' @@ -94,26 +117,28 @@ export class TimeWindowStruct { export class TimeWindowList { public '@class' = '.TimeWindowList' - public TimeWindowStruct: TimeWindowStruct[] = [] + public 'TimeWindowStruct': TimeWindowStruct[] = [] - constructor(props: any = {}) { - this.TimeWindowStruct = (props.TimeWindowStruct || []).map((tw: any) => new TimeWindowStruct(tw)) + 'constructor'(props: any = {}) { + this.TimeWindowStruct = (props.TimeWindowStruct || []).map( + (tw: any) => new TimeWindowStruct(tw) + ) } } // ScheduleDownload RPC export class ScheduleDownload { public '@class' = '.ScheduleDownload' - public CommandKey: string - public FileType: string - public URL: string - public Username?: string - public Password?: string - public FileSize?: number - public TargetFileName?: string - public TimeWindowList: TimeWindowList + public 'CommandKey': string + public 'FileType': string + public 'URL': string + public 'Username'?: string + public 'Password'?: string + public 'FileSize'?: number + public 'TargetFileName'?: string + public 'TimeWindowList': TimeWindowList - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey || '' this.FileType = props.FileType || '' this.URL = props.URL || '' @@ -124,7 +149,7 @@ export class ScheduleDownload { this.TimeWindowList = new TimeWindowList(props.TimeWindowList || {}) } - getXml() { + 'getXml'() { const tw = this.TimeWindowList?.TimeWindowStruct || [] const twXml = tw .map( @@ -156,9 +181,9 @@ export class ScheduleDownload { export class ScheduleDownloadResponse { public '@class' = '.ScheduleDownloadResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } @@ -166,12 +191,12 @@ export class ScheduleDownloadResponse { // CancelTransfer RPC export class CancelTransfer { public '@class' = '.CancelTransfer' - public CommandKey: string - constructor(props: any = {}) { + public 'CommandKey': string + 'constructor'(props: any = {}) { this.CommandKey = props.CommandKey || '' } - getXml() { + 'getXml'() { return ` ${this.CommandKey} ` @@ -180,9 +205,9 @@ export class CancelTransfer { export class CancelTransferResponse { public '@class' = '.CancelTransferResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } @@ -190,19 +215,20 @@ export class CancelTransferResponse { // Software Module Management types export type DeploymentUnitState = 'Installed' | 'Uninstalled' | 'Failed' -export class OperationStruct { // abstract base +export class OperationStruct { + // abstract base public '@class' = '.OperationStruct' } export class InstallOpStruct extends OperationStruct { public '@class' = '.InstallOpStruct' - public URL: string - public UUID?: string - public Username?: string - public Password?: string - public ExecutionEnvRef?: string + public 'URL': string + public 'UUID'?: string + public 'Username'?: string + public 'Password'?: string + public 'ExecutionEnvRef'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super() this.URL = props.URL || '' this.UUID = props.UUID @@ -214,13 +240,13 @@ export class InstallOpStruct extends OperationStruct { export class UpdateOpStruct extends OperationStruct { public '@class' = '.UpdateOpStruct' - public UUID?: string - public Version?: string - public URL?: string - public Username?: string - public Password?: string + public 'UUID'?: string + public 'Version'?: string + public 'URL'?: string + public 'Username'?: string + public 'Password'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super() this.UUID = props.UUID this.Version = props.Version @@ -232,11 +258,11 @@ export class UpdateOpStruct extends OperationStruct { export class UninstallOpStruct extends OperationStruct { public '@class' = '.UninstallOpStruct' - public UUID: string - public Version?: string - public ExecutionEnvRef?: string + public 'UUID': string + public 'Version'?: string + public 'ExecutionEnvRef'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super() this.UUID = props.UUID || '' this.Version = props.Version @@ -246,10 +272,10 @@ export class UninstallOpStruct extends OperationStruct { export class DeploymentUnitFaultStruct { public '@class' = '.DeploymentUnitFaultStruct' - public FaultCode: number - public FaultString?: string + public 'FaultCode': number + public 'FaultString'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.FaultCode = props.FaultCode ?? 0 this.FaultString = props.FaultString } @@ -257,17 +283,17 @@ export class DeploymentUnitFaultStruct { export class OpResultStruct { public '@class' = '.OpResultStruct' - public UUID: string - public DeploymentUnitRef: string - public Version: string - public CurrentState: DeploymentUnitState - public Resolved: boolean - public ExecutionUnitRefList: string - public StartTime: Date - public CompleteTime: Date - public Fault: DeploymentUnitFaultStruct + public 'UUID': string + public 'DeploymentUnitRef': string + public 'Version': string + public 'CurrentState': DeploymentUnitState + public 'Resolved': boolean + public 'ExecutionUnitRefList': string + public 'StartTime': Date + public 'CompleteTime': Date + public 'Fault': DeploymentUnitFaultStruct - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.UUID = props.UUID || '' this.DeploymentUnitRef = props.DeploymentUnitRef || '' this.Version = props.Version || '' @@ -282,9 +308,9 @@ export class OpResultStruct { export class AutonOpResultStruct extends OpResultStruct { public '@class' = '.AutonOpResultStruct' - public OperationPerformed: string + public 'OperationPerformed': string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) this.OperationPerformed = props.OperationPerformed || '' } @@ -293,51 +319,55 @@ export class AutonOpResultStruct extends OpResultStruct { // ChangeDUState RPC export class ChangeDUState { public '@class' = '.ChangeDUState' - public Operations: OperationStruct[] = [] - public CommandKey?: string + public 'Operations': OperationStruct[] = [] + public 'CommandKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Operations = (props.Operations || []).map((op: any) => { const type = op?.['@class'] || op?.type if (type === 'InstallOpStruct' || op?.URL) return new InstallOpStruct(op) - if (type === 'UpdateOpStruct' || op?.Version || (op?.UUID && !op?.ExecutionEnvRef)) return new UpdateOpStruct(op) - if (type === 'UninstallOpStruct' || op?.ExecutionEnvRef || (op?.UUID && !op?.URL && !op?.Version)) return new UninstallOpStruct(op) + if (type === 'UpdateOpStruct' || op?.Version || (op?.UUID && !op?.ExecutionEnvRef)) + return new UpdateOpStruct(op) + if ( + type === 'UninstallOpStruct' || + op?.ExecutionEnvRef || + (op?.UUID && !op?.URL && !op?.Version) + ) + return new UninstallOpStruct(op) return new OperationStruct() }) this.CommandKey = props.CommandKey } - getXml() { - const opsXml = this.Operations - .map((op) => { - if (op instanceof InstallOpStruct) { - return ` + 'getXml'() { + const opsXml = this.Operations.map((op) => { + if (op instanceof InstallOpStruct) { + return ` ${op.URL} ${op.UUID ? `${op.UUID}` : ''} ${op.Username ? `${op.Username}` : ''} ${op.Password ? `${op.Password}` : ''} ${op.ExecutionEnvRef ? `${op.ExecutionEnvRef}` : ''} ` - } - if (op instanceof UpdateOpStruct) { - return ` + } + if (op instanceof UpdateOpStruct) { + return ` ${op.UUID ? `${op.UUID}` : ''} ${op.Version ? `${op.Version}` : ''} ${op.URL ? `${op.URL}` : ''} ${op.Username ? `${op.Username}` : ''} ${op.Password ? `${op.Password}` : ''} ` - } - if (op instanceof UninstallOpStruct) { - return ` + } + if (op instanceof UninstallOpStruct) { + return ` ${op.UUID} ${op.Version ? `${op.Version}` : ''} ${op.ExecutionEnvRef ? `${op.ExecutionEnvRef}` : ''} ` - } - return '' - }) - .join('') + } + return '' + }).join('') return ` ${opsXml} @@ -348,9 +378,9 @@ export class ChangeDUState { export class ChangeDUStateResponse { public '@class' = '.ChangeDUStateResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } @@ -358,18 +388,17 @@ export class ChangeDUStateResponse { // DUStateChangeComplete RPCs export class DUStateChangeComplete { public '@class' = '.DUStateChangeComplete' - public Results: OpResultStruct[] - public CommandKey?: string + public 'Results': OpResultStruct[] + public 'CommandKey'?: string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Results = (props.Results || []).map((r: any) => new OpResultStruct(r)) this.CommandKey = props.CommandKey } - getXml() { - const resultsXml = this.Results - .map( - (r) => ` + 'getXml'() { + const resultsXml = this.Results.map( + (r) => ` ${r.UUID} ${r.DeploymentUnitRef} @@ -384,8 +413,7 @@ export class DUStateChangeComplete { ${r.Fault.FaultString ? `${r.Fault.FaultString}` : ''} ` - ) - .join('') + ).join('') return ` ${resultsXml} @@ -396,25 +424,24 @@ export class DUStateChangeComplete { export class DUStateChangeCompleteResponse { public '@class' = '.DUStateChangeCompleteResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } export class AutonomousDUStateChangeComplete { public '@class' = '.AutonomousDUStateChangeComplete' - public Results: AutonOpResultStruct[] + public 'Results': AutonOpResultStruct[] - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.Results = (props.Results || []).map((r: any) => new AutonOpResultStruct(r)) } - getXml() { - const resultsXml = this.Results - .map( - (r) => ` + 'getXml'() { + const resultsXml = this.Results.map( + (r) => ` ${r.UUID} ${r.DeploymentUnitRef} @@ -430,8 +457,7 @@ export class AutonomousDUStateChangeComplete { ${r.OperationPerformed} ` - ) - .join('') + ).join('') return ` ${resultsXml} @@ -441,9 +467,9 @@ export class AutonomousDUStateChangeComplete { export class AutonomousDUStateChangeCompleteResponse { public '@class' = '.AutonomousDUStateChangeCompleteResponse' - constructor(props: any = {}) {} + 'constructor'(props: any = {}) {} - getXml() { + 'getXml'() { return `` } } @@ -451,10 +477,10 @@ export class AutonomousDUStateChangeCompleteResponse { // TransferComplete-specific fault struct for 1.2 export class TransferCompleteFaultStruct { public '@class' = '.TransferCompleteFaultStruct' - public FaultCode: number - public FaultString: string + public 'FaultCode': number + public 'FaultString': string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.FaultCode = props.FaultCode ?? 0 this.FaultString = props.FaultString || '' } @@ -463,14 +489,14 @@ export class TransferCompleteFaultStruct { // Override of 1.1 AutonomousTransferComplete to use TransferCompleteFaultStruct export class AutonomousTransferComplete extends AutonomousTransferComplete_1_1 { public '@class' = '.AutonomousTransferComplete' - public FaultStruct: TransferCompleteFaultStruct + public 'FaultStruct': TransferCompleteFaultStruct - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) this.FaultStruct = new TransferCompleteFaultStruct(props.FaultStruct || {}) } - getXml() { + 'getXml'() { return ` ${this.AnnounceURL} ${this.TransferURL} diff --git a/app/protocol/cwmp-1-3.ts b/app/protocol/cwmp-1-3.ts index a8230d4..d126b5d 100644 --- a/app/protocol/cwmp-1-3.ts +++ b/app/protocol/cwmp-1-3.ts @@ -1,5 +1,5 @@ // @ts-nocheck — fichier copié de cwmp-connector (papaye) -import { Cwmp_1_2 } from './cwmp-1-2.js' +import { Cwmp_1_2 } from '#protocol/cwmp-1-2' /** * CWMP Version 1.3 Protocol Classes @@ -9,21 +9,23 @@ import { Cwmp_1_2 } from './cwmp-1-2.js' */ export class Cwmp_1_3 extends Cwmp_1_2 { public '@class' = '.Cwmp_1_3' - public SessionTimeout?: SessionTimeout + public 'SessionTimeout'?: SessionTimeout - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) - this.SessionTimeout = props.SessionTimeout ? new SessionTimeout(props.SessionTimeout) : undefined + this.SessionTimeout = props.SessionTimeout + ? new SessionTimeout(props.SessionTimeout) + : undefined } } // SOAP Header element for CWMP 1.3 export class SessionTimeout { public '@class' = '.SessionTimeout' - public MustUnderstand: string = '0' - public _: number + public 'MustUnderstand': string = '0' + public '_': number - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MustUnderstand = props.MustUnderstand ?? '0' this._ = props._ ?? 0 } diff --git a/app/protocol/cwmp-1-4.ts b/app/protocol/cwmp-1-4.ts index c2f5f0e..3dec7e7 100644 --- a/app/protocol/cwmp-1-4.ts +++ b/app/protocol/cwmp-1-4.ts @@ -1,5 +1,5 @@ // @ts-nocheck — fichier copié de cwmp-connector (papaye) -import { Cwmp_1_3 } from './cwmp-1-3.js' +import { Cwmp_1_3 } from '#protocol/cwmp-1-3' /** * CWMP Version 1.4 Protocol Classes @@ -11,13 +11,17 @@ import { Cwmp_1_3 } from './cwmp-1-3.js' */ export class Cwmp_1_4 extends Cwmp_1_3 { public '@class' = '.Cwmp_1_4' - public SupportedCWMPVersions?: SupportedCWMPVersions - public UseCWMPVersion?: UseCWMPVersion + public 'SupportedCWMPVersions'?: SupportedCWMPVersions + public 'UseCWMPVersion'?: UseCWMPVersion - constructor(props: any = {}) { + 'constructor'(props: any = {}) { super(props) - this.SupportedCWMPVersions = props.SupportedCWMPVersions ? new SupportedCWMPVersions(props.SupportedCWMPVersions) : undefined - this.UseCWMPVersion = props.UseCWMPVersion ? new UseCWMPVersion(props.UseCWMPVersion) : undefined + this.SupportedCWMPVersions = props.SupportedCWMPVersions + ? new SupportedCWMPVersions(props.SupportedCWMPVersions) + : undefined + this.UseCWMPVersion = props.UseCWMPVersion + ? new UseCWMPVersion(props.UseCWMPVersion) + : undefined } } @@ -48,10 +52,10 @@ export enum EventCode_1_4 { export class SupportedCWMPVersions { public '@class' = '.SupportedCWMPVersions' - public MustUnderstand?: string // should be 0 per spec, optional due to SOAP 1.1 quirks - public _: string // space or comma separated list per implementation + public 'MustUnderstand'?: string // should be 0 per spec, optional due to SOAP 1.1 quirks + public '_': string // space or comma separated list per implementation - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MustUnderstand = props.MustUnderstand ?? '0' this._ = props._ || '' } @@ -59,10 +63,10 @@ export class SupportedCWMPVersions { export class UseCWMPVersion { public '@class' = '.UseCWMPVersion' - public MustUnderstand: string = '1' - public _: string + public 'MustUnderstand': string = '1' + public '_': string - constructor(props: any = {}) { + 'constructor'(props: any = {}) { this.MustUnderstand = props.MustUnderstand ?? '1' this._ = props._ || '' } diff --git a/app/protocol/soap.ts b/app/protocol/soap.ts index 9964177..1a9f0de 100644 --- a/app/protocol/soap.ts +++ b/app/protocol/soap.ts @@ -1,7 +1,7 @@ import { XMLParser } from 'fast-xml-parser' -import type { CwmpMessage, SoapEnvelope, SoapHeader } from './tr069_types.js' +import type { CwmpMessage, SoapEnvelope, SoapHeader } from '#protocol/tr069_types' -export { type SoapEnvelope, type SoapHeader, type CwmpMessage } from './tr069_types.js' +export { type SoapEnvelope, type SoapHeader, type CwmpMessage } from '#protocol/tr069_types' export const CWMP_VERSIONS: Record = { 'urn:dslforum-org:cwmp-1-0': '1.0', diff --git a/app/protocol/soap_envelope.ts b/app/protocol/soap_envelope.ts index f840bc1..ccdae28 100644 --- a/app/protocol/soap_envelope.ts +++ b/app/protocol/soap_envelope.ts @@ -3,11 +3,11 @@ * * Séparées de soap.ts (le module de parsing d'adam-acs) pour éviter les conflits de nom. */ -import { Cwmp_1_0 } from './cwmp-1-0.js' -import { Cwmp_1_1 } from './cwmp-1-1.js' -import { Cwmp_1_2 } from './cwmp-1-2.js' -import { Cwmp_1_3, SessionTimeout } from './cwmp-1-3.js' -import { Cwmp_1_4, SupportedCWMPVersions, UseCWMPVersion } from './cwmp-1-4.js' +import { Cwmp_1_0 } from '#protocol/cwmp-1-0' +import { Cwmp_1_1 } from '#protocol/cwmp-1-1' +import { Cwmp_1_2 } from '#protocol/cwmp-1-2' +import { Cwmp_1_3, SessionTimeout } from '#protocol/cwmp-1-3' +import { Cwmp_1_4, SupportedCWMPVersions, UseCWMPVersion } from '#protocol/cwmp-1-4' type NamespaceDescriptor = { SoapEnc: string diff --git a/app/protocol/tr069_types.ts b/app/protocol/tr069_types.ts index ee9ad1c..eefb5f2 100644 --- a/app/protocol/tr069_types.ts +++ b/app/protocol/tr069_types.ts @@ -59,27 +59,27 @@ export { // Types primitifs type CommandKeyType, type ObjectNameType, -} from './cwmp-1-0.js' +} from '#protocol/cwmp-1-0' // ─── CWMP 1.1 ───────────────────────────────────────────────────────────────── -export { Cwmp_1_1, EventCode_1_1, FaultCodeType_1_1 } from './cwmp-1-1.js' +export { Cwmp_1_1, EventCode_1_1, FaultCodeType_1_1 } from '#protocol/cwmp-1-1' // ─── CWMP 1.2 ───────────────────────────────────────────────────────────────── -export { Cwmp_1_2, EventCode_1_2 } from './cwmp-1-2.js' +export { Cwmp_1_2, EventCode_1_2 } from '#protocol/cwmp-1-2' // ─── CWMP 1.3 ───────────────────────────────────────────────────────────────── -export { Cwmp_1_3, SessionTimeout } from './cwmp-1-3.js' +export { Cwmp_1_3, SessionTimeout } from '#protocol/cwmp-1-3' // ─── CWMP 1.4 ───────────────────────────────────────────────────────────────── -export { Cwmp_1_4, EventCode_1_4, SupportedCWMPVersions, UseCWMPVersion } from './cwmp-1-4.js' +export { Cwmp_1_4, EventCode_1_4, SupportedCWMPVersions, UseCWMPVersion } from '#protocol/cwmp-1-4' // ─── Types locaux complémentaires ───────────────────────────────────────────── -import type { Cwmp_1_0 } from './cwmp-1-0.js' -import type { Cwmp_1_1 } from './cwmp-1-1.js' -import type { Cwmp_1_2 } from './cwmp-1-2.js' -import type { Cwmp_1_3 } from './cwmp-1-3.js' -import type { Cwmp_1_4 } from './cwmp-1-4.js' +import type { Cwmp_1_0 } from '#protocol/cwmp-1-0' +import type { Cwmp_1_1 } from '#protocol/cwmp-1-1' +import type { Cwmp_1_2 } from '#protocol/cwmp-1-2' +import type { Cwmp_1_3 } from '#protocol/cwmp-1-3' +import type { Cwmp_1_4 } from '#protocol/cwmp-1-4' import type { Inform, TransferComplete, @@ -88,7 +88,7 @@ import type { GetParameterAttributesResponse, SetParameterValuesResponse, Fault as SoapFaultBody, -} from './cwmp-1-0.js' +} from '#protocol/cwmp-1-0' /** Union de tous les corps CWMP selon la version du protocole */ export type CwmpBody = Cwmp_1_0 | Cwmp_1_1 | Cwmp_1_2 | Cwmp_1_3 | Cwmp_1_4 diff --git a/app/services/command_service.ts b/app/services/command_service.ts index 38a2a4e..c5f0006 100644 --- a/app/services/command_service.ts +++ b/app/services/command_service.ts @@ -1,7 +1,7 @@ import CommandModel from '#models/command' -import { CommandRecord, CommandStatus, CommandType } from '../domain/commands/command.js' -import { ModeType } from '../domain/shared/mode.js' -import { Priority } from '../domain/commands/command.js' +import { type CommandRecord, CommandStatus, type CommandType } from '#domain/commands/command' +import { ModeType } from '#domain/shared/mode' +import { Priority } from '#domain/commands/command' export default class CommandService { async getCommands() { @@ -32,7 +32,10 @@ export default class CommandService { }) } - async getICommandsForDeviceWithStatus(deviceIdentifier: string, status: CommandStatus): Promise { + async getICommandsForDeviceWithStatus( + deviceIdentifier: string, + status: CommandStatus + ): Promise { const collection = CommandModel.getCollection() return collection .find({ deviceIdentifier, mode: ModeType.I, status }) @@ -40,7 +43,10 @@ export default class CommandService { .toArray() as unknown as Promise } - async getNICommandsForDeviceWithStatus(deviceIdentifier: string, status: CommandStatus): Promise { + async getNICommandsForDeviceWithStatus( + deviceIdentifier: string, + status: CommandStatus + ): Promise { const collection = CommandModel.getCollection() return collection .find({ deviceIdentifier, mode: ModeType.NI, status }) diff --git a/app/services/configuration_engine.ts b/app/services/configuration_engine.ts index 50366c6..fe04714 100644 --- a/app/services/configuration_engine.ts +++ b/app/services/configuration_engine.ts @@ -1,12 +1,16 @@ import ConfigurationModel from '#models/configuration' import DeviceModel from '#models/device' -import FirmwareCatalogService from './firmware_catalog_service.js' -import type { Configuration, ParameterCriteria, ParameterValueType } from '../domain/configuration/configuration.js' -import type { Device } from '../domain/device/device.js' -import type { MigrationStep } from '../domain/firmware/migration_step.js' -import { isWithinSchedule } from '../utils/schedule_window.js' -import { matchGlob } from '../utils/glob_match.js' -import { computeContentHash, parseProvisioningCode } from '../utils/provisioning_code.js' +import FirmwareCatalogService from '#services/firmware_catalog_service' +import type { + Configuration, + ParameterCriteria, + ParameterValueType, +} from '#domain/configuration/configuration' +import type { Device } from '#domain/device/device' +import type { MigrationStep } from '#domain/firmware/migration_step' +import { isWithinSchedule } from '#utils/schedule_window' +import { matchGlob } from '#utils/glob_match' +import { computeContentHash, parseProvisioningCode } from '#utils/provisioning_code' export interface ComplianceDeviceResult { identifier: string @@ -140,7 +144,10 @@ export default class ConfigurationEngine { skipFirmware = true } else { // Get current device version (from properties or parameter) - const currentVersion = this.getDeviceVersion(device, selectedConfig.firmwareTarget.productClass) + const currentVersion = this.getDeviceVersion( + device, + selectedConfig.firmwareTarget.productClass + ) if (currentVersion && currentVersion !== selectedConfig.firmwareTarget.targetVersion) { firmwareMigrationPath = await this.firmwareService.resolveUpgradePath( @@ -153,9 +160,7 @@ export default class ConfigurationEngine { } // Check if compliant (no diffs and no firmware needed) - const isCompliant = - parameterDiffs.length === 0 && - firmwareMigrationPath.length === 0 + const isCompliant = parameterDiffs.length === 0 && firmwareMigrationPath.length === 0 return { configuration: selectedConfig, @@ -369,17 +374,21 @@ export default class ConfigurationEngine { // Compare values (loose: both as strings to handle type mismatches) // If the desired type is numeric, compare numerically const desiredType: string = desired.type || '' - const isNumeric = desiredType === 'unsignedInt' || desiredType === 'int' || - desiredType === 'xsd:unsignedInt' || desiredType === 'xsd:int' + const isNumeric = + desiredType === 'unsignedInt' || + desiredType === 'int' || + desiredType === 'xsd:unsignedInt' || + desiredType === 'xsd:int' const isBool = desiredType === 'boolean' || desiredType === 'xsd:boolean' let valuesMatch: boolean if (isNumeric) { const numCurrent = Number(currentValue) const numDesired = Number(desired.value) - valuesMatch = (!isNaN(numCurrent) && !isNaN(numDesired)) - ? numCurrent === numDesired - : String(currentValue) === String(desired.value) + valuesMatch = + !Number.isNaN(numCurrent) && !Number.isNaN(numDesired) + ? numCurrent === numDesired + : String(currentValue) === String(desired.value) } else if (isBool) { const toBool = (v: any) => v === true || v === 'true' || v === '1' valuesMatch = toBool(currentValue) === toBool(desired.value) @@ -404,7 +413,10 @@ export default class ConfigurationEngine { * Get the current value of a parameter from the device. * Returns null if not found. */ - private getDeviceParameterValue(device: Device, paramName: string): string | number | boolean | null { + private getDeviceParameterValue( + device: Device, + paramName: string + ): string | number | boolean | null { // Try method-based access first (Device class instances) if (typeof (device as any).getParameter === 'function') { const param = (device as any).getParameter(paramName) @@ -419,7 +431,10 @@ export default class ConfigurationEngine { } // Fallback: plain DeviceRecord objects (parameters + properties arrays) - const allEntries = [...((device as any).parameters ?? []), ...((device as any).properties ?? [])] + const allEntries = [ + ...((device as any).parameters ?? []), + ...((device as any).properties ?? []), + ] const entry = allEntries.find((p: any) => p.name === paramName) if (!entry || entry.value === undefined || entry.value === null) return null if (typeof entry.value === 'boolean') return entry.value diff --git a/app/services/configuration_service.ts b/app/services/configuration_service.ts index 94e8039..16cf879 100644 --- a/app/services/configuration_service.ts +++ b/app/services/configuration_service.ts @@ -7,10 +7,10 @@ import { type DesiredParameter, type InventoryPath, PolicyType, -} from '../domain/configuration/configuration.js' -import type { ConfigurationVersion } from '../domain/configuration/configuration_version.js' -import { isParameterCoveredByInventory, suggestInventoryPath } from '../utils/inventory_coverage.js' -import { matchGlob } from '../utils/glob_match.js' +} from '#domain/configuration/configuration' +import type { ConfigurationVersion } from '#domain/configuration/configuration_version' +import { isParameterCoveredByInventory, suggestInventoryPath } from '#utils/inventory_coverage' +import { matchGlob } from '#utils/glob_match' /** * Allowed criteria fields — DeviceId attributes (immutable) + parameterCriteria (evaluated dynamically). @@ -82,7 +82,9 @@ export default class ConfigurationService { /** * Create a new Configuration after validation. */ - async create(data: CreateConfigurationDto): Promise { + async create( + data: CreateConfigurationDto + ): Promise { this.validateIdentifier(data.identifier) this.validateVersion(data.version) this.validatePriority(data.priority) @@ -186,7 +188,10 @@ export default class ConfigurationService { * Creates a version snapshot of the current state before applying changes. * Auto-increments the patch version on behavioral changes and resets device compliance. */ - async update(identifier: string, data: UpdateConfigurationDto): Promise { + async update( + identifier: string, + data: UpdateConfigurationDto + ): Promise { const existing = await ConfigurationModel.findByIdentifier(identifier) if (!existing) { throw new ValidationError(`Configuration '${identifier}' not found`, 'identifier', 404) @@ -243,7 +248,8 @@ export default class ConfigurationService { if (data.tags !== undefined) updatePayload.tags = data.tags if (data.criteria !== undefined) updatePayload.criteria = data.criteria if (data.inventory !== undefined) updatePayload.inventory = data.inventory - if (data.desiredParameters !== undefined) updatePayload.desiredParameters = data.desiredParameters + if (data.desiredParameters !== undefined) + updatePayload.desiredParameters = data.desiredParameters if (data.firmwareTarget !== undefined) updatePayload.firmwareTarget = data.firmwareTarget if (data.schedule !== undefined) updatePayload.schedule = data.schedule @@ -271,7 +277,13 @@ export default class ConfigurationService { identifier: string, page: number = 1, limit: number = 25 - ): Promise<{ data: ConfigurationVersion[]; total: number; page: number; perPage: number; lastPage: number }> { + ): Promise<{ + data: ConfigurationVersion[] + total: number + page: number + perPage: number + lastPage: number + }> { const existing = await ConfigurationModel.findByIdentifier(identifier) if (!existing) { throw new ValidationError(`Configuration '${identifier}' not found`, 'identifier', 404) @@ -298,11 +310,7 @@ export default class ConfigurationService { /** * Add and/or remove tags from a Configuration without modifying other fields. */ - async updateTags( - identifier: string, - add?: string[], - remove?: string[] - ): Promise { + async updateTags(identifier: string, add?: string[], remove?: string[]): Promise { const existing = await ConfigurationModel.findByIdentifier(identifier) if (!existing) { throw new ValidationError(`Configuration '${identifier}' not found`, 'identifier', 404) @@ -538,7 +546,7 @@ export default class ConfigurationService { private sanitizeCriteria(criteria: ConfigurationCriteria): ConfigurationCriteria { if (!criteria.parameterCriteria?.length) return criteria const filtered = criteria.parameterCriteria.filter( - (pc) => pc.name != null && String(pc.name).trim() !== '' + (pc) => pc.name !== null && pc.name !== undefined && String(pc.name).trim() !== '' ) return { ...criteria, diff --git a/app/services/cwmp/action_execution_helper.ts b/app/services/cwmp/action_execution_helper.ts index 68b2566..e87bb23 100644 --- a/app/services/cwmp/action_execution_helper.ts +++ b/app/services/cwmp/action_execution_helper.ts @@ -1,5 +1,5 @@ -import { Device } from '../../domain/device/device.js' -import { DeviceActionExecutor } from './device_action_executor.js' +import { type Device } from '#domain/device/device' +import { type DeviceActionExecutor } from '#services/cwmp/device_action_executor' import logger from '@adonisjs/core/services/logger' /** @@ -23,17 +23,29 @@ export async function executeAction( device: Device, actionType: ActionType, parameters: any[], - callback: ((result: unknown) => Promise) = () => Promise.resolve('') + callback: (result: unknown) => Promise = () => Promise.resolve('') ): Promise { switch (actionType) { case ActionType.SET_PARAMETER_VALUES: - return deviceAction.applySetParameterValues(device, parameters as any[], callback as (r: boolean) => Promise) + return deviceAction.applySetParameterValues( + device, + parameters as any[], + callback as (r: boolean) => Promise + ) case ActionType.SET_PARAMETER_ATTRIBUTES: - return deviceAction.applySetParameterAttributes(device, parameters as any[], callback as (r: boolean) => Promise) + return deviceAction.applySetParameterAttributes( + device, + parameters as any[], + callback as (r: boolean) => Promise + ) case ActionType.SCHEDULE_INFORM: - return deviceAction.applyScheduleInform(device, parameters[0] as any, callback as (r: boolean) => Promise) + return deviceAction.applyScheduleInform( + device, + parameters[0] as any, + callback as (r: boolean) => Promise + ) case ActionType.DOWNLOAD: { const p = parameters[0] diff --git a/app/services/cwmp/configuration_evaluation_state.ts b/app/services/cwmp/configuration_evaluation_state.ts index 47262de..7289eac 100644 --- a/app/services/cwmp/configuration_evaluation_state.ts +++ b/app/services/cwmp/configuration_evaluation_state.ts @@ -1,15 +1,12 @@ -import ConfigurationEngine from '../configuration_engine.js' -import type { EngineResult } from '../configuration_engine.js' -import type { DeviceStateResult, DeviceContext } from './main_state_machine.js' -import { PartialOperationalState } from './main_state_machine.js' +import ConfigurationEngine from '#services/configuration_engine' +import type { EngineResult } from '#services/configuration_engine' +import type { DeviceStateResult, DeviceContext } from '#services/cwmp/main_state_machine' +import { PartialOperationalState } from '#services/cwmp/main_state_machine' import DeviceModel from '#models/device' -import type { - GetParameterNamesResponse, - GetParameterValuesResponse, -} from '../../protocol/tr069_types.js' +import type { GetParameterNamesResponse, GetParameterValuesResponse } from '#protocol/tr069_types' import logger from '@adonisjs/core/services/logger' -import { ComplianceStatus } from '../../domain/configuration/compliance.js' -import { buildProvisioningCode } from '../../utils/provisioning_code.js' +import { ComplianceStatus } from '#domain/configuration/compliance' +import { buildProvisioningCode } from '#utils/provisioning_code' /** * ConfigurationEvaluationState diff --git a/app/services/cwmp/device_action_executor.ts b/app/services/cwmp/device_action_executor.ts index f8cec6e..994ada1 100644 --- a/app/services/cwmp/device_action_executor.ts +++ b/app/services/cwmp/device_action_executor.ts @@ -1,8 +1,8 @@ -import { type Device } from '../../domain/device/device.js' -import { DeviceParameter } from '../../domain/device/device_parameter.js' -import { ParameterType } from '../../domain/shared/types.js' -import { type CWMPTaskQueue, ResultStatus, type TaskResult } from './task_queue.js' -import DeviceModel from '../../models/device.js' +import { type Device } from '#domain/device/device' +import { DeviceParameter } from '#domain/device/device_parameter' +import { ParameterType } from '#domain/shared/types' +import { type CWMPTaskQueue, ResultStatus, type TaskResult } from '#services/cwmp/task_queue' +import DeviceModel from '#models/device' import logger from '@adonisjs/core/services/logger' import type { GetParameterValuesResponse, @@ -11,7 +11,7 @@ import type { ParameterValueStruct, ParameterAttributeStruct, ParameterInfoStruct, -} from '../../protocol/tr069_types.js' +} from '#protocol/tr069_types' // ─── Action parameter interfaces (exported pour usage externe) ───────────────── diff --git a/app/services/cwmp/immediate_command_state_machine.ts b/app/services/cwmp/immediate_command_state_machine.ts index 43c2026..e48a126 100644 --- a/app/services/cwmp/immediate_command_state_machine.ts +++ b/app/services/cwmp/immediate_command_state_machine.ts @@ -1,12 +1,12 @@ -import { type Device } from '../../domain/device/device.js' -import { type CWMPTaskQueue } from './task_queue.js' -import { DeviceActionExecutor } from './device_action_executor.js' +import { type Device } from '#domain/device/device' +import { type CWMPTaskQueue } from '#services/cwmp/task_queue' +import { DeviceActionExecutor } from '#services/cwmp/device_action_executor' import { ExecutingCommandsState, type DeviceContext, type DeviceStateResult, -} from './main_state_machine.js' -import type { CWMPTaskResultData } from '../../protocol/tr069_types.js' +} from '#services/cwmp/main_state_machine' +import type { CWMPTaskResultData } from '#protocol/tr069_types' import logger from '@adonisjs/core/services/logger' /** diff --git a/app/services/cwmp/main_state_machine.ts b/app/services/cwmp/main_state_machine.ts index db0765a..8ad24c9 100644 --- a/app/services/cwmp/main_state_machine.ts +++ b/app/services/cwmp/main_state_machine.ts @@ -1,26 +1,26 @@ -import { type Device } from '../../domain/device/device.js' -import { type CWMPTaskQueue } from './task_queue.js' -import { DeviceActionExecutor } from './device_action_executor.js' -import { getDeviceHashIdentifier } from '../../utils/device_utils.js' -import { CommandStatus, CommandType } from '../../domain/commands/command.js' -import DeviceModel from '../../models/device.js' -import CommandModel from '../../models/command.js' -import { ModeType } from '../../domain/shared/mode.js' +import { type Device } from '#domain/device/device' +import { type CWMPTaskQueue } from '#services/cwmp/task_queue' +import { DeviceActionExecutor } from '#services/cwmp/device_action_executor' +import { getDeviceHashIdentifier } from '#utils/device_utils' +import { CommandStatus, CommandType } from '#domain/commands/command' +import DeviceModel from '#models/device' +import CommandModel from '#models/command' +import { ModeType } from '#domain/shared/mode' import logger from '@adonisjs/core/services/logger' -import { ConfigurationEvaluationState } from './configuration_evaluation_state.js' -import { reclassifyDeviceFromCatalog } from '../parameter_writability.js' +import { ConfigurationEvaluationState } from '#services/cwmp/configuration_evaluation_state' +import { reclassifyDeviceFromCatalog } from '#services/parameter_writability' import type { CWMPTaskResultData, GetParameterNamesResponse, GetParameterValuesResponse, ParameterValueStruct, -} from '../../protocol/tr069_types.js' +} from '#protocol/tr069_types' import type { SetParameterAttribute, DownloadParameter, UploadParameter, RebootParameter, -} from './device_action_executor.js' +} from '#services/cwmp/device_action_executor' import { type ObjectId } from 'mongodb' // ─── Interfaces ──────────────────────────────────────────────────────────────── diff --git a/app/services/cwmp/state_machine_manager.ts b/app/services/cwmp/state_machine_manager.ts index 160615f..c54781f 100644 --- a/app/services/cwmp/state_machine_manager.ts +++ b/app/services/cwmp/state_machine_manager.ts @@ -1,14 +1,14 @@ import { EventEmitter } from 'node:events' -import type { Device } from '../../domain/device/device.js' -import type { DeviceId } from '../../domain/device/device_id.js' -import { CWMPTaskQueue, ResultStatus } from './task_queue.js' -import { MainStateMachine } from './main_state_machine.js' -import { ImmediateCommandStateMachine } from './immediate_command_state_machine.js' -import { getDeviceHashIdentifier } from '../../utils/device_utils.js' -import { resolveHighestPriorityEvent, normalizeEventCode } from '../../utils/cwmp-events.js' -import { CommandStatus } from '../../domain/commands/command.js' -import { ModeType } from '../../domain/shared/mode.js' -import CommandModel from '../../models/command.js' +import type { Device } from '#domain/device/device' +import type { DeviceId } from '#domain/device/device_id' +import { CWMPTaskQueue, ResultStatus } from '#services/cwmp/task_queue' +import { MainStateMachine } from '#services/cwmp/main_state_machine' +import { ImmediateCommandStateMachine } from '#services/cwmp/immediate_command_state_machine' +import { getDeviceHashIdentifier } from '#utils/device_utils' +import { resolveHighestPriorityEvent, normalizeEventCode } from '#utils/cwmp-events' +import { CommandStatus } from '#domain/commands/command' +import { ModeType } from '#domain/shared/mode' +import CommandModel from '#models/command' import logger from '@adonisjs/core/services/logger' export enum MachineStatus { @@ -129,7 +129,12 @@ export class StateMachineManager extends EventEmitter { existingMachine.session = session } // Replace with MainStateMachine - const newMachine = new MainStateMachine(device, session, this.taskQueue, normalizedEvents) + const newMachine = new MainStateMachine( + device, + session, + this.taskQueue, + normalizedEvents + ) ;(existingMachine as any).stateMachine = newMachine existingMachine.events = evts await newMachine.start() @@ -148,7 +153,11 @@ export class StateMachineManager extends EventEmitter { // Inform cycle which means the previous session is dead. Complete the old // machine and create a fresh one for the new session. logger.warn( - { oldSession: existingSessionId, newSession: session, state: existingMachine.currentState }, + { + oldSession: existingSessionId, + newSession: session, + state: existingMachine.currentState, + }, '[StateMachineManager] Replacing stale MainStateMachine from dropped session' ) this.completeMachine(existingMachine) @@ -179,7 +188,11 @@ export class StateMachineManager extends EventEmitter { } else if (primaryEvent === 'CONNECTION REQUEST') { // CONNECTION REQUEST only if no BOOTSTRAP/BOOT present stateMachine = new ImmediateCommandStateMachine(device, session, this.taskQueue) - } else if (primaryEvent === 'PERIODIC' || primaryEvent === 'VALUE CHANGE' || primaryEvent === 'SCHEDULED') { + } else if ( + primaryEvent === 'PERIODIC' || + primaryEvent === 'VALUE CHANGE' || + primaryEvent === 'SCHEDULED' + ) { // Lightweight MainStateMachine stateMachine = new MainStateMachine(device, session, this.taskQueue, normalizedEvents) } else if (primaryEvent === 'DIAGNOSTICS COMPLETE' || primaryEvent === 'TRANSFER COMPLETE') { @@ -337,7 +350,8 @@ export class StateMachineManager extends EventEmitter { // --- IP-only fallback (CPE reconnected on a new TCP port) --- if (!deviceKey) { const lastColon = remoteKey.lastIndexOf(':') - const remoteIp = lastColon > 0 ? remoteKey.slice(0, lastColon).replace(/^\[|\]$/g, '') : remoteKey + const remoteIp = + lastColon > 0 ? remoteKey.slice(0, lastColon).replace(/^\[|\]$/g, '') : remoteKey const candidates: string[] = [] for (const [key, dkJson] of this.remoteToDevice.entries()) { @@ -485,7 +499,11 @@ export class StateMachineManager extends EventEmitter { /** * Handle a CWMP response message */ - async handleCWMPResponse(session: string, success: boolean, message: import('./../../protocol/tr069_types.js').CWMPTaskResultData): Promise { + async handleCWMPResponse( + session: string, + success: boolean, + message: import('./../../protocol/tr069_types.js').CWMPTaskResultData + ): Promise { const machineId = this.sessionMachines.get(session) if (!machineId) return '' @@ -545,7 +563,11 @@ export class StateMachineManager extends EventEmitter { /** * Enqueue an immediate task for a device (e.g., after Inform) */ - async enqueueImmediate(device: Device, type: import('./../../protocol/tr069_types.js').CWMPTaskType, payload: import('./../../protocol/tr069_types.js').CWMPTaskPayload): Promise { + async enqueueImmediate( + device: Device, + type: import('./../../protocol/tr069_types.js').CWMPTaskType, + payload: import('./../../protocol/tr069_types.js').CWMPTaskPayload + ): Promise { this.taskQueue.addCWMPTask(device.deviceId, type, payload) } diff --git a/app/services/cwmp/task_queue.ts b/app/services/cwmp/task_queue.ts index 64cd962..8fade23 100644 --- a/app/services/cwmp/task_queue.ts +++ b/app/services/cwmp/task_queue.ts @@ -1,6 +1,6 @@ -import { type DeviceId } from '../../domain/device/device_id.js' +import { type DeviceId } from '#domain/device/device_id' import { EventEmitter } from 'node:events' -import { CWMPMessageBuilder } from '../../protocol/common/cwmp_message_builder.js' +import { CWMPMessageBuilder } from '#protocol/common/cwmp_message_builder' import logger from '@adonisjs/core/services/logger' import type { CWMPTaskType, @@ -12,7 +12,7 @@ import type { DownloadTaskPayload, UploadTaskPayload, RebootTaskPayload, -} from '../../protocol/tr069_types.js' +} from '#protocol/tr069_types' export class TaskResult { status!: ResultStatus diff --git a/app/services/device_service.ts b/app/services/device_service.ts index d81d8d0..a1dd74e 100644 --- a/app/services/device_service.ts +++ b/app/services/device_service.ts @@ -1,8 +1,8 @@ import DeviceModel from '#models/device' import CommandModel from '#models/command' -import { type DeviceRecord } from '../domain/device/device_record.js' -import { CommandStatus, CommandType, Priority } from '../domain/commands/command.js' -import { ModeType } from '../domain/shared/mode.js' +import { type DeviceRecord } from '#domain/device/device_record' +import { CommandStatus, CommandType, Priority } from '#domain/commands/command' +import { ModeType } from '#domain/shared/mode' import logger from '@adonisjs/core/services/logger' export interface PaginationData { @@ -163,8 +163,12 @@ export default class DeviceService { // Fallback chain: ConnectionRequestUsername > ManagementServer.Username > OUI-ProductClass-Serial const allParams = [...(device.properties || []), ...(device.parameters || [])] - const connReqUsername = allParams.find((p: any) => p.name?.includes('ConnectionRequestUsername')) - const connReqPassword = allParams.find((p: any) => p.name?.includes('ConnectionRequestPassword')) + const connReqUsername = allParams.find((p: any) => + p.name?.includes('ConnectionRequestUsername') + ) + const connReqPassword = allParams.find((p: any) => + p.name?.includes('ConnectionRequestPassword') + ) const mgmtUsername = allParams.find((p: any) => p.name?.endsWith('ManagementServer.Username')) const mgmtPassword = allParams.find((p: any) => p.name?.endsWith('ManagementServer.Password')) @@ -211,7 +215,10 @@ export default class DeviceService { ) continue // try next URL } - logger.info({ status: response.status, url: url.toString() }, 'Connection Request successful') + logger.info( + { status: response.status, url: url.toString() }, + 'Connection Request successful' + ) return true } catch (error: any) { logger.warn( diff --git a/app/services/exchange_index_checker.ts b/app/services/exchange_index_checker.ts index 83f8731..e3303d1 100644 --- a/app/services/exchange_index_checker.ts +++ b/app/services/exchange_index_checker.ts @@ -1,4 +1,4 @@ -import { Db } from 'mongodb' +import { type Db } from 'mongodb' import { getMongoDb } from '#providers/mongodb_provider' /** @@ -72,7 +72,10 @@ export async function verifyCwmpExchangesIndexes(db?: Db): Promise void; info: (msg: string) => void }): Promise { +export async function verifyIndexesAtStartup( + db: Db, + log: { warn: (msg: string) => void; info: (msg: string) => void } +): Promise { const result = await verifyCwmpExchangesIndexes(db) if (result.allPresent) { @@ -82,6 +85,8 @@ export async function verifyIndexesAtStartup(db: Db, log: { warn: (msg: string) const missing = result.indexes.filter((idx) => !idx.exists) for (const idx of missing) { - log.warn(`[ExchangeIndexCheck] Missing index on cwmp_exchanges: ${idx.name} (${idx.description})`) + log.warn( + `[ExchangeIndexCheck] Missing index on cwmp_exchanges: ${idx.name} (${idx.description})` + ) } } diff --git a/app/services/exchange_metrics_service.ts b/app/services/exchange_metrics_service.ts index bf85b61..9648835 100644 --- a/app/services/exchange_metrics_service.ts +++ b/app/services/exchange_metrics_service.ts @@ -53,10 +53,7 @@ export class ExchangeMetricsService { this.maxSamples = maxSamples } - static getInstance( - flushIntervalMs?: number, - maxSamples?: number - ): ExchangeMetricsService { + static getInstance(flushIntervalMs?: number, maxSamples?: number): ExchangeMetricsService { if (!ExchangeMetricsService.instance) { ExchangeMetricsService.instance = new ExchangeMetricsService(flushIntervalMs, maxSamples) } @@ -161,10 +158,7 @@ export class ExchangeMetricsService { Object.keys(metrics.apiResponseTimes).length > 0 if (hasData) { - logger.info( - { metrics }, - '[ExchangeMetrics] Aggregated performance metrics' - ) + logger.info({ metrics }, '[ExchangeMetrics] Aggregated performance metrics') } // Reset samples diff --git a/app/services/exchange_store_service.ts b/app/services/exchange_store_service.ts index 671f34a..86aadca 100644 --- a/app/services/exchange_store_service.ts +++ b/app/services/exchange_store_service.ts @@ -161,7 +161,6 @@ export class ExchangeStoreService { * Internal persist implementation (called within the per-device queue). */ private async doPersistExchange(options: PersistOptions): Promise { - try { let rawXml = options.rawXml || '' diff --git a/app/services/firmware_catalog_service.ts b/app/services/firmware_catalog_service.ts index 101b2fc..3ca1f36 100644 --- a/app/services/firmware_catalog_service.ts +++ b/app/services/firmware_catalog_service.ts @@ -1,9 +1,9 @@ import FirmwareEntryModel from '#models/firmware_entry' import MigrationRouteModel from '#models/migration_route' -import { FirmwareEntry, MigrationRoute } from '../domain/firmware/firmware_catalog.js' -import { MigrationStep } from '../domain/firmware/migration_step.js' -import { matchGlob } from '../utils/glob_match.js' -import { BadRequestException } from '../exceptions/index.js' +import { type FirmwareEntry, type MigrationRoute } from '#domain/firmware/firmware_catalog' +import { type MigrationStep } from '#domain/firmware/migration_step' +import { matchGlob } from '#utils/glob_match' +import { BadRequestException } from '#exceptions/index' export interface CreateFirmwareEntryDto { identifier: string @@ -125,7 +125,10 @@ export default class FirmwareCatalogService { return MigrationRouteModel.find({}) as unknown as Promise } - async updateEntry(identifier: string, data: Partial): Promise { + async updateEntry( + identifier: string, + data: Partial + ): Promise { const collection = FirmwareEntryModel.getCollection() const result = await collection.findOneAndUpdate( { identifier }, diff --git a/app/services/migration_service.ts b/app/services/migration_service.ts index 332f88f..f379f44 100644 --- a/app/services/migration_service.ts +++ b/app/services/migration_service.ts @@ -1,8 +1,8 @@ -import ConfigurationService from './configuration_service.js' -import FirmwareCatalogService from './firmware_catalog_service.js' -import type { CreateConfigurationDto } from './configuration_service.js' -import type { CreateFirmwareEntryDto } from './firmware_catalog_service.js' -import { Db } from 'mongodb' +import ConfigurationService from '#services/configuration_service' +import FirmwareCatalogService from '#services/firmware_catalog_service' +import type { CreateConfigurationDto } from '#services/configuration_service' +import type { CreateFirmwareEntryDto } from '#services/firmware_catalog_service' +import { type Db } from 'mongodb' interface MigrationReport { discoveryMigrated: number @@ -23,7 +23,7 @@ export default class MigrationService { constructor( private db: Db, private configService = new ConfigurationService(), - private firmwareCatalogService = new FirmwareCatalogService(), + private firmwareCatalogService = new FirmwareCatalogService() ) {} /** @@ -78,7 +78,9 @@ export default class MigrationService { await this.extractFirmwareEntry(action, legacy) report.firmwareEntriesCreated++ } catch (error) { - report.errors.push(`Firmware extraction for ${legacy.identifier}: ${(error as Error).message}`) + report.errors.push( + `Firmware extraction for ${legacy.identifier}: ${(error as Error).message}` + ) } } } @@ -180,8 +182,16 @@ export default class MigrationService { /** * Build desired parameters from legacy Set Parameter actions */ - private buildDesiredParametersFromLegacy(legacy: any): Array<{ name: string; value: string | number | boolean; type: 'string' | 'int' | 'unsignedInt' | 'boolean' | 'dateTime' }> { - const params: Array<{ name: string; value: string | number | boolean; type: 'string' | 'int' | 'unsignedInt' | 'boolean' | 'dateTime' }> = [] + private buildDesiredParametersFromLegacy(legacy: any): Array<{ + name: string + value: string | number | boolean + type: 'string' | 'int' | 'unsignedInt' | 'boolean' | 'dateTime' + }> { + const params: Array<{ + name: string + value: string | number | boolean + type: 'string' | 'int' | 'unsignedInt' | 'boolean' | 'dateTime' + }> = [] if (!legacy.actions) return params @@ -190,7 +200,12 @@ export default class MigrationService { params.push({ name: action.parameter, value: action.value, - type: typeof action.value === 'boolean' ? 'boolean' : typeof action.value === 'number' ? 'int' : 'string', + type: + typeof action.value === 'boolean' + ? 'boolean' + : typeof action.value === 'number' + ? 'int' + : 'string', }) } } @@ -275,11 +290,12 @@ export default class MigrationService { } private buildLegacyProvisioningFromConfig(config: any, originalId: string): any { - const actions = config.desiredParameters?.map((param: any) => ({ - type: 'SET_PARAMETER', - parameter: param.name, - value: param.value, - })) || [] + const actions = + config.desiredParameters?.map((param: any) => ({ + type: 'SET_PARAMETER', + parameter: param.name, + value: param.value, + })) || [] return { identifier: originalId, diff --git a/app/services/parameter_writability.ts b/app/services/parameter_writability.ts index 5fcba56..6048925 100644 --- a/app/services/parameter_writability.ts +++ b/app/services/parameter_writability.ts @@ -1,18 +1,20 @@ import { createRequire } from 'node:module' -import type { DeviceSnapshot } from '../domain/device/device.js' -import type { Device } from '../domain/device/device.js' -import { DeviceParameter } from '../domain/device/device_parameter.js' +import type { DeviceSnapshot } from '#domain/device/device' +import type { Device } from '#domain/device/device' +import { DeviceParameter } from '#domain/device/device_parameter' const require = createRequire(import.meta.url) -const tr181Catalog: Array<{ path: string; writable: boolean; deviceClass: string; type?: string }> = - require('../../config/tr181-catalog.json') +const tr181Catalog: Array<{ + path: string + writable: boolean + deviceClass: string + type?: string +}> = require('../../config/tr181-catalog.json') // Index chargé une fois au démarrage — O(1) lookup const catalogIndex = new Map(tr181Catalog.map((e) => [e.path, e.writable])) const catalogTypeIndex = new Map(tr181Catalog.map((e) => [e.path, e.type || 'xsd:string'])) -const catalogWritableIndex = new Set( - tr181Catalog.filter((e) => e.writable).map((e) => e.path) -) +const catalogWritableIndex = new Set(tr181Catalog.filter((e) => e.writable).map((e) => e.path)) /** Remplace les segments numériques par {i} pour matcher les entrées du catalogue */ export function normalizePath(path: string): string { @@ -69,7 +71,15 @@ export function reclassifyDeviceFromCatalog(device: Device): number { const snap = prop.toSnapshot() const catalogType = catalogTypeIndex.get(normalized) || snap.type device.setParameter( - new DeviceParameter(snap.name, snap.value, catalogType as any, snap.createdAt, snap.updatedAt, snap.notification, snap.accessList) + new DeviceParameter( + snap.name, + snap.value, + catalogType as any, + snap.createdAt, + snap.updatedAt, + snap.notification, + snap.accessList + ) ) ;(device as any)._properties.delete(prop.name) reclassified++ diff --git a/app/services/references/config_loader.ts b/app/services/references/config_loader.ts index 7f6371f..00ba2db 100644 --- a/app/services/references/config_loader.ts +++ b/app/services/references/config_loader.ts @@ -1,6 +1,6 @@ import { readFileSync } from 'node:fs' import { join } from 'node:path' -import type { ReferencesConfig } from './types.js' +import type { ReferencesConfig } from '#services/references/types' const CONFIG_PATH = join(process.cwd(), 'config', 'references.json') diff --git a/app/services/references/providers/wassup_provider.ts b/app/services/references/providers/wassup_provider.ts index b9ff611..b262887 100644 --- a/app/services/references/providers/wassup_provider.ts +++ b/app/services/references/providers/wassup_provider.ts @@ -1,12 +1,11 @@ -import type { DeviceRecord } from '../../../domain/device/device_record.js' +import type { DeviceRecord } from '#domain/device/device_record' import type { ReferenceProvider, ResolvedReference, InformContext, ProviderConfig, -} from '../types.js' -import { ReferenceEngine } from '../reference_engine.js' - +} from '#services/references/types' +import { ReferenceEngine } from '#services/references/reference_engine' /** * Wassup Provider — resolves customer identity via the Wassup protocol. @@ -33,13 +32,22 @@ export class WassupProvider implements ReferenceProvider { this.timeout = config.timeout || 3000 this.resolveBy = config.resolveBy || 'ip' this.service = config.options?.service || 'KRMSCO' - this.requestedProperties = config.options?.requestedProperties || ['sai', 'spr', 'clo', 'puid', 'utz'] + this.requestedProperties = config.options?.requestedProperties || [ + 'sai', + 'spr', + 'clo', + 'puid', + 'utz', + ] } async resolve(device: DeviceRecord, context: InformContext): Promise { const resolveValue = ReferenceEngine.extractResolveValue(device, this.resolveBy, context) if (!resolveValue) { - console.debug({ provider: this.name, resolveBy: this.resolveBy }, '[Wassup] Cannot resolve: no value') + console.debug( + { provider: this.name, resolveBy: this.resolveBy }, + '[Wassup] Cannot resolve: no value' + ) return null } @@ -53,7 +61,7 @@ export class WassupProvider implements ReferenceProvider { const response = await fetch(wassupUrl, { method: 'GET', headers: { - 'X_WASSUP_USER_IP': resolveValue, + X_WASSUP_USER_IP: resolveValue, }, signal: controller.signal, }) @@ -99,13 +107,13 @@ export class WassupProvider implements ReferenceProvider { // Map X_WASSUP_* keys to short names const properties: Record = {} const keyMapping: Record = { - 'X_WASSUP_SAI': 'sai', - 'X_WASSUP_SPR': 'spr', - 'X_WASSUP_CLO': 'clo', - 'X_WASSUP_PUID': 'puid', - 'X_WASSUP_UTZ': 'utz', - 'X_WASSUP_IUR': 'iur', - 'X_WASSUP_IUS': 'ius', + X_WASSUP_SAI: 'sai', + X_WASSUP_SPR: 'spr', + X_WASSUP_CLO: 'clo', + X_WASSUP_PUID: 'puid', + X_WASSUP_UTZ: 'utz', + X_WASSUP_IUR: 'iur', + X_WASSUP_IUS: 'ius', } for (const [wassupKey, shortKey] of Object.entries(keyMapping)) { @@ -114,7 +122,14 @@ export class WassupProvider implements ReferenceProvider { } } - console.info({ provider: this.name, resolveBy: `${this.resolveBy}:${resolveValue}`, keys: Object.keys(properties) }, '[Wassup] Resolved') + console.info( + { + provider: this.name, + resolveBy: `${this.resolveBy}:${resolveValue}`, + keys: Object.keys(properties), + }, + '[Wassup] Resolved' + ) return { provider: this.name, @@ -125,7 +140,10 @@ export class WassupProvider implements ReferenceProvider { } } catch (error: any) { const isTimeout = error.name === 'AbortError' - console.error({ provider: this.name, error: error.message, isTimeout }, '[Wassup] Resolution failed') + console.error( + { provider: this.name, error: error.message, isTimeout }, + '[Wassup] Resolution failed' + ) return { provider: this.name, diff --git a/app/services/references/reference_engine.ts b/app/services/references/reference_engine.ts index 615429f..50bf48d 100644 --- a/app/services/references/reference_engine.ts +++ b/app/services/references/reference_engine.ts @@ -1,13 +1,13 @@ -import type { DeviceRecord } from '../../domain/device/device_record.js' +import type { DeviceRecord } from '#domain/device/device_record' import type { ReferenceProvider, ResolvedReference, InformContext, ProviderConfig, -} from './types.js' -import { TRIGGER_EVENT_MAP } from './types.js' -import { loadReferencesConfig } from './config_loader.js' -import { WassupProvider } from './providers/wassup_provider.js' +} from '#services/references/types' +import { TRIGGER_EVENT_MAP } from '#services/references/types' +import { loadReferencesConfig } from '#services/references/config_loader' +import { WassupProvider } from '#services/references/providers/wassup_provider' export class ReferenceEngine { private providers: ReferenceProvider[] = [] @@ -27,7 +27,10 @@ export class ReferenceEngine { const provider = this.createProvider(providerConfig) if (provider) { this.providers.push(provider) - console.info({ name: providerConfig.name, type: providerConfig.type }, '[References] Provider registered') + console.info( + { name: providerConfig.name, type: providerConfig.type }, + '[References] Provider registered' + ) } } } @@ -41,13 +44,19 @@ export class ReferenceEngine { console.warn({ name: config.name }, '[References] http-json provider not yet implemented') return null case 'http-properties': - console.warn({ name: config.name }, '[References] http-properties provider not yet implemented') + console.warn( + { name: config.name }, + '[References] http-properties provider not yet implemented' + ) return null case 'static': console.warn({ name: config.name }, '[References] static provider not yet implemented') return null default: - console.error({ name: config.name, type: config.type }, '[References] Unknown provider type') + console.error( + { name: config.name, type: config.type }, + '[References] Unknown provider type' + ) return null } } @@ -60,9 +69,7 @@ export class ReferenceEngine { const applicable = this.getApplicableProviders(context.events) if (applicable.length === 0) return [] - const results = await Promise.allSettled( - applicable.map((p) => p.resolve(device, context)) - ) + const results = await Promise.allSettled(applicable.map((p) => p.resolve(device, context))) const resolved: ResolvedReference[] = [] for (const result of results) { @@ -79,7 +86,11 @@ export class ReferenceEngine { /** * Resolve a single provider by name. */ - async resolveOne(providerName: string, device: DeviceRecord, context: InformContext): Promise { + async resolveOne( + providerName: string, + device: DeviceRecord, + context: InformContext + ): Promise { const provider = this.providers.find((p) => p.name === providerName) if (!provider) { console.warn({ providerName }, '[References] Provider not found') @@ -112,7 +123,11 @@ export class ReferenceEngine { /** * Extracts the resolve value from a device based on the resolveBy config. */ - static extractResolveValue(device: DeviceRecord, resolveBy: string, context: InformContext): string | null { + static extractResolveValue( + device: DeviceRecord, + resolveBy: string, + context: InformContext + ): string | null { switch (resolveBy) { case 'ip': return context.remoteIp || null @@ -123,14 +138,14 @@ export class ReferenceEngine { case 'mac': { const allParams = [...(device.properties || []), ...(device.parameters || [])] const macParam = allParams.find((p) => p.name?.includes('MACAddress')) - return macParam?.value as string || null + return (macParam?.value as string) || null } default: if (resolveBy.startsWith('parameter:')) { const path = resolveBy.slice('parameter:'.length) const allParams = [...(device.properties || []), ...(device.parameters || [])] const param = allParams.find((p) => p.name === path) - return param?.value as string || null + return (param?.value as string) || null } return null } diff --git a/app/services/references/types.ts b/app/services/references/types.ts index 43217b1..daf4b32 100644 --- a/app/services/references/types.ts +++ b/app/services/references/types.ts @@ -5,7 +5,7 @@ * from N independent providers (Wassup, CRM, NOC, etc.) */ -import type { DeviceRecord } from '../../domain/device/device_record.js' +import type { DeviceRecord } from '#domain/device/device_record' // ─── Provider Interface ──────────────────────────────────────────────────────── diff --git a/app/services/telemetry.ts b/app/services/telemetry.ts index a70e031..ec652a5 100644 --- a/app/services/telemetry.ts +++ b/app/services/telemetry.ts @@ -12,13 +12,15 @@ export function initTelemetry() { // OpenTelemetry setup is optional - only initialize when available import('@opentelemetry/sdk-node') .then(({ NodeSDK }) => { - return import('@opentelemetry/auto-instrumentations-node').then(({ getNodeAutoInstrumentations }) => { - const sdk = new NodeSDK({ - serviceName: env.get('OTEL_SERVICE_NAME', 'papaye-v2'), - instrumentations: [getNodeAutoInstrumentations()], - }) - sdk.start() - }) + return import('@opentelemetry/auto-instrumentations-node').then( + ({ getNodeAutoInstrumentations }) => { + const sdk = new NodeSDK({ + serviceName: env.get('OTEL_SERVICE_NAME', 'papaye-v2'), + instrumentations: [getNodeAutoInstrumentations()], + }) + sdk.start() + } + ) }) .catch(() => { // OpenTelemetry not available, skip diff --git a/app/services/tr069_trace_service.ts b/app/services/tr069_trace_service.ts index e6b2a4b..26bee8b 100644 --- a/app/services/tr069_trace_service.ts +++ b/app/services/tr069_trace_service.ts @@ -98,12 +98,19 @@ export class Tr069TraceService { writeExchange(deviceId: string, direction: TraceDirection, sessionId: string, xml: string): void { const tail = this.writeQueues.get(deviceId) ?? Promise.resolve() - const next = tail.then(() => this.doWrite(deviceId, direction, sessionId, xml)).catch(() => undefined) + const next = tail + .then(() => this.doWrite(deviceId, direction, sessionId, xml)) + .catch(() => undefined) this.writeQueues.set(deviceId, next) } - private async doWrite(deviceId: string, direction: TraceDirection, sessionId: string, xml: string): Promise { + private async doWrite( + deviceId: string, + direction: TraceDirection, + sessionId: string, + xml: string + ): Promise { mkdirSync(LOG_DIR, { recursive: true }) const filePath = join(LOG_DIR, `${deviceId}.log`) diff --git a/app/utils/cwmp-events.ts b/app/utils/cwmp-events.ts index 177cfe9..5cc85a8 100644 --- a/app/utils/cwmp-events.ts +++ b/app/utils/cwmp-events.ts @@ -31,16 +31,26 @@ export function normalizeEventCode(raw: string): string { // Numeric-only → expand to standard label switch (trimmed) { - case '0': return 'BOOTSTRAP' - case '1': return 'BOOT' - case '2': return 'PERIODIC' - case '3': return 'SCHEDULED' - case '4': return 'VALUE CHANGE' - case '5': return 'KICKED' - case '6': return 'CONNECTION REQUEST' - case '7': return 'TRANSFER COMPLETE' - case '8': return 'DIAGNOSTICS COMPLETE' - default: return trimmed + case '0': + return 'BOOTSTRAP' + case '1': + return 'BOOT' + case '2': + return 'PERIODIC' + case '3': + return 'SCHEDULED' + case '4': + return 'VALUE CHANGE' + case '5': + return 'KICKED' + case '6': + return 'CONNECTION REQUEST' + case '7': + return 'TRANSFER COMPLETE' + case '8': + return 'DIAGNOSTICS COMPLETE' + default: + return trimmed } } diff --git a/app/utils/inventory_coverage.ts b/app/utils/inventory_coverage.ts index cc5f7b4..3bb30c5 100644 --- a/app/utils/inventory_coverage.ts +++ b/app/utils/inventory_coverage.ts @@ -1,4 +1,4 @@ -import type { InventoryPath } from '../domain/configuration/configuration.js' +import type { InventoryPath } from '#domain/configuration/configuration' /** * Checks whether a desired parameter is covered by at least one inventory path. diff --git a/app/utils/periodic_inform.ts b/app/utils/periodic_inform.ts index 30126d3..62dfe20 100644 --- a/app/utils/periodic_inform.ts +++ b/app/utils/periodic_inform.ts @@ -11,17 +11,17 @@ export function computeNextPeriodicInform( ): Date | null { if (!lastPeriodicInformAt) return null - const intervalSeconds = typeof periodicInformInterval === 'string' - ? parseInt(periodicInformInterval, 10) - : periodicInformInterval + const intervalSeconds = + typeof periodicInformInterval === 'string' + ? Number.parseInt(periodicInformInterval, 10) + : periodicInformInterval if (!intervalSeconds || intervalSeconds <= 0) return null - const lastDate = lastPeriodicInformAt instanceof Date - ? lastPeriodicInformAt - : new Date(lastPeriodicInformAt) + const lastDate = + lastPeriodicInformAt instanceof Date ? lastPeriodicInformAt : new Date(lastPeriodicInformAt) - if (isNaN(lastDate.getTime())) return null + if (Number.isNaN(lastDate.getTime())) return null return new Date(lastDate.getTime() + intervalSeconds * 1000) } diff --git a/app/utils/provisioning_code.ts b/app/utils/provisioning_code.ts index a1afa15..8e0f1e8 100644 --- a/app/utils/provisioning_code.ts +++ b/app/utils/provisioning_code.ts @@ -1,5 +1,5 @@ import { createHash } from 'node:crypto' -import type { Configuration } from '../domain/configuration/configuration.js' +import type { Configuration } from '#domain/configuration/configuration' /** * Computes a 12-character hex content hash of a Configuration's desired state. diff --git a/app/utils/schedule_window.ts b/app/utils/schedule_window.ts index 6e34a70..e8892c9 100644 --- a/app/utils/schedule_window.ts +++ b/app/utils/schedule_window.ts @@ -1,4 +1,4 @@ -import type { ScheduleWindow } from '../domain/configuration/configuration.js' +import type { ScheduleWindow } from '#domain/configuration/configuration' /** * Checks if the current time (or provided time) falls within the schedule window. @@ -41,10 +41,7 @@ export function isWithinSchedule(schedule: ScheduleWindow | undefined, now?: Dat /** * Gets the local hour and day-of-week for a given Date in a specific IANA timezone. */ -function getLocalTimeParts( - date: Date, - timezone: string -): { hour: number; dayOfWeek: number } { +function getLocalTimeParts(date: Date, timezone: string): { hour: number; dayOfWeek: number } { const formatter = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', diff --git a/app/validators/configuration.ts b/app/validators/configuration.ts index acd1b21..cb873f3 100644 --- a/app/validators/configuration.ts +++ b/app/validators/configuration.ts @@ -37,9 +37,15 @@ const scheduleWindowSchema = vine.object({ export const createConfigurationValidator = vine.compile( vine.object({ - identifier: vine.string().trim().regex(/^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/), + identifier: vine + .string() + .trim() + .regex(/^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/), name: vine.string().trim().minLength(1), - version: vine.string().trim().regex(/^\d+\.\d+\.\d+$/), + version: vine + .string() + .trim() + .regex(/^\d+\.\d+\.\d+$/), priority: vine.number().positive(), policy: vine.enum(['once', 'maintain']), enabled: vine.boolean().optional(), @@ -55,7 +61,11 @@ export const createConfigurationValidator = vine.compile( export const updateConfigurationValidator = vine.compile( vine.object({ name: vine.string().trim().minLength(1).optional(), - version: vine.string().trim().regex(/^\d+\.\d+\.\d+$/).optional(), + version: vine + .string() + .trim() + .regex(/^\d+\.\d+\.\d+$/) + .optional(), priority: vine.number().positive().optional(), policy: vine.enum(['once', 'maintain']).optional(), enabled: vine.boolean().optional(), diff --git a/app/validators/firmware_catalog.ts b/app/validators/firmware_catalog.ts index c17bdf6..c766203 100644 --- a/app/validators/firmware_catalog.ts +++ b/app/validators/firmware_catalog.ts @@ -2,7 +2,10 @@ import vine from '@vinejs/vine' export const createFirmwareEntryValidator = vine.compile( vine.object({ - identifier: vine.string().trim().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/), + identifier: vine + .string() + .trim() + .regex(/^[a-z0-9]+(-[a-z0-9]+)*$/), productClass: vine.string().trim().minLength(1), version: vine.string().trim().minLength(1), downloadUrl: vine.string().trim().url(), @@ -25,7 +28,10 @@ export const updateFirmwareEntryValidator = vine.compile( export const createMigrationRouteValidator = vine.compile( vine.object({ - identifier: vine.string().trim().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/), + identifier: vine + .string() + .trim() + .regex(/^[a-z0-9]+(-[a-z0-9]+)*$/), productClass: vine.string().trim().minLength(1), sourceVersionPattern: vine.string().trim().minLength(1), targetVersion: vine.string().trim().minLength(1), diff --git a/database/mongo_migrations/001_create_devices_collection.ts b/database/mongo_migrations/001_create_devices_collection.ts index fb01726..b5f3c27 100644 --- a/database/mongo_migrations/001_create_devices_collection.ts +++ b/database/mongo_migrations/001_create_devices_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateDevicesCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/002_create_commands_collection.ts b/database/mongo_migrations/002_create_commands_collection.ts index 32b4522..8cba32d 100644 --- a/database/mongo_migrations/002_create_commands_collection.ts +++ b/database/mongo_migrations/002_create_commands_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateCommandsCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/003_create_discovery_configs_collection.ts b/database/mongo_migrations/003_create_discovery_configs_collection.ts index 603918f..894bbb8 100644 --- a/database/mongo_migrations/003_create_discovery_configs_collection.ts +++ b/database/mongo_migrations/003_create_discovery_configs_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateDiscoveryConfigsCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/004_create_provisioning_configs_collection.ts b/database/mongo_migrations/004_create_provisioning_configs_collection.ts index 33f5d9f..c219e09 100644 --- a/database/mongo_migrations/004_create_provisioning_configs_collection.ts +++ b/database/mongo_migrations/004_create_provisioning_configs_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateProvisioningConfigsCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/005_create_configurations_collection.ts b/database/mongo_migrations/005_create_configurations_collection.ts index 6e40cc1..6e771f6 100644 --- a/database/mongo_migrations/005_create_configurations_collection.ts +++ b/database/mongo_migrations/005_create_configurations_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateConfigurationsCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/006_create_configuration_versions_collection.ts b/database/mongo_migrations/006_create_configuration_versions_collection.ts index dcb1f72..a6b0ab9 100644 --- a/database/mongo_migrations/006_create_configuration_versions_collection.ts +++ b/database/mongo_migrations/006_create_configuration_versions_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateConfigurationVersionsCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/007_create_firmware_entries_collection.ts b/database/mongo_migrations/007_create_firmware_entries_collection.ts index 84e1734..0da5758 100644 --- a/database/mongo_migrations/007_create_firmware_entries_collection.ts +++ b/database/mongo_migrations/007_create_firmware_entries_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateFirmwareEntriesCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/008_create_migration_routes_collection.ts b/database/mongo_migrations/008_create_migration_routes_collection.ts index 90c9d9c..454c9a2 100644 --- a/database/mongo_migrations/008_create_migration_routes_collection.ts +++ b/database/mongo_migrations/008_create_migration_routes_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateMigrationRoutesCollection extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/009_add_compliance_to_devices.ts b/database/mongo_migrations/009_add_compliance_to_devices.ts index e2e3017..accadba 100644 --- a/database/mongo_migrations/009_add_compliance_to_devices.ts +++ b/database/mongo_migrations/009_add_compliance_to_devices.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class AddComplianceToDevices extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/010_drop_legacy_collections.ts b/database/mongo_migrations/010_drop_legacy_collections.ts index 307743b..d597388 100644 --- a/database/mongo_migrations/010_drop_legacy_collections.ts +++ b/database/mongo_migrations/010_drop_legacy_collections.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class DropLegacyCollections extends MongoMigration { async up(): Promise { diff --git a/database/mongo_migrations/011_create_cwmp_exchanges_collection.ts b/database/mongo_migrations/011_create_cwmp_exchanges_collection.ts index 2b33769..40d40c2 100644 --- a/database/mongo_migrations/011_create_cwmp_exchanges_collection.ts +++ b/database/mongo_migrations/011_create_cwmp_exchanges_collection.ts @@ -1,4 +1,4 @@ -import { MongoMigration } from '../mongo_migrator.js' +import { MongoMigration } from '#database/mongo_migrator' export default class CreateCwmpExchangesCollection extends MongoMigration { async up(): Promise { diff --git a/package.json b/package.json index 6b393ff..c74b4f0 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,10 @@ "#database/*": "./database/*.js", "#tests/*": "./tests/*.js", "#start/*": "./start/*.js", - "#config/*": "./config/*.js" + "#config/*": "./config/*.js", + "#domain/*": "./app/domain/*.js", + "#protocol/*": "./app/protocol/*.js", + "#utils/*": "./app/utils/*.js" }, "devDependencies": { "@adonisjs/assembler": "^8.4.0",