@devbookhq/sdk
Advanced tools
Comparing version 2.6.57 to 2.6.58
@@ -7,3 +7,3 @@ export { default as Session } from './session'; | ||
export { OutType } from './session/out'; | ||
export type { TerminalManager, TerminalSession, ChildProcess } from './session/terminal'; | ||
export type { TerminalManager, TerminalSession } from './session/terminal'; | ||
export type { FilesystemManager, FileInfo } from './session/filesystem'; | ||
@@ -10,0 +10,0 @@ export { default as FilesystemWatcher, FilesystemOperation, } from './session/filesystemWatcher'; |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var s=require("normalize-path"),e=require("rpc-websocket-client");require("cross-fetch/polyfill");var t=require("openapi-typescript-fetch");function i(s){return s&&"object"==typeof s&&"default"in s?s:{default:s}}var o=i(s);function n(s,e,t,i){return new(t||(t=Promise))((function(o,n){function r(s){try{c(i.next(s))}catch(s){n(s)}}function l(s){try{c(i.throw(s))}catch(s){n(s)}}function c(s){var e;s.done?o(s.value):(e=s.value,e instanceof t?e:new t((function(s){s(e)}))).then(r,l)}c((i=i.apply(s,e||[])).next())}))}function r(s){let e="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=t.length;for(let o=0;o<s;o++)e+=t.charAt(Math.floor(Math.random()*i));return e}function l(s){return"fulfilled"===s.status}function c(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,e,t)=>"rejected"===e.status?s+"\n"+`[${t}]: `+`${JSON.stringify(e)}`:s),"errors:\n")}function d(){let s,e;return{promise:new Promise(((t,i)=>{s=t,e=i})),reject:e,resolve:s}}var h;exports.CodeSnippetExecState=void 0,(h=exports.CodeSnippetExecState||(exports.CodeSnippetExecState={})).Running="Running",h.Stopped="Stopped";var a;exports.FilesystemOperation=void 0,(a=exports.FilesystemOperation||(exports.FilesystemOperation={})).Create="Create",a.Write="Write",a.Remove="Remove",a.Rename="Rename",a.Chmod="Chmod";class u{constructor(s,e){this.sessConn=s,this.path=e,this.listeners=new Set}start(){return n(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe("filesystem",this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return n(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((e=>{e(s)}))}}const p=t.Fetcher.for();p.configure({baseUrl:"https://ondevbook.com"});class v{constructor(s,e=!1){this.logID=s,this.isEnabled=e}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function g(s){return new Promise((e=>setTimeout(e,s)))}const f=p.path("/sessions").method("post").create({api_key:!0}),b=p.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class y{constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new e.RpcWebSocketClient,this.subscribers=[],this.logger=new v("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const e=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${e}`:e}close(){var s,e,t;return n(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(s=this.rpc.ws)||void 0===s||s.close(),null===(t=null===(e=this.opts)||void 0===e?void 0:e.onClose)||void 0===t||t.call(e),this.logger.log("Disconected from the session")}}))}open(){return n(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield f({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof f.Error){const e=s.getActualType();if(400===e.status)throw new Error(`Error creating session - (${e.status}) bad request: ${e.data.message}`);if(401===e.status)throw new Error(`Error creating session - (${e.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${e.data.message}`);if(500===e.status)throw new Error(`Error creating session - (${e.status}) server error: ${e.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const e=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let t,i,o=!1;const r=new Promise(((s,e)=>{t=()=>{o||(o=!0,s())},i=()=>{o||(o=!0,e())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==t||t()})),this.rpc.onClose((s=>n(this,void 0,void 0,(function*(){var t,o,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(o=(t=this.opts).onDisconnect)||void 0===o||o.call(t),yield g(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(e),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==i||i()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(e)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield r}))}call(s,e,t){return n(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${e}`,t)}))}handleSubscriptions(...s){return n(this,void 0,void 0,(function*(){const e=yield Promise.allSettled(s);if(e.every((s=>"fulfilled"===s.status)))return e.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(e.filter(l).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(c(e))}))}unsubscribe(s){return n(this,void 0,void 0,(function*(){const e=this.subscribers.find((e=>e.subID===s));e&&(yield this.call(e.service,"unsubscribe",[e.subID]),this.subscribers=this.subscribers.filter((s=>s!==e)),this.logger.log(`Unsubscribed '${s}' from '${e.service}'`))}))}subscribe(s,e,t,...i){return n(this,void 0,void 0,(function*(){const o=yield this.call(s,"subscribe",[t,...i]);if("string"!=typeof o)throw new Error(`Cannot subscribe to ${s}_${t}${i.length>0?" with params ["+i.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(o)}`);return this.subscribers.push({handler:e,service:s,subID:o}),this.logger.log(`Subscribed to "${s}_${t}"${i.length>0?" with params ["+i.join(", ")+"] and":""} with id "${o}"`),o}))}handleNotification(s){this.subscribers.filter((e=>{var t;return e.subID===(null===(t=s.params)||void 0===t?void 0:t.subscription)})).forEach((e=>{var t;return e.handler(null===(t=s.params)||void 0===t?void 0:t.result)}))}refresh(s){return n(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield g(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield b({api_key:this.opts.apiKey,sessionID:s})}catch(e){if(e instanceof b.Error){const t=e.getActualType();if(404===t.status)return void this.logger.error(`Error refreshing session - (${t.status}): ${t.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${t.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}var m;exports.OutType=void 0,(m=exports.OutType||(exports.OutType={})).Stdout="Stdout",m.Stderr="Stderr",exports.FilesystemWatcher=u,exports.Session=class extends y{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const s=Object.create(null,{open:{get:()=>super.open}});var e,t,i,l;return n(this,void 0,void 0,(function*(){yield s.open.call(this),yield this.handleSubscriptions((null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStateChange)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStderr)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStdout)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(l=this.codeSnippetOpts)||void 0===l?void 0:l.onScanPorts)?this.subscribe("codeSnippet",this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,e={})=>n(this,void 0,void 0,(function*(){var t,i;const o=yield this.call("codeSnippet","run",[s,e]);return null===(i=null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)||void 0===i||i.call(t,o),o})),stop:()=>n(this,void 0,void 0,(function*(){var s,e;const t=yield this.call("codeSnippet","stop");return null===(e=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===e||e.call(s,t),t}))},this.filesystem={list:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","list",[s])})),read:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","read",[s])})),remove:s=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","remove",[s])})),write:(s,e)=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","write",[s,e])})),makeDir:s=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","makeDir",[s])})),watchDir:s=>{const e=o.default(s);return new u(this,e)}},this.terminal={createSession:({onData:s,onChildProcessesChange:e,size:t,onExit:i,envVars:o,cmd:l,rootdir:h,terminalID:a=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:u}=d(),[p,v,g]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",a),this.subscribe("terminal",u,"onExit",a),e?this.subscribe("terminal",e,"onChildProcessesChange",a):void 0),{promise:f,resolve:b}=d();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(v),this.unsubscribe(p),g?this.unsubscribe(g):void 0]));s&&this.logger.error(s),null==i||i(),b()}))));try{yield this.call("terminal","start",[a,t.cols,t.rows,...void 0!==l?[o,l,h]:[]])}catch(s){throw u(),yield f,s}return{destroy:()=>n(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[a])}finally{u(),yield f}})),resize:({cols:s,rows:e})=>n(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[a,s,e])})),sendData:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","data",[a,s])})),terminalID:a}})),killProcess:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","killProcess",[s])}))},this.process={start:({cmd:s,onStdout:e,onStderr:t,onExit:i,envVars:o={},rootdir:l="/",processID:h=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:a}=d(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",h),e?this.subscribe("process",e,"onStdout",h):void 0,t?this.subscribe("process",t,"onStderr",h):void 0),{promise:g,resolve:f}=d();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==i||i(),f()}))));try{yield this.call("process","start",[h,s,o,l])}catch(s){throw a(),yield g,s}return{kill:()=>n(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[h])}finally{a(),yield g}})),processID:h,sendStdin:s=>n(this,void 0,void 0,(function*(){yield this.call("process","stdin",[h,s])}))}}))}}))}},exports.api=p,exports.createSessionProcess=function({cmd:s,manager:e,onStderr:t,onStdout:i,processID:o,rootdir:r}){return n(this,void 0,void 0,(function*(){if(!e)throw new Error("Cannot create process - process manager is not defined");const{resolve:n,promise:l}=d(),c=yield e.start({cmd:s,onStdout:i,onStderr:t,onExit:()=>{n()},rootdir:r,processID:o});return{exited:l,processID:c.processID,kill:c.kill,sendStdin:c.sendStdin}}))}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var s=require("normalize-path"),t=require("rpc-websocket-client");require("cross-fetch/polyfill");var e=require("openapi-typescript-fetch");function i(s){return s&&"object"==typeof s&&"default"in s?s:{default:s}}var o=i(s);function n(s,t,e,i){return new(e||(e=Promise))((function(o,n){function r(s){try{c(i.next(s))}catch(s){n(s)}}function l(s){try{c(i.throw(s))}catch(s){n(s)}}function c(s){var t;s.done?o(s.value):(t=s.value,t instanceof e?t:new e((function(s){s(t)}))).then(r,l)}c((i=i.apply(s,t||[])).next())}))}function r(s){let t="";const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=e.length;for(let o=0;o<s;o++)t+=e.charAt(Math.floor(Math.random()*i));return t}function l(s){return"fulfilled"===s.status}function c(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,t,e)=>"rejected"===t.status?s+"\n"+`[${e}]: `+`${JSON.stringify(t)}`:s),"errors:\n")}function d(){let s,t;return{promise:new Promise(((e,i)=>{s=e,t=i})),reject:t,resolve:s}}var h;exports.CodeSnippetExecState=void 0,(h=exports.CodeSnippetExecState||(exports.CodeSnippetExecState={})).Running="Running",h.Stopped="Stopped";var a;exports.FilesystemOperation=void 0,(a=exports.FilesystemOperation||(exports.FilesystemOperation={})).Create="Create",a.Write="Write",a.Remove="Remove",a.Rename="Rename",a.Chmod="Chmod";class u{constructor(s,t){this.sessConn=s,this.path=t,this.listeners=new Set}start(){return n(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe("filesystem",this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return n(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((t=>{t(s)}))}}const p=e.Fetcher.for();p.configure({baseUrl:"https://ondevbook.com"});class v{constructor(s,t=!1){this.logID=s,this.isEnabled=t}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function g(s){return new Promise((t=>setTimeout(t,s)))}const f=p.path("/sessions").method("post").create({api_key:!0}),b=p.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class y{constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new t.RpcWebSocketClient,this.subscribers=[],this.logger=new v("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const t=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${t}`:t}close(){var s,t,e,i,o,r;return n(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(t=null===(s=this.rpc.ws)||void 0===s?void 0:s.terminate)||void 0===t||t.call(s),null===(i=null===(e=this.rpc.ws)||void 0===e?void 0:e.close)||void 0===i||i.call(e),null===(r=null===(o=this.opts)||void 0===o?void 0:o.onClose)||void 0===r||r.call(o),this.logger.log("Disconected from the session")}}))}open(){return n(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield f({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof f.Error){const t=s.getActualType();if(400===t.status)throw new Error(`Error creating session - (${t.status}) bad request: ${t.data.message}`);if(401===t.status)throw new Error(`Error creating session - (${t.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${t.data.message}`);if(500===t.status)throw new Error(`Error creating session - (${t.status}) server error: ${t.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const t=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let e,i,o=!1;const r=new Promise(((s,t)=>{e=()=>{o||(o=!0,s())},i=()=>{o||(o=!0,t())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==e||e()})),this.rpc.onClose((s=>n(this,void 0,void 0,(function*(){var e,o,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(o=(e=this.opts).onDisconnect)||void 0===o||o.call(e),yield g(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(t),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==i||i()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(t)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield r}))}call(s,t,e){return n(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${t}`,e)}))}handleSubscriptions(...s){return n(this,void 0,void 0,(function*(){const t=yield Promise.allSettled(s);if(t.every((s=>"fulfilled"===s.status)))return t.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(t.filter(l).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(c(t))}))}unsubscribe(s){return n(this,void 0,void 0,(function*(){const t=this.subscribers.find((t=>t.subID===s));t&&(yield this.call(t.service,"unsubscribe",[t.subID]),this.subscribers=this.subscribers.filter((s=>s!==t)),this.logger.log(`Unsubscribed '${s}' from '${t.service}'`))}))}subscribe(s,t,e,...i){return n(this,void 0,void 0,(function*(){const o=yield this.call(s,"subscribe",[e,...i]);if("string"!=typeof o)throw new Error(`Cannot subscribe to ${s}_${e}${i.length>0?" with params ["+i.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(o)}`);return this.subscribers.push({handler:t,service:s,subID:o}),this.logger.log(`Subscribed to "${s}_${e}"${i.length>0?" with params ["+i.join(", ")+"] and":""} with id "${o}"`),o}))}handleNotification(s){this.subscribers.filter((t=>{var e;return t.subID===(null===(e=s.params)||void 0===e?void 0:e.subscription)})).forEach((t=>{var e;return t.handler(null===(e=s.params)||void 0===e?void 0:e.result)}))}refresh(s){return n(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield g(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield b({api_key:this.opts.apiKey,sessionID:s})}catch(t){if(t instanceof b.Error){const e=t.getActualType();if(404===e.status)return void this.logger.error(`Error refreshing session - (${e.status}): ${e.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${e.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}var m;exports.OutType=void 0,(m=exports.OutType||(exports.OutType={})).Stdout="Stdout",m.Stderr="Stderr",exports.FilesystemWatcher=u,exports.Session=class extends y{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const s=Object.create(null,{open:{get:()=>super.open}});var t,e,i,l;return n(this,void 0,void 0,(function*(){yield s.open.call(this),yield this.handleSubscriptions((null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStderr)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStdout)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(l=this.codeSnippetOpts)||void 0===l?void 0:l.onScanPorts)?this.subscribe("codeSnippet",this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,t={})=>n(this,void 0,void 0,(function*(){var e,i;const o=yield this.call("codeSnippet","run",[s,t]);return null===(i=null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStateChange)||void 0===i||i.call(e,o),o})),stop:()=>n(this,void 0,void 0,(function*(){var s,t;const e=yield this.call("codeSnippet","stop");return null===(t=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===t||t.call(s,e),e}))},this.filesystem={list:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","list",[s])})),read:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","read",[s])})),remove:s=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","remove",[s])})),write:(s,t)=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","write",[s,t])})),makeDir:s=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","makeDir",[s])})),watchDir:s=>{const t=o.default(s);return new u(this,t)}},this.terminal={createSession:({onData:s,size:t,onExit:e,envVars:i,cmd:o,rootdir:l,terminalID:h=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:a}=d(),[u,p]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",h),this.subscribe("terminal",a,"onExit",h)),{promise:v,resolve:g}=d();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(p),this.unsubscribe(u)]));s&&this.logger.error(s),null==e||e(),g()}))));try{yield this.call("terminal","start",[h,t.cols,t.rows,...void 0!==o?[i,o,l]:[]])}catch(s){throw a(),yield v,s}return{destroy:()=>n(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[h])}finally{a(),yield v}})),resize:({cols:s,rows:t})=>n(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[h,s,t])})),sendData:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","data",[h,s])})),terminalID:h}}))},this.process={start:({cmd:s,onStdout:t,onStderr:e,onExit:i,envVars:o={},rootdir:l="/",processID:h=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:a}=d(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",h),t?this.subscribe("process",t,"onStdout",h):void 0,e?this.subscribe("process",e,"onStderr",h):void 0),{promise:g,resolve:f}=d();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==i||i(),f()}))));try{yield this.call("process","start",[h,s,o,l])}catch(s){throw a(),yield g,s}return{kill:()=>n(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[h])}finally{a(),yield g}})),processID:h,sendStdin:s=>n(this,void 0,void 0,(function*(){yield this.call("process","stdin",[h,s])}))}}))}}))}},exports.api=p,exports.createSessionProcess=function({cmd:s,manager:t,onStderr:e,onStdout:i,processID:o,rootdir:r}){return n(this,void 0,void 0,(function*(){if(!t)throw new Error("Cannot create process - process manager is not defined");const{resolve:n,promise:l}=d(),c=yield t.start({cmd:s,onStdout:i,onStderr:e,onExit:()=>{n()},rootdir:r,processID:o});return{exited:l,processID:c.processID,kill:c.kill,sendStdin:c.sendStdin}}))}; | ||
//# sourceMappingURL=index.js.map |
@@ -12,12 +12,6 @@ import { EnvVars } from './envVars'; | ||
} | ||
export interface ChildProcess { | ||
cmd: string; | ||
pid: number; | ||
} | ||
export interface TerminalManager { | ||
readonly killProcess: (pid: number) => Promise<void>; | ||
readonly createSession: (opts: { | ||
onData: (data: string) => void; | ||
onExit?: () => void; | ||
onChildProcessesChange?: (cps: ChildProcess[]) => void; | ||
size: { | ||
@@ -24,0 +18,0 @@ cols: number; |
@@ -7,3 +7,3 @@ export { default as Session } from './session'; | ||
export { OutType } from './session/out'; | ||
export type { TerminalManager, TerminalSession, ChildProcess } from './session/terminal'; | ||
export type { TerminalManager, TerminalSession } from './session/terminal'; | ||
export type { FilesystemManager, FileInfo } from './session/filesystem'; | ||
@@ -10,0 +10,0 @@ export { default as FilesystemWatcher, FilesystemOperation, } from './session/filesystemWatcher'; |
@@ -1,2 +0,2 @@ | ||
import s from"normalize-path";import{RpcWebSocketClient as i}from"rpc-websocket-client";import"cross-fetch/polyfill";import{Fetcher as t}from"openapi-typescript-fetch";function e(s,i,t,e){return new(t||(t=Promise))((function(o,n){function r(s){try{c(e.next(s))}catch(s){n(s)}}function l(s){try{c(e.throw(s))}catch(s){n(s)}}function c(s){var i;s.done?o(s.value):(i=s.value,i instanceof t?i:new t((function(s){s(i)}))).then(r,l)}c((e=e.apply(s,i||[])).next())}))}function o(s){let i="";const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",e=t.length;for(let o=0;o<s;o++)i+=t.charAt(Math.floor(Math.random()*e));return i}function n(s){return"fulfilled"===s.status}function r(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,i,t)=>"rejected"===i.status?s+"\n"+`[${t}]: `+`${JSON.stringify(i)}`:s),"errors:\n")}function l(){let s,i;return{promise:new Promise(((t,e)=>{s=t,i=e})),reject:i,resolve:s}}var c;!function(s){s.Running="Running",s.Stopped="Stopped"}(c||(c={}));var d;!function(s){s.Create="Create",s.Write="Write",s.Remove="Remove",s.Rename="Rename",s.Chmod="Chmod"}(d||(d={}));class h{constructor(s,i){this.sessConn=s,this.path=i,this.listeners=new Set}start(){return e(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe("filesystem",this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return e(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((i=>{i(s)}))}}const a=t.for();a.configure({baseUrl:"https://ondevbook.com"});class u{constructor(s,i=!1){this.logID=s,this.isEnabled=i}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function p(s){return new Promise((i=>setTimeout(i,s)))}const v=a.path("/sessions").method("post").create({api_key:!0}),g=a.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class f{constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new i,this.subscribers=[],this.logger=new u("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const i=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${i}`:i}close(){var s,i,t;return e(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(s=this.rpc.ws)||void 0===s||s.close(),null===(t=null===(i=this.opts)||void 0===i?void 0:i.onClose)||void 0===t||t.call(i),this.logger.log("Disconected from the session")}}))}open(){return e(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield v({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof v.Error){const i=s.getActualType();if(400===i.status)throw new Error(`Error creating session - (${i.status}) bad request: ${i.data.message}`);if(401===i.status)throw new Error(`Error creating session - (${i.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${i.data.message}`);if(500===i.status)throw new Error(`Error creating session - (${i.status}) server error: ${i.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const i=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let t,o,n=!1;const r=new Promise(((s,i)=>{t=()=>{n||(n=!0,s())},o=()=>{n||(n=!0,i())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==t||t()})),this.rpc.onClose((s=>e(this,void 0,void 0,(function*(){var t,e,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(e=(t=this.opts).onDisconnect)||void 0===e||e.call(t),yield p(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(i),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==o||o()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(i)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield r}))}call(s,i,t){return e(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${i}`,t)}))}handleSubscriptions(...s){return e(this,void 0,void 0,(function*(){const i=yield Promise.allSettled(s);if(i.every((s=>"fulfilled"===s.status)))return i.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(i.filter(n).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(r(i))}))}unsubscribe(s){return e(this,void 0,void 0,(function*(){const i=this.subscribers.find((i=>i.subID===s));i&&(yield this.call(i.service,"unsubscribe",[i.subID]),this.subscribers=this.subscribers.filter((s=>s!==i)),this.logger.log(`Unsubscribed '${s}' from '${i.service}'`))}))}subscribe(s,i,t,...o){return e(this,void 0,void 0,(function*(){const e=yield this.call(s,"subscribe",[t,...o]);if("string"!=typeof e)throw new Error(`Cannot subscribe to ${s}_${t}${o.length>0?" with params ["+o.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(e)}`);return this.subscribers.push({handler:i,service:s,subID:e}),this.logger.log(`Subscribed to "${s}_${t}"${o.length>0?" with params ["+o.join(", ")+"] and":""} with id "${e}"`),e}))}handleNotification(s){this.subscribers.filter((i=>{var t;return i.subID===(null===(t=s.params)||void 0===t?void 0:t.subscription)})).forEach((i=>{var t;return i.handler(null===(t=s.params)||void 0===t?void 0:t.result)}))}refresh(s){return e(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield p(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield g({api_key:this.opts.apiKey,sessionID:s})}catch(i){if(i instanceof g.Error){const t=i.getActualType();if(404===t.status)return void this.logger.error(`Error refreshing session - (${t.status}): ${t.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${t.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}class b extends f{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const i=Object.create(null,{open:{get:()=>super.open}});var t,n,c,d;return e(this,void 0,void 0,(function*(){yield i.open.call(this),yield this.handleSubscriptions((null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(n=this.codeSnippetOpts)||void 0===n?void 0:n.onStderr)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(c=this.codeSnippetOpts)||void 0===c?void 0:c.onStdout)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(d=this.codeSnippetOpts)||void 0===d?void 0:d.onScanPorts)?this.subscribe("codeSnippet",this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,i={})=>e(this,void 0,void 0,(function*(){var t,e;const o=yield this.call("codeSnippet","run",[s,i]);return null===(e=null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)||void 0===e||e.call(t,o),o})),stop:()=>e(this,void 0,void 0,(function*(){var s,i;const t=yield this.call("codeSnippet","stop");return null===(i=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===i||i.call(s,t),t}))},this.filesystem={list:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","list",[s])})),read:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","read",[s])})),remove:s=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","remove",[s])})),write:(s,i)=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","write",[s,i])})),makeDir:s=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","makeDir",[s])})),watchDir:i=>{const t=s(i);return new h(this,t)}},this.terminal={createSession:({onData:s,onChildProcessesChange:i,size:t,onExit:n,envVars:c,cmd:d,rootdir:h,terminalID:a=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:u}=l(),[p,v,g]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",a),this.subscribe("terminal",u,"onExit",a),i?this.subscribe("terminal",i,"onChildProcessesChange",a):void 0),{promise:f,resolve:b}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(v),this.unsubscribe(p),g?this.unsubscribe(g):void 0]));s&&this.logger.error(s),null==n||n(),b()}))));try{yield this.call("terminal","start",[a,t.cols,t.rows,...void 0!==d?[c,d,h]:[]])}catch(s){throw u(),yield f,s}return{destroy:()=>e(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[a])}finally{u(),yield f}})),resize:({cols:s,rows:i})=>e(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[a,s,i])})),sendData:s=>e(this,void 0,void 0,(function*(){yield this.call("terminal","data",[a,s])})),terminalID:a}})),killProcess:s=>e(this,void 0,void 0,(function*(){yield this.call("terminal","killProcess",[s])}))},this.process={start:({cmd:s,onStdout:i,onStderr:t,onExit:n,envVars:c={},rootdir:d="/",processID:h=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:a}=l(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",h),i?this.subscribe("process",i,"onStdout",h):void 0,t?this.subscribe("process",t,"onStderr",h):void 0),{promise:g,resolve:f}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==n||n(),f()}))));try{yield this.call("process","start",[h,s,c,d])}catch(s){throw a(),yield g,s}return{kill:()=>e(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[h])}finally{a(),yield g}})),processID:h,sendStdin:s=>e(this,void 0,void 0,(function*(){yield this.call("process","stdin",[h,s])}))}}))}}))}}var m;function y({cmd:s,manager:i,onStderr:t,onStdout:o,processID:n,rootdir:r}){return e(this,void 0,void 0,(function*(){if(!i)throw new Error("Cannot create process - process manager is not defined");const{resolve:e,promise:c}=l(),d=yield i.start({cmd:s,onStdout:o,onStderr:t,onExit:()=>{e()},rootdir:r,processID:n});return{exited:c,processID:d.processID,kill:d.kill,sendStdin:d.sendStdin}}))}!function(s){s.Stdout="Stdout",s.Stderr="Stderr"}(m||(m={}));export{c as CodeSnippetExecState,d as FilesystemOperation,h as FilesystemWatcher,m as OutType,b as Session,a as api,y as createSessionProcess}; | ||
import s from"normalize-path";import{RpcWebSocketClient as t}from"rpc-websocket-client";import"cross-fetch/polyfill";import{Fetcher as i}from"openapi-typescript-fetch";function e(s,t,i,e){return new(i||(i=Promise))((function(o,n){function r(s){try{c(e.next(s))}catch(s){n(s)}}function l(s){try{c(e.throw(s))}catch(s){n(s)}}function c(s){var t;s.done?o(s.value):(t=s.value,t instanceof i?t:new i((function(s){s(t)}))).then(r,l)}c((e=e.apply(s,t||[])).next())}))}function o(s){let t="";const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",e=i.length;for(let o=0;o<s;o++)t+=i.charAt(Math.floor(Math.random()*e));return t}function n(s){return"fulfilled"===s.status}function r(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,t,i)=>"rejected"===t.status?s+"\n"+`[${i}]: `+`${JSON.stringify(t)}`:s),"errors:\n")}function l(){let s,t;return{promise:new Promise(((i,e)=>{s=i,t=e})),reject:t,resolve:s}}var c;!function(s){s.Running="Running",s.Stopped="Stopped"}(c||(c={}));var d;!function(s){s.Create="Create",s.Write="Write",s.Remove="Remove",s.Rename="Rename",s.Chmod="Chmod"}(d||(d={}));class h{constructor(s,t){this.sessConn=s,this.path=t,this.listeners=new Set}start(){return e(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe("filesystem",this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return e(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((t=>{t(s)}))}}const a=i.for();a.configure({baseUrl:"https://ondevbook.com"});class u{constructor(s,t=!1){this.logID=s,this.isEnabled=t}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function p(s){return new Promise((t=>setTimeout(t,s)))}const v=a.path("/sessions").method("post").create({api_key:!0}),g=a.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class f{constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new t,this.subscribers=[],this.logger=new u("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const t=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${t}`:t}close(){var s,t,i,o,n,r;return e(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(t=null===(s=this.rpc.ws)||void 0===s?void 0:s.terminate)||void 0===t||t.call(s),null===(o=null===(i=this.rpc.ws)||void 0===i?void 0:i.close)||void 0===o||o.call(i),null===(r=null===(n=this.opts)||void 0===n?void 0:n.onClose)||void 0===r||r.call(n),this.logger.log("Disconected from the session")}}))}open(){return e(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield v({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof v.Error){const t=s.getActualType();if(400===t.status)throw new Error(`Error creating session - (${t.status}) bad request: ${t.data.message}`);if(401===t.status)throw new Error(`Error creating session - (${t.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${t.data.message}`);if(500===t.status)throw new Error(`Error creating session - (${t.status}) server error: ${t.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const t=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let i,o,n=!1;const r=new Promise(((s,t)=>{i=()=>{n||(n=!0,s())},o=()=>{n||(n=!0,t())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==i||i()})),this.rpc.onClose((s=>e(this,void 0,void 0,(function*(){var i,e,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(e=(i=this.opts).onDisconnect)||void 0===e||e.call(i),yield p(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(t),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==o||o()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(t)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield r}))}call(s,t,i){return e(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${t}`,i)}))}handleSubscriptions(...s){return e(this,void 0,void 0,(function*(){const t=yield Promise.allSettled(s);if(t.every((s=>"fulfilled"===s.status)))return t.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(t.filter(n).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(r(t))}))}unsubscribe(s){return e(this,void 0,void 0,(function*(){const t=this.subscribers.find((t=>t.subID===s));t&&(yield this.call(t.service,"unsubscribe",[t.subID]),this.subscribers=this.subscribers.filter((s=>s!==t)),this.logger.log(`Unsubscribed '${s}' from '${t.service}'`))}))}subscribe(s,t,i,...o){return e(this,void 0,void 0,(function*(){const e=yield this.call(s,"subscribe",[i,...o]);if("string"!=typeof e)throw new Error(`Cannot subscribe to ${s}_${i}${o.length>0?" with params ["+o.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(e)}`);return this.subscribers.push({handler:t,service:s,subID:e}),this.logger.log(`Subscribed to "${s}_${i}"${o.length>0?" with params ["+o.join(", ")+"] and":""} with id "${e}"`),e}))}handleNotification(s){this.subscribers.filter((t=>{var i;return t.subID===(null===(i=s.params)||void 0===i?void 0:i.subscription)})).forEach((t=>{var i;return t.handler(null===(i=s.params)||void 0===i?void 0:i.result)}))}refresh(s){return e(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield p(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield g({api_key:this.opts.apiKey,sessionID:s})}catch(t){if(t instanceof g.Error){const i=t.getActualType();if(404===i.status)return void this.logger.error(`Error refreshing session - (${i.status}): ${i.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${i.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}class b extends f{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const t=Object.create(null,{open:{get:()=>super.open}});var i,n,c,d;return e(this,void 0,void 0,(function*(){yield t.open.call(this),yield this.handleSubscriptions((null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStateChange)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(n=this.codeSnippetOpts)||void 0===n?void 0:n.onStderr)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(c=this.codeSnippetOpts)||void 0===c?void 0:c.onStdout)?this.subscribe("codeSnippet",this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(d=this.codeSnippetOpts)||void 0===d?void 0:d.onScanPorts)?this.subscribe("codeSnippet",this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,t={})=>e(this,void 0,void 0,(function*(){var i,e;const o=yield this.call("codeSnippet","run",[s,t]);return null===(e=null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStateChange)||void 0===e||e.call(i,o),o})),stop:()=>e(this,void 0,void 0,(function*(){var s,t;const i=yield this.call("codeSnippet","stop");return null===(t=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===t||t.call(s,i),i}))},this.filesystem={list:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","list",[s])})),read:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","read",[s])})),remove:s=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","remove",[s])})),write:(s,t)=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","write",[s,t])})),makeDir:s=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","makeDir",[s])})),watchDir:t=>{const i=s(t);return new h(this,i)}},this.terminal={createSession:({onData:s,size:t,onExit:i,envVars:n,cmd:c,rootdir:d,terminalID:h=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:a}=l(),[u,p]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",h),this.subscribe("terminal",a,"onExit",h)),{promise:v,resolve:g}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(p),this.unsubscribe(u)]));s&&this.logger.error(s),null==i||i(),g()}))));try{yield this.call("terminal","start",[h,t.cols,t.rows,...void 0!==c?[n,c,d]:[]])}catch(s){throw a(),yield v,s}return{destroy:()=>e(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[h])}finally{a(),yield v}})),resize:({cols:s,rows:t})=>e(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[h,s,t])})),sendData:s=>e(this,void 0,void 0,(function*(){yield this.call("terminal","data",[h,s])})),terminalID:h}}))},this.process={start:({cmd:s,onStdout:t,onStderr:i,onExit:n,envVars:c={},rootdir:d="/",processID:h=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:a}=l(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",h),t?this.subscribe("process",t,"onStdout",h):void 0,i?this.subscribe("process",i,"onStderr",h):void 0),{promise:g,resolve:f}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==n||n(),f()}))));try{yield this.call("process","start",[h,s,c,d])}catch(s){throw a(),yield g,s}return{kill:()=>e(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[h])}finally{a(),yield g}})),processID:h,sendStdin:s=>e(this,void 0,void 0,(function*(){yield this.call("process","stdin",[h,s])}))}}))}}))}}var m;function y({cmd:s,manager:t,onStderr:i,onStdout:o,processID:n,rootdir:r}){return e(this,void 0,void 0,(function*(){if(!t)throw new Error("Cannot create process - process manager is not defined");const{resolve:e,promise:c}=l(),d=yield t.start({cmd:s,onStdout:o,onStderr:i,onExit:()=>{e()},rootdir:r,processID:n});return{exited:c,processID:d.processID,kill:d.kill,sendStdin:d.sendStdin}}))}!function(s){s.Stdout="Stdout",s.Stderr="Stderr"}(m||(m={}));export{c as CodeSnippetExecState,d as FilesystemOperation,h as FilesystemWatcher,m as OutType,b as Session,a as api,y as createSessionProcess}; | ||
//# sourceMappingURL=index.js.map |
@@ -12,12 +12,6 @@ import { EnvVars } from './envVars'; | ||
} | ||
export interface ChildProcess { | ||
cmd: string; | ||
pid: number; | ||
} | ||
export interface TerminalManager { | ||
readonly killProcess: (pid: number) => Promise<void>; | ||
readonly createSession: (opts: { | ||
onData: (data: string) => void; | ||
onExit?: () => void; | ||
onChildProcessesChange?: (cps: ChildProcess[]) => void; | ||
size: { | ||
@@ -24,0 +18,0 @@ cols: number; |
@@ -7,3 +7,3 @@ export { default as Session } from './session'; | ||
export { OutType } from './session/out'; | ||
export type { TerminalManager, TerminalSession, ChildProcess } from './session/terminal'; | ||
export type { TerminalManager, TerminalSession } from './session/terminal'; | ||
export type { FilesystemManager, FileInfo } from './session/filesystem'; | ||
@@ -10,0 +10,0 @@ export { default as FilesystemWatcher, FilesystemOperation, } from './session/filesystemWatcher'; |
@@ -1,2 +0,2 @@ | ||
!function(s,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("normalize-path"),require("rpc-websocket-client"),require("cross-fetch/polyfill"),require("openapi-typescript-fetch")):"function"==typeof define&&define.amd?define(["exports","normalize-path","rpc-websocket-client","cross-fetch/polyfill","openapi-typescript-fetch"],t):t((s="undefined"!=typeof globalThis?globalThis:s||self)["@devbookhq/sdk"]={},s.normalizePath,s.rpcWebsocketClient,null,s.openapiTypescriptFetch)}(this,(function(s,t,e,i,o){"use strict";function n(s){return s&&"object"==typeof s&&"default"in s?s:{default:s}}var r=n(t);function l(s,t,e,i){return new(e||(e=Promise))((function(o,n){function r(s){try{c(i.next(s))}catch(s){n(s)}}function l(s){try{c(i.throw(s))}catch(s){n(s)}}function c(s){var t;s.done?o(s.value):(t=s.value,t instanceof e?t:new e((function(s){s(t)}))).then(r,l)}c((i=i.apply(s,t||[])).next())}))}function c(s){let t="";const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=e.length;for(let o=0;o<s;o++)t+=e.charAt(Math.floor(Math.random()*i));return t}function d(s){return"fulfilled"===s.status}function h(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,t,e)=>"rejected"===t.status?s+"\n"+`[${e}]: `+`${JSON.stringify(t)}`:s),"errors:\n")}function a(){let s,t;return{promise:new Promise(((e,i)=>{s=e,t=i})),reject:t,resolve:s}}const u="codeSnippet";var p;s.CodeSnippetExecState=void 0,(p=s.CodeSnippetExecState||(s.CodeSnippetExecState={})).Running="Running",p.Stopped="Stopped";const v="filesystem";var f;s.FilesystemOperation=void 0,(f=s.FilesystemOperation||(s.FilesystemOperation={})).Create="Create",f.Write="Write",f.Remove="Remove",f.Rename="Rename",f.Chmod="Chmod";class g{constructor(s,t){this.sessConn=s,this.path=t,this.listeners=new Set}start(){return l(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe(v,this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return l(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((t=>{t(s)}))}}const b="process",y=o.Fetcher.for();y.configure({baseUrl:"https://ondevbook.com"});class m{constructor(s,t=!1){this.logID=s,this.isEnabled=t}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function S(s){return new Promise((t=>setTimeout(t,s)))}const w=y.path("/sessions").method("post").create({api_key:!0}),E=y.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class ${constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new e.RpcWebSocketClient,this.subscribers=[],this.logger=new m("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const t=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${t}`:t}close(){var s,t,e;return l(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(s=this.rpc.ws)||void 0===s||s.close(),null===(e=null===(t=this.opts)||void 0===t?void 0:t.onClose)||void 0===e||e.call(t),this.logger.log("Disconected from the session")}}))}open(){return l(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield w({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof w.Error){const t=s.getActualType();if(400===t.status)throw new Error(`Error creating session - (${t.status}) bad request: ${t.data.message}`);if(401===t.status)throw new Error(`Error creating session - (${t.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${t.data.message}`);if(500===t.status)throw new Error(`Error creating session - (${t.status}) server error: ${t.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const t=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let e,i,o=!1;const n=new Promise(((s,t)=>{e=()=>{o||(o=!0,s())},i=()=>{o||(o=!0,t())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==e||e()})),this.rpc.onClose((s=>l(this,void 0,void 0,(function*(){var e,o,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(o=(e=this.opts).onDisconnect)||void 0===o||o.call(e),yield S(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(t),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==i||i()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(t)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield n}))}call(s,t,e){return l(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${t}`,e)}))}handleSubscriptions(...s){return l(this,void 0,void 0,(function*(){const t=yield Promise.allSettled(s);if(t.every((s=>"fulfilled"===s.status)))return t.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(t.filter(d).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(h(t))}))}unsubscribe(s){return l(this,void 0,void 0,(function*(){const t=this.subscribers.find((t=>t.subID===s));t&&(yield this.call(t.service,"unsubscribe",[t.subID]),this.subscribers=this.subscribers.filter((s=>s!==t)),this.logger.log(`Unsubscribed '${s}' from '${t.service}'`))}))}subscribe(s,t,e,...i){return l(this,void 0,void 0,(function*(){const o=yield this.call(s,"subscribe",[e,...i]);if("string"!=typeof o)throw new Error(`Cannot subscribe to ${s}_${e}${i.length>0?" with params ["+i.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(o)}`);return this.subscribers.push({handler:t,service:s,subID:o}),this.logger.log(`Subscribed to "${s}_${e}"${i.length>0?" with params ["+i.join(", ")+"] and":""} with id "${o}"`),o}))}handleNotification(s){this.subscribers.filter((t=>{var e;return t.subID===(null===(e=s.params)||void 0===e?void 0:e.subscription)})).forEach((t=>{var e;return t.handler(null===(e=s.params)||void 0===e?void 0:e.result)}))}refresh(s){return l(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield S(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield E({api_key:this.opts.apiKey,sessionID:s})}catch(t){if(t instanceof E.Error){const e=t.getActualType();if(404===e.status)return void this.logger.error(`Error refreshing session - (${e.status}): ${e.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${e.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}const D="terminal";var _;s.OutType=void 0,(_=s.OutType||(s.OutType={})).Stdout="Stdout",_.Stderr="Stderr",s.FilesystemWatcher=g,s.Session=class extends ${constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const s=Object.create(null,{open:{get:()=>super.open}});var t,e,i,o;return l(this,void 0,void 0,(function*(){yield s.open.call(this),yield this.handleSubscriptions((null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)?this.subscribe(u,this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStderr)?this.subscribe(u,this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStdout)?this.subscribe(u,this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(o=this.codeSnippetOpts)||void 0===o?void 0:o.onScanPorts)?this.subscribe(u,this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,t={})=>l(this,void 0,void 0,(function*(){var e,i;const o=yield this.call(u,"run",[s,t]);return null===(i=null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStateChange)||void 0===i||i.call(e,o),o})),stop:()=>l(this,void 0,void 0,(function*(){var s,t;const e=yield this.call(u,"stop");return null===(t=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===t||t.call(s,e),e}))},this.filesystem={list:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"list",[s])})),read:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"read",[s])})),remove:s=>l(this,void 0,void 0,(function*(){yield this.call(v,"remove",[s])})),write:(s,t)=>l(this,void 0,void 0,(function*(){yield this.call(v,"write",[s,t])})),makeDir:s=>l(this,void 0,void 0,(function*(){yield this.call(v,"makeDir",[s])})),watchDir:s=>{const t=r.default(s);return new g(this,t)}},this.terminal={createSession:({onData:s,onChildProcessesChange:t,size:e,onExit:i,envVars:o,cmd:n,rootdir:r,terminalID:d=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:c,resolve:u}=a(),[p,v,f]=yield this.handleSubscriptions(this.subscribe(D,s,"onData",d),this.subscribe(D,u,"onExit",d),t?this.subscribe(D,t,"onChildProcessesChange",d):void 0),{promise:g,resolve:b}=a();c.then((()=>l(this,void 0,void 0,(function*(){const s=h(yield Promise.allSettled([this.unsubscribe(v),this.unsubscribe(p),f?this.unsubscribe(f):void 0]));s&&this.logger.error(s),null==i||i(),b()}))));try{yield this.call(D,"start",[d,e.cols,e.rows,...void 0!==n?[o,n,r]:[]])}catch(s){throw u(),yield g,s}return{destroy:()=>l(this,void 0,void 0,(function*(){try{yield this.call(D,"destroy",[d])}finally{u(),yield g}})),resize:({cols:s,rows:t})=>l(this,void 0,void 0,(function*(){yield this.call(D,"resize",[d,s,t])})),sendData:s=>l(this,void 0,void 0,(function*(){yield this.call(D,"data",[d,s])})),terminalID:d}})),killProcess:s=>l(this,void 0,void 0,(function*(){yield this.call(D,"killProcess",[s])}))},this.process={start:({cmd:s,onStdout:t,onStderr:e,onExit:i,envVars:o={},rootdir:n="/",processID:r=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:c,resolve:d}=a(),[u,p,v]=yield this.handleSubscriptions(this.subscribe(b,d,"onExit",r),t?this.subscribe(b,t,"onStdout",r):void 0,e?this.subscribe(b,e,"onStderr",r):void 0),{promise:f,resolve:g}=a();c.then((()=>l(this,void 0,void 0,(function*(){const s=h(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==i||i(),g()}))));try{yield this.call(b,"start",[r,s,o,n])}catch(s){throw d(),yield f,s}return{kill:()=>l(this,void 0,void 0,(function*(){try{yield this.call(b,"kill",[r])}finally{d(),yield f}})),processID:r,sendStdin:s=>l(this,void 0,void 0,(function*(){yield this.call(b,"stdin",[r,s])}))}}))}}))}},s.api=y,s.createSessionProcess=function({cmd:s,manager:t,onStderr:e,onStdout:i,processID:o,rootdir:n}){return l(this,void 0,void 0,(function*(){if(!t)throw new Error("Cannot create process - process manager is not defined");const{resolve:r,promise:l}=a(),c=yield t.start({cmd:s,onStdout:i,onStderr:e,onExit:()=>{r()},rootdir:n,processID:o});return{exited:l,processID:c.processID,kill:c.kill,sendStdin:c.sendStdin}}))},Object.defineProperty(s,"__esModule",{value:!0})})); | ||
!function(s,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("normalize-path"),require("rpc-websocket-client"),require("cross-fetch/polyfill"),require("openapi-typescript-fetch")):"function"==typeof define&&define.amd?define(["exports","normalize-path","rpc-websocket-client","cross-fetch/polyfill","openapi-typescript-fetch"],t):t((s="undefined"!=typeof globalThis?globalThis:s||self)["@devbookhq/sdk"]={},s.normalizePath,s.rpcWebsocketClient,null,s.openapiTypescriptFetch)}(this,(function(s,t,e,i,o){"use strict";function n(s){return s&&"object"==typeof s&&"default"in s?s:{default:s}}var r=n(t);function l(s,t,e,i){return new(e||(e=Promise))((function(o,n){function r(s){try{c(i.next(s))}catch(s){n(s)}}function l(s){try{c(i.throw(s))}catch(s){n(s)}}function c(s){var t;s.done?o(s.value):(t=s.value,t instanceof e?t:new e((function(s){s(t)}))).then(r,l)}c((i=i.apply(s,t||[])).next())}))}function c(s){let t="";const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",i=e.length;for(let o=0;o<s;o++)t+=e.charAt(Math.floor(Math.random()*i));return t}function d(s){return"fulfilled"===s.status}function h(s){if(!s.every((s=>"fulfilled"===s.status)))return s.reduce(((s,t,e)=>"rejected"===t.status?s+"\n"+`[${e}]: `+`${JSON.stringify(t)}`:s),"errors:\n")}function a(){let s,t;return{promise:new Promise(((e,i)=>{s=e,t=i})),reject:t,resolve:s}}const u="codeSnippet";var p;s.CodeSnippetExecState=void 0,(p=s.CodeSnippetExecState||(s.CodeSnippetExecState={})).Running="Running",p.Stopped="Stopped";const v="filesystem";var f;s.FilesystemOperation=void 0,(f=s.FilesystemOperation||(s.FilesystemOperation={})).Create="Create",f.Write="Write",f.Remove="Remove",f.Rename="Rename",f.Chmod="Chmod";class g{constructor(s,t){this.sessConn=s,this.path=t,this.listeners=new Set}start(){return l(this,void 0,void 0,(function*(){this.rpcSubscriptionID||(this.handleFilesystemEvents=this.handleFilesystemEvents.bind(this),this.rpcSubscriptionID=yield this.sessConn.subscribe(v,this.handleFilesystemEvents,"watchDir",this.path))}))}stop(){return l(this,void 0,void 0,(function*(){this.listeners.clear(),this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID))}))}addEventListener(s){return this.listeners.add(s),()=>this.listeners.delete(s)}handleFilesystemEvents(s){this.listeners.forEach((t=>{t(s)}))}}const b="process",y=o.Fetcher.for();y.configure({baseUrl:"https://ondevbook.com"});class m{constructor(s,t=!1){this.logID=s,this.isEnabled=t}error(...s){console.error(`[31m[${this.id()} ERROR][0m`,...s)}log(...s){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function S(s){return new Promise((t=>setTimeout(t,s)))}const w=y.path("/sessions").method("post").create({api_key:!0}),E=y.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});class ${constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new e.RpcWebSocketClient,this.subscribers=[],this.logger=new m("Session",s.debug),this.logger.log(`Session for code snippet "${s.id}" initialized`)}getHostname(s){if(this.opts.__debug_hostname)return s&&"remote"===this.opts.__debug_devEnv?`${s}-${this.opts.__debug_hostname}`:s?`${this.opts.__debug_hostname}:${s}`:this.opts.__debug_hostname;if(!this.session)return;const t=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${t}`:t}close(){var s,t,e,i,o,n;return l(this,void 0,void 0,(function*(){if(this.isOpen){this.logger.log("Closing",this.session),this.isOpen=!1,this.logger.log("Unsubscribing...");(yield Promise.allSettled(this.subscribers.map((s=>this.unsubscribe(s.subID))))).forEach((s=>{"rejected"===s.status&&this.logger.log(`Failed to unsubscribe: "${s.reason}"`)})),null===(t=null===(s=this.rpc.ws)||void 0===s?void 0:s.terminate)||void 0===t||t.call(s),null===(i=null===(e=this.rpc.ws)||void 0===e?void 0:e.close)||void 0===i||i.call(e),null===(n=null===(o=this.opts)||void 0===o?void 0:o.onClose)||void 0===n||n.call(o),this.logger.log("Disconected from the session")}}))}open(){return l(this,void 0,void 0,(function*(){if(this.isOpen||this.session)throw new Error("Session connect was already called");if(this.isOpen=!0,!this.opts.__debug_hostname)try{const s=yield w({api_key:this.opts.apiKey,codeSnippetID:this.opts.id,editEnabled:this.opts.editEnabled});this.session=s.data,this.logger.log("Aquired session:",this.session),this.refresh(this.session.sessionID)}catch(s){if(s instanceof w.Error){const t=s.getActualType();if(400===t.status)throw new Error(`Error creating session - (${t.status}) bad request: ${t.data.message}`);if(401===t.status)throw new Error(`Error creating session - (${t.status}) unauthenticated (you need to be authenticated to start an session with persistent edits): ${t.data.message}`);if(500===t.status)throw new Error(`Error creating session - (${t.status}) server error: ${t.data.message}`)}throw s}const s=this.getHostname(this.opts.__debug_port||49982);if(!s)throw new Error("Cannot get session's hostname");const t=`${"local"===this.opts.__debug_devEnv?"ws":"wss"}://${s}/ws`;this.rpc.onError((s=>{this.logger.log("Error in WS session:",this.session,s)}));let e,i,o=!1;const n=new Promise(((s,t)=>{e=()=>{o||(o=!0,s())},i=()=>{o||(o=!0,t())}}));this.rpc.onOpen((()=>{this.logger.log("Connected to session:",this.session),null==e||e()})),this.rpc.onClose((s=>l(this,void 0,void 0,(function*(){var e,o,n,r;if(this.logger.log("Closing WS connection to session:",this.session,s),this.isOpen){null===(o=(e=this.opts).onDisconnect)||void 0===o||o.call(e),yield S(600),this.logger.log("Reconnecting to session:",this.session);try{this.subscribers=[],yield this.rpc.connect(t),null===(r=(n=this.opts).onReconnect)||void 0===r||r.call(n),this.logger.log("Reconnected to session:",this.session)}catch(s){this.logger.log("Failed reconnecting to session:",this.session,s)}}else null==i||i()})))),this.rpc.onNotification.push(this.handleNotification.bind(this));try{this.logger.log("Connection to session:",this.session),yield this.rpc.connect(t)}catch(s){this.logger.log("Error connecting to session",this.session,s)}yield n}))}call(s,t,e){return l(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${t}`,e)}))}handleSubscriptions(...s){return l(this,void 0,void 0,(function*(){const t=yield Promise.allSettled(s);if(t.every((s=>"fulfilled"===s.status)))return t.map((s=>"fulfilled"===s.status?s.value:void 0));throw yield Promise.all(t.filter(d).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(h(t))}))}unsubscribe(s){return l(this,void 0,void 0,(function*(){const t=this.subscribers.find((t=>t.subID===s));t&&(yield this.call(t.service,"unsubscribe",[t.subID]),this.subscribers=this.subscribers.filter((s=>s!==t)),this.logger.log(`Unsubscribed '${s}' from '${t.service}'`))}))}subscribe(s,t,e,...i){return l(this,void 0,void 0,(function*(){const o=yield this.call(s,"subscribe",[e,...i]);if("string"!=typeof o)throw new Error(`Cannot subscribe to ${s}_${e}${i.length>0?" with params ["+i.join(", ")+"]":""}. Expected response should have been a subscription ID, instead we got ${JSON.stringify(o)}`);return this.subscribers.push({handler:t,service:s,subID:o}),this.logger.log(`Subscribed to "${s}_${e}"${i.length>0?" with params ["+i.join(", ")+"] and":""} with id "${o}"`),o}))}handleNotification(s){this.subscribers.filter((t=>{var e;return t.subID===(null===(e=s.params)||void 0===e?void 0:e.subscription)})).forEach((t=>{var e;return t.handler(null===(e=s.params)||void 0===e?void 0:e.result)}))}refresh(s){return l(this,void 0,void 0,(function*(){this.logger.log(`Started refreshing session "${s}"`);try{for(;;){if(!this.isOpen)return void this.logger.log("Cannot refresh session - it was closed",this.session);yield S(5e3);try{this.logger.log(`Refreshed session "${s}"`),yield E({api_key:this.opts.apiKey,sessionID:s})}catch(t){if(t instanceof E.Error){const e=t.getActualType();if(404===e.status)return void this.logger.error(`Error refreshing session - (${e.status}): ${e.data.message}`);this.logger.error(`Refreshing session "${s}" failed - (${e.status})`)}}}}finally{this.logger.log(`Stopped refreshing session "${s}"`),this.close()}}))}}const D="terminal";var _;s.OutType=void 0,(_=s.OutType||(s.OutType={})).Stdout="Stdout",_.Stderr="Stderr",s.FilesystemWatcher=g,s.Session=class extends ${constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const s=Object.create(null,{open:{get:()=>super.open}});var t,e,i,o;return l(this,void 0,void 0,(function*(){yield s.open.call(this),yield this.handleSubscriptions((null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.onStateChange)?this.subscribe(u,this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStderr)?this.subscribe(u,this.codeSnippetOpts.onStderr,"stderr"):void 0,(null===(i=this.codeSnippetOpts)||void 0===i?void 0:i.onStdout)?this.subscribe(u,this.codeSnippetOpts.onStdout,"stdout"):void 0,(null===(o=this.codeSnippetOpts)||void 0===o?void 0:o.onScanPorts)?this.subscribe(u,this.codeSnippetOpts.onScanPorts,"scanOpenedPorts"):void 0),this.codeSnippet={run:(s,t={})=>l(this,void 0,void 0,(function*(){var e,i;const o=yield this.call(u,"run",[s,t]);return null===(i=null===(e=this.codeSnippetOpts)||void 0===e?void 0:e.onStateChange)||void 0===i||i.call(e,o),o})),stop:()=>l(this,void 0,void 0,(function*(){var s,t;const e=yield this.call(u,"stop");return null===(t=null===(s=this.codeSnippetOpts)||void 0===s?void 0:s.onStateChange)||void 0===t||t.call(s,e),e}))},this.filesystem={list:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"list",[s])})),read:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"read",[s])})),remove:s=>l(this,void 0,void 0,(function*(){yield this.call(v,"remove",[s])})),write:(s,t)=>l(this,void 0,void 0,(function*(){yield this.call(v,"write",[s,t])})),makeDir:s=>l(this,void 0,void 0,(function*(){yield this.call(v,"makeDir",[s])})),watchDir:s=>{const t=r.default(s);return new g(this,t)}},this.terminal={createSession:({onData:s,size:t,onExit:e,envVars:i,cmd:o,rootdir:n,terminalID:r=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:c,resolve:d}=a(),[u,p]=yield this.handleSubscriptions(this.subscribe(D,s,"onData",r),this.subscribe(D,d,"onExit",r)),{promise:v,resolve:f}=a();c.then((()=>l(this,void 0,void 0,(function*(){const s=h(yield Promise.allSettled([this.unsubscribe(p),this.unsubscribe(u)]));s&&this.logger.error(s),null==e||e(),f()}))));try{yield this.call(D,"start",[r,t.cols,t.rows,...void 0!==o?[i,o,n]:[]])}catch(s){throw d(),yield v,s}return{destroy:()=>l(this,void 0,void 0,(function*(){try{yield this.call(D,"destroy",[r])}finally{d(),yield v}})),resize:({cols:s,rows:t})=>l(this,void 0,void 0,(function*(){yield this.call(D,"resize",[r,s,t])})),sendData:s=>l(this,void 0,void 0,(function*(){yield this.call(D,"data",[r,s])})),terminalID:r}}))},this.process={start:({cmd:s,onStdout:t,onStderr:e,onExit:i,envVars:o={},rootdir:n="/",processID:r=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:c,resolve:d}=a(),[u,p,v]=yield this.handleSubscriptions(this.subscribe(b,d,"onExit",r),t?this.subscribe(b,t,"onStdout",r):void 0,e?this.subscribe(b,e,"onStderr",r):void 0),{promise:f,resolve:g}=a();c.then((()=>l(this,void 0,void 0,(function*(){const s=h(yield Promise.allSettled([this.unsubscribe(u),p?this.unsubscribe(p):void 0,v?this.unsubscribe(v):void 0]));s&&this.logger.error(s),null==i||i(),g()}))));try{yield this.call(b,"start",[r,s,o,n])}catch(s){throw d(),yield f,s}return{kill:()=>l(this,void 0,void 0,(function*(){try{yield this.call(b,"kill",[r])}finally{d(),yield f}})),processID:r,sendStdin:s=>l(this,void 0,void 0,(function*(){yield this.call(b,"stdin",[r,s])}))}}))}}))}},s.api=y,s.createSessionProcess=function({cmd:s,manager:t,onStderr:e,onStdout:i,processID:o,rootdir:n}){return l(this,void 0,void 0,(function*(){if(!t)throw new Error("Cannot create process - process manager is not defined");const{resolve:r,promise:l}=a(),c=yield t.start({cmd:s,onStdout:i,onStderr:e,onExit:()=>{r()},rootdir:n,processID:o});return{exited:l,processID:c.processID,kill:c.kill,sendStdin:c.sendStdin}}))},Object.defineProperty(s,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.js.map |
@@ -12,12 +12,6 @@ import { EnvVars } from './envVars'; | ||
} | ||
export interface ChildProcess { | ||
cmd: string; | ||
pid: number; | ||
} | ||
export interface TerminalManager { | ||
readonly killProcess: (pid: number) => Promise<void>; | ||
readonly createSession: (opts: { | ||
onData: (data: string) => void; | ||
onExit?: () => void; | ||
onChildProcessesChange?: (cps: ChildProcess[]) => void; | ||
size: { | ||
@@ -24,0 +18,0 @@ cols: number; |
{ | ||
"name": "@devbookhq/sdk", | ||
"version": "2.6.57", | ||
"version": "2.6.58", | ||
"description": "SDK for managing Devbook sessions from JavaScript/TypeScript", | ||
@@ -5,0 +5,0 @@ "homepage": "https://usedevbook.com", |
@@ -15,3 +15,3 @@ export { default as Session } from './session' | ||
export { OutType } from './session/out' | ||
export type { TerminalManager, TerminalSession, ChildProcess } from './session/terminal' | ||
export type { TerminalManager, TerminalSession } from './session/terminal' | ||
export type { FilesystemManager, FileInfo } from './session/filesystem' | ||
@@ -18,0 +18,0 @@ export { |
@@ -141,3 +141,2 @@ import normalizePath from 'normalize-path' | ||
onData, | ||
onChildProcessesChange, | ||
size, | ||
@@ -152,15 +151,6 @@ onExit, | ||
const [onDataSubID, onExitSubID, onChildProcessesChangeSubID] = | ||
await this.handleSubscriptions( | ||
this.subscribe(terminalService, onData, 'onData', terminalID), | ||
this.subscribe(terminalService, triggerExit, 'onExit', terminalID), | ||
onChildProcessesChange | ||
? this.subscribe( | ||
terminalService, | ||
onChildProcessesChange, | ||
'onChildProcessesChange', | ||
terminalID, | ||
) | ||
: undefined, | ||
) | ||
const [onDataSubID, onExitSubID] = await this.handleSubscriptions( | ||
this.subscribe(terminalService, onData, 'onData', terminalID), | ||
this.subscribe(terminalService, triggerExit, 'onExit', terminalID), | ||
) | ||
@@ -174,5 +164,2 @@ const { promise: unsubscribing, resolve: handleFinishUnsubscribing } = | ||
this.unsubscribe(onDataSubID), | ||
onChildProcessesChangeSubID | ||
? this.unsubscribe(onChildProcessesChangeSubID) | ||
: undefined, | ||
]) | ||
@@ -221,5 +208,2 @@ | ||
}, | ||
killProcess: async pid => { | ||
await this.call(terminalService, 'killProcess', [pid]) | ||
}, | ||
} | ||
@@ -226,0 +210,0 @@ |
@@ -122,3 +122,6 @@ import { IRpcNotification, RpcWebSocketClient } from 'rpc-websocket-client' | ||
this.rpc.ws?.close() | ||
// This is `ws` way of closing connection | ||
this.rpc.ws?.terminate?.() | ||
// This is the browser WebSocket way of closing connection | ||
this.rpc.ws?.close?.() | ||
this.opts?.onClose?.() | ||
@@ -125,0 +128,0 @@ this.logger.log('Disconected from the session') |
@@ -12,13 +12,6 @@ import { EnvVars } from './envVars' | ||
export interface ChildProcess { | ||
cmd: string | ||
pid: number | ||
} | ||
export interface TerminalManager { | ||
readonly killProcess: (pid: number) => Promise<void> | ||
readonly createSession: (opts: { | ||
onData: (data: string) => void | ||
onExit?: () => void | ||
onChildProcessesChange?: (cps: ChildProcess[]) => void | ||
size: { cols: number; rows: number } | ||
@@ -25,0 +18,0 @@ terminalID?: string |
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
283399
3291