jspurefix 5.3.0 → 5.5.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 (45) hide show
  1. package/BACKPORT_PLAN.md +120 -10
  2. package/dist/dictionary/parser/quickfix/dictionary-validator.d.ts +39 -0
  3. package/dist/dictionary/parser/quickfix/dictionary-validator.js +321 -0
  4. package/dist/dictionary/parser/quickfix/dictionary-validator.js.map +1 -0
  5. package/dist/dictionary/parser/quickfix/index-visitor.d.ts +10 -0
  6. package/dist/dictionary/parser/quickfix/index-visitor.js +68 -0
  7. package/dist/dictionary/parser/quickfix/index-visitor.js.map +1 -0
  8. package/dist/dictionary/parser/quickfix/index.d.ts +7 -0
  9. package/dist/dictionary/parser/quickfix/index.js +7 -0
  10. package/dist/dictionary/parser/quickfix/index.js.map +1 -1
  11. package/dist/dictionary/parser/quickfix/quick-fix-graph-file-parser.d.ts +13 -0
  12. package/dist/dictionary/parser/quickfix/quick-fix-graph-file-parser.js +65 -0
  13. package/dist/dictionary/parser/quickfix/quick-fix-graph-file-parser.js.map +1 -0
  14. package/dist/dictionary/parser/quickfix/quick-fix-graph-parser.d.ts +73 -0
  15. package/dist/dictionary/parser/quickfix/quick-fix-graph-parser.js +363 -0
  16. package/dist/dictionary/parser/quickfix/quick-fix-graph-parser.js.map +1 -0
  17. package/dist/dictionary/parser/quickfix/sax-tree-builder.d.ts +5 -0
  18. package/dist/dictionary/parser/quickfix/sax-tree-builder.js +103 -0
  19. package/dist/dictionary/parser/quickfix/sax-tree-builder.js.map +1 -0
  20. package/dist/dictionary/parser/quickfix/validation-error.d.ts +17 -0
  21. package/dist/dictionary/parser/quickfix/validation-error.js +32 -0
  22. package/dist/dictionary/parser/quickfix/validation-error.js.map +1 -0
  23. package/dist/dictionary/parser/quickfix/x-element.d.ts +26 -0
  24. package/dist/dictionary/parser/quickfix/x-element.js +82 -0
  25. package/dist/dictionary/parser/quickfix/x-element.js.map +1 -0
  26. package/dist/store/fix-msg-ascii-store-resend.js +6 -0
  27. package/dist/store/fix-msg-ascii-store-resend.js.map +1 -1
  28. package/dist/store/store-config.d.ts +1 -0
  29. package/dist/store/store-config.js.map +1 -1
  30. package/dist/util/definition-factory.js +1 -1
  31. package/dist/util/definition-factory.js.map +1 -1
  32. package/jsfix.test_client.txt +67 -67
  33. package/jsfix.test_server.txt +64 -64
  34. package/package.json +6 -6
  35. package/src/dictionary/parser/quickfix/dictionary-validator.ts +473 -0
  36. package/src/dictionary/parser/quickfix/index-visitor.ts +100 -0
  37. package/src/dictionary/parser/quickfix/index.ts +7 -0
  38. package/src/dictionary/parser/quickfix/quick-fix-graph-file-parser.ts +63 -0
  39. package/src/dictionary/parser/quickfix/quick-fix-graph-parser.ts +450 -0
  40. package/src/dictionary/parser/quickfix/sax-tree-builder.ts +112 -0
  41. package/src/dictionary/parser/quickfix/validation-error.ts +34 -0
  42. package/src/dictionary/parser/quickfix/x-element.ts +115 -0
  43. package/src/store/fix-msg-ascii-store-resend.ts +8 -0
  44. package/src/store/store-config.ts +1 -0
  45. package/src/util/definition-factory.ts +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quick-fix-graph-parser.js","sourceRoot":"","sources":["../../../../src/dictionary/parser/quickfix/quick-fix-graph-parser.ts"],"names":[],"mappings":";;;AAWA,yDAAmD;AACnD,iEAA4D;AAC5D,sEAAiE;AACjE,sFAAgF;AAChF,4FAAsF;AACtF,oFAA8E;AAC9E,4EAAuE;AAEvE,mFAA6E;AAC7E,yFAAmF;AACnF,iFAA2E;AAC3E,iFAA2E;AAC3E,uEAAiE;AACjE,qDAAgD;AAChD,mDAA8C;AAE9C,IAAY,eASX;AATD,WAAY,eAAe;IACzB,0DAAuC,CAAA;IACvC,kEAA+C,CAAA;IAC/C,oEAAiD,CAAA;IACjD,kEAA+C,CAAA;IAC/C,sDAAmC,CAAA;IACnC,wDAAqC,CAAA;IACrC,8DAA2C,CAAA;IAC3C,gEAA6C,CAAA;AAC/C,CAAC,EATW,eAAe,+BAAf,eAAe,QAS1B;AAOD,MAAa,SAAS;IAGpB,YACkB,EAAU,EACV,IAAY,EACZ,IAAqB,EACrB,OAAc;QAHd,OAAE,GAAF,EAAE,CAAQ;QACV,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAiB;QACrB,YAAO,GAAP,OAAO,CAAO;QANf,WAAM,GAAW,EAAE,CAAA;IAOjC,CAAC;IAEJ,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,QAAQ,CAAE,IAAY;QACpB,MAAM,IAAI,GAAS,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAA;QAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,UAAU;QACR,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO,IAAI,CAAA;QAClF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,CAAA;IACnD,CAAC;IAED,QAAQ;QACN,OAAO,YAAY,IAAI,CAAC,EAAE,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,IAAI,EAAE,CAAA;IACpE,CAAC;CACF;AA5BD,8BA4BC;AAMD,MAAa,mBAAmB;IAY9B,YAAa,WAA2B,EAAE,UAAsC,EAAE;;QAVjE,UAAK,GAAG,IAAI,GAAG,EAAqB,CAAA;QACpC,kBAAa,GAAG,IAAI,GAAG,EAA6B,CAAA;QACpD,UAAK,GAAgB,EAAE,CAAA;QAChC,WAAM,GAAG,CAAC,CAAA;QACV,WAAM,GAAqB,IAAI,CAAA;QAC/B,YAAO,GAAqB,IAAI,CAAA;QAEjC,cAAS,GAA+B,IAAI,CAAA;QAIjD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,qBAAqB,GAAG,MAAA,OAAO,CAAC,qBAAqB,mCAAI,IAAI,CAAA;IACpE,CAAC;IAMD,SAAS,CAAE,GAAW;QACpB,MAAM,GAAG,GAAG,iCAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACrC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;IAKD,aAAa,CAAE,GAAc;QAC3B,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,GAAG,IAAI,0CAAmB,EAAE,CAAA;YAC1C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAA;QAChC,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACtB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QACtB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QAEvB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAA;YAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;QASD,IAAI,4BAAY,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAE5C,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAIO,QAAQ,CAAE,IAAY,EAAE,OAAc,EAAE,IAAqB;QACnE,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QAC9D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrB,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,iBAAiB,CAAE,IAAY,EAAE,QAAmB,EAAE,OAAc,EAAE,IAAqB;QACjG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;QACnD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QAC9B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAChC,CAAC;IAIO,YAAY,CAAE,GAAc;;QAClC,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QAC7D,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QACzE,MAAM,WAAW,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;YACpD,CAAC,CAAC,OAAO,KAAK,IAAI,KAAK,EAAE;YACzB,CAAC,CAAC,OAAO,KAAK,IAAI,KAAK,KAAK,WAAW,EAAE,CAAA;QAC3C,MAAM,QAAQ,GAAG,0BAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAEjD,IAAI,QAAQ,KAAK,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,yCAAyC,WAAW,4CAA4C,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;QAC7I,CAAC;IACH,CAAC;IAEO,WAAW,CAAE,GAAc;QACjC,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QAChD,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,KAAK,MAAM,YAAY,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAA;QAChH,CAAC;IACH,CAAC;IAEO,eAAe,CAAE,GAAc;QACrC,MAAM,cAAc,GAAG,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;QACxD,IAAI,CAAC,cAAc;YAAE,OAAM;QAC3B,KAAK,MAAM,gBAAgB,IAAI,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAA;QACtH,CAAC;IACH,CAAC;IAEO,WAAW,CAAE,GAAc;QACjC,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QAC5C,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;QACrE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAA;IAC5F,CAAC;IAEO,YAAY,CAAE,GAAc;QAClC,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QACvE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAA;IAC/F,CAAC;IAEO,aAAa,CAAE,GAAc;QACnC,MAAM,YAAY,GAAG,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;QACpD,IAAI,CAAC,YAAY;YAAE,OAAM;QACzB,KAAK,MAAM,cAAc,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;YACnD,IAAI,CAAC,OAAO;gBAAE,SAAQ;YACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,CAAC,iBAAiB,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC;IAIO,IAAI,CAAE,IAAe;QAC3B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC;gBAC3C,MAAM,EAAE,GAAG,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACrD,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAA;gBACtC,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;gBAC5B,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACzC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;gBAC9B,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC;gBAC5C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAA;gBACjC,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC;gBAC3C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;gBAChC,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC;gBACrC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;gBAC1B,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,oBAAoB,CAAC,CAAC,CAAC;gBAC1C,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;gBAC/B,MAAK;YACP,CAAC;YACD,KAAK,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAEtC,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAIO,sBAAsB,CAAE,IAAe;QAC7C,IAAI,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1D,IAAI,UAAU;YAAE,OAAO,UAAU,CAAA;QACjC,UAAU,GAAG,IAAI,qDAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAChF,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;QACjD,OAAO,UAAU,CAAA;IACnB,CAAC;IAEO,oBAAoB,CAAE,IAAe;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAA;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,+DAA+D,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QACpH,CAAC;QACD,MAAM,kBAAkB,GAAG,IAAI,mDAAuB,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;QAC9G,IAAI,2CAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QAC1D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAC/C,CAAC;IAEO,iBAAiB,CAAE,IAAe;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAA;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;QAErD,MAAM,EAAE,GAAG,mBAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvD,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QAGnC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;QACzG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACpB,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAC7G,CAAC;IAEO,mBAAmB,CAAE,IAAe;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAA;QACpD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;QAC3C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IAEO,eAAe,CAAE,IAAe;;QACtC,MAAM,IAAI,GAAG,MAAA,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,0CAAE,IAAI,CAAA;QAChC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,iDAAiD,CAAC,CAAA;QAChF,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,4CAA4C,CAAC,CAAA;QAC3E,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IAEO,qBAAqB,CAAE,IAAe;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,wDAAwD,CAAC,CAAA;QACvF,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,2CAA2C,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QAChG,CAAC;QACD,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjE,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,uEAAuE,CAAC,CAAA;QACtG,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,MAAM,UAAU,GAAG,IAAI,6CAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAA;QACvF,MAAM,cAAc,GAAG,IAAI,2CAAmB,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;QACtG,IAAI,2CAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACtD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,eAAe,CAAC,CAAA;IACnF,CAAC;IAEO,sBAAsB,CAAE,IAAe;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,yDAAyD,CAAC,CAAA;QACxF,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,6CAA6C,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QAClG,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjD,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,sCAAsC,CAAC,CAAA;QACxE,CAAC;QACD,MAAM,oBAAoB,GAAG,IAAI,6CAAoB,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAA;QAC5G,IAAI,2CAAmB,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;IAC9D,CAAC;IAQO,SAAS,CAAE,IAAe;QAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC5C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;oBAC7B,MAAK;gBACP,CAAC;gBACD,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;oBAC7B,MAAK;gBACP,CAAC;gBACD,KAAK,WAAW,CAAC,CAAC,CAAC;oBACjB,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;oBACjC,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,WAAW,CAAE,IAAe,EAAE,OAAc;QAClD,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAA;IACtH,CAAC;IAEO,WAAW,CAAE,IAAe,EAAE,OAAc;QAClD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,qBAAqB,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAA;IAC7G,CAAC;IAEO,eAAe,CAAE,IAAe,EAAE,OAAc;QACtD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,mBAAmB,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAC/G,CAAC;IAEO,cAAc,CACpB,IAAe,EACf,OAAc,EACd,aAA8B,EAC9B,cAA+B;QAE/B,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;QACtD,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAA;QACrE,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;IAC1D,CAAC;IAQD,MAAM,CAAC,QAAQ,CAAE,OAAc;;QAC7B,IAAI,IAAI,GAAG,MAAA,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,mCAAI,EAAE,CAAA;QAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YACxD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAA;QACnB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,QAAQ,CAAE,OAAc;;QAC7B,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5D,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAA;QACzD,MAAM,IAAI,GAAG,MAAA,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,mCAAI,QAAQ,CAAA;QAElD,MAAM,EAAE,GAAG,IAAI,+CAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAErF,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;YACvC,MAAM,WAAW,GAAG,MAAA,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,mCAAI,EAAE,CAAA;YACxD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;gBACpB,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;YAC/C,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,UAAU,CAAE,OAAc;;QAC/B,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,mCAAI,EAAE,CAAA;QAChD,MAAM,OAAO,GAAG,MAAA,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,mCAAI,EAAE,CAAA;QAClD,OAAO,IAAI,sCAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IACjE,CAAC;IAKD,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,UAAsC,EAAE;;QAEjE,MAAM,GAAG,GAAG,iCAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QAC7D,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAA,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,mCAAI,GAAG,EAAE,EAAE,CAAC,CAAA;QACzE,MAAM,WAAW,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,WAAW,KAAK,CAAC,CAAC;YACpD,CAAC,CAAC,OAAO,KAAK,IAAI,KAAK,EAAE;YACzB,CAAC,CAAC,OAAO,KAAK,IAAI,KAAK,KAAK,WAAW,EAAE,CAAA;QAC3C,MAAM,WAAW,GAAG,IAAI,gCAAc,CAAC,2CAAmB,CAAC,QAAQ,EAAE,0BAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;QACtG,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QAC5D,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;CACF;AApXD,kDAoXC","sourcesContent":["/**\n * Graph-based QuickFix XML dictionary parser.\n *\n * Verbatim port of C# QuickFixXmlFileParser. Uses XDocument tree (from SaxTreeBuilder)\n * for random-access XML traversal and a Node/Edge/work-queue pattern for forward\n * reference resolution. Replaces the iterative N-pass SAX-streaming approach.\n *\n * Pre-parse validation via DictionaryValidator catches missing fields, duplicates,\n * and undefined references with \"did you mean\" suggestions before parsing begins.\n */\nimport { XDocument, XNode } from './x-element'\nimport { SaxTreeBuilder } from './sax-tree-builder'\nimport { DictionaryValidator } from './dictionary-validator'\nimport { FixDefinitions } from '../../definition/fix-definitions'\nimport { SimpleFieldDefinition } from '../../definition/simple-field-definition'\nimport { ComponentFieldDefinition } from '../../definition/component-field-definition'\nimport { GroupFieldDefinition } from '../../definition/group-field-definition'\nimport { MessageDefinition } from '../../definition/message-definition'\nimport { ContainedFieldSet } from '../../contained/contained-field-set'\nimport { ContainedSimpleField } from '../../contained/contained-simple-field'\nimport { ContainedComponentField } from '../../contained/contained-component-field'\nimport { ContainedGroupField } from '../../contained/contained-group-field'\nimport { ContainedSetBuilder } from '../../contained/contained-set-builder'\nimport { FixDefinitionSource } from '../../fix-definition-source'\nimport { VersionUtil } from '../../version-util'\nimport { IndexVisitor } from './index-visitor'\n\nexport enum NodeElementType {\n MessageDefinition = 'MessageDefinition',\n SimpleFieldDefinition = 'SimpleFieldDefinition',\n SimpleFieldDeclaration = 'SimpleFieldDeclaration',\n InlineGroupDefinition = 'InlineGroupDefinition',\n GroupDefinition = 'GroupDefinition',\n GroupDeclaration = 'GroupDeclaration',\n ComponentDefinition = 'ComponentDefinition',\n ComponentDeclaration = 'ComponentDeclaration'\n}\n\nexport interface Edge {\n readonly head: number\n readonly tail: number\n}\n\nexport class GraphNode {\n private readonly _edges: Edge[] = []\n\n constructor (\n public readonly id: number,\n public readonly name: string,\n public readonly type: NodeElementType,\n public readonly element: XNode\n ) {}\n\n get edges (): ReadonlyArray<Edge> {\n return this._edges\n }\n\n makeEdge (tail: number): Edge {\n const edge: Edge = { head: this.id, tail }\n this._edges.push(edge)\n return edge\n }\n\n isRequired (): boolean {\n if (this.name === 'StandardHeader' || this.name === 'StandardTrailer') return true\n return this.element.attribute('required') === 'Y'\n }\n\n toString (): string {\n return `Node: id=${this.id}, name=${this.name}, type=${this.type}`\n }\n}\n\nexport interface QuickFixGraphParserOptions {\n validateBeforeParsing?: boolean\n}\n\nexport class QuickFixGraphParser {\n private readonly definitions: FixDefinitions\n private readonly nodes = new Map<number, GraphNode>()\n private readonly containedSets = new Map<number, ContainedFieldSet>()\n private readonly queue: GraphNode[] = []\n private nextId = 0\n private header: GraphNode | null = null\n private trailer: GraphNode | null = null\n\n public validator: DictionaryValidator | null = null\n public readonly validateBeforeParsing: boolean\n\n constructor (definitions: FixDefinitions, options: QuickFixGraphParserOptions = {}) {\n this.definitions = definitions\n this.validateBeforeParsing = options.validateBeforeParsing ?? true\n }\n\n /**\n * Parse XML text into the FixDefinitions provided at construction.\n * Throws DictionaryValidationException if validation is enabled and errors are found.\n */\n parseText (xml: string): FixDefinitions {\n const doc = SaxTreeBuilder.parse(xml)\n return this.parseDocument(doc)\n }\n\n /**\n * Parse a pre-built XDocument tree.\n */\n parseDocument (doc: XDocument): FixDefinitions {\n if (this.validateBeforeParsing) {\n this.validator = new DictionaryValidator()\n this.validator.validate(doc)\n this.validator.throwIfErrors()\n }\n\n this.parseVersion(doc)\n this.parseFields(doc)\n this.parseComponents(doc)\n this.parseHeader(doc)\n this.parseTrailer(doc)\n this.parseMessages(doc)\n\n while (this.queue.length > 0) {\n const node = this.queue.shift()!\n this.work(node)\n }\n\n /*\n * At this point all fields on all sets are placed, however the parent (e.g. an\n * Instrument component) is not aware of the tags contained in nested groups/components\n * that were resolved AFTER it. The IndexVisitor walks every message and re-indexes\n * its tree post-order so each set knows all tags below it — essential for the segment\n * parser to work.\n */\n new IndexVisitor().compute(this.definitions)\n\n return this.definitions\n }\n\n // ── Graph construction ──\n\n private makeNode (name: string, element: XNode, type: NodeElementType): GraphNode {\n const node = new GraphNode(this.nextId++, name, type, element)\n this.nodes.set(node.id, node)\n this.queue.push(node)\n return node\n }\n\n private constructTailNode (name: string, headNode: GraphNode, element: XNode, type: NodeElementType): void {\n const tailNode = this.makeNode(name, element, type)\n headNode.makeEdge(tailNode.id)\n tailNode.makeEdge(headNode.id)\n }\n\n // ── Parsing entry points ──\n\n private parseVersion (doc: XDocument): void {\n const version = doc.firstDescendant('fix')\n if (!version) throw new Error('no <fix> root element')\n const major = parseInt(version.attribute('major') ?? '0', 10)\n const minor = parseInt(version.attribute('minor') ?? '0', 10)\n const servicepack = parseInt(version.attribute('servicepack') ?? '0', 10)\n const description = (major !== 5 || servicepack === 0)\n ? `FIX.${major}.${minor}`\n : `FIX.${major}.${minor}SP${servicepack}`\n const resolved = VersionUtil.resolve(description)\n // FixDefinitions doesn't have a setVersion — version is set at construction\n if (resolved !== this.definitions.version) {\n throw new Error(`version mismatch: dictionary declares ${description} but FixDefinitions was constructed with ${this.definitions.version}`)\n }\n }\n\n private parseFields (doc: XDocument): void {\n const fieldsNode = doc.firstDescendant('fields')\n if (!fieldsNode) return\n for (const fieldElement of fieldsNode.elements('field')) {\n this.makeNode(QuickFixGraphParser.nameFrom(fieldElement), fieldElement, NodeElementType.SimpleFieldDefinition)\n }\n }\n\n private parseComponents (doc: XDocument): void {\n const componentsNode = doc.firstDescendant('components')\n if (!componentsNode) return\n for (const componentElement of componentsNode.elements('component')) {\n this.makeNode(QuickFixGraphParser.nameFrom(componentElement), componentElement, NodeElementType.ComponentDefinition)\n }\n }\n\n private parseHeader (doc: XDocument): void {\n const header = doc.firstDescendant('header')\n if (!header) throw new Error('no header declared in fix definitions')\n this.header = this.makeNode('StandardHeader', header, NodeElementType.ComponentDefinition)\n }\n\n private parseTrailer (doc: XDocument): void {\n const trailer = doc.firstDescendant('trailer')\n if (!trailer) throw new Error('no trailer declared in fix definitions')\n this.trailer = this.makeNode('StandardTrailer', trailer, NodeElementType.ComponentDefinition)\n }\n\n private parseMessages (doc: XDocument): void {\n const messagesNode = doc.firstDescendant('messages')\n if (!messagesNode) return\n for (const messageElement of messagesNode.elements('message')) {\n const msgType = messageElement.attribute('msgtype')\n if (!msgType) continue\n this.makeNode(msgType, messageElement, NodeElementType.MessageDefinition)\n }\n }\n\n // ── Work queue dispatch ──\n\n private work (node: GraphNode): void {\n switch (node.type) {\n case NodeElementType.SimpleFieldDefinition: {\n const sd = QuickFixGraphParser.getField(node.element)\n this.definitions.addSimpleFieldDef(sd)\n break\n }\n case NodeElementType.MessageDefinition: {\n this.messageDefinition(node)\n break\n }\n case NodeElementType.ComponentDefinition: {\n this.componentDefinition(node)\n break\n }\n case NodeElementType.SimpleFieldDeclaration: {\n this.simpleFieldDeclaration(node)\n break\n }\n case NodeElementType.InlineGroupDefinition: {\n this.inlineGroupDefinition(node)\n break\n }\n case NodeElementType.GroupDefinition: {\n this.groupDefinition(node)\n break\n }\n case NodeElementType.ComponentDeclaration: {\n this.componentDeclaration(node)\n break\n }\n case NodeElementType.GroupDeclaration: {\n // QuickFix XML never has standalone group declarations — groups are always inline\n break\n }\n }\n }\n\n // ── Definition handlers ──\n\n private getComponentDefinition (node: GraphNode): ComponentFieldDefinition {\n let definition = this.definitions.component.get(node.name)\n if (definition) return definition\n definition = new ComponentFieldDefinition(node.name, node.name, null, node.name)\n this.definitions.addComponentFieldDef(definition)\n return definition\n }\n\n private componentDeclaration (node: GraphNode): void {\n const definition = this.getComponentDefinition(node)\n const edge = node.edges[0]\n const parentSet = this.containedSets.get(edge.tail)\n if (!parentSet) {\n throw new Error(`edge tail ${edge.tail} has no contained set on which to place declared component '${node.name}'`)\n }\n const containedComponent = new ContainedComponentField(definition, parentSet.fields.length, node.isRequired())\n new ContainedSetBuilder(parentSet).add(containedComponent)\n this.containedSets.set(edge.head, definition)\n }\n\n private messageDefinition (node: GraphNode): void {\n if (!this.header) throw new Error('header not set')\n if (!this.trailer) throw new Error('trailer not set')\n\n const md = QuickFixGraphParser.getMessage(node.element)\n this.definitions.addMessage(md)\n this.containedSets.set(node.id, md)\n\n // wrap the message body in StandardHeader + content + StandardTrailer\n this.constructTailNode('StandardHeader', node, this.header.element, NodeElementType.ComponentDeclaration)\n this.expandSet(node)\n this.constructTailNode('StandardTrailer', node, this.trailer.element, NodeElementType.ComponentDeclaration)\n }\n\n private componentDefinition (node: GraphNode): void {\n const definition = this.getComponentDefinition(node)\n this.containedSets.set(node.id, definition)\n this.expandSet(node)\n }\n\n private groupDefinition (node: GraphNode): void {\n const tail = node.edges[0]?.tail\n if (tail == null) {\n throw new Error(`node ${node} has no edges to find tail for group definition`)\n }\n const definition = this.containedSets.get(tail)\n if (!definition) {\n throw new Error(`node ${node} has no contained set for group definition`)\n }\n this.containedSets.set(node.edges[0].head, definition)\n this.expandSet(node)\n }\n\n private inlineGroupDefinition (node: GraphNode): void {\n const edge = node.edges[0]\n if (!edge) {\n throw new Error(`node ${node} has no edges to find tail for inline group definition`)\n }\n const parentSet = this.containedSets.get(edge.tail)\n if (!parentSet) {\n throw new Error(`edge tail ${edge.tail} has no contained set for inline group '${node.name}'`)\n }\n const noOFieldDefinition = this.definitions.simple.get(node.name)\n if (!noOFieldDefinition) {\n throw new Error(`${node.name} does not exist in simple field definitions to construct inline group`)\n }\n const name = node.name\n const definition = new GroupFieldDefinition(name, name, null, noOFieldDefinition, name)\n const containedGroup = new ContainedGroupField(definition, parentSet.fields.length, node.isRequired())\n new ContainedSetBuilder(parentSet).add(containedGroup)\n this.containedSets.set(edge.head, definition)\n this.constructTailNode(name, node, node.element, NodeElementType.GroupDefinition)\n }\n\n private simpleFieldDeclaration (node: GraphNode): void {\n const edge = node.edges[0]\n if (!edge) {\n throw new Error(`node ${node} has no edges to find tail for simple field declaration`)\n }\n const parentSet = this.containedSets.get(edge.tail)\n if (!parentSet) {\n throw new Error(`edge tail ${edge.tail} has no contained set for declared field '${node.name}'`)\n }\n const sd = this.definitions.simple.get(node.name)\n if (!sd) {\n throw new Error(`element ${node} cannot be located as a simple field`)\n }\n const containedSimpleField = new ContainedSimpleField(sd, parentSet.fields.length, node.isRequired(), false)\n new ContainedSetBuilder(parentSet).add(containedSimpleField)\n }\n\n // ── Set expansion ──\n\n /**\n * Walks the children of a definition node and constructs tail nodes for each\n * field/group/component reference, queuing them for resolution.\n */\n private expandSet (node: GraphNode): void {\n for (const child of node.element.elements()) {\n switch (child.name) {\n case 'field': {\n this.expandField(node, child)\n break\n }\n case 'group': {\n this.expandGroup(node, child)\n break\n }\n case 'component': {\n this.expandComponent(node, child)\n break\n }\n }\n }\n }\n\n private expandField (node: GraphNode, element: XNode): void {\n this.constructTailNode(QuickFixGraphParser.nameFrom(element), node, element, NodeElementType.SimpleFieldDeclaration)\n }\n\n private expandGroup (node: GraphNode, element: XNode): void {\n this.expandSetChild(node, element, NodeElementType.InlineGroupDefinition, NodeElementType.GroupDeclaration)\n }\n\n private expandComponent (node: GraphNode, element: XNode): void {\n this.expandSetChild(node, element, NodeElementType.ComponentDefinition, NodeElementType.ComponentDeclaration)\n }\n\n private expandSetChild (\n node: GraphNode,\n element: XNode,\n defineElement: NodeElementType,\n declareElement: NodeElementType\n ): void {\n const name = QuickFixGraphParser.nameFrom(element)\n const hasInlinedFields = element.elements().length > 0\n const elementType = hasInlinedFields ? defineElement : declareElement\n this.constructTailNode(name, node, element, elementType)\n }\n\n // ── Static helpers ──\n\n /**\n * Extract a name from an element's attributes, with the same conventions as the C# parser:\n * strip spaces, prefix with 'F' if the name starts with a digit.\n */\n static nameFrom (element: XNode): string {\n let name = element.attribute('name') ?? ''\n name = name.replace(/ /g, '')\n if (name.length > 0 && name[0] >= '0' && name[0] <= '9') {\n name = `F${name}`\n }\n return name\n }\n\n static getField (element: XNode): SimpleFieldDefinition {\n const name = QuickFixGraphParser.nameFrom(element)\n const numberStr = element.attribute('number')\n const tag = numberStr != null ? parseInt(numberStr, 10) : -1\n if (tag < 0) throw new Error(`no tag/number for ${name}`)\n const type = element.attribute('type') ?? 'STRING'\n\n const sd = new SimpleFieldDefinition(String(tag), name, name, null, null, type, null)\n // Add enum values\n for (const value of element.elements('value')) {\n const enumKey = value.attribute('enum')\n const description = value.attribute('description') ?? ''\n if (enumKey != null) {\n sd.addEnum(enumKey, description, description)\n }\n }\n return sd\n }\n\n static getMessage (element: XNode): MessageDefinition {\n const name = QuickFixGraphParser.nameFrom(element)\n const msgCat = element.attribute('msgcat') ?? ''\n const msgType = element.attribute('msgtype') ?? ''\n return new MessageDefinition(name, name, msgType, msgCat, name)\n }\n\n /**\n * Convenience: parse XML text into a fresh FixDefinitions.\n */\n static parse (xml: string, options: QuickFixGraphParserOptions = {}): FixDefinitions {\n // Pre-parse the version so we can construct FixDefinitions correctly\n const doc = SaxTreeBuilder.parse(xml)\n const fixRoot = doc.firstDescendant('fix')\n if (!fixRoot) throw new Error('no <fix> root element')\n const major = parseInt(fixRoot.attribute('major') ?? '0', 10)\n const minor = parseInt(fixRoot.attribute('minor') ?? '0', 10)\n const servicepack = parseInt(fixRoot.attribute('servicepack') ?? '0', 10)\n const description = (major !== 5 || servicepack === 0)\n ? `FIX.${major}.${minor}`\n : `FIX.${major}.${minor}SP${servicepack}`\n const definitions = new FixDefinitions(FixDefinitionSource.QuickFix, VersionUtil.resolve(description))\n const parser = new QuickFixGraphParser(definitions, options)\n return parser.parseDocument(doc)\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { XDocument } from './x-element';
2
+ export declare class SaxTreeBuilder {
3
+ static parse(xml: string): XDocument;
4
+ static parseStream(readable: NodeJS.ReadableStream): Promise<XDocument>;
5
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SaxTreeBuilder = void 0;
13
+ const x_element_1 = require("./x-element");
14
+ class SaxTreeBuilder {
15
+ static parse(xml) {
16
+ const sax = require('sax');
17
+ const parser = sax.parser(true, {});
18
+ const stack = [];
19
+ let root = null;
20
+ let lastWasSelfClosing = false;
21
+ parser.onopentag = (node) => {
22
+ const element = {
23
+ name: node.name,
24
+ attributes: Object.assign({}, node.attributes),
25
+ children: [],
26
+ line: parser.line + 1
27
+ };
28
+ if (stack.length > 0) {
29
+ stack[stack.length - 1].children.push(element);
30
+ }
31
+ lastWasSelfClosing = node.isSelfClosing;
32
+ if (!node.isSelfClosing) {
33
+ stack.push(element);
34
+ }
35
+ if (!root)
36
+ root = element;
37
+ };
38
+ parser.onclosetag = () => {
39
+ if (lastWasSelfClosing) {
40
+ lastWasSelfClosing = false;
41
+ return;
42
+ }
43
+ stack.pop();
44
+ };
45
+ parser.onerror = (err) => {
46
+ throw new Error(`XML parse error at line ${parser.line + 1}: ${err.message}`);
47
+ };
48
+ parser.write(xml).close();
49
+ if (!root) {
50
+ throw new Error('empty XML document');
51
+ }
52
+ return new x_element_1.XDocument(root);
53
+ }
54
+ static parseStream(readable) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ return yield new Promise((resolve, reject) => {
57
+ const sax = require('sax');
58
+ const saxStream = sax.createStream(true, {});
59
+ const stack = [];
60
+ let root = null;
61
+ let lastWasSelfClosing = false;
62
+ saxStream.on('opentag', (node) => {
63
+ const element = {
64
+ name: node.name,
65
+ attributes: Object.assign({}, node.attributes),
66
+ children: [],
67
+ line: saxStream._parser.line + 1
68
+ };
69
+ if (stack.length > 0) {
70
+ stack[stack.length - 1].children.push(element);
71
+ }
72
+ lastWasSelfClosing = node.isSelfClosing;
73
+ if (!node.isSelfClosing) {
74
+ stack.push(element);
75
+ }
76
+ if (!root)
77
+ root = element;
78
+ });
79
+ saxStream.on('closetag', () => {
80
+ if (lastWasSelfClosing) {
81
+ lastWasSelfClosing = false;
82
+ return;
83
+ }
84
+ stack.pop();
85
+ });
86
+ saxStream.on('error', (err) => {
87
+ reject(new Error(`XML parse error: ${err.message}`));
88
+ });
89
+ saxStream.on('end', () => {
90
+ if (!root) {
91
+ reject(new Error('empty XML document'));
92
+ }
93
+ else {
94
+ resolve(new x_element_1.XDocument(root));
95
+ }
96
+ });
97
+ readable.pipe(saxStream);
98
+ });
99
+ });
100
+ }
101
+ }
102
+ exports.SaxTreeBuilder = SaxTreeBuilder;
103
+ //# sourceMappingURL=sax-tree-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sax-tree-builder.js","sourceRoot":"","sources":["../../../../src/dictionary/parser/quickfix/sax-tree-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { XDocument, XElement } from './x-element'\n\n/**\n * Builds an in-memory XElement tree from XML using a single SAX pass.\n * After construction, the tree provides DOM-like random access for\n * graph-based parsing and validation.\n */\nexport class SaxTreeBuilder {\n /**\n * Parse XML text into an XDocument.\n */\n static parse (xml: string): XDocument {\n const sax = require('sax')\n const parser = sax.parser(true, {})\n const stack: XElement[] = []\n let root: XElement | null = null\n let lastWasSelfClosing = false\n\n parser.onopentag = (node: { name: string, attributes: Record<string, string>, isSelfClosing: boolean }) => {\n const element: XElement = {\n name: node.name,\n attributes: { ...node.attributes },\n children: [],\n line: parser.line + 1\n }\n\n if (stack.length > 0) {\n stack[stack.length - 1].children.push(element)\n }\n\n lastWasSelfClosing = node.isSelfClosing\n if (!node.isSelfClosing) {\n stack.push(element)\n }\n if (!root) root = element\n }\n\n parser.onclosetag = () => {\n if (lastWasSelfClosing) {\n lastWasSelfClosing = false\n return\n }\n stack.pop()\n }\n\n parser.onerror = (err: Error) => {\n throw new Error(`XML parse error at line ${parser.line + 1}: ${err.message}`)\n }\n\n parser.write(xml).close()\n\n if (!root) {\n throw new Error('empty XML document')\n }\n\n return new XDocument(root)\n }\n\n /**\n * Parse XML from a readable stream into an XDocument.\n */\n static async parseStream (readable: NodeJS.ReadableStream): Promise<XDocument> {\n return await new Promise<XDocument>((resolve, reject) => {\n const sax = require('sax')\n const saxStream = sax.createStream(true, {})\n const stack: XElement[] = []\n let root: XElement | null = null\n let lastWasSelfClosing = false\n\n saxStream.on('opentag', (node: { name: string, attributes: Record<string, string>, isSelfClosing: boolean }) => {\n const element: XElement = {\n name: node.name,\n attributes: { ...node.attributes },\n children: [],\n line: saxStream._parser.line + 1\n }\n\n if (stack.length > 0) {\n stack[stack.length - 1].children.push(element)\n }\n\n lastWasSelfClosing = node.isSelfClosing\n if (!node.isSelfClosing) {\n stack.push(element)\n }\n if (!root) root = element\n })\n\n saxStream.on('closetag', () => {\n if (lastWasSelfClosing) {\n lastWasSelfClosing = false\n return\n }\n stack.pop()\n })\n\n saxStream.on('error', (err: Error) => {\n reject(new Error(`XML parse error: ${err.message}`))\n })\n\n saxStream.on('end', () => {\n if (!root) {\n reject(new Error('empty XML document'))\n } else {\n resolve(new XDocument(root))\n }\n })\n\n readable.pipe(saxStream)\n })\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ export declare enum ValidationSeverity {
2
+ Warning = "Warning",
3
+ Error = "Error"
4
+ }
5
+ export interface ValidationError {
6
+ readonly severity: ValidationSeverity;
7
+ readonly code: string;
8
+ readonly message: string;
9
+ readonly elementName?: string;
10
+ readonly elementType?: string;
11
+ readonly lineNumber?: number;
12
+ readonly suggestion?: string;
13
+ }
14
+ export declare class DictionaryValidationException extends Error {
15
+ readonly errors: ReadonlyArray<ValidationError>;
16
+ constructor(errors: ReadonlyArray<ValidationError>);
17
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DictionaryValidationException = exports.ValidationSeverity = void 0;
4
+ var ValidationSeverity;
5
+ (function (ValidationSeverity) {
6
+ ValidationSeverity["Warning"] = "Warning";
7
+ ValidationSeverity["Error"] = "Error";
8
+ })(ValidationSeverity || (exports.ValidationSeverity = ValidationSeverity = {}));
9
+ class DictionaryValidationException extends Error {
10
+ constructor(errors) {
11
+ const errorCount = errors.filter(e => e.severity === ValidationSeverity.Error).length;
12
+ const warningCount = errors.filter(e => e.severity === ValidationSeverity.Warning).length;
13
+ const header = `FIX dictionary validation failed with ${errorCount} error(s) and ${warningCount} warning(s):`;
14
+ const details = errors
15
+ .filter(e => e.severity === ValidationSeverity.Error)
16
+ .slice(0, 20)
17
+ .map(e => {
18
+ let line = ` [${e.code}] ${e.message}`;
19
+ if (e.lineNumber != null)
20
+ line += ` (line ${e.lineNumber})`;
21
+ if (e.suggestion)
22
+ line += ` — ${e.suggestion}`;
23
+ return line;
24
+ })
25
+ .join('\n');
26
+ super(`${header}\n${details}`);
27
+ this.errors = errors;
28
+ this.name = 'DictionaryValidationException';
29
+ }
30
+ }
31
+ exports.DictionaryValidationException = DictionaryValidationException;
32
+ //# sourceMappingURL=validation-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-error.js","sourceRoot":"","sources":["../../../../src/dictionary/parser/quickfix/validation-error.ts"],"names":[],"mappings":";;;AAAA,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,qCAAe,CAAA;AACjB,CAAC,EAHW,kBAAkB,kCAAlB,kBAAkB,QAG7B;AAYD,MAAa,6BAA8B,SAAQ,KAAK;IACtD,YAA6B,MAAsC;QACjE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,kBAAkB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;QACrF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,kBAAkB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAA;QACzF,MAAM,MAAM,GAAG,yCAAyC,UAAU,iBAAiB,YAAY,cAAc,CAAA;QAC7G,MAAM,OAAO,GAAG,MAAM;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,kBAAkB,CAAC,KAAK,CAAC;aACpD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;aACZ,GAAG,CAAC,CAAC,CAAC,EAAE;YACP,IAAI,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAA;YACvC,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI;gBAAE,IAAI,IAAI,UAAU,CAAC,CAAC,UAAU,GAAG,CAAA;YAC3D,IAAI,CAAC,CAAC,UAAU;gBAAE,IAAI,IAAI,MAAM,CAAC,CAAC,UAAU,EAAE,CAAA;YAC9C,OAAO,IAAI,CAAA;QACb,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAA;QACb,KAAK,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAA;QAdH,WAAM,GAAN,MAAM,CAAgC;QAejE,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;IAC7C,CAAC;CACF;AAlBD,sEAkBC","sourcesContent":["export enum ValidationSeverity {\n Warning = 'Warning',\n Error = 'Error'\n}\n\nexport interface ValidationError {\n readonly severity: ValidationSeverity\n readonly code: string\n readonly message: string\n readonly elementName?: string\n readonly elementType?: string\n readonly lineNumber?: number\n readonly suggestion?: string\n}\n\nexport class DictionaryValidationException extends Error {\n constructor (public readonly errors: ReadonlyArray<ValidationError>) {\n const errorCount = errors.filter(e => e.severity === ValidationSeverity.Error).length\n const warningCount = errors.filter(e => e.severity === ValidationSeverity.Warning).length\n const header = `FIX dictionary validation failed with ${errorCount} error(s) and ${warningCount} warning(s):`\n const details = errors\n .filter(e => e.severity === ValidationSeverity.Error)\n .slice(0, 20)\n .map(e => {\n let line = ` [${e.code}] ${e.message}`\n if (e.lineNumber != null) line += ` (line ${e.lineNumber})`\n if (e.suggestion) line += ` — ${e.suggestion}`\n return line\n })\n .join('\\n')\n super(`${header}\\n${details}`)\n this.name = 'DictionaryValidationException'\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ export interface XElement {
2
+ readonly name: string;
3
+ readonly attributes: Record<string, string>;
4
+ readonly children: XElement[];
5
+ readonly line?: number;
6
+ }
7
+ export declare class XNode {
8
+ readonly element: XElement;
9
+ constructor(element: XElement);
10
+ attribute(name: string): string | undefined;
11
+ elements(name?: string): XNode[];
12
+ firstElement(name: string): XNode | undefined;
13
+ descendants(name: string): XNode[];
14
+ firstDescendant(name: string): XNode | undefined;
15
+ requiredAttribute(name: string): string;
16
+ get name(): string;
17
+ get line(): number | undefined;
18
+ private collectDescendants;
19
+ private findDescendant;
20
+ }
21
+ export declare class XDocument {
22
+ readonly root: XNode;
23
+ constructor(rootElement: XElement);
24
+ descendants(name: string): XNode[];
25
+ firstDescendant(name: string): XNode | undefined;
26
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XDocument = exports.XNode = void 0;
4
+ class XNode {
5
+ constructor(element) {
6
+ this.element = element;
7
+ }
8
+ attribute(name) {
9
+ return this.element.attributes[name];
10
+ }
11
+ elements(name) {
12
+ const children = name
13
+ ? this.element.children.filter(c => c.name === name)
14
+ : this.element.children;
15
+ return children.map(c => new XNode(c));
16
+ }
17
+ firstElement(name) {
18
+ const child = this.element.children.find(c => c.name === name);
19
+ return child ? new XNode(child) : undefined;
20
+ }
21
+ descendants(name) {
22
+ const result = [];
23
+ this.collectDescendants(this.element, name, result);
24
+ return result;
25
+ }
26
+ firstDescendant(name) {
27
+ return this.findDescendant(this.element, name);
28
+ }
29
+ requiredAttribute(name) {
30
+ var _a;
31
+ const val = this.element.attributes[name];
32
+ if (val === undefined) {
33
+ throw new Error(`missing required attribute '${name}' on <${this.element.name}> at line ${(_a = this.element.line) !== null && _a !== void 0 ? _a : '?'}`);
34
+ }
35
+ return val;
36
+ }
37
+ get name() {
38
+ return this.element.name;
39
+ }
40
+ get line() {
41
+ return this.element.line;
42
+ }
43
+ collectDescendants(el, name, result) {
44
+ for (const child of el.children) {
45
+ if (child.name === name) {
46
+ result.push(new XNode(child));
47
+ }
48
+ this.collectDescendants(child, name, result);
49
+ }
50
+ }
51
+ findDescendant(el, name) {
52
+ for (const child of el.children) {
53
+ if (child.name === name) {
54
+ return new XNode(child);
55
+ }
56
+ const found = this.findDescendant(child, name);
57
+ if (found)
58
+ return found;
59
+ }
60
+ return undefined;
61
+ }
62
+ }
63
+ exports.XNode = XNode;
64
+ class XDocument {
65
+ constructor(rootElement) {
66
+ this.root = new XNode(rootElement);
67
+ }
68
+ descendants(name) {
69
+ const result = [];
70
+ if (this.root.name === name)
71
+ result.push(this.root);
72
+ result.push(...this.root.descendants(name));
73
+ return result;
74
+ }
75
+ firstDescendant(name) {
76
+ if (this.root.name === name)
77
+ return this.root;
78
+ return this.root.firstDescendant(name);
79
+ }
80
+ }
81
+ exports.XDocument = XDocument;
82
+ //# sourceMappingURL=x-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-element.js","sourceRoot":"","sources":["../../../../src/dictionary/parser/quickfix/x-element.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lightweight in-memory XML element tree — provides DOM-like random access\n * over XML parsed by SAX. Mirrors the C# XDocument/XElement API surface\n * used by QuickFixXmlFileParser and DictionaryValidator.\n */\nexport interface XElement {\n readonly name: string\n readonly attributes: Record<string, string>\n readonly children: XElement[]\n readonly line?: number\n}\n\n/**\n * Query helper wrapping an XElement tree with C#-style traversal methods.\n * Mirrors XDocument/XElement LINQ-to-XML API used in cspurefix.\n */\nexport class XNode {\n constructor (public readonly element: XElement) {}\n\n /** Attribute value by name, or undefined if not present. */\n attribute (name: string): string | undefined {\n return this.element.attributes[name]\n }\n\n /** Direct children with the given tag name. */\n elements (name?: string): XNode[] {\n const children = name\n ? this.element.children.filter(c => c.name === name)\n : this.element.children\n return children.map(c => new XNode(c))\n }\n\n /** First direct child with the given tag name, or undefined. */\n firstElement (name: string): XNode | undefined {\n const child = this.element.children.find(c => c.name === name)\n return child ? new XNode(child) : undefined\n }\n\n /** All descendants (recursive) with the given tag name. */\n descendants (name: string): XNode[] {\n const result: XNode[] = []\n this.collectDescendants(this.element, name, result)\n return result\n }\n\n /** First descendant with the given tag name, or undefined. */\n firstDescendant (name: string): XNode | undefined {\n return this.findDescendant(this.element, name)\n }\n\n /** Shorthand: attribute value, throwing if missing. */\n requiredAttribute (name: string): string {\n const val = this.element.attributes[name]\n if (val === undefined) {\n throw new Error(`missing required attribute '${name}' on <${this.element.name}> at line ${this.element.line ?? '?'}`)\n }\n return val\n }\n\n /** The element's tag name. */\n get name (): string {\n return this.element.name\n }\n\n /** The element's source line number, if available. */\n get line (): number | undefined {\n return this.element.line\n }\n\n private collectDescendants (el: XElement, name: string, result: XNode[]): void {\n for (const child of el.children) {\n if (child.name === name) {\n result.push(new XNode(child))\n }\n this.collectDescendants(child, name, result)\n }\n }\n\n private findDescendant (el: XElement, name: string): XNode | undefined {\n for (const child of el.children) {\n if (child.name === name) {\n return new XNode(child)\n }\n const found = this.findDescendant(child, name)\n if (found) return found\n }\n return undefined\n }\n}\n\n/**\n * Parsed XML document — wraps the root element with query methods.\n * Equivalent to C# XDocument.\n */\nexport class XDocument {\n public readonly root: XNode\n\n constructor (rootElement: XElement) {\n this.root = new XNode(rootElement)\n }\n\n /** All descendants of the root with the given tag name (including the root itself if it matches). */\n descendants (name: string): XNode[] {\n const result: XNode[] = []\n if (this.root.name === name) result.push(this.root)\n result.push(...this.root.descendants(name))\n return result\n }\n\n /** First descendant of the root with the given tag name (including the root itself if it matches). */\n firstDescendant (name: string): XNode | undefined {\n if (this.root.name === name) return this.root\n return this.root.firstDescendant(name)\n }\n}\n"]}
@@ -22,6 +22,12 @@ class FixMsgAsciiStoreResend {
22
22
  }
23
23
  getResendRequest(startSeq, endSeq) {
24
24
  return __awaiter(this, void 0, void 0, function* () {
25
+ var _a;
26
+ if (((_a = this.config.description.store) === null || _a === void 0 ? void 0 : _a.resendGapFillOnly) === true) {
27
+ const gapFillOnly = [];
28
+ this.gap(startSeq, endSeq + 1, gapFillOnly);
29
+ return gapFillOnly;
30
+ }
25
31
  return yield new Promise((resolve, reject) => {
26
32
  this.store.getSeqNumRange(startSeq, endSeq).then(res => {
27
33
  resolve(this.inflateRange(startSeq, endSeq, res));
@@ -1 +1 @@
1
- {"version":3,"file":"fix-msg-ascii-store-resend.js","sourceRoot":"","sources":["../../src/store/fix-msg-ascii-store-resend.ts"],"names":[],"mappings":"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","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\nimport { FixMsgStoreRecord, IFixMsgStoreRecord } from './fix-msg-store-record'\nimport { IJsFixConfig } from '../config'\nimport { MsgType } from '../types'\nimport { ElasticBuffer, MsgView } from '../buffer'\nimport { AsciiParser } from '../buffer/ascii'\nimport { ISequenceReset, IStandardHeader } from '../types/FIX4.4/repo'\n\nexport class FixMsgAsciiStoreResend {\n parser: AsciiParser\n constructor (public readonly store: IFixMsgStore, public readonly config: IJsFixConfig) {\n this.parser = new AsciiParser(this.config, null, new ElasticBuffer(160 * 1024))\n }\n\n public async getResendRequest (startSeq: number, endSeq: number): Promise<IFixMsgStoreRecord[]> {\n // need to cover request from start to end where any missing numbers are\n // included as gaps to allow vector of messages to be sent by the session\n // on a request\n\n return await new Promise((resolve, reject) => {\n this.store.getSeqNumRange(startSeq, endSeq).then(res => {\n resolve(this.inflateRange(startSeq, endSeq, res))\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {\n const toResend: IFixMsgStoreRecord[] = []\n // If no records for this given sequence number range, returns a single gap fill\n if (input.length === 0) {\n this.gap(startSeq, endSeq + 1, toResend)\n return toResend\n }\n\n let expected = startSeq\n for (let i = 0; i < input.length; ++i) {\n const record = this.prepareRecordForRetransmission(input[i])\n const seqNum = record.seqNum\n const toGap = seqNum - expected\n if (toGap > 0) {\n this.gap(expected, seqNum, toResend)\n }\n expected = seqNum + 1\n if (record.encoded) {\n this.inflate(record)\n }\n toResend.push(record)\n }\n if (endSeq - expected > 0) {\n this.gap(expected, endSeq + 1, toResend)\n }\n return toResend\n }\n\n private gap (beginGap: number, newSeq: number, arr: IFixMsgStoreRecord[]): void {\n if (beginGap > 0) {\n arr.push(this.sequenceResetGap(beginGap, newSeq))\n }\n }\n\n // if records were sent as encoded text then inflate back to object\n // so can be resent or examined\n\n private inflate (record: IFixMsgStoreRecord): void {\n if (record.obj) return\n if (!record.encoded) return\n const parser = this.parser\n parser.on('error', (_: Error) => {\n record.obj = null\n })\n parser.on('msg', (view: MsgView) => {\n record.obj = view.toObject()\n })\n // inline parse\n parser.parseText(record.encoded)\n }\n\n /**\n * A continuous sequence of messages not being retransmitted should be skipped over using a\n * single SequenceReset(35=4) message with GapFillFlag(123) set to “Y” and MsgSeqNum(34) set\n * to the sequence number of the first skipped message and NewSeqNo(36) must always be set\n * to the value of the next sequence number to be expected by the peer immediately following\n * the messages being skipped.\n */\n private sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {\n const factory = this.config.factory\n const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset\n gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap, new Date()) as IStandardHeader\n gapFill.StandardHeader.PossDupFlag = true\n\n return new FixMsgStoreRecord(\n MsgType.SequenceReset,\n new Date(),\n startGap,\n gapFill,\n null\n )\n }\n\n /**\n * Prepares the FIX message as response to ResendRequest (2).\n *\n * The FIX session processor retransmitting a message with the PossDupFlag(43) set to \"Y\" must modify the following fields:\n *\n * SendingTime(52) set to the current sending time\n * OrigSendingTime(122) set to the SendingTime(52) from the original message\n * Recalculate the BodyLength(9)\n * Recalculate the CheckSum(10)\n *\n * If the message is encrypted, SecureDataLen(90) and SecureData(91) may also require re-encryption and re-encoding\n *\n * @see https://www.fixtrading.org/standards/fix-session-layer-online/#message-recovery\n *\n * @param originalRecord the FIX message to be retransmitted as possible duplicate\n * @returns the FIX message ready to be retransmitted\n */\n private prepareRecordForRetransmission (originalRecord: IFixMsgStoreRecord): IFixMsgStoreRecord {\n const retransmitted = originalRecord.clone() // We don't want to accidently change any fields of the original record\n\n const factory = this.config.factory\n if (!retransmitted.obj) {\n retransmitted.obj = {}\n }\n\n // Rebuilds header with the updated fields\n const header = factory?.header(\n retransmitted.msgType,\n retransmitted.seqNum,\n new Date(), // SendingTime(52)\n {\n PossDupFlag: true,\n OrigSendingTime: retransmitted.timestamp\n }\n )\n retransmitted.obj = {\n ...retransmitted.obj,\n StandardHeader: header\n }\n return retransmitted\n }\n}\n"]}
1
+ {"version":3,"file":"fix-msg-ascii-store-resend.js","sourceRoot":"","sources":["../../src/store/fix-msg-ascii-store-resend.ts"],"names":[],"mappings":"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","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\nimport { FixMsgStoreRecord, IFixMsgStoreRecord } from './fix-msg-store-record'\nimport { IJsFixConfig } from '../config'\nimport { MsgType } from '../types'\nimport { ElasticBuffer, MsgView } from '../buffer'\nimport { AsciiParser } from '../buffer/ascii'\nimport { ISequenceReset, IStandardHeader } from '../types/FIX4.4/repo'\n\nexport class FixMsgAsciiStoreResend {\n parser: AsciiParser\n constructor (public readonly store: IFixMsgStore, public readonly config: IJsFixConfig) {\n this.parser = new AsciiParser(this.config, null, new ElasticBuffer(160 * 1024))\n }\n\n public async getResendRequest (startSeq: number, endSeq: number): Promise<IFixMsgStoreRecord[]> {\n // Safety feature: If ResendGapFillOnly is enabled, ALWAYS send GapFill instead of\n // replaying stored messages. This prevents accidental duplicate order execution.\n if (this.config.description.store?.resendGapFillOnly === true) {\n const gapFillOnly: IFixMsgStoreRecord[] = []\n this.gap(startSeq, endSeq + 1, gapFillOnly)\n return gapFillOnly\n }\n\n // need to cover request from start to end where any missing numbers are\n // included as gaps to allow vector of messages to be sent by the session\n // on a request\n\n return await new Promise((resolve, reject) => {\n this.store.getSeqNumRange(startSeq, endSeq).then(res => {\n resolve(this.inflateRange(startSeq, endSeq, res))\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {\n const toResend: IFixMsgStoreRecord[] = []\n // If no records for this given sequence number range, returns a single gap fill\n if (input.length === 0) {\n this.gap(startSeq, endSeq + 1, toResend)\n return toResend\n }\n\n let expected = startSeq\n for (let i = 0; i < input.length; ++i) {\n const record = this.prepareRecordForRetransmission(input[i])\n const seqNum = record.seqNum\n const toGap = seqNum - expected\n if (toGap > 0) {\n this.gap(expected, seqNum, toResend)\n }\n expected = seqNum + 1\n if (record.encoded) {\n this.inflate(record)\n }\n toResend.push(record)\n }\n if (endSeq - expected > 0) {\n this.gap(expected, endSeq + 1, toResend)\n }\n return toResend\n }\n\n private gap (beginGap: number, newSeq: number, arr: IFixMsgStoreRecord[]): void {\n if (beginGap > 0) {\n arr.push(this.sequenceResetGap(beginGap, newSeq))\n }\n }\n\n // if records were sent as encoded text then inflate back to object\n // so can be resent or examined\n\n private inflate (record: IFixMsgStoreRecord): void {\n if (record.obj) return\n if (!record.encoded) return\n const parser = this.parser\n parser.on('error', (_: Error) => {\n record.obj = null\n })\n parser.on('msg', (view: MsgView) => {\n record.obj = view.toObject()\n })\n // inline parse\n parser.parseText(record.encoded)\n }\n\n /**\n * A continuous sequence of messages not being retransmitted should be skipped over using a\n * single SequenceReset(35=4) message with GapFillFlag(123) set to “Y” and MsgSeqNum(34) set\n * to the sequence number of the first skipped message and NewSeqNo(36) must always be set\n * to the value of the next sequence number to be expected by the peer immediately following\n * the messages being skipped.\n */\n private sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {\n const factory = this.config.factory\n const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset\n gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap, new Date()) as IStandardHeader\n gapFill.StandardHeader.PossDupFlag = true\n\n return new FixMsgStoreRecord(\n MsgType.SequenceReset,\n new Date(),\n startGap,\n gapFill,\n null\n )\n }\n\n /**\n * Prepares the FIX message as response to ResendRequest (2).\n *\n * The FIX session processor retransmitting a message with the PossDupFlag(43) set to \"Y\" must modify the following fields:\n *\n * SendingTime(52) set to the current sending time\n * OrigSendingTime(122) set to the SendingTime(52) from the original message\n * Recalculate the BodyLength(9)\n * Recalculate the CheckSum(10)\n *\n * If the message is encrypted, SecureDataLen(90) and SecureData(91) may also require re-encryption and re-encoding\n *\n * @see https://www.fixtrading.org/standards/fix-session-layer-online/#message-recovery\n *\n * @param originalRecord the FIX message to be retransmitted as possible duplicate\n * @returns the FIX message ready to be retransmitted\n */\n private prepareRecordForRetransmission (originalRecord: IFixMsgStoreRecord): IFixMsgStoreRecord {\n const retransmitted = originalRecord.clone() // We don't want to accidently change any fields of the original record\n\n const factory = this.config.factory\n if (!retransmitted.obj) {\n retransmitted.obj = {}\n }\n\n // Rebuilds header with the updated fields\n const header = factory?.header(\n retransmitted.msgType,\n retransmitted.seqNum,\n new Date(), // SendingTime(52)\n {\n PossDupFlag: true,\n OrigSendingTime: retransmitted.timestamp\n }\n )\n retransmitted.obj = {\n ...retransmitted.obj,\n StandardHeader: header\n }\n return retransmitted\n }\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  export interface StoreConfig {
2
2
  readonly type: 'memory' | 'file';
3
3
  readonly directory?: string;
4
+ readonly resendGapFillOnly?: boolean;
4
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"store-config.js","sourceRoot":"","sources":["../../src/store/store-config.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Configuration for session message store.\n * Add to session description JSON to enable persistent storage.\n *\n * Examples:\n * \"store\": { \"type\": \"memory\" } — explicit in-memory (default)\n * \"store\": { \"type\": \"file\" } — file store in ./store directory\n * \"store\": { \"type\": \"file\", \"directory\": \"/var/fix/sessions\" }\n *\n * Omitting the store block entirely uses in-memory storage.\n */\nexport interface StoreConfig {\n readonly type: 'memory' | 'file'\n readonly directory?: string\n}\n"]}
1
+ {"version":3,"file":"store-config.js","sourceRoot":"","sources":["../../src/store/store-config.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Configuration for session message store.\n * Add to session description JSON to enable persistent storage.\n *\n * Examples:\n * \"store\": { \"type\": \"memory\" } — explicit in-memory (default)\n * \"store\": { \"type\": \"file\" } — file store in ./store directory\n * \"store\": { \"type\": \"file\", \"directory\": \"/var/fix/sessions\" }\n *\n * Omitting the store block entirely uses in-memory storage.\n */\nexport interface StoreConfig {\n readonly type: 'memory' | 'file'\n readonly directory?: string\n readonly resendGapFillOnly?: boolean\n}\n"]}
@@ -74,7 +74,7 @@ class DefinitionFactory {
74
74
  parser = new parser_1.RepositoryXmlParser(path, getLogger);
75
75
  }
76
76
  else {
77
- parser = new parser_1.QuickFixXmlFileParser(() => new transport_1.FileDuplex(path), getLogger);
77
+ parser = new parser_1.QuickFixGraphFileParser(() => new transport_1.FileDuplex(path), getLogger);
78
78
  }
79
79
  return parser;
80
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definition-factory.js","sourceRoot":"","sources":["../../src/util/definition-factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,sCAA2D;AAC3D,2CAA4B;AAC5B,uCAAwB;AACxB,iDAA+F;AAE/F,4CAAyC;AAEzC,MAAM,IAAI,GAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AAEnD,MAAa,iBAAiB;IAC5B,WAAW,CAAE,CAAS;QACpB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAA;QACnE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAA;IACtB,CAAC;IAEK,cAAc;6DAAE,IAAY,EAAE,YAA4B,wBAAe;YAC7E,MAAM,EAAE,GAAoB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAClD,IAAI,EAAE,EAAE,CAAC;gBACP,IAAI,GAAG,EAAE,CAAC,IAAI,CAAA;YAChB,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAC9C,OAAO,MAAM,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;KAAA;IAED,SAAS,CAAE,IAAY,EAAE,SAAyB;QAChD,IAAI,MAAiB,CAAA;QACrB,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/D,MAAM,GAAG,IAAI,qBAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC5C,CAAC;aAAM,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,MAAM,GAAG,IAAI,4BAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,8BAAqB,CAAC,GAAG,EAAE,CAAC,IAAI,sBAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAA;QAC3E,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,CAAE,CAAS;QACb,IAAI,CAAC,GAAW,CAAC,CAAA;QACjB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACxB,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC;CACF;AAnCD,8CAmCC","sourcesContent":["import { FixParser } from '../dictionary'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { GetJsFixLogger, makeEmptyLogger } from '../config'\nimport * as path from 'path'\nimport * as fs from 'fs'\nimport { FixXsdParser, QuickFixXmlFileParser, RepositoryXmlParser } from '../dictionary/parser'\nimport { IDictionaryPath } from './dictionary-path'\nimport { FileDuplex } from '../transport'\n\nconst root: string = path.join(__dirname, '../../')\n\nexport class DefinitionFactory {\n getDictPath (p: string): IDictionaryPath {\n const dictionary = require(path.join(root, 'data/dictionary.json'))\n return dictionary[p]\n }\n\n async getDefinitions (path: string, getLogger: GetJsFixLogger = makeEmptyLogger): Promise<FixDefinitions> {\n const dp: IDictionaryPath = this.getDictPath(path)\n if (dp) {\n path = dp.dict\n }\n path = this.norm(path)\n const parser = this.getParser(path, getLogger)\n return parser.parse()\n }\n\n getParser (path: string, getLogger: GetJsFixLogger): FixParser {\n let parser: FixParser\n if (fs.lstatSync(path).isDirectory() && path.includes('fixml')) {\n parser = new FixXsdParser(path, getLogger)\n } else if (fs.lstatSync(path).isDirectory()) {\n parser = new RepositoryXmlParser(path, getLogger)\n } else {\n parser = new QuickFixXmlFileParser(() => new FileDuplex(path), getLogger)\n }\n return parser\n }\n\n norm (p: string): string {\n let f: string = p\n if (!path.isAbsolute(p)) {\n f = path.join(root, f)\n }\n return f\n }\n}\n"]}
1
+ {"version":3,"file":"definition-factory.js","sourceRoot":"","sources":["../../src/util/definition-factory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,sCAA2D;AAC3D,2CAA4B;AAC5B,uCAAwB;AACxB,iDAAiG;AAEjG,4CAAyC;AAEzC,MAAM,IAAI,GAAW,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AAEnD,MAAa,iBAAiB;IAC5B,WAAW,CAAE,CAAS;QACpB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAA;QACnE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAA;IACtB,CAAC;IAEK,cAAc;6DAAE,IAAY,EAAE,YAA4B,wBAAe;YAC7E,MAAM,EAAE,GAAoB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAClD,IAAI,EAAE,EAAE,CAAC;gBACP,IAAI,GAAG,EAAE,CAAC,IAAI,CAAA;YAChB,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAC9C,OAAO,MAAM,CAAC,KAAK,EAAE,CAAA;QACvB,CAAC;KAAA;IAED,SAAS,CAAE,IAAY,EAAE,SAAyB;QAChD,IAAI,MAAiB,CAAA;QACrB,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/D,MAAM,GAAG,IAAI,qBAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC5C,CAAC;aAAM,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,MAAM,GAAG,IAAI,4BAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,IAAI,gCAAuB,CAAC,GAAG,EAAE,CAAC,IAAI,sBAAU,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAA;QAC7E,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,CAAE,CAAS;QACb,IAAI,CAAC,GAAW,CAAC,CAAA;QACjB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACxB,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC;CACF;AAnCD,8CAmCC","sourcesContent":["import { FixParser } from '../dictionary'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { GetJsFixLogger, makeEmptyLogger } from '../config'\nimport * as path from 'path'\nimport * as fs from 'fs'\nimport { FixXsdParser, QuickFixGraphFileParser, RepositoryXmlParser } from '../dictionary/parser'\nimport { IDictionaryPath } from './dictionary-path'\nimport { FileDuplex } from '../transport'\n\nconst root: string = path.join(__dirname, '../../')\n\nexport class DefinitionFactory {\n getDictPath (p: string): IDictionaryPath {\n const dictionary = require(path.join(root, 'data/dictionary.json'))\n return dictionary[p]\n }\n\n async getDefinitions (path: string, getLogger: GetJsFixLogger = makeEmptyLogger): Promise<FixDefinitions> {\n const dp: IDictionaryPath = this.getDictPath(path)\n if (dp) {\n path = dp.dict\n }\n path = this.norm(path)\n const parser = this.getParser(path, getLogger)\n return parser.parse()\n }\n\n getParser (path: string, getLogger: GetJsFixLogger): FixParser {\n let parser: FixParser\n if (fs.lstatSync(path).isDirectory() && path.includes('fixml')) {\n parser = new FixXsdParser(path, getLogger)\n } else if (fs.lstatSync(path).isDirectory()) {\n parser = new RepositoryXmlParser(path, getLogger)\n } else {\n parser = new QuickFixGraphFileParser(() => new FileDuplex(path), getLogger)\n }\n return parser\n }\n\n norm (p: string): string {\n let f: string = p\n if (!path.isAbsolute(p)) {\n f = path.join(root, f)\n }\n return f\n }\n}\n"]}