fix: correct orphan references after TR-069 typing refactor
- tests/device.spec.ts: fix 6× organizeParameters() calls passing wrapped
response object instead of flat ParameterInfoStruct[] (runtime break)
- tests/device.spec.ts: fix setTmpParamValues([{x:1}]) with valid shape
- immediate_command_state_machine.ts: type handleResponse message param as
CWMPTaskResultData (was any, gap in typing contract)
- configuration_evaluation_state.ts: replace fragile ../../../app/ dynamic
import paths with proper static imports from ../../protocol/tr069_types.js
- main_state_machine.ts: replace all inline dynamic import() type casts with
static imports (GetParameterNamesResponse, GetParameterValuesResponse,
ParameterValueStruct, SetParameterAttribute, DownloadParameter, etc.)
This commit is contained in:
1 parent
f3eb8e1650
commit
b643077e8d
4 files changed
+35
-36
No files matched your search
@@ -3,6 +3,7 @@ import type { EngineResult } from '../configuration_engine.js'
|
||||
import type { DeviceStateResult, DeviceContext } from './main_state_machine.js'
|
||||
import { PartialOperationalState } from './main_state_machine.js'
|
||||
import DeviceModel from '#models/device'
|
||||
import type { GetParameterNamesResponse, GetParameterValuesResponse } from '../../protocol/tr069_types.js'
|
||||
import logger from '@adonisjs/core/services/logger'
|
||||
import { ComplianceStatus } from '../../domain/configuration/compliance.js'
|
||||
import { buildProvisioningCode } from '../../utils/provisioning_code.js'
|
||||
@@ -95,7 +96,7 @@ export class ConfigurationEvaluationState {
|
||||
if (this.awaitingPhase === 'gpn_response') {
|
||||
this.awaitingPhase = null
|
||||
if (context.message?.success && context.message.data) {
|
||||
const gpnResp = context.message.data as import('../../../app/protocol/tr069_types.js').GetParameterNamesResponse
|
||||
const gpnResp = context.message.data as GetParameterNamesResponse
|
||||
const infoList = gpnResp?.ParameterList?.ParameterInfoStruct ?? []
|
||||
const leafNames: string[] = infoList
|
||||
.map((info) => {
|
||||
@@ -116,7 +117,7 @@ export class ConfigurationEvaluationState {
|
||||
} else if (this.awaitingPhase === 'gpv_response') {
|
||||
this.awaitingPhase = null
|
||||
if (context.message?.success && context.message.data) {
|
||||
const gpvResp = context.message.data as import('../../../app/protocol/tr069_types.js').GetParameterValuesResponse
|
||||
const gpvResp = context.message.data as GetParameterValuesResponse
|
||||
const list = gpvResp?.ParameterList?.ParameterValueStruct ?? []
|
||||
if (list.length > 0) {
|
||||
const normalized = list.map((pv) => ({
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Device } from '../../domain/device/device.js'
|
||||
import { CWMPTaskQueue } from './task_queue.js'
|
||||
import { DeviceActionExecutor } from './device_action_executor.js'
|
||||
import { ExecutingCommandsState, DeviceContext, DeviceStateResult } from './main_state_machine.js'
|
||||
import type { CWMPTaskResultData } from '../../protocol/tr069_types.js'
|
||||
import logger from '@adonisjs/core/services/logger'
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,7 @@ export class ImmediateCommandStateMachine {
|
||||
return this.execute()
|
||||
}
|
||||
|
||||
async handleResponse(success: boolean, message: any): Promise<string> {
|
||||
async handleResponse(success: boolean, message: CWMPTaskResultData): Promise<string> {
|
||||
this.context.message = { success, data: message }
|
||||
return this.execute()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,18 @@ import { ModeType } from '../../domain/shared/mode.js'
|
||||
import logger from '@adonisjs/core/services/logger'
|
||||
import { ConfigurationEvaluationState } from './configuration_evaluation_state.js'
|
||||
import { reclassifyDeviceFromCatalog } from '../parameter_writability.js'
|
||||
import type { CWMPTaskResultData } from '../../protocol/tr069_types.js'
|
||||
import type {
|
||||
CWMPTaskResultData,
|
||||
GetParameterNamesResponse,
|
||||
GetParameterValuesResponse,
|
||||
ParameterValueStruct,
|
||||
} from '../../protocol/tr069_types.js'
|
||||
import type {
|
||||
SetParameterAttribute,
|
||||
DownloadParameter,
|
||||
UploadParameter,
|
||||
RebootParameter,
|
||||
} from './device_action_executor.js'
|
||||
import { ObjectId } from 'mongodb'
|
||||
|
||||
// ─── Interfaces ────────────────────────────────────────────────────────────────
|
||||
@@ -181,7 +192,7 @@ class DiscoveringParametersState extends DeviceState {
|
||||
// GPN success — process the response
|
||||
if (context.message?.success && context.message.data) {
|
||||
try {
|
||||
const gpnResp = context.message.data as import('../../protocol/tr069_types.js').GetParameterNamesResponse
|
||||
const gpnResp = context.message.data as GetParameterNamesResponse
|
||||
const infoList = gpnResp?.ParameterList?.ParameterInfoStruct ?? []
|
||||
context.device.organizeParameters(infoList, new Date())
|
||||
context.device.setGpnStatus('supported')
|
||||
@@ -245,7 +256,7 @@ class CriticalReadsState extends DeviceState {
|
||||
criticalPaths,
|
||||
async (result) => {
|
||||
if (result.status === 'success') {
|
||||
const resp = result.data as import('../../protocol/tr069_types.js').GetParameterValuesResponse
|
||||
const resp = result.data as GetParameterValuesResponse
|
||||
const list = resp?.ParameterList?.ParameterValueStruct ?? []
|
||||
if (list.length > 0) {
|
||||
context.device.setTmpParamValues(list)
|
||||
@@ -260,7 +271,7 @@ class CriticalReadsState extends DeviceState {
|
||||
// After GPV response: process values from the response, then reclassify
|
||||
if (context.message?.success && context.message.data) {
|
||||
try {
|
||||
const resp = context.message.data as import('../../protocol/tr069_types.js').GetParameterValuesResponse
|
||||
const resp = context.message.data as GetParameterValuesResponse
|
||||
const list = resp?.ParameterList?.ParameterValueStruct ?? []
|
||||
if (list.length > 0) {
|
||||
// Normalize Name fields: XMLParser may return {_: "path", "$xsi:type": "..."} when Name has attributes
|
||||
@@ -337,7 +348,7 @@ export class ExecutingCommandsState extends DeviceState {
|
||||
// Optimistic update for SPV
|
||||
if (this.currentCommandRecord.action === CommandType.SET_PARAMETER_VALUES) {
|
||||
const rawList = Array.isArray(this.currentCommandRecord.parameters) ? this.currentCommandRecord.parameters as Array<{ name?: string; value?: unknown }> : []
|
||||
const pvStructs: import('../../protocol/tr069_types.js').ParameterValueStruct[] = rawList.map((p) => ({
|
||||
const pvStructs: ParameterValueStruct[] = rawList.map((p) => ({
|
||||
'@class': '.ParameterValueStruct',
|
||||
Name: p?.name ?? '',
|
||||
Value: { '@class': '.ValueObject', _: String(p?.value ?? ''), $: { '@class': '.ValueObjectAttribute', Type: 'xsd:string' } },
|
||||
@@ -433,19 +444,19 @@ export class ExecutingCommandsState extends DeviceState {
|
||||
case CommandType.SET_PARAMETER_ATTRIBUTES: {
|
||||
const p = params as Record<string, unknown> | unknown[] | undefined
|
||||
const spaParams = Array.isArray(p) ? p : ((p as Record<string, unknown>)?.attributes as unknown[] || (p as Record<string, unknown>)?.parameterAttributes as unknown[] || [])
|
||||
return context.services.deviceAction.applySetParameterAttributes(context.device, spaParams as import('../../services/cwmp/device_action_executor.js').SetParameterAttribute[], () => Promise.resolve(''))
|
||||
return context.services.deviceAction.applySetParameterAttributes(context.device, spaParams as SetParameterAttribute[], () => Promise.resolve(''))
|
||||
}
|
||||
case CommandType.DOWNLOAD: {
|
||||
const p = (params as Record<string, unknown>) || {}
|
||||
return context.services.deviceAction.applyDownload(context.device, p as unknown as import('../../services/cwmp/device_action_executor.js').DownloadParameter, () => Promise.resolve(''))
|
||||
return context.services.deviceAction.applyDownload(context.device, p as unknown as DownloadParameter, () => Promise.resolve(''))
|
||||
}
|
||||
case CommandType.UPLOAD: {
|
||||
const p = (params as Record<string, unknown>) || {}
|
||||
return context.services.deviceAction.applyUpload(context.device, p as unknown as import('../../services/cwmp/device_action_executor.js').UploadParameter, () => Promise.resolve(''))
|
||||
return context.services.deviceAction.applyUpload(context.device, p as unknown as UploadParameter, () => Promise.resolve(''))
|
||||
}
|
||||
case CommandType.REBOOT: {
|
||||
const p = (params as Record<string, unknown>) || {}
|
||||
return context.services.deviceAction.applyReboot(context.device, p as import('../../services/cwmp/device_action_executor.js').RebootParameter, () => Promise.resolve(''))
|
||||
return context.services.deviceAction.applyReboot(context.device, p as RebootParameter, () => Promise.resolve(''))
|
||||
}
|
||||
case CommandType.FACTORY_RESET: {
|
||||
return context.services.deviceAction.applyFactoryReset(context.device, {}, () => Promise.resolve(''))
|
||||
|
||||
@@ -89,14 +89,10 @@ describe('Device', () => {
|
||||
d.setProperty(new DeviceProperty('Device.ManagementServer.PeriodicInformInterval', '60'))
|
||||
d.setProperty(new DeviceProperty('Device.DeviceInfo.Manufacturer', 'Sagemcom'))
|
||||
d.organizeParameters(
|
||||
{
|
||||
ParameterList: {
|
||||
ParameterInfoStruct: [
|
||||
{ Name: 'Device.ManagementServer.PeriodicInformInterval', Writable: '1' },
|
||||
{ Name: 'Device.DeviceInfo.Manufacturer', Writable: '0' },
|
||||
],
|
||||
},
|
||||
},
|
||||
[
|
||||
{ Name: 'Device.ManagementServer.PeriodicInformInterval', Writable: '1' },
|
||||
{ Name: 'Device.DeviceInfo.Manufacturer', Writable: '0' },
|
||||
],
|
||||
new Date()
|
||||
)
|
||||
// Writable=1 → parameter, Writable=0 → property
|
||||
@@ -153,7 +149,7 @@ describe('Device', () => {
|
||||
|
||||
it('clearTmpValues resets temporary state', () => {
|
||||
const d = makeDevice()
|
||||
d.setTmpParamValues([{ x: 1 }])
|
||||
d.setTmpParamValues([{ Name: 'Device.X', Value: { _: '1' } }])
|
||||
d.tmpPC = 'code'
|
||||
d.clearTmpValues()
|
||||
expect(d.getTmpParamValues()).toEqual([])
|
||||
@@ -163,9 +159,7 @@ describe('Device', () => {
|
||||
it('organizeParameters moves writable property to parameter', () => {
|
||||
const d = makeDevice()
|
||||
d.setProperty(new DeviceProperty('Device.X', 'val'))
|
||||
d.organizeParameters({
|
||||
ParameterList: { ParameterInfoStruct: [{ Name: 'Device.X', Writable: '1' }] },
|
||||
}, new Date())
|
||||
d.organizeParameters([{ Name: 'Device.X', Writable: '1' }], new Date())
|
||||
expect(d.getParameter('Device.X')).toBeDefined()
|
||||
expect(d.getProperty('Device.X')).toBeNull()
|
||||
})
|
||||
@@ -173,34 +167,26 @@ describe('Device', () => {
|
||||
it('organizeParameters moves non-writable parameter to property', () => {
|
||||
const d = makeDevice()
|
||||
d.setParameter(new DeviceParameter('Device.Y', 'val'))
|
||||
d.organizeParameters({
|
||||
ParameterList: { ParameterInfoStruct: [{ Name: 'Device.Y', Writable: 0 }] },
|
||||
}, new Date())
|
||||
d.organizeParameters([{ Name: 'Device.Y', Writable: 0 }], new Date())
|
||||
expect(d.getProperty('Device.Y')).toBeDefined()
|
||||
expect(d.getParameter('Device.Y')).toBeNull()
|
||||
})
|
||||
|
||||
it('organizeParameters adds new writable as parameter', () => {
|
||||
const d = makeDevice()
|
||||
d.organizeParameters({
|
||||
ParameterList: { ParameterInfoStruct: [{ Name: 'Device.New.Param', Writable: '1' }] },
|
||||
}, new Date())
|
||||
d.organizeParameters([{ Name: 'Device.New.Param', Writable: '1' }], new Date())
|
||||
expect(d.getParameter('Device.New.Param')).toBeDefined()
|
||||
})
|
||||
|
||||
it('organizeParameters adds new non-writable as property', () => {
|
||||
const d = makeDevice()
|
||||
d.organizeParameters({
|
||||
ParameterList: { ParameterInfoStruct: [{ Name: 'Device.New.Prop', Writable: '0' }] },
|
||||
}, new Date())
|
||||
d.organizeParameters([{ Name: 'Device.New.Prop', Writable: '0' }], new Date())
|
||||
expect(d.getProperty('Device.New.Prop')).toBeDefined()
|
||||
})
|
||||
|
||||
it('organizeParameters skips object paths (ending with dot)', () => {
|
||||
const d = makeDevice()
|
||||
d.organizeParameters({
|
||||
ParameterList: { ParameterInfoStruct: [{ Name: 'Device.Info.', Writable: '1' }] },
|
||||
}, new Date())
|
||||
d.organizeParameters([{ Name: 'Device.Info.', Writable: '1' }], new Date())
|
||||
expect(d.getParameter('Device.Info.')).toBeNull()
|
||||
expect(d.getProperty('Device.Info.')).toBeNull()
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user