@automationcloud/client
Advanced tools
Comparing version 1.3.0 to 1.4.2
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.AutomationCloud=e():t.AutomationCloud=e()}(self,(function(){return t={739:t=>{self,t.exports=(()=>{"use strict";var t={300:(t,e)=>{var s=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==s)return s;throw new Error("unable to locate global object")}();t.exports=e=s.fetch,s.fetch&&(e.default=s.fetch.bind(s)),e.Headers=s.Headers,e.Request=s.Request,e.Response=s.Response},395:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthAgent=void 0,e.AuthAgent=class{}},614:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BasicAuthAgent=void 0;const n=s(395),r=s(20);class o extends n.AuthAgent{constructor(t){super(),this.params=t}async getHeader(){const{username:t,password:e}=this.params,s=`${t}:${e}`;return"Basic "+r.toBase64(s)}invalidate(){}}e.BasicAuthAgent=o},924:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BearerAuthAgent=void 0;const n=s(395);class r extends n.AuthAgent{constructor(t){super(),this.params=t}async getHeader(){const{prefix:t="Bearer",token:e}=this.params;return e?`${t} ${e}`:null}invalidate(){}}e.BearerAuthAgent=r},12:function(t,e,s){var n=this&&this.__createBinding||(Object.create?function(t,e,s,n){void 0===n&&(n=s),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[s]}})}:function(t,e,s,n){void 0===n&&(n=s),t[n]=e[s]}),r=this&&this.__exportStar||function(t,e){for(var s in t)"default"===s||e.hasOwnProperty(s)||n(e,t,s)};Object.defineProperty(e,"__esModule",{value:!0}),r(s(26),e),r(s(614),e),r(s(924),e),r(s(890),e),r(s(658),e)},26:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.NoAuthAgent=void 0;const n=s(395);class r extends n.AuthAgent{async getHeader(){return null}invalidate(){}}e.NoAuthAgent=r},890:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthNotSupportedError=e.OAuth1Agent=void 0;const n=s(395),r=s(222);class o extends n.AuthAgent{async getHeader(t){throw new i}invalidate(){}}e.OAuth1Agent=o;class i extends r.Exception{constructor(){super("This auth agent is not supported in browser environment.")}}e.AuthNotSupportedError=i},658:function(t,e,s){var n=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Agent=e.OAuth2GrantType=void 0;const r=s(458),o=n(s(91)),i=s(395);var a;!function(t){t.CLIENT_CREDENTIALS="client_credentials",t.REFRESH_TOKEN="refresh_token",t.AUTHORIZATION_CODE="authorization_code",t.PASSWORD="password"}(a=e.OAuth2GrantType||(e.OAuth2GrantType={}));class c extends i.AuthAgent{constructor(t){super(),this.params=Object.assign({fetch:o.default},t)}async getHeader(){const t=await this.getAccessToken();return t?"Bearer "+t:null}async createToken(t){const{tokenUrl:e,fetch:s}=this.params,n=new r.Request({fetch:s}),o=Object.entries(t).filter((([t,e])=>null!=e)),i=await n.send("post",e,{body:new URLSearchParams(o)}),a=await i.json();return{accessToken:a.access_token,accessExpiresIn:a.expires_in,refreshToken:a.refresh_token}}setTokens(t){const{accessToken:e,accessExpiresIn:s,refreshToken:n}=t,r=s?Date.now()+1e3*s:null;this.params.accessToken=e,this.params.expiresAt=r,n&&(this.params.refreshToken=n)}invalidate(){this.params.accessToken=null,this.params.expiresAt=null}async getAccessToken(){const t=[this.tryCachedAccessToken,this.tryRefreshToken,this.tryClientSecret];for(const e of t)try{const t=await e.call(this);if(t)return t}catch(t){this.invalidate()}return null}async tryCachedAccessToken(){const{accessToken:t,expiresAt:e,minValiditySeconds:s=300}=this.params,n=null!=e&&e-1e3*s>Date.now();return t&&n?t:null}async tryRefreshToken(){const{refreshToken:t,clientId:e,clientSecret:s}=this.params;if(!t)return null;try{const n=await this.createToken({grant_type:a.REFRESH_TOKEN,client_id:e,client_secret:s,refresh_token:t});return this.setTokens(n),n.accessToken}catch(t){throw this.params.refreshToken=null,t}}async tryClientSecret(){const{clientId:t,clientSecret:e}=this.params;if(!e)return null;const s=await this.createToken({grant_type:a.CLIENT_CREDENTIALS,client_id:t,client_secret:e});return this.setTokens(s),s.accessToken}}e.OAuth2Agent=c},222:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Exception=void 0;class s extends Error{constructor(){super(...arguments),this.name=this.constructor.name,this.status=500,this.details={}}}e.Exception=s},91:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default="undefined"!=typeof window&&window.fetch?fetch.bind(window):s(300)},863:function(t,e,s){var n=this&&this.__createBinding||(Object.create?function(t,e,s,n){void 0===n&&(n=s),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[s]}})}:function(t,e,s,n){void 0===n&&(n=s),t[n]=e[s]}),r=this&&this.__exportStar||function(t,e){for(var s in t)"default"===s||e.hasOwnProperty(s)||n(e,t,s)},o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.Response=void 0,r(s(458),e),r(s(12),e),r(s(157),e),r(s(687),e);const i=o(s(210));e.Response=i.default},458:function(t,e,s){var n=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.RequestFailedError=e.Request=e.DEFAULT_REQUEST_CONFIG=e.NETWORK_ERRORS=void 0;const r=s(222),o=s(12),i=n(s(91));e.NETWORK_ERRORS=["EAI_AGAIN","EHOSTDOWN","EHOSTUNREACH","ECONNABORTED","ECONNREFUSED","ECONNRESET","EPIPE"],e.DEFAULT_REQUEST_CONFIG={baseUrl:"",auth:new o.NoAuthAgent,retryAttempts:4,retryDelay:500,retryDelayIncrement:500,retryStatusCodes:[429,502,503,504],authInvalidateStatusCodes:[401,403],authInvalidateInterval:6e4,headers:{},fetch:i.default},e.Request=class{constructor(t){this.authInvalidatedAt=0,this.config=Object.assign(Object.assign({},e.DEFAULT_REQUEST_CONFIG),t)}async get(t,e={}){return await this.sendJson("get",t,e)}async post(t,e={}){return await this.sendJson("post",t,e)}async put(t,e={}){return await this.sendJson("put",t,e)}async delete(t,e={}){return await this.sendJson("delete",t,e)}async sendJson(t,e,s={}){const{body:n,query:r,headers:o}=s,i=await this.send(t,e,{headers:Object.assign({"content-type":"application/json"},o),query:r,body:n?JSON.stringify(n):null}),{status:a}=i;return 204===a||"0"===i.headers.get("content-length")?null:await i.json()}async send(t,s,n={}){var r,o,i;const{fetch:a}=this.config,c=Math.max(this.config.retryAttempts+1,1);let u,l;for(let h=0;h<c;h++){let c=!1,d=this.config.retryDelay+this.config.retryDelayIncrement*h;try{const e=await this.prepareRequestSpec(t,s,n),r=await a(e.url,{method:e.method,headers:e.headers,body:e.body});if(!r.ok)throw this.config.authInvalidateStatusCodes.includes(r.status)?(c=Date.now()-this.authInvalidatedAt>this.config.authInvalidateInterval,this.authInvalidatedAt=Date.now(),d=0,this.config.auth.invalidate()):c=this.config.retryStatusCodes.includes(r.status),await this.createErrorFromResponse(e,r);return r}catch(a){const h=null===(r=a.details)||void 0===r?void 0:r.status,p=null===(o=a.details)||void 0===o?void 0:o.statusText,f={method:t,url:s,headers:null!==(i=n.headers)&&void 0!==i?i:{},status:h,statusText:p};if(c||e.NETWORK_ERRORS.includes(a.code)){u=a,l=f,this.onRetry(a,f),await new Promise((t=>setTimeout(t,d)));continue}throw this.onError(a,f),a}}throw this.onError(u,l),u}async sendRaw(t,e,s={}){const n=await this.prepareRequestSpec(t,e,s),{fetch:r}=this.config;return await r(n.url,{method:n.method,headers:n.headers,body:n.body})}async prepareRequestSpec(t,e,s={}){var n,r;const{auth:o}=this.config,{body:i}=s,a=this.prepareUrl(e,s),c=null!==(n=await o.getHeader({url:a,method:t,body:i}))&&void 0!==n?n:"";return{method:t,url:a,headers:this.mergeHeaders({"content-type":null!==(r=this.inferContentTypeFromBody(i))&&void 0!==r?r:""},this.config.headers||{},{authorization:c},s.headers||{}),body:i}}prepareUrl(t,e){var s;const{baseUrl:n}=this.config,r=n&&"/"!==n.slice(-1)?n+"/":n,o=new URL("/"===t[0]?t.slice(1):t,r||void 0);return o.search=new URLSearchParams(Object.entries(null!==(s=e.query)&&void 0!==s?s:{})).toString(),o.toString()}inferContentTypeFromBody(t){switch(!0){case null==t:return null;case t instanceof URLSearchParams:return"application/x-www-form-urlencoded";case"object"==typeof t:return"application/json";case"string"==typeof t:return"text/plain";default:return null}}mergeHeaders(...t){const e={};for(const s of t)for(const[t,n]of Object.entries(s))n&&(e[t.toLowerCase()]=n);return e}async createErrorFromResponse(t,e){return new a(t,e)}onRetry(t,e){}onError(t,e){}};class a extends r.Exception{constructor(t,e){super(`Request failed: ${e.status} ${e.statusText}`),this.details={method:t.method,url:t.url,requestHeaders:t.headers,status:e.status,statusText:e.statusText},Object.defineProperty(this,"requestSpec",{enumerable:!1,value:t}),Object.defineProperty(this,"response",{enumerable:!1,value:e})}}e.RequestFailedError=a},210:(t,e,s)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default="undefined"==typeof Response?s(300).Response:Response},157:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},20:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.toBase64=void 0,e.toBase64=function(t){return btoa(t)}},687:function(t,e,s){var n=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.fetchMock=void 0;const r=n(s(210));e.fetchMock=function(t,e={},s){const n={called:!1,calledCount:0,params:[]},o=(o,i)=>new Promise(((a,c)=>{const u=Object.assign({status:200},t);if(n.called=!0,n.calledCount+=1,n.params.push({fullUrl:o,fetchOptions:i}),s)return c(s);a(new r.default(JSON.stringify(e),u))}));return o.spy=n,o}}},e={};return function s(n){if(e[n])return e[n].exports;var r=e[n]={exports:{}};return t[n].call(r.exports,r,r.exports,s),r.exports}(863)})()},729:t=>{"use strict";var e=Object.prototype.hasOwnProperty,s="~";function n(){}function r(t,e,s){this.fn=t,this.context=e,this.once=s||!1}function o(t,e,n,o,i){if("function"!=typeof n)throw new TypeError("The listener must be a function");var a=new r(n,o||t,i),c=s?s+e:e;return t._events[c]?t._events[c].fn?t._events[c]=[t._events[c],a]:t._events[c].push(a):(t._events[c]=a,t._eventsCount++),t}function i(t,e){0==--t._eventsCount?t._events=new n:delete t._events[e]}function a(){this._events=new n,this._eventsCount=0}Object.create&&(n.prototype=Object.create(null),(new n).__proto__||(s=!1)),a.prototype.eventNames=function(){var t,n,r=[];if(0===this._eventsCount)return r;for(n in t=this._events)e.call(t,n)&&r.push(s?n.slice(1):n);return Object.getOwnPropertySymbols?r.concat(Object.getOwnPropertySymbols(t)):r},a.prototype.listeners=function(t){var e=s?s+t:t,n=this._events[e];if(!n)return[];if(n.fn)return[n.fn];for(var r=0,o=n.length,i=new Array(o);r<o;r++)i[r]=n[r].fn;return i},a.prototype.listenerCount=function(t){var e=s?s+t:t,n=this._events[e];return n?n.fn?1:n.length:0},a.prototype.emit=function(t,e,n,r,o,i){var a=s?s+t:t;if(!this._events[a])return!1;var c,u,l=this._events[a],h=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),h){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,r),!0;case 5:return l.fn.call(l.context,e,n,r,o),!0;case 6:return l.fn.call(l.context,e,n,r,o,i),!0}for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];l.fn.apply(l.context,c)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(t,l[u].fn,void 0,!0),h){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,e);break;case 3:l[u].fn.call(l[u].context,e,n);break;case 4:l[u].fn.call(l[u].context,e,n,r);break;default:if(!c)for(d=1,c=new Array(h-1);d<h;d++)c[d-1]=arguments[d];l[u].fn.apply(l[u].context,c)}}return!0},a.prototype.on=function(t,e,s){return o(this,t,e,s,!1)},a.prototype.once=function(t,e,s){return o(this,t,e,s,!0)},a.prototype.removeListener=function(t,e,n,r){var o=s?s+t:t;if(!this._events[o])return this;if(!e)return i(this,o),this;var a=this._events[o];if(a.fn)a.fn!==e||r&&!a.once||n&&a.context!==n||i(this,o);else{for(var c=0,u=[],l=a.length;c<l;c++)(a[c].fn!==e||r&&!a[c].once||n&&a[c].context!==n)&&u.push(a[c]);u.length?this._events[o]=1===u.length?u[0]:u:i(this,o)}return this},a.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&i(this,e)):(this._events=new n,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=s,a.EventEmitter=a,t.exports=a},330:(t,e,s)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.AcRequest=e.AcApi=void 0;const n=s(739);e.AcApi=class{constructor(t){this.params=t;const e="string"==typeof t.auth?new n.BasicAuthAgent({username:t.auth}):new n.OAuth2Agent({clientId:t.auth.clientId,clientSecret:t.auth.clientSecret,tokenUrl:t.apiTokenUrl});this.request=new r({baseUrl:t.apiUrl,auth:e,retryAttempts:t.requestRetryCount,retryDelay:t.requestRetryDelay})}async createJob(t){const{serviceId:e,category:s,input:n}=t;return await this.request.post("/jobs",{body:{serviceId:e,category:s,input:n}})}async getJob(t){return await this.request.get(`/jobs/${t}`)}async getJobAccessToken(t){return(await this.request.get(`/jobs/${t}/end-user`)).token}async getJobEvents(t,e){const{data:s}=await this.request.get(`/jobs/${t}/events`,{query:{offset:e}});return s}async getJobOutputData(t,e){var s;try{return await this.request.get(`/jobs/${t}/outputs/${e}`)}catch(t){if(404===(null===(s=t.details)||void 0===s?void 0:s.status))return null;throw t}}async sendJobInput(t,e,s){return await this.request.post(`/jobs/${t}/inputs`,{body:{key:e,data:s}})}async cancelJob(t){await this.request.post(`/jobs/${t}/cancel`)}async queryPreviousOutputs(t,e,s=[]){const{data:n}=await this.request.post(`/services/${t}/previous-job-outputs`,{body:{inputs:s},query:{key:e}});return n}};class r extends n.Request{async createErrorFromResponse(t,e){var s;if(null===(s=e.headers.get("content-type"))||void 0===s?void 0:s.startsWith("application/json")){const t=await e.json();if(t.name&&t.message){const e=new Error(t.message);return e.name=t.name,e.code=t.code,e.details=t.details,e}}return super.createErrorFromResponse(t,e)}}e.AcRequest=r},967:(t,e,s)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Client=void 0;const n=s(330),r=s(909),o=s(157),i=s(894);e.Client=class{constructor(t){this.logger=console,this.config=Object.assign({apiUrl:"https://api.automationcloud.net",apiTokenUrl:"https://auth.automationcloud.net/auth/realms/automationcloud/protocol/openid-connect/token",vaultUrl:"https://vault.automationcloud.net",pollInterval:1e3,requestRetryCount:4,requestRetryDelay:500,autoTrack:!0},t),this.api=new n.AcApi({logger:this.logger,apiTokenUrl:this.config.apiTokenUrl,apiUrl:this.config.apiUrl,auth:this.config.auth,requestRetryCount:this.config.requestRetryCount,requestRetryDelay:this.config.requestRetryDelay}),this.vault=new i.Vault(this)}async getJob(t){const e=new r.Job(this);return await e.trackExisting(t),e}async queryPreviousOutput(t,e=[]){const s=await this.api.queryPreviousOutputs(this.config.serviceId,t,e);return s.length?s[0]:null}async createJob(t={}){return await this._createJob(Object.assign({category:o.JobCategory.TEST,input:{}},t))}async _createJob(t){const e=new r.Job(this,t);return await e.start(),e}}},313:(t,e,s)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.JobTrackError=e.JobFailedError=e.JobMissingOutputsError=e.JobAlreadyStartedError=e.JobNotInitializedError=void 0;const n=s(222);class r extends n.Exception{constructor(){super("Invalid state: job not yet initialized")}}e.JobNotInitializedError=r;class o extends n.Exception{constructor(t={}){super("Job is already initialized"),this.details=t}}e.JobAlreadyStartedError=o;class i extends n.Exception{constructor(t,e={}){super(t),this.message=t,this.details=e}}e.JobMissingOutputsError=i;class a extends n.Exception{constructor(t){var e,s,n;super(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"),this.name=null!==(s=null==t?void 0:t.code)&&void 0!==s?s:"UnknownError",this.details=Object.assign({category:null!==(n=null==t?void 0:t.category)&&void 0!==n?n:"server"},null==t?void 0:t.details)}}e.JobFailedError=a;class c extends n.Exception{constructor(t){super(`Job tracking failed: ${t.message}`),this.cause=t}}e.JobTrackError=c},222:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Exception=void 0;class s extends Error{constructor(){super(...arguments),this.name=this.constructor.name,this.status=500,this.details={}}}e.Exception=s},863:function(t,e,s){"use strict";var n=this&&this.__createBinding||(Object.create?function(t,e,s,n){void 0===n&&(n=s),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[s]}})}:function(t,e,s,n){void 0===n&&(n=s),t[n]=e[s]}),r=this&&this.__exportStar||function(t,e){for(var s in t)"default"===s||Object.prototype.hasOwnProperty.call(e,s)||n(e,t,s)};Object.defineProperty(e,"__esModule",{value:!0}),r(s(330),e),r(s(967),e),r(s(222),e),r(s(313),e),r(s(909),e),r(s(273),e),r(s(157),e),r(s(894),e)},909:function(t,e,s){"use strict";var n=this&&this.__createBinding||(Object.create?function(t,e,s,n){void 0===n&&(n=s),Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[s]}})}:function(t,e,s,n){void 0===n&&(n=s),t[n]=e[s]}),r=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),o=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var s in t)"default"!==s&&Object.prototype.hasOwnProperty.call(t,s)&&n(e,t,s);return r(e,t),e};Object.defineProperty(e,"__esModule",{value:!0}),e.Job=void 0;const i=s(729),a=o(s(313)),c=s(157);e.Job=class{constructor(t,e={}){this.client=t,this._events=new i.EventEmitter,this._inputsMap=new Map,this._outputsMap=new Map,this._state=c.JobState.CREATED,this._error=null,this._awaitingInputKey=null,this._trackPromise=null,this._jobId=null,this._jobEventOffset=0,this._isTracking=!1,this._initParams=Object.assign({category:c.JobCategory.TEST,input:{}},e)}get jobId(){if(!this._jobId)throw new a.JobNotInitializedError;return this._jobId}async start(){if(this._jobId)throw new a.JobAlreadyStartedError(this.jobId);const{category:t,input:e}=this._initParams,{serviceId:s}=this.client.config,{id:n,state:r}=await this.api.createJob({serviceId:s,category:t,input:e});this._jobId=n,this._setState(r);for(const[t,s]of Object.entries(e))this._inputsMap.set(t,{key:t,data:s});this.client.config.autoTrack&&this.startTracking()}async trackExisting(t){if(this._jobId)throw new a.JobAlreadyStartedError({jobId:this.jobId});const{state:e,category:s}=await this.api.getJob(t);this._jobId=t,this._initParams.category=s,this._setState(e),this.startTracking()}startTracking(){this._trackPromise||(this._isTracking=!0,this._trackPromise=this._track(),this._trackPromise.catch((t=>{})).then((()=>{this._isTracking=!1,this._trackPromise=null})))}stopTracking(){this._isTracking=!1}getState(){return this._state}_setState(t){const e=this._state;this._state=t,this._events.emit("stateChanged",t,e)}getErrorInfo(){return this._error}getAwaitingInputKey(){return this._awaitingInputKey}async getAccessToken(){return await this.api.getJobAccessToken(this.jobId)}async submitInput(t,e){await this.api.sendJobInput(this.jobId,t,e),this._inputsMap.set(t,{key:t,data:e})}async getOutput(t){const e=this._outputsMap.get(t);if(e)return e.data;const s=await this.api.getJobOutputData(this.jobId,t);return null==s?void 0:s.data}async waitForCompletion(){await this._trackPromise}async cancel(){await this.api.cancelJob(this.jobId)}async waitForOutputs(...t){return new Promise(((e,s)=>{const n=()=>{const s=this._checkOutputs(t);s&&(c(),e(s))},r=()=>{c(),s(new a.JobMissingOutputsError("Job succeded, but specified outputs were not emitted",{keys:t,jobId:this.jobId}))},o=()=>{c(),s(new a.JobMissingOutputsError("Job failed, and specified outputs were not emitted",{keys:t,jobId:this.jobId}))},i=t=>{c(),s(t)},c=()=>{this._events.off("output",n),this._events.off("success",r),this._events.off("fail",o),this._events.off("trackError",i)};this._events.on("output",n),this._events.on("success",r),this._events.on("fail",o),this._events.on("trackError",i),n()}))}onAwaitingInput(t,e){return this._createJobEventHandler("awaitingInput",(async s=>{if("*"===t||s===t){const n=await e(s);void 0!==n&&await this.submitInput(t,n)}}))}onOutput(t,e){return this._createJobEventHandler("output",(async s=>{s.key===t&&await e(s.data)}))}onAnyOutput(t){return this._createJobEventHandler("output",(async e=>{await t(e.key,e.data)}))}onStateChanged(t){return this._createJobEventHandler("stateChanged",t)}onSuccess(t){return this._createJobEventHandler("success",t)}onFail(t){return this._createJobEventHandler("fail",t)}async _track(){for(;this._isTracking;){const{pollInterval:t}=this.client.config;try{const t=await this.api.getJobEvents(this.jobId,this._jobEventOffset);this._jobEventOffset+=t.length;for(const e of t)await this._processJobEvent(e)}catch(t){const e=new a.JobTrackError(t);throw this._events.emit("trackError",e),e}switch(this._state){case c.JobState.SUCCESS:return;case c.JobState.FAIL:throw new a.JobFailedError(this._error)}await new Promise((e=>setTimeout(e,t)))}}async _processJobEvent(t){const e=t.key;switch(t.name){case"awaitingInput":this._setState(c.JobState.AWAITING_INPUT),this._awaitingInputKey=e,this._events.emit("awaitingInput",e);break;case"createOutput":{const t=await this.api.getJobOutputData(this.jobId,e);if(t){const s=t.data;this._outputsMap.set(e,{key:e,data:s}),this._events.emit("output",{key:e,data:s})}}break;case"processing":this._setState(c.JobState.PROCESSING);break;case"success":this._setState(c.JobState.SUCCESS),this._events.emit("success");break;case"fail":{const{error:t}=await this.api.getJob(this.jobId);this._setState(c.JobState.FAIL),this._error=Object.assign({category:"server",code:"UnknownError",message:"Unknown error"},t);const e=new a.JobFailedError(this._error);this._events.emit("fail",e)}}}_checkOutputs(t){const e=[];for(const s of t){const t=this._outputsMap.get(s);if(!t)break;e.push(t.data)}return e.length===t.length?e:null}get api(){return this.client.api}_createJobEventHandler(t,e){const s=async(...t)=>{await e(...t)};return this._events.on(t,s),()=>this._events.off(t,s)}}},273:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0})},157:(t,e)=>{"use strict";var s,n;Object.defineProperty(e,"__esModule",{value:!0}),e.JobCategory=e.JobState=void 0,(n=e.JobState||(e.JobState={})).CREATED="created",n.SCHEDULED="scheduled",n.PROCESSING="processing",n.AWAITING_INPUT="awaitingInput",n.AWAITING_TDS="awaitingTds",n.PENDING="pending",n.SUCCESS="success",n.FAIL="fail",(s=e.JobCategory||(e.JobCategory={})).LIVE="live",s.TEST="test"},894:(t,e,s)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Vault=void 0;const n=s(739);function r(t){return"string"==typeof t?t:[t.name,t.label,t.placeholder].map((t=>t.replace(/_/g,""))).join("_")}e.Vault=class{constructor(t){this.client=t;const{config:e}=t,s="string"==typeof e.auth?new n.BasicAuthAgent({username:e.auth}):new n.OAuth2Agent({clientId:e.auth.clientId,clientSecret:e.auth.clientSecret,tokenUrl:e.apiTokenUrl});this.request=new n.Request({baseUrl:e.vaultUrl,auth:s})}get api(){return this.client.api}async createOtp(){const{id:t}=await this.request.post("/otp");return t}async createPanToken(t,e){const s=null!=e?e:await this.createOtp(),{panToken:n}=await this.request.post("/pan",{body:{otp:s,pan:t}});return n}getPaymentIframeUrl(t,e={}){var s,n,o;const i=[["otp",t],["css",e.cssUrl],["name",e.name],["fields",null===(s=e.fields)||void 0===s?void 0:s.map(r).join(",")],["brands",null===(n=e.brands)||void 0===n?void 0:n.join(",")],["validateOnInput",!0===e.validateOnInput?"on":void 0]].filter((t=>null!=t[1]));return(null!==(o=e.iframeUrl)&&void 0!==o?o:"https://vault.automationcloud.net/forms/index.html")+"?"+i.map((t=>{var e;return`${t[0]}=${encodeURIComponent(null!==(e=t[1])&&void 0!==e?e:"")}`})).join("&")}getSingleInputIframeUrl(t,e={}){var s;const n=[["otp",t],["css",e.cssUrl],["inputType",e.inputType],["pattern",e.pattern],["minlength",e.minlength],["maxlength",e.maxlength],["required",e.required],["validateOnInput",!0===e.validateOnInput?"on":void 0]].filter((t=>null!=t[1]));return(null!==(s=e.iframeUrl)&&void 0!==s?s:"https://vault.automationcloud.net/forms/single-input.html")+"?"+n.map((t=>{var e;return`${t[0]}=${encodeURIComponent(null!==(e=t[1])&&void 0!==e?e:"")}`})).join("&")}}}},e={},function s(n){if(e[n])return e[n].exports;var r=e[n]={exports:{}};return t[n].call(r.exports,r,r.exports,s),r.exports}(863);var t,e})); | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.AutomationCloud=e():t.AutomationCloud=e()}(self,(function(){return t={739:t=>{self,t.exports=(()=>{"use strict";var t={300:(t,e)=>{var n=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==n)return n;throw new Error("unable to locate global object")}();t.exports=e=n.fetch,n.fetch&&(e.default=n.fetch.bind(n)),e.Headers=n.Headers,e.Request=n.Request,e.Response=n.Response},395:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthAgent=void 0,e.AuthAgent=class{}},614:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BasicAuthAgent=void 0;const s=n(395),r=n(20);class o extends s.AuthAgent{constructor(t){super(),this.params=t}async getHeader(){const{username:t,password:e}=this.params,n=`${t}:${e}`;return"Basic "+r.toBase64(n)}invalidate(){}}e.BasicAuthAgent=o},924:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.BearerAuthAgent=void 0;const s=n(395);class r extends s.AuthAgent{constructor(t){super(),this.params=t}async getHeader(){const{prefix:t="Bearer",token:e}=this.params;return e?`${t} ${e}`:null}invalidate(){}}e.BearerAuthAgent=r},12:function(t,e,n){var s=this&&this.__createBinding||(Object.create?function(t,e,n,s){void 0===s&&(s=n),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,s){void 0===s&&(s=n),t[s]=e[n]}),r=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||e.hasOwnProperty(n)||s(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),r(n(26),e),r(n(614),e),r(n(924),e),r(n(890),e),r(n(658),e)},26:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.NoAuthAgent=void 0;const s=n(395);class r extends s.AuthAgent{async getHeader(){return null}invalidate(){}}e.NoAuthAgent=r},890:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.AuthNotSupportedError=e.OAuth1Agent=void 0;const s=n(395),r=n(222);class o extends s.AuthAgent{async getHeader(t){throw new a}invalidate(){}}e.OAuth1Agent=o;class a extends r.Exception{constructor(){super("This auth agent is not supported in browser environment.")}}e.AuthNotSupportedError=a},658:function(t,e,n){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.OAuth2Agent=e.OAuth2GrantType=void 0;const r=n(458),o=s(n(91)),a=n(395);var i;!function(t){t.CLIENT_CREDENTIALS="client_credentials",t.REFRESH_TOKEN="refresh_token",t.AUTHORIZATION_CODE="authorization_code",t.PASSWORD="password"}(i=e.OAuth2GrantType||(e.OAuth2GrantType={}));class c extends a.AuthAgent{constructor(t){super(),this.params=Object.assign({fetch:o.default},t)}async getHeader(){const t=await this.getAccessToken();return t?"Bearer "+t:null}async createToken(t){const{tokenUrl:e,fetch:n}=this.params,s=new r.Request({fetch:n}),o=Object.entries(t).filter((([t,e])=>null!=e)),a=await s.send("post",e,{body:new URLSearchParams(o)}),i=await a.json();return{accessToken:i.access_token,accessExpiresIn:i.expires_in,refreshToken:i.refresh_token}}setTokens(t){const{accessToken:e,accessExpiresIn:n,refreshToken:s}=t,r=n?Date.now()+1e3*n:null;this.params.accessToken=e,this.params.expiresAt=r,s&&(this.params.refreshToken=s)}invalidate(){this.params.accessToken=null,this.params.expiresAt=null}async getAccessToken(){const t=[this.tryCachedAccessToken,this.tryRefreshToken,this.tryClientSecret];for(const e of t)try{const t=await e.call(this);if(t)return t}catch(t){this.invalidate()}return null}async tryCachedAccessToken(){const{accessToken:t,expiresAt:e,minValiditySeconds:n=300}=this.params,s=null!=e&&e-1e3*n>Date.now();return t&&s?t:null}async tryRefreshToken(){const{refreshToken:t,clientId:e,clientSecret:n}=this.params;if(!t)return null;try{const s=await this.createToken({grant_type:i.REFRESH_TOKEN,client_id:e,client_secret:n,refresh_token:t});return this.setTokens(s),s.accessToken}catch(t){throw this.params.refreshToken=null,t}}async tryClientSecret(){const{clientId:t,clientSecret:e}=this.params;if(!e)return null;const n=await this.createToken({grant_type:i.CLIENT_CREDENTIALS,client_id:t,client_secret:e});return this.setTokens(n),n.accessToken}}e.OAuth2Agent=c},222:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Exception=void 0;class n extends Error{constructor(){super(...arguments),this.name=this.constructor.name,this.status=500,this.details={}}}e.Exception=n},91:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default="undefined"!=typeof window&&window.fetch?fetch.bind(window):n(300)},863:function(t,e,n){var s=this&&this.__createBinding||(Object.create?function(t,e,n,s){void 0===s&&(s=n),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,s){void 0===s&&(s=n),t[s]=e[n]}),r=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||e.hasOwnProperty(n)||s(e,t,n)},o=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.Response=void 0,r(n(458),e),r(n(12),e),r(n(157),e),r(n(687),e);const a=o(n(210));e.Response=a.default},458:function(t,e,n){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.RequestFailedError=e.Request=e.DEFAULT_REQUEST_CONFIG=e.NETWORK_ERRORS=void 0;const r=n(222),o=n(12),a=s(n(91));e.NETWORK_ERRORS=["EAI_AGAIN","EHOSTDOWN","EHOSTUNREACH","ECONNABORTED","ECONNREFUSED","ECONNRESET","EPIPE"],e.DEFAULT_REQUEST_CONFIG={baseUrl:"",auth:new o.NoAuthAgent,retryAttempts:4,retryDelay:500,retryDelayIncrement:500,retryStatusCodes:[429,502,503,504],authInvalidateStatusCodes:[401,403],authInvalidateInterval:6e4,headers:{},fetch:a.default},e.Request=class{constructor(t){this.authInvalidatedAt=0,this.config=Object.assign(Object.assign({},e.DEFAULT_REQUEST_CONFIG),t)}async get(t,e={}){return await this.sendJson("get",t,e)}async post(t,e={}){return await this.sendJson("post",t,e)}async put(t,e={}){return await this.sendJson("put",t,e)}async delete(t,e={}){return await this.sendJson("delete",t,e)}async sendJson(t,e,n={}){const{body:s,query:r,headers:o}=n,a=await this.send(t,e,{headers:Object.assign({"content-type":"application/json"},o),query:r,body:s?JSON.stringify(s):null}),{status:i}=a;return 204===i||"0"===a.headers.get("content-length")?null:await a.json()}async send(t,n,s={}){var r,o,a;const{fetch:i}=this.config,c=Math.max(this.config.retryAttempts+1,1);let u,l;for(let h=0;h<c;h++){let c=!1,d=this.config.retryDelay+this.config.retryDelayIncrement*h;try{const e=await this.prepareRequestSpec(t,n,s),r=await i(e.url,{method:e.method,headers:e.headers,body:e.body});if(!r.ok)throw this.config.authInvalidateStatusCodes.includes(r.status)?(c=Date.now()-this.authInvalidatedAt>this.config.authInvalidateInterval,this.authInvalidatedAt=Date.now(),d=0,this.config.auth.invalidate()):c=this.config.retryStatusCodes.includes(r.status),await this.createErrorFromResponse(e,r);return r}catch(i){const h=null===(r=i.details)||void 0===r?void 0:r.status,p=null===(o=i.details)||void 0===o?void 0:o.statusText,f={method:t,url:n,headers:null!==(a=s.headers)&&void 0!==a?a:{},status:h,statusText:p};if(c||e.NETWORK_ERRORS.includes(i.code)){u=i,l=f,this.onRetry(i,f),await new Promise((t=>setTimeout(t,d)));continue}throw this.onError(i,f),i}}throw this.onError(u,l),u}async sendRaw(t,e,n={}){const s=await this.prepareRequestSpec(t,e,n),{fetch:r}=this.config;return await r(s.url,{method:s.method,headers:s.headers,body:s.body})}async prepareRequestSpec(t,e,n={}){var s,r;const{auth:o}=this.config,{body:a}=n,i=this.prepareUrl(e,n),c=null!==(s=await o.getHeader({url:i,method:t,body:a}))&&void 0!==s?s:"";return{method:t,url:i,headers:this.mergeHeaders({"content-type":null!==(r=this.inferContentTypeFromBody(a))&&void 0!==r?r:""},this.config.headers||{},{authorization:c},n.headers||{}),body:a}}prepareUrl(t,e){var n;const{baseUrl:s}=this.config,r=s&&"/"!==s.slice(-1)?s+"/":s,o=new URL("/"===t[0]?t.slice(1):t,r||void 0);return o.search=new URLSearchParams(Object.entries(null!==(n=e.query)&&void 0!==n?n:{})).toString(),o.toString()}inferContentTypeFromBody(t){switch(!0){case null==t:return null;case t instanceof URLSearchParams:return"application/x-www-form-urlencoded";case"object"==typeof t:return"application/json";case"string"==typeof t:return"text/plain";default:return null}}mergeHeaders(...t){const e={};for(const n of t)for(const[t,s]of Object.entries(n))s&&(e[t.toLowerCase()]=s);return e}async createErrorFromResponse(t,e){return new i(t,e)}onRetry(t,e){}onError(t,e){}};class i extends r.Exception{constructor(t,e){super(`Request failed: ${e.status} ${e.statusText}`),this.details={method:t.method,url:t.url,requestHeaders:t.headers,status:e.status,statusText:e.statusText},Object.defineProperty(this,"requestSpec",{enumerable:!1,value:t}),Object.defineProperty(this,"response",{enumerable:!1,value:e})}}e.RequestFailedError=i},210:(t,e,n)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.default="undefined"==typeof Response?n(300).Response:Response},157:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},20:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.toBase64=void 0,e.toBase64=function(t){return btoa(t)}},687:function(t,e,n){var s=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.fetchMock=void 0;const r=s(n(210));e.fetchMock=function(t,e={},n){const s={called:!1,calledCount:0,params:[]},o=(o,a)=>new Promise(((i,c)=>{const u=Object.assign({status:200},t);if(s.called=!0,s.calledCount+=1,s.params.push({fullUrl:o,fetchOptions:a}),n)return c(n);i(new r.default(JSON.stringify(e),u))}));return o.spy=s,o}}},e={};return function n(s){if(e[s])return e[s].exports;var r=e[s]={exports:{}};return t[s].call(r.exports,r,r.exports,n),r.exports}(863)})()},729:t=>{"use strict";var e=Object.prototype.hasOwnProperty,n="~";function s(){}function r(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function o(t,e,s,o,a){if("function"!=typeof s)throw new TypeError("The listener must be a function");var i=new r(s,o||t,a),c=n?n+e:e;return t._events[c]?t._events[c].fn?t._events[c]=[t._events[c],i]:t._events[c].push(i):(t._events[c]=i,t._eventsCount++),t}function a(t,e){0==--t._eventsCount?t._events=new s:delete t._events[e]}function i(){this._events=new s,this._eventsCount=0}Object.create&&(s.prototype=Object.create(null),(new s).__proto__||(n=!1)),i.prototype.eventNames=function(){var t,s,r=[];if(0===this._eventsCount)return r;for(s in t=this._events)e.call(t,s)&&r.push(n?s.slice(1):s);return Object.getOwnPropertySymbols?r.concat(Object.getOwnPropertySymbols(t)):r},i.prototype.listeners=function(t){var e=n?n+t:t,s=this._events[e];if(!s)return[];if(s.fn)return[s.fn];for(var r=0,o=s.length,a=new Array(o);r<o;r++)a[r]=s[r].fn;return a},i.prototype.listenerCount=function(t){var e=n?n+t:t,s=this._events[e];return s?s.fn?1:s.length:0},i.prototype.emit=function(t,e,s,r,o,a){var i=n?n+t:t;if(!this._events[i])return!1;var c,u,l=this._events[i],h=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),h){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,s),!0;case 4:return l.fn.call(l.context,e,s,r),!0;case 5:return l.fn.call(l.context,e,s,r,o),!0;case 6:return l.fn.call(l.context,e,s,r,o,a),!0}for(u=1,c=new Array(h-1);u<h;u++)c[u-1]=arguments[u];l.fn.apply(l.context,c)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(t,l[u].fn,void 0,!0),h){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,e);break;case 3:l[u].fn.call(l[u].context,e,s);break;case 4:l[u].fn.call(l[u].context,e,s,r);break;default:if(!c)for(d=1,c=new Array(h-1);d<h;d++)c[d-1]=arguments[d];l[u].fn.apply(l[u].context,c)}}return!0},i.prototype.on=function(t,e,n){return o(this,t,e,n,!1)},i.prototype.once=function(t,e,n){return o(this,t,e,n,!0)},i.prototype.removeListener=function(t,e,s,r){var o=n?n+t:t;if(!this._events[o])return this;if(!e)return a(this,o),this;var i=this._events[o];if(i.fn)i.fn!==e||r&&!i.once||s&&i.context!==s||a(this,o);else{for(var c=0,u=[],l=i.length;c<l;c++)(i[c].fn!==e||r&&!i[c].once||s&&i[c].context!==s)&&u.push(i[c]);u.length?this._events[o]=1===u.length?u[0]:u:a(this,o)}return this},i.prototype.removeAllListeners=function(t){var e;return t?(e=n?n+t:t,this._events[e]&&a(this,e)):(this._events=new s,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,t.exports=i},330:(t,e,n)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.AcRequest=e.AcApi=void 0;const s=n(739);e.AcApi=class{constructor(t){this.params=t;const e="string"==typeof t.auth?new s.BasicAuthAgent({username:t.auth}):new s.OAuth2Agent({clientId:t.auth.clientId,clientSecret:t.auth.clientSecret,tokenUrl:t.apiTokenUrl});this.request=new r({baseUrl:t.apiUrl,auth:e,retryAttempts:t.requestRetryCount,retryDelay:t.requestRetryDelay})}async createJob(t){const{serviceId:e,category:n,input:s}=t;return await this.request.post("/jobs",{body:{serviceId:e,category:n,input:s}})}async getJob(t){return await this.request.get(`/jobs/${t}`)}async getJobAccessToken(t){return(await this.request.get(`/jobs/${t}/end-user`)).token}async getJobEvents(t,e){const{data:n}=await this.request.get(`/jobs/${t}/events`,{query:{offset:e}});return n}async getJobOutputData(t,e){var n;try{return await this.request.get(`/jobs/${t}/outputs/${e}`)}catch(t){if(404===(null===(n=t.details)||void 0===n?void 0:n.status))return null;throw t}}async sendJobInput(t,e,n){return await this.request.post(`/jobs/${t}/inputs`,{body:{key:e,data:n}})}async cancelJob(t){await this.request.post(`/jobs/${t}/cancel`)}async queryPreviousOutputs(t,e,n=[]){const{data:s}=await this.request.post(`/services/${t}/previous-job-outputs`,{body:{inputs:n},query:{key:e}});return s}};class r extends s.Request{async createErrorFromResponse(t,e){var n;if(null===(n=e.headers.get("content-type"))||void 0===n?void 0:n.startsWith("application/json")){const t=await e.json();if(t.name&&t.message){const e=new Error(t.message);return e.name=t.name,e.code=t.code,e.details=t.details,e}}return super.createErrorFromResponse(t,e)}}e.AcRequest=r},967:(t,e,n)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Client=void 0;const s=n(330),r=n(909),o=n(157),a=n(894);e.Client=class{constructor(t){this.logger=console,this.config=Object.assign({apiUrl:"https://api.automationcloud.net",apiTokenUrl:"https://auth.automationcloud.net/auth/realms/automationcloud/protocol/openid-connect/token",vaultUrl:"https://vault.automationcloud.net",pollInterval:1e3,requestRetryCount:4,requestRetryDelay:500,autoTrack:!0},t),this.api=new s.AcApi({logger:this.logger,apiTokenUrl:this.config.apiTokenUrl,apiUrl:this.config.apiUrl,auth:this.config.auth,requestRetryCount:this.config.requestRetryCount,requestRetryDelay:this.config.requestRetryDelay}),this.vault=new a.Vault(this)}async getJob(t){const e=new r.Job(this);return await e.trackExisting(t),e}async queryPreviousOutput(t,e=[]){const n=await this.api.queryPreviousOutputs(this.config.serviceId,t,e);return n.length?n[0]:null}async createJob(t={}){return await this._createJob(Object.assign({category:o.JobCategory.TEST,input:{}},t))}async _createJob(t){const e=new r.Job(this,t);return await e.start(),e}}},313:(t,e,n)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.JobTrackError=e.JobFailedError=e.JobOutputWaitError=e.JobAlreadyStartedError=e.JobNotInitializedError=void 0;const s=n(222);class r extends s.Exception{constructor(){super("Invalid state: job not yet initialized")}}e.JobNotInitializedError=r;class o extends s.Exception{constructor(t={}){super("Job is already initialized"),this.details=t}}e.JobAlreadyStartedError=o;class a extends s.Exception{constructor(t,e={}){super(t),this.message=t,this.details=e}}e.JobOutputWaitError=a;class i extends s.Exception{constructor(t){var e,n,s;super(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"),this.name=null!==(n=null==t?void 0:t.code)&&void 0!==n?n:"UnknownError",this.details=Object.assign({category:null!==(s=null==t?void 0:t.category)&&void 0!==s?s:"server"},null==t?void 0:t.details)}}e.JobFailedError=i;class c extends s.Exception{constructor(t){super(`Job tracking failed: ${t.message}`),this.details={cause:t}}}e.JobTrackError=c},222:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Exception=void 0;class n extends Error{constructor(){super(...arguments),this.name=this.constructor.name,this.status=500,this.details={}}}e.Exception=n},863:function(t,e,n){"use strict";var s=this&&this.__createBinding||(Object.create?function(t,e,n,s){void 0===s&&(s=n),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,s){void 0===s&&(s=n),t[s]=e[n]}),r=this&&this.__exportStar||function(t,e){for(var n in t)"default"===n||Object.prototype.hasOwnProperty.call(e,n)||s(e,t,n)};Object.defineProperty(e,"__esModule",{value:!0}),r(n(330),e),r(n(967),e),r(n(222),e),r(n(313),e),r(n(909),e),r(n(273),e),r(n(157),e),r(n(894),e)},909:function(t,e,n){"use strict";var s=this&&this.__createBinding||(Object.create?function(t,e,n,s){void 0===s&&(s=n),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[n]}})}:function(t,e,n,s){void 0===s&&(s=n),t[s]=e[n]}),r=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),o=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)"default"!==n&&Object.prototype.hasOwnProperty.call(t,n)&&s(e,t,n);return r(e,t),e};Object.defineProperty(e,"__esModule",{value:!0}),e.Job=void 0;const a=n(729),i=o(n(313)),c=n(157);e.Job=class{constructor(t,e={}){this.client=t,this._events=new a.EventEmitter,this._inputsMap=new Map,this._outputsMap=new Map,this._state=c.JobState.CREATED,this._error=null,this._awaitingInputKey=null,this._trackPromise=null,this._jobId=null,this._jobEventOffset=0,this._isTracking=!1,this._initParams=Object.assign({category:c.JobCategory.TEST,input:{}},e)}get jobId(){if(!this._jobId)throw new i.JobNotInitializedError;return this._jobId}async start(){if(this._jobId)throw new i.JobAlreadyStartedError(this.jobId);const{category:t,input:e}=this._initParams,{serviceId:n}=this.client.config,{id:s,state:r}=await this.api.createJob({serviceId:n,category:t,input:e});this._jobId=s,this._setState(r);for(const[t,n]of Object.entries(e))this._inputsMap.set(t,{key:t,data:n});this.client.config.autoTrack&&this.startTracking()}async trackExisting(t){if(this._jobId)throw new i.JobAlreadyStartedError({jobId:this.jobId});const{state:e,category:n}=await this.api.getJob(t);this._jobId=t,this._initParams.category=n,this._setState(e),this.startTracking()}startTracking(){this._trackPromise||(this._isTracking=!0,this._trackPromise=this._track(),this._trackPromise.catch((t=>{})).then((()=>{this._isTracking=!1,this._trackPromise=null})))}stopTracking(){this._isTracking=!1}getState(){return this._state}_setState(t){const e=this._state;this._state=t,this._events.emit("stateChanged",t,e)}getErrorInfo(){return this._error}getAwaitingInputKey(){return this._awaitingInputKey}async getAccessToken(){return await this.api.getJobAccessToken(this.jobId)}async submitInput(t,e){await this.api.sendJobInput(this.jobId,t,e),this._inputsMap.set(t,{key:t,data:e})}async getOutput(t){const e=this._outputsMap.get(t);if(e)return e.data;const n=await this.api.getJobOutputData(this.jobId,t);return null==n?void 0:n.data}async waitForCompletion(){await this._trackPromise}async cancel(){await this.api.cancelJob(this.jobId)}async waitForOutputs(...t){return await this._waitFor((()=>{const e=this._checkOutputs(t);if(null!=e)return e;if(this.getState()===c.JobState.FAIL)throw new i.JobOutputWaitError("Job failed, and specified outputs were not emitted",{state:this.getState(),jobId:this.jobId});if(this.getState()===c.JobState.SUCCESS)throw new i.JobOutputWaitError("Job succeeded, but specified outputs were not emitted",{state:this.getState(),jobId:this.jobId})}))}async _waitFor(t){return new Promise(((e,n)=>{const s=()=>{try{const n=t();void 0!==n&&(o(),e(n))}catch(t){o(),n(t)}},r=t=>{o(),n(t)},o=()=>{this._events.off("trackTick",s),this._events.off("trackError",r)};this._events.on("trackTick",s),this._events.on("trackError",r),s()}))}onAwaitingInput(t,e){return this._createJobEventHandler("awaitingInput",(async n=>{if("*"===t||n===t){const s=await e(n);void 0!==s&&await this.submitInput(t,s)}}))}onOutput(t,e){return this._createJobEventHandler("output",(async n=>{this._matchKey(t,n.key)&&await e(n.data)}))}onDynamicOutput(t,e){return this._createJobEventHandler("output",(async n=>{(n.key.startsWith(t+":")||this._matchKey(t,n.key))&&await e(n.key,n.data)}))}onAnyOutput(t){return this._createJobEventHandler("output",(async e=>{await t(e.key,e.data)}))}onOutputEvent(t,e){return this.onDynamicOutput("events",(async(n,s)=>{s&&"object"==typeof s&&this._matchKey(t,s.type)&&await e(s)}))}onStateChanged(t){return this._createJobEventHandler("stateChanged",t)}onSuccess(t){return this._createJobEventHandler("success",t)}onFail(t){return this._createJobEventHandler("fail",t)}async _track(){for(;this._isTracking;){const{pollInterval:t}=this.client.config;try{const t=await this.api.getJobEvents(this.jobId,this._jobEventOffset);this._jobEventOffset+=t.length;for(const e of t)await this._processJobEvent(e);this._events.emit("trackTick")}catch(t){const e=new i.JobTrackError(t);throw this._events.emit("trackError",e),e}switch(this._state){case c.JobState.SUCCESS:return;case c.JobState.FAIL:throw new i.JobFailedError(this._error)}await new Promise((e=>setTimeout(e,t)))}}async _processJobEvent(t){const e=t.key;switch(t.name){case"awaitingInput":this._setState(c.JobState.AWAITING_INPUT),this._awaitingInputKey=e,this._events.emit("awaitingInput",e);break;case"createOutput":{const t=await this.api.getJobOutputData(this.jobId,e);if(t){const n=t.data;this._outputsMap.set(e,{key:e,data:n}),this._events.emit("output",{key:e,data:n})}}break;case"processing":this._setState(c.JobState.PROCESSING);break;case"success":this._setState(c.JobState.SUCCESS),this._events.emit("success");break;case"fail":{const{error:t}=await this.api.getJob(this.jobId);this._setState(c.JobState.FAIL),this._error=Object.assign({category:"server",code:"UnknownError",message:"Unknown error"},t);const e=new i.JobFailedError(this._error);this._events.emit("fail",e)}}}_checkOutputs(t){const e=[];for(const n of t){const t=this._outputsMap.get(n);if(!t)break;e.push(t.data)}return e.length===t.length?e:null}get api(){return this.client.api}_createJobEventHandler(t,e){const n=async(...t)=>{await e(...t)};return this._events.on(t,n),()=>this._events.off(t,n)}_matchKey(t,e){if(t.endsWith(":*")){const n=t.split(":")[0];return e.startsWith(n+":")}return e===t}}},273:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0})},157:(t,e)=>{"use strict";var n,s;Object.defineProperty(e,"__esModule",{value:!0}),e.JobCategory=e.JobState=void 0,(s=e.JobState||(e.JobState={})).CREATED="created",s.SCHEDULED="scheduled",s.PROCESSING="processing",s.AWAITING_INPUT="awaitingInput",s.AWAITING_TDS="awaitingTds",s.PENDING="pending",s.SUCCESS="success",s.FAIL="fail",(n=e.JobCategory||(e.JobCategory={})).LIVE="live",n.TEST="test"},894:(t,e,n)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Vault=void 0;const s=n(739);function r(t){return"string"==typeof t?t:[t.name,t.label,t.placeholder].map((t=>t.replace(/_/g,""))).join("_")}e.Vault=class{constructor(t){this.client=t;const{config:e}=t,n="string"==typeof e.auth?new s.BasicAuthAgent({username:e.auth}):new s.OAuth2Agent({clientId:e.auth.clientId,clientSecret:e.auth.clientSecret,tokenUrl:e.apiTokenUrl});this.request=new s.Request({baseUrl:e.vaultUrl,auth:n})}get api(){return this.client.api}async createOtp(){const{id:t}=await this.request.post("/otp");return t}async createPanToken(t,e){const n=null!=e?e:await this.createOtp(),{panToken:s}=await this.request.post("/pan",{body:{otp:n,pan:t}});return s}getPaymentIframeUrl(t,e={}){var n,s,o;const a=[["otp",t],["css",e.cssUrl],["name",e.name],["fields",null===(n=e.fields)||void 0===n?void 0:n.map(r).join(",")],["brands",null===(s=e.brands)||void 0===s?void 0:s.join(",")],["validateOnInput",!0===e.validateOnInput?"on":void 0]].filter((t=>null!=t[1]));return(null!==(o=e.iframeUrl)&&void 0!==o?o:"https://vault.automationcloud.net/forms/index.html")+"?"+a.map((t=>{var e;return`${t[0]}=${encodeURIComponent(null!==(e=t[1])&&void 0!==e?e:"")}`})).join("&")}getSingleInputIframeUrl(t,e={}){var n;const s=[["otp",t],["css",e.cssUrl],["inputType",e.inputType],["pattern",e.pattern],["minlength",e.minlength],["maxlength",e.maxlength],["required",e.required],["validateOnInput",!0===e.validateOnInput?"on":void 0]].filter((t=>null!=t[1]));return(null!==(n=e.iframeUrl)&&void 0!==n?n:"https://vault.automationcloud.net/forms/single-input.html")+"?"+s.map((t=>{var e;return`${t[0]}=${encodeURIComponent(null!==(e=t[1])&&void 0!==e?e:"")}`})).join("&")}}}},e={},function n(s){if(e[s])return e[s].exports;var r=e[s]={exports:{}};return t[s].call(r.exports,r,r.exports,n),r.exports}(863);var t,e})); |
@@ -10,3 +10,3 @@ import { Exception } from './exception'; | ||
} | ||
export declare class JobMissingOutputsError extends Exception { | ||
export declare class JobOutputWaitError extends Exception { | ||
message: string; | ||
@@ -20,5 +20,4 @@ details: any; | ||
export declare class JobTrackError extends Exception { | ||
cause: Error; | ||
constructor(cause: Error); | ||
} | ||
//# sourceMappingURL=errors.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.JobTrackError = exports.JobFailedError = exports.JobMissingOutputsError = exports.JobAlreadyStartedError = exports.JobNotInitializedError = void 0; | ||
exports.JobTrackError = exports.JobFailedError = exports.JobOutputWaitError = exports.JobAlreadyStartedError = exports.JobNotInitializedError = void 0; | ||
const exception_1 = require("./exception"); | ||
@@ -18,3 +18,3 @@ class JobNotInitializedError extends exception_1.Exception { | ||
exports.JobAlreadyStartedError = JobAlreadyStartedError; | ||
class JobMissingOutputsError extends exception_1.Exception { | ||
class JobOutputWaitError extends exception_1.Exception { | ||
constructor(message, details = {}) { | ||
@@ -26,3 +26,3 @@ super(message); | ||
} | ||
exports.JobMissingOutputsError = JobMissingOutputsError; | ||
exports.JobOutputWaitError = JobOutputWaitError; | ||
class JobFailedError extends exception_1.Exception { | ||
@@ -40,3 +40,3 @@ constructor(jobError) { | ||
super(`Job tracking failed: ${cause.message}`); | ||
this.cause = cause; | ||
this.details = { cause }; | ||
} | ||
@@ -43,0 +43,0 @@ } |
import { AcJobEvent } from './ac-api'; | ||
import { Client } from './client'; | ||
import { JobError, JobEventHandler, JobInitParams, JobInput, JobOutput, JobState } from './types'; | ||
import { JobError, JobEventHandler, JobInitParams, JobInput, JobOutput, JobOutputEvent, JobState } from './types'; | ||
/** | ||
@@ -156,2 +156,3 @@ * Job instance reflexts the Job created in Automation Cloud. | ||
waitForOutputs(...keys: string[]): Promise<any[]>; | ||
protected _waitFor<T>(resultFn: () => T | undefined): Promise<T>; | ||
/** | ||
@@ -183,2 +184,8 @@ * Subscribes to `awaitingInput` event for specified input key and optionally fulfills | ||
/** | ||
* Subscribes to `output` event for dynamic outputs with specified `key` prefix. | ||
* | ||
* @param fn handler callback, can be either synchronous or asynchronous | ||
*/ | ||
onDynamicOutput(keyPrefix: string, fn: (outputKey: string, outputData: any) => void | Promise<void>): JobEventHandler; | ||
/** | ||
* Subscribes to `output` event for all output keys. | ||
@@ -192,2 +199,7 @@ * | ||
/** | ||
* @param eventType | ||
* @beta | ||
*/ | ||
onOutputEvent(eventType: string, fn: (eventData: JobOutputEvent) => void | Promise<void>): JobEventHandler; | ||
/** | ||
* Subscribes to state change event. | ||
@@ -241,2 +253,3 @@ * | ||
protected _createJobEventHandler(event: 'fail', fn: (error: Error) => void | Promise<void>): JobEventHandler; | ||
protected _matchKey(keyPattern: string, actualKey: string): boolean; | ||
} | ||
@@ -256,2 +269,3 @@ /** | ||
emit(event: 'fail', error: Error): boolean; | ||
emit(event: 'trackTick'): boolean; | ||
emit(event: 'trackError', error: Error): boolean; | ||
@@ -265,2 +279,3 @@ on(event: 'input', fn: (input: JobInput) => void): this; | ||
on(event: 'fail', fn: (error: Error) => void): this; | ||
on(event: 'trackTick', fn: () => void): this; | ||
on(event: 'trackError', fn: (error: Error) => void): this; | ||
@@ -267,0 +282,0 @@ off(event: string, fn: (...args: any[]) => any): this; |
@@ -262,24 +262,38 @@ "use strict"; | ||
async waitForOutputs(...keys) { | ||
return await this._waitFor(() => { | ||
const outputs = this._checkOutputs(keys); | ||
if (outputs != null) { | ||
return outputs; | ||
} | ||
if (this.getState() === types_1.JobState.FAIL) { | ||
throw new errors.JobOutputWaitError('Job failed, and specified outputs were not emitted', { | ||
state: this.getState(), | ||
jobId: this.jobId, | ||
}); | ||
} | ||
if (this.getState() === types_1.JobState.SUCCESS) { | ||
throw new errors.JobOutputWaitError('Job succeeded, but specified outputs were not emitted', { | ||
state: this.getState(), | ||
jobId: this.jobId, | ||
}); | ||
} | ||
// Keep waiting | ||
return undefined; | ||
}); | ||
} | ||
async _waitFor(resultFn) { | ||
return new Promise((resolve, reject) => { | ||
const onOutput = () => { | ||
const values = this._checkOutputs(keys); | ||
if (values) { | ||
const check = () => { | ||
try { | ||
const result = resultFn(); | ||
if (result !== undefined) { | ||
cleanup(); | ||
resolve(result); | ||
} | ||
} | ||
catch (err) { | ||
cleanup(); | ||
resolve(values); | ||
reject(err); | ||
} | ||
}; | ||
const onSuccess = () => { | ||
cleanup(); | ||
reject(new errors.JobMissingOutputsError(`Job succeded, but specified outputs were not emitted`, { | ||
keys, | ||
jobId: this.jobId, | ||
})); | ||
}; | ||
const onFail = () => { | ||
cleanup(); | ||
reject(new errors.JobMissingOutputsError(`Job failed, and specified outputs were not emitted`, { | ||
keys, | ||
jobId: this.jobId, | ||
})); | ||
}; | ||
const onTrackError = (err) => { | ||
@@ -290,12 +304,8 @@ cleanup(); | ||
const cleanup = () => { | ||
this._events.off('output', onOutput); | ||
this._events.off('success', onSuccess); | ||
this._events.off('fail', onFail); | ||
this._events.off('trackTick', check); | ||
this._events.off('trackError', onTrackError); | ||
}; | ||
this._events.on('output', onOutput); | ||
this._events.on('success', onSuccess); | ||
this._events.on('fail', onFail); | ||
this._events.on('trackTick', check); | ||
this._events.on('trackError', onTrackError); | ||
onOutput(); | ||
check(); | ||
}); | ||
@@ -338,3 +348,3 @@ } | ||
return this._createJobEventHandler('output', async (output) => { | ||
if (output.key === key) { | ||
if (this._matchKey(key, output.key)) { | ||
await fn(output.data); | ||
@@ -345,2 +355,14 @@ } | ||
/** | ||
* Subscribes to `output` event for dynamic outputs with specified `key` prefix. | ||
* | ||
* @param fn handler callback, can be either synchronous or asynchronous | ||
*/ | ||
onDynamicOutput(keyPrefix, fn) { | ||
return this._createJobEventHandler('output', async (output) => { | ||
if (output.key.startsWith(keyPrefix + ':') || this._matchKey(keyPrefix, output.key)) { | ||
await fn(output.key, output.data); | ||
} | ||
}); | ||
} | ||
/** | ||
* Subscribes to `output` event for all output keys. | ||
@@ -358,2 +380,16 @@ * | ||
/** | ||
* @param eventType | ||
* @beta | ||
*/ | ||
onOutputEvent(eventType, fn) { | ||
return this.onDynamicOutput('events', async (_key, data) => { | ||
if (!data || typeof data !== 'object') { | ||
return; | ||
} | ||
if (this._matchKey(eventType, data.type)) { | ||
await fn(data); | ||
} | ||
}); | ||
} | ||
/** | ||
* Subscribes to state change event. | ||
@@ -402,2 +438,3 @@ * | ||
} | ||
this._events.emit('trackTick'); | ||
} | ||
@@ -503,4 +540,11 @@ catch (err) { | ||
} | ||
_matchKey(keyPattern, actualKey) { | ||
if (keyPattern.endsWith(':*')) { | ||
const keyBase = keyPattern.split(':')[0]; | ||
return actualKey.startsWith(keyBase + ':'); | ||
} | ||
return actualKey === keyPattern; | ||
} | ||
} | ||
exports.Job = Job; | ||
//# sourceMappingURL=job.js.map |
@@ -89,2 +89,9 @@ /** | ||
/** | ||
* Output event produced by automation job. | ||
*/ | ||
export interface JobOutputEvent { | ||
type: string; | ||
[key: string]: any; | ||
} | ||
/** | ||
* Event subscription methods like `onOutput` return handlers which can subsequently be invoked | ||
@@ -91,0 +98,0 @@ * with zero arguments to unsubscribe from the event. |
{ | ||
"name": "@automationcloud/client", | ||
"version": "1.3.0", | ||
"version": "1.4.2", | ||
"description": "JavaScript/TypeScript Client Library for Automation Cloud API", | ||
@@ -14,3 +14,4 @@ "main": "out/main/index.js", | ||
"docs": "typedoc --tsconfig ./tsconfig.json ./src/main && git add docs/", | ||
"preversion": "npm run lint && npm run clean && npm run compile && npm run docs && npm run build:browser" | ||
"preversion": "npm run lint && npm run clean && npm run compile && npm run docs && npm run build:browser", | ||
"postversion": "npm publish --access public && git push origin main --tags" | ||
}, | ||
@@ -17,0 +18,0 @@ "files": [ |
@@ -174,7 +174,7 @@ # Automation Cloud API Client | ||
const job = await client.createJob(/* ... */); | ||
const token = await job.getAccessToken(); | ||
const accessToken = await job.getAccessToken(); | ||
res.send({ | ||
serviceId, | ||
jobId: job.id, | ||
token, | ||
jobId: job.jobId, | ||
accessToken, | ||
}); | ||
@@ -186,5 +186,5 @@ }); | ||
const res = await fetch('/booking', /*...*/); | ||
const { serviceId, jobId, token } = await res.json(); | ||
const client = new Client({ serviceId, auth: token }); | ||
const job = await client.getJob(); | ||
const { serviceId, jobId, accessToken } = await res.json(); | ||
const client = new Client({ serviceId, auth: accessToken }); | ||
const job = await client.getJob(jobId); | ||
// Proceed working with job safely | ||
@@ -191,0 +191,0 @@ await job.waitForCompletion(); |
@@ -16,3 +16,3 @@ import { Exception } from './exception'; | ||
export class JobMissingOutputsError extends Exception { | ||
export class JobOutputWaitError extends Exception { | ||
constructor(public message: string, public details: any = {}) { | ||
@@ -37,5 +37,6 @@ super(message); | ||
export class JobTrackError extends Exception { | ||
constructor(public cause: Error) { | ||
constructor(cause: Error) { | ||
super(`Job tracking failed: ${cause.message}`); | ||
this.details = { cause }; | ||
} | ||
} |
@@ -19,3 +19,3 @@ // Copyright 2020 UBIO Limited | ||
import * as errors from './errors'; | ||
import { JobCategory, JobError, JobEventHandler, JobInitParams, JobInput, JobOutput, JobState } from './types'; | ||
import { JobCategory, JobError, JobEventHandler, JobInitParams, JobInput, JobOutput, JobOutputEvent, JobState } from './types'; | ||
@@ -268,24 +268,38 @@ /** | ||
async waitForOutputs(...keys: string[]): Promise<any[]> { | ||
return await this._waitFor<any[]>(() => { | ||
const outputs = this._checkOutputs(keys); | ||
if (outputs != null) { | ||
return outputs; | ||
} | ||
if (this.getState() === JobState.FAIL) { | ||
throw new errors.JobOutputWaitError('Job failed, and specified outputs were not emitted', { | ||
state: this.getState(), | ||
jobId: this.jobId, | ||
}); | ||
} | ||
if (this.getState() === JobState.SUCCESS) { | ||
throw new errors.JobOutputWaitError('Job succeeded, but specified outputs were not emitted', { | ||
state: this.getState(), | ||
jobId: this.jobId, | ||
}); | ||
} | ||
// Keep waiting | ||
return undefined; | ||
}); | ||
} | ||
protected async _waitFor<T>(resultFn: () => T | undefined): Promise<T> { | ||
return new Promise((resolve, reject) => { | ||
const onOutput = () => { | ||
const values = this._checkOutputs(keys); | ||
if (values) { | ||
const check = () => { | ||
try { | ||
const result = resultFn(); | ||
if (result !== undefined) { | ||
cleanup(); | ||
resolve(result); | ||
} | ||
} catch (err) { | ||
cleanup(); | ||
resolve(values); | ||
reject(err); | ||
} | ||
}; | ||
const onSuccess = () => { | ||
cleanup(); | ||
reject(new errors.JobMissingOutputsError(`Job succeded, but specified outputs were not emitted`, { | ||
keys, | ||
jobId: this.jobId, | ||
})); | ||
}; | ||
const onFail = () => { | ||
cleanup(); | ||
reject(new errors.JobMissingOutputsError(`Job failed, and specified outputs were not emitted`, { | ||
keys, | ||
jobId: this.jobId, | ||
})); | ||
}; | ||
const onTrackError = (err: Error) => { | ||
@@ -296,12 +310,8 @@ cleanup(); | ||
const cleanup = () => { | ||
this._events.off('output', onOutput); | ||
this._events.off('success', onSuccess); | ||
this._events.off('fail', onFail); | ||
this._events.off('trackTick', check); | ||
this._events.off('trackError', onTrackError); | ||
}; | ||
this._events.on('output', onOutput); | ||
this._events.on('success', onSuccess); | ||
this._events.on('fail', onFail); | ||
this._events.on('trackTick', check); | ||
this._events.on('trackError', onTrackError); | ||
onOutput(); | ||
check(); | ||
}); | ||
@@ -346,3 +356,3 @@ } | ||
return this._createJobEventHandler('output', async (output: JobOutput) => { | ||
if (output.key === key) { | ||
if (this._matchKey(key, output.key)) { | ||
await fn(output.data); | ||
@@ -354,2 +364,15 @@ } | ||
/** | ||
* Subscribes to `output` event for dynamic outputs with specified `key` prefix. | ||
* | ||
* @param fn handler callback, can be either synchronous or asynchronous | ||
*/ | ||
onDynamicOutput(keyPrefix: string, fn: (outputKey: string, outputData: any) => void | Promise<void>): JobEventHandler { | ||
return this._createJobEventHandler('output', async (output: JobOutput) => { | ||
if (output.key.startsWith(keyPrefix + ':') || this._matchKey(keyPrefix, output.key)) { | ||
await fn(output.key, output.data); | ||
} | ||
}); | ||
} | ||
/** | ||
* Subscribes to `output` event for all output keys. | ||
@@ -368,2 +391,17 @@ * | ||
/** | ||
* @param eventType | ||
* @beta | ||
*/ | ||
onOutputEvent(eventType: string, fn: (eventData: JobOutputEvent) => void | Promise<void>): JobEventHandler { | ||
return this.onDynamicOutput('events', async (_key, data) => { | ||
if (!data || typeof data !== 'object') { | ||
return; | ||
} | ||
if (this._matchKey(eventType, data.type)) { | ||
await fn(data); | ||
} | ||
}); | ||
} | ||
/** | ||
* Subscribes to state change event. | ||
@@ -415,2 +453,3 @@ * | ||
} | ||
this._events.emit('trackTick'); | ||
} catch (err) { | ||
@@ -518,2 +557,10 @@ const error = new errors.JobTrackError(err); | ||
} | ||
protected _matchKey(keyPattern: string, actualKey: string) { | ||
if (keyPattern.endsWith(':*')) { | ||
const keyBase = keyPattern.split(':')[0]; | ||
return actualKey.startsWith(keyBase + ':'); | ||
} | ||
return actualKey === keyPattern; | ||
} | ||
} | ||
@@ -534,2 +581,3 @@ | ||
emit(event: 'fail', error: Error): boolean; | ||
emit(event: 'trackTick'): boolean; | ||
emit(event: 'trackError', error: Error): boolean; | ||
@@ -544,2 +592,3 @@ | ||
on(event: 'fail', fn: (error: Error) => void): this; | ||
on(event: 'trackTick', fn: () => void): this; | ||
on(event: 'trackError', fn: (error: Error) => void): this; | ||
@@ -546,0 +595,0 @@ |
@@ -113,2 +113,10 @@ // Copyright 2020 UBIO Limited | ||
/** | ||
* Output event produced by automation job. | ||
*/ | ||
export interface JobOutputEvent { | ||
type: string; | ||
[key: string]: any; | ||
} | ||
/** | ||
* Event subscription methods like `onOutput` return handlers which can subsequently be invoked | ||
@@ -115,0 +123,0 @@ * with zero arguments to unsubscribe from the event. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
189826
3102