rcs-data
Version:
RCS消息数据结构
311 lines • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThumbnailInfo = exports.FileInfo = exports.FileData = exports.File = void 0;
const RcsMsgInitial_1 = require("./RcsMsgInitial");
const mime_1 = require("../mime");
const fast_xml_parser_1 = require("fast-xml-parser");
const debug = require('debug')('rcs:file');
class FileData {
constructor(url, until) {
this._url = url;
this._until = until;
}
get url() {
return this._url;
}
get until() {
return this._until;
}
}
exports.FileData = FileData;
class BaseInfo {
constructor(size, url, type) {
this._size = size;
this._data = url;
this._type = type;
}
get size() {
return this._size;
}
set size(value) {
this._size = value;
}
get type() {
return this._type;
}
set type(value) {
this._type = value;
}
get data() {
return this._data;
}
set url(value) {
this._data = value;
}
forXml() {
let result = {};
if (this.size !== undefined && this.size !== null)
result['file-size'] = this.size;
if (this.type !== undefined && this.size !== null)
result['content-type'] = this.type;
if (this.data && this.data.url && typeof this.data.until !== "undefined")
result['data'] = { '@_url': this.data.url, '@_until': this.data.until };
return result;
}
}
class FileInfo extends BaseInfo {
constructor(name, size, url, type) {
super(size, url, type);
this._name = name;
}
get name() {
return this._name;
}
set name(value) {
this._name = value;
}
forXml() {
let obj = super.forXml();
obj['@_type'] = 'file';
obj['file-name'] = this.name;
return obj;
}
copy(data) {
this.size = parseInt(typeof data.size !== "undefined" ? data.size : null || typeof data.fileSize !== "undefined" ? data.fileSize : null);
this.name = data.name || data.fileName;
this.type = data.type || data.contentType;
if (typeof data.url === 'string' && typeof data.until === 'string') {
this.url = new FileData(data.url, data.until);
}
else {
this.url = data.data || data.url;
}
}
toJSON() {
let json = {
type: 'file',
fileSize: this.size,
fileName: this.name,
contentType: this.type,
url: this.data.url,
until: this.data.until,
};
return json;
}
static build(input) {
let name = input.hasOwnProperty('fileName')
? input.fileName
: input.hasOwnProperty('name')
? input.name
: undefined;
let size = input.hasOwnProperty('fileSize')
? input.fileSize
: input.hasOwnProperty('size')
? input.size
: undefined;
let type = input.hasOwnProperty('contentType')
? input.contentType
: input.hasOwnProperty('type')
? input.type
: undefined;
let url = input.hasOwnProperty('url')
? input.url
: input.hasOwnProperty('data')
? input.data.url
: undefined;
let until = input.hasOwnProperty('until')
? input.until
: input.hasOwnProperty('data')
? input.data.until
: undefined;
return new FileInfo(name, size, new FileData(url, until), type);
}
}
exports.FileInfo = FileInfo;
class ThumbnailInfo extends BaseInfo {
constructor(size, url, type) {
super(size, url, type);
}
forXml() {
let obj = super.forXml();
obj['@_type'] = 'thumbnail';
return obj;
}
copy(data) {
this.size = parseInt(typeof data.size !== "undefined" ? data.size : null || typeof data.fileSize !== "undefined" ? data.fileSize : null);
this.type = data.contentType || data.type;
if (typeof data.url === 'string' && typeof data.until === 'string') {
this.url = new FileData(data.url, data.until);
}
else {
this.url = data.data || data.url;
}
}
toJSON() {
let json = {
type: 'thumbnail',
fileSize: this.size,
contentType: this.type,
url: this.data.url,
until: this.data.until,
};
return json;
}
static build(input) {
let size = input.hasOwnProperty('fileSize')
? input.fileSize
: input.hasOwnProperty('size')
? input.size
: undefined;
let type = input.hasOwnProperty('contentType')
? input.contentType
: input.hasOwnProperty('type')
? input.type
: undefined;
let url = input.hasOwnProperty('url')
? input.url
: input.hasOwnProperty('data')
? input.data.url
: undefined;
let until = input.hasOwnProperty('until')
? input.until
: input.hasOwnProperty('data')
? input.data.until
: undefined;
return new ThumbnailInfo(size, new FileData(url, until), type);
}
}
exports.ThumbnailInfo = ThumbnailInfo;
class File extends RcsMsgInitial_1.RcsMsgInitial {
constructor(file, thumbnail) {
if (!file)
file = new FileInfo();
if (!thumbnail)
thumbnail = new ThumbnailInfo();
const builder = new fast_xml_parser_1.XMLBuilder({
format: true,
ignoreAttributes: false,
suppressEmptyNode: true,
});
builder['tagEndChar'] = '>\r\n';
builder['newLine'] = '\r\n';
let body = () => {
const infoXmls = [];
if (this.thumbnailValid)
infoXmls.push(this._thumbnail.forXml());
if (this._file)
infoXmls.push(this._file.forXml());
let body = builder.build({
file: {
'@_xmlns': 'urn:gsma:params:xml:ns:rcs:rcs:fthttp',
'file-info': infoXmls,
},
});
body = '<?xml version="1.0" encoding="UTF-8"?>\r\n' + body;
mime.header('Content-Length', `${body.length}`);
return body;
};
let mime = (0, mime_1.factory)({
contentType: 'application/vnd.gsma.rcs-ft-http+xml',
body,
});
super(mime);
this._file = file;
this._thumbnail = thumbnail;
}
get thumbnailValid() {
return !!(this._thumbnail &&
this._thumbnail.data &&
this._thumbnail.data.url);
}
get content() {
let { _file: file, _thumbnail: thumbnail } = this;
let thumbnailValid = this.thumbnailValid;
return { file, thumbnail, thumbnailValid };
}
get messagePlainObject() {
let msg = {
contentType: 'application/vnd.gsma.rcs-ft-http',
contentEncoding: 'utf8',
contentText: [],
};
if (this._thumbnail)
msg.contentText.push(this._thumbnail.toJSON());
if (this._file)
msg.contentText.push(this._file.toJSON());
return msg;
}
static parse(raw) {
let file, thumbnail;
if (typeof raw === 'string') {
debug(`收到要解析的文本:${raw}`);
let options = { attributeNamePrefix: '', ignoreAttributes: false };
const parser = new fast_xml_parser_1.XMLParser(options);
let jObj = parser.parse(raw);
debug(`解析后的对象:${JSON.stringify(jObj, null, 2)}`);
if (Array.isArray(jObj.file['file-info'])) {
for (let i = 0, l = jObj.file['file-info'].length; i < l; i++) {
let xmlInfo = jObj.file['file-info'][i];
let { url, until } = xmlInfo.data;
let size = xmlInfo['file-size'];
let ctype = xmlInfo['content-type'];
let oUrl = new FileData(url, until);
if (xmlInfo.type === 'file') {
file = new FileInfo(xmlInfo['file-name'], size, oUrl, ctype);
}
else if (xmlInfo.type === 'thumbnail') {
thumbnail = new ThumbnailInfo(size, oUrl, ctype);
}
}
}
else if (Object.prototype.toString.call(jObj.file['file-info']) === "[object Object]") {
let xmlInfo = jObj.file['file-info'];
let { url, until } = xmlInfo.data;
let size = xmlInfo['file-size'];
let ctype = xmlInfo['content-type'];
let oUrl = new FileData(url, until);
if (xmlInfo.type === 'file') {
file = new FileInfo(xmlInfo['file-name'], size, oUrl, ctype);
}
else if (xmlInfo.type === 'thumbnail') {
thumbnail = new ThumbnailInfo(size, oUrl, ctype);
}
}
}
else if (Array.isArray(raw) && raw.length > 0) {
const parse = (data) => {
if (data['type'] === 'file') {
file = new FileInfo();
file.copy(data);
}
else if (data['type'] === 'thumbnail') {
thumbnail = new ThumbnailInfo();
thumbnail.copy(data);
}
};
parse(raw[0]);
if (raw.length > 1)
parse(raw[1]);
}
return new File(file, thumbnail);
}
static build(input) {
if (!Array.isArray(input) || input.length < 1 || input.length > 2)
throw Error('参数错误,必须是数组,长度为1或2');
let thumbnail, file;
input.forEach((i) => {
if (i.type == 'thumbnail') {
thumbnail = ThumbnailInfo.build(i);
}
else if (i.type === 'file') {
file = FileInfo.build(i);
}
});
if (!file)
throw Error('构造文件消息对象失败,没有提供文件信息');
let rcsfile = new File(file, thumbnail);
return rcsfile;
}
}
exports.File = File;
//# sourceMappingURL=File.js.map