UNPKG

@astronautlabs/amf

Version:

Action Message Format (AMF0/3)

616 lines 21.2 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import { BitstreamElement, Field, Variant, ReservedLow, VariantMarker } from "@astronautlabs/bitstream"; import * as AMF3 from './amf3'; export var TypeMarker; (function (TypeMarker) { TypeMarker[TypeMarker["Number"] = 0] = "Number"; TypeMarker[TypeMarker["Boolean"] = 1] = "Boolean"; TypeMarker[TypeMarker["String"] = 2] = "String"; TypeMarker[TypeMarker["Object"] = 3] = "Object"; TypeMarker[TypeMarker["MovieClip"] = 4] = "MovieClip"; TypeMarker[TypeMarker["Null"] = 5] = "Null"; TypeMarker[TypeMarker["Undefined"] = 6] = "Undefined"; TypeMarker[TypeMarker["Reference"] = 7] = "Reference"; TypeMarker[TypeMarker["EcmaArray"] = 8] = "EcmaArray"; TypeMarker[TypeMarker["ObjectEnd"] = 9] = "ObjectEnd"; TypeMarker[TypeMarker["StrictArray"] = 10] = "StrictArray"; TypeMarker[TypeMarker["Date"] = 11] = "Date"; TypeMarker[TypeMarker["LongString"] = 12] = "LongString"; TypeMarker[TypeMarker["Unsupported"] = 13] = "Unsupported"; TypeMarker[TypeMarker["RecordSet"] = 14] = "RecordSet"; TypeMarker[TypeMarker["XmlDocument"] = 15] = "XmlDocument"; TypeMarker[TypeMarker["TypedObject"] = 16] = "TypedObject"; TypeMarker[TypeMarker["AvmPlus"] = 17] = "AvmPlus"; // x })(TypeMarker || (TypeMarker = {})); export class Value extends BitstreamElement { get referenceTable() { if (!this._referenceTable) { if (this.context) { if (this.context.__references) { this._referenceTable = this.context.__references; } else { this.context.__references = this._referenceTable = []; } } } return this._referenceTable; } get value() { return undefined; } set value(value) { throw new Error(`Cannot set value [${this.constructor.name}]`); } static get undefined() { return new UndefinedValue(); } static get true() { return this.boolean(true); } static get false() { return this.boolean(false); } static boolean(value) { return new BooleanValue().with({ value }); } static number(value) { return new NumberValue().with({ value }); } static string(value) { if (value.length > 0xFFFF) return new LongStringValue().with({ value }); else return new StringValue().with({ value }); } static xmlDocument(value) { return new XmlDocumentValue().with({ value }); } static object(value, className) { if (value === null || value === void 0 || typeof value !== 'object') throw new Error(`Invalid value for object: ${value}`); if (className) return new TypedObjectValue().with({ value, className }); else return new ObjectValue().with({ value }); } static get null() { return new NullValue(); } static date(value) { return new DateValue().with({ value }); } static array(value) { return new StrictArrayValue().with({ value }); } static associativeArray(value) { if (value instanceof Map) return new EcmaArrayValue().with({ value }); else return new EcmaArrayValue().with({ value: new Map(Object.keys(value).map(key => [key, value[key]])) }); } static any(value) { if (value instanceof Value) return value; if (value === void 0) return this.undefined; if (value === true) return this.true; if (value === false) return this.false; if (value === null) return this.null; if (typeof value === 'number') return this.number(value); if (typeof value === 'string') return this.string(value); if (value instanceof Date) return this.date(value); if (value instanceof Map) return this.associativeArray(value); if (Array.isArray(value)) return this.array(value); if (typeof value === 'object') return this.object(value); } static avmPlus(value) { return new AvmPlusValue().with({ value }); } static amf3(value) { return this.avmPlus(value); } } __decorate([ Field(8 * 1), __metadata("design:type", Number) ], Value.prototype, "marker", void 0); export class ObjectProperty extends BitstreamElement { get key() { return this._key; } set key(value) { if (typeof value !== 'string') throw new Error(`Key must be a string`); this._key = value; this.keyLength = value.length; } } __decorate([ Field(8 * 2, { writtenValue: (i) => Buffer.from(i.key).length }), __metadata("design:type", Number) ], ObjectProperty.prototype, "keyLength", void 0); __decorate([ Field((i) => i.keyLength, { string: { encoding: 'utf-8' } }), __metadata("design:type", String), __metadata("design:paramtypes", [Object]) ], ObjectProperty.prototype, "key", null); __decorate([ Field(), __metadata("design:type", Value) ], ObjectProperty.prototype, "value", void 0); export class ObjectPropertyArraySerializer { *read(reader, type, parent, field) { let properties = []; let readOperation; let hasMore = true; while (hasMore) { readOperation = ObjectProperty.read(reader); while (true) { let propResult = readOperation.next(); if (propResult.done === false) { yield propResult.value; } else { let prop = propResult.value; if (prop.value instanceof ObjectEndValue) hasMore = false; else properties.push(prop); break; } } } return properties; } write(writer, type, parent, field, value) { for (let prop of value) prop.write(writer); new ObjectProperty() .with({ key: "", value: new ObjectEndValue() }) .write(writer); } } let NumberValue = class NumberValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Number; } get value() { return this.$value; } set value(value) { this.$value = value; } }; __decorate([ Field(8 * 8, { number: { format: 'float' } }), __metadata("design:type", Number) ], NumberValue.prototype, "$value", void 0); NumberValue = __decorate([ Variant(i => i.marker === TypeMarker.Number) ], NumberValue); export { NumberValue }; let BooleanValue = class BooleanValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Boolean; } get value() { return this.$value; } set value(value) { this.$value = value; } }; __decorate([ Field(8 * 1), __metadata("design:type", Boolean) ], BooleanValue.prototype, "$value", void 0); BooleanValue = __decorate([ Variant(i => i.marker === TypeMarker.Boolean) ], BooleanValue); export { BooleanValue }; let StringValue = class StringValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.String; this.length = 0; } get value() { return this.$value; } set value(value) { if (typeof value !== 'string') throw new Error(`Value must be a string`); this.$value = value; this.length = value.length; } }; __decorate([ Field(8 * 2, { writtenValue: (i) => Buffer.from(i.value).length }), __metadata("design:type", Number) ], StringValue.prototype, "length", void 0); __decorate([ Field((i) => i.length, { string: { encoding: 'utf-8' } }), __metadata("design:type", String) ], StringValue.prototype, "$value", void 0); StringValue = __decorate([ Variant(i => i.marker === TypeMarker.String) ], StringValue); export { StringValue }; let ComplexValue = class ComplexValue extends Value { write(bitstream, options) { var _a, _b, _c; this.context = (_a = options === null || options === void 0 ? void 0 : options.context) !== null && _a !== void 0 ? _a : {}; let json = JSON.stringify(this); if (!this.context.id) this.context.id = Math.floor(Math.random() * 1000); let index = (_c = (_b = this.referenceTable) === null || _b === void 0 ? void 0 : _b.findIndex) === null || _c === void 0 ? void 0 : _c.call(_b, x => JSON.stringify(x) === json); if (index >= 0) { new ReferenceValue().with({ index }).write(bitstream, options); } else { super.write(bitstream, options); } } onSerializeFinished() { this.referenceTable.push(this); } onParseFinished() { this.referenceTable.push(this); } }; ComplexValue = __decorate([ Variant(i => [TypeMarker.Object, TypeMarker.TypedObject, TypeMarker.StrictArray, TypeMarker.EcmaArray].includes(i.marker)) ], ComplexValue); export { ComplexValue }; function symbol() { return Symbol(''); } let ObjectValue = class ObjectValue extends ComplexValue { constructor() { super(...arguments); this.marker = TypeMarker.Object; } get properties() { return this._properties; } set properties(value) { this._properties = value; this.buildValue(); } buildValue() { this._value = this.properties.reduce((o, p) => (o[p.key] = p.value.value, o), {}); } get value() { return this._value; } set value(value) { this._value = value; this._properties = Object .keys(value !== null && value !== void 0 ? value : {}) .map(key => new ObjectProperty().with({ key, value: Value.any(value[key]) })); } }; __decorate([ VariantMarker(), __metadata("design:type", Object) ], ObjectValue.prototype, "$objectVariantMarker", void 0); __decorate([ Field(0, { array: { type: ObjectProperty }, serializer: new ObjectPropertyArraySerializer() }), __metadata("design:type", Array), __metadata("design:paramtypes", [Object]) ], ObjectValue.prototype, "properties", null); ObjectValue = __decorate([ Variant(i => [TypeMarker.Object, TypeMarker.TypedObject].includes(i.marker)) ], ObjectValue); export { ObjectValue }; let TypedObjectValue = class TypedObjectValue extends ObjectValue { constructor() { super(...arguments); this.marker = TypeMarker.TypedObject; } get className() { return this._className; } set className(value) { if (typeof value !== 'string') throw new TypeError(`Class name must be a string`); this._className = value; this.classNameLength = value.length; } }; __decorate([ Field(8 * 2, { writtenValue: (i) => Buffer.from(i.className).length }), __metadata("design:type", Number) ], TypedObjectValue.prototype, "classNameLength", void 0); __decorate([ Field((i) => i.classNameLength, { string: { encoding: 'utf-8' } }), __metadata("design:type", String), __metadata("design:paramtypes", [Object]) ], TypedObjectValue.prototype, "className", null); TypedObjectValue = __decorate([ Variant(i => i.marker === TypeMarker.TypedObject) ], TypedObjectValue); export { TypedObjectValue }; let NullValue = class NullValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Null; } }; NullValue = __decorate([ Variant(i => i.marker === TypeMarker.Null) ], NullValue); export { NullValue }; let UndefinedValue = class UndefinedValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Undefined; } }; UndefinedValue = __decorate([ Variant(i => i.marker === TypeMarker.Undefined) ], UndefinedValue); export { UndefinedValue }; let ReferenceValue = class ReferenceValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Reference; } get reference() { var _a; return (_a = this.referenceTable) === null || _a === void 0 ? void 0 : _a[this.index]; } get value() { var _a; return (_a = this.reference) === null || _a === void 0 ? void 0 : _a.value; } }; __decorate([ Field(8 * 2), __metadata("design:type", Number) ], ReferenceValue.prototype, "index", void 0); ReferenceValue = __decorate([ Variant(i => i.marker === TypeMarker.Reference) ], ReferenceValue); export { ReferenceValue }; let EcmaArrayValue = class EcmaArrayValue extends ComplexValue { constructor() { super(...arguments); this.marker = TypeMarker.EcmaArray; this.endKey = ''; this.endMarker = TypeMarker.ObjectEnd; } get properties() { return this._properties; } set properties(value) { this._properties = value; this._value = new Map(value.map(prop => [prop.key, prop.value.value])); } get value() { return this._value; } set value(value) { this._value = value; this._properties = Array.from(value.entries()).map(([key, value]) => new ObjectProperty().with({ key, value: Value.any(value) })); this._count = this._properties.length; } }; __decorate([ Field(8 * 4, { writtenValue: (i) => i._properties.length }), __metadata("design:type", Number) ], EcmaArrayValue.prototype, "_count", void 0); __decorate([ Field((i) => i._count, { array: { type: ObjectProperty } }), __metadata("design:type", Array), __metadata("design:paramtypes", [Object]) ], EcmaArrayValue.prototype, "properties", null); __decorate([ Field((i) => 0, { string: { encoding: 'utf-8' }, writtenValue: '' }), __metadata("design:type", Object) ], EcmaArrayValue.prototype, "endKey", void 0); __decorate([ Field(8, { writtenValue: TypeMarker.ObjectEnd }), __metadata("design:type", Object) ], EcmaArrayValue.prototype, "endMarker", void 0); EcmaArrayValue = __decorate([ Variant(i => i.marker === TypeMarker.EcmaArray) ], EcmaArrayValue); export { EcmaArrayValue }; let ObjectEndValue = class ObjectEndValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.ObjectEnd; } }; ObjectEndValue = __decorate([ Variant(i => i.marker === TypeMarker.ObjectEnd) ], ObjectEndValue); export { ObjectEndValue }; let StrictArrayValue = class StrictArrayValue extends ComplexValue { constructor() { super(...arguments); this.marker = TypeMarker.StrictArray; } get values() { return this._values; } set values(value) { this._values = value; this._value = value.map(z => z.value); } get value() { return this._value; } static elementValues(value) { return value.values; } set value(value) { if (!Array.isArray(value)) throw new Error(`Value must be an array`); this._value = value; this.values = value.map(z => Value.any(z)); this.count = value.length; } }; __decorate([ Field(8 * 4), __metadata("design:type", Number) ], StrictArrayValue.prototype, "count", void 0); __decorate([ Field((i) => i.count, { array: { type: Value } }), __metadata("design:type", Array), __metadata("design:paramtypes", [Object]) ], StrictArrayValue.prototype, "values", null); StrictArrayValue = __decorate([ Variant(i => i.marker === TypeMarker.StrictArray) ], StrictArrayValue); export { StrictArrayValue }; let DateValue = class DateValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Date; } get $value() { return this._value; } set $value(value) { this._value = Math.floor(value); } get value() { return new Date(this.$value); } set value(value) { this.$value = value.getTime(); } }; __decorate([ Field(8 * 8, { number: { format: 'float' } }), __metadata("design:type", Number), __metadata("design:paramtypes", [Object]) ], DateValue.prototype, "$value", null); __decorate([ ReservedLow(8 * 2, { writtenValue: 0x0000 }), __metadata("design:type", Number) ], DateValue.prototype, "timeZone", void 0); DateValue = __decorate([ Variant(i => i.marker === TypeMarker.Date) ], DateValue); export { DateValue }; let LongStringValue = class LongStringValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.LongString; } get value() { return this.$value; } set value(value) { if (typeof value !== 'string') throw new TypeError(`Value must be a string`); this.$value = value; this._length = value.length; } }; __decorate([ Field(8 * 4, { writtenValue: (i) => Buffer.from(i.value).length }), __metadata("design:type", Number) ], LongStringValue.prototype, "_length", void 0); __decorate([ Field((i) => i._length, { string: { encoding: 'utf-8' } }), __metadata("design:type", String) ], LongStringValue.prototype, "$value", void 0); LongStringValue = __decorate([ Variant(i => i.marker === TypeMarker.LongString) ], LongStringValue); export { LongStringValue }; let UnsupportedValue = class UnsupportedValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Unsupported; } }; UnsupportedValue = __decorate([ Variant(i => i.marker === TypeMarker.Unsupported) ], UnsupportedValue); export { UnsupportedValue }; let RecordSetValue = class RecordSetValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.RecordSet; } }; RecordSetValue = __decorate([ Variant(i => i.marker === TypeMarker.RecordSet) ], RecordSetValue); export { RecordSetValue }; let MovieClipValue = class MovieClipValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.MovieClip; } }; MovieClipValue = __decorate([ Variant(i => i.marker === TypeMarker.MovieClip) ], MovieClipValue); export { MovieClipValue }; let XmlDocumentValue = class XmlDocumentValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.XmlDocument; } get value() { return this.$value; } set value(value) { if (typeof value !== 'string') throw new TypeError(`Value must be a string`); this.$value = value; this._length = value.length; } }; __decorate([ Field(8 * 4, { writtenValue: (i) => Buffer.from(i.value).length }), __metadata("design:type", Number) ], XmlDocumentValue.prototype, "_length", void 0); __decorate([ Field((i) => i._length, { string: { encoding: 'utf-8' } }), __metadata("design:type", String) ], XmlDocumentValue.prototype, "$value", void 0); XmlDocumentValue = __decorate([ Variant(i => i.marker === TypeMarker.XmlDocument) ], XmlDocumentValue); export { XmlDocumentValue }; let AvmPlusValue = class AvmPlusValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.AvmPlus; } get value() { var _a; return (_a = this.$value) === null || _a === void 0 ? void 0 : _a.value; } set value(value) { this.$value = AMF3.Value.any(value); } static unwrap(v) { return v.$value; } }; __decorate([ Field(), __metadata("design:type", AMF3.Value) ], AvmPlusValue.prototype, "$value", void 0); AvmPlusValue = __decorate([ Variant(i => i.marker === TypeMarker.AvmPlus) ], AvmPlusValue); export { AvmPlusValue }; //# sourceMappingURL=amf0.js.map