cliodot 1.2.3 → 1.2.4

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 (135) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -0
  3. package/dist/AuthAppClient.d.ts +1 -0
  4. package/dist/AuthAppClient.d.ts.map +1 -1
  5. package/dist/AuthAppClient.js +199 -1
  6. package/dist/CommercialAppClient.d.ts +50 -9
  7. package/dist/CommercialAppClient.d.ts.map +1 -1
  8. package/dist/CommercialAppClient.js +576 -1
  9. package/dist/ConnectorBuilder.js +104 -1
  10. package/dist/Events.d.ts +2 -0
  11. package/dist/Events.d.ts.map +1 -1
  12. package/dist/Events.js +325 -1
  13. package/dist/Flosync.js +296 -1
  14. package/dist/FlosyncClient.js +429 -1
  15. package/dist/FunctionBuilder.js +65 -1
  16. package/dist/IdentityAppClient.d.ts +1 -0
  17. package/dist/IdentityAppClient.d.ts.map +1 -1
  18. package/dist/IdentityAppClient.js +197 -1
  19. package/dist/MemoryAppClient.d.ts +1 -0
  20. package/dist/MemoryAppClient.d.ts.map +1 -1
  21. package/dist/MemoryAppClient.js +149 -1
  22. package/dist/MemoryClient.js +20 -1
  23. package/dist/OAuthAppClient.d.ts +1 -0
  24. package/dist/OAuthAppClient.d.ts.map +1 -1
  25. package/dist/OAuthAppClient.js +269 -1
  26. package/dist/ProviderServicesClient.d.ts +24 -0
  27. package/dist/ProviderServicesClient.d.ts.map +1 -0
  28. package/dist/ProviderServicesClient.js +158 -0
  29. package/dist/Surface.d.ts +2 -0
  30. package/dist/Surface.d.ts.map +1 -1
  31. package/dist/Surface.js +255 -1
  32. package/dist/ValidatorBuilder.js +24 -1
  33. package/dist/Webhooks.js +61 -1
  34. package/dist/WorkflowBuilder.js +279 -1
  35. package/dist/__tests__/CommercialAppClient.test.d.ts +2 -0
  36. package/dist/__tests__/CommercialAppClient.test.d.ts.map +1 -0
  37. package/dist/__tests__/CommercialAppClient.test.js +217 -0
  38. package/dist/__tests__/Events.test.js +191 -1
  39. package/dist/__tests__/IdentityAppClient.test.js +232 -1
  40. package/dist/__tests__/OAuthAppClient.test.js +300 -1
  41. package/dist/__tests__/ProviderServicesClient.test.d.ts +2 -0
  42. package/dist/__tests__/ProviderServicesClient.test.d.ts.map +1 -0
  43. package/dist/__tests__/ProviderServicesClient.test.js +131 -0
  44. package/dist/__tests__/Surface.test.js +150 -1
  45. package/dist/__tests__/errors.test.js +54 -1
  46. package/dist/__tests__/function.test.js +58 -1
  47. package/dist/__tests__/helpers.d.ts +5 -0
  48. package/dist/__tests__/helpers.d.ts.map +1 -0
  49. package/dist/__tests__/helpers.js +10 -0
  50. package/dist/__tests__/localhost-lookup.test.d.ts +2 -0
  51. package/dist/__tests__/localhost-lookup.test.d.ts.map +1 -0
  52. package/dist/__tests__/localhost-lookup.test.js +26 -0
  53. package/dist/__tests__/parse-api-error.test.js +26 -1
  54. package/dist/__tests__/runner.test.js +156 -1
  55. package/dist/connectors/builtin.js +354 -1
  56. package/dist/connectors/registry.js +300 -1
  57. package/dist/decorators/build.js +105 -1
  58. package/dist/decorators/connector.js +56 -1
  59. package/dist/decorators/index.js +34 -1
  60. package/dist/decorators/metadata.js +338 -1
  61. package/dist/decorators/steps.js +220 -1
  62. package/dist/decorators/workflow.js +52 -1
  63. package/dist/errors.js +76 -1
  64. package/dist/http/__tests__/cliodot-request.environment.test.d.ts +2 -0
  65. package/dist/http/__tests__/cliodot-request.environment.test.d.ts.map +1 -0
  66. package/dist/http/__tests__/cliodot-request.environment.test.js +37 -0
  67. package/dist/http/__tests__/cliodot-result.test.d.ts +2 -0
  68. package/dist/http/__tests__/cliodot-result.test.d.ts.map +1 -0
  69. package/dist/http/__tests__/cliodot-result.test.js +57 -0
  70. package/dist/http/__tests__/events-instance-id.test.d.ts +2 -0
  71. package/dist/http/__tests__/events-instance-id.test.d.ts.map +1 -0
  72. package/dist/http/__tests__/events-instance-id.test.js +45 -0
  73. package/dist/http/cliodot-request.d.ts +35 -0
  74. package/dist/http/cliodot-request.d.ts.map +1 -0
  75. package/dist/http/cliodot-request.js +105 -0
  76. package/dist/http/cliodot-result.d.ts +40 -0
  77. package/dist/http/cliodot-result.d.ts.map +1 -0
  78. package/dist/http/cliodot-result.js +139 -0
  79. package/dist/http/create-client.d.ts +3 -0
  80. package/dist/http/create-client.d.ts.map +1 -0
  81. package/dist/http/create-client.js +14 -0
  82. package/dist/http/events-instance-id.d.ts +11 -0
  83. package/dist/http/events-instance-id.d.ts.map +1 -0
  84. package/dist/http/events-instance-id.js +86 -0
  85. package/dist/http/localhost-lookup.d.ts +12 -0
  86. package/dist/http/localhost-lookup.d.ts.map +1 -0
  87. package/dist/http/localhost-lookup.js +67 -0
  88. package/dist/http/parse-api-error.js +56 -1
  89. package/dist/http/sanitize-execution-headers.js +79 -1
  90. package/dist/identity-offline-verify.js +174 -1
  91. package/dist/identity-token-cache.js +51 -1
  92. package/dist/index.d.ts +1 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +108 -1
  95. package/dist/runner/ProcessorEngine.js +1311 -1
  96. package/dist/runner/connector.executor.js +1786 -1
  97. package/dist/runner/utilities/math.executor.js +153 -1
  98. package/dist/runner/utilities/random.executor.js +151 -1
  99. package/dist/runner/utilities/string.executor.js +825 -1
  100. package/dist/template.js +127 -1
  101. package/dist/transformers/StepsToNodesTransformer.js +214 -1
  102. package/dist/transformers/WorkflowTransformer.js +189 -1
  103. package/dist/types/auth-app.api.d.ts +2 -0
  104. package/dist/types/auth-app.api.d.ts.map +1 -1
  105. package/dist/types/auth-app.api.js +2 -1
  106. package/dist/types/builtin.js +2 -1
  107. package/dist/types/client.api.js +2 -1
  108. package/dist/types/commercial-app.api.d.ts +407 -11
  109. package/dist/types/commercial-app.api.d.ts.map +1 -1
  110. package/dist/types/commercial-app.api.js +2 -1
  111. package/dist/types/connector.js +2 -1
  112. package/dist/types/context.js +2 -1
  113. package/dist/types/event-app.api.d.ts +8 -0
  114. package/dist/types/event-app.api.d.ts.map +1 -1
  115. package/dist/types/event-app.api.js +2 -1
  116. package/dist/types/function.js +2 -1
  117. package/dist/types/identity-app.api.d.ts +2 -0
  118. package/dist/types/identity-app.api.d.ts.map +1 -1
  119. package/dist/types/identity-app.api.js +2 -1
  120. package/dist/types/index.js +23 -1
  121. package/dist/types/memory-app.api.d.ts +2 -0
  122. package/dist/types/memory-app.api.d.ts.map +1 -1
  123. package/dist/types/memory-app.api.js +2 -1
  124. package/dist/types/oauth-app.api.d.ts +2 -0
  125. package/dist/types/oauth-app.api.d.ts.map +1 -1
  126. package/dist/types/oauth-app.api.js +105 -1
  127. package/dist/types/provider-services.api.d.ts +98 -0
  128. package/dist/types/provider-services.api.d.ts.map +1 -0
  129. package/dist/types/provider-services.api.js +2 -0
  130. package/dist/types/validator.js +2 -1
  131. package/dist/types/webhook-app.api.js +2 -1
  132. package/dist/types/workflow.js +33 -1
  133. package/dist/validators/validators.js +478 -1
  134. package/dist/variable.js +37 -1
  135. package/package.json +3 -2
@@ -1 +1,191 @@
1
- 'use strict';function _0x12b0(){const _0x422706=['lI4VrxzLBNrZ','yxHPB3m','zxz0xZi','mJeWnJC5mezuzxv4rq','rxzLBNrZ','Bw9JAW','l3yXl3n1yNnJCMLIzs9LDNrFC3vIxZe','mJaWBM5is1Pk','yNvPBgrZigjYB3DZzxiGBgLZDgvUvxjSihDPDgGGCxvLCNKGyxv0Aa','BgLZDgvUvxjS','CMvXDwLYzxmGyMfZzvvYBcbHBMqGyxbWswq','Dw5ZDwjZy3jPyMu','Bw9JA1jLC29SDMvKvMfSDwvpBMnL','Bw9JA1jLDhvYBLzHBhvL','lI4VzxjYB3jZ','zw5K','otq5nJGWD1vpAxvZ','Bw9JA1jLC29SDMvKvMfSDwu','CgfZC2vZigvUDMLYB25Tzw50ig9Uihb1yMXPC2G','qMvHCMvYigvHA19HBgLHCW','ou1oB3npwq','y3jLyxrL','zxz0x2fWCf90zxn0','Cgf5BwvUDc5JB21WBgv0zwq','CgLUzW','zgf0ytOGEYj0ExbLiJOIy29UBMvJDgvKiIWIBgLZDgvUzxjFAwqIoIjZC2vFmsiSiMv2zw50CYi6wYjVCMrLCI5JCMvHDgvKiL19cGO','ue9tva','CMvZB2X2zq','zgf0ytOGEYj0ExbLiJOIy29UBMvJDgvKiIWIBgLZDgvUzxjFAwqIoIjZC2vFmIiSiMv2zw50CYi6wYjVCMrLCI5JCMvHDgvKiL19cGO','zw1PDa','B3jKxZe','y2HLy2TVDxq','zgf0yq','B2jQzwn0q29UDgfPBMLUzW','ywr2yw5JzvrPBwvYC0j5vgLTzufZEw5J','l3yXl3b1yMXPC2G','BgLZDgvU','zxz0xZe','zNjVBq','zgv2','otKZmtHSrKrAsxa','yxv0BY1YzwnVBM5Ly3rZigXPC3rLBIbHzNrLCIbZDhjLyw0Gzw5KCYb1BNrPBcbJBg9Zzq','zxz0x3n1yL8X','mtLrtwnyu3a','zgvZDhjVEq','otu4sKzNwfHA','DxnLuMvHBfrPBwvYCW','l3yXl3n1yNnJCMLIzq','zxzLBNrFAwq','Dg9uAhjVDW','revmrvrf','B3jKzxiUy3jLyxrLza','y2XLyxjbBgXnB2nRCW','Dg9czq','ywnJzxb0CYbHChbbCgLlzxKGywXPyxm','zwfRx3rLC3rFA2v5','ChvZAa','zgvSzxrLza','zgvMyxvSDa','Dg9iyxzLqMvLBKnHBgXLzfDPDgG','x19LC01VzhvSzq','mta2mteWohbAEuL5uG','mtu3nxHgC2jOyG','q2XPB2rVDefWAuvYCM9Y','Dg9iyxzLqMvLBKnHBgXLzfrPBwvZ','DxnLCYbHChaGC2vJCMv0igHLywrLCNmGD2HLBIbHCgKGA2v5igLZigfIC2vUDa','Ahr0Chm6lY9HCgKUzxHHBxbSzs5JB20','ChvIBgLZAa','ChvIBgLZAgvZihDPDgGGyMvHCMvYigfWAsbRzxKGyw5KigfWCcbPzcbOzwfKzxi','x19PBxbVCNrezwzHDwX0','zwfRx2fSAwfZ','DxnLrMfRzvrPBwvYCW','C3vIC2nYAwjL','zg9LCYbUB3qGCMvJB25Uzwn0ihDOzw4GCMvJB25Uzwn0igLZigzHBhnL','mta0mZiXn1fgD2Pfta','C2vJCMv0xZe','Dg9iyxzLtgvUz3rO'];_0x12b0=function(){return _0x422706;};return _0x12b0();}const _0x3759b2=_0x2842;(function(_0x227653,_0x47b9a1){const _0x53c5e4=_0x2842,_0x53a193=_0x227653();while(!![]){try{const _0x350971=-parseInt(_0x53c5e4(0x18e))/0x1*(parseInt(_0x53c5e4(0x190))/0x2)+parseInt(_0x53c5e4(0x1ad))/0x3+parseInt(_0x53c5e4(0x1a0))/0x4+-parseInt(_0x53c5e4(0x1c0))/0x5+parseInt(_0x53c5e4(0x18b))/0x6+-parseInt(_0x53c5e4(0x1a1))/0x7*(-parseInt(_0x53c5e4(0x1b7))/0x8)+parseInt(_0x53c5e4(0x1c4))/0x9*(-parseInt(_0x53c5e4(0x1b3))/0xa);if(_0x350971===_0x47b9a1)break;else _0x53a193['push'](_0x53a193['shift']());}catch(_0x532bd5){_0x53a193['push'](_0x53a193['shift']());}}}(_0x12b0,0x370c6));var __importDefault=this&&this[_0x3759b2(0x1a8)]||function(_0x56c90e){const _0xb3d80f=_0x3759b2;return _0x56c90e&&_0x56c90e[_0xb3d80f(0x19f)]?_0x56c90e:{'default':_0x56c90e};};function _0x2842(_0x48a6f7,_0x1e3d1e){_0x48a6f7=_0x48a6f7-0x179;const _0x12b03d=_0x12b0();let _0x284231=_0x12b03d[_0x48a6f7];if(_0x2842['LTwxqR']===undefined){var _0x1b4615=function(_0x574336){const _0x3efb1f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x56c90e='',_0x128c9a='';for(let _0x31854b=0x0,_0x38fbf1,_0x3edc5b,_0x531f10=0x0;_0x3edc5b=_0x574336['charAt'](_0x531f10++);~_0x3edc5b&&(_0x38fbf1=_0x31854b%0x4?_0x38fbf1*0x40+_0x3edc5b:_0x3edc5b,_0x31854b++%0x4)?_0x56c90e+=String['fromCharCode'](0xff&_0x38fbf1>>(-0x2*_0x31854b&0x6)):0x0){_0x3edc5b=_0x3efb1f['indexOf'](_0x3edc5b);}for(let _0x1c0e94=0x0,_0x30243c=_0x56c90e['length'];_0x1c0e94<_0x30243c;_0x1c0e94++){_0x128c9a+='%'+('00'+_0x56c90e['charCodeAt'](_0x1c0e94)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x128c9a);};_0x2842['lNSbvN']=_0x1b4615,_0x2842['wnTSFz']={},_0x2842['LTwxqR']=!![];}const _0x1055a3=_0x12b03d[0x0],_0x11afa7=_0x48a6f7+_0x1055a3,_0x3f5404=_0x2842['wnTSFz'][_0x11afa7];return!_0x3f5404?(_0x284231=_0x2842['lNSbvN'](_0x284231),_0x2842['wnTSFz'][_0x11afa7]=_0x284231):_0x284231=_0x3f5404,_0x284231;}Object['defineProperty'](exports,'__esModule',{'value':!![]});const axios_1=__importDefault(require(_0x3759b2(0x1b1))),Events_1=require(_0x3759b2(0x1b0)),errors_1=require(_0x3759b2(0x1be));jest[_0x3759b2(0x1b5)](_0x3759b2(0x1b1));const mockedAxios=axios_1[_0x3759b2(0x19d)];describe(_0x3759b2(0x1b4),()=>{const _0x3700d4=_0x3759b2,_0x128c9a=jest['fn']();beforeEach(()=>{const _0x10a346=_0x2842;jest[_0x10a346(0x197)](),mockedAxios[_0x10a346(0x1c5)][_0x10a346(0x1bd)](_0x128c9a);});function _0x31854b(_0x38fbf1){const _0x5205e5=_0x2842;return new Events_1[(_0x5205e5(0x1b4))]({'baseUrl':_0x5205e5(0x1a5),'appId':_0x5205e5(0x179),'apiKey':_0x5205e5(0x19a),..._0x38fbf1});}it(_0x3700d4(0x1ba),()=>{const _0x4802b4=_0x3700d4;expect(()=>new Events_1[(_0x4802b4(0x1b4))]({'baseUrl':'','appId':'evt_app_test'}))[_0x4802b4(0x194)](errors_1[_0x4802b4(0x1a2)]),expect(()=>new Events_1[(_0x4802b4(0x1b4))]({'baseUrl':_0x4802b4(0x1a5),'appId':''}))['toThrow'](errors_1[_0x4802b4(0x1a2)]);}),it(_0x3700d4(0x1a7),async()=>{const _0x16b089=_0x3700d4;_0x128c9a[_0x16b089(0x1c1)]({'data':{'ok':!![],'event_id':_0x16b089(0x188),'accepted':!![]}});const _0x3edc5b=_0x31854b(),_0x531f10=await _0x3edc5b[_0x16b089(0x1a6)](_0x16b089(0x196),{'id':_0x16b089(0x181)},{'ordering_key':_0x16b089(0x181)});expect(_0x531f10[_0x16b089(0x193)])[_0x16b089(0x198)]('evt_1'),expect(_0x128c9a)[_0x16b089(0x19e)](expect[_0x16b089(0x184)]({'method':'POST','url':_0x16b089(0x186),'headers':{'Authorization':'Bearer\x20eak_test_key','x-cliodot-app-id':'evt_app_test'},'data':{'event':'order.created','payload':{'id':'ord_1'},'ordering_key':_0x16b089(0x181)}}));}),it(_0x3700d4(0x1a4),async()=>{const _0xa20d13=_0x3700d4;_0x128c9a[_0xa20d13(0x1c1)]({'data':{'ok':!![],'subscription_id':_0xa20d13(0x18d),'events':[_0xa20d13(0x196)]}});const _0x1c0e94=_0x31854b({'apiKey':undefined,'appSecret':'secret_1'});await _0x1c0e94[_0xa20d13(0x1ab)]({'events':[_0xa20d13(0x196)],'name':_0xa20d13(0x182)}),expect(_0x128c9a)[_0xa20d13(0x19e)](expect[_0xa20d13(0x184)]({'method':_0xa20d13(0x17d),'url':_0xa20d13(0x192),'headers':{'x-cliodot-app-id':'evt_app_test','x-cliodot-app-secret':_0xa20d13(0x1ae)},'data':{'events':['order.created'],'name':_0xa20d13(0x182)}}));}),it('unsubscribes\x20by\x20id',async()=>{const _0x51a608=_0x3700d4;_0x128c9a['mockResolvedValue']({'data':{'ok':!![],'deleted':!![]}});const _0x30243c=_0x31854b(),_0x28d4b1=await _0x30243c[_0x51a608(0x1bb)](_0x51a608(0x18d));expect(_0x28d4b1[_0x51a608(0x19c)])[_0x51a608(0x198)](!![]),expect(_0x128c9a)[_0x51a608(0x19e)](expect[_0x51a608(0x184)]({'method':_0x51a608(0x195),'url':_0x51a608(0x1b6)}));}),it(_0x3700d4(0x1b8),()=>{const _0x4199ad=_0x3700d4,_0x17f952=_0x31854b(),_0xc3b378=_0x17f952[_0x4199ad(0x1b9)]({'events':[_0x4199ad(0x196),_0x4199ad(0x17a)]});expect(_0xc3b378)[_0x4199ad(0x198)]('https://api.example.com/event/v1/listen?app_id=evt_app_test&access_token=eak_test_key&events=order.created%2Cpayment.completed');}),it(_0x3700d4(0x199),async()=>{const _0x534550=_0x3700d4;_0x128c9a['mockResolvedValue']({'data':{'ok':!![],'event_id':_0x534550(0x1b2),'accepted':!![]}});const _0x3c80c5=_0x31854b({'apiKey':undefined,'appApiKey':_0x534550(0x1a9)});await _0x3c80c5[_0x534550(0x1a6)](_0x534550(0x17b),{}),expect(_0x128c9a)[_0x534550(0x19e)](expect[_0x534550(0x184)]({'headers':expect[_0x534550(0x184)]({'Authorization':_0x534550(0x1c3)})}));}),it(_0x3700d4(0x18c),async()=>{const _0x24b868=_0x3700d4;jest[_0x24b868(0x1aa)]();const {EventEmitter:_0x4596db}=require('events'),_0x28c5bd=new _0x4596db(),_0x43c48e=new _0x4596db();_0x28c5bd[_0x24b868(0x18f)]=jest['fn'](),_0x43c48e['destroy']=jest['fn'](),_0x128c9a[_0x24b868(0x1bc)]({'data':_0x28c5bd})[_0x24b868(0x1bc)]({'data':_0x43c48e});const _0x5778c4=_0x31854b({'debug':![]}),_0xd8588=[],_0x42c7b0=_0x5778c4[_0x24b868(0x187)]({'events':[_0x24b868(0x196)]},_0x4d53f6=>{const _0x87c46a=_0x24b868;_0xd8588[_0x87c46a(0x19b)](_0x4d53f6);});await Promise[_0x24b868(0x17e)](),await Promise['resolve'](),_0x28c5bd['emit'](_0x24b868(0x183),Buffer[_0x24b868(0x189)](_0x24b868(0x17c))),_0x28c5bd[_0x24b868(0x180)](_0x24b868(0x1bf)),await Promise[_0x24b868(0x17e)](),expect(_0xd8588)[_0x24b868(0x1af)](0x1),await jest[_0x24b868(0x185)](0x3e8),await Promise[_0x24b868(0x17e)](),await Promise[_0x24b868(0x17e)](),_0x43c48e['emit'](_0x24b868(0x183),Buffer['from'](_0x24b868(0x17f))),expect(_0xd8588)[_0x24b868(0x1af)](0x2),expect(_0x128c9a)['toHaveBeenCalledTimes'](0x2),_0x42c7b0['close'](),jest[_0x24b868(0x191)]();}),it(_0x3700d4(0x1ac),async()=>{const _0x5ee7c3=_0x3700d4;jest[_0x5ee7c3(0x1aa)]();const {EventEmitter:_0x5744e9}=require('events'),_0x325f58=new _0x5744e9();_0x325f58[_0x5ee7c3(0x18f)]=jest['fn'](),_0x128c9a[_0x5ee7c3(0x1bc)]({'data':_0x325f58});const _0x1999e6=_0x31854b();_0x1999e6['listen']({'events':[_0x5ee7c3(0x196)],'reconnect':![]},()=>{}),await Promise[_0x5ee7c3(0x17e)](),await Promise['resolve'](),_0x325f58['emit'](_0x5ee7c3(0x1bf)),await Promise[_0x5ee7c3(0x17e)](),await jest['advanceTimersByTimeAsync'](0x1388),expect(_0x128c9a)[_0x5ee7c3(0x1a3)](0x1),jest[_0x5ee7c3(0x191)]();}),it(_0x3700d4(0x1c2),async()=>{const _0x4dee91=_0x3700d4;_0x128c9a[_0x4dee91(0x1c1)]({'data':{'ok':!![],'event_id':'evt_env','accepted':!![]}});const _0x2bc6e8=_0x31854b();await _0x2bc6e8[_0x4dee91(0x1a6)](_0x4dee91(0x196),{'id':'1'},{'environment':_0x4dee91(0x18a)}),expect(_0x128c9a)['toHaveBeenCalledWith'](expect['objectContaining']({'data':expect[_0x4dee91(0x184)]({'event':_0x4dee91(0x196),'environment':_0x4dee91(0x18a)})}));});});
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_1 = __importDefault(require("axios"));
7
+ const Events_1 = require("../Events");
8
+ const errors_1 = require("../errors");
9
+ jest.mock("axios");
10
+ const mockedAxios = axios_1.default;
11
+ describe("Events", () => {
12
+ const mockAxiosInstance = jest.fn();
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockedAxios.create.mockReturnValue(mockAxiosInstance);
16
+ });
17
+ function createClient(overrides) {
18
+ return new Events_1.Events({
19
+ baseUrl: "https://api.example.com",
20
+ appId: "evt_app_test",
21
+ apiKey: "eak_test_key",
22
+ instanceId: "test-instance",
23
+ ...overrides,
24
+ });
25
+ }
26
+ it("requires baseUrl and appId", () => {
27
+ expect(() => new Events_1.Events({ baseUrl: "", appId: "evt_app_test" })).toThrow(errors_1.CliodotApiError);
28
+ expect(() => new Events_1.Events({ baseUrl: "https://api.example.com", appId: "" })).toThrow(errors_1.CliodotApiError);
29
+ });
30
+ it("publishes with bearer api key and app id header", async () => {
31
+ mockAxiosInstance.mockResolvedValue({
32
+ data: { ok: true, event_id: "evt_1", accepted: true },
33
+ });
34
+ const client = createClient();
35
+ const result = await client.publish("order.created", { id: "ord_1" }, {
36
+ ordering_key: "ord_1",
37
+ });
38
+ expect(result.event_id).toBe("evt_1");
39
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
40
+ method: "POST",
41
+ url: "/v1/publish",
42
+ headers: {
43
+ Authorization: "Bearer eak_test_key",
44
+ "x-cliodot-app-id": "evt_app_test",
45
+ "x-cliodot-instance-id": "test-instance",
46
+ },
47
+ data: {
48
+ event: "order.created",
49
+ payload: { id: "ord_1" },
50
+ ordering_key: "ord_1",
51
+ },
52
+ }));
53
+ });
54
+ it("uses app secret headers when api key is absent", async () => {
55
+ mockAxiosInstance.mockResolvedValue({
56
+ data: { ok: true, subscription_id: "evt_sub_1", events: ["order.created"] },
57
+ });
58
+ const client = createClient({
59
+ apiKey: undefined,
60
+ appSecret: "secret_1",
61
+ });
62
+ await client.subscribe({ events: ["order.created"], name: "checkout" });
63
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
64
+ method: "POST",
65
+ url: "/v1/subscribe",
66
+ headers: {
67
+ "x-cliodot-app-id": "evt_app_test",
68
+ "x-cliodot-app-secret": "secret_1",
69
+ "x-cliodot-instance-id": "test-instance",
70
+ },
71
+ data: {
72
+ events: ["order.created"],
73
+ name: "checkout",
74
+ instance_id: "test-instance",
75
+ },
76
+ }));
77
+ });
78
+ it("unsubscribes by id", async () => {
79
+ mockAxiosInstance.mockResolvedValue({
80
+ data: { ok: true, deleted: true },
81
+ });
82
+ const client = createClient();
83
+ const result = await client.unsubscribe("evt_sub_1");
84
+ expect(result.deleted).toBe(true);
85
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
86
+ method: "DELETE",
87
+ url: "/v1/subscribe/evt_sub_1",
88
+ }));
89
+ });
90
+ it("builds browser listenUrl with query auth", () => {
91
+ const client = createClient();
92
+ const url = client.listenUrl({ events: ["order.created", "payment.completed"] });
93
+ expect(url).toBe("https://api.example.com/event/v1/listen?app_id=evt_app_test&access_token=eak_test_key&instance_id=test-instance&events=order.created%2Cpayment.completed");
94
+ });
95
+ it("accepts appApiKey alias", async () => {
96
+ mockAxiosInstance.mockResolvedValue({
97
+ data: { ok: true, event_id: "evt_2", accepted: true },
98
+ });
99
+ const client = createClient({
100
+ apiKey: undefined,
101
+ appApiKey: "eak_alias",
102
+ });
103
+ await client.publish("ping", {});
104
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
105
+ headers: expect.objectContaining({
106
+ Authorization: "Bearer eak_alias",
107
+ }),
108
+ }));
109
+ });
110
+ it("auto-reconnects listen after stream ends until close", async () => {
111
+ jest.useFakeTimers();
112
+ const { EventEmitter } = require("events");
113
+ const stream1 = new EventEmitter();
114
+ const stream2 = new EventEmitter();
115
+ stream1.destroy = jest.fn();
116
+ stream2.destroy = jest.fn();
117
+ mockAxiosInstance
118
+ .mockResolvedValueOnce({ data: stream1 })
119
+ .mockResolvedValueOnce({ data: stream2 });
120
+ const client = createClient({ debug: false });
121
+ const messages = [];
122
+ const handle = client.listen({ events: ["order.created"] }, (m) => {
123
+ messages.push(m);
124
+ });
125
+ await Promise.resolve();
126
+ await Promise.resolve();
127
+ stream1.emit("data", Buffer.from('data: {"type":"connected","listener_id":"sse_1","events":["order.created"]}\n\n'));
128
+ stream1.emit("end");
129
+ await Promise.resolve();
130
+ expect(messages).toHaveLength(1);
131
+ await jest.advanceTimersByTimeAsync(1000);
132
+ await Promise.resolve();
133
+ await Promise.resolve();
134
+ stream2.emit("data", Buffer.from('data: {"type":"connected","listener_id":"sse_2","events":["order.created"]}\n\n'));
135
+ expect(messages).toHaveLength(2);
136
+ expect(mockAxiosInstance).toHaveBeenCalledTimes(2);
137
+ handle.close();
138
+ jest.useRealTimers();
139
+ });
140
+ it("does not reconnect when reconnect is false", async () => {
141
+ jest.useFakeTimers();
142
+ const { EventEmitter } = require("events");
143
+ const stream1 = new EventEmitter();
144
+ stream1.destroy = jest.fn();
145
+ mockAxiosInstance.mockResolvedValueOnce({ data: stream1 });
146
+ const client = createClient();
147
+ client.listen({ events: ["order.created"], reconnect: false }, () => { });
148
+ await Promise.resolve();
149
+ await Promise.resolve();
150
+ stream1.emit("end");
151
+ await Promise.resolve();
152
+ await jest.advanceTimersByTimeAsync(5000);
153
+ expect(mockAxiosInstance).toHaveBeenCalledTimes(1);
154
+ jest.useRealTimers();
155
+ });
156
+ it("passes environment on publish", async () => {
157
+ mockAxiosInstance.mockResolvedValue({
158
+ data: { ok: true, event_id: "evt_env", accepted: true },
159
+ });
160
+ const client = createClient();
161
+ await client.publish("order.created", { id: "1" }, { environment: "dev" });
162
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
163
+ data: expect.objectContaining({
164
+ event: "order.created",
165
+ environment: "dev",
166
+ }),
167
+ }));
168
+ });
169
+ it("keeps instance id stable for this client and distinct across computers", async () => {
170
+ mockAxiosInstance.mockResolvedValue({
171
+ data: {
172
+ ok: true,
173
+ subscription_id: "evt_sub_1",
174
+ events: ["order.created"],
175
+ instance_id: "test-instance",
176
+ },
177
+ });
178
+ const sameBox = createClient();
179
+ await sameBox.subscribe({ events: ["order.created"] });
180
+ await sameBox.subscribe({ events: ["order.created"] });
181
+ const otherBox = createClient({ instanceId: "other-computer" });
182
+ await otherBox.subscribe({ events: ["order.created"] });
183
+ const calls = mockAxiosInstance.mock.calls.filter((c) => c[0]?.url === "/v1/subscribe");
184
+ expect(calls).toHaveLength(3);
185
+ expect(calls[0][0].data.instance_id).toBe("test-instance");
186
+ expect(calls[1][0].data.instance_id).toBe("test-instance");
187
+ expect(calls[2][0].data.instance_id).toBe("other-computer");
188
+ expect(sameBox.instanceId).toBe("test-instance");
189
+ expect(otherBox.instanceId).not.toBe(sameBox.instanceId);
190
+ });
191
+ });
@@ -1 +1,232 @@
1
- 'use strict';const _0x14e0b3=_0x1ad2;(function(_0xb83ce4,_0x44682d){const _0x5a1261=_0x1ad2,_0x134ae7=_0xb83ce4();while(!![]){try{const _0x134fe0=parseInt(_0x5a1261(0x17e))/0x1+-parseInt(_0x5a1261(0x19b))/0x2*(parseInt(_0x5a1261(0x1a5))/0x3)+parseInt(_0x5a1261(0x18c))/0x4*(parseInt(_0x5a1261(0x19f))/0x5)+parseInt(_0x5a1261(0x176))/0x6*(-parseInt(_0x5a1261(0x17c))/0x7)+parseInt(_0x5a1261(0x1ae))/0x8*(parseInt(_0x5a1261(0x1a6))/0x9)+-parseInt(_0x5a1261(0x1b0))/0xa+-parseInt(_0x5a1261(0x16d))/0xb;if(_0x134fe0===_0x44682d)break;else _0x134ae7['push'](_0x134ae7['shift']());}catch(_0x3e404e){_0x134ae7['push'](_0x134ae7['shift']());}}}(_0x2f55,0x91c2a));var __importDefault=this&&this[_0x14e0b3(0x1b3)]||function(_0x17e3b5){const _0x29c9ae=_0x14e0b3;return _0x17e3b5&&_0x17e3b5[_0x29c9ae(0x188)]?_0x17e3b5:{'default':_0x17e3b5};};Object[_0x14e0b3(0x187)](exports,_0x14e0b3(0x188),{'value':!![]});function _0x1ad2(_0x31b049,_0x443475){_0x31b049=_0x31b049-0x16c;const _0x2f5568=_0x2f55();let _0x1ad277=_0x2f5568[_0x31b049];if(_0x1ad2['uucuYr']===undefined){var _0x28d7b4=function(_0x30249a){const _0x5b394e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x17e3b5='',_0x7022ff='';for(let _0x35f292=0x0,_0x2626d8,_0x418461,_0x5801d2=0x0;_0x418461=_0x30249a['charAt'](_0x5801d2++);~_0x418461&&(_0x2626d8=_0x35f292%0x4?_0x2626d8*0x40+_0x418461:_0x418461,_0x35f292++%0x4)?_0x17e3b5+=String['fromCharCode'](0xff&_0x2626d8>>(-0x2*_0x35f292&0x6)):0x0){_0x418461=_0x5b394e['indexOf'](_0x418461);}for(let _0x120647=0x0,_0x217a63=_0x17e3b5['length'];_0x120647<_0x217a63;_0x120647++){_0x7022ff+='%'+('00'+_0x17e3b5['charCodeAt'](_0x120647)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x7022ff);};_0x1ad2['VClRCh']=_0x28d7b4,_0x1ad2['pgLVQN']={},_0x1ad2['uucuYr']=!![];}const _0x3d2429=_0x2f5568[0x0],_0x3bcace=_0x31b049+_0x3d2429,_0x15a846=_0x1ad2['pgLVQN'][_0x3bcace];return!_0x15a846?(_0x1ad277=_0x1ad2['VClRCh'](_0x1ad277),_0x1ad2['pgLVQN'][_0x3bcace]=_0x1ad277):_0x1ad277=_0x15a846,_0x1ad277;}const axios_1=__importDefault(require('axios')),crypto_1=__importDefault(require(_0x14e0b3(0x1a1))),jsonwebtoken_1=__importDefault(require(_0x14e0b3(0x16f))),IdentityAppClient_1=require(_0x14e0b3(0x193)),errors_1=require(_0x14e0b3(0x184)),identity_offline_verify_1=require(_0x14e0b3(0x16e)),identity_token_cache_1=require(_0x14e0b3(0x18f));jest[_0x14e0b3(0x177)]('axios');const mockedAxios=axios_1['default'];describe(_0x14e0b3(0x1b5),()=>{const _0x529230=_0x14e0b3,_0x7022ff=jest['fn']();beforeEach(()=>{const _0x48a0d1=_0x1ad2;jest[_0x48a0d1(0x192)](),mockedAxios['create'][_0x48a0d1(0x198)](_0x7022ff);});function _0x35f292(_0x2626d8){const _0x3aab7c=_0x1ad2;return new IdentityAppClient_1[(_0x3aab7c(0x1b5))]({'baseUrl':'https://api.example.com','appId':_0x3aab7c(0x1b2),'appApiKey':_0x3aab7c(0x1ad),..._0x2626d8});}it(_0x529230(0x17a),()=>{const _0x1badb1=_0x529230;expect(()=>new IdentityAppClient_1[(_0x1badb1(0x1b5))]({'baseUrl':'','appId':_0x1badb1(0x1b2)}))[_0x1badb1(0x19a)](errors_1[_0x1badb1(0x1a3)]),expect(()=>new IdentityAppClient_1[(_0x1badb1(0x1b5))]({'baseUrl':_0x1badb1(0x17f),'appId':''}))[_0x1badb1(0x19a)](errors_1['CliodotApiError']);}),it(_0x529230(0x1b7),async()=>{const _0x6fac07=_0x529230;_0x7022ff[_0x6fac07(0x1aa)]({'data':{'ok':!![],'access_token':_0x6fac07(0x1a7),'token_type':'Bearer','expires_in':0xe10,'caller_app_id':'identity_payroll','target_app_id':_0x6fac07(0x186)}});const _0x418461=_0x35f292(),_0x5801d2=await _0x418461[_0x6fac07(0x171)]({'target_app_id':_0x6fac07(0x186)});expect(_0x5801d2[_0x6fac07(0x199)])['toBe']('jwt'),expect(_0x7022ff)[_0x6fac07(0x185)](expect['objectContaining']({'method':_0x6fac07(0x182),'url':_0x6fac07(0x191),'headers':{'x-cliodot-app-id':_0x6fac07(0x1b2),'Authorization':_0x6fac07(0x172)},'data':{'target_app_id':'identity_hrms'}}));}),it(_0x529230(0x175),async()=>{const _0x11bd7f=_0x529230;_0x7022ff[_0x11bd7f(0x1aa)]({'data':{'ok':!![],'access_token':_0x11bd7f(0x1a7),'token_type':'Bearer','expires_in':0xe10,'caller_app_id':_0x11bd7f(0x1b2),'target_app_id':'identity_hrms'}});const _0x120647=_0x35f292();await _0x120647['authenticate']({'target_app_id':'identity_hrms','scopes':[_0x11bd7f(0x180)]}),expect(_0x7022ff)[_0x11bd7f(0x185)](expect[_0x11bd7f(0x17d)]({'data':{'target_app_id':_0x11bd7f(0x186),'scopes':[_0x11bd7f(0x180)]}})),_0x7022ff[_0x11bd7f(0x1aa)]({'data':{'ok':!![],'valid':!![],'jti':'j1','caller_app_id':_0x11bd7f(0x1b2),'target_app_id':'identity_hrms','expires_at':new Date()['toISOString'](),'claims':{'scope':_0x11bd7f(0x180)}}}),await _0x120647['verify']({'access_token':'jwt','required_scopes':[_0x11bd7f(0x180)]}),expect(_0x7022ff)[_0x11bd7f(0x185)](expect[_0x11bd7f(0x17d)]({'data':{'access_token':_0x11bd7f(0x1a7),'required_scopes':[_0x11bd7f(0x180)]}}));}),it(_0x529230(0x1a4),async()=>{const _0x8c2d90=_0x529230;_0x7022ff['mockResolvedValue']({'data':{'ok':!![],'app':{'_id':_0x8c2d90(0x1b2),'name':'Payroll','slug':_0x8c2d90(0x1b2),'tenant_id':'t1','status':_0x8c2d90(0x1a2)}}});const _0x217a63=_0x35f292({'appApiKey':undefined,'appSecret':_0x8c2d90(0x170)});await _0x217a63['me'](),expect(_0x7022ff)[_0x8c2d90(0x185)](expect[_0x8c2d90(0x17d)]({'method':_0x8c2d90(0x183),'url':_0x8c2d90(0x1b4),'headers':{'x-cliodot-app-id':_0x8c2d90(0x1b2),'x-cliodot-app-secret':_0x8c2d90(0x170)}}));}),it(_0x529230(0x1b9),async()=>{const _0x275fe3=_0x529230;_0x7022ff[_0x275fe3(0x1aa)]({'data':{'ok':![],'error':_0x275fe3(0x16c),'code':_0x275fe3(0x17b)}});const _0x2122bf=_0x35f292();await expect(_0x2122bf[_0x275fe3(0x171)]({'target_app_id':_0x275fe3(0x186)}))['rejects'][_0x275fe3(0x1a8)]({'code':_0x275fe3(0x17b)});}),it(_0x529230(0x194),async()=>{const _0x2a888f=_0x529230;_0x7022ff[_0x2a888f(0x1aa)]({'data':{'keys':[{'kid':'k1','kty':_0x2a888f(0x1bb)}]}});const _0x13b399=_0x35f292(),_0x4fb268=await _0x13b399[_0x2a888f(0x173)](_0x2a888f(0x186));expect(_0x4fb268[_0x2a888f(0x1ac)][0x0][_0x2a888f(0x195)])['toBe']('k1'),expect(_0x7022ff)[_0x2a888f(0x185)](expect[_0x2a888f(0x17d)]({'method':_0x2a888f(0x183),'url':_0x2a888f(0x19d)}));});}),describe('verifyIdentityTokenOffline',()=>{const _0xe50ff3=_0x14e0b3;beforeEach(()=>{const _0x2ee37d=_0x1ad2;(0x0,identity_offline_verify_1[_0x2ee37d(0x1a0)])();}),it(_0xe50ff3(0x190),async()=>{const _0x18e174=_0xe50ff3,_0x3f5593='ijwt_test_secret_value_1234567890',_0x11c52b=jsonwebtoken_1['default'][_0x18e174(0x189)]({'sub':_0x18e174(0x1b2),'jti':'j1','exp':Math[_0x18e174(0x1ba)](Date['now']()/0x3e8)+0x3c},_0x3f5593,{'algorithm':'HS256','noTimestamp':!![]}),_0x1bc23a=await(0x0,identity_offline_verify_1[_0x18e174(0x1b6)])(_0x11c52b,{'algorithm':'HS256','secret':_0x3f5593});expect(_0x1bc23a['jti'])[_0x18e174(0x181)]('j1');}),it(_0xe50ff3(0x18b),async()=>{const _0x5944d2=_0xe50ff3,{publicKey:_0x25835b,privateKey:_0x2e3003}=crypto_1['default'][_0x5944d2(0x19c)](_0x5944d2(0x1b1),{'modulusLength':0x800,'publicKeyEncoding':{'type':_0x5944d2(0x1bf),'format':_0x5944d2(0x1be)},'privateKeyEncoding':{'type':'pkcs8','format':_0x5944d2(0x1be)}}),_0x19751b=crypto_1[_0x5944d2(0x1a9)][_0x5944d2(0x18a)](_0x25835b)[_0x5944d2(0x18d)]({'format':'jwk'}),_0x2b434b=jsonwebtoken_1['default'][_0x5944d2(0x189)]({'sub':_0x5944d2(0x1b2),'jti':'j2','exp':Math[_0x5944d2(0x1ba)](Date[_0x5944d2(0x1b8)]()/0x3e8)+0x3c},_0x2e3003,{'algorithm':_0x5944d2(0x1c0),'keyid':_0x5944d2(0x18e),'noTimestamp':!![]}),_0x403c43=jest['fn']()[_0x5944d2(0x1aa)]({'ok':!![],'json':async()=>({'keys':[{'kty':_0x19751b[_0x5944d2(0x174)]||_0x5944d2(0x1bb),'kid':_0x5944d2(0x18e),'n':_0x19751b['n'],'e':_0x19751b['e'],'alg':_0x5944d2(0x1c0),'use':_0x5944d2(0x179)}]})}),_0x35d9fc=await(0x0,identity_offline_verify_1['verifyIdentityTokenOffline'])(_0x2b434b,{'algorithm':_0x5944d2(0x1c0),'jwksUrl':_0x5944d2(0x197),'fetch':_0x403c43});expect(_0x35d9fc['jti'])[_0x5944d2(0x181)]('j2'),expect(_0x403c43)['toHaveBeenCalled']();}),it('tokenHasScopes\x20checks\x20JWT\x20scope\x20claim',()=>{const _0x5ce3de=_0xe50ff3,_0xbf2e=jsonwebtoken_1[_0x5ce3de(0x1a9)]['sign']({'scope':_0x5ce3de(0x196),'jti':'j'},_0x5ce3de(0x1bd),{'algorithm':_0x5ce3de(0x1bc),'noTimestamp':!![]});expect((0x0,identity_offline_verify_1[_0x5ce3de(0x1ab)])(_0xbf2e,[_0x5ce3de(0x180)]))['toBe'](!![]),expect((0x0,identity_offline_verify_1[_0x5ce3de(0x1ab)])(_0xbf2e,['employees.admin']))[_0x5ce3de(0x181)](![]);});}),describe(_0x14e0b3(0x178),()=>{const _0x53b7c1=_0x14e0b3;it(_0x53b7c1(0x1c1),async()=>{const _0x23a1bb=_0x53b7c1,_0x5cc0fe=jest['fn']()[_0x23a1bb(0x1aa)]({'ok':!![],'access_token':_0x23a1bb(0x19e),'token_type':'Bearer','expires_in':0xe10,'refresh_token':'irt_1','caller_app_id':_0x23a1bb(0x1b2),'target_app_id':'identity_hrms'}),_0x51bcca=jest['fn'](),_0x2b9d3a=(0x0,identity_token_cache_1[_0x23a1bb(0x178)])({'client':{'authenticate':_0x5cc0fe,'refresh':_0x51bcca}}),_0x599643=await _0x2b9d3a[_0x23a1bb(0x1af)]('identity_hrms'),_0x362f18=await _0x2b9d3a[_0x23a1bb(0x1af)](_0x23a1bb(0x186));expect(_0x599643)[_0x23a1bb(0x181)]('at_1'),expect(_0x362f18)['toBe']('at_1'),expect(_0x5cc0fe)['toHaveBeenCalledTimes'](0x1);});});function _0x2f55(){const _0x2b56c6=['A2LK','zw1WBg95zwvZlNjLywqGzw1WBg95zwvZlNDYAxrL','Ahr0Chm6lY9HCgKUzxHHBxbSzs5JB20VAwrLBNrPDhKVDJeVyxbWCY9PzgvUDgL0Ev9OCM1Zl2P3A3mUANnVBG','Bw9JA1jLDhvYBLzHBhvL','ywnJzxnZx3rVA2vU','Dg9uAhjVDW','mM9pC25LCq','z2vUzxjHDgvlzxLqywLYu3LUyW','l3yXl2fWChmVAwrLBNrPDhLFAhjTCY9QD2TZlMPZB24','yxrFmq','nwHHzgzgyW','y2XLyxjjzgvUDgL0EuP3A3ndywnOzq','y3j5ChrV','ywn0AxzL','q2XPB2rVDefWAuvYCM9Y','DxnLCYbHChaGC2vJCMv0igHLywrLCNmGD2HLBIbUBYbHCgKGA2v5','mJeXoda1mu93Bvrfqq','mty1oduYELfTAMnP','AND0','Dg9nyxrJAe9IAMvJDa','zgvMyxvSDa','Bw9JA1jLC29SDMvKvMfSDwu','Dg9Rzw5iyxnty29Wzxm','A2v5CW','AwfRx3rLC3rFA2v5','mJy0wgj2y0zJ','z2v0qwnJzxnZvg9Rzw4','mJq2otK1mhDMBuHjzq','CNnH','AwrLBNrPDhLFCgf5CM9SBa','x19PBxbVCNrezwzHDwX0','l3yXl21L','swrLBNrPDhLbChbdBgLLBNq','DMvYAwz5swrLBNrPDhLuB2TLBK9MzMXPBMu','yxv0AgvUDgLJyxrLCYb3AxrOigjLyxjLCIbHCgKGA2v5','BM93','BwfWCYbbueKGzxjYB3iGy29Kzxm','zMXVB3i','uLnb','sfmYnty','C2vJCMv0','CgvT','C3bRAq','uLmYnty','yxv0AgvUDgLJyxrLCYb0AgvUihjLDxnLCYb1BNrPBcbUzwfYigv4CgLYEq','vgfYz2v0igfWCcbKB2vZig5VDcb0CNvZDcb0AguGy2fSBgvY','mtuXnta2m0jZCNLsqq','lI4VAwrLBNrPDhKTB2zMBgLUzs12zxjPzNK','ANnVBNDLyNrVA2vU','C2vJCMv0x2HLEa','yxv0AgvUDgLJyxrL','qMvHCMvYigLHA190zxn0x2TLEq','z2v0sNDRCW','A3r5','yxv0AgvUDgLJyxrLigfUzcb2zxjPzNKGCgfZCYbZy29Wzxm','nLHRwNL3zW','Bw9JAW','y3jLyxrLswrLBNrPDhLuB2TLBKnHy2HL','C2LN','CMvXDwLYzxmGyMfZzvvYBcbHBMqGyxbWswq','surftLrjvfLFvfjvu1rFrevosuve','mtG2mZG4m3PsEufOva','B2jQzwn0q29UDgfPBMLUzW','otm4nduZyMHVBxre','Ahr0Chm6lY9HCgKUzxHHBxbSzs5JB20','zw1WBg95zwvZlNjLywq','Dg9czq','ue9tva','r0vu','lI4VzxjYB3jZ','Dg9iyxzLqMvLBKnHBgXLzfDPDgG','AwrLBNrPDhLFAhjTCW','zgvMAw5LuhjVCgvYDhK','x19LC01VzhvSzq','C2LNBG','y3jLyxrLuhvIBgLJs2v5','DMvYAwzPzxmGuLmYntyGDMLHiePxs1mGA2LK','mtyYotG4nfvtrfzvyW','zxHWB3j0','A2LKxZe','lI4VAwrLBNrPDhKTDg9Rzw4Ty2fJAgu','DMvYAwzPzxmGsfmYntyGDg9Rzw5Z','l3yXl2f1DgHLBNrPy2f0zq','y2XLyxjbBgXnB2nRCW','lI4VswrLBNrPDhLbChbdBgLLBNq','zMv0y2HLCYbkv0TtihDPDgHVDxqGyxv0AcbOzwfKzxjZ'];_0x2f55=function(){return _0x2b56c6;};return _0x2f55();}
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_1 = __importDefault(require("axios"));
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
+ const IdentityAppClient_1 = require("../IdentityAppClient");
10
+ const errors_1 = require("../errors");
11
+ const identity_offline_verify_1 = require("../identity-offline-verify");
12
+ const identity_token_cache_1 = require("../identity-token-cache");
13
+ jest.mock("axios");
14
+ const mockedAxios = axios_1.default;
15
+ describe("IdentityAppClient", () => {
16
+ const mockAxiosInstance = jest.fn();
17
+ beforeEach(() => {
18
+ jest.clearAllMocks();
19
+ mockedAxios.create.mockReturnValue(mockAxiosInstance);
20
+ });
21
+ function createClient(overrides) {
22
+ return new IdentityAppClient_1.IdentityAppClient({
23
+ baseUrl: "https://api.example.com",
24
+ appId: "identity_payroll",
25
+ appApiKey: "iak_test_key",
26
+ ...overrides,
27
+ });
28
+ }
29
+ it("requires baseUrl and appId", () => {
30
+ expect(() => new IdentityAppClient_1.IdentityAppClient({ baseUrl: "", appId: "identity_payroll" })).toThrow(errors_1.CliodotApiError);
31
+ expect(() => new IdentityAppClient_1.IdentityAppClient({
32
+ baseUrl: "https://api.example.com",
33
+ appId: "",
34
+ })).toThrow(errors_1.CliodotApiError);
35
+ });
36
+ it("authenticates with bearer api key", async () => {
37
+ mockAxiosInstance.mockResolvedValue({
38
+ data: {
39
+ ok: true,
40
+ access_token: "jwt",
41
+ token_type: "Bearer",
42
+ expires_in: 3600,
43
+ caller_app_id: "identity_payroll",
44
+ target_app_id: "identity_hrms",
45
+ },
46
+ });
47
+ const client = createClient();
48
+ const result = await client.authenticate({
49
+ target_app_id: "identity_hrms",
50
+ });
51
+ expect(result.access_token).toBe("jwt");
52
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
53
+ method: "POST",
54
+ url: "/v1/authenticate",
55
+ headers: {
56
+ "x-cliodot-app-id": "identity_payroll",
57
+ Authorization: "Bearer iak_test_key",
58
+ },
59
+ data: { target_app_id: "identity_hrms" },
60
+ }));
61
+ });
62
+ it("authenticate and verify pass scopes", async () => {
63
+ mockAxiosInstance.mockResolvedValue({
64
+ data: {
65
+ ok: true,
66
+ access_token: "jwt",
67
+ token_type: "Bearer",
68
+ expires_in: 3600,
69
+ caller_app_id: "identity_payroll",
70
+ target_app_id: "identity_hrms",
71
+ },
72
+ });
73
+ const client = createClient();
74
+ await client.authenticate({
75
+ target_app_id: "identity_hrms",
76
+ scopes: ["employees.read"],
77
+ });
78
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
79
+ data: {
80
+ target_app_id: "identity_hrms",
81
+ scopes: ["employees.read"],
82
+ },
83
+ }));
84
+ mockAxiosInstance.mockResolvedValue({
85
+ data: {
86
+ ok: true,
87
+ valid: true,
88
+ jti: "j1",
89
+ caller_app_id: "identity_payroll",
90
+ target_app_id: "identity_hrms",
91
+ expires_at: new Date().toISOString(),
92
+ claims: { scope: "employees.read" },
93
+ },
94
+ });
95
+ await client.verify({
96
+ access_token: "jwt",
97
+ required_scopes: ["employees.read"],
98
+ });
99
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
100
+ data: {
101
+ access_token: "jwt",
102
+ required_scopes: ["employees.read"],
103
+ },
104
+ }));
105
+ });
106
+ it("uses app secret headers when no api key", async () => {
107
+ mockAxiosInstance.mockResolvedValue({
108
+ data: {
109
+ ok: true,
110
+ app: {
111
+ _id: "identity_payroll",
112
+ name: "Payroll",
113
+ slug: "identity_payroll",
114
+ tenant_id: "t1",
115
+ status: "active",
116
+ },
117
+ },
118
+ });
119
+ const client = createClient({
120
+ appApiKey: undefined,
121
+ appSecret: "secret_hex",
122
+ });
123
+ await client.me();
124
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
125
+ method: "GET",
126
+ url: "/v1/me",
127
+ headers: {
128
+ "x-cliodot-app-id": "identity_payroll",
129
+ "x-cliodot-app-secret": "secret_hex",
130
+ },
131
+ }));
132
+ });
133
+ it("maps API error codes", async () => {
134
+ mockAxiosInstance.mockResolvedValue({
135
+ data: {
136
+ ok: false,
137
+ error: "Target app does not trust the caller",
138
+ code: "IDENTITY_TRUST_DENIED",
139
+ },
140
+ });
141
+ const client = createClient();
142
+ await expect(client.authenticate({ target_app_id: "identity_hrms" })).rejects.toMatchObject({
143
+ code: "IDENTITY_TRUST_DENIED",
144
+ });
145
+ });
146
+ it("fetches JWKS without auth headers", async () => {
147
+ mockAxiosInstance.mockResolvedValue({
148
+ data: { keys: [{ kid: "k1", kty: "RSA" }] },
149
+ });
150
+ const client = createClient();
151
+ const jwks = await client.getJwks("identity_hrms");
152
+ expect(jwks.keys[0].kid).toBe("k1");
153
+ expect(mockAxiosInstance).toHaveBeenCalledWith(expect.objectContaining({
154
+ method: "GET",
155
+ url: "/v1/apps/identity_hrms/jwks.json",
156
+ }));
157
+ });
158
+ });
159
+ describe("verifyIdentityTokenOffline", () => {
160
+ beforeEach(() => {
161
+ (0, identity_offline_verify_1.clearIdentityJwksCache)();
162
+ });
163
+ it("verifies HS256 tokens", async () => {
164
+ const secret = "ijwt_test_secret_value_1234567890";
165
+ const token = jsonwebtoken_1.default.sign({ sub: "identity_payroll", jti: "j1", exp: Math.floor(Date.now() / 1000) + 60 }, secret, { algorithm: "HS256", noTimestamp: true });
166
+ const claims = await (0, identity_offline_verify_1.verifyIdentityTokenOffline)(token, {
167
+ algorithm: "HS256",
168
+ secret,
169
+ });
170
+ expect(claims.jti).toBe("j1");
171
+ });
172
+ it("verifies RS256 via JWKS kid", async () => {
173
+ const { publicKey, privateKey } = crypto_1.default.generateKeyPairSync("rsa", {
174
+ modulusLength: 2048,
175
+ publicKeyEncoding: { type: "spki", format: "pem" },
176
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
177
+ });
178
+ const jwk = crypto_1.default
179
+ .createPublicKey(publicKey)
180
+ .export({ format: "jwk" });
181
+ const token = jsonwebtoken_1.default.sign({ sub: "identity_payroll", jti: "j2", exp: Math.floor(Date.now() / 1000) + 60 }, privateKey, { algorithm: "RS256", keyid: "kid_1", noTimestamp: true });
182
+ const fetchImpl = jest.fn().mockResolvedValue({
183
+ ok: true,
184
+ json: async () => ({
185
+ keys: [
186
+ {
187
+ kty: jwk.kty || "RSA",
188
+ kid: "kid_1",
189
+ n: jwk.n,
190
+ e: jwk.e,
191
+ alg: "RS256",
192
+ use: "sig",
193
+ },
194
+ ],
195
+ }),
196
+ });
197
+ const claims = await (0, identity_offline_verify_1.verifyIdentityTokenOffline)(token, {
198
+ algorithm: "RS256",
199
+ jwksUrl: "https://api.example.com/identity/v1/apps/identity_hrms/jwks.json",
200
+ fetch: fetchImpl,
201
+ });
202
+ expect(claims.jti).toBe("j2");
203
+ expect(fetchImpl).toHaveBeenCalled();
204
+ });
205
+ it("tokenHasScopes checks JWT scope claim", () => {
206
+ const token = jsonwebtoken_1.default.sign({ scope: "employees.read employees.write", jti: "j" }, "secret", { algorithm: "HS256", noTimestamp: true });
207
+ expect((0, identity_offline_verify_1.tokenHasScopes)(token, ["employees.read"])).toBe(true);
208
+ expect((0, identity_offline_verify_1.tokenHasScopes)(token, ["employees.admin"])).toBe(false);
209
+ });
210
+ });
211
+ describe("createIdentityTokenCache", () => {
212
+ it("authenticates then reuses until near expiry", async () => {
213
+ const authenticate = jest.fn().mockResolvedValue({
214
+ ok: true,
215
+ access_token: "at_1",
216
+ token_type: "Bearer",
217
+ expires_in: 3600,
218
+ refresh_token: "irt_1",
219
+ caller_app_id: "identity_payroll",
220
+ target_app_id: "identity_hrms",
221
+ });
222
+ const refresh = jest.fn();
223
+ const cache = (0, identity_token_cache_1.createIdentityTokenCache)({
224
+ client: { authenticate, refresh },
225
+ });
226
+ const first = await cache.getAccessToken("identity_hrms");
227
+ const second = await cache.getAccessToken("identity_hrms");
228
+ expect(first).toBe("at_1");
229
+ expect(second).toBe("at_1");
230
+ expect(authenticate).toHaveBeenCalledTimes(1);
231
+ });
232
+ });