New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@devbookhq/sdk

Package Overview
Dependencies
Maintainers
2
Versions
152
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@devbookhq/sdk - npm Package Compare versions

Comparing version 2.5.9 to 2.5.10

2

dist/cjs/index.js

@@ -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 h(){let s,e;return{promise:new Promise(((t,i)=>{s=t,e=i})),reject:e,resolve:s}}var d;exports.CodeSnippetExecState=void 0,(d=exports.CodeSnippetExecState||(exports.CodeSnippetExecState={})).Running="Running",d.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,"watch",this.path))}))}stop(){return n(this,void 0,void 0,(function*(){this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID)),this.listeners.clear()}))}addEventListener(s){return this.listeners.add(s),{remove:()=>{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(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...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});var y;exports.OutType=void 0,(y=exports.OutType||(exports.OutType={})).Stdout="Stdout",y.Stderr="Stderr",exports.FilesystemWatcher=u,exports.Session=class extends class{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(100),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 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()}}))}}{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={listAllFiles:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","listAllFiles",[s])})),readFile:s=>n(this,void 0,void 0,(function*(){return yield this.call("filesystem","readFile",[s])})),removeFile:s=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","removeFile",[s])})),writeFile:(s,e)=>n(this,void 0,void 0,(function*(){yield this.call("filesystem","writeFile",[s,e])})),watch:s=>{const e=o.default(s);return new u(this,e)}},this.terminal={createSession:({onData:s,onChildProcessesChange:e,size:t,onExit:i,terminalID:o=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:l}=h(),[d,a,u]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",o),this.subscribe("terminal",l,"onExit",o),e?this.subscribe("terminal",e,"onChildProcessesChange",o):void 0),{promise:p,resolve:v}=h();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(a),this.unsubscribe(d),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==i||i(),v()}))));try{yield this.call("terminal","start",[o,t.cols,t.rows])}catch(s){throw l(),yield p,s}return{destroy:()=>n(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[o])}finally{l(),yield p}})),resize:({cols:s,rows:e})=>n(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[o,s,e])})),sendData:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","data",[o,s])})),terminalID:o}})),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:d=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:a}=h(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",d),e?this.subscribe("process",e,"onStdout",d):void 0,t?this.subscribe("process",t,"onStderr",d):void 0),{promise:g,resolve:f}=h();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",[d,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",[d])}finally{a(),yield g}})),processID:d,sendStdin:s=>n(this,void 0,void 0,(function*(){yield this.call("process","stdin",[d,s])}))}}))}}))}},exports.api=p;
"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 h(){let s,t;return{promise:new Promise(((e,i)=>{s=e,t=i})),reject:t,resolve:s}}var d;exports.CodeSnippetExecState=void 0,(d=exports.CodeSnippetExecState||(exports.CodeSnippetExecState={})).Running="Running",d.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(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...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});var y;exports.OutType=void 0,(y=exports.OutType||(exports.OutType={})).Stdout="Stdout",y.Stderr="Stderr",exports.FilesystemWatcher=u,exports.Session=class extends class{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;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===(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 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(100),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()}}))}}{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,onChildProcessesChange:t,size:e,onExit:i,terminalID:o=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:l}=h(),[d,a,u]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",o),this.subscribe("terminal",l,"onExit",o),t?this.subscribe("terminal",t,"onChildProcessesChange",o):void 0),{promise:p,resolve:v}=h();r.then((()=>n(this,void 0,void 0,(function*(){const s=c(yield Promise.allSettled([this.unsubscribe(a),this.unsubscribe(d),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==i||i(),v()}))));try{yield this.call("terminal","start",[o,e.cols,e.rows])}catch(s){throw l(),yield p,s}return{destroy:()=>n(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[o])}finally{l(),yield p}})),resize:({cols:s,rows:t})=>n(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[o,s,t])})),sendData:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","data",[o,s])})),terminalID:o}})),killProcess:s=>n(this,void 0,void 0,(function*(){yield this.call("terminal","killProcess",[s])}))},this.process={start:({cmd:s,onStdout:t,onStderr:e,onExit:i,envVars:o={},rootdir:l="/",processID:d=r(12)})=>n(this,void 0,void 0,(function*(){const{promise:r,resolve:a}=h(),[u,p,v]=yield this.handleSubscriptions(this.subscribe("process",a,"onExit",d),t?this.subscribe("process",t,"onStdout",d):void 0,e?this.subscribe("process",e,"onStderr",d):void 0),{promise:g,resolve:f}=h();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",[d,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",[d])}finally{a(),yield g}})),processID:d,sendStdin:s=>n(this,void 0,void 0,(function*(){yield this.call("process","stdin",[d,s])}))}}))}}))}},exports.api=p;
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

import FilesystemWatcher from "./filesystemWatcher";
import FilesystemWatcher from './filesystemWatcher';
export declare const filesystemService = "filesystem";

@@ -8,7 +8,8 @@ export interface FileInfo {

export interface FilesystemManager {
readonly writeFile: (path: string, content: string) => Promise<void>;
readonly readFile: (path: string) => Promise<string>;
readonly removeFile: (path: string) => Promise<void>;
readonly listAllFiles: (path: string) => Promise<FileInfo[]>;
readonly watch: (path: string) => FilesystemWatcher;
readonly write: (path: string, content: string) => Promise<void>;
readonly read: (path: string) => Promise<string>;
readonly remove: (path: string) => Promise<void>;
readonly list: (path: string) => Promise<FileInfo[]>;
readonly makeDir: (path: string) => Promise<void>;
readonly watchDir: (path: string) => FilesystemWatcher;
}

@@ -11,5 +11,6 @@ import SessionConnection from './sessionConnection';

path: string;
name: string;
operation: FilesystemOperation;
timestamp: number;
isDirectory: boolean;
isDir: boolean;
}

@@ -25,7 +26,5 @@ export declare type FilesystemEventListener = (event: FilesystemEvent) => void;

stop(): Promise<void>;
addEventListener(l: FilesystemEventListener): {
remove: () => void;
};
addEventListener(l: FilesystemEventListener): () => boolean;
private handleFilesystemEvents;
}
export default 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 h;!function(s){s.Create="Create",s.Write="Write",s.Remove="Remove",s.Rename="Rename",s.Chmod="Chmod"}(h||(h={}));class d{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,"watch",this.path))}))}stop(){return e(this,void 0,void 0,(function*(){this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID)),this.listeners.clear()}))}addEventListener(s){return this.listeners.add(s),{remove:()=>{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(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...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 extends class{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(100),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 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()}}))}}{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const i=Object.create(null,{open:{get:()=>super.open}});var t,n,c,h;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===(h=this.codeSnippetOpts)||void 0===h?void 0:h.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={listAllFiles:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","listAllFiles",[s])})),readFile:s=>e(this,void 0,void 0,(function*(){return yield this.call("filesystem","readFile",[s])})),removeFile:s=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","removeFile",[s])})),writeFile:(s,i)=>e(this,void 0,void 0,(function*(){yield this.call("filesystem","writeFile",[s,i])})),watch:i=>{const t=s(i);return new d(this,t)}},this.terminal={createSession:({onData:s,onChildProcessesChange:i,size:t,onExit:n,terminalID:c=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:h}=l(),[d,a,u]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",c),this.subscribe("terminal",h,"onExit",c),i?this.subscribe("terminal",i,"onChildProcessesChange",c):void 0),{promise:p,resolve:v}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(a),this.unsubscribe(d),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==n||n(),v()}))));try{yield this.call("terminal","start",[c,t.cols,t.rows])}catch(s){throw h(),yield p,s}return{destroy:()=>e(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[c])}finally{h(),yield p}})),resize:({cols:s,rows:i})=>e(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[c,s,i])})),sendData:s=>e(this,void 0,void 0,(function*(){yield this.call("terminal","data",[c,s])})),terminalID:c}})),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:h="/",processID:d=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",d),i?this.subscribe("process",i,"onStdout",d):void 0,t?this.subscribe("process",t,"onStderr",d):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",[d,s,c,h])}catch(s){throw a(),yield g,s}return{kill:()=>e(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[d])}finally{a(),yield g}})),processID:d,sendStdin:s=>e(this,void 0,void 0,(function*(){yield this.call("process","stdin",[d,s])}))}}))}}))}}var b;!function(s){s.Stdout="Stdout",s.Stderr="Stderr"}(b||(b={}));export{c as CodeSnippetExecState,h as FilesystemOperation,d as FilesystemWatcher,b as OutType,f as Session,a as api};
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 h;!function(s){s.Create="Create",s.Write="Write",s.Remove="Remove",s.Rename="Rename",s.Chmod="Chmod"}(h||(h={}));class d{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(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...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 extends class{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(100),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()}}))}}{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const i=Object.create(null,{open:{get:()=>super.open}});var t,n,c,h;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===(h=this.codeSnippetOpts)||void 0===h?void 0:h.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 d(this,t)}},this.terminal={createSession:({onData:s,onChildProcessesChange:i,size:t,onExit:n,terminalID:c=o(12)})=>e(this,void 0,void 0,(function*(){const{promise:o,resolve:h}=l(),[d,a,u]=yield this.handleSubscriptions(this.subscribe("terminal",s,"onData",c),this.subscribe("terminal",h,"onExit",c),i?this.subscribe("terminal",i,"onChildProcessesChange",c):void 0),{promise:p,resolve:v}=l();o.then((()=>e(this,void 0,void 0,(function*(){const s=r(yield Promise.allSettled([this.unsubscribe(a),this.unsubscribe(d),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==n||n(),v()}))));try{yield this.call("terminal","start",[c,t.cols,t.rows])}catch(s){throw h(),yield p,s}return{destroy:()=>e(this,void 0,void 0,(function*(){try{yield this.call("terminal","destroy",[c])}finally{h(),yield p}})),resize:({cols:s,rows:i})=>e(this,void 0,void 0,(function*(){yield this.call("terminal","resize",[c,s,i])})),sendData:s=>e(this,void 0,void 0,(function*(){yield this.call("terminal","data",[c,s])})),terminalID:c}})),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:h="/",processID:d=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",d),i?this.subscribe("process",i,"onStdout",d):void 0,t?this.subscribe("process",t,"onStderr",d):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",[d,s,c,h])}catch(s){throw a(),yield g,s}return{kill:()=>e(this,void 0,void 0,(function*(){try{yield this.call("process","kill",[d])}finally{a(),yield g}})),processID:d,sendStdin:s=>e(this,void 0,void 0,(function*(){yield this.call("process","stdin",[d,s])}))}}))}}))}}var b;!function(s){s.Stdout="Stdout",s.Stderr="Stderr"}(b||(b={}));export{c as CodeSnippetExecState,h as FilesystemOperation,d as FilesystemWatcher,b as OutType,f as Session,a as api};
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

import FilesystemWatcher from "./filesystemWatcher";
import FilesystemWatcher from './filesystemWatcher';
export declare const filesystemService = "filesystem";

@@ -8,7 +8,8 @@ export interface FileInfo {

export interface FilesystemManager {
readonly writeFile: (path: string, content: string) => Promise<void>;
readonly readFile: (path: string) => Promise<string>;
readonly removeFile: (path: string) => Promise<void>;
readonly listAllFiles: (path: string) => Promise<FileInfo[]>;
readonly watch: (path: string) => FilesystemWatcher;
readonly write: (path: string, content: string) => Promise<void>;
readonly read: (path: string) => Promise<string>;
readonly remove: (path: string) => Promise<void>;
readonly list: (path: string) => Promise<FileInfo[]>;
readonly makeDir: (path: string) => Promise<void>;
readonly watchDir: (path: string) => FilesystemWatcher;
}

@@ -11,5 +11,6 @@ import SessionConnection from './sessionConnection';

path: string;
name: string;
operation: FilesystemOperation;
timestamp: number;
isDirectory: boolean;
isDir: boolean;
}

@@ -25,7 +26,5 @@ export declare type FilesystemEventListener = (event: FilesystemEvent) => void;

stop(): Promise<void>;
addEventListener(l: FilesystemEventListener): {
remove: () => void;
};
addEventListener(l: FilesystemEventListener): () => boolean;
private handleFilesystemEvents;
}
export default FilesystemWatcher;

@@ -1,2 +0,2 @@

!function(s,e){"object"==typeof exports&&"undefined"!=typeof module?e(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"],e):e((s="undefined"!=typeof globalThis?globalThis:s||self)["@devbookhq/sdk"]={},s.normalizePath,s.rpcWebsocketClient,null,s.openapiTypescriptFetch)}(this,(function(s,e,t,i,o){"use strict";function n(s){return s&&"object"==typeof s&&"default"in s?s:{default:s}}var r=n(e);function l(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 c(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 h(s){return"fulfilled"===s.status}function d(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 a(){let s,e;return{promise:new Promise(((t,i)=>{s=t,e=i})),reject:e,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,e){this.sessConn=s,this.path=e,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,"watch",this.path))}))}stop(){return l(this,void 0,void 0,(function*(){this.rpcSubscriptionID&&(yield this.sessConn.unsubscribe(this.rpcSubscriptionID)),this.listeners.clear()}))}addEventListener(s){return this.listeners.add(s),{remove:()=>{this.listeners.delete(s)}}}handleFilesystemEvents(s){this.listeners.forEach((e=>{e(s)}))}}const b="process",y=o.Fetcher.for();y.configure({baseUrl:"https://ondevbook.com"});class m{constructor(s,e=!1){this.logID=s,this.isEnabled=e}error(...s){console.error(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...s)}id(){return"function"==typeof this.logID?this.logID():this.logID}}function S(s){return new Promise((e=>setTimeout(e,s)))}const w=y.path("/sessions").method("post").create({api_key:!0}),E=y.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});const $="terminal";var _;s.OutType=void 0,(_=s.OutType||(s.OutType={})).Stdout="Stdout",_.Stderr="Stderr",s.FilesystemWatcher=g,s.Session=class extends class{constructor(s){this.opts=s,this.isOpen=!1,this.rpc=new t.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 e=`${this.session.sessionID}-${this.session.clientID}.ondevbook.com`;return s?`${s}-${e}`:e}close(){var s,e,t;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===(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 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 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 n=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=>l(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 S(100),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 n}))}call(s,e,t){return l(this,void 0,void 0,(function*(){return this.rpc.call(`${s}_${e}`,t)}))}handleSubscriptions(...s){return l(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(h).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(d(e))}))}unsubscribe(s){return l(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 from "${e.service}"`))}))}subscribe(s,e,t,...i){return l(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 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(e){if(e instanceof E.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()}}))}}{constructor(s){super(s),this.codeSnippetOpts=s.codeSnippet}open(){const s=Object.create(null,{open:{get:()=>super.open}});var e,t,i,o;return l(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(u,this.codeSnippetOpts.onStateChange,"state"):void 0,(null===(t=this.codeSnippetOpts)||void 0===t?void 0:t.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,e={})=>l(this,void 0,void 0,(function*(){var t,i;const o=yield this.call(u,"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:()=>l(this,void 0,void 0,(function*(){var s,e;const t=yield this.call(u,"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={listAllFiles:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"listAllFiles",[s])})),readFile:s=>l(this,void 0,void 0,(function*(){return yield this.call(v,"readFile",[s])})),removeFile:s=>l(this,void 0,void 0,(function*(){yield this.call(v,"removeFile",[s])})),writeFile:(s,e)=>l(this,void 0,void 0,(function*(){yield this.call(v,"writeFile",[s,e])})),watch:s=>{const e=r.default(s);return new g(this,e)}},this.terminal={createSession:({onData:s,onChildProcessesChange:e,size:t,onExit:i,terminalID:o=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:n,resolve:r}=a(),[c,h,u]=yield this.handleSubscriptions(this.subscribe($,s,"onData",o),this.subscribe($,r,"onExit",o),e?this.subscribe($,e,"onChildProcessesChange",o):void 0),{promise:p,resolve:v}=a();n.then((()=>l(this,void 0,void 0,(function*(){const s=d(yield Promise.allSettled([this.unsubscribe(h),this.unsubscribe(c),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==i||i(),v()}))));try{yield this.call($,"start",[o,t.cols,t.rows])}catch(s){throw r(),yield p,s}return{destroy:()=>l(this,void 0,void 0,(function*(){try{yield this.call($,"destroy",[o])}finally{r(),yield p}})),resize:({cols:s,rows:e})=>l(this,void 0,void 0,(function*(){yield this.call($,"resize",[o,s,e])})),sendData:s=>l(this,void 0,void 0,(function*(){yield this.call($,"data",[o,s])})),terminalID:o}})),killProcess:s=>l(this,void 0,void 0,(function*(){yield this.call($,"killProcess",[s])}))},this.process={start:({cmd:s,onStdout:e,onStderr:t,onExit:i,envVars:o={},rootdir:n="/",processID:r=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:c,resolve:h}=a(),[u,p,v]=yield this.handleSubscriptions(this.subscribe(b,h,"onExit",r),e?this.subscribe(b,e,"onStdout",r):void 0,t?this.subscribe(b,t,"onStderr",r):void 0),{promise:f,resolve:g}=a();c.then((()=>l(this,void 0,void 0,(function*(){const s=d(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 h(),yield f,s}return{kill:()=>l(this,void 0,void 0,(function*(){try{yield this.call(b,"kill",[r])}finally{h(),yield f}})),processID:r,sendStdin:s=>l(this,void 0,void 0,(function*(){yield this.call(b,"stdin",[r,s])}))}}))}}))}},s.api=y,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 h(s){return"fulfilled"===s.status}function d(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(`[${this.id()} ERROR]`,...s)}log(...s){this.isEnabled&&console.log(`[${this.id()}]`,...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}),$=y.path("/sessions/{sessionID}/refresh").method("post").create({api_key:!0});const E="terminal";var D;s.OutType=void 0,(D=s.OutType||(s.OutType={})).Stdout="Stdout",D.Stderr="Stderr",s.FilesystemWatcher=g,s.Session=class extends 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(100),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(h).map((s=>s.value?this.unsubscribe(s.value):void 0))),new Error(d(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 $({api_key:this.opts.apiKey,sessionID:s})}catch(t){if(t instanceof $.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()}}))}}{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,terminalID:o=c(12)})=>l(this,void 0,void 0,(function*(){const{promise:n,resolve:r}=a(),[c,h,u]=yield this.handleSubscriptions(this.subscribe(E,s,"onData",o),this.subscribe(E,r,"onExit",o),t?this.subscribe(E,t,"onChildProcessesChange",o):void 0),{promise:p,resolve:v}=a();n.then((()=>l(this,void 0,void 0,(function*(){const s=d(yield Promise.allSettled([this.unsubscribe(h),this.unsubscribe(c),u?this.unsubscribe(u):void 0]));s&&this.logger.error(s),null==i||i(),v()}))));try{yield this.call(E,"start",[o,e.cols,e.rows])}catch(s){throw r(),yield p,s}return{destroy:()=>l(this,void 0,void 0,(function*(){try{yield this.call(E,"destroy",[o])}finally{r(),yield p}})),resize:({cols:s,rows:t})=>l(this,void 0,void 0,(function*(){yield this.call(E,"resize",[o,s,t])})),sendData:s=>l(this,void 0,void 0,(function*(){yield this.call(E,"data",[o,s])})),terminalID:o}})),killProcess:s=>l(this,void 0,void 0,(function*(){yield this.call(E,"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:h}=a(),[u,p,v]=yield this.handleSubscriptions(this.subscribe(b,h,"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=d(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 h(),yield f,s}return{kill:()=>l(this,void 0,void 0,(function*(){try{yield this.call(b,"kill",[r])}finally{h(),yield f}})),processID:r,sendStdin:s=>l(this,void 0,void 0,(function*(){yield this.call(b,"stdin",[r,s])}))}}))}}))}},s.api=y,Object.defineProperty(s,"__esModule",{value:!0})}));
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

import FilesystemWatcher from "./filesystemWatcher";
import FilesystemWatcher from './filesystemWatcher';
export declare const filesystemService = "filesystem";

@@ -8,7 +8,8 @@ export interface FileInfo {

export interface FilesystemManager {
readonly writeFile: (path: string, content: string) => Promise<void>;
readonly readFile: (path: string) => Promise<string>;
readonly removeFile: (path: string) => Promise<void>;
readonly listAllFiles: (path: string) => Promise<FileInfo[]>;
readonly watch: (path: string) => FilesystemWatcher;
readonly write: (path: string, content: string) => Promise<void>;
readonly read: (path: string) => Promise<string>;
readonly remove: (path: string) => Promise<void>;
readonly list: (path: string) => Promise<FileInfo[]>;
readonly makeDir: (path: string) => Promise<void>;
readonly watchDir: (path: string) => FilesystemWatcher;
}

@@ -11,5 +11,6 @@ import SessionConnection from './sessionConnection';

path: string;
name: string;
operation: FilesystemOperation;
timestamp: number;
isDirectory: boolean;
isDir: boolean;
}

@@ -25,7 +26,5 @@ export declare type FilesystemEventListener = (event: FilesystemEvent) => void;

stop(): Promise<void>;
addEventListener(l: FilesystemEventListener): {
remove: () => void;
};
addEventListener(l: FilesystemEventListener): () => boolean;
private handleFilesystemEvents;
}
export default FilesystemWatcher;
{
"name": "@devbookhq/sdk",
"version": "2.5.9",
"version": "2.5.10",
"description": "SDK for managing Devbook sessions from JavaScript/TypeScript",

@@ -5,0 +5,0 @@ "homepage": "https://usedevbook.com",

# Devbook SDK
SDK for managing Devbook sessions from JavaScript/TypeScript.
SDK for managing Devbook sessions from JavaScript/TypeScript. Devbook SDK requires [`devbookd`](https://github.com/devbookhq/devbookd) running on the server to which it's connecting.

@@ -19,3 +19,3 @@ ## Installation

### Open a New Session
### Open a new session

@@ -57,3 +57,3 @@ You **start a new session** by creating a `Session` instance and calling the `session.open` method.

### Run Code Snippet
### Run code snippet

@@ -72,24 +72,60 @@ You can **run arbitrary code** with the runtime predefined in the Devbook env by calling `session.codeSnippet.run`.

### Interact with the Filesystem
### Interact with the filesystem
You can **list all the files and directories** in a specific directory by calling the `session.filesystem.listAllFiles` method.
Following filesystem operations are supported.
You can **create a file and/or modify its content** by calling the `session.filesystem.writeFile` method.
- **`list`**
You can **read the file's content** by calling the `session.filesystem.readFile` method. The method throws an error if the file is not found.
Lists content of a directory.
```ts
const dirBContent = await session.filesystem.list('/dirA/dirB')
```
You can **remove file** by calling the `session.filesystem.removeFile` method.
- **`write`**
Writes content to a new file.
```ts
const files = await session.filesystem.listAllFiles('/')
// This will create a new file 'file.txt' inside the dir 'dirB' with the content 'Hello world'.
await session.filesystem.write('/dirA/dirB/file.txt', 'Hello World')
```
await session.filesystem.writeFile('/new.sh', 'echo 2')
- **`read`**
const content = await session.filesystem.readFile('/new.sh')
Reads content of a file.
```ts
const fileContent = await session.filesystem.read('/dirA/dirB/file.txt')
```
await session.filesystem.removeFile('/new.sh')
- **`remove`**
Removes a file or a directory.
```ts
// Remove a file.
await session.filesystem.remove('/dirA/dirB/file.txt')
// Remove a directory and all of its content.
await session.filesystem.remove('/dirA')
```
### Start a Terminal
- **`makeDir`**
Creates a new directory and all directories along the way if needed.
```ts
// Creates a new directory 'dirC' and also 'dirA' and 'dirB' if those directories don't already exist.
await session.filesystem.makeDir('/dirA/dirB/dirC')
```
- **`watchDir`**
Watches a directory for filesystem events.
```ts
const watcher = session.filesystem.watchDir('/dirA/dirB')
watcher.addEventListener(fsevent => {
console.log('Change inside the dirB', fsevent)
})
await watcher.start()
```
### Start a terminal session
You can **start a new terminal** in the session by calling `session.terminal.createSession`.

@@ -125,3 +161,3 @@

### Start a Process
### Start a process

@@ -128,0 +164,0 @@ You can **start a new process** in the session by calling `session.process.start`. The only required option is the `cmd`, but you can also define the `rootdir` and `envVars` options that the command should be executed with.

@@ -1,2 +0,2 @@

import FilesystemWatcher from "./filesystemWatcher"
import FilesystemWatcher from './filesystemWatcher'

@@ -11,7 +11,8 @@ export const filesystemService = 'filesystem'

export interface FilesystemManager {
readonly writeFile: (path: string, content: string) => Promise<void>
readonly readFile: (path: string) => Promise<string>
readonly removeFile: (path: string) => Promise<void>
readonly listAllFiles: (path: string) => Promise<FileInfo[]>
readonly watch: (path: string) => FilesystemWatcher
readonly write: (path: string, content: string) => Promise<void>
readonly read: (path: string) => Promise<string>
readonly remove: (path: string) => Promise<void>
readonly list: (path: string) => Promise<FileInfo[]>
readonly makeDir: (path: string) => Promise<void>
readonly watchDir: (path: string) => FilesystemWatcher
}

@@ -14,6 +14,7 @@ import { filesystemService } from './filesystem'

path: string
name: string
operation: FilesystemOperation
// Unix epoch in nanoseconds
timestamp: number
isDirectory: boolean
isDir: boolean
}

@@ -44,3 +45,3 @@

this.handleFilesystemEvents,
'watch',
'watchDir',
this.path,

@@ -52,6 +53,6 @@ )

async stop() {
this.listeners.clear()
if (this.rpcSubscriptionID) {
await this.sessConn.unsubscribe(this.rpcSubscriptionID)
}
this.listeners.clear()
}

@@ -61,7 +62,3 @@

this.listeners.add(l)
return {
remove: () => {
this.listeners.delete(l)
},
}
return () => this.listeners.delete(l)
}

@@ -68,0 +65,0 @@

@@ -88,15 +88,46 @@ import normalizePath from 'normalize-path'

this.filesystem = {
listAllFiles: async path => {
return (await this.call(filesystemService, 'listAllFiles', [path])) as FileInfo[]
/**
* List files in a directory.
* @param path path to a directory
* @returns Array of files in a directory
*/
list: async path => {
return (await this.call(filesystemService, 'list', [path])) as FileInfo[]
},
readFile: async path => {
return (await this.call(filesystemService, 'readFile', [path])) as string
/**
* Reads the whole content of a file.
* @param path path to a file
* @returns Content of a file
*/
read: async path => {
return (await this.call(filesystemService, 'read', [path])) as string
},
removeFile: async path => {
await this.call(filesystemService, 'removeFile', [path])
/**
* Removes a file or a directory.
* @param path path to a file or a directory
*/
remove: async path => {
await this.call(filesystemService, 'remove', [path])
},
writeFile: async (path, content) => {
await this.call(filesystemService, 'writeFile', [path, content])
/**
* Writes content to a new file on path.
* @param path path to a new file. For example '/dirA/dirB/newFile.txt' when creating 'newFile.txt'
* @param content content to write to a new file
*/
write: async (path, content) => {
await this.call(filesystemService, 'write', [path, content])
},
watch: (path: string) => {
/**
* Creates a new directory and all directories along the way if needed on the specified pth.
* @param path path to a new directory. For example '/dirA/dirB' when creating 'dirB'.
*/
makeDir: async path => {
await this.call(filesystemService, 'makeDir', [path])
},
/**
* Watches directory for filesystem events.
* @param path path to a directory that will be watched
* @returns new watcher
*/
watchDir: (path: string) => {
const npath = normalizePath(path)

@@ -103,0 +134,0 @@ return new FilesystemWatcher(this, npath)

@@ -281,3 +281,3 @@ import { IRpcNotification, RpcWebSocketClient } from 'rpc-websocket-client'

this.subscribers = this.subscribers.filter(s => s !== subscription)
this.logger.log(`Unsubscribed from "${subscription.service}"`)
this.logger.log(`Unsubscribed '${subID}' from '${subscription.service}'`)
}

@@ -284,0 +284,0 @@

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc