onvif-nvt-ts
Version:
Wrapper for ONVIF spec to control NVT (Network Video Transitter) devices. Forked and added TypeScript support from onvif-nvt.
145 lines (129 loc) • 3.99 kB
text/typescript
import Crypto from 'crypto'
import Xml2js from 'xml2js'
export function URLWithEnforcedPort(xaddr: string, port: number) {
const badURL = new URL(xaddr)
if (badURL.origin.endsWith(`:${port}`)) return badURL
const idx = badURL.origin.indexOf(':', 6)
const originWithoutPort = badURL.origin.slice(0, idx < 0 ? badURL.origin.length : idx)
return new URL(xaddr.replace(badURL.origin, `${originWithoutPort}:${port}`))
}
export function createUuidV4() {
const clist = Crypto.randomBytes(16).toString('hex').toLowerCase().split('')
clist[12] = '4'
clist[16] = ((parseInt(clist[16], 16) & 3) | 8).toString(16)
const m = clist.join('').match(/^(.{8})(.{4})(.{4})(.{4})(.{12})/)
const uuid = [m[1], m[2], m[3], m[4], m[5]].join('-')
return uuid
}
export function getTypeOfValue(value: any) {
if (value === undefined) {
return 'undefined'
} else if (value === null) {
return 'null'
} else if (Array.isArray(value)) {
return 'array'
}
const t = typeof value
if (t === 'boolean') {
return 'boolean'
} else if (t === 'string') {
return 'string'
} else if (t === 'number') {
if (value % 1 === 0) {
return 'integer'
} else {
return 'float'
}
} else if (t === 'object') {
if (Object.prototype.toString.call(value) === '[object Object]') {
return 'object'
} else {
return 'unknown'
}
} else if (t === 'function') {
return 'function'
} else {
return 'unknown'
}
}
export function isValidCallback(callback) {
return !!(callback && typeof callback === 'function')
}
export function execCallback(callback, arg1, arg2) {
if (isValidCallback(callback)) {
callback(arg1, arg2)
}
}
export function isXml(xml: string) {
if (!xml) {
return false
}
const opts = {
explicitRoot: false,
explicitArray: false,
// 'ignoreAttrs' : true,
ignoreAttrs: false,
tagNameProcessors: [
function (name: string) {
// strip namespaces
/* eslint-disable no-useless-escape */
const m = name.match(/^([^\:]+)\:([^\:]+)$/)
/* eslint-enable no-useless-escape */
return m ? m[2] : name
}
]
}
let retVal = false
Xml2js.parseString(xml, opts, (error, results) => {
if (error) {
console.log(`isXml: ${xml} is not xml`, error)
retVal = false
} else {
retVal = true
}
})
return retVal
}
export function isInvalidValue(value: any, type: string, allowEmpty?: boolean) {
const vt = getTypeOfValue(value)
// special handling for type 'xml' as typeof will be 'string'
if (type === 'xml') {
if (!isXml(value)) {
return ' The type of the value must be a"' + type + '".'
}
}
if (type === 'float') {
/* eslint-disable no-useless-escape */
if (!vt.match(/^(float|integer)$/)) {
/* eslint-enable no-useless-escape */
return ' The type of the value must be a "' + type + '".'
}
} else {
if (vt !== type && type !== 'xml') {
return ' The type of the value must be a "' + type + '".'
}
}
if (!allowEmpty) {
if (vt === 'array' && value.length === 0) {
return ' The value must not be an empty array.'
} else if (vt === 'string' && value === '') {
return ' The value must not be an empty string.'
}
}
if (typeof value === 'string') {
/* eslint-disable no-useless-escape */
if (value.match(/[^\x20-\x7e]/)) {
/* eslint-enable no-useless-escape */
return ' The value must consist of ascii characters.'
} else if (type !== 'xml' && value.match(/[\<\>]/)) {
/* eslint-disable no-useless-escape */
/* eslint-enable no-useless-escape */
return ' Invalid characters were found in the value ("<", ">")'
} else if (type === 'xml' && !value.match(/[\<\>]/)) {
/* eslint-disable no-useless-escape */
/* eslint-enable no-useless-escape */
return ' Valid characters were found in the value for xml ("<", ">")'
}
}
return ''
}