mos-connection
Advanced tools
Comparing version 0.3.17 to 0.4.0
@@ -5,2 +5,25 @@ # Change Log | ||
<a name="0.4.0"></a> | ||
# [0.4.0](https://github.com/nrkno/tv-automation-mos-connection/compare/0.3.17...0.4.0) (2018-08-03) | ||
### Bug Fixes | ||
* changes in parser when data structures has changed ([4491b8f](https://github.com/nrkno/tv-automation-mos-connection/commit/4491b8f)) | ||
* metadata tag might be empty ([897df5c](https://github.com/nrkno/tv-automation-mos-connection/commit/897df5c)) | ||
* mosString, flat attributes and removed usage of xml2json ([92bbe41](https://github.com/nrkno/tv-automation-mos-connection/commit/92bbe41)) | ||
* single child xml data ([b3dc170](https://github.com/nrkno/tv-automation-mos-connection/commit/b3dc170)) | ||
* tests ([cdea898](https://github.com/nrkno/tv-automation-mos-connection/commit/cdea898)) | ||
* update xml2Body to retain order ([681fd68](https://github.com/nrkno/tv-automation-mos-connection/commit/681fd68)) | ||
* xml2js: changed internal structure to $name & $type, instead of name & type, to avoid collisions ([1706185](https://github.com/nrkno/tv-automation-mos-connection/commit/1706185)) | ||
### Features | ||
* added dependency on xml-js ([f2ac082](https://github.com/nrkno/tv-automation-mos-connection/commit/f2ac082)) | ||
* keep order of tags inside some fields ([95fe1f8](https://github.com/nrkno/tv-automation-mos-connection/commit/95fe1f8)) | ||
* tweaked the parsing, got the test to pass ([ec9c3bd](https://github.com/nrkno/tv-automation-mos-connection/commit/ec9c3bd)) | ||
<a name="0.3.17"></a> | ||
@@ -7,0 +30,0 @@ ## [0.3.17](https://github.com/nrkno/tv-automation-mos-connection/compare/0.3.16...0.3.17) (2018-06-15) |
@@ -126,2 +126,3 @@ import { IProfiles } from './config/connectionConfig'; | ||
Slug?: MosString128; | ||
ObjectSlug?: MosString128; | ||
ObjectID: MosString128; | ||
@@ -200,9 +201,9 @@ MOSID: string; | ||
TimeBase: number; | ||
Revision: number; | ||
Revision?: number; | ||
Duration: number; | ||
Status: IMOSObjectStatus; | ||
AirStatus: IMOSObjectAirStatus; | ||
Status?: IMOSObjectStatus; | ||
AirStatus?: IMOSObjectAirStatus; | ||
Paths: Array<IMOSObjectPath>; | ||
CreatedBy: MosString128; | ||
Created: MosTime; | ||
CreatedBy?: MosString128; | ||
Created?: MosTime; | ||
ChangedBy?: MosString128; | ||
@@ -212,2 +213,3 @@ Changed?: MosTime; | ||
MosExternalMetaData?: Array<IMOSExternalMetaData>; | ||
MosItemEditorProgID?: MosString128; | ||
} | ||
@@ -218,2 +220,3 @@ export declare enum IMOSObjectType { | ||
VIDEO = "VIDEO", | ||
OTHER = "OTHER", | ||
} | ||
@@ -220,0 +223,0 @@ export declare enum IMOSObjectStatus { |
@@ -8,2 +8,3 @@ "use strict"; | ||
IMOSObjectType["VIDEO"] = "VIDEO"; | ||
IMOSObjectType["OTHER"] = "OTHER"; // unknown/not speficied | ||
})(IMOSObjectType = exports.IMOSObjectType || (exports.IMOSObjectType = {})); | ||
@@ -10,0 +11,0 @@ var IMOSObjectStatus; |
@@ -6,9 +6,4 @@ "use strict"; | ||
const socketConnection_1 = require("./socketConnection"); | ||
const parser = require("xml2json"); | ||
const Utils_1 = require("../utils/Utils"); | ||
const iconv = require('iconv-lite'); | ||
const parseOptions = { | ||
'object': true, | ||
coerce: true, | ||
trim: true | ||
}; | ||
class MosSocketClient extends events_1.EventEmitter { | ||
@@ -256,3 +251,3 @@ /** */ | ||
// Data ready to be parsed: | ||
parsedData = parser.toJson(messageString, parseOptions); | ||
parsedData = Utils_1.xml2js(messageString); // , { compact: true, trim: true, nativeType: true }) | ||
this.dataChunks = ''; | ||
@@ -262,3 +257,3 @@ } | ||
// Last chunk, ready to parse with saved data: | ||
parsedData = parser.toJson(this.dataChunks + messageString, parseOptions); | ||
parsedData = Utils_1.xml2js(this.dataChunks); // , { compact: true, trim: true, nativeType: true }) | ||
this.dataChunks = ''; | ||
@@ -276,2 +271,3 @@ } | ||
if (parsedData) { | ||
// console.log(parsedData, newParserData) | ||
let messageId = parsedData.mos.messageID; | ||
@@ -278,0 +274,0 @@ if (messageId) { |
@@ -8,5 +8,8 @@ export declare class MosString128 { | ||
/** */ | ||
string: string; | ||
string: string | { | ||
text: string; | ||
type: string; | ||
}; | ||
/** */ | ||
private _validate(); | ||
} |
@@ -6,3 +6,8 @@ "use strict"; | ||
constructor(str) { | ||
this.string = '' + str + ''; | ||
if (typeof str === 'object' && str.text) { | ||
this.string = str.text; | ||
} | ||
else { | ||
this.string = '' + str + ''; | ||
} | ||
} | ||
@@ -15,3 +20,8 @@ /** */ | ||
set string(str) { | ||
this._str = str; | ||
if (typeof str === 'object' && str.type === 'text') { | ||
this._str = str.text; | ||
} | ||
else { | ||
this._str = '' + str + ''; | ||
} | ||
this._validate(); | ||
@@ -18,0 +28,0 @@ } |
@@ -9,3 +9,3 @@ "use strict"; | ||
const NCSServerConnection_1 = require("./connection/NCSServerConnection"); | ||
const parser = require("xml2json"); | ||
const Utils_1 = require("./utils/Utils"); | ||
const MosMessage_1 = require("./mosModel/MosMessage"); | ||
@@ -273,7 +273,2 @@ const mosAck_1 = require("./mosModel/mosAck"); | ||
let parsed = null; | ||
let parseOptions = { | ||
object: true, | ||
coerce: true, | ||
trim: true | ||
}; | ||
let firstMatch = '<mos>'; // <mos> | ||
@@ -290,11 +285,11 @@ let first = messageString.substr(0, firstMatch.length); | ||
// Data ready to be parsed: | ||
parsed = parser.toJson(messageString, parseOptions); | ||
parsed = Utils_1.xml2js(messageString); | ||
} | ||
else if (last === lastMatch) { | ||
// Last chunk, ready to parse with saved data: | ||
parsed = parser.toJson(client.chunks + messageString, parseOptions); | ||
parsed = Utils_1.xml2js(client.chunks + messageString); | ||
client.chunks = ''; | ||
} | ||
else if (first === firstMatch) { | ||
// Chunk, save for later: | ||
// First chunk, save for later: | ||
client.chunks = messageString; | ||
@@ -301,0 +296,0 @@ } |
@@ -8,3 +8,2 @@ "use strict"; | ||
const mosDuration_1 = require("../dataTypes/mosDuration"); | ||
const parser = require("xml2json"); | ||
const ROAck_1 = require("../mosModel/ROAck"); | ||
@@ -171,2 +170,8 @@ function isEmpty(obj) { | ||
item.MosExternalMetaData = xml2MetaData(xml.mosExternalMetadata); | ||
if (xml.hasOwnProperty('mosAbstract')) | ||
item.mosAbstract = xml.mosAbstract + ''; | ||
if (xml.hasOwnProperty('objSlug')) | ||
item.ObjectSlug = new mosString128_1.MosString128(xml.objSlug); | ||
if (xml.hasOwnProperty('itemChannel')) | ||
item.Channel = new mosString128_1.MosString128(xml.itemChannel); | ||
if (xml.hasOwnProperty('mosObj')) { | ||
@@ -206,7 +211,7 @@ // Note: the <mosObj> is sent in roStorySend | ||
} | ||
if (type) { | ||
if (type && Object.keys(xmlPath.o).length > 0) { | ||
paths.push({ | ||
Type: type, | ||
Description: xmlPath.o.techDescription, | ||
Target: xmlPath.o.$t | ||
Description: xmlPath.o.techDescription || xmlPath.o.attributes.techDescription, | ||
Target: xmlPath.o.text || xmlPath.o.$t | ||
}); | ||
@@ -282,2 +287,18 @@ } | ||
Parser.item2xml = item2xml; | ||
function fixPayload(obj) { | ||
if (typeof obj === 'object') { | ||
for (let key in obj) { | ||
let o = obj[key]; | ||
if (typeof o === 'object') { | ||
if (isEmpty(o)) { | ||
obj[key] = ''; | ||
} | ||
else { | ||
fixPayload(o); | ||
} | ||
} | ||
} | ||
} | ||
return obj; | ||
} | ||
function xml2MetaData(xml) { | ||
@@ -293,3 +314,3 @@ if (!xml) | ||
MosSchema: xmlmd.mosSchema + '', | ||
MosPayload: xmlmd.mosPayload | ||
MosPayload: fixPayload(xmlmd.mosPayload) | ||
}; | ||
@@ -301,9 +322,10 @@ return md; | ||
function metaData2xml(md) { | ||
let xmlMD = XMLBuilder.create('mosExternalMetadata'); | ||
if (md.MosScope) | ||
xmlMD.ele('mosScope', {}, md.MosScope); | ||
xmlMD.ele('mosSchema', {}, md.MosSchema); | ||
let payload = parser.toXml(md.MosPayload); // TODO: implement this properly, convert to xml | ||
xmlMD.ele('mosPayload', {}, payload); | ||
return xmlMD; | ||
// let xmlMD = XMLBuilder.create('mosExternalMetadata') | ||
// if (md.MosScope) xmlMD.ele('mosScope', {}, md.MosScope) | ||
// xmlMD.ele('mosSchema', {}, md.MosSchema) | ||
// let payload = parser.toXml(md.MosPayload) // TODO: implement this properly, convert to xml | ||
// let payload = js2xml({ mosExternalMetadata: md }, { compact: true }) | ||
return XMLBuilder.create({ mosExternalMetadata: md }); | ||
// xmlMD.ele('mosPayload', {}, payload) | ||
// return xmlMD | ||
} | ||
@@ -404,2 +426,4 @@ Parser.metaData2xml = metaData2xml; | ||
mosObj.MosExternalMetaData = xml2MetaData(xml.mosExternalMetadata); | ||
if (xml.hasOwnProperty('mosItemEditorProgID')) | ||
mosObj.MosItemEditorProgID = new mosString128_1.MosString128(xml.mosItemEditorProgID); | ||
return mosObj; | ||
@@ -465,2 +489,14 @@ } | ||
*/ | ||
if (xml.elements && Array.isArray(xml.elements)) { | ||
for (const item of xml.elements) { | ||
let bodyItem = { | ||
Type: item.$name || item.$type, | ||
Content: item | ||
}; | ||
if (item.$name === 'storyItem') { | ||
bodyItem.Content = xml2Item(item); | ||
} | ||
body.push(bodyItem); | ||
} | ||
} | ||
// Temporary implementation: | ||
@@ -467,0 +503,0 @@ if (xml.storyItem) { |
/** */ | ||
export declare function pad(n: string, width: number, z?: string): string; | ||
export declare function xml2js(messageString: string): object; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const xml_js_1 = require("xml-js"); | ||
/** */ | ||
@@ -10,2 +11,152 @@ function pad(n, width, z) { | ||
exports.pad = pad; | ||
function xml2js(messageString) { | ||
let object = xml_js_1.xml2js(messageString, { compact: false, trim: true, nativeType: true }); | ||
// common tags we typically want to know the order of the contents of: | ||
const orderedTags = new Set(['storyBody', 'mosAbstract', 'description', 'p', 'em', 'span', 'h1', 'h2', 'i', 'b']); | ||
/** | ||
* Doing a post-order tree traversal we try to make the objectified tree as compact as possible. | ||
* Whenever we find an "orderedTag" we keep the order of it's children. | ||
* | ||
* ps: post-order means we make a node's children as compact as possible first, and then try to make | ||
* that node compact. | ||
*/ | ||
const concatChildrenAndTraverseObject = (element) => { | ||
if (element.name) { | ||
element.$name = element.name; | ||
delete element.name; | ||
} | ||
if (element.type) { | ||
element.$type = element.type; | ||
delete element.type; | ||
} | ||
if (element.elements) { | ||
if (element.elements.length === 1) { | ||
concatChildrenAndTraverseObject(element.elements[0]); | ||
const childEl = element.elements[0]; | ||
const name = childEl.$name || childEl.$type || 'unknownElement'; | ||
if (childEl.$type && childEl.$type === 'text') { | ||
element.$type = 'text'; | ||
element.text = childEl.text; | ||
} | ||
else { | ||
delete childEl.$name; | ||
delete childEl.$type; | ||
element[name] = element.elements[0]; | ||
} | ||
delete element.elements; | ||
if (childEl.$type === 'text') { | ||
element[name] = childEl.text; | ||
if (childEl.attributes) { | ||
for (const key in childEl.attributes) { | ||
element[key] = childEl.attributes[key]; | ||
} | ||
delete childEl.attributes; | ||
} | ||
} | ||
} | ||
else if (element.elements.length > 1) { | ||
for (const childEl of element.elements) { | ||
concatChildrenAndTraverseObject(childEl); | ||
} | ||
if (!orderedTags.has(element.$name)) { // if the element name is contained in the set of orderedTag names we don't make it any more compact | ||
let names = element.elements.map((obj) => obj.$name || obj.$type || 'unknownElement'); | ||
let namesSet = new Set(names); | ||
if ((namesSet.size === 1 && names.length !== 1) && !namesSet.has('type') && !namesSet.has('name')) { | ||
// make array compact: | ||
const array = []; | ||
for (const childEl of element.elements) { | ||
if (childEl.$type && childEl.$type === 'text') { | ||
if (Object.keys(childEl).length > 2) { | ||
array.push(childEl); | ||
} | ||
else if (childEl.attributes) { | ||
childEl.attributes.text = childEl.text; | ||
array.push(childEl.attributes); | ||
} | ||
else { | ||
array.push(childEl.text); | ||
} | ||
} | ||
else { | ||
if (childEl.$type) | ||
delete childEl.$type; | ||
if (childEl.$name) | ||
delete childEl.$name; | ||
if (Object.keys(childEl).length > 1) { | ||
// might contain something useful like attributes | ||
if (childEl.attributes) { | ||
for (const key in childEl.attributes) { | ||
childEl[key] = childEl.attributes[key]; | ||
} | ||
delete childEl.attributes; | ||
} | ||
array.push(childEl); | ||
} | ||
else { | ||
array.push(childEl[Object.keys(childEl)[0]]); | ||
} | ||
} | ||
} | ||
element[names[0]] = array; | ||
delete element.elements; | ||
} | ||
else if (names.length === namesSet.size) { | ||
// all elements are unique | ||
for (const childEl of element.elements) { | ||
if (childEl.$type && childEl.$type === 'text' && (Object.keys(childEl).length <= 3 || (!childEl.$name && Object.keys(childEl).length < 3))) { | ||
if (!childEl.text) { | ||
element.text = childEl.text; | ||
} | ||
element[childEl.$name] = childEl.text; | ||
} | ||
else { | ||
if (childEl.attributes) { | ||
for (const key in childEl.attributes) { | ||
childEl[key] = childEl.attributes[key]; | ||
} | ||
delete childEl.attributes; | ||
} | ||
const name = childEl.$name || childEl.$type || 'unknownEl'; | ||
if (childEl.$type) | ||
delete childEl.$type; | ||
if (childEl.$name) | ||
delete childEl.$name; | ||
element[name] = childEl; | ||
} | ||
} | ||
delete element.elements; | ||
} | ||
else if (names.length !== namesSet.size) { | ||
const holder = {}; | ||
for (let childEl of element.elements) { | ||
const name = childEl.$name; | ||
if (childEl.$type === 'text' && Object.keys(childEl).length <= 3) { | ||
childEl = childEl.text; | ||
} | ||
else if (childEl.attributes) { | ||
for (const key in childEl.attributes) { | ||
childEl[key] = childEl.attributes[key]; | ||
} | ||
delete childEl.attributes; | ||
} | ||
if (holder[name]) { | ||
holder[name].push(childEl); | ||
} | ||
else { | ||
holder[name] = [childEl]; | ||
} | ||
} | ||
for (const key in holder) { | ||
element[key] = holder[key].length > 1 ? holder[key] : holder[key][0]; | ||
} | ||
delete element.elements; | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
concatChildrenAndTraverseObject(object); | ||
return object; | ||
} | ||
exports.xml2js = xml2js; | ||
//# sourceMappingURL=Utils.js.map |
{ | ||
"name": "mos-connection", | ||
"version": "0.3.17", | ||
"version": "0.4.0", | ||
"description": "MOS compliant TCP/IP Socket connection.", | ||
@@ -120,9 +120,6 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@types/xml2js": "^0.4.2", | ||
"@types/xml2json": "^0.10.0", | ||
"@types/xmlbuilder": "^0.0.32", | ||
"moment": "^2.20.1", | ||
"tslib": "^1.6.0", | ||
"xml2js": "^0.4.19", | ||
"xml2json": "^0.11.2", | ||
"xml-js": "^1.6.4", | ||
"xmlbuilder": "^9.0.7" | ||
@@ -129,0 +126,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
306822
5
4245
+ Addedxml-js@^1.6.4
+ Addedxml-js@1.6.11(transitive)
- Removed@types/xml2js@^0.4.2
- Removed@types/xml2json@^0.10.0
- Removedxml2js@^0.4.19
- Removedxml2json@^0.11.2
- Removed@types/node@22.10.10(transitive)
- Removed@types/xml2js@0.4.14(transitive)
- Removed@types/xml2json@0.10.0(transitive)
- Removedbindings@1.5.0(transitive)
- Removedfile-uri-to-path@1.0.0(transitive)
- Removedhoek@4.3.15.0.46.1.3(transitive)
- Removedisemail@3.2.0(transitive)
- Removedjoi@13.7.0(transitive)
- Removednan@2.22.0(transitive)
- Removednode-expat@2.4.1(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedtopo@3.0.3(transitive)
- Removedundici-types@6.20.0(transitive)
- Removedxml2js@0.4.23(transitive)
- Removedxml2json@0.11.2(transitive)
- Removedxmlbuilder@11.0.1(transitive)