jspurefix 5.9.2 → 5.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +35 -0
  2. package/dist/buffer/ascii/ascii-encoder.d.ts +1 -0
  3. package/dist/buffer/ascii/ascii-encoder.js +15 -0
  4. package/dist/buffer/ascii/ascii-encoder.js.map +1 -1
  5. package/dist/buffer/msg-encoder.d.ts +2 -0
  6. package/dist/buffer/msg-encoder.js +1 -0
  7. package/dist/buffer/msg-encoder.js.map +1 -1
  8. package/dist/runtime/session-container.d.ts +3 -0
  9. package/dist/runtime/session-container.js +8 -0
  10. package/dist/runtime/session-container.js.map +1 -1
  11. package/dist/runtime/session-launcher.d.ts +2 -1
  12. package/dist/runtime/session-launcher.js +4 -1
  13. package/dist/runtime/session-launcher.js.map +1 -1
  14. package/dist/transport/ascii/ascii-msg-transmitter.d.ts +1 -0
  15. package/dist/transport/ascii/ascii-msg-transmitter.js +15 -0
  16. package/dist/transport/ascii/ascii-msg-transmitter.js.map +1 -1
  17. package/dist/transport/ascii/ascii-session-msg-factory.js +1 -7
  18. package/dist/transport/ascii/ascii-session-msg-factory.js.map +1 -1
  19. package/dist/transport/fixml/fixml-session-msg-factory.js +1 -6
  20. package/dist/transport/fixml/fixml-session-msg-factory.js.map +1 -1
  21. package/dist/transport/index.d.ts +3 -0
  22. package/dist/transport/index.js +3 -0
  23. package/dist/transport/index.js.map +1 -1
  24. package/dist/transport/msg-payload.d.ts +3 -1
  25. package/dist/transport/msg-payload.js +2 -1
  26. package/dist/transport/msg-payload.js.map +1 -1
  27. package/dist/transport/msg-transmitter.d.ts +4 -1
  28. package/dist/transport/msg-transmitter.js +18 -2
  29. package/dist/transport/msg-transmitter.js.map +1 -1
  30. package/dist/transport/send-callback.d.ts +7 -0
  31. package/dist/transport/send-callback.js +3 -0
  32. package/dist/transport/send-callback.js.map +1 -0
  33. package/dist/transport/session/fix-session.d.ts +2 -1
  34. package/dist/transport/session/fix-session.js +12 -3
  35. package/dist/transport/session/fix-session.js.map +1 -1
  36. package/dist/transport/session/session-description.d.ts +2 -0
  37. package/dist/transport/session/session-description.js.map +1 -1
  38. package/docs/custom-logon.md +225 -0
  39. package/jsfix.test_client.txt +62 -62
  40. package/jsfix.test_server.txt +72 -72
  41. package/package.json +1 -1
  42. package/src/buffer/ascii/ascii-encoder.ts +20 -0
  43. package/src/buffer/msg-encoder.ts +12 -0
  44. package/src/runtime/session-container.ts +20 -0
  45. package/src/runtime/session-launcher.ts +19 -2
  46. package/src/transport/ascii/ascii-msg-transmitter.ts +20 -0
  47. package/src/transport/ascii/ascii-session-msg-factory.ts +6 -1
  48. package/src/transport/fixml/fixml-session-msg-factory.ts +3 -1
  49. package/src/transport/index.ts +5 -0
  50. package/src/transport/msg-payload.ts +5 -1
  51. package/src/transport/msg-transmitter.ts +31 -2
  52. package/src/transport/send-callback.ts +33 -0
  53. package/src/transport/session/fix-session.ts +22 -3
  54. package/src/transport/session/session-description.ts +14 -0
package/README.md CHANGED
@@ -12,6 +12,7 @@ A fast, fully native TypeScript [FIX protocol](https://www.fixtrading.org/) engi
12
12
  - [Examples](#examples)
13
13
  - [Quickstart](#quickstart)
14
14
  - [Session Configuration](#session-configuration)
15
+ - [Customising the Logon](#customising-the-logon)
15
16
  - [TLS](#tls)
16
17
  - [Body length padding](#body-length-padding)
17
18
  - [Persistence & Recovery](#persistence--recovery)
@@ -19,6 +20,7 @@ A fast, fully native TypeScript [FIX protocol](https://www.fixtrading.org/) engi
19
20
  - [`ResetSeqNumFlag` semantics](#resetseqnumflag-semantics)
20
21
  - [Resending messages](#resending-messages)
21
22
  - [Working with Messages](#working-with-messages)
23
+ - [Knowing what a send did](#knowing-what-a-send-did)
22
24
  - [FIXML over HTTP](#fixml-over-http)
23
25
  - [Data Dictionaries](#data-dictionaries)
24
26
  - [`jsfix` CLI — log parsing & stats](#jsfix-cli--log-parsing--stats)
@@ -151,6 +153,21 @@ A session is described by a JSON file (or any object matching `ISessionDescripti
151
153
  }
152
154
  ```
153
155
 
156
+ ### Customising the Logon
157
+
158
+ Most counterparties want a tag on the Logon the standard message does not carry. Name the extra fields under a `Logon` block — they are merged over the ones the engine derives, and a `null` suppresses one you do not want sent:
159
+
160
+ ```json
161
+ {
162
+ "Logon": {
163
+ "Account": "TVKD_001",
164
+ "DefaultApplVerID": "9"
165
+ }
166
+ }
167
+ ```
168
+
169
+ A field named here must also be declared on `Logon` in the dictionary the session loads, or the encoder has no tag to write it to and will say so in the log. For values computed at run time, or for a header a counterparty stamps differently, supply your own session message factory. See [docs/custom-logon.md](docs/custom-logon.md) for the whole picture.
170
+
154
171
  ### TLS
155
172
 
156
173
  Add a `tls` block under `application.tcp`. The `ca` field is only needed for self-signed certificates; commercial vendors will supply this for you. `script/getKey.ps1` will generate a self-signed CA + client/server pair (requires `openssl` on the path).
@@ -277,6 +294,24 @@ import { ITradeCaptureReport } from 'jspurefix/dist/types/FIX4.4/repo'
277
294
  const tc: ITradeCaptureReport = view.toObject()
278
295
  ```
279
296
 
297
+ ### Knowing what a send did
298
+
299
+ `send` writes into an encode stream and returns, so on its own it tells you nothing: not the sequence number your message went out under, and not whether it went out at all. Pass a callback when you need to know ([issue #86](https://github.com/TimelordUK/jspurefix/issues/86)):
300
+
301
+ ```typescript
302
+ this.send(MsgType.NewOrderSingle, order, (err, result) => {
303
+ if (err) {
304
+ this.logger.error(err) // dropped - session down, or it would not encode
305
+ return
306
+ }
307
+ this.pending.set(result.header?.MsgSeqNum, order)
308
+ })
309
+ ```
310
+
311
+ `result` carries the `msgType`, the `StandardHeader` the engine stamped (sequence number, sending time, comp ids) and the encoded bytes. It fires when the message has been encoded and handed to the transport — the FIX session layer has no acknowledgement of the socket flushing, so neither does this.
312
+
313
+ An error is reported for a session that has stopped, a missing transport, a `msgType` the dictionary does not define, and anything thrown during encoding. All of those still reach the session's error channel exactly as before; the callback is additional, never a replacement.
314
+
280
315
  Read a single tag by name or number:
281
316
 
282
317
  ```typescript
@@ -22,6 +22,7 @@ export declare class AsciiEncoder extends MsgEncoder {
22
22
  encodeSet(objectToEncode: ILooseObject, set: IContainedSet): void;
23
23
  private encodeObject;
24
24
  private getFields;
25
+ private static expectedMiss;
25
26
  private encodeInstances;
26
27
  private WriteTagEquals;
27
28
  private writeDelimiter;
@@ -73,11 +73,26 @@ class AsciiEncoder extends msg_encoder_1.MsgEncoder {
73
73
  if (field) {
74
74
  a[j++] = field;
75
75
  }
76
+ else if (this.onUnknownField && !AsciiEncoder.expectedMiss(set, current)) {
77
+ this.onUnknownField(current, set.name);
78
+ }
76
79
  return a;
77
80
  }, new Array(keys.length));
78
81
  fields.sort((a, b) => a.position - b.position);
79
82
  return fields;
80
83
  }
84
+ static expectedMiss(set, name) {
85
+ var _a;
86
+ if (name === 'StandardHeader' || name === 'StandardTrailer') {
87
+ return true;
88
+ }
89
+ for (const group of set.groups.values()) {
90
+ if (((_a = group.noOfField) === null || _a === void 0 ? void 0 : _a.name) === name) {
91
+ return true;
92
+ }
93
+ }
94
+ return false;
95
+ }
81
96
  encodeInstances(o, gf) {
82
97
  const noOfField = gf.definition.noOfField;
83
98
  if (!noOfField)
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-encoder.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILooseObject } from '../../collections/collection'\nimport {\n ContainedGroupField, ContainedSimpleField,\n IContainedSet, ContainedField,\n ContainedComponentField, FieldsDispatch\n} from '../../dictionary/contained'\nimport { SimpleFieldDefinition, FixDefinitions } from '../../dictionary/definition'\nimport { MsgEncoder } from '../msg-encoder'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { TimeFormatter } from './time-formatter'\nimport { ITimeFormatter } from './itime-formatter'\nimport { AsciiChars } from './ascii-chars'\nimport { Tags } from '../tag/tags'\nimport { TagType } from '../tag/tag-type'\n\nexport class AsciiEncoder extends MsgEncoder {\n public bodyLengthPos: number\n public msgTypePos: number\n public tags: Tags\n public checkGroups: boolean = true\n readonly dispatcher: FieldsDispatch = new FieldsDispatch()\n\n constructor (public readonly buffer: ElasticBuffer,\n public readonly definitions: FixDefinitions,\n public readonly timeFormatter: ITimeFormatter = new TimeFormatter(buffer),\n public readonly delimiter: number = AsciiChars.Soh,\n public readonly logDelimiter: number = AsciiChars.Pipe) {\n super(definitions)\n this.tags = new Tags()\n }\n\n public trim (): Buffer {\n const b = this.buffer.copy()\n const delimiter = this.delimiter\n const logDelimiter = this.logDelimiter\n const tags = this.tags\n if (delimiter !== logDelimiter) {\n for (let p = 0; p < tags.nextTagPos; ++p) {\n const tagPos = tags.tagPos[p]\n b.writeUInt8(delimiter, tagPos.start + tagPos.len)\n }\n }\n\n return b\n }\n\n // only reset tags after entire message is encoded - <hdr>body<trl>\n\n public reset (): void {\n this.buffer.reset()\n this.tags.reset()\n }\n\n public encodeSet (objectToEncode: ILooseObject, set: IContainedSet): void {\n const summary: AsciiEncodeSetSummary = new AsciiEncodeSetSummary()\n this.encodeObject(objectToEncode, set, summary)\n }\n\n private encodeObject (objectToEncode: ILooseObject, set: IContainedSet, state: AsciiEncodeSetSummary): void {\n const fields: ContainedField[] = this.getFields(set, objectToEncode)\n this.dispatcher.dispatchFields(fields, {\n simple: (sf: ContainedSimpleField) => {\n const val: any = objectToEncode[sf.name]\n // Empty strings are omitted as they result in empty values for tags, which are considered malformed.\n if (val != null && val !== '') {\n if (state.count === 0) {\n state.firstSimple = sf\n }\n state.lastSimple = sf\n state.count++\n this.encodeSimple(objectToEncode, set, sf, val)\n }\n },\n component: (cf: ContainedComponentField) => {\n const instance: ILooseObject = objectToEncode[cf.definition.name]\n if (instance) {\n this.encodeObject(instance, cf.definition, state)\n }\n },\n group: (gf: ContainedGroupField) => {\n this.encodeInstances(objectToEncode, gf)\n }\n })\n }\n\n private getFields (set: IContainedSet, o: ILooseObject): ContainedField[] {\n const keys: string[] = Object.keys(o)\n let j: number = 0\n const fields: ContainedField[] = keys.reduce((a: ContainedField[], current: string) => {\n const field = set.localNameToField.get(current)\n if (field) {\n a[j++] = field\n }\n return a\n }, new Array(keys.length))\n fields.sort((a: ContainedField, b: ContainedField) => a.position - b.position)\n return fields\n }\n\n private encodeInstances (o: ILooseObject, gf: ContainedGroupField): void {\n const noOfField: SimpleFieldDefinition | null = gf.definition.noOfField\n if (!noOfField) return\n const instances: ILooseObject[] = o[gf.name] || o[noOfField.name]\n\n const buffer = this.buffer\n if (!Array.isArray(instances)) {\n throw new Error(`expected array instance for group ${noOfField.name}`)\n }\n if (instances) {\n const validator = new GroupValidator(gf)\n const test: AsciiEncodeSetSummary = validator.test\n\n // a repeated group has number of instances at the start of group\n this.WriteTagEquals(noOfField.tag)\n const posValBegin = buffer.getPos()\n buffer.writeWholeNumber(instances.length)\n this.writeDelimiter(posValBegin, noOfField.tag)\n for (let field = 0; field < instances.length; ++field) {\n const instance: ILooseObject = instances[field]\n test.reset()\n const summary = validator.getSummary(field)\n this.encodeObject(instance, gf.definition, summary)\n if (this.checkGroups) {\n validator.assertInstanceValid(field)\n }\n }\n }\n }\n\n private WriteTagEquals (tag: number): void {\n const buffer = this.buffer\n buffer.writeWholeNumber(tag)\n buffer.writeChar(AsciiChars.Equal)\n }\n\n private writeDelimiter (posValBegin: number, tag: number): void {\n const delimiter = this.logDelimiter\n const buffer = this.buffer\n this.tags.store(posValBegin, buffer.getPos() - posValBegin, tag)\n buffer.writeChar(delimiter)\n }\n\n private encodeSimple (o: ILooseObject, set: IContainedSet, sf: ContainedSimpleField, val: any): void {\n const definition = sf.definition\n const tag: number = definition.tag\n const buffer = this.buffer\n const delimiter = this.logDelimiter\n const tf = this.timeFormatter\n const pos = buffer.getPos()\n let posValBegin = 0\n\n let tagType: TagType\n if (typeof val === 'string') {\n switch (definition.tagType) {\n case TagType.Boolean: {\n tagType = definition.tagType\n const vs: string = val\n const first: string = vs.length > 0 ? vs.charAt(0) : 'N'\n val = first === 'Y' || first === 'T'\n break\n }\n default: {\n tagType = TagType.String\n }\n }\n } else {\n tagType = definition.tagType\n }\n\n switch (tagType) {\n case TagType.RawData: {\n // may need to first write raw message length (see below)\n break\n }\n\n default: {\n this.WriteTagEquals(tag)\n posValBegin = buffer.getPos()\n break\n }\n }\n\n switch (tagType) {\n case TagType.String: {\n buffer.writeString(val as string)\n break\n }\n\n case TagType.Float: {\n buffer.writeNumber(val as number)\n break\n }\n\n case TagType.Int:\n case TagType.Length: {\n buffer.writeWholeNumber(val as number)\n break\n }\n\n case TagType.Boolean: {\n buffer.writeBoolean(val as boolean)\n break\n }\n\n case TagType.UtcTimestamp: {\n tf.writeUtcTimestamp(val as Date)\n break\n }\n\n case TagType.UtcTimeOnly: {\n tf.writeUtcTime(val as Date)\n break\n }\n\n case TagType.UtcDateOnly: {\n tf.writeUtcDate(val as Date)\n break\n }\n\n case TagType.LocalDate: {\n tf.writeLocalDate(val as Date)\n break\n }\n\n case TagType.RawData: {\n const b = val as Buffer\n const lenField: ContainedSimpleField = set.fields[sf.position - 1] as ContainedSimpleField\n if (o[lenField.name] == null) {\n this.WriteTagEquals(lenField.definition.tag)\n buffer.writeWholeNumber(b.length)\n buffer.writeChar(delimiter)\n }\n this.WriteTagEquals(tag)\n buffer.writeBuffer(b)\n posValBegin = buffer.getPos()\n break\n }\n\n default: {\n buffer.writeString(val as string)\n break\n }\n }\n\n this.writeDelimiter(posValBegin, tag)\n\n switch (tag) {\n case Tags.BodyLengthTag:\n this.bodyLengthPos = pos + 2\n break\n\n case Tags.MsgTag:\n this.msgTypePos = pos\n break\n }\n }\n}\n\nclass GroupValidator {\n constructor (public readonly gf: ContainedGroupField,\n public readonly first: AsciiEncodeSetSummary = new AsciiEncodeSetSummary(),\n public readonly test: AsciiEncodeSetSummary = new AsciiEncodeSetSummary()) {\n }\n\n getSummary (field: number): AsciiEncodeSetSummary {\n return field === 0 ? this.first : this.test\n }\n\n assertInstanceValid (field: number): void {\n const first = this.first\n const test = this.test\n if (field === 0 && first.empty()) {\n throw new Error(`first group instance has no delimiter present ${this.gf.name}`)\n }\n if (field > 0 && test.empty()) {\n throw new Error(`group instance [${field}] has no delimiter present ${this.gf.name}`)\n }\n if (field > 0) {\n const firstTag = first.firstSimple?.definition.tag\n const tag = test.firstSimple?.definition.tag\n if (firstTag !== tag) {\n const msg = `group instance [${field}] inconsistent delimiter ${tag} expected tag ${firstTag}`\n throw new Error(msg)\n }\n }\n }\n}\n\nclass AsciiEncodeSetSummary {\n constructor (public firstSimple: ContainedSimpleField | null = null,\n public lastSimple: ContainedSimpleField | null = null,\n public count: number = 0) {\n }\n\n public reset (): void {\n this.firstSimple = null\n this.lastSimple = null\n this.count = 0\n }\n\n public empty (): boolean {\n return this.firstSimple === null || this.count === 0\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-encoder.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILooseObject } from '../../collections/collection'\nimport {\n ContainedGroupField, ContainedSimpleField,\n IContainedSet, ContainedField,\n ContainedComponentField, FieldsDispatch\n} from '../../dictionary/contained'\nimport { SimpleFieldDefinition, FixDefinitions } from '../../dictionary/definition'\nimport { MsgEncoder } from '../msg-encoder'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { TimeFormatter } from './time-formatter'\nimport { ITimeFormatter } from './itime-formatter'\nimport { AsciiChars } from './ascii-chars'\nimport { Tags } from '../tag/tags'\nimport { TagType } from '../tag/tag-type'\n\nexport class AsciiEncoder extends MsgEncoder {\n public bodyLengthPos: number\n public msgTypePos: number\n public tags: Tags\n public checkGroups: boolean = true\n readonly dispatcher: FieldsDispatch = new FieldsDispatch()\n\n constructor (public readonly buffer: ElasticBuffer,\n public readonly definitions: FixDefinitions,\n public readonly timeFormatter: ITimeFormatter = new TimeFormatter(buffer),\n public readonly delimiter: number = AsciiChars.Soh,\n public readonly logDelimiter: number = AsciiChars.Pipe) {\n super(definitions)\n this.tags = new Tags()\n }\n\n public trim (): Buffer {\n const b = this.buffer.copy()\n const delimiter = this.delimiter\n const logDelimiter = this.logDelimiter\n const tags = this.tags\n if (delimiter !== logDelimiter) {\n for (let p = 0; p < tags.nextTagPos; ++p) {\n const tagPos = tags.tagPos[p]\n b.writeUInt8(delimiter, tagPos.start + tagPos.len)\n }\n }\n\n return b\n }\n\n // only reset tags after entire message is encoded - <hdr>body<trl>\n\n public reset (): void {\n this.buffer.reset()\n this.tags.reset()\n }\n\n public encodeSet (objectToEncode: ILooseObject, set: IContainedSet): void {\n const summary: AsciiEncodeSetSummary = new AsciiEncodeSetSummary()\n this.encodeObject(objectToEncode, set, summary)\n }\n\n private encodeObject (objectToEncode: ILooseObject, set: IContainedSet, state: AsciiEncodeSetSummary): void {\n const fields: ContainedField[] = this.getFields(set, objectToEncode)\n this.dispatcher.dispatchFields(fields, {\n simple: (sf: ContainedSimpleField) => {\n const val: any = objectToEncode[sf.name]\n // Empty strings are omitted as they result in empty values for tags, which are considered malformed.\n if (val != null && val !== '') {\n if (state.count === 0) {\n state.firstSimple = sf\n }\n state.lastSimple = sf\n state.count++\n this.encodeSimple(objectToEncode, set, sf, val)\n }\n },\n component: (cf: ContainedComponentField) => {\n const instance: ILooseObject = objectToEncode[cf.definition.name]\n if (instance) {\n this.encodeObject(instance, cf.definition, state)\n }\n },\n group: (gf: ContainedGroupField) => {\n this.encodeInstances(objectToEncode, gf)\n }\n })\n }\n\n private getFields (set: IContainedSet, o: ILooseObject): ContainedField[] {\n const keys: string[] = Object.keys(o)\n let j: number = 0\n const fields: ContainedField[] = keys.reduce((a: ContainedField[], current: string) => {\n const field = set.localNameToField.get(current)\n if (field) {\n a[j++] = field\n } else if (this.onUnknownField && !AsciiEncoder.expectedMiss(set, current)) {\n this.onUnknownField(current, set.name)\n }\n return a\n }, new Array(keys.length))\n fields.sort((a: ContainedField, b: ContainedField) => a.position - b.position)\n return fields\n }\n\n /**\n * Keys that legitimately fail to resolve against this set, so reporting them would\n * be noise: the header and trailer are encoded separately by the transmitter, and\n * a repeating group may be keyed by its count field rather than the group name -\n * encodeInstances accepts either.\n */\n private static expectedMiss (set: IContainedSet, name: string): boolean {\n if (name === 'StandardHeader' || name === 'StandardTrailer') {\n return true\n }\n for (const group of set.groups.values()) {\n if ((group as any).noOfField?.name === name) {\n return true\n }\n }\n return false\n }\n\n private encodeInstances (o: ILooseObject, gf: ContainedGroupField): void {\n const noOfField: SimpleFieldDefinition | null = gf.definition.noOfField\n if (!noOfField) return\n const instances: ILooseObject[] = o[gf.name] || o[noOfField.name]\n\n const buffer = this.buffer\n if (!Array.isArray(instances)) {\n throw new Error(`expected array instance for group ${noOfField.name}`)\n }\n if (instances) {\n const validator = new GroupValidator(gf)\n const test: AsciiEncodeSetSummary = validator.test\n\n // a repeated group has number of instances at the start of group\n this.WriteTagEquals(noOfField.tag)\n const posValBegin = buffer.getPos()\n buffer.writeWholeNumber(instances.length)\n this.writeDelimiter(posValBegin, noOfField.tag)\n for (let field = 0; field < instances.length; ++field) {\n const instance: ILooseObject = instances[field]\n test.reset()\n const summary = validator.getSummary(field)\n this.encodeObject(instance, gf.definition, summary)\n if (this.checkGroups) {\n validator.assertInstanceValid(field)\n }\n }\n }\n }\n\n private WriteTagEquals (tag: number): void {\n const buffer = this.buffer\n buffer.writeWholeNumber(tag)\n buffer.writeChar(AsciiChars.Equal)\n }\n\n private writeDelimiter (posValBegin: number, tag: number): void {\n const delimiter = this.logDelimiter\n const buffer = this.buffer\n this.tags.store(posValBegin, buffer.getPos() - posValBegin, tag)\n buffer.writeChar(delimiter)\n }\n\n private encodeSimple (o: ILooseObject, set: IContainedSet, sf: ContainedSimpleField, val: any): void {\n const definition = sf.definition\n const tag: number = definition.tag\n const buffer = this.buffer\n const delimiter = this.logDelimiter\n const tf = this.timeFormatter\n const pos = buffer.getPos()\n let posValBegin = 0\n\n let tagType: TagType\n if (typeof val === 'string') {\n switch (definition.tagType) {\n case TagType.Boolean: {\n tagType = definition.tagType\n const vs: string = val\n const first: string = vs.length > 0 ? vs.charAt(0) : 'N'\n val = first === 'Y' || first === 'T'\n break\n }\n default: {\n tagType = TagType.String\n }\n }\n } else {\n tagType = definition.tagType\n }\n\n switch (tagType) {\n case TagType.RawData: {\n // may need to first write raw message length (see below)\n break\n }\n\n default: {\n this.WriteTagEquals(tag)\n posValBegin = buffer.getPos()\n break\n }\n }\n\n switch (tagType) {\n case TagType.String: {\n buffer.writeString(val as string)\n break\n }\n\n case TagType.Float: {\n buffer.writeNumber(val as number)\n break\n }\n\n case TagType.Int:\n case TagType.Length: {\n buffer.writeWholeNumber(val as number)\n break\n }\n\n case TagType.Boolean: {\n buffer.writeBoolean(val as boolean)\n break\n }\n\n case TagType.UtcTimestamp: {\n tf.writeUtcTimestamp(val as Date)\n break\n }\n\n case TagType.UtcTimeOnly: {\n tf.writeUtcTime(val as Date)\n break\n }\n\n case TagType.UtcDateOnly: {\n tf.writeUtcDate(val as Date)\n break\n }\n\n case TagType.LocalDate: {\n tf.writeLocalDate(val as Date)\n break\n }\n\n case TagType.RawData: {\n const b = val as Buffer\n const lenField: ContainedSimpleField = set.fields[sf.position - 1] as ContainedSimpleField\n if (o[lenField.name] == null) {\n this.WriteTagEquals(lenField.definition.tag)\n buffer.writeWholeNumber(b.length)\n buffer.writeChar(delimiter)\n }\n this.WriteTagEquals(tag)\n buffer.writeBuffer(b)\n posValBegin = buffer.getPos()\n break\n }\n\n default: {\n buffer.writeString(val as string)\n break\n }\n }\n\n this.writeDelimiter(posValBegin, tag)\n\n switch (tag) {\n case Tags.BodyLengthTag:\n this.bodyLengthPos = pos + 2\n break\n\n case Tags.MsgTag:\n this.msgTypePos = pos\n break\n }\n }\n}\n\nclass GroupValidator {\n constructor (public readonly gf: ContainedGroupField,\n public readonly first: AsciiEncodeSetSummary = new AsciiEncodeSetSummary(),\n public readonly test: AsciiEncodeSetSummary = new AsciiEncodeSetSummary()) {\n }\n\n getSummary (field: number): AsciiEncodeSetSummary {\n return field === 0 ? this.first : this.test\n }\n\n assertInstanceValid (field: number): void {\n const first = this.first\n const test = this.test\n if (field === 0 && first.empty()) {\n throw new Error(`first group instance has no delimiter present ${this.gf.name}`)\n }\n if (field > 0 && test.empty()) {\n throw new Error(`group instance [${field}] has no delimiter present ${this.gf.name}`)\n }\n if (field > 0) {\n const firstTag = first.firstSimple?.definition.tag\n const tag = test.firstSimple?.definition.tag\n if (firstTag !== tag) {\n const msg = `group instance [${field}] inconsistent delimiter ${tag} expected tag ${firstTag}`\n throw new Error(msg)\n }\n }\n }\n}\n\nclass AsciiEncodeSetSummary {\n constructor (public firstSimple: ContainedSimpleField | null = null,\n public lastSimple: ContainedSimpleField | null = null,\n public count: number = 0) {\n }\n\n public reset (): void {\n this.firstSimple = null\n this.lastSimple = null\n this.count = 0\n }\n\n public empty (): boolean {\n return this.firstSimple === null || this.count === 0\n }\n}\n"]}
@@ -2,8 +2,10 @@ import { ILooseObject } from '../collections/collection';
2
2
  import { FixDefinitions } from '../dictionary/definition';
3
3
  import { IContainedSet } from '../dictionary/contained';
4
4
  import * as events from 'events';
5
+ export type UnknownFieldHandler = (fieldName: string, setName: string) => void;
5
6
  export declare abstract class MsgEncoder extends events.EventEmitter {
6
7
  readonly definitions: FixDefinitions;
8
+ onUnknownField: UnknownFieldHandler | null;
7
9
  protected constructor(definitions: FixDefinitions);
8
10
  encode(o: ILooseObject, name: string): void;
9
11
  abstract reset(): void;
@@ -39,6 +39,7 @@ class MsgEncoder extends events.EventEmitter {
39
39
  constructor(definitions) {
40
40
  super();
41
41
  this.definitions = definitions;
42
+ this.onUnknownField = null;
42
43
  }
43
44
  encode(o, name) {
44
45
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"msg-encoder.js","sourceRoot":"","sources":["../../src/buffer/msg-encoder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,+CAAgC;AAEhC,MAAsB,UAAW,SAAQ,MAAM,CAAC,YAAY;IAC1D,YAAuC,WAA2B;QAChE,KAAK,EAAE,CAAA;QAD8B,gBAAW,GAAX,WAAW,CAAgB;IAElE,CAAC;IAEM,MAAM,CAAE,CAAe,EAAE,IAAY;;QAC1C,MAAM,GAAG,GAA8B,MAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mCACvE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;CAKF;AAjBD,gCAiBC","sourcesContent":["import { ILooseObject } from '../collections/collection'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { IContainedSet } from '../dictionary/contained'\nimport * as events from 'events'\n\nexport abstract class MsgEncoder extends events.EventEmitter {\n protected constructor (public readonly definitions: FixDefinitions) {\n super()\n }\n\n public encode (o: ILooseObject, name: string): void {\n const set: IContainedSet | undefined = this.definitions.message.get(name) ??\n this.definitions.component.get(name)\n if (!set) {\n return\n }\n this.encodeSet(o, set)\n }\n\n public abstract reset (): void\n public abstract trim (): Buffer\n public abstract encodeSet (o: ILooseObject, set: IContainedSet): void\n}\n"]}
1
+ {"version":3,"file":"msg-encoder.js","sourceRoot":"","sources":["../../src/buffer/msg-encoder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,+CAAgC;AAIhC,MAAsB,UAAW,SAAQ,MAAM,CAAC,YAAY;IAW1D,YAAuC,WAA2B;QAChE,KAAK,EAAE,CAAA;QAD8B,gBAAW,GAAX,WAAW,CAAgB;QAF3D,mBAAc,GAA+B,IAAI,CAAA;IAIxD,CAAC;IAEM,MAAM,CAAE,CAAe,EAAE,IAAY;;QAC1C,MAAM,GAAG,GAA8B,MAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mCACvE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;CAKF;AA3BD,gCA2BC","sourcesContent":["import { ILooseObject } from '../collections/collection'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { IContainedSet } from '../dictionary/contained'\nimport * as events from 'events'\n\nexport type UnknownFieldHandler = (fieldName: string, setName: string) => void\n\nexport abstract class MsgEncoder extends events.EventEmitter {\n /**\n * Called when an object carries a key the set being encoded has no field for.\n * The key is dropped - it has no tag, so there is nothing to write - and without\n * this hook that happens in complete silence, which is the single most confusing\n * thing about adding a bespoke field. Every report of \"my tag never goes on the\n * wire\" (issues #93, #39, #96) is this, and the fix is nearly always a dictionary\n * that does not declare the field on that message.\n */\n public onUnknownField: UnknownFieldHandler | null = null\n\n protected constructor (public readonly definitions: FixDefinitions) {\n super()\n }\n\n public encode (o: ILooseObject, name: string): void {\n const set: IContainedSet | undefined = this.definitions.message.get(name) ??\n this.definitions.component.get(name)\n if (!set) {\n return\n }\n this.encodeSet(o, set)\n }\n\n public abstract reset (): void\n public abstract trim (): Buffer\n public abstract encodeSet (o: ILooseObject, set: IContainedSet): void\n}\n"]}
@@ -1,7 +1,10 @@
1
1
  import { DependencyContainer } from 'tsyringe';
2
2
  import { IJsFixConfig, JsFixLoggerFactory } from '../config';
3
3
  import { ISessionMsgFactory, ISessionDescription } from '../transport';
4
+ export type SessionMsgFactoryProvider = (description: ISessionDescription) => ISessionMsgFactory | null;
4
5
  export declare class SessionContainer {
6
+ readonly msgFactoryProvider: SessionMsgFactoryProvider | null;
7
+ constructor(msgFactoryProvider?: SessionMsgFactoryProvider | null);
5
8
  reset(): void;
6
9
  registerGlobal(loggerFactory?: JsFixLoggerFactory): void;
7
10
  registerGlobal(level: string): void;
@@ -25,6 +25,9 @@ const buffer_1 = require("../buffer");
25
25
  const ascii_2 = require("../buffer/ascii");
26
26
  const fixml_2 = require("../buffer/fixml");
27
27
  class SessionContainer {
28
+ constructor(msgFactoryProvider = null) {
29
+ this.msgFactoryProvider = msgFactoryProvider;
30
+ }
28
31
  reset() {
29
32
  tsyringe_1.container.reset();
30
33
  }
@@ -46,6 +49,11 @@ class SessionContainer {
46
49
  });
47
50
  }
48
51
  makeSessionFactory(description) {
52
+ var _a;
53
+ const supplied = (_a = this.msgFactoryProvider) === null || _a === void 0 ? void 0 : _a.call(this, description);
54
+ if (supplied) {
55
+ return supplied;
56
+ }
49
57
  const fixml = !this.isAscii(description);
50
58
  return fixml
51
59
  ? new fixml_1.FixmlSessionMsgFactory(description)
@@ -1 +1 @@
1
- {"version":3,"file":"session-container.js","sourceRoot":"","sources":["../../src/runtime/session-container.ts"],"names":[],"mappings":"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","sourcesContent":["import { container, DependencyContainer } from 'tsyringe'\nimport { DefinitionFactory } from '../util'\nimport { IJsFixConfig, JsFixLoggerFactory, JsFixWinstonLogFactory, WinstonLogger } from '../config'\nimport { DITokens } from './di-tokens'\nimport { RuntimeFactory } from './make-config'\n\nimport {\n TcpAcceptorListener, RecoveringTcpInitiator,\n TcpInitiatorConnector, TcpInitiator\n} from '../transport/tcp'\nimport { HttpInitiator, HttpAcceptorListener, HttpJsonSampleAdapter } from '../transport/http'\nimport { ISessionMsgFactory, MsgTransmitter, ISessionDescription } from '../transport'\nimport { AsciiMsgTransmitter } from '../transport/ascii/ascii-msg-transmitter'\nimport { FixmlMsgTransmitter } from '../transport/fixml/fixml-msg-transmitter'\nimport { FixmlSessionMsgFactory } from '../transport/fixml'\nimport { AsciiSessionMsgFactory } from '../transport/ascii'\nimport { ElasticBuffer, MsgEncoder, MsgParser } from '../buffer'\nimport { AsciiParser, AsciiParserState, AsciiSegmentParser } from '../buffer/ascii'\nimport { FixmlEncoder, FiXmlParser } from '../buffer/fixml'\nimport { FixEntity } from '../transport/fix-entity'\nimport { IHttpAdapter } from '../transport/http/http-adapter'\n\nexport class SessionContainer {\n public reset (): void {\n container.reset()\n }\n\n public registerGlobal (loggerFactory?: JsFixLoggerFactory): void\n public registerGlobal (level: string): void\n public registerGlobal (levelOrLoggerFactory: string | JsFixLoggerFactory = 'info'): void {\n container.registerInstance(DefinitionFactory, new DefinitionFactory())\n let lf: JsFixLoggerFactory\n if (typeof levelOrLoggerFactory === 'string') {\n lf = new JsFixWinstonLogFactory(WinstonLogger.consoleOptions(levelOrLoggerFactory))\n } else {\n lf = levelOrLoggerFactory\n }\n container.registerInstance(DITokens.JsFixLoggerFactory, lf)\n container.register<RuntimeFactory>(RuntimeFactory, {\n useClass: RuntimeFactory\n })\n container.register<ElasticBuffer>(DITokens.ElasticBuffer, {\n useClass: ElasticBuffer\n })\n }\n\n protected makeSessionFactory (description: ISessionDescription): ISessionMsgFactory {\n const fixml = !this.isAscii(description)\n return fixml\n ? new FixmlSessionMsgFactory(description)\n : new AsciiSessionMsgFactory(description)\n }\n\n public newChild (description: ISessionDescription): DependencyContainer {\n const sessionContainer = container.createChildContainer()\n const sf = this.makeSessionFactory(description)\n sessionContainer.registerInstance(DITokens.ISessionDescription, description)\n sessionContainer.registerInstance(DITokens.ISessionMsgFactory, sf)\n return sessionContainer\n }\n\n public async makeSystem (description: ISessionDescription): Promise<DependencyContainer> {\n return await new Promise<DependencyContainer>((resolve, reject) => {\n const sessionContainer = this.newChild(description)\n const factory = sessionContainer.resolve<RuntimeFactory>(RuntimeFactory)\n factory.makeConfig().then((c: IJsFixConfig) => {\n this.registerSession(c, sessionContainer)\n resolve(sessionContainer)\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public isAscii (description: ISessionDescription): boolean {\n return description.application?.protocol === 'ascii'\n }\n\n public isInitiator (description: ISessionDescription): boolean {\n return description.application?.type === 'initiator'\n }\n\n public asAscii (description: ISessionDescription, sessionContainer: DependencyContainer): void {\n sessionContainer.register<MsgTransmitter>(DITokens.MsgTransmitter, {\n useClass: AsciiMsgTransmitter\n })\n sessionContainer.register<MsgParser>(DITokens.MsgParser, {\n useClass: AsciiParser\n })\n const parseSize = 160 * 1024\n const sendSize = 10 * 1024\n\n sessionContainer.register(DITokens.maxMessageLen, {\n useValue: parseSize\n })\n sessionContainer.register<AsciiSegmentParser>(AsciiSegmentParser, {\n useClass: AsciiSegmentParser\n })\n sessionContainer.register<AsciiParserState>(AsciiParserState, {\n useClass: AsciiParserState\n })\n\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.TransmitBuffer, new ElasticBuffer(sendSize))\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.ParseBuffer, new ElasticBuffer(parseSize))\n\n if (this.isInitiator(description)) {\n sessionContainer.register<TcpInitiator>(TcpInitiator, {\n useClass: TcpInitiator\n })\n sessionContainer.register<RecoveringTcpInitiator>(RecoveringTcpInitiator, {\n useClass: RecoveringTcpInitiator\n })\n sessionContainer.register<TcpInitiatorConnector>(TcpInitiatorConnector, {\n useClass: TcpInitiatorConnector\n })\n if (description.application?.resilient) {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: RecoveringTcpInitiator\n })\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: TcpInitiatorConnector\n })\n }\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: TcpAcceptorListener\n })\n }\n }\n\n public asFixml (description: ISessionDescription, sessionContainer: DependencyContainer): void {\n sessionContainer.register<MsgTransmitter>(DITokens.MsgTransmitter, {\n useClass: FixmlMsgTransmitter\n })\n const sendSize = 10 * 1024\n\n sessionContainer.register<MsgParser>(DITokens.MsgParser, {\n useClass: FiXmlParser\n })\n sessionContainer.register(DITokens.maxMessageLocations, {\n useValue: sendSize\n })\n sessionContainer.register<MsgEncoder>(DITokens.MsgEncoder, {\n useClass: FixmlEncoder\n })\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.TransmitBuffer, new ElasticBuffer(sendSize))\n sessionContainer.register<HttpAcceptorListener>(HttpAcceptorListener, {\n useClass: HttpAcceptorListener\n })\n sessionContainer.register<HttpInitiator>(HttpInitiator, {\n useClass: HttpInitiator\n })\n if (this.isInitiator(description)) {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: HttpInitiator\n })\n sessionContainer.register<IHttpAdapter>(DITokens.IHttpAdapter, {\n useClass: HttpJsonSampleAdapter\n })\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: HttpAcceptorListener\n })\n }\n }\n\n protected asciiConstants (c: IJsFixConfig, sessionContainer: DependencyContainer): void {\n sessionContainer.register(DITokens.delimiter, {\n useValue: c.delimiter\n })\n sessionContainer.register(DITokens.logDelimiter, {\n useValue: c.logDelimiter\n })\n }\n\n public registerSession (c: IJsFixConfig, sessionContainer: DependencyContainer): void {\n if (this.isAscii(c.description)) {\n this.asAscii(c.description, sessionContainer)\n this.asciiConstants(c, sessionContainer)\n } else {\n this.asFixml(c.description, sessionContainer)\n }\n c.sessionContainer = sessionContainer\n sessionContainer.registerInstance(DITokens.IJsFixConfig, c)\n sessionContainer.registerInstance(DITokens.Definitions, c.definitions)\n }\n}\n"]}
1
+ {"version":3,"file":"session-container.js","sourceRoot":"","sources":["../../src/runtime/session-container.ts"],"names":[],"mappings":"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","sourcesContent":["import { container, DependencyContainer } from 'tsyringe'\nimport { DefinitionFactory } from '../util'\nimport { IJsFixConfig, JsFixLoggerFactory, JsFixWinstonLogFactory, WinstonLogger } from '../config'\nimport { DITokens } from './di-tokens'\nimport { RuntimeFactory } from './make-config'\n\nimport {\n TcpAcceptorListener, RecoveringTcpInitiator,\n TcpInitiatorConnector, TcpInitiator\n} from '../transport/tcp'\nimport { HttpInitiator, HttpAcceptorListener, HttpJsonSampleAdapter } from '../transport/http'\nimport { ISessionMsgFactory, MsgTransmitter, ISessionDescription } from '../transport'\nimport { AsciiMsgTransmitter } from '../transport/ascii/ascii-msg-transmitter'\nimport { FixmlMsgTransmitter } from '../transport/fixml/fixml-msg-transmitter'\nimport { FixmlSessionMsgFactory } from '../transport/fixml'\nimport { AsciiSessionMsgFactory } from '../transport/ascii'\nimport { ElasticBuffer, MsgEncoder, MsgParser } from '../buffer'\nimport { AsciiParser, AsciiParserState, AsciiSegmentParser } from '../buffer/ascii'\nimport { FixmlEncoder, FiXmlParser } from '../buffer/fixml'\nimport { FixEntity } from '../transport/fix-entity'\nimport { IHttpAdapter } from '../transport/http/http-adapter'\n\n/**\n * Supplies the session message factory for a description. Return null to accept the\n * stock factory for the protocol.\n */\nexport type SessionMsgFactoryProvider = (description: ISessionDescription) => ISessionMsgFactory | null\n\nexport class SessionContainer {\n /**\n * @param msgFactoryProvider an application that needs its own session messages -\n * typically a Logon carrying tags the standard message does not - can pass one\n * here rather than subclassing to override makeSessionFactory:\n *\n * new SessionContainer(d => new MyFactory(d))\n */\n constructor (public readonly msgFactoryProvider: SessionMsgFactoryProvider | null = null) {\n }\n\n public reset (): void {\n container.reset()\n }\n\n public registerGlobal (loggerFactory?: JsFixLoggerFactory): void\n public registerGlobal (level: string): void\n public registerGlobal (levelOrLoggerFactory: string | JsFixLoggerFactory = 'info'): void {\n container.registerInstance(DefinitionFactory, new DefinitionFactory())\n let lf: JsFixLoggerFactory\n if (typeof levelOrLoggerFactory === 'string') {\n lf = new JsFixWinstonLogFactory(WinstonLogger.consoleOptions(levelOrLoggerFactory))\n } else {\n lf = levelOrLoggerFactory\n }\n container.registerInstance(DITokens.JsFixLoggerFactory, lf)\n container.register<RuntimeFactory>(RuntimeFactory, {\n useClass: RuntimeFactory\n })\n container.register<ElasticBuffer>(DITokens.ElasticBuffer, {\n useClass: ElasticBuffer\n })\n }\n\n protected makeSessionFactory (description: ISessionDescription): ISessionMsgFactory {\n const supplied = this.msgFactoryProvider?.(description)\n if (supplied) {\n return supplied\n }\n const fixml = !this.isAscii(description)\n return fixml\n ? new FixmlSessionMsgFactory(description)\n : new AsciiSessionMsgFactory(description)\n }\n\n public newChild (description: ISessionDescription): DependencyContainer {\n const sessionContainer = container.createChildContainer()\n const sf = this.makeSessionFactory(description)\n sessionContainer.registerInstance(DITokens.ISessionDescription, description)\n sessionContainer.registerInstance(DITokens.ISessionMsgFactory, sf)\n return sessionContainer\n }\n\n public async makeSystem (description: ISessionDescription): Promise<DependencyContainer> {\n return await new Promise<DependencyContainer>((resolve, reject) => {\n const sessionContainer = this.newChild(description)\n const factory = sessionContainer.resolve<RuntimeFactory>(RuntimeFactory)\n factory.makeConfig().then((c: IJsFixConfig) => {\n this.registerSession(c, sessionContainer)\n resolve(sessionContainer)\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public isAscii (description: ISessionDescription): boolean {\n return description.application?.protocol === 'ascii'\n }\n\n public isInitiator (description: ISessionDescription): boolean {\n return description.application?.type === 'initiator'\n }\n\n public asAscii (description: ISessionDescription, sessionContainer: DependencyContainer): void {\n sessionContainer.register<MsgTransmitter>(DITokens.MsgTransmitter, {\n useClass: AsciiMsgTransmitter\n })\n sessionContainer.register<MsgParser>(DITokens.MsgParser, {\n useClass: AsciiParser\n })\n const parseSize = 160 * 1024\n const sendSize = 10 * 1024\n\n sessionContainer.register(DITokens.maxMessageLen, {\n useValue: parseSize\n })\n sessionContainer.register<AsciiSegmentParser>(AsciiSegmentParser, {\n useClass: AsciiSegmentParser\n })\n sessionContainer.register<AsciiParserState>(AsciiParserState, {\n useClass: AsciiParserState\n })\n\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.TransmitBuffer, new ElasticBuffer(sendSize))\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.ParseBuffer, new ElasticBuffer(parseSize))\n\n if (this.isInitiator(description)) {\n sessionContainer.register<TcpInitiator>(TcpInitiator, {\n useClass: TcpInitiator\n })\n sessionContainer.register<RecoveringTcpInitiator>(RecoveringTcpInitiator, {\n useClass: RecoveringTcpInitiator\n })\n sessionContainer.register<TcpInitiatorConnector>(TcpInitiatorConnector, {\n useClass: TcpInitiatorConnector\n })\n if (description.application?.resilient) {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: RecoveringTcpInitiator\n })\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: TcpInitiatorConnector\n })\n }\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: TcpAcceptorListener\n })\n }\n }\n\n public asFixml (description: ISessionDescription, sessionContainer: DependencyContainer): void {\n sessionContainer.register<MsgTransmitter>(DITokens.MsgTransmitter, {\n useClass: FixmlMsgTransmitter\n })\n const sendSize = 10 * 1024\n\n sessionContainer.register<MsgParser>(DITokens.MsgParser, {\n useClass: FiXmlParser\n })\n sessionContainer.register(DITokens.maxMessageLocations, {\n useValue: sendSize\n })\n sessionContainer.register<MsgEncoder>(DITokens.MsgEncoder, {\n useClass: FixmlEncoder\n })\n sessionContainer.registerInstance<ElasticBuffer>(DITokens.TransmitBuffer, new ElasticBuffer(sendSize))\n sessionContainer.register<HttpAcceptorListener>(HttpAcceptorListener, {\n useClass: HttpAcceptorListener\n })\n sessionContainer.register<HttpInitiator>(HttpInitiator, {\n useClass: HttpInitiator\n })\n if (this.isInitiator(description)) {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: HttpInitiator\n })\n sessionContainer.register<IHttpAdapter>(DITokens.IHttpAdapter, {\n useClass: HttpJsonSampleAdapter\n })\n } else {\n sessionContainer.register<FixEntity>(DITokens.FixEntity, {\n useClass: HttpAcceptorListener\n })\n }\n }\n\n protected asciiConstants (c: IJsFixConfig, sessionContainer: DependencyContainer): void {\n sessionContainer.register(DITokens.delimiter, {\n useValue: c.delimiter\n })\n sessionContainer.register(DITokens.logDelimiter, {\n useValue: c.logDelimiter\n })\n }\n\n public registerSession (c: IJsFixConfig, sessionContainer: DependencyContainer): void {\n if (this.isAscii(c.description)) {\n this.asAscii(c.description, sessionContainer)\n this.asciiConstants(c, sessionContainer)\n } else {\n this.asFixml(c.description, sessionContainer)\n }\n c.sessionContainer = sessionContainer\n sessionContainer.registerInstance(DITokens.IJsFixConfig, c)\n sessionContainer.registerInstance(DITokens.Definitions, c.definitions)\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { IJsFixConfig, IJsFixLogger, JsFixLoggerFactory } from '../config';
2
- import { ISessionDescription } from '../transport';
2
+ import { ISessionDescription, ISessionMsgFactory } from '../transport';
3
3
  import { DependencyContainer } from 'tsyringe';
4
4
  import { EngineFactory } from './engine-factory';
5
5
  import { SessionContainer } from './session-container';
@@ -11,6 +11,7 @@ export declare abstract class SessionLauncher {
11
11
  readonly acceptorConfig: ISessionDescription | null;
12
12
  protected constructor(initiatorConfig?: string | ISessionDescription | null, acceptorConfig?: string | ISessionDescription | null, loggerFactory?: JsFixLoggerFactory);
13
13
  protected sessionContainer: SessionContainer;
14
+ protected makeSessionMsgFactory(_description: ISessionDescription): ISessionMsgFactory | null;
14
15
  private empty;
15
16
  private acceptorEntity;
16
17
  protected getAcceptor(sessionContainer: DependencyContainer): Promise<any>;
@@ -52,12 +52,15 @@ class SessionLauncher {
52
52
  constructor(initiatorConfig = null, acceptorConfig = null, loggerFactory = defaultLoggerFactory) {
53
53
  this.loggerFactory = loggerFactory;
54
54
  this.root = '../../';
55
- this.sessionContainer = new session_container_1.SessionContainer();
55
+ this.sessionContainer = new session_container_1.SessionContainer((d) => this.makeSessionMsgFactory(d));
56
56
  this.acceptorEntity = null;
57
57
  this.logger = this.loggerFactory.logger('launcher');
58
58
  this.initiatorConfig = initiatorConfig ? this.loadConfig(initiatorConfig) : null;
59
59
  this.acceptorConfig = acceptorConfig ? this.loadConfig(acceptorConfig) : null;
60
60
  }
61
+ makeSessionMsgFactory(_description) {
62
+ return null;
63
+ }
61
64
  empty() {
62
65
  return __awaiter(this, void 0, void 0, function* () {
63
66
  return yield new Promise((resolve, reject) => {
@@ -1 +1 @@
1
- {"version":3,"file":"session-launcher.js","sourceRoot":"","sources":["../../src/runtime/session-launcher.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path'\nimport { IJsFixConfig, IJsFixLogger, JsFixLoggerFactory, JsFixWinstonLogFactory, WinstonLogger } from '../config'\nimport { FixEntity, FixSession, ISessionDescription } from '../transport'\nimport { DependencyContainer } from 'tsyringe'\nimport { EngineFactory } from './engine-factory'\nimport { SessionContainer } from './session-container'\nimport { DITokens } from './di-tokens'\n\nconst defaultLoggerFactory = new JsFixWinstonLogFactory(WinstonLogger.consoleOptions('info'))\n\nexport abstract class SessionLauncher {\n public root: string = '../../'\n protected readonly logger: IJsFixLogger\n public readonly initiatorConfig: ISessionDescription | null\n public readonly acceptorConfig: ISessionDescription | null\n\n protected constructor (\n initiatorConfig: string | ISessionDescription | null = null,\n acceptorConfig: string | ISessionDescription | null = null,\n private readonly loggerFactory: JsFixLoggerFactory = defaultLoggerFactory\n ) {\n this.logger = this.loggerFactory.logger('launcher')\n this.initiatorConfig = initiatorConfig ? this.loadConfig(initiatorConfig) : null\n this.acceptorConfig = acceptorConfig ? this.loadConfig(acceptorConfig) : null\n }\n\n protected sessionContainer: SessionContainer = new SessionContainer()\n\n private async empty (): Promise<any> {\n return await new Promise((resolve, reject) => {\n try {\n setImmediate(() => {\n this.logger.info('resolving an empty promise')\n resolve(null)\n })\n } catch (e) {\n reject(e)\n }\n })\n }\n\n private acceptorEntity: FixEntity | null = null\n\n protected async getAcceptor (sessionContainer: DependencyContainer): Promise<any> {\n if (sessionContainer.isRegistered<FixEntity>(DITokens.FixEntity)) {\n const entity = sessionContainer.resolve<FixEntity>(DITokens.FixEntity)\n this.acceptorEntity = entity\n return entity.start()\n } else {\n return this.empty()\n }\n }\n\n protected async getInitiator (sessionContainer: DependencyContainer): Promise<any> {\n if (sessionContainer.isRegistered<FixEntity>(DITokens.FixEntity)) {\n const entity = sessionContainer.resolve<FixEntity>(DITokens.FixEntity)\n return entity.start()\n } else {\n return this.empty()\n }\n }\n\n /**\n * provide a factory which will be invoked with a config where an instance of the application\n * should be constructed and returned.\n * @param config to be provided to the constucted application representing this session\n * @protected\n */\n protected makeFactory (config: IJsFixConfig): EngineFactory | null {\n return null\n }\n\n public async run (): Promise<boolean> {\n return await new Promise<any>((resolve, reject) => {\n const logger = this.logger\n logger.info('launching ..')\n this.setup().then(() => {\n logger.info('.. done')\n resolve(true)\n }).catch((e: Error) => {\n logger.error(e)\n reject(e)\n })\n })\n }\n\n public exec (): void {\n this.run().then(() => {\n console.log('finished.')\n }).catch(e => {\n console.error(e)\n })\n }\n\n /**\n * is this session config representing an ascii based session\n * @param description config to be tested.\n */\n public isAscii (description: ISessionDescription): boolean {\n return this.sessionContainer.isAscii(description)\n }\n\n /**\n * is this session config representing an initiator based session\n * @param description config to be tested.\n */\n public isInitiator (description: ISessionDescription): boolean {\n return this.sessionContainer.isInitiator(description)\n }\n\n protected registerApplication (_: DependencyContainer): void {\n this.logger.info('bypass register via DI')\n }\n\n private async makeSystem (description: ISessionDescription): Promise<DependencyContainer> {\n const name = description.application?.name ?? 'na'\n const protocol = description.application?.protocol ?? 'ascii'\n this.logger.info(`creating app ${name} [protocol ${protocol}]`)\n return await this.sessionContainer.makeSystem(description)\n }\n\n private register (container: DependencyContainer): void {\n const config = container.resolve<IJsFixConfig>(DITokens.IJsFixConfig)\n const factory = this.makeFactory(config)\n if (!factory) {\n this.registerApplication(container)\n } else {\n if (factory.makeSession) {\n // resolve the config from the container doing the resolving, not the one\n // captured here. An acceptor resolves each session from a per-connection\n // child scope which re-registers IJsFixConfig, so this is how an application\n // receives that session's own description, store and message factory.\n container.register<FixSession>(DITokens.FixSession, {\n useFactory: (c) => factory.makeSession(c.resolve<IJsFixConfig>(DITokens.IJsFixConfig))\n })\n }\n }\n }\n\n private async makeClient (): Promise<any> {\n if (!this.initiatorConfig) return\n const sessionContainer = await this.makeSystem(this.initiatorConfig)\n this.register(sessionContainer)\n this.logger.info('create initiator')\n return await this.getInitiator(sessionContainer)\n }\n\n private async makeServer (): Promise<any> {\n if (!this.acceptorConfig) return\n const sessionContainer = await this.makeSystem(this.acceptorConfig)\n this.register(sessionContainer)\n this.logger.info('create acceptor')\n return await this.getAcceptor(sessionContainer)\n }\n\n async serverOrEmpty (): Promise<any> {\n return this.acceptorConfig ? this.makeServer() : this.empty()\n }\n\n async clientOrEmpty (): Promise<any> {\n return this.initiatorConfig ? this.makeClient() : this.empty()\n }\n\n private async setup (): Promise<any> {\n this.sessionContainer.registerGlobal(this.loggerFactory)\n const server = this.serverOrEmpty()\n const client = this.clientOrEmpty()\n this.logger.info('launching ....')\n if (this.acceptorConfig && this.initiatorConfig) {\n // Both mode: client drives the lifecycle. When client finishes,\n // stop the acceptor so the process can exit cleanly.\n await client\n this.logger.info('client finished, stopping acceptor')\n this.stopAcceptor()\n return true\n }\n return await Promise.all([server, client])\n }\n\n private stopAcceptor (): void {\n const entity = this.acceptorEntity as any\n if (entity && typeof entity.stop === 'function') {\n entity.stop()\n }\n }\n\n private loadConfig (config: string | ISessionDescription): ISessionDescription {\n if (typeof config === 'string') {\n return require(path.join(this.root, config))\n }\n return config\n }\n}\n"]}
1
+ {"version":3,"file":"session-launcher.js","sourceRoot":"","sources":["../../src/runtime/session-launcher.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path'\nimport { IJsFixConfig, IJsFixLogger, JsFixLoggerFactory, JsFixWinstonLogFactory, WinstonLogger } from '../config'\nimport { FixEntity, FixSession, ISessionDescription, ISessionMsgFactory } from '../transport'\nimport { DependencyContainer } from 'tsyringe'\nimport { EngineFactory } from './engine-factory'\nimport { SessionContainer } from './session-container'\nimport { DITokens } from './di-tokens'\n\nconst defaultLoggerFactory = new JsFixWinstonLogFactory(WinstonLogger.consoleOptions('info'))\n\nexport abstract class SessionLauncher {\n public root: string = '../../'\n protected readonly logger: IJsFixLogger\n public readonly initiatorConfig: ISessionDescription | null\n public readonly acceptorConfig: ISessionDescription | null\n\n protected constructor (\n initiatorConfig: string | ISessionDescription | null = null,\n acceptorConfig: string | ISessionDescription | null = null,\n private readonly loggerFactory: JsFixLoggerFactory = defaultLoggerFactory\n ) {\n this.logger = this.loggerFactory.logger('launcher')\n this.initiatorConfig = initiatorConfig ? this.loadConfig(initiatorConfig) : null\n this.acceptorConfig = acceptorConfig ? this.loadConfig(acceptorConfig) : null\n }\n\n // the arrow defers to makeSessionMsgFactory at resolve time, so a subclass need\n // only override that one method - no SessionContainer subclass required\n protected sessionContainer: SessionContainer =\n new SessionContainer((d: ISessionDescription) => this.makeSessionMsgFactory(d))\n\n /**\n * Override to supply this application's own session message factory - the place to\n * put a Logon carrying tags the standard message does not, or a header a\n * counterparty stamps differently. Return null (the default) for the stock\n * factory.\n *\n * For a Logon that only needs extra fields, prefer the \"Logon\" block in the session\n * description - it needs no code at all. Reach for a factory when the values are\n * computed at run time (a signature, a nonce, a token fetched at start up).\n */\n protected makeSessionMsgFactory (_description: ISessionDescription): ISessionMsgFactory | null {\n return null\n }\n\n private async empty (): Promise<any> {\n return await new Promise((resolve, reject) => {\n try {\n setImmediate(() => {\n this.logger.info('resolving an empty promise')\n resolve(null)\n })\n } catch (e) {\n reject(e)\n }\n })\n }\n\n private acceptorEntity: FixEntity | null = null\n\n protected async getAcceptor (sessionContainer: DependencyContainer): Promise<any> {\n if (sessionContainer.isRegistered<FixEntity>(DITokens.FixEntity)) {\n const entity = sessionContainer.resolve<FixEntity>(DITokens.FixEntity)\n this.acceptorEntity = entity\n return entity.start()\n } else {\n return this.empty()\n }\n }\n\n protected async getInitiator (sessionContainer: DependencyContainer): Promise<any> {\n if (sessionContainer.isRegistered<FixEntity>(DITokens.FixEntity)) {\n const entity = sessionContainer.resolve<FixEntity>(DITokens.FixEntity)\n return entity.start()\n } else {\n return this.empty()\n }\n }\n\n /**\n * provide a factory which will be invoked with a config where an instance of the application\n * should be constructed and returned.\n * @param config to be provided to the constucted application representing this session\n * @protected\n */\n protected makeFactory (config: IJsFixConfig): EngineFactory | null {\n return null\n }\n\n public async run (): Promise<boolean> {\n return await new Promise<any>((resolve, reject) => {\n const logger = this.logger\n logger.info('launching ..')\n this.setup().then(() => {\n logger.info('.. done')\n resolve(true)\n }).catch((e: Error) => {\n logger.error(e)\n reject(e)\n })\n })\n }\n\n public exec (): void {\n this.run().then(() => {\n console.log('finished.')\n }).catch(e => {\n console.error(e)\n })\n }\n\n /**\n * is this session config representing an ascii based session\n * @param description config to be tested.\n */\n public isAscii (description: ISessionDescription): boolean {\n return this.sessionContainer.isAscii(description)\n }\n\n /**\n * is this session config representing an initiator based session\n * @param description config to be tested.\n */\n public isInitiator (description: ISessionDescription): boolean {\n return this.sessionContainer.isInitiator(description)\n }\n\n protected registerApplication (_: DependencyContainer): void {\n this.logger.info('bypass register via DI')\n }\n\n private async makeSystem (description: ISessionDescription): Promise<DependencyContainer> {\n const name = description.application?.name ?? 'na'\n const protocol = description.application?.protocol ?? 'ascii'\n this.logger.info(`creating app ${name} [protocol ${protocol}]`)\n return await this.sessionContainer.makeSystem(description)\n }\n\n private register (container: DependencyContainer): void {\n const config = container.resolve<IJsFixConfig>(DITokens.IJsFixConfig)\n const factory = this.makeFactory(config)\n if (!factory) {\n this.registerApplication(container)\n } else {\n if (factory.makeSession) {\n // resolve the config from the container doing the resolving, not the one\n // captured here. An acceptor resolves each session from a per-connection\n // child scope which re-registers IJsFixConfig, so this is how an application\n // receives that session's own description, store and message factory.\n container.register<FixSession>(DITokens.FixSession, {\n useFactory: (c) => factory.makeSession(c.resolve<IJsFixConfig>(DITokens.IJsFixConfig))\n })\n }\n }\n }\n\n private async makeClient (): Promise<any> {\n if (!this.initiatorConfig) return\n const sessionContainer = await this.makeSystem(this.initiatorConfig)\n this.register(sessionContainer)\n this.logger.info('create initiator')\n return await this.getInitiator(sessionContainer)\n }\n\n private async makeServer (): Promise<any> {\n if (!this.acceptorConfig) return\n const sessionContainer = await this.makeSystem(this.acceptorConfig)\n this.register(sessionContainer)\n this.logger.info('create acceptor')\n return await this.getAcceptor(sessionContainer)\n }\n\n async serverOrEmpty (): Promise<any> {\n return this.acceptorConfig ? this.makeServer() : this.empty()\n }\n\n async clientOrEmpty (): Promise<any> {\n return this.initiatorConfig ? this.makeClient() : this.empty()\n }\n\n private async setup (): Promise<any> {\n this.sessionContainer.registerGlobal(this.loggerFactory)\n const server = this.serverOrEmpty()\n const client = this.clientOrEmpty()\n this.logger.info('launching ....')\n if (this.acceptorConfig && this.initiatorConfig) {\n // Both mode: client drives the lifecycle. When client finishes,\n // stop the acceptor so the process can exit cleanly.\n await client\n this.logger.info('client finished, stopping acceptor')\n this.stopAcceptor()\n return true\n }\n return await Promise.all([server, client])\n }\n\n private stopAcceptor (): void {\n const entity = this.acceptorEntity as any\n if (entity && typeof entity.stop === 'function') {\n entity.stop()\n }\n }\n\n private loadConfig (config: string | ISessionDescription): ISessionDescription {\n if (typeof config === 'string') {\n return require(path.join(this.root, config))\n }\n return config\n }\n}\n"]}
@@ -8,6 +8,7 @@ export declare class AsciiMsgTransmitter extends MsgTransmitter {
8
8
  private readonly header;
9
9
  private readonly trailer;
10
10
  constructor(config: IJsFixConfig);
11
+ private reportUnknownFields;
11
12
  private checksum;
12
13
  encodeMessage(msgType: string, obj: ILooseObject): (ILooseObject | null);
13
14
  }
@@ -40,6 +40,21 @@ let AsciiMsgTransmitter = class AsciiMsgTransmitter extends msg_transmitter_1.Ms
40
40
  const components = config.definitions.component;
41
41
  this.header = components.get('StandardHeader');
42
42
  this.trailer = components.get('StandardTrailer');
43
+ this.reportUnknownFields(config);
44
+ }
45
+ reportUnknownFields(config) {
46
+ var _a, _b;
47
+ const name = (_b = (_a = config.description.application) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'na';
48
+ const logger = config.logFactory.logger(`${name}:encoder`);
49
+ const reported = new Set();
50
+ this.encoder.onUnknownField = (fieldName, setName) => {
51
+ const key = `${setName}.${fieldName}`;
52
+ if (reported.has(key))
53
+ return;
54
+ reported.add(key);
55
+ logger.warning(`field '${fieldName}' is not declared on ${setName} in this dictionary - it will not be sent`);
56
+ this.emit('unknown-field', fieldName, setName);
57
+ };
43
58
  }
44
59
  checksum() {
45
60
  const buffer = this.buffer;
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-msg-transmitter.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-msg-transmitter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAA4E;AAC5E,wDAAmD;AAMnD,uCAA6C;AAC7C,uDAAkD;AAI3C,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,gCAAc;IAOrD,YAA4D,MAAoB;;QAC9E,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAgB,oBAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QAD5D,WAAM,GAAN,MAAM,CAAc;QAE9E,IAAI,CAAC,SAAS,GAAG,CAAC,MAAA,MAAM,CAAC,WAAW,CAAC,cAAc,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,EAAE,GAAkB,IAAI,qBAAa,CAAC,MAAM,CAAC,CAAA;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,oBAAY,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,EAC5D,MAAA,MAAM,CAAC,SAAS,mCAAI,kBAAU,CAAC,GAAG,EAClC,MAAA,MAAM,CAAC,YAAY,mCAAI,kBAAU,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAA;QAC/C,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;QAC9C,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IAClD,CAAC;IAEO,QAAQ;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,OAAO,GAAiB,IAAI,CAAC,OAAuB,CAAA;QAC1D,IAAI,QAAQ,GAAW,MAAM,CAAC,GAAG,EAAE,CAAA;QACnC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAA;YACvC,QAAQ,IAAI,OAAO,GAAG,OAAO,CAAC,YAAY,CAAA;YAC1C,QAAQ,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAA;QACzC,CAAC;QACD,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAA;QACzB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,aAAa,CAAE,OAAe,EAAE,GAAiB;;QACtD,MAAM,OAAO,GAAiB,IAAI,CAAC,OAAuB,CAAA;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QACnC,IAAI,WAAW,GAA6B,EAAE,CAAA;QAC9C,MAAM,EAAE,cAAc,KAAmB,GAAG,EAAjB,SAAS,UAAK,GAAG,EAAtC,kBAAgC,CAAM,CAAA;QAC5C,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,KAAY,cAAc,EAArB,EAAE,UAAK,cAAc,EAAlH,sGAAiG,CAAiB,CAAA;YACxH,WAAW,GAAG,EAAE,CAAA;YAChB,WAAW,CAAC,eAAe,GAAG,WAAW,CAAA;QAC3C,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAA;QAC3C,MAAM,GAAG,GAAwB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,mCAAI,IAAI,CAAA;QAEtG,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACrB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,MAAM,GAAkC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACnF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,gDAAgD,OAAO,EAAE,CAAC,CAAC,CAAA;YACxF,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,UAAU,GAAW,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,IAAI,mCAAI,QAAQ,CAAA;QACxD,MAAM,WAAW,GAAW,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,mCAAI,SAAS,CAAA;QAC3D,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAA;QACpC,MAAM,UAAU,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAA,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,mCAAI,CAAC,CAAC,CAAA;QACpF,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAA;QAChD,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAW,IAAI,CAAC,QAAQ,EAAE,CAAA;QACxC,MAAM,GAAG,GAAwB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,QAAQ,CAAC,mCAAI,IAAI,CAAA;QACnE,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF,CAAA;AA3EY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,qBAAU,GAAE;IAQG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GAPhC,mBAAmB,CA2E/B","sourcesContent":["import { AsciiChars, AsciiEncoder, TimeFormatter } from '../../buffer/ascii'\nimport { MsgTransmitter } from '../msg-transmitter'\nimport { ILooseObject } from '../../collections/collection'\nimport { IContainedSet } from '../../dictionary/contained'\nimport { MessageDefinition } from '../../dictionary/definition'\nimport { IJsFixConfig } from '../../config'\nimport { IStandardHeader } from '../../types/FIX4.4/repo'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ElasticBuffer } from '../../buffer'\n\n@injectable()\nexport class AsciiMsgTransmitter extends MsgTransmitter {\n public msgSeqNum: number\n public time: Date\n\n private readonly header: IContainedSet | undefined\n private readonly trailer: IContainedSet | undefined\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config.sessionContainer.resolve<ElasticBuffer>(DITokens.TransmitBuffer), config.definitions, config.description)\n this.msgSeqNum = (config.description.LastSentSeqNum ?? 0) + 1 // adding 1 as this the next sequence # to use.\n const buffer = this.buffer\n const tf: TimeFormatter = new TimeFormatter(buffer)\n this.encoder = new AsciiEncoder(buffer, config.definitions, tf,\n config.delimiter ?? AsciiChars.Soh,\n config.logDelimiter ?? AsciiChars.Pipe)\n const components = config.definitions.component\n this.header = components.get('StandardHeader')\n this.trailer = components.get('StandardTrailer')\n }\n\n private checksum (): number {\n const buffer = this.buffer\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n let checksum: number = buffer.sum()\n if (encoder.delimiter !== encoder.logDelimiter) {\n const changes = encoder.tags.nextTagPos\n checksum -= changes * encoder.logDelimiter\n checksum += changes * encoder.delimiter\n }\n checksum = checksum % 256\n return checksum\n }\n\n public encodeMessage (msgType: string, obj: ILooseObject): (ILooseObject | null) {\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n const factory = this.config.factory\n let headerProps: Partial<IStandardHeader> = {}\n const { StandardHeader, ...bodyProps } = obj\n if (StandardHeader) {\n const { BeginString, BodyLength, MsgType, SenderCompID, SendingTime, TargetCompID, TargetSubID, ...hp } = StandardHeader\n headerProps = hp // pick up any optional applied by application\n headerProps.OrigSendingTime = SendingTime // when first sent\n }\n\n const msgSeqNum = this.msgSeqNum\n const sendingTime = this.time || new Date()\n const hdr: ILooseObject | null = factory?.header(msgType, msgSeqNum, sendingTime, headerProps) ?? null\n // Only increment sequence number if this is not a duplicate message.\n if (!hdr) return null\n if (!headerProps.PossDupFlag) {\n this.msgSeqNum++\n }\n\n const buffer = this.buffer\n buffer.reset()\n const msgDef: MessageDefinition | undefined = this.definitions.message.get(msgType)\n if (!msgDef) {\n this.emit('error', new Error(`ascii transmitter cannot find definition for ${msgType}`))\n return null\n }\n const headerName: string = this.header?.name ?? 'header'\n const trailerName: string = this.trailer?.name ?? 'trailer'\n encoder.encode(hdr, headerName)\n encoder.encode(bodyProps, msgDef.name)\n const lenPos = encoder.bodyLengthPos\n const bodyLength: number = Math.max(4, this.config.description.BodyLengthChars ?? 7)\n const len = buffer.getPos() - encoder.msgTypePos\n buffer.patchPaddedNumberAtPos(lenPos, len, bodyLength)\n const checksum: number = this.checksum()\n const trl: ILooseObject | null = factory?.trailer(checksum) ?? null\n if (trl) {\n encoder.encode(trl, trailerName)\n }\n return hdr\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-msg-transmitter.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-msg-transmitter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAA4E;AAC5E,wDAAmD;AAMnD,uCAA6C;AAC7C,uDAAkD;AAI3C,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,gCAAc;IAOrD,YAA4D,MAAoB;;QAC9E,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAgB,oBAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QAD5D,WAAM,GAAN,MAAM,CAAc;QAE9E,IAAI,CAAC,SAAS,GAAG,CAAC,MAAA,MAAM,CAAC,WAAW,CAAC,cAAc,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,EAAE,GAAkB,IAAI,qBAAa,CAAC,MAAM,CAAC,CAAA;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,oBAAY,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,EAC5D,MAAA,MAAM,CAAC,SAAS,mCAAI,kBAAU,CAAC,GAAG,EAClC,MAAA,MAAM,CAAC,YAAY,mCAAI,kBAAU,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAA;QAC/C,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;QAC9C,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;QAChD,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAQO,mBAAmB,CAAE,MAAoB;;QAC/C,MAAM,IAAI,GAAG,MAAA,MAAA,MAAM,CAAC,WAAW,CAAC,WAAW,0CAAE,IAAI,mCAAI,IAAI,CAAA;QACzD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;QAClC,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,CAAC,SAAiB,EAAE,OAAe,EAAE,EAAE;YACnE,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,SAAS,EAAE,CAAA;YACrC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAM;YAC7B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACjB,MAAM,CAAC,OAAO,CAAC,UAAU,SAAS,wBAAwB,OAAO,2CAA2C,CAAC,CAAA;YAC7G,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAChD,CAAC,CAAA;IACH,CAAC;IAEO,QAAQ;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,OAAO,GAAiB,IAAI,CAAC,OAAuB,CAAA;QAC1D,IAAI,QAAQ,GAAW,MAAM,CAAC,GAAG,EAAE,CAAA;QACnC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAA;YACvC,QAAQ,IAAI,OAAO,GAAG,OAAO,CAAC,YAAY,CAAA;YAC1C,QAAQ,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAA;QACzC,CAAC;QACD,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAA;QACzB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,aAAa,CAAE,OAAe,EAAE,GAAiB;;QACtD,MAAM,OAAO,GAAiB,IAAI,CAAC,OAAuB,CAAA;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QACnC,IAAI,WAAW,GAA6B,EAAE,CAAA;QAC9C,MAAM,EAAE,cAAc,KAAmB,GAAG,EAAjB,SAAS,UAAK,GAAG,EAAtC,kBAAgC,CAAM,CAAA;QAC5C,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,KAAY,cAAc,EAArB,EAAE,UAAK,cAAc,EAAlH,sGAAiG,CAAiB,CAAA;YACxH,WAAW,GAAG,EAAE,CAAA;YAChB,WAAW,CAAC,eAAe,GAAG,WAAW,CAAA;QAC3C,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAA;QAC3C,MAAM,GAAG,GAAwB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,mCAAI,IAAI,CAAA;QAEtG,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QACrB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAA;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,MAAM,GAAkC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACnF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,gDAAgD,OAAO,EAAE,CAAC,CAAC,CAAA;YACxF,OAAO,IAAI,CAAA;QACb,CAAC;QACD,MAAM,UAAU,GAAW,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,IAAI,mCAAI,QAAQ,CAAA;QACxD,MAAM,WAAW,GAAW,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,mCAAI,SAAS,CAAA;QAC3D,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAA;QACpC,MAAM,UAAU,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAA,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,mCAAI,CAAC,CAAC,CAAA;QACpF,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAA;QAChD,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAW,IAAI,CAAC,QAAQ,EAAE,CAAA;QACxC,MAAM,GAAG,GAAwB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,QAAQ,CAAC,mCAAI,IAAI,CAAA;QACnE,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF,CAAA;AA/FY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,qBAAU,GAAE;IAQG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GAPhC,mBAAmB,CA+F/B","sourcesContent":["import { AsciiChars, AsciiEncoder, TimeFormatter } from '../../buffer/ascii'\nimport { MsgTransmitter } from '../msg-transmitter'\nimport { ILooseObject } from '../../collections/collection'\nimport { IContainedSet } from '../../dictionary/contained'\nimport { MessageDefinition } from '../../dictionary/definition'\nimport { IJsFixConfig } from '../../config'\nimport { IStandardHeader } from '../../types/FIX4.4/repo'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ElasticBuffer } from '../../buffer'\n\n@injectable()\nexport class AsciiMsgTransmitter extends MsgTransmitter {\n public msgSeqNum: number\n public time: Date\n\n private readonly header: IContainedSet | undefined\n private readonly trailer: IContainedSet | undefined\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config.sessionContainer.resolve<ElasticBuffer>(DITokens.TransmitBuffer), config.definitions, config.description)\n this.msgSeqNum = (config.description.LastSentSeqNum ?? 0) + 1 // adding 1 as this the next sequence # to use.\n const buffer = this.buffer\n const tf: TimeFormatter = new TimeFormatter(buffer)\n this.encoder = new AsciiEncoder(buffer, config.definitions, tf,\n config.delimiter ?? AsciiChars.Soh,\n config.logDelimiter ?? AsciiChars.Pipe)\n const components = config.definitions.component\n this.header = components.get('StandardHeader')\n this.trailer = components.get('StandardTrailer')\n this.reportUnknownFields(config)\n }\n\n /**\n * A field the dictionary does not declare on the message being encoded has no tag,\n * so it cannot be written and is dropped. Say so once per offending field - the\n * alternative, and what this library did for years, is that a bespoke Logon tag\n * simply never appears on the wire and nothing anywhere explains why.\n */\n private reportUnknownFields (config: IJsFixConfig): void {\n const name = config.description.application?.name ?? 'na'\n const logger = config.logFactory.logger(`${name}:encoder`)\n const reported = new Set<string>()\n this.encoder.onUnknownField = (fieldName: string, setName: string) => {\n const key = `${setName}.${fieldName}`\n if (reported.has(key)) return\n reported.add(key)\n logger.warning(`field '${fieldName}' is not declared on ${setName} in this dictionary - it will not be sent`)\n this.emit('unknown-field', fieldName, setName)\n }\n }\n\n private checksum (): number {\n const buffer = this.buffer\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n let checksum: number = buffer.sum()\n if (encoder.delimiter !== encoder.logDelimiter) {\n const changes = encoder.tags.nextTagPos\n checksum -= changes * encoder.logDelimiter\n checksum += changes * encoder.delimiter\n }\n checksum = checksum % 256\n return checksum\n }\n\n public encodeMessage (msgType: string, obj: ILooseObject): (ILooseObject | null) {\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n const factory = this.config.factory\n let headerProps: Partial<IStandardHeader> = {}\n const { StandardHeader, ...bodyProps } = obj\n if (StandardHeader) {\n const { BeginString, BodyLength, MsgType, SenderCompID, SendingTime, TargetCompID, TargetSubID, ...hp } = StandardHeader\n headerProps = hp // pick up any optional applied by application\n headerProps.OrigSendingTime = SendingTime // when first sent\n }\n\n const msgSeqNum = this.msgSeqNum\n const sendingTime = this.time || new Date()\n const hdr: ILooseObject | null = factory?.header(msgType, msgSeqNum, sendingTime, headerProps) ?? null\n // Only increment sequence number if this is not a duplicate message.\n if (!hdr) return null\n if (!headerProps.PossDupFlag) {\n this.msgSeqNum++\n }\n\n const buffer = this.buffer\n buffer.reset()\n const msgDef: MessageDefinition | undefined = this.definitions.message.get(msgType)\n if (!msgDef) {\n this.emit('error', new Error(`ascii transmitter cannot find definition for ${msgType}`))\n return null\n }\n const headerName: string = this.header?.name ?? 'header'\n const trailerName: string = this.trailer?.name ?? 'trailer'\n encoder.encode(hdr, headerName)\n encoder.encode(bodyProps, msgDef.name)\n const lenPos = encoder.bodyLengthPos\n const bodyLength: number = Math.max(4, this.config.description.BodyLengthChars ?? 7)\n const len = buffer.getPos() - encoder.msgTypePos\n buffer.patchPaddedNumberAtPos(lenPos, len, bodyLength)\n const checksum: number = this.checksum()\n const trl: ILooseObject | null = factory?.trailer(checksum) ?? null\n if (trl) {\n encoder.encode(trl, trailerName)\n }\n return hdr\n }\n}\n"]}
@@ -13,13 +13,7 @@ class AsciiSessionMsgFactory extends a_session_msg_factory_1.ASessionMsgFactory
13
13
  }
14
14
  logon() {
15
15
  const description = this.description;
16
- const o = {
17
- Username: description.Username,
18
- Password: description.Password,
19
- HeartBtInt: description.HeartBtInt,
20
- ResetSeqNumFlag: description.ResetSeqNumFlag,
21
- EncryptMethod: repo_1.EncryptMethod.None
22
- };
16
+ const o = Object.assign({ Username: description.Username, Password: description.Password, HeartBtInt: description.HeartBtInt, ResetSeqNumFlag: description.ResetSeqNumFlag, EncryptMethod: repo_1.EncryptMethod.None }, description.Logon);
23
17
  return this.mutate(o, types_1.MsgType.Logon);
24
18
  }
25
19
  logout(text) {
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,kDAKgC;AAEhC,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;QAEpD,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,WAAW,CAAC,WAAW,0CAAE,QAAQ,MAAK,OAAO,CAAA;IAC9D,CAAC;IAEM,KAAK;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAW;YAChB,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,eAAe,EAAE,WAAW,CAAC,eAAe;YAC5C,aAAa,EAAE,oBAAa,CAAC,IAAI;SACxB,CAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAEM,MAAM,CAAE,IAAY;QACzB,MAAM,CAAC,GAAY;YACjB,IAAI,EAAE,IAAI;SACA,CAAA;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,MAAc,EAAE,IAAU,EAAE,YAAuC;;QACjG,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,UAAU,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAA,WAAW,CAAC,eAAe,mCAAI,CAAC,CAAC,CAAA;QACxE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QACpD,MAAM,CAAC,mBACL,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,WAAW,EAAE,WAAW,CAAC,WAAW,IACjC,YAAY,CAChB,CAAA;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACzC,CAAC;CACF;AA3CD,wDA2CC;AAED,MAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,YAA6B,WAAgC,EAAS,UAAgC,IAAI;QACxG,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADA,gBAAW,GAAX,WAAW,CAAqB;QAAS,YAAO,GAAP,OAAO,CAA6B;IAE1G,CAAC;CACF;AAJD,8CAIC","sourcesContent":["import { ISessionDescription } from '../session/session-description'\nimport { ILooseObject } from '../../collections/collection'\nimport { MsgType } from '../../types'\nimport { ASessionMsgFactory, ObjectMutator } from '../session/a-session-msg-factory'\n\nimport {\n EncryptMethod,\n ILogon,\n ILogout,\n IStandardHeader\n} from '../../types/FIX4.4/repo'\n\nexport class AsciiSessionMsgFactory extends ASessionMsgFactory {\n constructor (readonly description: ISessionDescription, mutator: ObjectMutator | null = null) {\n super(description, mutator)\n this.isAscii = description.application?.protocol === 'ascii'\n }\n\n public logon (): ILooseObject {\n const description = this.description\n const o: ILogon = {\n Username: description.Username,\n Password: description.Password,\n HeartBtInt: description.HeartBtInt,\n ResetSeqNumFlag: description.ResetSeqNumFlag,\n EncryptMethod: EncryptMethod.None\n } as ILogon\n return this.mutate(o, MsgType.Logon)\n }\n\n public logout (text: string): ILooseObject {\n const o: ILogout = {\n Text: text\n } as ILogout\n return this.mutate(o, MsgType.Logout)\n }\n\n public header (msgType: string, seqNum: number, time: Date, overrideData?: Partial<IStandardHeader>): ILooseObject {\n const description = this.description\n const bodyLength: number = Math.max(4, description.BodyLengthChars ?? 7)\n const placeHolder = Math.pow(10, bodyLength - 1) + 1\n const o: IStandardHeader = {\n BeginString: description.BeginString,\n BodyLength: placeHolder,\n MsgType: msgType,\n SenderCompID: description.SenderCompId,\n MsgSeqNum: seqNum,\n SendingTime: time,\n TargetCompID: description.TargetCompID,\n TargetSubID: description.TargetSubID,\n SenderSubID: description.SenderSubID,\n ...overrideData\n }\n return this.mutate(o, 'StandardHeader')\n }\n}\n\nexport class SessionMsgFactory extends AsciiSessionMsgFactory {\n constructor (public readonly description: ISessionDescription, public mutator: ObjectMutator | null = null) {\n super(description, mutator)\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,kDAKgC;AAEhC,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;QAEpD,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,WAAW,CAAC,WAAW,0CAAE,QAAQ,MAAK,OAAO,CAAA;IAC9D,CAAC;IAEM,KAAK;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAW,gBAChB,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,UAAU,EAAE,WAAW,CAAC,UAAU,EAClC,eAAe,EAAE,WAAW,CAAC,eAAe,EAC5C,aAAa,EAAE,oBAAa,CAAC,IAAI,IAK9B,WAAW,CAAC,KAAK,CACX,CAAA;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAEM,MAAM,CAAE,IAAY;QACzB,MAAM,CAAC,GAAY;YACjB,IAAI,EAAE,IAAI;SACA,CAAA;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,MAAc,EAAE,IAAU,EAAE,YAAuC;;QACjG,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,UAAU,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAA,WAAW,CAAC,eAAe,mCAAI,CAAC,CAAC,CAAA;QACxE,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QACpD,MAAM,CAAC,mBACL,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,EACjB,YAAY,EAAE,WAAW,CAAC,YAAY,EACtC,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,WAAW,EAAE,WAAW,CAAC,WAAW,IACjC,YAAY,CAChB,CAAA;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACzC,CAAC;CACF;AAhDD,wDAgDC;AAED,MAAa,iBAAkB,SAAQ,sBAAsB;IAC3D,YAA6B,WAAgC,EAAS,UAAgC,IAAI;QACxG,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADA,gBAAW,GAAX,WAAW,CAAqB;QAAS,YAAO,GAAP,OAAO,CAA6B;IAE1G,CAAC;CACF;AAJD,8CAIC","sourcesContent":["import { ISessionDescription } from '../session/session-description'\nimport { ILooseObject } from '../../collections/collection'\nimport { MsgType } from '../../types'\nimport { ASessionMsgFactory, ObjectMutator } from '../session/a-session-msg-factory'\n\nimport {\n EncryptMethod,\n ILogon,\n ILogout,\n IStandardHeader\n} from '../../types/FIX4.4/repo'\n\nexport class AsciiSessionMsgFactory extends ASessionMsgFactory {\n constructor (readonly description: ISessionDescription, mutator: ObjectMutator | null = null) {\n super(description, mutator)\n this.isAscii = description.application?.protocol === 'ascii'\n }\n\n public logon (): ILooseObject {\n const description = this.description\n const o: ILogon = {\n Username: description.Username,\n Password: description.Password,\n HeartBtInt: description.HeartBtInt,\n ResetSeqNumFlag: description.ResetSeqNumFlag,\n EncryptMethod: EncryptMethod.None,\n // a counterparty demanding a tag the standard Logon does not carry needs no\n // code at all - name it under \"Logon\" in the session description. Spread last\n // so an application can also override what the engine derived, or null out a\n // field it does not want sent. See issue #93.\n ...description.Logon\n } as ILogon\n return this.mutate(o, MsgType.Logon)\n }\n\n public logout (text: string): ILooseObject {\n const o: ILogout = {\n Text: text\n } as ILogout\n return this.mutate(o, MsgType.Logout)\n }\n\n public header (msgType: string, seqNum: number, time: Date, overrideData?: Partial<IStandardHeader>): ILooseObject {\n const description = this.description\n const bodyLength: number = Math.max(4, description.BodyLengthChars ?? 7)\n const placeHolder = Math.pow(10, bodyLength - 1) + 1\n const o: IStandardHeader = {\n BeginString: description.BeginString,\n BodyLength: placeHolder,\n MsgType: msgType,\n SenderCompID: description.SenderCompId,\n MsgSeqNum: seqNum,\n SendingTime: time,\n TargetCompID: description.TargetCompID,\n TargetSubID: description.TargetSubID,\n SenderSubID: description.SenderSubID,\n ...overrideData\n }\n return this.mutate(o, 'StandardHeader')\n }\n}\n\nexport class SessionMsgFactory extends AsciiSessionMsgFactory {\n constructor (public readonly description: ISessionDescription, public mutator: ObjectMutator | null = null) {\n super(description, mutator)\n }\n}\n"]}
@@ -28,12 +28,7 @@ class FixmlSessionMsgFactory extends a_session_msg_factory_1.ASessionMsgFactory
28
28
  fixmlLogon(userRequestId, isResponse) {
29
29
  const description = this.description;
30
30
  if (!isResponse) {
31
- const o = {
32
- Username: description.Username,
33
- Password: description.Password,
34
- UserRequestID: userRequestId,
35
- UserRequestType: FIXML50SP2_1.UserRequestType.LogOnUser
36
- };
31
+ const o = Object.assign({ Username: description.Username, Password: description.Password, UserRequestID: userRequestId, UserRequestType: FIXML50SP2_1.UserRequestType.LogOnUser }, description.Logon);
37
32
  return this.mutate(o, types_1.MsgType.Logon);
38
33
  }
39
34
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"fixml-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/fixml/fixml-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,uDAM+B;AAE/B,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;IAEtD,CAAC;IAEM,KAAK,CAAE,gBAAwB,EAAE,EAAE,aAAsB,KAAK;QACnE,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;IACnD,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,IAAY;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAA;IACzD,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,SAAiB,CAAC,EAAE,OAAa,IAAI,IAAI,EAAE,EAAE,YAAuC;QAClH,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAoB;YACzB,YAAY,EAAE,WAAW,CAAC,YAAY;YACtC,YAAY,EAAE,WAAW,CAAC,YAAY;YACtC,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,WAAW,EAAE,WAAW,CAAC,WAAW;SAClB,CAAA;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACzC,CAAC;IAEO,UAAU,CAAE,aAAqB,EAAE,UAAmB;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,GAAiB;gBACtB,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,aAAa,EAAE,aAAa;gBAC5B,eAAe,EAAE,4BAAe,CAAC,SAAS;aAC3B,CAAA;YACjB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAkB;gBACvB,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,aAAa,EAAE,aAAa;gBAC5B,UAAU,EAAE,uBAAU,CAAC,QAAQ;aACf,CAAA;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAEO,WAAW,CAAE,aAAqB,EAAE,UAAmB;QAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,GAAiB;gBACtB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,aAAa,EAAE,aAAa;gBAC5B,eAAe,EAAE,4BAAe,CAAC,UAAU;aAC5B,CAAA;YACjB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAkB;gBACvB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,aAAa,EAAE,aAAa;gBAC5B,UAAU,EAAE,uBAAU,CAAC,WAAW;aAClB,CAAA;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;CACF;AA7DD,wDA6DC","sourcesContent":["import { ISessionDescription } from '../session/session-description'\nimport { ILooseObject } from '../../collections/collection'\nimport { MsgType } from '../../types'\nimport { ASessionMsgFactory, ObjectMutator } from '../session/a-session-msg-factory'\n\nimport {\n IStandardHeader,\n IUserRequest,\n IUserResponse,\n UserRequestType,\n UserStatus\n} from '../../types/FIXML50SP2'\n\nexport class FixmlSessionMsgFactory extends ASessionMsgFactory {\n constructor (readonly description: ISessionDescription, mutator: ObjectMutator | null = null) {\n super(description, mutator)\n }\n\n public logon (userRequestId: string = '', isResponse: boolean = false): ILooseObject {\n return this.fixmlLogon(userRequestId, isResponse)\n }\n\n public logout (msgType: string, text: string): ILooseObject {\n return this.fixmlLogout(msgType, msgType !== 'UserReq')\n }\n\n public header (msgType: string, seqNum: number = 0, time: Date = new Date(), overrideData?: Partial<IStandardHeader>): ILooseObject {\n const description = this.description\n const o: IStandardHeader = {\n SenderCompID: description.SenderCompId,\n TargetCompID: description.TargetCompID,\n SenderSubID: description.SenderSubID,\n TargetSubID: description.TargetSubID\n } as IStandardHeader\n return this.mutate(o, 'StandardHeader')\n }\n\n private fixmlLogon (userRequestId: string, isResponse: boolean): ILooseObject {\n const description = this.description\n if (!isResponse) {\n const o: IUserRequest = {\n Username: description.Username,\n Password: description.Password,\n UserRequestID: userRequestId,\n UserRequestType: UserRequestType.LogOnUser\n } as IUserRequest\n return this.mutate(o, MsgType.Logon)\n } else {\n const o: IUserResponse = {\n Username: description.Username,\n UserRequestID: userRequestId,\n UserStatus: UserStatus.LoggedIn\n } as IUserResponse\n return this.mutate(o, MsgType.Logon)\n }\n }\n\n private fixmlLogout (userRequestId: string, isResponse: boolean): ILooseObject {\n if (!isResponse) {\n const o: IUserRequest = {\n Username: this.description.Username,\n UserRequestID: userRequestId,\n UserRequestType: UserRequestType.LogOffUser\n } as IUserRequest\n return this.mutate(o, MsgType.Logout)\n } else {\n const o: IUserResponse = {\n Username: this.description.Username,\n UserRequestID: userRequestId,\n UserStatus: UserStatus.NotLoggedIn\n } as IUserResponse\n return this.mutate(o, MsgType.Logout)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"fixml-session-msg-factory.js","sourceRoot":"","sources":["../../../src/transport/fixml/fixml-session-msg-factory.ts"],"names":[],"mappings":";;;AAEA,uCAAqC;AACrC,4EAAoF;AAEpF,uDAM+B;AAE/B,MAAa,sBAAuB,SAAQ,0CAAkB;IAC5D,YAAsB,WAAgC,EAAE,UAAgC,IAAI;QAC1F,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QADP,gBAAW,GAAX,WAAW,CAAqB;IAEtD,CAAC;IAEM,KAAK,CAAE,gBAAwB,EAAE,EAAE,aAAsB,KAAK;QACnE,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;IACnD,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,IAAY;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAA;IACzD,CAAC;IAEM,MAAM,CAAE,OAAe,EAAE,SAAiB,CAAC,EAAE,OAAa,IAAI,IAAI,EAAE,EAAE,YAAuC;QAClH,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,MAAM,CAAC,GAAoB;YACzB,YAAY,EAAE,WAAW,CAAC,YAAY;YACtC,YAAY,EAAE,WAAW,CAAC,YAAY;YACtC,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,WAAW,EAAE,WAAW,CAAC,WAAW;SAClB,CAAA;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACzC,CAAC;IAEO,UAAU,CAAE,aAAqB,EAAE,UAAmB;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,GAAiB,gBACtB,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAC9B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,4BAAe,CAAC,SAAS,IAEvC,WAAW,CAAC,KAAK,CACL,CAAA;YACjB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAkB;gBACvB,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,aAAa,EAAE,aAAa;gBAC5B,UAAU,EAAE,uBAAU,CAAC,QAAQ;aACf,CAAA;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAEO,WAAW,CAAE,aAAqB,EAAE,UAAmB;QAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,GAAiB;gBACtB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,aAAa,EAAE,aAAa;gBAC5B,eAAe,EAAE,4BAAe,CAAC,UAAU;aAC5B,CAAA;YACjB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAkB;gBACvB,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,aAAa,EAAE,aAAa;gBAC5B,UAAU,EAAE,uBAAU,CAAC,WAAW;aAClB,CAAA;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,eAAO,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;CACF;AA/DD,wDA+DC","sourcesContent":["import { ISessionDescription } from '../session/session-description'\nimport { ILooseObject } from '../../collections/collection'\nimport { MsgType } from '../../types'\nimport { ASessionMsgFactory, ObjectMutator } from '../session/a-session-msg-factory'\n\nimport {\n IStandardHeader,\n IUserRequest,\n IUserResponse,\n UserRequestType,\n UserStatus\n} from '../../types/FIXML50SP2'\n\nexport class FixmlSessionMsgFactory extends ASessionMsgFactory {\n constructor (readonly description: ISessionDescription, mutator: ObjectMutator | null = null) {\n super(description, mutator)\n }\n\n public logon (userRequestId: string = '', isResponse: boolean = false): ILooseObject {\n return this.fixmlLogon(userRequestId, isResponse)\n }\n\n public logout (msgType: string, text: string): ILooseObject {\n return this.fixmlLogout(msgType, msgType !== 'UserReq')\n }\n\n public header (msgType: string, seqNum: number = 0, time: Date = new Date(), overrideData?: Partial<IStandardHeader>): ILooseObject {\n const description = this.description\n const o: IStandardHeader = {\n SenderCompID: description.SenderCompId,\n TargetCompID: description.TargetCompID,\n SenderSubID: description.SenderSubID,\n TargetSubID: description.TargetSubID\n } as IStandardHeader\n return this.mutate(o, 'StandardHeader')\n }\n\n private fixmlLogon (userRequestId: string, isResponse: boolean): ILooseObject {\n const description = this.description\n if (!isResponse) {\n const o: IUserRequest = {\n Username: description.Username,\n Password: description.Password,\n UserRequestID: userRequestId,\n UserRequestType: UserRequestType.LogOnUser,\n // same escape hatch as the ascii factory - see ISessionDescription.Logon\n ...description.Logon\n } as IUserRequest\n return this.mutate(o, MsgType.Logon)\n } else {\n const o: IUserResponse = {\n Username: description.Username,\n UserRequestID: userRequestId,\n UserStatus: UserStatus.LoggedIn\n } as IUserResponse\n return this.mutate(o, MsgType.Logon)\n }\n }\n\n private fixmlLogout (userRequestId: string, isResponse: boolean): ILooseObject {\n if (!isResponse) {\n const o: IUserRequest = {\n Username: this.description.Username,\n UserRequestID: userRequestId,\n UserRequestType: UserRequestType.LogOffUser\n } as IUserRequest\n return this.mutate(o, MsgType.Logout)\n } else {\n const o: IUserResponse = {\n Username: this.description.Username,\n UserRequestID: userRequestId,\n UserStatus: UserStatus.NotLoggedIn\n } as IUserResponse\n return this.mutate(o, MsgType.Logout)\n }\n }\n}\n"]}
@@ -4,7 +4,10 @@ export * from './fix-acceptor';
4
4
  export * from './fix-initiator';
5
5
  export * from './msg-transmitter';
6
6
  export * from './msg-payload';
7
+ export * from './send-callback';
7
8
  export * from './tick-action';
8
9
  export * from './msg-application';
9
10
  export * from './ascii/ascii-session';
11
+ export * from './ascii/ascii-session-msg-factory';
12
+ export * from './fixml/fixml-session-msg-factory';
10
13
  export * from './session';
@@ -20,8 +20,11 @@ __exportStar(require("./fix-acceptor"), exports);
20
20
  __exportStar(require("./fix-initiator"), exports);
21
21
  __exportStar(require("./msg-transmitter"), exports);
22
22
  __exportStar(require("./msg-payload"), exports);
23
+ __exportStar(require("./send-callback"), exports);
23
24
  __exportStar(require("./tick-action"), exports);
24
25
  __exportStar(require("./msg-application"), exports);
25
26
  __exportStar(require("./ascii/ascii-session"), exports);
27
+ __exportStar(require("./ascii/ascii-session-msg-factory"), exports);
28
+ __exportStar(require("./fixml/fixml-session-msg-factory"), exports);
26
29
  __exportStar(require("./session"), exports);
27
30
  //# sourceMappingURL=index.js.map