@things-factory/integration-base 10.0.0-beta.92 โ†’ 10.0.0-y.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 (56) hide show
  1. package/dist-server/engine/connection-manager.d.ts +19 -0
  2. package/dist-server/engine/connection-manager.js +148 -16
  3. package/dist-server/engine/connection-manager.js.map +1 -1
  4. package/dist-server/engine/connector/headless-connector.d.ts +12 -0
  5. package/dist-server/engine/connector/headless-connector.js +74 -31
  6. package/dist-server/engine/connector/headless-connector.js.map +1 -1
  7. package/dist-server/engine/evaluate-template.d.ts +22 -3
  8. package/dist-server/engine/evaluate-template.js +43 -4
  9. package/dist-server/engine/evaluate-template.js.map +1 -1
  10. package/dist-server/engine/task/script.js +25 -17
  11. package/dist-server/engine/task/script.js.map +1 -1
  12. package/dist-server/engine/types.d.ts +32 -0
  13. package/dist-server/engine/types.js.map +1 -1
  14. package/dist-server/service/connection/connection-mutation.d.ts +3 -0
  15. package/dist-server/service/connection/connection-subscription.js +4 -4
  16. package/dist-server/service/connection/connection-subscription.js.map +1 -1
  17. package/dist-server/service/connection/connection-type.d.ts +4 -1
  18. package/dist-server/service/connection/connection-type.js +21 -0
  19. package/dist-server/service/connection/connection-type.js.map +1 -1
  20. package/dist-server/service/connection/connection.d.ts +80 -2
  21. package/dist-server/service/connection/connection.js +59 -15
  22. package/dist-server/service/connection/connection.js.map +1 -1
  23. package/dist-server/service/domain-attribute/domain-attribute-query.d.ts +17 -0
  24. package/dist-server/service/domain-attribute/domain-attribute-query.js +76 -0
  25. package/dist-server/service/domain-attribute/domain-attribute-query.js.map +1 -0
  26. package/dist-server/service/domain-attribute/domain-attribute-type.d.ts +15 -0
  27. package/dist-server/service/domain-attribute/domain-attribute-type.js +46 -0
  28. package/dist-server/service/domain-attribute/domain-attribute-type.js.map +1 -0
  29. package/dist-server/service/domain-attribute/index.d.ts +3 -0
  30. package/dist-server/service/domain-attribute/index.js +8 -0
  31. package/dist-server/service/domain-attribute/index.js.map +1 -0
  32. package/dist-server/service/index.d.ts +1 -1
  33. package/dist-server/service/index.js +3 -1
  34. package/dist-server/service/index.js.map +1 -1
  35. package/dist-server/service/scenario/scenario-mutation.js +10 -0
  36. package/dist-server/service/scenario/scenario-mutation.js.map +1 -1
  37. package/dist-server/service/scenario/scenario-query.d.ts +3 -3
  38. package/dist-server/service/scenario/scenario-query.js +9 -9
  39. package/dist-server/service/scenario/scenario-query.js.map +1 -1
  40. package/dist-server/service/scenario-instance/scenario-instance-subscription.js +4 -4
  41. package/dist-server/service/scenario-instance/scenario-instance-subscription.js.map +1 -1
  42. package/dist-server/service/scenario-instance/scenario-instance-type.js +79 -0
  43. package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
  44. package/dist-server/service/scenario-queue/scenario-queue-subscription.js +2 -2
  45. package/dist-server/service/scenario-queue/scenario-queue-subscription.js.map +1 -1
  46. package/dist-server/service/state-register/data-resolver.js +4 -3
  47. package/dist-server/service/state-register/data-resolver.js.map +1 -1
  48. package/dist-server/service/step/step-mutation.js +15 -0
  49. package/dist-server/service/step/step-mutation.js.map +1 -1
  50. package/dist-server/service/step/step-query.js +11 -2
  51. package/dist-server/service/step/step-query.js.map +1 -1
  52. package/dist-server/tsconfig.tsbuildinfo +1 -1
  53. package/dist-server/utils/domain-inheritance.d.ts +27 -0
  54. package/dist-server/utils/domain-inheritance.js +67 -0
  55. package/dist-server/utils/domain-inheritance.js.map +1 -1
  56. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"headless-connector.js","sourceRoot":"","sources":["../../../server/engine/connector/headless-connector.ts"],"names":[],"mappings":";;;AAAA,8DAAyD;AAEzD,kEAA8E;AAG9E;;;;;;;;;;EAUE;AAEF,MAAa,iBAAiB;IAC5B,KAAK,CAAC,KAAK,CAAC,iBAAiB;QAC3B,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjE,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;IAC3E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAU;QACtB,MAAM,EACJ,QAAQ,EAAE,GAAG,GAAG,GAAG,EACnB,MAAM,EAAE,EACN,QAAQ,GAAG,EAAE,EACb,QAAQ,GAAG,EAAE,EACb,aAAa,GAAG,QAAQ,EACxB,WAAW,GAAG,IAAI,EAClB,gBAAgB,GAAG,WAAW,EAC9B,gBAAgB,GAAG,WAAW,EAC9B,cAAc,GAAG,SAAS,EAC1B,eAAe,GAAG,IAAI,EACtB,kBAAkB,GAAG,EAAE,EAAE,uCAAuC;QAChE,OAAO,GAAG,KAAK,EAAE,iCAAiC;QAClD,OAAO,GAAG,CAAC,CAAC,sDAAsD;UACnE,GAAG,EAAE,EACP,GAAG,UAAU,CAAA;QAEd,MAAM,SAAS,GAAG;YAChB,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,iCAAiC;YACnE,QAAQ;YACR,QAAQ;YACR,aAAa;YACb,WAAW;YACX,OAAO;YACP,OAAO;YACP,cAAc,EAAE;gBACd,gBAAgB;gBAChB,gBAAgB;gBAChB,cAAc;gBACd,eAAe;gBACf,kBAAkB,EAAE,kBAAkB;qBACnC,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;qBAChC,MAAM,CAAC,OAAO,CAAC;aACnB;SACF,CAAA;QAED,KAAK,UAAU,cAAc;YAC3B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,+BAAe,GAAE,CAAA;gBAE9B,sBAAsB;gBACtB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAA,4BAAY,GAAE,CAAA;oBAC5B,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,KAAK,CAAC,QAAQ,gBAAgB,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBACrJ,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAA;gBACxE,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;gBACpC,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAA;gBACxE,OAAO,OAAO,CAAA;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAA;gBAE7E,mBAAmB;gBACnB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAA,4BAAY,GAAE,CAAA;oBAC5B,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,KAAK,CAAC,QAAQ,gBAAgB,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,OAAO,UAAU,KAAK,CAAC,GAAG,EAAE,CAAC,CAAA;gBAC9K,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,UAAU,CAAC,CAAA;gBACtF,CAAC;gBAED,MAAM,KAAK,CAAA;YACb,CAAC;QACH,CAAC;QAED,KAAK,UAAU,cAAc,CAAC,OAAgB;YAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;gBAC5E,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,uBAAuB;gBACvB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;oBAC3B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;oBAC1E,OAAM;gBACR,CAAC;gBAED,uBAAuB;gBACvB,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,IAAA,4BAAY,GAAE,CAAA;oBAClC,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,WAAW,CAAC,QAAQ,gBAAgB,WAAW,CAAC,SAAS,EAAE,CAAC,CAAA;gBACtI,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE,UAAU,CAAC,CAAA;gBACvF,CAAC;gBAED,MAAM,IAAI,GAAG,IAAA,+BAAe,GAAE,CAAA;gBAC9B,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBAC3B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAA;gBAEtE,uBAAuB;gBACvB,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,IAAA,4BAAY,GAAE,CAAA;oBACjC,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,UAAU,CAAC,QAAQ,gBAAgB,UAAU,CAAC,SAAS,EAAE,CAAC,CAAA;gBACnI,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,UAAU,CAAC,CAAA;gBACtF,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;gBAE3E,iBAAiB;gBACjB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAA,4BAAY,GAAE,CAAA;oBAC5B,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,KAAK,CAAC,QAAQ,gBAAgB,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC3J,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE,UAAU,CAAC,CAAA;gBAC9F,CAAC;gBAED,8BAA8B;gBAC9B,IAAI,CAAC;oBACH,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;wBACrC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;wBACrB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAA;oBACtF,CAAC;gBACH,CAAC;gBAAC,OAAO,eAAe,EAAE,CAAC;oBACzB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,2DAA2D,EAAE,eAAe,CAAC,CAAA;gBAC9G,CAAC;YACH,CAAC;QACH,CAAC;QAED,sCAAiB,CAAC,qBAAqB,CAAC,UAAU,EAAE;YAClD,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,kBAAkB,EAAE,KAAK,IAAI,EAAE;gBAC7B,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAA;gBACtC,IAAI,IAAI,CAAA;gBACR,IAAI,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;gBAEhC,IAAI,CAAC;oBACH,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;oBAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;oBAExC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;wBAC5B,gBAAgB;wBAChB,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAA;wBAE5D,6BAA6B;wBAC7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;4BACvC,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;iCAClD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;iCACvD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;wBACtB,CAAC,CAAC,CAAA;wBAEF,IAAI,OAAO,EAAE,CAAC;4BACZ,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAA;4BACnF,OAAO,IAAI,CAAA;wBACb,CAAC;wBAED,IAAI,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;4BACtC,MAAM,IAAI,CAAC,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;4BACjE,OAAO,IAAI,CAAA;wBACb,CAAC;wBAED,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;wBAC7C,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;wBAC9B,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;oBAC9B,CAAC;yBAAM,CAAC;wBACN,+BAA+B;wBAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAA;oBAC9D,CAAC;oBAED,OAAO,IAAI,CAAA;gBACb,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;oBAExE,+BAA+B;oBAC/B,IAAI,IAAI,EAAE,CAAC;wBACT,IAAI,CAAC;4BACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;4BAClB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAA;wBACvF,CAAC;wBAAC,OAAO,UAAU,EAAE,CAAC;4BACpB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,EAAE,UAAU,CAAC,CAAA;wBACrG,CAAC;oBACH,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;wBAC7B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;oBAC5F,CAAC;oBAAC,OAAO,YAAY,EAAE,CAAC;wBACtB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,4DAA4D,EAAE,YAAY,CAAC,CAAA;oBAC5G,CAAC;oBAED,MAAM,KAAK,CAAA;gBACb,CAAC;YACH,CAAC;YACD,WAAW,EAAE,KAAK,EAAE,IAAU,EAAE,EAAE;gBAChC,IAAI,CAAC;oBACH,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;wBAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;wBAE9B,aAAa;wBACb,IAAI,CAAC;4BACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;4BAClB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;wBAC3D,CAAC;wBAAC,OAAO,UAAU,EAAE,CAAC;4BACpB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAA;wBACrE,CAAC;wBAED,cAAc;wBACd,IAAI,CAAC;4BACH,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;4BAC7B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;wBAChE,CAAC;wBAAC,OAAO,YAAY,EAAE,CAAC;4BACtB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,YAAY,CAAC,CAAA;4BAC1E,8BAA8B;4BAC9B,IAAI,CAAC;gCACH,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;oCACrC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;oCACrB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAA;gCACtF,CAAC;4BACH,CAAC;4BAAC,OAAO,eAAe,EAAE,CAAC;gCACzB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAA;4BACnF,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAA;gBACzE,CAAC;YACH,CAAC;YACD,qBAAqB;YACrB,qBAAqB,EAAE,KAAK,IAAI,EAAE;gBAChC,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;gBAE7F,IAAI,OAAO,GAAG,IAAI,CAAA;gBAClB,IAAI,IAAI,GAAG,IAAI,CAAA;gBAEf,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,cAAc,EAAE,CAAA;oBAChC,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;oBAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;oBAElD,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;wBAC5B,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,CAAA;wBAC7C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;wBACvC,UAAU,CAAC,OAAO,GAAG,UAAU,CAAA;wBAC/B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,yDAAyD,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;oBAC3G,CAAC;oBAED,6CAA6C;oBAC7C,OAAO;wBACL,IAAI;wBACJ,OAAO;wBACP,qBAAqB,EAAE,IAAI,CAAE,eAAe;qBAC7C,CAAA;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;oBAE7G,kBAAkB;oBAClB,IAAI,IAAI,EAAE,CAAC;wBACT,IAAI,CAAC;4BACH,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gCACrB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;gCAClB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;4BAC3E,CAAC;wBACH,CAAC;wBAAC,OAAO,UAAU,EAAE,CAAC;4BACpB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,UAAU,CAAC,CAAA;wBACzF,CAAC;oBACH,CAAC;oBAED,IAAI,OAAO,EAAE,CAAC;wBACZ,IAAI,CAAC;4BACH,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;4BAC7B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAA;wBAChF,CAAC;wBAAC,OAAO,YAAY,EAAE,CAAC;4BACtB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE,YAAY,CAAC,CAAA;4BAC9F,8BAA8B;4BAC9B,IAAI,CAAC;gCACH,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;oCAC1B,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;oCACrB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;gCAC1G,CAAC;4BACH,CAAC;4BAAC,OAAO,eAAe,EAAE,CAAC;gCACzB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,EAAE,eAAe,CAAC,CAAA;4BACvG,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,MAAM,KAAK,CAAA;gBACb,CAAC;YACH,CAAC;YACD,YAAY;YACZ,eAAe,EAAE,KAAK,EAAE,IAAU,EAAE,EAAE;gBACpC,IAAI,CAAC;oBACH,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC;wBAC7B,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,uBAAuB;oBACvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;wBAC7B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;wBAC1F,OAAO,KAAK,CAAA;oBACd,CAAC;oBAED,qBAAqB;oBACrB,IAAI,UAAkB,CAAA;oBACtB,IAAI,CAAC;wBACH,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;oBACzB,CAAC;oBAAC,OAAO,QAAQ,EAAE,CAAC;wBAClB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA;wBACjG,OAAO,KAAK,CAAA;oBACd,CAAC;oBAED,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC;wBAC5C,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC7B,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;wBAC9B,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;wBACjC,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,UAAU,EAAE,CAAC,CAAA;wBACxE,OAAO,KAAK,CAAA;oBACd,CAAC;oBAED,iBAAiB;oBACjB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;wBAC1C,IAAI,CAAC;4BACH,yBAAyB;4BACzB,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAA;4BACtF,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gCACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAgB,CAAA;gCAC/D,OAAO,OAAO,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,CAAA,CAAC,aAAa;4BAC/D,CAAC,CAAC,CAAA;wBACJ,CAAC;wBAAC,OAAO,SAAS,EAAE,CAAC;4BACnB,OAAO,IAAI,CAAA,CAAC,wBAAwB;wBACtC,CAAC;oBACH,CAAC,CAAC,CAAA;oBAEF,iCAAiC;oBACjC,IAAI,CAAC;wBACH,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;4BAClD,IAAI,CAAC;gCACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;oCACnD,MAAM,EAAE,MAAM;oCACd,WAAW,EAAE,SAAS;iCACvB,CAAC,CAAA;gCACF,OAAO;oCACL,MAAM,EAAE,QAAQ,CAAC,MAAM;oCACvB,EAAE,EAAE,QAAQ,CAAC,EAAE;iCAChB,CAAA;4BACH,CAAC;4BAAC,OAAO,UAAU,EAAE,CAAC;gCACpB,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;4BACjC,CAAC;wBACH,CAAC,CAAC,CAAA;wBAEF,oCAAoC;wBACpC,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;4BAC/D,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,YAAY,CAAC,MAAM,oBAAoB,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;4BAC5H,OAAO,KAAK,CAAA;wBACd,CAAC;oBACH,CAAC;oBAAC,OAAO,YAAY,EAAE,CAAC;wBACtB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,UAAU,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,CAAA;wBACzG,6CAA6C;oBAC/C,CAAC;oBAED,OAAO,CAAC,UAAU,CAAA;gBACpB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;oBACpG,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;YACD,cAAc;YACd,cAAc;SACf,CAAC,CAAA;QAEF,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAC3B,iCAAiC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,gBAAgB,CACxF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO;QAChC,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAA;QAEvC,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAE7B,MAAM,IAAI,CAAC,YAAY,CACrB,sHAAsH,CACvH,CAAA;QAED,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE;YACpC,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;QACrE,CAAC,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,mBAAmB,CAAC;YAC7B,2BAA2B,EAAE,GAAG;YAChC,iBAAiB,EAAE,gBAAgB;YACnC,OAAO,EAAE,GAAG;SACb,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAA;QAE/C,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YAE7F,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;gBACpC,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAA;YAChG,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;gBACvB,IAAI,IAAI;oBAAE,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;YAC1E,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;YAC3B,IAAI,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC;gBAC3C,OAAM;YACR,CAAC;YAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAA;YAE3C,2CAA2C;YAC3C,IAAI,YAAY,KAAK,OAAO,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;gBACvD,OAAO,CAAC,QAAQ,EAAE,CAAA;gBAClB,OAAM;YACR,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;YACjC,IAAI,OAAO,CAAC,gCAAgC,CAAC,EAAE,CAAC;gBAC9C,MAAM,eAAe,GAAG,OAAO,CAAC,gCAAgC,CAAC;qBAC9D,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;qBAC5B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,2BAA2B,CAAC,CAAA;gBAEzE,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,gCAAgC,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACxE,CAAC;qBAAM,CAAC;oBACN,OAAO,OAAO,CAAC,gCAAgC,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;YAED,IAAI,OAAO,CAAC,2BAA2B,CAAC,EAAE,CAAC;gBACzC,OAAO,OAAO,CAAC,2BAA2B,CAAC,CAAA;YAC7C,CAAC;YAED,kCAAkC;YAClC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC3D,OAAO,CAAC,KAAK,EAAE,CAAA;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,QAAQ,EAAE,CAAA;YACpB,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE;YACjC,IAAI,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;gBAC9B,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;gBACtC,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;gBAC5C,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;gBAC9D,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBAE5C,IAAI,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;oBACvB,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;YACzD,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS;QACzD,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,CAAA;QAChC,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;QAE5E,IAAI,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACzC,IAAI,EACJ,SAAS,CAAC,cAAc,CAAC,kBAAkB,EAC3C,SAAS,CAAC,cAAc,CAAC,eAAe,CACzC,CAAA;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;YACpD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS;QACrC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;YAC9D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;gBAE9G,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAC/C,IAAI,EACJ,SAAS,CAAC,cAAc,CAAC,kBAAkB,EAC3C,SAAS,CAAC,cAAc,CAAC,gBAAgB,CAC1C,CAAA;gBACD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAC/C,IAAI,EACJ,SAAS,CAAC,cAAc,CAAC,kBAAkB,EAC3C,SAAS,CAAC,cAAc,CAAC,gBAAgB,CAC1C,CAAA;gBACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAC9C,IAAI,EACJ,SAAS,CAAC,cAAc,CAAC,kBAAkB,EAC3C,SAAS,CAAC,cAAc,CAAC,cAAc,CACxC,CAAA;gBAED,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;gBAClE,CAAC;gBAED,MAAM,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;gBAC5C,MAAM,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;gBAE5C,IAAI,WAAW,GACb,SAAS,CAAC,WAAW;oBACrB,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;wBAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;wBACnC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;oBAClC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAA;gBAEnB,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,WAAW,GAAG,GAAG,GAAG,GAAG,WAAW,EAAE,CAAA;gBACtC,CAAC;gBAED,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;gBACtD,CAAC;gBAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAAA;gBAErD,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBACnC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;wBAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAA;wBAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAA;wBAE1C,OAAO,GAAG,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;oBAC1G,CAAC,CAAC;oBACF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC;oBACrD,IAAI,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,gBAAgB;iBACnG,CAAC,CAAA;gBAEF,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAA;oBAChC,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;wBAClC,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,MAAM,EAAE,CAAC,CAAA;wBAC7E,OAAM;oBACR,CAAC;yBAAM,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;wBACzB,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAA;oBAC7D,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;gBACtD,CAAC;gBAED,IAAI,SAAS,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;oBAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACzC,IAAI,EACJ,SAAS,CAAC,cAAc,CAAC,kBAAkB,EAC3C,SAAS,CAAC,cAAc,CAAC,eAAe,CACzC,CAAA;oBACD,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;oBAC7D,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,UAAU,EAAE,KAAK,CAAC,CAAA;gBAExE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,8BAA8B,OAAO,MAAM,EAAE,CAAC,CAAA;gBAC9E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;gBACxE,CAAC;gBAED,IAAI,OAAO,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,CAAC,OAAO,WAAW,CAAC,CAAA;gBACrE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,cAAc;QAC1D,IAAI,OAAO,CAAA;QAEX,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrD,uDAAuD;YACvD,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA,CAAC,8CAA8C;YACzE,OAAO,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAA,CAAC,uCAAuC;QAC1E,CAAC;QAED,OAAO,GAAG,IAAI,CAAA,CAAC,qCAAqC;QACpD,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;YAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAA;YACvD,CAAC;YACD,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;QAC1E,CAAC;QACD,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAA;IAC7G,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAU;QACzB,IAAI,CAAC;YACH,oBAAoB;YACpB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,UAAU,CAAC,IAAI,EAAE,CAAC,CAAA;YAE/F,mBAAmB;YACnB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAA,+BAAe,GAAE,CAAA;gBAC9B,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YACvG,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;YAChG,CAAC;YAED,sCAAiB,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAA;YACtD,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,UAAU,CAAC,IAAI,mBAAmB,CAAC,CAAA;QACpG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,UAAU,CAAC,IAAI,IAAI,EAAE,KAAK,CAAC,CAAA;YAC/G,qEAAqE;YACrE,IAAI,CAAC;gBACH,sCAAiB,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAA;YACxD,CAAC;YAAC,OAAO,WAAW,EAAE,CAAC;gBACrB,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,UAAU,CAAC,IAAI,GAAG,EAAE,WAAW,CAAC,CAAA;YACzG,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,aAAa;QACf,OAAO;YACL;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,UAAU;gBACjB,kBAAkB,EAAE,IAAI;aACzB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,UAAU;gBACjB,kBAAkB,EAAE,IAAI;aACzB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,iBAAiB;aACzB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,eAAe;aACvB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,mBAAmB;aAC3B;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,mBAAmB;aAC3B;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,iBAAiB;aACzB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,kBAAkB;aAC1B;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,sBAAsB;aAC9B;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,KAAK;aACb;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,iBAAiB;gBACxB,KAAK,EAAE,CAAC;aACT;SACF,CAAA;IACH,CAAC;IAED,IAAI,YAAY;QACd,OAAO,CAAC,UAAU,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,iDAAiD,CAAA;IAC1D,CAAC;IAED,IAAI,IAAI;QACN,OAAO,0CAA0C,CAAA;IACnD,CAAC;CACF;AAtrBD,8CAsrBC;AAED,sCAAiB,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,IAAI,iBAAiB,EAAE,CAAC,CAAA;AAElF,SAAS,aAAa,CAAC,OAAc;IACnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,0BAA0B;IACxD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,CAAA;AAC9E,CAAC","sourcesContent":["import { ConnectionManager } from '../connection-manager'\nimport { Connector } from '../types'\nimport { getHeadlessPool, getPoolStats } from '../resource-pool/headless-pool'\nimport { Browser, Page } from 'puppeteer'\n\n/*\n Functionality of the headless-connector:\n - Provides a mechanism to acquire an active session page.\n - Performs login when necessary to obtain valid cookies.\n - Applies these cookies to the page for session management.\n - Pages are acquired from the `headlessPool`, which manages browser instances.\n - During the login process, pages from the pool are used for actions like form filling and navigation.\n - Valid cookies are saved after login and reused for subsequent page acquisitions.\n - Users must explicitly release the page after use through the `releasePage` method.\n - Released pages are returned to the `headlessPool` for reuse.\n*/\n\nexport class HeadlessConnector implements Connector {\n async ready(connectionConfigs) {\n await Promise.all(connectionConfigs.map(this.connect.bind(this)))\n ConnectionManager.logger.info('headless-connector connections are ready')\n }\n\n async connect(connection) {\n const {\n endpoint: uri = '1',\n params: {\n username = '',\n password = '',\n loginPagePath = '/login',\n loginApiUrl = null,\n usernameSelector = '#username',\n passwordSelector = '#password',\n submitSelector = '#submit',\n successSelector = null,\n shadowDomSelectors = '', // Comma separated shadow DOM selectors\n timeout = 15000, // Default timeout for operations\n retries = 3 // Default number of retries for login or page actions\n } = {}\n } = connection\n\n const loginInfo = {\n loginRequired: Boolean(username), // Determine if login is required\n username,\n password,\n loginPagePath,\n loginApiUrl,\n timeout,\n retries,\n loginSelectors: {\n usernameSelector,\n passwordSelector,\n submitSelector,\n successSelector,\n shadowDomSelectors: shadowDomSelectors\n .split(',')\n .map(selector => selector.trim())\n .filter(Boolean)\n }\n }\n\n async function acquireBrowser() {\n try {\n const pool = getHeadlessPool()\n \n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋””๋ฒ„๊น…์šฉ)\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats before acquire - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats:', statsError)\n }\n \n const browser = await pool.acquire()\n ConnectionManager.logger.info('Browser acquired successfully from pool')\n return browser\n } catch (error) {\n ConnectionManager.logger.error('Failed to acquire browser from pool:', error)\n \n // ํ’€ ์ƒํƒœ ๋กœ๊น…์œผ๋กœ ๋””๋ฒ„๊น… ๋„์›€\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.error(`Pool stats during acquire error - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}, max: ${stats.max}`)\n } catch (statsError) {\n ConnectionManager.logger.error('Failed to get pool stats during error:', statsError)\n }\n \n throw error\n }\n }\n\n async function releaseBrowser(browser: Browser) {\n if (!browser) {\n ConnectionManager.logger.warn('Attempted to release null/undefined browser')\n return\n }\n\n try {\n // ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„์ง ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ\n if (!browser.isConnected()) {\n ConnectionManager.logger.warn('Attempted to release disconnected browser')\n return\n }\n\n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋ฆด๋ฆฌ์ฆˆ ์ „)\n try {\n const statsBefore = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats before release - borrowed: ${statsBefore.borrowed}, available: ${statsBefore.available}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats before release:', statsError)\n }\n\n const pool = getHeadlessPool()\n await pool.release(browser)\n ConnectionManager.logger.info('Browser successfully released to pool')\n \n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋ฆด๋ฆฌ์ฆˆ ํ›„)\n try {\n const statsAfter = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats after release - borrowed: ${statsAfter.borrowed}, available: ${statsAfter.available}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats after release:', statsError)\n }\n } catch (error) {\n ConnectionManager.logger.error('Failed to release browser to pool:', error)\n \n // ์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ํ’€ ์ƒํƒœ ๋กœ๊น…\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.error(`Pool stats during release error - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}`)\n } catch (statsError) {\n ConnectionManager.logger.error('Failed to get pool stats during release error:', statsError)\n }\n \n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser && browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser after pool release failure:', forceCloseError)\n }\n }\n }\n\n ConnectionManager.addConnectionInstance(connection, {\n endpoint: connection.endpoint,\n params: connection.params,\n acquireSessionPage: async () => {\n const browser = await acquireBrowser()\n let page\n let cookies = connection.cookies\n\n try {\n page = await browser.newPage()\n await this.setupPage(page, uri, timeout)\n\n if (loginInfo.loginRequired) {\n // ๋จผ์ € ๊ธฐ๋ณธ ํŽ˜์ด์ง€๋กœ ์ด๋™\n await page.goto(uri, { waitUntil: 'networkidle2', timeout })\n\n // ํ˜„์žฌ ์„ธ์…˜์˜ Authorization ํ—ค๋” ํ™•์ธ\n const headers = await page.evaluate(() => {\n return fetch(window.location.href, { method: 'GET' })\n .then(response => response.headers.get('Authorization'))\n .catch(() => null)\n })\n\n if (headers) {\n ConnectionManager.logger.info('User is already logged in, skipping login process.')\n return page\n }\n\n if (cookies && isCookieValid(cookies)) {\n await this.applyCookiesAndVerifySession(page, cookies, loginInfo)\n return page\n }\n\n await this.performLogin(page, uri, loginInfo)\n cookies = await page.cookies()\n connection.cookies = cookies\n } else {\n // ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ๊ธฐ๋ณธ ํŽ˜์ด์ง€๋กœ ์ด๋™\n await page.goto(uri, { waitUntil: 'networkidle2', timeout })\n }\n\n return page\n } catch (error) {\n ConnectionManager.logger.error('Failed to acquire session page:', error)\n \n // CRITICAL: ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ํ™•์‹คํ•œ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ\n if (page) {\n try {\n await page.close()\n ConnectionManager.logger.info('Page closed during acquireSessionPage error handling')\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page during acquireSessionPage error:', closeError)\n }\n }\n \n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released during acquireSessionPage error handling')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser during acquireSessionPage error:', releaseError)\n }\n \n throw error\n }\n },\n releasePage: async (page: Page) => {\n try {\n if (page && !page.isClosed()) {\n const browser = page.browser()\n \n // ํŽ˜์ด์ง€๋ฅผ ๋จผ์ € ๋‹ซ๊ธฐ\n try {\n await page.close()\n ConnectionManager.logger.info('Page closed successfully')\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page:', closeError)\n }\n \n // ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ’€์— ๋ฐ˜ํ™˜\n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released successfully')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser:', releaseError)\n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser && browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser:', forceCloseError)\n }\n }\n }\n } catch (error) {\n ConnectionManager.logger.error('Critical error in releasePage:', error)\n }\n },\n // ์„ธ์…˜ ํšŒ๋ณต์„ ์œ„ํ•œ ์žฌ๋กœ๊ทธ์ธ ๋ฉ”์„œ๋“œ\n reAuthenticateSession: async () => {\n ConnectionManager.logger.info(`Re-authenticating session for connection: ${connection.name}`)\n \n let browser = null\n let page = null\n\n try {\n browser = await acquireBrowser()\n page = await browser.newPage()\n await this.setupPage(page, uri, loginInfo.timeout)\n \n if (loginInfo.loginRequired) {\n await this.performLogin(page, uri, loginInfo)\n const newCookies = await page.cookies()\n connection.cookies = newCookies\n ConnectionManager.logger.info(`Session re-authenticated successfully for connection: ${connection.name}`)\n }\n \n // CRITICAL: ํŽ˜์ด์ง€์™€ ํ•จ๊ป˜ ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ •ํ™•ํ•œ ๋ฆด๋ฆฌ์ฆˆ ์ถ”์ \n return {\n page,\n browser,\n requiresManualRelease: true // ์ˆ˜๋™ ๋ฆด๋ฆฌ์ฆˆ ํ•„์š” ํ‘œ์‹œ\n }\n } catch (error) {\n ConnectionManager.logger.error(`Failed to re-authenticate session for connection: ${connection.name}`, error)\n \n // ์—๋Ÿฌ ์‹œ ํ™•์‹คํ•œ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ\n if (page) {\n try {\n if (!page.isClosed()) {\n await page.close()\n ConnectionManager.logger.info('Page closed during reauth error handling')\n }\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page during reauth error:', closeError)\n }\n }\n \n if (browser) {\n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released during reauth error handling')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser during reauth error:', releaseError)\n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser during reauth error due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser during reauth error:', forceCloseError)\n }\n }\n }\n \n throw error\n }\n },\n // ์„ธ์…˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ\n validateSession: async (page: Page) => {\n try {\n if (!loginInfo.loginRequired) {\n return true\n }\n\n // ํŽ˜์ด์ง€๊ฐ€ ๋‹ซํ˜”๊ฑฐ๋‚˜ ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ๊ฒฝ์šฐ\n if (!page || page.isClosed()) {\n ConnectionManager.logger.warn(`Page is closed or null for connection: ${connection.name}`)\n return false\n }\n\n // URL ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ ๋ฆฌ๋””๋ ‰์…˜ ์ฒดํฌ\n let currentUrl: string\n try {\n currentUrl = page.url()\n } catch (urlError) {\n ConnectionManager.logger.warn(`Cannot get page URL for connection: ${connection.name}`, urlError)\n return false\n }\n \n if (currentUrl.includes(loginInfo.loginPagePath) || \n currentUrl.includes('/login') || \n currentUrl.includes('/signin') || \n currentUrl.includes('/auth')) {\n ConnectionManager.logger.info(`Redirected to login page: ${currentUrl}`)\n return false\n }\n\n // ๋กœ๊ทธ์ธ ํผ ์š”์†Œ ๊ธฐ๋ฐ˜ ์ฒดํฌ\n const needsLogin = await page.evaluate(() => {\n try {\n // ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ํŠน์ • ์š”์†Œ๋“ค์ด ์žˆ๋Š”์ง€ ํ™•์ธ\n const loginIndicators = ['#username', '#password', '.login-form', '[type=\"password\"]']\n return loginIndicators.some(selector => {\n const element = document.querySelector(selector) as HTMLElement\n return element && element.offsetParent !== null // ๋ณด์ด๋Š” ์š”์†Œ๋งŒ ์ฒดํฌ\n })\n } catch (evalError) {\n return true // ์—๋Ÿฌ ์‹œ ์•ˆ์ „ํ•˜๊ฒŒ ์žฌ๋กœ๊ทธ์ธ ํ•„์š”๋กœ ๊ฐ„์ฃผ\n }\n })\n\n // ์ถ”๊ฐ€ ์„ธ์…˜ ๊ฒ€์ฆ: ๊ฐ„๋‹จํ•œ API ํ˜ธ์ถœ๋กœ ์ธ์ฆ ์ƒํƒœ ํ™•์ธ\n try {\n const testResponse = await page.evaluate(async () => {\n try {\n const response = await fetch(window.location.origin, { \n method: 'HEAD',\n credentials: 'include'\n })\n return {\n status: response.status,\n ok: response.ok\n }\n } catch (fetchError) {\n return { status: 0, ok: false }\n }\n })\n \n // ์ธ์ฆ์ด ํ•„์š”ํ•œ ์—”๋“œํฌ์ธํŠธ์—์„œ 401/403 ๋ฐ˜ํ™˜์‹œ ์„ธ์…˜ ๋ฌดํšจ\n if (testResponse.status === 401 || testResponse.status === 403) {\n ConnectionManager.logger.info(`Authentication failed with status ${testResponse.status} for connection: ${connection.name}`)\n return false\n }\n } catch (apiTestError) {\n ConnectionManager.logger.warn(`Session API test failed for connection: ${connection.name}`, apiTestError)\n // API ํ…Œ์ŠคํŠธ ์‹คํŒจ๋Š” ์„ธ์…˜ ๋ฌดํšจ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Œ (๋„คํŠธ์›Œํฌ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์Œ)\n }\n\n return !needsLogin\n } catch (error) {\n ConnectionManager.logger.warn(`Session validation failed for connection: ${connection.name}`, error)\n return false\n }\n },\n acquireBrowser,\n releaseBrowser\n })\n\n ConnectionManager.logger.info(\n `headless-connector connection(${connection.name}:${connection.endpoint}) is connected`\n )\n }\n\n async setupPage(page, uri, timeout) {\n await page.setRequestInterception(true)\n\n await page.setBypassCSP(true)\n\n await page.setUserAgent(\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.204 Safari/537.36'\n )\n\n await page.evaluateOnNewDocument(() => {\n Object.defineProperty(navigator, 'webdriver', { get: () => false })\n })\n\n await page.setExtraHTTPHeaders({\n 'Upgrade-Insecure-Requests': '0',\n 'accept-language': 'en-US,en;q=0.9',\n referer: uri\n })\n\n await page.setDefaultNavigationTimeout(timeout)\n\n page.on('console', async msg => {\n const args = await Promise.all(msg.args().map(arg => arg.jsonValue().catch(() => undefined)))\n\n if (args.some(a => a !== undefined)) {\n ConnectionManager.logger.info(`[browser ${msg.type()}]`, ...args.filter(a => a !== undefined))\n } else {\n const text = msg.text()\n if (text) ConnectionManager.logger.info(`[browser ${msg.type()}]`, text)\n }\n })\n\n page.on('request', request => {\n if (request.isInterceptResolutionHandled()) {\n return\n }\n\n const resourceType = request.resourceType()\n\n // fetch(), XMLHttpRequest ๋“ฑ์˜ API ํ˜ธ์ถœ์€ ํ•ญ์ƒ ํ—ˆ์šฉ\n if (resourceType === 'fetch' || resourceType === 'xhr') {\n request.continue()\n return\n }\n\n const headers = request.headers()\n if (headers['access-control-request-headers']) {\n const filteredHeaders = headers['access-control-request-headers']\n .split(',')\n .map(header => header.trim())\n .filter(header => header.toLowerCase() !== 'upgrade-insecure-requests')\n\n if (filteredHeaders.length > 0) {\n headers['access-control-request-headers'] = filteredHeaders.join(', ')\n } else {\n delete headers['access-control-request-headers']\n }\n }\n\n if (headers['upgrade-insecure-requests']) {\n delete headers['upgrade-insecure-requests']\n }\n\n // ์ด๋ฏธ์ง€, ์Šคํƒ€์ผ์‹œํŠธ, ํฐํŠธ๋Š” ์ฐจ๋‹จํ•˜๋˜ API ์š”์ฒญ์€ ํ—ˆ์šฉ\n if (['image', 'stylesheet', 'font'].includes(resourceType)) {\n request.abort()\n } else {\n request.continue()\n }\n })\n\n page.on('requestfailed', request => {\n try {\n console.log('Request failed:')\n console.log(`- URL: ${request.url()}`)\n console.log(`- Method: ${request.method()}`)\n console.log(`- Failure Text: ${request.failure()?.errorText}`)\n console.log(`- Headers:`, request.headers())\n\n if (request.postData()) {\n console.log(`- Post Data: ${request.postData()}`)\n }\n } catch (error) {\n console.error('Error in requestfailed handler:', error)\n }\n })\n }\n\n async applyCookiesAndVerifySession(page, cookies, loginInfo) {\n await page.setCookie(...cookies)\n await page.reload({ waitUntil: 'networkidle2', timeout: loginInfo.timeout })\n\n if (loginInfo.loginRequired && loginInfo.loginSelectors.successSelector) {\n const success = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.successSelector\n )\n if (!success) {\n throw new Error('Session invalid, login required')\n }\n }\n }\n\n async performLogin(page, uri, loginInfo) {\n for (let attempt = 1; attempt <= loginInfo.retries; attempt++) {\n try {\n await page.goto(`${uri}${loginInfo.loginPagePath}`, { waitUntil: 'networkidle2', timeout: loginInfo.timeout })\n\n const usernameInput = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.usernameSelector\n )\n const passwordInput = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.passwordSelector\n )\n const submitButton = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.submitSelector\n )\n\n if (!usernameInput || !passwordInput || !submitButton) {\n throw new Error('Failed to locate input elements in shadow DOM')\n }\n\n await usernameInput.type(loginInfo.username)\n await passwordInput.type(loginInfo.password)\n\n var loginApiUrl =\n loginInfo.loginApiUrl ||\n (await page.evaluate(button => {\n const form = button.closest('form')\n return form ? form.action : null\n }, submitButton))\n\n if (loginApiUrl && !loginApiUrl.startsWith('http')) {\n loginApiUrl = `${uri}${loginApiUrl}`\n }\n\n if (!loginApiUrl) {\n throw new Error('โŒ Unable to detect login API URL!')\n }\n\n console.log('โœ… Detected login API URL:', loginApiUrl)\n\n const [response] = await Promise.all([\n page.waitForResponse(response => {\n const url = response.url()\n const method = response.request().method()\n\n return url === loginApiUrl && method === 'POST' && [200, 201, 204, 302, 304].includes(response.status())\n }),\n page.evaluate(button => button.click(), submitButton),\n page.waitForNavigation({ waitUntil: 'networkidle2', timeout: loginInfo.timeout }) // ๋กœ๊ทธ์ธ ํ›„ ๋ฆฌ๋””๋ ‰์…˜ ๊ฐ์ง€\n ])\n\n if (response) {\n const status = response.status()\n if (status >= 200 && status < 400) {\n ConnectionManager.logger.info(`Login successful with status code: ${status}`)\n return\n } else if (status >= 400) {\n throw new Error(`Login failed with status code: ${status}`)\n }\n } else {\n throw new Error('No response received during login')\n }\n\n if (loginInfo.loginSelectors.successSelector) {\n const success = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.successSelector\n )\n if (!success) {\n throw new Error('Login failed: Success selector not found')\n }\n }\n } catch (error) {\n ConnectionManager.logger.warn(`Login attempt ${attempt} failed:`, error)\n\n try {\n await page.screenshot({ path: `logs/login-failure-attempt-${attempt}.png` })\n } catch (error) {\n ConnectionManager.logger.error('Failed to capture screenshot:', error)\n }\n\n if (attempt === loginInfo.retries) {\n throw new Error(`Login failed after ${loginInfo.retries} attempts`)\n }\n }\n }\n }\n\n async resolveShadowDom(page, shadowSelectors, targetSelector) {\n let context\n\n if (!shadowSelectors || shadowSelectors.length === 0) {\n // No Shadow DOM path; use document root as the context\n context = page.mainFrame() // Puppeteer uses frames to represent document\n return context.$(targetSelector) // Search directly in the document root\n }\n\n context = page // Start with the page as the context\n for (const selector of shadowSelectors) {\n const shadowHost = await context.$(selector)\n if (!shadowHost) {\n throw new Error(`Shadow host not found: ${selector}`)\n }\n context = await page.evaluateHandle(host => host.shadowRoot, shadowHost)\n }\n return context.evaluateHandle((shadowRoot, selector) => shadowRoot.querySelector(selector), targetSelector)\n }\n\n async disconnect(connection) {\n try {\n // ์—ฐ๊ฒฐ ํ•ด์ œ ์ „ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ ๋กœ๊ทธ\n ConnectionManager.logger.info(`Starting disconnect process for connection: ${connection.name}`)\n \n // ํ’€ ์ƒํƒœ ํ™•์ธ (์ •๋ณด์„ฑ ๋กœ๊น…)\n try {\n const pool = getHeadlessPool()\n ConnectionManager.logger.info(`Pool status before disconnect - available resources exist: ${!!pool}`)\n } catch (poolError) {\n ConnectionManager.logger.warn(`Could not access pool during disconnect: ${poolError.message}`)\n }\n\n ConnectionManager.removeConnectionInstance(connection)\n ConnectionManager.logger.info(`headless-connector connection(${connection.name}) is disconnected`)\n } catch (error) {\n ConnectionManager.logger.error(`Error disconnecting headless-connector connection(${connection.name}):`, error)\n // Still try to remove the connection instance even if cleanup failed\n try {\n ConnectionManager.removeConnectionInstance(connection)\n } catch (removeError) {\n ConnectionManager.logger.error(`Failed to remove connection instance ${connection.name}:`, removeError)\n }\n }\n }\n\n get parameterSpec() {\n return [\n {\n type: 'string',\n name: 'username',\n label: 'username',\n useDomainAttribute: true\n },\n {\n type: 'secret',\n name: 'password',\n label: 'password',\n useDomainAttribute: true\n },\n {\n type: 'string',\n name: 'loginPagePath',\n label: 'login-page-path'\n },\n {\n type: 'string',\n name: 'loginApiUrl',\n label: 'login-api-url'\n },\n {\n type: 'string',\n name: 'usernameSelector',\n label: 'username-selector'\n },\n {\n type: 'string',\n name: 'passwordSelector',\n label: 'password-selector'\n },\n {\n type: 'string',\n name: 'submitSelector',\n label: 'submit-selector'\n },\n {\n type: 'string',\n name: 'successSelector',\n label: 'success-selector'\n },\n {\n type: 'string',\n name: 'shadowDomSelectors',\n label: 'shadow-dom-selectors'\n },\n {\n type: 'number',\n name: 'timeout',\n label: 'timeout',\n value: 15000\n },\n {\n type: 'number',\n name: 'retries',\n label: 'maximum-retries',\n value: 3\n }\n ]\n }\n\n get taskPrefixes() {\n return ['headless']\n }\n\n get description() {\n return 'Headless Pool Connector with login capabilities'\n }\n\n get help() {\n return 'integration/connector/headless-connector'\n }\n}\n\nConnectionManager.registerConnector('headless-connector', new HeadlessConnector())\n\nfunction isCookieValid(cookies: any[]): boolean {\n if (!cookies || cookies.length === 0) return false\n const now = Date.now() / 1000 // Current time in seconds\n return cookies.some((cookie: any) => cookie.expires && cookie.expires > now)\n}\n"]}
1
+ {"version":3,"file":"headless-connector.js","sourceRoot":"","sources":["../../../server/engine/connector/headless-connector.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionManager } from '../connection-manager'\nimport { Connector } from '../types'\nimport { getHeadlessPool, getPoolStats } from '../resource-pool/headless-pool'\nimport { Browser, Page } from 'puppeteer'\n\n/*\n Functionality of the headless-connector:\n - Provides a mechanism to acquire an active session page.\n - Performs login when necessary to obtain valid cookies.\n - Applies these cookies to the page for session management.\n - Pages are acquired from the `headlessPool`, which manages browser instances.\n - During the login process, pages from the pool are used for actions like form filling and navigation.\n - Valid cookies are saved after login and reused for subsequent page acquisitions.\n - Users must explicitly release the page after use through the `releasePage` method.\n - Released pages are returned to the `headlessPool` for reuse.\n*/\n\nexport class HeadlessConnector implements Connector {\n /**\n * ์™ธ๋ถ€ ์‚ฌ์ดํŠธ ๋กœ๊ทธ์ธ ์„ธ์…˜ ๋ณด์œ  โ€” ๊ฐ™์€ connection name ์˜ ๋™์‹œ acquireSessionPage\n * ํ˜ธ์ถœ์ด ๊ฐ™์€ ์™ธ๋ถ€ ๊ณ„์ • ์„ธ์…˜์„ ์„œ๋กœ invalidate ํ•˜์ง€ ์•Š๋„๋ก ConnectionManager ๊ฐ€\n * mutex ์ง๋ ฌํ™”. ์ƒ์† connector (allbaro, kiscon ๋“ฑ) ์ž๋™ ์ ์šฉ.\n */\n sessionExclusive = true\n\n /**\n * ์ž์‹ ๋„๋ฉ”์ธ์ด ๋ถ€๋ชจ์˜ Connection ์ •์˜๋ฅผ inherit ํ•  ๋•Œ ์ž์‹๋ณ„ ์ƒˆ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ.\n * cookies/์„ธ์…˜ยท์ž๊ฒฉ์ฆ๋ช… ๊ฒฉ๋ฆฌ. ํ—ค๋“œ๋ฆฌ์Šค ์‚ฌ์ดํŠธ connector ๋Š” ์™ธ๋ถ€ ์ž๊ฒฉ์ฆ๋ช…์ด\n * ์ž์‹ (ํ…Œ๋„ŒํŠธ) ๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ISOLATE ๊ฐ€ ์ž์—ฐ default.\n */\n inheritanceMode = 'isolate' as const\n\n async ready(connectionConfigs) {\n await Promise.all(connectionConfigs.map(this.connect.bind(this)))\n ConnectionManager.logger.info('headless-connector connections are ready')\n }\n\n async connect(connection) {\n const {\n endpoint: uri = '1',\n params: {\n username = '',\n password = '',\n loginPagePath = '/login',\n loginApiUrl = null,\n usernameSelector = '#username',\n passwordSelector = '#password',\n submitSelector = '#submit',\n successSelector = null,\n shadowDomSelectors = '', // Comma separated shadow DOM selectors\n timeout = 15000, // Default timeout for operations\n retries = 3, // Default number of retries for login or page actions\n // ์ฟ ํ‚ค ์บ์‹œ ์žฌ์‚ฌ์šฉ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋งค acquireSessionPage ๋งˆ๋‹ค ๋กœ๊ทธ์ธํ•˜๋„๋ก ๊ฐ•์ œ.\n // ์„œ๋ฒ„ ์„ธ์…˜ ๋งŒ๋ฃŒ๊ฐ€ ์žฆ๊ฑฐ๋‚˜ ๊ฒ€์ฆ์ด ๋น„์‹ผ ์‚ฌ์ดํŠธ(์˜ˆ: ์˜ฌ๋ฐ”๋กœ) ์—์„œ ์‚ฌ์šฉ.\n forceLogin = false\n } = {}\n } = connection\n\n const loginInfo = {\n loginRequired: Boolean(username), // Determine if login is required\n forceLogin: Boolean(forceLogin),\n username,\n password,\n loginPagePath,\n loginApiUrl,\n timeout,\n retries,\n loginSelectors: {\n usernameSelector,\n passwordSelector,\n submitSelector,\n successSelector,\n shadowDomSelectors: shadowDomSelectors\n .split(',')\n .map(selector => selector.trim())\n .filter(Boolean)\n }\n }\n\n async function acquireBrowser() {\n try {\n const pool = getHeadlessPool()\n \n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋””๋ฒ„๊น…์šฉ)\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats before acquire - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats:', statsError)\n }\n \n const browser = await pool.acquire()\n ConnectionManager.logger.info('Browser acquired successfully from pool')\n return browser\n } catch (error) {\n ConnectionManager.logger.error('Failed to acquire browser from pool:', error)\n \n // ํ’€ ์ƒํƒœ ๋กœ๊น…์œผ๋กœ ๋””๋ฒ„๊น… ๋„์›€\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.error(`Pool stats during acquire error - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}, max: ${stats.max}`)\n } catch (statsError) {\n ConnectionManager.logger.error('Failed to get pool stats during error:', statsError)\n }\n \n throw error\n }\n }\n\n async function releaseBrowser(browser: Browser) {\n if (!browser) {\n ConnectionManager.logger.warn('Attempted to release null/undefined browser')\n return\n }\n\n try {\n // ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„์ง ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ\n if (!browser.isConnected()) {\n ConnectionManager.logger.warn('Attempted to release disconnected browser')\n return\n }\n\n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋ฆด๋ฆฌ์ฆˆ ์ „)\n try {\n const statsBefore = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats before release - borrowed: ${statsBefore.borrowed}, available: ${statsBefore.available}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats before release:', statsError)\n }\n\n const pool = getHeadlessPool()\n await pool.release(browser)\n ConnectionManager.logger.info('Browser successfully released to pool')\n \n // Pool ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง (๋ฆด๋ฆฌ์ฆˆ ํ›„)\n try {\n const statsAfter = getPoolStats()\n ConnectionManager.logger.debug(`Pool stats after release - borrowed: ${statsAfter.borrowed}, available: ${statsAfter.available}`)\n } catch (statsError) {\n ConnectionManager.logger.warn('Failed to get pool stats after release:', statsError)\n }\n } catch (error) {\n ConnectionManager.logger.error('Failed to release browser to pool:', error)\n \n // ์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ํ’€ ์ƒํƒœ ๋กœ๊น…\n try {\n const stats = getPoolStats()\n ConnectionManager.logger.error(`Pool stats during release error - borrowed: ${stats.borrowed}, available: ${stats.available}, pending: ${stats.pending}`)\n } catch (statsError) {\n ConnectionManager.logger.error('Failed to get pool stats during release error:', statsError)\n }\n \n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser && browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser after pool release failure:', forceCloseError)\n }\n }\n }\n\n ConnectionManager.addConnectionInstance(connection, {\n endpoint: connection.endpoint,\n params: connection.params,\n acquireSessionPage: async () => {\n const browser = await acquireBrowser()\n let page\n let cookies = connection.cookies\n\n try {\n page = await browser.newPage()\n await this.setupPage(page, uri, timeout)\n\n if (loginInfo.loginRequired) {\n if (loginInfo.forceLogin) {\n // ๋งค๋ฒˆ ์ƒˆ๋กœ ๋กœ๊ทธ์ธ โ€” ์ฟ ํ‚คยท์„ธ์…˜ ์žฌ์‚ฌ์šฉ ๊ฒ€์ฆ ๋ชจ๋‘ ๊ฑด๋„ˆ๋œ€.\n // ์„ธ์…˜์ด ์„œ๋ฒ„์ธก์—์„œ ์ž์ฃผ ๋งŒ๋ฃŒ๋˜๋Š” ์‚ฌ์ดํŠธ ์šฉ๋„.\n ConnectionManager.logger.info('forceLogin=true โ€” skipping cookie reuse, performing fresh login')\n connection.cookies = undefined\n await this.performLogin(page, uri, loginInfo)\n cookies = await page.cookies()\n connection.cookies = cookies\n } else {\n // ๋จผ์ € ๊ธฐ๋ณธ ํŽ˜์ด์ง€๋กœ ์ด๋™\n await page.goto(uri, { waitUntil: 'networkidle2', timeout })\n\n // ํ˜„์žฌ ์„ธ์…˜์˜ Authorization ํ—ค๋” ํ™•์ธ\n const headers = await page.evaluate(() => {\n return fetch(window.location.href, { method: 'GET' })\n .then(response => response.headers.get('Authorization'))\n .catch(() => null)\n })\n\n if (headers) {\n ConnectionManager.logger.info('User is already logged in, skipping login process.')\n return page\n }\n\n if (cookies && isCookieValid(cookies)) {\n await this.applyCookiesAndVerifySession(page, cookies, loginInfo)\n return page\n }\n\n await this.performLogin(page, uri, loginInfo)\n cookies = await page.cookies()\n connection.cookies = cookies\n }\n } else {\n // ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ๊ธฐ๋ณธ ํŽ˜์ด์ง€๋กœ ์ด๋™\n await page.goto(uri, { waitUntil: 'networkidle2', timeout })\n }\n\n return page\n } catch (error) {\n ConnectionManager.logger.error('Failed to acquire session page:', error)\n \n // CRITICAL: ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ํ™•์‹คํ•œ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ\n if (page) {\n try {\n await page.close()\n ConnectionManager.logger.info('Page closed during acquireSessionPage error handling')\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page during acquireSessionPage error:', closeError)\n }\n }\n \n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released during acquireSessionPage error handling')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser during acquireSessionPage error:', releaseError)\n }\n \n throw error\n }\n },\n releasePage: async (page: Page) => {\n try {\n if (page && !page.isClosed()) {\n const browser = page.browser()\n \n // ํŽ˜์ด์ง€๋ฅผ ๋จผ์ € ๋‹ซ๊ธฐ\n try {\n await page.close()\n ConnectionManager.logger.info('Page closed successfully')\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page:', closeError)\n }\n \n // ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ’€์— ๋ฐ˜ํ™˜\n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released successfully')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser:', releaseError)\n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser && browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser:', forceCloseError)\n }\n }\n }\n } catch (error) {\n ConnectionManager.logger.error('Critical error in releasePage:', error)\n }\n },\n // ์„ธ์…˜ ํšŒ๋ณต์„ ์œ„ํ•œ ์žฌ๋กœ๊ทธ์ธ ๋ฉ”์„œ๋“œ\n reAuthenticateSession: async () => {\n ConnectionManager.logger.info(`Re-authenticating session for connection: ${connection.name}`)\n \n let browser = null\n let page = null\n\n try {\n browser = await acquireBrowser()\n page = await browser.newPage()\n await this.setupPage(page, uri, loginInfo.timeout)\n \n if (loginInfo.loginRequired) {\n await this.performLogin(page, uri, loginInfo)\n const newCookies = await page.cookies()\n connection.cookies = newCookies\n ConnectionManager.logger.info(`Session re-authenticated successfully for connection: ${connection.name}`)\n }\n \n // CRITICAL: ํŽ˜์ด์ง€์™€ ํ•จ๊ป˜ ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ •ํ™•ํ•œ ๋ฆด๋ฆฌ์ฆˆ ์ถ”์ \n return {\n page,\n browser,\n requiresManualRelease: true // ์ˆ˜๋™ ๋ฆด๋ฆฌ์ฆˆ ํ•„์š” ํ‘œ์‹œ\n }\n } catch (error) {\n ConnectionManager.logger.error(`Failed to re-authenticate session for connection: ${connection.name}`, error)\n \n // ์—๋Ÿฌ ์‹œ ํ™•์‹คํ•œ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ\n if (page) {\n try {\n if (!page.isClosed()) {\n await page.close()\n ConnectionManager.logger.info('Page closed during reauth error handling')\n }\n } catch (closeError) {\n ConnectionManager.logger.error('Failed to close page during reauth error:', closeError)\n }\n }\n \n if (browser) {\n try {\n await releaseBrowser(browser)\n ConnectionManager.logger.info('Browser released during reauth error handling')\n } catch (releaseError) {\n ConnectionManager.logger.error('Failed to release browser during reauth error:', releaseError)\n // ํ’€ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ ๋ธŒ๋ผ์šฐ์ € ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„\n try {\n if (browser.isConnected()) {\n await browser.close()\n ConnectionManager.logger.warn('Forcibly closed browser during reauth error due to pool release failure')\n }\n } catch (forceCloseError) {\n ConnectionManager.logger.error('Failed to force close browser during reauth error:', forceCloseError)\n }\n }\n }\n \n throw error\n }\n },\n // ์„ธ์…˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ\n validateSession: async (page: Page) => {\n try {\n if (!loginInfo.loginRequired) {\n return true\n }\n\n // ํŽ˜์ด์ง€๊ฐ€ ๋‹ซํ˜”๊ฑฐ๋‚˜ ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง„ ๊ฒฝ์šฐ\n if (!page || page.isClosed()) {\n ConnectionManager.logger.warn(`Page is closed or null for connection: ${connection.name}`)\n return false\n }\n\n // URL ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ ๋ฆฌ๋””๋ ‰์…˜ ์ฒดํฌ\n let currentUrl: string\n try {\n currentUrl = page.url()\n } catch (urlError) {\n ConnectionManager.logger.warn(`Cannot get page URL for connection: ${connection.name}`, urlError)\n return false\n }\n \n if (currentUrl.includes(loginInfo.loginPagePath) || \n currentUrl.includes('/login') || \n currentUrl.includes('/signin') || \n currentUrl.includes('/auth')) {\n ConnectionManager.logger.info(`Redirected to login page: ${currentUrl}`)\n return false\n }\n\n // ๋กœ๊ทธ์ธ ํผ ์š”์†Œ ๊ธฐ๋ฐ˜ ์ฒดํฌ\n const needsLogin = await page.evaluate(() => {\n try {\n // ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ํŠน์ • ์š”์†Œ๋“ค์ด ์žˆ๋Š”์ง€ ํ™•์ธ\n const loginIndicators = ['#username', '#password', '.login-form', '[type=\"password\"]']\n return loginIndicators.some(selector => {\n const element = document.querySelector(selector) as HTMLElement\n return element && element.offsetParent !== null // ๋ณด์ด๋Š” ์š”์†Œ๋งŒ ์ฒดํฌ\n })\n } catch (evalError) {\n return true // ์—๋Ÿฌ ์‹œ ์•ˆ์ „ํ•˜๊ฒŒ ์žฌ๋กœ๊ทธ์ธ ํ•„์š”๋กœ ๊ฐ„์ฃผ\n }\n })\n\n // ์ถ”๊ฐ€ ์„ธ์…˜ ๊ฒ€์ฆ: ๊ฐ„๋‹จํ•œ API ํ˜ธ์ถœ๋กœ ์ธ์ฆ ์ƒํƒœ ํ™•์ธ\n try {\n const testResponse = await page.evaluate(async () => {\n try {\n const response = await fetch(window.location.origin, { \n method: 'HEAD',\n credentials: 'include'\n })\n return {\n status: response.status,\n ok: response.ok\n }\n } catch (fetchError) {\n return { status: 0, ok: false }\n }\n })\n \n // ์ธ์ฆ์ด ํ•„์š”ํ•œ ์—”๋“œํฌ์ธํŠธ์—์„œ 401/403 ๋ฐ˜ํ™˜์‹œ ์„ธ์…˜ ๋ฌดํšจ\n if (testResponse.status === 401 || testResponse.status === 403) {\n ConnectionManager.logger.info(`Authentication failed with status ${testResponse.status} for connection: ${connection.name}`)\n return false\n }\n } catch (apiTestError) {\n ConnectionManager.logger.warn(`Session API test failed for connection: ${connection.name}`, apiTestError)\n // API ํ…Œ์ŠคํŠธ ์‹คํŒจ๋Š” ์„ธ์…˜ ๋ฌดํšจ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š์Œ (๋„คํŠธ์›Œํฌ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์Œ)\n }\n\n return !needsLogin\n } catch (error) {\n ConnectionManager.logger.warn(`Session validation failed for connection: ${connection.name}`, error)\n return false\n }\n },\n acquireBrowser,\n releaseBrowser\n })\n\n ConnectionManager.logger.info(\n `headless-connector connection(${connection.name}:${connection.endpoint}) is connected`\n )\n }\n\n async setupPage(page, uri, timeout) {\n await page.setRequestInterception(true)\n\n await page.setBypassCSP(true)\n\n await page.setUserAgent(\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.204 Safari/537.36'\n )\n\n await page.evaluateOnNewDocument(() => {\n Object.defineProperty(navigator, 'webdriver', { get: () => false })\n })\n\n await page.setExtraHTTPHeaders({\n 'Upgrade-Insecure-Requests': '0',\n 'accept-language': 'en-US,en;q=0.9',\n referer: uri\n })\n\n await page.setDefaultNavigationTimeout(timeout)\n\n page.on('console', async msg => {\n const args = await Promise.all(msg.args().map(arg => arg.jsonValue().catch(() => undefined)))\n\n if (args.some(a => a !== undefined)) {\n ConnectionManager.logger.info(`[browser ${msg.type()}]`, ...args.filter(a => a !== undefined))\n } else {\n const text = msg.text()\n if (text) ConnectionManager.logger.info(`[browser ${msg.type()}]`, text)\n }\n })\n\n page.on('request', request => {\n if (request.isInterceptResolutionHandled()) {\n return\n }\n\n const resourceType = request.resourceType()\n\n // fetch(), XMLHttpRequest ๋“ฑ์˜ API ํ˜ธ์ถœ์€ ํ•ญ์ƒ ํ—ˆ์šฉ\n if (resourceType === 'fetch' || resourceType === 'xhr') {\n request.continue()\n return\n }\n\n const headers = request.headers()\n if (headers['access-control-request-headers']) {\n const filteredHeaders = headers['access-control-request-headers']\n .split(',')\n .map(header => header.trim())\n .filter(header => header.toLowerCase() !== 'upgrade-insecure-requests')\n\n if (filteredHeaders.length > 0) {\n headers['access-control-request-headers'] = filteredHeaders.join(', ')\n } else {\n delete headers['access-control-request-headers']\n }\n }\n\n if (headers['upgrade-insecure-requests']) {\n delete headers['upgrade-insecure-requests']\n }\n\n // ์ด๋ฏธ์ง€, ์Šคํƒ€์ผ์‹œํŠธ, ํฐํŠธ๋Š” ์ฐจ๋‹จํ•˜๋˜ API ์š”์ฒญ์€ ํ—ˆ์šฉ\n if (['image', 'stylesheet', 'font'].includes(resourceType)) {\n request.abort()\n } else {\n request.continue()\n }\n })\n\n page.on('requestfailed', request => {\n try {\n // ์ •์  ๋ฆฌ์†Œ์Šค(์ด๋ฏธ์ง€ยทํฐํŠธยทCSS ๋“ฑ) ์˜ ์‹คํŒจ๋Š” ๋กœ๊ทธ์ธ ํ๋ฆ„๊ณผ ๋ฌด๊ด€ํ•œ ์†Œ์Œ์ด๋ฏ€๋กœ ๋ฌด์‹œ.\n // document / xhr / fetch ๊ฐ™์€ ์˜๋ฏธ์žˆ๋Š” ์š”์ฒญ ์‹คํŒจ๋งŒ ์ถœ๋ ฅ.\n const type = request.resourceType()\n const NOISY_TYPES = new Set(['image', 'font', 'stylesheet', 'media', 'manifest', 'other'])\n if (NOISY_TYPES.has(type)) return\n\n // ์ผ๋ถ€ ์‚ฌ์ดํŠธ์˜ ์ •์  ์ž์›์ด ๋‹ค๋ฅธ type ์œผ๋กœ ์žกํž ์ˆ˜ ์žˆ์–ด ํ™•์žฅ์ž ๊ธฐ๋ฐ˜ ๋ณด๊ฐ• ํ•„ํ„ฐ.\n const url = request.url()\n if (/\\.(png|jpe?g|gif|webp|svg|ico|woff2?|ttf|otf|eot|css|map)(\\?|$)/i.test(url)) return\n\n console.warn(\n `[headless] request failed (type=${type}): ${request.method()} ${url} โ€” ${request.failure()?.errorText}`\n )\n } catch (error) {\n console.error('Error in requestfailed handler:', error)\n }\n })\n }\n\n async applyCookiesAndVerifySession(page, cookies, loginInfo) {\n await page.setCookie(...cookies)\n await page.reload({ waitUntil: 'networkidle2', timeout: loginInfo.timeout })\n\n if (loginInfo.loginRequired && loginInfo.loginSelectors.successSelector) {\n const success = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.successSelector\n )\n if (!success) {\n throw new Error('Session invalid, login required')\n }\n }\n }\n\n async performLogin(page, uri, loginInfo) {\n let lastError: Error | null = null\n for (let attempt = 1; attempt <= loginInfo.retries; attempt++) {\n try {\n await page.goto(`${uri}${loginInfo.loginPagePath}`, { waitUntil: 'networkidle2', timeout: loginInfo.timeout })\n\n const usernameInput = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.usernameSelector\n )\n const passwordInput = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.passwordSelector\n )\n const submitButton = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.submitSelector\n )\n\n if (!usernameInput || !passwordInput || !submitButton) {\n throw new Error(\n `Failed to locate login form elements ` +\n `(username=${!!usernameInput}, password=${!!passwordInput}, submit=${!!submitButton}). ` +\n `Selectors: username='${loginInfo.loginSelectors.usernameSelector}', ` +\n `password='${loginInfo.loginSelectors.passwordSelector}', ` +\n `submit='${loginInfo.loginSelectors.submitSelector}'. ` +\n `์‚ฌ์ดํŠธ ํผ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ โ€” Connection params ์˜ *Selector ๊ฐ’์„ ์‹ค์ œ ํผ์— ๋งž์ถฐ ๋ฎ์–ด์“ฐ์„ธ์š”.`\n )\n }\n\n await usernameInput.type(loginInfo.username)\n await passwordInput.type(loginInfo.password)\n\n var loginApiUrl =\n loginInfo.loginApiUrl ||\n (await page.evaluate(button => {\n const form = button.closest('form')\n return form ? form.action : null\n }, submitButton))\n\n if (loginApiUrl && !loginApiUrl.startsWith('http')) {\n loginApiUrl = `${uri}${loginApiUrl}`\n }\n\n if (!loginApiUrl) {\n throw new Error('โŒ Unable to detect login API URL!')\n }\n\n console.log('โœ… Detected login API URL:', loginApiUrl)\n\n const [response] = await Promise.all([\n page.waitForResponse(response => {\n const url = response.url()\n const method = response.request().method()\n\n return url === loginApiUrl && method === 'POST' && [200, 201, 204, 302, 304].includes(response.status())\n }),\n page.evaluate(button => button.click(), submitButton),\n page.waitForNavigation({ waitUntil: 'networkidle2', timeout: loginInfo.timeout }) // ๋กœ๊ทธ์ธ ํ›„ ๋ฆฌ๋””๋ ‰์…˜ ๊ฐ์ง€\n ])\n\n if (response) {\n const status = response.status()\n if (status >= 200 && status < 400) {\n ConnectionManager.logger.info(`Login successful with status code: ${status}`)\n return\n } else if (status >= 400) {\n throw new Error(`Login failed with status code: ${status}`)\n }\n } else {\n throw new Error('No response received during login')\n }\n\n if (loginInfo.loginSelectors.successSelector) {\n const success = await this.resolveShadowDom(\n page,\n loginInfo.loginSelectors.shadowDomSelectors,\n loginInfo.loginSelectors.successSelector\n )\n if (!success) {\n throw new Error('Login failed: Success selector not found')\n }\n }\n } catch (error: any) {\n lastError = error\n ConnectionManager.logger.warn(`Login attempt ${attempt} failed:`, error)\n\n try {\n await page.screenshot({ path: `logs/login-failure-attempt-${attempt}.png` })\n } catch (error) {\n ConnectionManager.logger.error('Failed to capture screenshot:', error)\n }\n\n if (attempt === loginInfo.retries) {\n throw new Error(\n `Login failed after ${loginInfo.retries} attempts โ€” last cause: ${lastError?.message || lastError}`\n )\n }\n }\n }\n }\n\n async resolveShadowDom(page, shadowSelectors, targetSelector) {\n let context\n\n if (!shadowSelectors || shadowSelectors.length === 0) {\n // No Shadow DOM path; use document root as the context.\n // XPath ์ง€์› โ€” puppeteer 22+ ์˜ ํ†ตํ•ฉ ์„ ํƒ์ž: `xpath/<expression>` prefix.\n // ์…€๋ ‰ํ„ฐ๊ฐ€ `//`, `(//`, `.//` ๋กœ ์‹œ์ž‘ํ•˜๋ฉด xpath/ ๋กœ ๊ฐ์‹ธ page.$ ์— ์ „๋‹ฌ.\n if (typeof targetSelector === 'string' && /^\\s*(\\(|\\/\\/|\\.\\/\\/)/.test(targetSelector)) {\n return await page.$('xpath/' + targetSelector.trim())\n }\n context = page.mainFrame() // Puppeteer uses frames to represent document\n return context.$(targetSelector) // CSS selector โ€” Search directly in the document root\n }\n\n context = page // Start with the page as the context\n for (const selector of shadowSelectors) {\n const shadowHost = await context.$(selector)\n if (!shadowHost) {\n throw new Error(`Shadow host not found: ${selector}`)\n }\n context = await page.evaluateHandle(host => host.shadowRoot, shadowHost)\n }\n return context.evaluateHandle((shadowRoot, selector) => shadowRoot.querySelector(selector), targetSelector)\n }\n\n async disconnect(connection) {\n try {\n // ์—ฐ๊ฒฐ ํ•ด์ œ ์ „ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ ๋กœ๊ทธ\n ConnectionManager.logger.info(`Starting disconnect process for connection: ${connection.name}`)\n \n // ํ’€ ์ƒํƒœ ํ™•์ธ (์ •๋ณด์„ฑ ๋กœ๊น…)\n try {\n const pool = getHeadlessPool()\n ConnectionManager.logger.info(`Pool status before disconnect - available resources exist: ${!!pool}`)\n } catch (poolError) {\n ConnectionManager.logger.warn(`Could not access pool during disconnect: ${poolError.message}`)\n }\n\n ConnectionManager.removeConnectionInstance(connection)\n ConnectionManager.logger.info(`headless-connector connection(${connection.name}) is disconnected`)\n } catch (error) {\n ConnectionManager.logger.error(`Error disconnecting headless-connector connection(${connection.name}):`, error)\n // Still try to remove the connection instance even if cleanup failed\n try {\n ConnectionManager.removeConnectionInstance(connection)\n } catch (removeError) {\n ConnectionManager.logger.error(`Failed to remove connection instance ${connection.name}:`, removeError)\n }\n }\n }\n\n get parameterSpec() {\n return [\n {\n type: 'string',\n name: 'username',\n label: 'username',\n useDomainAttribute: true\n },\n {\n type: 'secret',\n name: 'password',\n label: 'password',\n useDomainAttribute: true\n },\n {\n type: 'string',\n name: 'loginPagePath',\n label: 'login-page-path'\n },\n {\n type: 'string',\n name: 'loginApiUrl',\n label: 'login-api-url'\n },\n {\n type: 'string',\n name: 'usernameSelector',\n label: 'username-selector'\n },\n {\n type: 'string',\n name: 'passwordSelector',\n label: 'password-selector'\n },\n {\n type: 'string',\n name: 'submitSelector',\n label: 'submit-selector'\n },\n {\n type: 'string',\n name: 'successSelector',\n label: 'success-selector'\n },\n {\n type: 'string',\n name: 'shadowDomSelectors',\n label: 'shadow-dom-selectors'\n },\n {\n type: 'number',\n name: 'timeout',\n label: 'timeout',\n value: 15000\n },\n {\n type: 'number',\n name: 'retries',\n label: 'maximum-retries',\n value: 3\n }\n ]\n }\n\n get taskPrefixes() {\n return ['headless']\n }\n\n get description() {\n return 'Headless Pool Connector with login capabilities'\n }\n\n get help() {\n return 'integration/connector/headless-connector'\n }\n}\n\nConnectionManager.registerConnector('headless-connector', new HeadlessConnector())\n\nfunction isCookieValid(cookies: any[]): boolean {\n if (!cookies || cookies.length === 0) return false\n const now = Date.now() / 1000 // Current time in seconds\n return cookies.some((cookie: any) => cookie.expires && cookie.expires > now)\n}\n"]}
@@ -14,8 +14,27 @@ export declare function evaluateTemplate(template: string, scope: Record<string,
14
14
  *
15
15
  * Replaces the former SES `Compartment.evaluate(script)` pattern.
16
16
  *
17
- * @param script - The JavaScript source to execute
18
- * @param scope - An object whose keys become local variable names
17
+ * @param script - The JavaScript source to execute
18
+ * @param scope - An object whose keys become local variable names inside the script
19
+ * @param thisArg - Optional `this` binding. SES Compartment ์‹œ์ ˆ์˜ `this.X` ํŒจํ„ด
20
+ * ํ˜ธํ™˜์„ ์œ„ํ•ด ๋ณดํ†ต `scope` ์ž์ฒด๋ฅผ ๋„˜๊ธด๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด script ๋‚ด๋ถ€์—์„œ
21
+ * `X` ์ง์ ‘ ์ ‘๊ทผ๊ณผ `this.X` ๋‘˜ ๋‹ค ๋™์ผ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.
22
+ * thisArg ๋ฅผ scope ๋ณด๋‹ค ๋„“์€ ๊ฐ์ฒด๋กœ ๋„˜๊ธฐ๋ฉด platform internal ๊นŒ์ง€
23
+ * ๋…ธ์ถœ๋˜๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ.
19
24
  * @returns The result of the script evaluation
20
25
  */
21
- export declare function evaluateScript(script: string, scope: Record<string, any>): any;
26
+ export declare function evaluateScript(script: string, scope: Record<string, any>, thisArg?: any): any;
27
+ /**
28
+ * Object ์˜ string ๊ฐ’๋“ค์— ํ•œํ•ด evaluateTemplate ์„ ์ ์šฉํ•ด ๋ฐ˜ํ™˜.
29
+ *
30
+ * ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์˜ค์šฉ ํŒจํ„ด ํ•ด์†Œ์šฉ:
31
+ * `evaluateTemplate(step.params, data)` ์ฒ˜๋Ÿผ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋‚ด๋ถ€ `'`...`'`
32
+ * wrap ์— ์˜ํ•ด `"[object Object]"` ๊ฐ€ ๋ฐ˜ํ™˜๋˜์–ด ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์‚ฌ๋ผ์ง.
33
+ *
34
+ * ์ด ํ—ฌํผ๋Š” step.params ๊ฐ™์€ plain object ๋ฅผ ๋ฐ›์•„ ๊ฐ string ํ•„๋“œ๋ฅผ ๊ฐœ๋ณ„ template
35
+ * ์œผ๋กœ ํ‰๊ฐ€ํ•˜๊ณ , ๋น„-๋ฌธ์ž์—ด ํ•„๋“œ๋Š” ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.
36
+ *
37
+ * @param obj ์Šคํ… params ๋“ฑ ํ‰ํƒ„ object
38
+ * @param scope ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„ (์‹œ๋‚˜๋ฆฌ์˜ค data)
39
+ */
40
+ export declare function evaluateTemplateObject<T extends Record<string, any>>(obj: T | null | undefined, scope: Record<string, any>): T;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.evaluateTemplate = evaluateTemplate;
4
4
  exports.evaluateScript = evaluateScript;
5
+ exports.evaluateTemplateObject = evaluateTemplateObject;
5
6
  /**
6
7
  * Evaluate a template string with context variables using `new Function`.
7
8
  *
@@ -23,14 +24,52 @@ function evaluateTemplate(template, scope) {
23
24
  *
24
25
  * Replaces the former SES `Compartment.evaluate(script)` pattern.
25
26
  *
26
- * @param script - The JavaScript source to execute
27
- * @param scope - An object whose keys become local variable names
27
+ * @param script - The JavaScript source to execute
28
+ * @param scope - An object whose keys become local variable names inside the script
29
+ * @param thisArg - Optional `this` binding. SES Compartment ์‹œ์ ˆ์˜ `this.X` ํŒจํ„ด
30
+ * ํ˜ธํ™˜์„ ์œ„ํ•ด ๋ณดํ†ต `scope` ์ž์ฒด๋ฅผ ๋„˜๊ธด๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด script ๋‚ด๋ถ€์—์„œ
31
+ * `X` ์ง์ ‘ ์ ‘๊ทผ๊ณผ `this.X` ๋‘˜ ๋‹ค ๋™์ผ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.
32
+ * thisArg ๋ฅผ scope ๋ณด๋‹ค ๋„“์€ ๊ฐ์ฒด๋กœ ๋„˜๊ธฐ๋ฉด platform internal ๊นŒ์ง€
33
+ * ๋…ธ์ถœ๋˜๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ.
28
34
  * @returns The result of the script evaluation
29
35
  */
30
- function evaluateScript(script, scope) {
36
+ function evaluateScript(script, scope, thisArg) {
31
37
  const keys = Object.keys(scope);
32
38
  const values = keys.map(k => scope[k]);
33
39
  const fn = new Function(...keys, script);
34
- return fn(...values);
40
+ return thisArg !== undefined ? fn.call(thisArg, ...values) : fn(...values);
41
+ }
42
+ /**
43
+ * Object ์˜ string ๊ฐ’๋“ค์— ํ•œํ•ด evaluateTemplate ์„ ์ ์šฉํ•ด ๋ฐ˜ํ™˜.
44
+ *
45
+ * ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์˜ค์šฉ ํŒจํ„ด ํ•ด์†Œ์šฉ:
46
+ * `evaluateTemplate(step.params, data)` ์ฒ˜๋Ÿผ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋‚ด๋ถ€ `'`...`'`
47
+ * wrap ์— ์˜ํ•ด `"[object Object]"` ๊ฐ€ ๋ฐ˜ํ™˜๋˜์–ด ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์‚ฌ๋ผ์ง.
48
+ *
49
+ * ์ด ํ—ฌํผ๋Š” step.params ๊ฐ™์€ plain object ๋ฅผ ๋ฐ›์•„ ๊ฐ string ํ•„๋“œ๋ฅผ ๊ฐœ๋ณ„ template
50
+ * ์œผ๋กœ ํ‰๊ฐ€ํ•˜๊ณ , ๋น„-๋ฌธ์ž์—ด ํ•„๋“œ๋Š” ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.
51
+ *
52
+ * @param obj ์Šคํ… params ๋“ฑ ํ‰ํƒ„ object
53
+ * @param scope ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„ (์‹œ๋‚˜๋ฆฌ์˜ค data)
54
+ */
55
+ function evaluateTemplateObject(obj, scope) {
56
+ if (!obj || typeof obj !== 'object')
57
+ return obj;
58
+ const result = {};
59
+ for (const k of Object.keys(obj)) {
60
+ const v = obj[k];
61
+ if (typeof v === 'string' && v.indexOf('${') >= 0) {
62
+ try {
63
+ result[k] = evaluateTemplate(v, scope);
64
+ }
65
+ catch {
66
+ result[k] = v;
67
+ }
68
+ }
69
+ else {
70
+ result[k] = v;
71
+ }
72
+ }
73
+ return result;
35
74
  }
36
75
  //# sourceMappingURL=evaluate-template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-template.js","sourceRoot":"","sources":["../../server/engine/evaluate-template.ts"],"names":[],"mappings":";;AAUA,4CAKC;AAWD,wCAKC;AA/BD;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,KAA0B;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAA;IAC/D,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAA;AACtB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAAC,MAAc,EAAE,KAA0B;IACvE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;IACxC,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAA;AACtB,CAAC","sourcesContent":["/**\n * Evaluate a template string with context variables using `new Function`.\n *\n * Replaces the former SES `Compartment.evaluate('`' + tpl + '`')` pattern.\n * The template is evaluated as a JS template literal, so `${data.foo}` works.\n *\n * @param template - The raw template string (without surrounding back-ticks)\n * @param scope - An object whose keys become local variable names\n * @returns The interpolated string\n */\nexport function evaluateTemplate(template: string, scope: Record<string, any>): string {\n const keys = Object.keys(scope)\n const values = keys.map(k => scope[k])\n const fn = new Function(...keys, 'return (`' + template + '`)')\n return fn(...values)\n}\n\n/**\n * Evaluate an arbitrary script string with context variables using `new Function`.\n *\n * Replaces the former SES `Compartment.evaluate(script)` pattern.\n *\n * @param script - The JavaScript source to execute\n * @param scope - An object whose keys become local variable names\n * @returns The result of the script evaluation\n */\nexport function evaluateScript(script: string, scope: Record<string, any>): any {\n const keys = Object.keys(scope)\n const values = keys.map(k => scope[k])\n const fn = new Function(...keys, script)\n return fn(...values)\n}\n"]}
1
+ {"version":3,"file":"evaluate-template.js","sourceRoot":"","sources":["../../server/engine/evaluate-template.ts"],"names":[],"mappings":";;AAUA,4CAKC;AAgBD,wCAKC;AAeD,wDAmBC;AAtED;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,KAA0B;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAA;IAC/D,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAA;AACtB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,cAAc,CAAC,MAAc,EAAE,KAA0B,EAAE,OAAa;IACtF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAA;IACxC,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAA;AAC5E,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,sBAAsB,CACpC,GAAyB,EACzB,KAA0B;IAE1B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAQ,CAAA;IACpD,MAAM,MAAM,GAAwB,EAAE,CAAA;IACtC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,GAAI,GAAW,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,MAAM,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;YACf,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACf,CAAC;IACH,CAAC;IACD,OAAO,MAAW,CAAA;AACpB,CAAC","sourcesContent":["/**\n * Evaluate a template string with context variables using `new Function`.\n *\n * Replaces the former SES `Compartment.evaluate('`' + tpl + '`')` pattern.\n * The template is evaluated as a JS template literal, so `${data.foo}` works.\n *\n * @param template - The raw template string (without surrounding back-ticks)\n * @param scope - An object whose keys become local variable names\n * @returns The interpolated string\n */\nexport function evaluateTemplate(template: string, scope: Record<string, any>): string {\n const keys = Object.keys(scope)\n const values = keys.map(k => scope[k])\n const fn = new Function(...keys, 'return (`' + template + '`)')\n return fn(...values)\n}\n\n/**\n * Evaluate an arbitrary script string with context variables using `new Function`.\n *\n * Replaces the former SES `Compartment.evaluate(script)` pattern.\n *\n * @param script - The JavaScript source to execute\n * @param scope - An object whose keys become local variable names inside the script\n * @param thisArg - Optional `this` binding. SES Compartment ์‹œ์ ˆ์˜ `this.X` ํŒจํ„ด\n * ํ˜ธํ™˜์„ ์œ„ํ•ด ๋ณดํ†ต `scope` ์ž์ฒด๋ฅผ ๋„˜๊ธด๋‹ค โ€” ๊ทธ๋Ÿฌ๋ฉด script ๋‚ด๋ถ€์—์„œ\n * `X` ์ง์ ‘ ์ ‘๊ทผ๊ณผ `this.X` ๋‘˜ ๋‹ค ๋™์ผ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.\n * thisArg ๋ฅผ scope ๋ณด๋‹ค ๋„“์€ ๊ฐ์ฒด๋กœ ๋„˜๊ธฐ๋ฉด platform internal ๊นŒ์ง€\n * ๋…ธ์ถœ๋˜๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ.\n * @returns The result of the script evaluation\n */\nexport function evaluateScript(script: string, scope: Record<string, any>, thisArg?: any): any {\n const keys = Object.keys(scope)\n const values = keys.map(k => scope[k])\n const fn = new Function(...keys, script)\n return thisArg !== undefined ? fn.call(thisArg, ...values) : fn(...values)\n}\n\n/**\n * Object ์˜ string ๊ฐ’๋“ค์— ํ•œํ•ด evaluateTemplate ์„ ์ ์šฉํ•ด ๋ฐ˜ํ™˜.\n *\n * ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์˜ค์šฉ ํŒจํ„ด ํ•ด์†Œ์šฉ:\n * `evaluateTemplate(step.params, data)` ์ฒ˜๋Ÿผ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋‚ด๋ถ€ `'`...`'`\n * wrap ์— ์˜ํ•ด `\"[object Object]\"` ๊ฐ€ ๋ฐ˜ํ™˜๋˜์–ด ๋ชจ๋“  ํ•„๋“œ๊ฐ€ ์‚ฌ๋ผ์ง.\n *\n * ์ด ํ—ฌํผ๋Š” step.params ๊ฐ™์€ plain object ๋ฅผ ๋ฐ›์•„ ๊ฐ string ํ•„๋“œ๋ฅผ ๊ฐœ๋ณ„ template\n * ์œผ๋กœ ํ‰๊ฐ€ํ•˜๊ณ , ๋น„-๋ฌธ์ž์—ด ํ•„๋“œ๋Š” ๊ทธ๋Œ€๋กœ ๋‘”๋‹ค.\n *\n * @param obj ์Šคํ… params ๋“ฑ ํ‰ํƒ„ object\n * @param scope ๋ณ€์ˆ˜ ์Šค์ฝ”ํ”„ (์‹œ๋‚˜๋ฆฌ์˜ค data)\n */\nexport function evaluateTemplateObject<T extends Record<string, any>>(\n obj: T | null | undefined,\n scope: Record<string, any>\n): T {\n if (!obj || typeof obj !== 'object') return obj as T\n const result: Record<string, any> = {}\n for (const k of Object.keys(obj)) {\n const v = (obj as any)[k]\n if (typeof v === 'string' && v.indexOf('${') >= 0) {\n try {\n result[k] = evaluateTemplate(v, scope)\n } catch {\n result[k] = v\n }\n } else {\n result[k] = v\n }\n }\n return result as T\n}\n"]}
@@ -10,24 +10,28 @@ async function Script(step, context) {
10
10
  ${script}
11
11
  })();
12
12
  `;
13
+ // scope ๋ณ€์ˆ˜๋“ค โ€” script ๋‚ด๋ถ€์—์„œ ์ง์ ‘ ๋ณ€์ˆ˜ (data.foo) ๋˜๋Š” this.data.foo ๋‘˜ ๋‹ค ๊ฐ€๋Šฅ.
14
+ // SES Compartment ์‹œ์ ˆ์˜ this ์ ‘๊ทผ ํ˜ธํ™˜์„ฑ ๋ณต์›.
15
+ const scope = {
16
+ domain,
17
+ user,
18
+ data,
19
+ variables,
20
+ logger,
21
+ lng,
22
+ console,
23
+ Math,
24
+ JSON,
25
+ Date,
26
+ setTimeout,
27
+ setInterval,
28
+ clearTimeout,
29
+ clearInterval
30
+ };
13
31
  try {
14
32
  return {
15
- data: await (0, evaluate_template_1.evaluateScript)(scriptSource, {
16
- domain,
17
- user,
18
- data,
19
- variables,
20
- logger,
21
- lng,
22
- console,
23
- Math,
24
- JSON,
25
- Date,
26
- setTimeout,
27
- setInterval,
28
- clearTimeout,
29
- clearInterval
30
- })
33
+ // thisArg = scope โ†’ script ๋‚ด๋ถ€ this ๊ฐ€ scope ๊ฐ์ฒด. this.data === data.
34
+ data: await (0, evaluate_template_1.evaluateScript)(scriptSource, scope, scope)
31
35
  };
32
36
  }
33
37
  catch (err) {
@@ -45,7 +49,11 @@ Script.parameterSpec = [
45
49
  },
46
50
  styles: {
47
51
  flex: '1'
48
- }
52
+ },
53
+ description: '์‹œ๋‚˜๋ฆฌ์˜ค context ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋Š” JavaScript. ' +
54
+ '์‚ฌ์šฉ ๊ฐ€๋Šฅ: `domain`, `user`, `data`, `variables`, `logger`, `lng`, `console`, `Math`, `JSON`, `Date`, `setTimeout`/`setInterval`/`clearTimeout`/`clearInterval`. ' +
55
+ '์ง์ ‘ ๋ณ€์ˆ˜ (`data.foo`) ๋˜๋Š” this ์ ‘๊ทผ (`this.data.foo`) ๋‘˜ ๋‹ค ๋™์ž‘. ' +
56
+ '๋น„๋™๊ธฐ ์ฝ”๋“œ ๊ฐ€๋Šฅ (await ์‚ฌ์šฉ). ๋ฐ˜ํ™˜๊ฐ’์€ ๋‹ค์Œ step ์˜ `data` ๋กœ ์ „๋‹ฌ.'
49
57
  }
50
58
  ];
51
59
  Script.connectorFree = true;
@@ -1 +1 @@
1
- {"version":3,"file":"script.js","sourceRoot":"","sources":["../../../server/engine/task/script.ts"],"names":[],"mappings":";;AAAA,oDAA+C;AAC/C,4DAAqD;AAIrD,KAAK,UAAU,MAAM,CAAC,IAAe,EAAE,OAAgB;IACrD,MAAM,EACJ,MAAM,EAAE,EAAE,MAAM,EAAE,EACnB,GAAG,IAAI,CAAA;IAER,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAE9D,MAAM,YAAY,GAAG;;QAEf,MAAM;;GAEX,CAAA;IAED,IAAI,CAAC;QACH,OAAO;YACL,IAAI,EAAE,MAAM,IAAA,kCAAc,EAAC,YAAY,EAAE;gBACvC,MAAM;gBACN,IAAI;gBACJ,IAAI;gBACJ,SAAS;gBACT,MAAM;gBACN,GAAG;gBACH,OAAO;gBACP,IAAI;gBACJ,IAAI;gBACJ,IAAI;gBACJ,UAAU;gBACV,WAAW;gBACX,YAAY;gBACZ,aAAa;aACd,CAAC;SACH,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,aAAa,GAAG;IACrB;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE;YACR,QAAQ,EAAE,YAAY;YACtB,eAAe,EAAE,IAAI;SACtB;QACD,MAAM,EAAE;YACN,IAAI,EAAE,GAAG;SACV;KACF;CACF,CAAA;AAED,MAAM,CAAC,aAAa,GAAG,IAAI,CAAA;AAC3B,MAAM,CAAC,IAAI,GAAG,yBAAyB,CAAA;AAEvC,4BAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA","sourcesContent":["import { TaskRegistry } from '../task-registry'\nimport { evaluateScript } from '../evaluate-template'\nimport { InputStep } from '../../service/step/step-type'\nimport { Context } from '../types'\n\nasync function Script(step: InputStep, context: Context) {\n const {\n params: { script }\n } = step\n\n const { domain, user, data, variables, lng, logger } = context\n\n const scriptSource = `\n return (async () => {\n ${script}\n })();\n `\n\n try {\n return {\n data: await evaluateScript(scriptSource, {\n domain,\n user,\n data,\n variables,\n logger,\n lng,\n console,\n Math,\n JSON,\n Date,\n setTimeout,\n setInterval,\n clearTimeout,\n clearInterval\n })\n }\n } catch (err) {\n throw new Error(`Script execution failed: ${err.message}`)\n }\n}\n\nScript.parameterSpec = [\n {\n type: 'textarea',\n name: 'script',\n label: 'script',\n property: {\n language: 'javascript',\n showLineNumbers: true\n },\n styles: {\n flex: '1'\n }\n }\n]\n\nScript.connectorFree = true\nScript.help = 'integration/task/script'\n\nTaskRegistry.registerTaskHandler('script', Script)\n"]}
1
+ {"version":3,"file":"script.js","sourceRoot":"","sources":["../../../server/engine/task/script.ts"],"names":[],"mappings":";;AAAA,oDAA+C;AAC/C,4DAAqD;AAIrD,KAAK,UAAU,MAAM,CAAC,IAAe,EAAE,OAAgB;IACrD,MAAM,EACJ,MAAM,EAAE,EAAE,MAAM,EAAE,EACnB,GAAG,IAAI,CAAA;IAER,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAE9D,MAAM,YAAY,GAAG;;QAEf,MAAM;;GAEX,CAAA;IAED,oEAAoE;IACpE,sCAAsC;IACtC,MAAM,KAAK,GAAG;QACZ,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,SAAS;QACT,MAAM;QACN,GAAG;QACH,OAAO;QACP,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,UAAU;QACV,WAAW;QACX,YAAY;QACZ,aAAa;KACd,CAAA;IAED,IAAI,CAAC;QACH,OAAO;YACL,mEAAmE;YACnE,IAAI,EAAE,MAAM,IAAA,kCAAc,EAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC;SACvD,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,aAAa,GAAG;IACrB;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE;YACR,QAAQ,EAAE,YAAY;YACtB,eAAe,EAAE,IAAI;SACtB;QACD,MAAM,EAAE;YACN,IAAI,EAAE,GAAG;SACV;QACD,WAAW,EACT,oCAAoC;YACpC,+JAA+J;YAC/J,0DAA0D;YAC1D,mDAAmD;KACtD;CACF,CAAA;AAED,MAAM,CAAC,aAAa,GAAG,IAAI,CAAA;AAC3B,MAAM,CAAC,IAAI,GAAG,yBAAyB,CAAA;AAEvC,4BAAY,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA","sourcesContent":["import { TaskRegistry } from '../task-registry'\nimport { evaluateScript } from '../evaluate-template'\nimport { InputStep } from '../../service/step/step-type'\nimport { Context } from '../types'\n\nasync function Script(step: InputStep, context: Context) {\n const {\n params: { script }\n } = step\n\n const { domain, user, data, variables, lng, logger } = context\n\n const scriptSource = `\n return (async () => {\n ${script}\n })();\n `\n\n // scope ๋ณ€์ˆ˜๋“ค โ€” script ๋‚ด๋ถ€์—์„œ ์ง์ ‘ ๋ณ€์ˆ˜ (data.foo) ๋˜๋Š” this.data.foo ๋‘˜ ๋‹ค ๊ฐ€๋Šฅ.\n // SES Compartment ์‹œ์ ˆ์˜ this ์ ‘๊ทผ ํ˜ธํ™˜์„ฑ ๋ณต์›.\n const scope = {\n domain,\n user,\n data,\n variables,\n logger,\n lng,\n console,\n Math,\n JSON,\n Date,\n setTimeout,\n setInterval,\n clearTimeout,\n clearInterval\n }\n\n try {\n return {\n // thisArg = scope โ†’ script ๋‚ด๋ถ€ this ๊ฐ€ scope ๊ฐ์ฒด. this.data === data.\n data: await evaluateScript(scriptSource, scope, scope)\n }\n } catch (err) {\n throw new Error(`Script execution failed: ${err.message}`)\n }\n}\n\nScript.parameterSpec = [\n {\n type: 'textarea',\n name: 'script',\n label: 'script',\n property: {\n language: 'javascript',\n showLineNumbers: true\n },\n styles: {\n flex: '1'\n },\n description:\n '์‹œ๋‚˜๋ฆฌ์˜ค context ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋Š” JavaScript. ' +\n '์‚ฌ์šฉ ๊ฐ€๋Šฅ: `domain`, `user`, `data`, `variables`, `logger`, `lng`, `console`, `Math`, `JSON`, `Date`, `setTimeout`/`setInterval`/`clearTimeout`/`clearInterval`. ' +\n '์ง์ ‘ ๋ณ€์ˆ˜ (`data.foo`) ๋˜๋Š” this ์ ‘๊ทผ (`this.data.foo`) ๋‘˜ ๋‹ค ๋™์ž‘. ' +\n '๋น„๋™๊ธฐ ์ฝ”๋“œ ๊ฐ€๋Šฅ (await ์‚ฌ์šฉ). ๋ฐ˜ํ™˜๊ฐ’์€ ๋‹ค์Œ step ์˜ `data` ๋กœ ์ „๋‹ฌ.'\n }\n]\n\nScript.connectorFree = true\nScript.help = 'integration/task/script'\n\nTaskRegistry.registerTaskHandler('script', Script)\n"]}
@@ -9,6 +9,38 @@ export interface Connector {
9
9
  taskPrefixes?: string[];
10
10
  description?: string;
11
11
  help?: string;
12
+ /**
13
+ * ์™ธ๋ถ€ ์„ธ์…˜ (๋กœ๊ทธ์ธ ์ƒํƒœ) ์„ ๋ณด์œ ํ•œ connector ์ธ์ง€ ์—ฌ๋ถ€.
14
+ * true ์ด๋ฉด ConnectionManager.withSession ์ด connection name ๋‹จ์œ„ mutex ๋กœ
15
+ * ๋™์‹œ acquireSessionPage ํ˜ธ์ถœ์„ ์ง๋ ฌํ™” โ€” ๊ฐ™์€ ์™ธ๋ถ€ ๊ณ„์ •์˜ ์ค‘๋ณต ๋กœ๊ทธ์ธ ์ถฉ๋Œ ๋ฐฉ์ง€.
16
+ *
17
+ * ๊ธฐ๋ณธ๊ฐ’ false (stateless ๋˜๋Š” ์ž์ฒด ์„ธ์…˜ ๊ด€๋ฆฌ). HeadlessConnector ๋“ฑ ๋กœ๊ทธ์ธ ์„ธ์…˜
18
+ * ๊ธฐ๋ฐ˜ connector ๊ฐ€ true ๋กœ ์„ ์–ธ.
19
+ */
20
+ sessionExclusive?: boolean;
21
+ /**
22
+ * ์ด connector ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด inheritance default โ€” ์ž์‹ ๋„๋ฉ”์ธ์ด ๋ถ€๋ชจ์˜ Connection
23
+ * ์ •์˜๋ฅผ inherit ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒŒ ์ž์—ฐ์ธ์ง€๋ฅผ connector ์ž‘์„ฑ์ž๊ฐ€ ์„ ์–ธ.
24
+ *
25
+ * ๊ฐ’์€ string literal 'isolate' | 'share' โ€” runtime ํ˜ธํ™˜์„ ์œ„ํ•ด string ์œผ๋กœ
26
+ * ๋น„๊ต (Connection.inheritanceMode column ์˜ ๊ฐ’๊ณผ ์ง์ ‘ ๋น„๊ต ๊ฐ€๋Šฅํ•˜๋„๋ก).
27
+ *
28
+ * **๊ฒฐ์ • ๊ฐ€์ด๋“œ** (connector ์ž‘์„ฑ์ž์šฉ):
29
+ * 1. ์™ธ๋ถ€ ์ž์›์ด ๋„๋ฉ”์ธ(ํ…Œ๋„ŒํŠธ)๋ณ„๋กœ ๋‹ค๋ฅธ identityยท์ž๊ฒฉ์ฆ๋ช…ยท์„ธ์…˜์ด ํ•„์š”ํ•œ๊ฐ€?
30
+ * - ์˜ˆ (stateful + per-tenant: ๋กœ๊ทธ์ธ connector, ํ…Œ๋„ŒํŠธ๋ณ„ DB pool) โ†’ 'isolate'
31
+ * - ์•„๋‹ˆ์˜ค (๊ณต์šฉ ์ž์›: ๋‹จ์ผ ๋ธŒ๋กœ์ปคยท์„œ๋ฒ„ / stateless API) โ†’ 'share'
32
+ *
33
+ * 2. ์ž์‹ ๋„๋ฉ”์ธ์ด ๋ถ€๋ชจ์˜ cookiesยท์„ธ์…˜ยทparams ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ด๋„ ๋˜๋Š”๊ฐ€?
34
+ * - ์•ˆ ๋จ (์ž๋ฃŒ ๊ฒฉ๋ฆฌยท์ž๊ฒฉ์ฆ๋ช… ๊ฒฉ๋ฆฌ ํ•„์š”) โ†’ 'isolate'
35
+ * - ๋จ (๋ชจ๋‘ ๊ฐ™์€ ์ž์› ๊ณต์œ ) โ†’ 'share'
36
+ *
37
+ * 3. ๋ช…์‹œ ์•ˆ ํ•˜๋ฉด framework ๊ฐ€ ISOLATE ํด๋ฐฑ (๊ฒฉ๋ฆฌ ์šฐ์„ ). ์ž์› ํšจ์œจ์ด ์ค‘์š”ํ•œ
38
+ * connector ์ž‘์„ฑ์ž๋Š” 'share' ๋ฅผ ๋ช…์‹œ ์„ ์–ธ.
39
+ *
40
+ * Connection.inheritanceMode ๊ฐ€ ๋ช…์‹œ๋˜๋ฉด ๊ทธ๊ฒƒ์ด ์šฐ์„ . ์šด์˜์ž๊ฐ€ ํŠน์ˆ˜ ์ผ€์ด์Šค๋ฅผ
41
+ * ์œ„ํ•ด connector default ๋ฅผ override ํ•  ์ˆ˜ ์žˆ์Œ.
42
+ */
43
+ inheritanceMode?: 'isolate' | 'share';
12
44
  }
13
45
  export type Context = {
14
46
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../server/engine/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Connection, PropertySpec, ScenarioInstance, ScenarioInstanceStatus, Step } from '../service'\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\nexport interface Connector {\n ready(connections: Connection[]): Promise<any>\n connect(connection: Connection): Promise<any>\n disconnect(connection: Connection): Promise<any>\n parameterSpec: PropertySpec[]\n taskPrefixes?: string[]\n description?: string\n help?: string\n}\n\nexport type Context = {\n /**\n * Represents the domain context.\n */\n domain: Domain\n\n /**\n * User information.\n */\n user: User\n\n /**\n * Language code, for example 'en', 'ko'.\n */\n lng: string\n\n /**\n * Flag to indicate if the IP is unsafe, can be undefined.\n */\n unsafeIP: boolean | undefined\n\n /**\n * List of prohibited privileges, can be undefined.\n */\n prohibitedPrivileges: { category: string; privilege: string }[] | undefined\n\n /**\n * Logger for logging purposes.\n */\n logger: any\n\n /**\n * Function to publish events or messages.\n */\n publish: Function\n\n /**\n * Function to load resources or data.\n */\n load: Function\n\n /**\n * Current status of the scenario instance.\n */\n state: ScenarioInstanceStatus\n\n /**\n * General data storage object.\n */\n data: any\n\n /**\n * Variables related to the context.\n */\n variables: Object\n\n /**\n * Local GraphQL client object.\n */\n client: any /* graphql local client */\n\n /**\n * Root object, can be used for various purposes.\n */\n root?: ScenarioInstance\n\n /**\n * Array of function closures.\n */\n closures: Function[]\n\n /**\n * Function to check the state.\n */\n checkState: Function\n\n /**\n * MQTT subscriber context object.\n */\n __mqtt_subscriber?: any\n\n /**\n * socket listener context object.\n */\n __socket_listener?: any\n\n /**\n * csv readline context object.\n */\n __csv_resources?: any\n}\n\nexport type TaskHandler = (\n step: Step,\n context: Context\n) => Promise<{\n next?: string\n state?: ScenarioInstanceStatus\n data?: any\n}>\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../server/engine/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Connection, PropertySpec, ScenarioInstance, ScenarioInstanceStatus, Step } from '../service'\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\nexport interface Connector {\n ready(connections: Connection[]): Promise<any>\n connect(connection: Connection): Promise<any>\n disconnect(connection: Connection): Promise<any>\n parameterSpec: PropertySpec[]\n taskPrefixes?: string[]\n description?: string\n help?: string\n /**\n * ์™ธ๋ถ€ ์„ธ์…˜ (๋กœ๊ทธ์ธ ์ƒํƒœ) ์„ ๋ณด์œ ํ•œ connector ์ธ์ง€ ์—ฌ๋ถ€.\n * true ์ด๋ฉด ConnectionManager.withSession ์ด connection name ๋‹จ์œ„ mutex ๋กœ\n * ๋™์‹œ acquireSessionPage ํ˜ธ์ถœ์„ ์ง๋ ฌํ™” โ€” ๊ฐ™์€ ์™ธ๋ถ€ ๊ณ„์ •์˜ ์ค‘๋ณต ๋กœ๊ทธ์ธ ์ถฉ๋Œ ๋ฐฉ์ง€.\n *\n * ๊ธฐ๋ณธ๊ฐ’ false (stateless ๋˜๋Š” ์ž์ฒด ์„ธ์…˜ ๊ด€๋ฆฌ). HeadlessConnector ๋“ฑ ๋กœ๊ทธ์ธ ์„ธ์…˜\n * ๊ธฐ๋ฐ˜ connector ๊ฐ€ true ๋กœ ์„ ์–ธ.\n */\n sessionExclusive?: boolean\n\n /**\n * ์ด connector ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด inheritance default โ€” ์ž์‹ ๋„๋ฉ”์ธ์ด ๋ถ€๋ชจ์˜ Connection\n * ์ •์˜๋ฅผ inherit ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒŒ ์ž์—ฐ์ธ์ง€๋ฅผ connector ์ž‘์„ฑ์ž๊ฐ€ ์„ ์–ธ.\n *\n * ๊ฐ’์€ string literal 'isolate' | 'share' โ€” runtime ํ˜ธํ™˜์„ ์œ„ํ•ด string ์œผ๋กœ\n * ๋น„๊ต (Connection.inheritanceMode column ์˜ ๊ฐ’๊ณผ ์ง์ ‘ ๋น„๊ต ๊ฐ€๋Šฅํ•˜๋„๋ก).\n *\n * **๊ฒฐ์ • ๊ฐ€์ด๋“œ** (connector ์ž‘์„ฑ์ž์šฉ):\n * 1. ์™ธ๋ถ€ ์ž์›์ด ๋„๋ฉ”์ธ(ํ…Œ๋„ŒํŠธ)๋ณ„๋กœ ๋‹ค๋ฅธ identityยท์ž๊ฒฉ์ฆ๋ช…ยท์„ธ์…˜์ด ํ•„์š”ํ•œ๊ฐ€?\n * - ์˜ˆ (stateful + per-tenant: ๋กœ๊ทธ์ธ connector, ํ…Œ๋„ŒํŠธ๋ณ„ DB pool) โ†’ 'isolate'\n * - ์•„๋‹ˆ์˜ค (๊ณต์šฉ ์ž์›: ๋‹จ์ผ ๋ธŒ๋กœ์ปคยท์„œ๋ฒ„ / stateless API) โ†’ 'share'\n *\n * 2. ์ž์‹ ๋„๋ฉ”์ธ์ด ๋ถ€๋ชจ์˜ cookiesยท์„ธ์…˜ยทparams ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ด๋„ ๋˜๋Š”๊ฐ€?\n * - ์•ˆ ๋จ (์ž๋ฃŒ ๊ฒฉ๋ฆฌยท์ž๊ฒฉ์ฆ๋ช… ๊ฒฉ๋ฆฌ ํ•„์š”) โ†’ 'isolate'\n * - ๋จ (๋ชจ๋‘ ๊ฐ™์€ ์ž์› ๊ณต์œ ) โ†’ 'share'\n *\n * 3. ๋ช…์‹œ ์•ˆ ํ•˜๋ฉด framework ๊ฐ€ ISOLATE ํด๋ฐฑ (๊ฒฉ๋ฆฌ ์šฐ์„ ). ์ž์› ํšจ์œจ์ด ์ค‘์š”ํ•œ\n * connector ์ž‘์„ฑ์ž๋Š” 'share' ๋ฅผ ๋ช…์‹œ ์„ ์–ธ.\n *\n * Connection.inheritanceMode ๊ฐ€ ๋ช…์‹œ๋˜๋ฉด ๊ทธ๊ฒƒ์ด ์šฐ์„ . ์šด์˜์ž๊ฐ€ ํŠน์ˆ˜ ์ผ€์ด์Šค๋ฅผ\n * ์œ„ํ•ด connector default ๋ฅผ override ํ•  ์ˆ˜ ์žˆ์Œ.\n */\n inheritanceMode?: 'isolate' | 'share'\n}\n\nexport type Context = {\n /**\n * Represents the domain context.\n */\n domain: Domain\n\n /**\n * User information.\n */\n user: User\n\n /**\n * Language code, for example 'en', 'ko'.\n */\n lng: string\n\n /**\n * Flag to indicate if the IP is unsafe, can be undefined.\n */\n unsafeIP: boolean | undefined\n\n /**\n * List of prohibited privileges, can be undefined.\n */\n prohibitedPrivileges: { category: string; privilege: string }[] | undefined\n\n /**\n * Logger for logging purposes.\n */\n logger: any\n\n /**\n * Function to publish events or messages.\n */\n publish: Function\n\n /**\n * Function to load resources or data.\n */\n load: Function\n\n /**\n * Current status of the scenario instance.\n */\n state: ScenarioInstanceStatus\n\n /**\n * General data storage object.\n */\n data: any\n\n /**\n * Variables related to the context.\n */\n variables: Object\n\n /**\n * Local GraphQL client object.\n */\n client: any /* graphql local client */\n\n /**\n * Root object, can be used for various purposes.\n */\n root?: ScenarioInstance\n\n /**\n * Array of function closures.\n */\n closures: Function[]\n\n /**\n * Function to check the state.\n */\n checkState: Function\n\n /**\n * MQTT subscriber context object.\n */\n __mqtt_subscriber?: any\n\n /**\n * socket listener context object.\n */\n __socket_listener?: any\n\n /**\n * csv readline context object.\n */\n __csv_resources?: any\n}\n\nexport type TaskHandler = (\n step: Step,\n context: Context\n) => Promise<{\n next?: string\n state?: ScenarioInstanceStatus\n data?: any\n}>\n"]}
@@ -20,6 +20,7 @@ export declare class ConnectionMutation {
20
20
  endpoint: string;
21
21
  active: boolean;
22
22
  onDemand: boolean;
23
+ inheritanceMode?: import("./connection").ConnectionInheritanceMode;
23
24
  params: {
24
25
  [key: string]: any;
25
26
  };
@@ -29,6 +30,8 @@ export declare class ConnectionMutation {
29
30
  creatorId: string;
30
31
  updater: import("@things-factory/auth-base").User;
31
32
  updaterId: string;
33
+ __inheritedFrom?: string;
34
+ __sharedFrom?: string;
32
35
  }>;
33
36
  importConnections(connections: Connection[], context: ResolverContext): Promise<boolean>;
34
37
  }
@@ -23,7 +23,7 @@ exports.ConnectionSubscription = ConnectionSubscription;
23
23
  tslib_1.__decorate([
24
24
  (0, type_graphql_1.Subscription)({
25
25
  description: 'Subscribes to the state changes of connections.',
26
- subscribe: ({ args, context, info }) => {
26
+ subscribe: async ({ args, context, info }) => {
27
27
  const { domain, user } = context.state;
28
28
  const { name } = args;
29
29
  const subdomain = domain?.subdomain;
@@ -31,7 +31,7 @@ tslib_1.__decorate([
31
31
  if (!domain) {
32
32
  throw new Error('domain required.');
33
33
  }
34
- if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {
34
+ if (!user.domains?.find(d => d.subdomain === subdomain) && !(await process.superUserGranted(domain, user))) {
35
35
  throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`);
36
36
  }
37
37
  // ancestor ๋„๋ฉ”์ธ ids ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜์—ฌ ์žฌ์‚ฌ์šฉ (subscribe ๋Š” sync ๋ผ lazy memoize)
@@ -76,7 +76,7 @@ tslib_1.__decorate([
76
76
  tslib_1.__decorate([
77
77
  (0, type_graphql_1.Subscription)({
78
78
  description: 'Subscribes to log messages from connections.',
79
- subscribe: ({ args, context, info }) => {
79
+ subscribe: async ({ args, context, info }) => {
80
80
  const { domain, user } = context.state;
81
81
  const { level } = args;
82
82
  const subdomain = domain?.subdomain;
@@ -84,7 +84,7 @@ tslib_1.__decorate([
84
84
  if (!domain) {
85
85
  throw new Error('domain required');
86
86
  }
87
- if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {
87
+ if (!user.domains?.find(d => d.subdomain === subdomain) && !(await process.superUserGranted(domain, user))) {
88
88
  throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`);
89
89
  }
90
90
  return (0, graphql_yoga_1.pipe)(shell_1.pubsub.subscribe('connection-log'), (0, graphql_yoga_1.filter)(async (payload) => {
@@ -1 +1 @@
1
- {"version":3,"file":"connection-subscription.js","sourceRoot":"","sources":["../../../server/service/connection/connection-subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import { filter, pipe } from 'graphql-yoga'\nimport { Arg, Resolver, Root, Subscription } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { getRepository, Log, pubsub } from '@things-factory/shell'\n\nimport { ConnectionManager } from '../../engine/connection-manager'\nimport { Connection, ConnectionStatus } from './connection'\nimport { ConnectionState } from './connection-type'\nimport { getDomainIdsWithAncestors } from '../../utils/domain-inheritance'\n\nconst debug = require('debug')('things-factory:integration:connection-subscription')\n\n@Resolver(Connection)\nexport class ConnectionSubscription {\n @Subscription({\n description: 'Subscribes to the state changes of connections.',\n subscribe: ({ args, context, info }) => {\n const { domain, user } = context.state\n const { name } = args\n const subdomain = domain?.subdomain\n\n debug('subscribe', subdomain)\n if (!domain) {\n throw new Error('domain required.')\n }\n\n if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {\n throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)\n }\n\n // ancestor ๋„๋ฉ”์ธ ids ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜์—ฌ ์žฌ์‚ฌ์šฉ (subscribe ๋Š” sync ๋ผ lazy memoize)\n let ancestorIdsPromise: Promise<string[]> | null = null\n const resolveAncestorIds = () =>\n (ancestorIdsPromise ||= getDomainIdsWithAncestors(domain))\n\n process.nextTick(async () => {\n const domainIds = await resolveAncestorIds()\n var where: any = { domain: { id: In(domainIds) } }\n if (name) {\n where['name'] = name\n }\n\n var connections = await getRepository(Connection).find({\n where,\n relations: ['domain', 'edge']\n })\n\n connections.forEach(connection => {\n pubsub.publish('connection-state', {\n connectionState: {\n ...connection,\n domain /* ์ƒ์† ๋ฐ on-demand ์—ฐ๊ฒฐ์—์„œ connection.domain ๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ */,\n state: ConnectionManager.getConnectionInstance(connection)\n ? ConnectionStatus.CONNECTED\n : ConnectionStatus.DISCONNECTED,\n timestamp: new Date()\n }\n })\n })\n })\n\n return pipe(\n pubsub.subscribe('connection-state'),\n filter(async (payload: { connectionState: ConnectionState }) => {\n const { domain: pdomain, name: pname } = payload.connectionState\n const domainIds = await resolveAncestorIds()\n\n return (!name || name === pname) && domainIds.includes(pdomain?.id)\n })\n )\n }\n })\n connectionState(\n @Root() payload: { connectionState: ConnectionState },\n @Arg('name', { nullable: true }) name: string\n ): ConnectionState {\n return payload.connectionState\n }\n\n @Subscription({\n description: 'Subscribes to log messages from connections.',\n subscribe: ({ args, context, info }) => {\n const { domain, user } = context.state\n const { level } = args\n\n const subdomain = domain?.subdomain\n\n debug('subscribe', subdomain)\n\n if (!domain) {\n throw new Error('domain required')\n }\n\n if (!user.domains?.find(d => d.subdomain === subdomain) && !process.superUserGranted(domain, user)) {\n throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)\n }\n\n return pipe(\n pubsub.subscribe('connection-log'),\n filter(async (payload: { log: Log }) => {\n // TODO support domain filtering\n const { /* source, */ level: plevel } = payload.log\n // const { domain: pdomain } = source\n\n // if (subdomain !== pdomain?.subdomain) {\n // return false\n // }\n\n if (level && level !== plevel) {\n return false\n }\n\n return true\n })\n )\n }\n })\n connectionLog(@Root() payload: { log: Log }, @Arg('level', { nullable: true }) level: string): Log {\n return payload.log\n }\n}\n"]}
1
+ {"version":3,"file":"connection-subscription.js","sourceRoot":"","sources":["../../../server/service/connection/connection-subscription.ts"],"names":[],"mappings":"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","sourcesContent":["import { filter, pipe } from 'graphql-yoga'\nimport { Arg, Resolver, Root, Subscription } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { getRepository, Log, pubsub } from '@things-factory/shell'\n\nimport { ConnectionManager } from '../../engine/connection-manager'\nimport { Connection, ConnectionStatus } from './connection'\nimport { ConnectionState } from './connection-type'\nimport { getDomainIdsWithAncestors } from '../../utils/domain-inheritance'\n\nconst debug = require('debug')('things-factory:integration:connection-subscription')\n\n@Resolver(Connection)\nexport class ConnectionSubscription {\n @Subscription({\n description: 'Subscribes to the state changes of connections.',\n subscribe: async ({ args, context, info }) => {\n const { domain, user } = context.state\n const { name } = args\n const subdomain = domain?.subdomain\n\n debug('subscribe', subdomain)\n if (!domain) {\n throw new Error('domain required.')\n }\n\n if (!user.domains?.find(d => d.subdomain === subdomain) && !(await process.superUserGranted(domain, user))) {\n throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)\n }\n\n // ancestor ๋„๋ฉ”์ธ ids ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜์—ฌ ์žฌ์‚ฌ์šฉ (subscribe ๋Š” sync ๋ผ lazy memoize)\n let ancestorIdsPromise: Promise<string[]> | null = null\n const resolveAncestorIds = () =>\n (ancestorIdsPromise ||= getDomainIdsWithAncestors(domain))\n\n process.nextTick(async () => {\n const domainIds = await resolveAncestorIds()\n var where: any = { domain: { id: In(domainIds) } }\n if (name) {\n where['name'] = name\n }\n\n var connections = await getRepository(Connection).find({\n where,\n relations: ['domain', 'edge']\n })\n\n connections.forEach(connection => {\n pubsub.publish('connection-state', {\n connectionState: {\n ...connection,\n domain /* ์ƒ์† ๋ฐ on-demand ์—ฐ๊ฒฐ์—์„œ connection.domain ๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ */,\n state: ConnectionManager.getConnectionInstance(connection)\n ? ConnectionStatus.CONNECTED\n : ConnectionStatus.DISCONNECTED,\n timestamp: new Date()\n }\n })\n })\n })\n\n return pipe(\n pubsub.subscribe('connection-state'),\n filter(async (payload: { connectionState: ConnectionState }) => {\n const { domain: pdomain, name: pname } = payload.connectionState\n const domainIds = await resolveAncestorIds()\n\n return (!name || name === pname) && domainIds.includes(pdomain?.id)\n })\n )\n }\n })\n connectionState(\n @Root() payload: { connectionState: ConnectionState },\n @Arg('name', { nullable: true }) name: string\n ): ConnectionState {\n return payload.connectionState\n }\n\n @Subscription({\n description: 'Subscribes to log messages from connections.',\n subscribe: async ({ args, context, info }) => {\n const { domain, user } = context.state\n const { level } = args\n\n const subdomain = domain?.subdomain\n\n debug('subscribe', subdomain)\n\n if (!domain) {\n throw new Error('domain required')\n }\n\n if (!user.domains?.find(d => d.subdomain === subdomain) && !(await process.superUserGranted(domain, user))) {\n throw new Error(`domain(${subdomain}) is not working for user(${user.email}).`)\n }\n\n return pipe(\n pubsub.subscribe('connection-log'),\n filter(async (payload: { log: Log }) => {\n // TODO support domain filtering\n const { /* source, */ level: plevel } = payload.log\n // const { domain: pdomain } = source\n\n // if (subdomain !== pdomain?.subdomain) {\n // return false\n // }\n\n if (level && level !== plevel) {\n return false\n }\n\n return true\n })\n )\n }\n })\n connectionLog(@Root() payload: { log: Log }, @Arg('level', { nullable: true }) level: string): Log {\n return payload.log\n }\n}\n"]}