Best JavaScript code snippet using mountebank
perspectivesApiProxy.js
Source:perspectivesApiProxy.js
1// BEGIN LICENSE2// Perspectives Distributed Runtime3// Copyright (C) 2019 Joop Ringelberg (joopringelberg@perspect.it), Cor Baars4//5// This program is free software: you can redistribute it and/or modify6// it under the terms of the GNU General Public License as published by7// the Free Software Foundation, either version 3 of the License, or8// (at your option) any later version.9//10// This program is distributed in the hope that it will be useful,11// but WITHOUT ANY WARRANTY; without even the implied warranty of12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13// GNU General Public License for more details.14//15// You should have received a copy of the GNU General Public License16// along with this program. If not, see <https://www.gnu.org/licenses/>.17//18// Full text of this license can be found in the LICENSE file in the projects root.19// END LICENSE20/*21This module is imported both by the core and by clients and bridges the gap between the two. It supports several architectures:22 1 with core and client in the same javascript process;23 2 with core and client in different javascript processes, connected by the Channel Messaging API24 https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API25 3 with core and client in different processes, connected by TCP. OBSOLETE!! We have commented the code out. It will serve as an example when we develop the Language Server. See the design text "TCP architecture.txt".26The core resolves two promises:27 - one called PDRproxy, resolving to an instance of PerspectivesProxy with an InternalChannel, to be used in the first architecture by direct import;28 - one called InternalChannel, resolving to an instance of InternalChannel, to be used in the second architecture, used by the Service Worker by direct import;29Then there are two functions to be used by clients, that both resolve the PDRproxy promise.30 - createServiceWorkerConnectionToPerspectives, for the second architecture. It resolves the PDRproxy promise with an instance of SharedWorkerChannel, that *uses* the InternalChannel to communicate with the core;31 - createTcpConnectionToPerspectives, for the third architecture. It resolves the PDRproxy promise with an instance of TcpChannel.32The PDRproxy promise is imported by all of the modules in perspectives-react that must connect to the core.33*/34////////////////////////////////////////////////////////////////////////////////35//// CLIENT SIDE PROMISES36////////////////////////////////////////////////////////////////////////////////37let pdrProxyResolver/*, pdrProxyRejecter*/;38let internalChannelResolver, internalChannelRejecter;39let sharedWorkerChannelResolver/*, sharedWorkerChannelRejecter*/;40// This promise will resolve to an instance of PerspectivesProxy, with an InternalChannel.41// The proxy uses the channel to actually send requests to the core. These requests will42// turn up as 'output' of a Producer, ready to be consumed by some process.43// The channel uses the emit function as a callback: when it has a request to send, it calls 'emit'44// after wrapping the request in the appropriate constructor (usually the emitStep).45const PDRproxy = new Promise(46 function (resolve/*, reject*/)47 {48 pdrProxyResolver = resolve;49 //pdrProxyRejecter = reject;50 });51// This promise will resolve to an instance of the InternalChannel.52// It is used by a ServiceWorker that runs in the same javascript process as the core.53const InternalChannelPromise = new Promise(54 function (resolve, reject)55 {56 internalChannelResolver = resolve;57 internalChannelRejecter = reject;58 });59// This promise will resolve to an instance of the the SharedWorkerChannel.60// It is used by InPlace, running in the same javascript process as this proxy.61const SharedWorkerChannelPromise = new Promise(62 function (resolve/*, reject*/)63 {64 sharedWorkerChannelResolver = resolve;65 // sharedWorkerChannelRejecter = reject;66 });67////////////////////////////////////////////////////////////////////////////////68//// RESOLVE AND CONFIGURE PDRPROXY WITH A CHANNEL69////////////////////////////////////////////////////////////////////////////////70// Creates an instance of PerspectivesProxy with a selected type of channel and71// fullfills the PDRproxy with it.72// Options as described in the module Control.Aff.Sockets:73// type TCPOptions opts = {port :: Port, host :: Host, allowHalfOpen :: Boolean | opts}74// type Port = Int75// type Host = String76function configurePDRproxy (channeltype, options)77{78 let sharedWorkerChannel;79 switch( channeltype )80 {81 case "internalChannel":82 InternalChannelPromise.then(83 function( ic )84 {85 pdrProxyResolver( new PerspectivesProxy( ic ) );86 }87 );88 break;89 // case "tcpChannel":90 // pdrProxyResolver( new PerspectivesProxy( new TcpChannel( options ) ) );91 // break;92 case "sharedWorkerChannel":93 sharedWorkerChannel = new SharedWorkerChannel( sharedWorkerHostingPDRPort() );94 sharedWorkerChannelResolver( sharedWorkerChannel );95 pdrProxyResolver( new PerspectivesProxy( sharedWorkerChannel ) );96 break;97 case "hostPageChannel":98 sharedWorkerChannel = new SharedWorkerChannel( options.pageHostingPDRPort() );99 sharedWorkerChannelResolver( sharedWorkerChannel );100 pdrProxyResolver( new PerspectivesProxy( sharedWorkerChannel ) );101 break;102 }103}104////////////////////////////////////////////////////////////////////////////////105//// PORT TO SHARED WORKER THAT HOSTS PDR106////////////////////////////////////////////////////////////////////////////////107function sharedWorkerHostingPDRPort()108{109 return new SharedWorker('perspectives-sharedworker.js').port;110}111////////////////////////////////////////////////////////////////////////////////112//// SERVER SIDE RESOLVER TO INTERNAL CHANNEL113////////////////////////////////////////////////////////////////////////////////114// This function will be called from Perspectives Core if it want to set up an internal channel to a GUI.115// emitStep will be bound to the constructor Emit, finishStep will be the constructor Finish.116function createRequestEmitterImpl (emitStep, finishStep, emit)117{118 try119 {120 // Resolve InternalChannelPromise made above.121 const icp = new InternalChannel(emitStep, finishStep, emit);122 internalChannelResolver (icp);123 }124 catch(e)125 {126 internalChannelRejecter(e);127 }128}129////////////////////////////////////////////////////////////////////////////////130//// REQUEST STRUCTURE131////////////////////////////////////////////////////////////////////////////////132const defaultRequest =133 {134 request: "WrongRequest",135 subject: "The original request did not have a request type!",136 predicate: "",137 object: "",138 reactStateSetter: function(){},139 corrId: "",140 contextDescription: {}141 };142////////////////////////////////////////////////////////////////////////////////143//// INTERNAL CHANNEL144////////////////////////////////////////////////////////////////////////////////145class InternalChannel146{147 // emitStep will be bound to the constructor Emit, finishStep will be the constructor Finish.148 // emit must be bound to an Effect producing function.149 constructor (emitStep, finishStep, emit)150 {151 this.emitStep = emitStep;152 this.finishStep = finishStep;153 this.emit = emit;154 this.requestId = -1;155 }156 nextRequestId ()157 {158 this.requestId = this.requestId + 1;159 return this.requestId;160 }161 // Inform the server that this client shuts down.162 // No other requests may follow this message.163 close()164 {165 this.emit( this.finishStep({}) )();166 this.emit = function()167 {168 throw( "This client has shut down!");169 };170 }171 // Returns a promise for unsubscriber information of the form: {subject: req.subject, corrId: req.corrId}172 send ( req, fireAndForget )173 {174 const proxy = this;175 const setter = req.reactStateSetter;176 // Create a correlation identifier and store it in the request.177 if ( !req.corrId )178 {179 req.corrId = this.nextRequestId();180 }181 // console.log( req );182 if (fireAndForget)183 {184 req.reactStateSetter = function( result )185 {186 // Move all properties to the default request to ensure we send a complete request.187 proxy.send(188 Object.assign(189 Object.assign({}, defaultRequest),190 { request: "Unsubscribe"191 , subject: req.subject192 , corrId: req.corrId}) );193 setter( result );194 };195 }196 this.emit( this.emitStep(req) )();197 // return a promise for the elementary data for unsubscribing.198 return new Promise( function( resolver /*.rejecter*/)199 {200 resolver( {subject: req.subject, corrId: req.corrId} );201 } );202 }203 unsubscribe(req)204 {205 this.send(206 {request: "Unsubscribe", subject: req.subject, predicate: req.predicate, setterId: req.setterId}207 );208 }209}210////////////////////////////////////////////////////////////////////////////////211//// SHARED WORKER CHANNEL212//// This code will be executed by the client!213//// The SharedWorkerChannel is a proxy for the ServiceWorker for the client.214////////////////////////////////////////////////////////////////////////////////215class SharedWorkerChannel216{217 constructor( port )218 {219 const serviceWorkerChannel = this;220 this.requestId = -1;221 this.valueReceivers = {};222 this.channelIdResolver = undefined;223 this.channelId = new Promise(224 function (resolve/*, reject*/)225 {226 serviceWorkerChannel.channelIdResolver = resolve;227 });228 this.port = port;229 this.handleWorkerResponse = this.handleWorkerResponse.bind(this);230 this.port.onmessage = this.handleWorkerResponse;231 }232 // The sharedworker or pageworker sends messages of various types.233 // Among them are responses received by the core.234 //235 handleWorkerResponse (e)236 {237 if (e.data.error)238 {239 // {corrId: i, error: s} where s is is a String, i an int.240 // we just pass errors on.241 this.valueReceivers[ e.data.corrId ]( e.data );242 }243 else if ( e.data.result )244 {245 // {corrId: i, result: s} where s is an Array of String, i an int.246 // pass the result on247 this.valueReceivers[ e.data.corrId ]( e.data );248 }249 // Then we have a category of incoming messages that originate in the service worker itself,250 // often in response to a specific request sent by the proxy.251 else if ( e.data.serviceWorkerMessage )252 {253 // {serviceWorkerMessage: m, <field>: <value>} where m is a string. The object may contain any number of other fields, depending on the type of message (i.e. the value of m).254 switch( e.data.serviceWorkerMessage )255 {256 case "channelId":257 // This actually is a response that is not provoked by explicitly asking for it.258 // As soon as the SharedWorker receives a port from this proxy, it will return the channels id.259 // {serviceWorkerMessage: "channelId", channelId: i} where i is a multiple of a million.260 // Handle the port identification message that is sent by the service worker.261 this.channelIdResolver( e.data.channelId );262 break;263 case "isUserLoggedIn":264 // {serviceWorkerMessage: "isUserLoggedIn", isUserLoggedIn: b} where b is a boolean.265 this.valueReceivers.isUserLoggedIn( e.data.isUserLoggedIn );266 break;267 case "resetAccount":268 // {serviceWorkerMessage: "resetAccount", resetSuccesful: b} where b is a boolean.269 this.valueReceivers.resetAccount( e.data.resetSuccesful );270 break;271 case "recompileBasicModels":272 // {serviceWorkerMessage: "recompileBasicModels", recompileSuccesful: b} where b is a boolean.273 this.valueReceivers.recompileBasicModels( e.data.recompileSuccesful );274 break;275 case "removeAccount":276 // {serviceWorkerMessage: "removeAccount", removeSuccesful: b} where b is a boolean.277 this.valueReceivers.removeAccount( e.data.removeSuccesful );278 break;279 case "runPDR":280 // {serviceWorkerMessage: "runPDR", error: e }281 this.valueReceivers.runPDR( e );282 break;283 case "createAccount":284 // {serviceWorkerMessage: "createAccount", createSuccesful: b} where b is a boolean.285 this.valueReceivers.createAccount( e.data.createSuccesful );286 break;287 }288 }289 }290 // Returns a promise for a boolean value, reflecting whether the end user has logged in before or not.291 isUserLoggedIn ()292 {293 const proxy = this;294 const p = new Promise(295 function(resolver/*, rejecter*/)296 {297 proxy.valueReceivers.isUserLoggedIn = function(isLoggedIn)298 {299 proxy.valueReceivers.isUserLoggedIn = undefined;300 resolver( isLoggedIn );301 };302 }303 );304 proxy.channelId.then( channelId => proxy.port.postMessage( {proxyRequest: "isUserLoggedIn", channelId } ) );305 return p;306 }307 // runPDR :: UserName -> Password -> PouchdbUser -> Url -> Effect Unit308 // Runs the PDR, if a value is returned it will be an error message.309 // {serviceWorkerMessage: "runPDR", startSuccesful: success }310 // {serviceWorkerMessage: "runPDR", error: e }311 runPDR (username, pouchdbuser, publicrepo)312 {313 const proxy = this;314 const p = new Promise(315 function(resolver, rejecter)316 {317 proxy.valueReceivers.runPDR = function( e )318 {319 proxy.valueReceivers.runPDR = undefined;320 if (e.error)321 {322 rejecter( e.errormessage );323 }324 else325 {326 resolver( e.startSuccesful );327 }328 };329 }330 );331 proxy.channelId.then( channelId => this.port.postMessage({proxyRequest: "runPDR", username, pouchdbuser, publicrepo, channelId }));332 return p;333 }334 createUser (username, pouchdbuser, publicrepo)335 {336 const proxy = this;337 const p = new Promise(338 function(resolver/*, rejecter*/)339 {340 proxy.valueReceivers.createAccount = function(result)341 {342 proxy.valueReceivers.createAccount = undefined;343 resolver( result );344 };345 }346 );347 proxy.channelId.then( channelId => this.port.postMessage( {proxyRequest: "createAccount", username, pouchdbuser, publicrepo, channelId } ) );348 return p;349 }350 resetAccount (username, pouchdbuser, publicrepo)351 {352 const proxy = this;353 const p = new Promise(354 function(resolver/*, rejecter*/)355 {356 proxy.valueReceivers.resetAccount = function(result)357 {358 proxy.valueReceivers.resetAccount = undefined;359 resolver( result );360 };361 }362 );363 proxy.channelId.then( channelId => this.port.postMessage( {proxyRequest: "resetAccount", username, pouchdbuser, publicrepo, channelId } ) );364 return p;365 }366 recompileBasicModels (pouchdbuser, publicrepo)367 {368 const proxy = this;369 const p = new Promise(370 function(resolver/*, rejecter*/)371 {372 proxy.valueReceivers.recompileBasicModels = function(result)373 {374 proxy.valueReceivers.recompileBasicModels = undefined;375 resolver( result );376 };377 }378 );379 proxy.channelId.then( channelId => this.port.postMessage( {proxyRequest: "recompileBasicModels", pouchdbuser, publicrepo, channelId } ) );380 return p;381 }382 removeAccount (username, pouchdbuser, publicrepo)383 {384 const proxy = this;385 const p = new Promise(386 function(resolver/*, rejecter*/)387 {388 proxy.valueReceivers.removeAccount = function(result)389 {390 proxy.valueReceivers.removeAccount = undefined;391 resolver( result );392 };393 }394 );395 proxy.channelId.then( channelId => this.port.postMessage( {proxyRequest: "removeAccount", username, pouchdbuser, publicrepo, channelId } ) );396 return p;397 }398 // Inform the server that this client shuts down.399 // No other requests may follow this message.400 close()401 {402 // send a message that will make the internal channel in the Service Worker close.403 this.port.postMessage({proxyRequest: "Close"});404 }405 unsubscribe(req)406 {407 // Send a message that will make the internal channel in the Service Worker close.408 this.port.postMessage( {proxyRequest: "unsubscribe", request: req } );409 }410 nextRequestId ()411 {412 const proxy = this;413 return this.channelId.then(414 function( channelId )415 {416 proxy.requestId = proxy.requestId + 1;417 return proxy.requestId + channelId;418 }419 );420 }421 // Returns a promise for unsuscriber information of the form: {subject: req.subject, corrId: req.corrId}422 send ( req, fireAndForget )423 {424 const proxy = this;425 return this.nextRequestId().then(426 function( reqId )427 {428 const setter = req.reactStateSetter;429 // Create a correlation identifier and store it in the request.430 if ( !req.corrId )431 {432 req.corrId = reqId;433 }434 // Store the valueReceiver.435 if (fireAndForget)436 {437 proxy.valueReceivers[ req.corrId ] = function( result )438 {439 // Move all properties to the default request to ensure we send a complete request.440 proxy.send(441 Object.assign(442 Object.assign({}, defaultRequest),443 { request: "Unsubscribe"444 , subject: req.subject445 , corrId: req.corrId}) );446 setter( result );447 };448 }449 else450 {451 proxy.valueReceivers[ req.corrId ] = setter;452 }453 // cannot serialise a function, remove it from the request.454 req.reactStateSetter = undefined;455 // console.log( req );456 // send the request through the channel to the service worker.457 proxy.port.postMessage( req );458 // return the elementary data for unsubscribing.459 return {subject: req.subject, corrId: req.corrId};460 }461 );462 }463}464////////////////////////////////////////////////////////////////////////////////465//// PERSPECTIVESPROXY466////////////////////////////////////////////////////////////////////////////////467class PerspectivesProxy468{469 constructor (channel)470 {471 this.channel = channel;472 }473 // Inform the server that this client shuts down.474 // No other requests may follow this message.475 close()476 {477 this.channel.close();478 }479 // Returns a promise for unsuscriber information of the form: {subject: req.subject, corrId: req.corrId}480 // that can be used by the caller to unsubscribe from the core dependency network.481 send (req, receiveValues, fireAndForget)482 {483 // Handle errors here. Use `errorHandler` if provided by the PerspectivesProxy method, otherwise484 // just log a warning on the console.485 const handleErrors = function(response) // response = PerspectivesApiTypes.ResponseRecord486 {487 if (response.error)488 {489 console.warn( "This request:\n" + JSON.stringify(req) + "\n results in this error: \n" + response.error );490 }491 else {492 receiveValues(response.result);493 }494 // This is the Effect.495 return function () {};496 };497 req.reactStateSetter = handleErrors;498 // Move all properties to the default request to ensure we send a complete request.499 const fullRequest = Object.assign( Object.assign({}, defaultRequest), req);500 // DEVELOPMENT ONLY: warn if any value is undefined501 if ( Object.values(defaultRequest).includes( undefined ) )502 {503 console.warn( "Request misses values: " + JSON.stringify(defaultRequest) );504 }505 return this.channel.send( fullRequest, fireAndForget );506 }507 // unsubscribe from the channel.508 unsubscribe (req)509 {510 this.channel.unsubscribe(req);511 }512 // getRolBinding (contextID, rolName, receiveValues)513 // {514 // return this.send(515 // {request: "GetRolBinding", subject: contextID, predicate: rolName},516 // receiveValues);517 // }518 // rolName must be qualified but may use default prefixes.519 getRol (contextID, rolName, receiveValues, fireAndForget)520 {521 return this.send(522 {request: "GetRol", subject: contextID, predicate: rolName},523 receiveValues,524 fireAndForget);525 }526 getUnqualifiedRol (contextID, localRolName, receiveValues, fireAndForget)527 {528 return this.send(529 {request: "GetUnqualifiedRol", subject: contextID, predicate: localRolName},530 receiveValues,531 fireAndForget);532 }533 getProperty (rolID, propertyName, roleType, receiveValues, fireAndForget)534 {535 return this.send(536 {request: "GetProperty", subject: rolID, predicate: propertyName, object: roleType},537 receiveValues,538 fireAndForget);539 }540 getPropertyFromLocalName (rolID, propertyName, roleType, receiveValues, fireAndForget)541 {542 return this.send(543 {request: "GetPropertyFromLocalName", subject: rolID, predicate: propertyName, object: roleType},544 receiveValues,545 fireAndForget546 );547 }548 getBinding (rolID, receiveValues, fireAndForget)549 {550 return this.send(551 {request: "GetBinding", subject: rolID, predicate: ""},552 receiveValues,553 fireAndForget);554 }555 getBindingType (rolID, receiveValues, fireAndForget)556 {557 return this.send(558 {request: "GetBindingType", subject: rolID, predicate: ""},559 receiveValues,560 fireAndForget);561 }562 // Note: this function is currently not in use.563 // The lexical context of the roleType can be used by providing the empty string564 // as argument for parameter contextType.565 getRoleBinders (rolID, contextType, roleType, receiveValues, fireAndForget)566 {567 return this.send(568 {request: "GetRoleBinders", subject: rolID, predicate: roleType, object: contextType},569 receiveValues,570 fireAndForget);571 }572 // getUnqualifiedRoleBinders (rolID, localRolName, receiveValues)573 // {574 // return this.send(575 // {request: "GetUnqualifiedRoleBinders", subject: rolID, predicate: localRolName},576 // receiveValues);577 // }578 getViewProperties (rolType, viewName, receiveValues, fireAndForget)579 {580 return this.send(581 {request: "GetViewProperties", subject: rolType, predicate: viewName},582 receiveValues,583 fireAndForget);584 }585 getRolContext (rolID, receiveValues, fireAndForget)586 {587 return this.send(588 {request: "GetRolContext", subject: rolID, predicate: ""},589 receiveValues,590 fireAndForget);591 }592 getContextType (contextID, receiveValues, fireAndForget)593 {594 return this.send(595 {request: "GetContextType", subject: contextID, predicate: ""},596 receiveValues,597 fireAndForget);598 }599 getRolType (rolID, receiveValues, fireAndForget)600 {601 return this.send(602 {request: "GetRolType", subject: rolID, predicate: ""},603 receiveValues,604 fireAndForget);605 }606 // RoleInContext | ContextRole | ExternalRole | UserRole | BotRole607 getRoleKind (rolID, receiveValues, fireAndForget)608 {609 return this.send(610 {request: "GetRoleKind", subject: rolID, predicate: ""},611 receiveValues,612 fireAndForget);613 }614 getUnqualifiedRolType (contextType, localRolName, receiveValues, fireAndForget)615 {616 return this.send(617 {request: "GetUnqualifiedRolType", subject: contextType, predicate: localRolName},618 receiveValues,619 fireAndForget);620 }621 // Returns an array of Role Types.622 getMeForContext (externalRoleInstance, receiveValues, fireAndForget)623 {624 return this.send(625 {request: "GetMeForContext", subject: externalRoleInstance},626 receiveValues,627 fireAndForget628 );629 }630 // NOTE: it is not possible to subscribe to update events on this query.631 getAllMyRoleTypes(externalRoleInstance, receiveValues)632 {633 return this.send(634 {request: "GetAllMyRoleTypes", subject: externalRoleInstance},635 receiveValues,636 true637 );638 }639 // The instance of model:System$PerspectivesSystem$User that represents the user operating this PDR.640 getUserIdentifier (receiveValues, fireAndForget)641 {642 return this.send(643 {request: "GetUserIdentifier"},644 receiveValues,645 fireAndForget646 );647 }648 getPerspectives (contextInstance, userRoleType, receiveValues, fireAndForget)649 {650 return this.send(651 { request: "GetPerspectives"652 , subject: userRoleType653 , object: contextInstance654 },655 function (perspectiveStrings)656 {657 return receiveValues(perspectiveStrings.map( JSON.parse ));658 },659 fireAndForget660 );661 }662 // { request: "GetPerspective", subject: UserRoleType OPTIONAL, predicate: RoleInstance, object: ContextInstance OPTIONAL }663 getPerspective (contextInstance/*optional*/, userRoleType/*optional*/, roleInstance, receiveValues, fireAndForget)664 {665 return this.send(666 { request: "GetPerspective"667 , subject: userRoleType668 , predicate: roleInstance669 , object: contextInstance670 },671 function (perspectiveStrings)672 {673 return receiveValues(perspectiveStrings.map( JSON.parse ));674 },675 fireAndForget676 );677 }678 // { request: "GetScreen", subject: UserRoleType, predicate: ContextType, object: ContextInstance }679 getScreen(userRoleType, contextInstance, contextType, receiveValues, fireAndForget)680 {681 return this.send(682 { request: "GetScreen"683 , subject: userRoleType684 , predicate: contextType685 , object: contextInstance686 },687 function (screenStrings)688 {689 return receiveValues(screenStrings.map( JSON.parse ));690 },691 fireAndForget692 );693 }694 getRolesWithProperties (contextInstance, roleType, receiveValues, fireAndForget)695 {696 return this.send(697 { request: "GetRolesWithProperties"698 , object: contextInstance699 , predicate: roleType },700 function (roleWithPropertiesStrings)701 {702 return receiveValues( roleWithPropertiesStrings.map (JSON.parse ) );703 },704 fireAndForget705 );706 }707 getLocalRoleSpecialisation( localAspectName, contextInstance, receiveValues, fireAndForget )708 {709 return this.send(710 { request: "GetLocalRoleSpecialisation"711 , subject: contextInstance712 , predicate: localAspectName},713 receiveValues,714 fireAndForget715 );716 }717 getRoleName( rid, receiveValues, fireAndForget )718 {719 this.send(720 { request: "GetRoleName"721 , object: rid722 }723 , receiveValues724 , fireAndForget725 );726 }727 // Create a context, bound to a new instance of <roleType> in <contextId>. <roleType> may be a local name.728 // The ctype in the contextDescription must be qualified, but it may use a default prefix.729 // createContext( <contextDescription>, <roleType>, <contextId>, <EmbeddingContextType>, <myRoleType> ...)730 // roleType may be a name local to the EmbeddingContextType.731 // EmbeddingContextType must be fully qualified.732 // contextId must be a valid identifier for the context to create. Default namespaces will be expanded (e.g. usr:)733 // Either throws an error, or returns an array with734 // - just a single string identifiying the external role of a DBQ role;735 // - that string and a second that identifies the new context role otherwise.736 // So: [<externalRoleId>(, <contextRoleId>)?]737 createContext (contextDescription, roleType, contextId, embeddingContextType, myroletype, receiveResponse)738 {739 this.send(740 {request: "CreateContext", subject: contextId, predicate: roleType, object: embeddingContextType, contextDescription: contextDescription, authoringRole: myroletype},741 function(r)742 {743 receiveResponse( r );744 }745 );746 }747 // Create a context, bound to the given role instance.748 // createContext_( <contextDescription>, <roleinstance>, ...)749 // Either throws an error, or returns an array with a context identifier.750 createContext_ (contextDescription, roleInstance, myroletype, receiveResponse)751 {752 this.send(753 {request: "CreateContext_", subject: roleInstance, contextDescription: contextDescription, authoringRole: myroletype},754 function(r)755 {756 receiveResponse( r );757 }758 );759 }760 // Either throws an error, or returns an array of context identifiers.761 importContexts (contextDescription, receiveResponse)762 {763 this.send(764 {request: "ImportContexts", contextDescription: contextDescription},765 function(r)766 {767 receiveResponse( r );768 }769 );770 }771 // Either throws an error, or returns an empty array.772 // Notice we re-use the contextDescription field.773 importTransaction (transaction, receiveResponse)774 {775 this.send(776 {request: "ImportTransaction", contextDescription: transaction},777 function(r)778 {779 receiveResponse( r );780 }781 );782 }783 // value is just a single string!784 setProperty (rolID, propertyName, value, myroletype, callback)785 {786 this.send(787 {request: "SetProperty", subject: rolID, predicate: propertyName, object: value, authoringRole: myroletype},788 callback || function() {}789 );790 }791 // Function returns a promise.792 setPropertyP (rolID, propertyName, value, myroletype)793 {794 const proxy = this;795 return new Promise(function(resolver)796 {797 proxy.send(798 {request: "SetProperty", subject: rolID, predicate: propertyName, object: value, authoringRole: myroletype},799 function(whatever)800 {801 resolver( whatever );802 }803 );804 });805 }806 deleteProperty (rolID, propertyName, myroletype)807 {808 this.send(809 {request: "DeleteProperty", subject: rolID, predicate: propertyName, authoringRole: myroletype},810 function() {}811 );812 }813 // { request: Action814 // , predicate: <object of perspective role instance>815 // , object: <context instance>816 // , contextDescription:817 // { perspectiveId:818 // , actionName:819 // }820 // , authoringRole821 // ...}822 action (objectRoleInstance, contextInstance, perspectiveId, actionName, authoringRole)823 {824 const req = { request: "Action"825 , predicate: objectRoleInstance826 , object: contextInstance827 , contextDescription: { perspectiveId, actionName }828 , authoringRole829 };830 if (objectRoleInstance)831 {832 req.predicate = objectRoleInstance;833 }834 this.send( req );835 }836 // { request: ContextAction837 // , subject: RoleType // the user role type838 // , predicate: String // action identifier839 // , object: ContextId840 // }841 contextAction( contextid, myRoleType, actionName)842 {843 this.send({request: "ContextAction", subject: myRoleType, predicate: actionName, object: contextid, authoringRole: myRoleType });844 }845 // { request: GetContextActions846 // , subject: RoleType // the user role type847 // , object: ContextInstance848 // }849 getContextActions(myRoleType, contextInstance, receiveValues)850 {851 this.send({ request: "GetContextActions", subject: myRoleType, object: contextInstance }, receiveValues);852 }853 removeBinding (rolID, myroletype)854 {855 this.send(856 {request: "RemoveBinding", subject: rolID, authoringRole: myroletype},857 function() {}858 );859 }860 removeRol (rolName, rolID, myroletype, callback)861 {862 this.send(863 {request: "RemoveRol", subject: rolID, predicate: rolName, authoringRole: myroletype},864 (callback ? callback : function(){})865 );866 }867 //{request: "RemoveContext", subject: rolID, predicate: rolName, authoringRole: myroletype}868 // rolName must be qualified.869 removeContext (rolID, rolName, myroletype, callback)870 {871 this.send(872 {request: "RemoveContext", subject: rolID, predicate: rolName, authoringRole: myroletype},873 (callback ? callback : function(){})874 );875 }876 // Currently not used!877 deleteRole (contextID, rolName, rolID, myroletype)878 {879 this.send(880 {request: "DeleteRole", subject: rolName, predicate: contextID, authoringRole: myroletype},881 function() {}882 );883 }884 bind (contextinstance, localRolName, contextType, rolDescription, myroletype/*, receiveResponse*/)885 {886 this.send(887 {request: "Bind", subject: contextinstance, predicate: localRolName, object: contextType, rolDescription: rolDescription, authoringRole: myroletype },888 function() {}889 );890 }891 bind_ (binder, binding, myroletype)892 {893 this.send(894 {request: "Bind_", subject: binder, object: binding, authoringRole: myroletype},895 function() {}896 );897 }898 // checkBinding( <contexttype>, <(local)RolName>, <binding>, [() -> undefined] )899 // Where (local)RolName identifies the role in <contexttype> whose binding specification we want to compare with <binding>.900 checkBinding (contextType, localRolName, rolInstance, callback, fireAndForget)901 {902 this.send(903 {request: "CheckBinding", subject: contextType, predicate: localRolName, object: rolInstance}904 , callback905 , fireAndForget906 );907 }908 // We have room for checkBinding_( <binder>, <binding>, [() -> undefined] )909 createRole (contextinstance, rolType, myroletype/*, receiveResponse*/)910 {911 this.send(912 {request: "CreateRol", subject: contextinstance, predicate: rolType, authoringRole: myroletype },913 function() {}914 );915 }916 setPreferredUserRoleType( externalRoleId, userRoleName )917 {918 this.send(919 {request: "SetPreferredUserRoleType", subject: externalRoleId, object: userRoleName},920 function(){}921 );922 }923 // NOTE: this function returns a promise and does not take a callback!924 matchContextName( name )925 {926 const proxy = this;927 return new Promise(function(resolver)928 {929 proxy.send(930 {request: "MatchContextName", subject: name},931 function(qualifiedNames)932 {933 resolver( qualifiedNames );934 }935 );936 });937 }938 // NOTE: this function returns a promise and does not take a callback!939 getCouchdbUrl()940 {941 const proxy = this;942 return new Promise(function (resolver)943 {944 proxy.send(945 { request: "GetCouchdbUrl" },946 function( url )947 {948 resolver( url );949 }950 );951 });952 }953}954module.exports = {955 PDRproxy: PDRproxy,956 InternalChannelPromise: InternalChannelPromise,957 SharedWorkerChannelPromise: SharedWorkerChannelPromise,958 createRequestEmitterImpl: createRequestEmitterImpl,959 // createTcpConnectionToPerspectives: createTcpConnectionToPerspectives,960 // createServiceWorkerConnectionToPerspectives: createServiceWorkerConnectionToPerspectives,961 configurePDRproxy: configurePDRproxy,962 FIREANDFORGET: true963};964////////////////////////////////////////////////////////////////////////////////965//// TCP CHANNEL966////////////////////////////////////////////////////////////////////////////////967// class TcpChannel968// {969// constructor (options)970// {971// let connection;972// this.requestId = -1;973// const valueReceivers = {};974// // This creates a net.Socket (https://nodejs.org/api/net.html#net_net_createconnection).975// this.connection = require("net").createConnection(976// options,977// // message will be in base64. Appending a string to it converts it to a new string.978// function ()979// {980// console.log("Connection made.");981// });982// connection = this.connection;983// this.valueReceivers = valueReceivers;984//985// // See: https://nodejs.org/api/net.html#net_class_net_socket986// connection.on('data',987// // message will be in base64. Appending a string to it converts it to a new string.988// function (message)989// {990// const messages = (message + "").split("\n");991// messages.forEach( function(m) // m :: PerspectivesApiTypes.ResponseRecord992// {993// if (m !== "")994// {995// try996// {997// const responseRecord = JSON.parse(m);998// valueReceivers[responseRecord.corrId](responseRecord);999// }1000// catch(e)1001// {1002// console.log(e);1003// }1004// }1005// });1006// });1007//1008// // https://nodejs.org/docs/latest-v6.x/api/net.html#net_event_error1009// // Emitted when an error occurs. The 'close' event will be called1010// // directly following this event.1011// connection.on('error',1012// function(error)1013// {1014// console.log( "Error on the connection: " + error );1015// // Half-closes the socket. i.e., it sends a FIN packet.1016// // It is possible the server will still send some data.1017// connection.end();1018// });1019//1020// // https://nodejs.org/docs/latest-v6.x/api/net.html#net_event_close1021// // Emitted once the socket is fully closed. The argument had_error is a boolean1022// // which says if the socket was closed due to a transmission error.1023// connection.on('close',1024// function(had_error)1025// {1026// // No data will come anymore.1027// if ( had_error )1028// {1029// console.log("The Perspectives Core has hung up because of an error.");1030// }1031// else1032// {1033// console.log("The Perspectives Core has hung up.");1034// }1035// });1036//1037// // https://nodejs.org/docs/latest-v6.x/api/net.html#net_event_end1038// // Emitted when the other end of the socket sends a FIN packet.1039// // By default (allowHalfOpen == false) the socket will destroy its file1040// // descriptor once it has written out its pending write queue.1041// connection.on('end',1042// function()1043// {1044// // This means the other side will no longer send data.1045// console.log("The Perspectives Core has hung up.");1046// });1047// }1048//1049// nextRequestId ()1050// {1051// this.requestId = this.requestId + 1;1052// return this.requestId.toString();1053// }1054//1055// // close will lead the messageProducer of the perspectives core to receive (Right unit).1056// close()1057// {1058// // https://nodejs.org/api/net.html#net_socket_end_data_encoding_callback1059// this.connection.end();1060// this.send = function()1061// {1062// throw( "This client has shut down!");1063// };1064// }1065//1066// // req has the following format (taken from: module Perspectives.Api)1067// // { request :: String1068// // , subject :: String1069// // , predicate :: String1070// // , setterId :: ReactStateSetterIdentifier}1071// // type ReactStateSetterIdentifier = String1072// // Returns a structure that can be used by the caller to unsubscribe from the core dependency network.1073// send(req, receiveValues)1074// {1075// req.corrId = this.nextRequestId();1076// this.valueReceivers[ req.corrId ] = receiveValues;1077// // https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback1078// this.connection.write(JSON.stringify(req) + "\n");1079// // return the elementary data for unsubscribing.1080// return {subject: req.subject, predicate: req.corrId};1081// }1082//1083// unsubscribe(req)1084// {1085// delete this.valueReceivers[req.setterId];1086// // https://nodejs.org/api/net.html#net_socket_write_data_encoding_callback1087// this.connection.write(1088// {request: "Unsubscribe", subject: req.subject, predicate: req.predicate, setterId: req.setterId}1089// );1090// }...
index.spec.ts
Source:index.spec.ts
...19 await wait(10);20 count++;21 return Promise.reject(new Error("ups, some error happened"));22 }23 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());24 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());25 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());26 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEndAndReject());27 await fireAndForget.close();28 expect(count).toBe(4);29 });30 it("close should throw a timeout closing error if timeout is reached and fire and forget operation are still in process", async () => {31 expect.assertions(3);32 const fireAndForget = fireAndForgetter();33 let count = 0;34 async function doSumeSuffAndIncrementCountAtTheEnd(): Promise<void> {35 await wait(1000);36 count++;37 return Promise.resolve();38 }39 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());40 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());41 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());42 try {43 await fireAndForget.close({ timeout: 10 });44 } catch (error) {45 expect(error instanceof TimeoutClosingError).toBe(true);46 expect((error as Error).message).toBe("Cannot close after 10ms, 3 fire and forget operations are still in progress");47 expect(count).toBe(0);48 }49 });50 it("close should resolve when no fire and forget operations are in process", async () => {51 const fireAndForget = fireAndForgetter();52 await expect(fireAndForget.close()).resolves;53 });54 it("fireAndForget should call onError callback when operation rejects", async () => {55 expect.assertions(2);56 const fireAndForget = fireAndForgetter();57 async function doSumeSuffAndReject(): Promise<void> {58 await wait(10);59 return Promise.reject(new Error("ups, some error happened"));60 }61 fireAndForget(() => doSumeSuffAndReject(), (error) => {62 expect(error instanceof Error).toBe(true);63 expect((error as Error).message).toBe("ups, some error happened");64 });65 await fireAndForget.close();66 });67 it("fireAndForget should call defaultOnError callback when operation rejects and no onError callback is set", async () => {68 expect.assertions(2);69 const fireAndForget = fireAndForgetter({70 defaultOnError: (error) => {71 expect(error instanceof Error).toBe(true);72 expect(error.message).toBe("ups, some error happened");73 },74 });75 async function doSumeSuffAndReject(): Promise<void> {76 await wait(10);77 return Promise.reject(new Error("ups, some error happened"));78 }79 fireAndForget(() => doSumeSuffAndReject());80 await fireAndForget.close();81 });82 it("fireAndForget should throw a closing error if fire and forget has been closed", async () => {83 expect.assertions(2);84 const fireAndForget = fireAndForgetter();85 async function doSumeSuffAndIncrementCountAtTheEnd(): Promise<void> {86 await wait(100);87 return Promise.resolve();88 }89 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());90 fireAndForget.close();91 try {92 fireAndForget(() => doSumeSuffAndIncrementCountAtTheEnd());93 } catch (error) {94 expect(error instanceof ClosingError).toBe(true);95 expect((error as Error).message).toBe("Cannot longer execute fire and forget operation as is closing or closed");96 }97 });...
ModuleApi.ts
Source:ModuleApi.ts
...27 startModuleInstallation: (request: ModuleInstallationRequest, onComplete: Dispatch<Module>) => {28 requestResponse(createFunctionRequest(START_MODULE_INSTALLATION, request), onComplete, actions.errorHandler())29 },30 processModuleInstallation: (request: Module) => {31 fireAndForget(createFunctionRequest(PROCESS_MODULE_INSTALLATION, request))32 },33 reinstallModule: (id: number) => {34 fireAndForget(createFunctionRequest(REINSTALL_MODULE, id))35 },36 getModule: (request: number, onComplete: Dispatch<Module>) => {37 requestResponse(createFunctionRequest(GET_MODULE, request), onComplete, actions.errorHandler())38 },39 getModules: (onComplete: Dispatch<Module[]>) => {40 requestResponse(41 createFunctionRequest(GET_MODULES),42 modules => onComplete(modules.filter(module => platform.user()?.availableProjects?.includes(module.projectId))),43 actions.errorHandler()44 )45 },46 getFilteredModules: (request: ModuleFilterCriteria, onComplete: Dispatch<ModuleInformation[]>) => {47 requestResponse(48 createFunctionRequest(GET_FILTERED_MODULES, request),49 modules => onComplete(modules.filter(module => platform.user()?.admin || platform.user()?.availableProjects?.includes(module.projectId))),50 actions.errorHandler()51 )52 },53 startModuleUpdating: (request: ModuleUpdateRequest, onComplete: Dispatch<Module>) => {54 requestResponse(createFunctionRequest(START_MODULE_UPDATING, request), onComplete, actions.errorHandler())55 },56 processModuleUpdating: (request: Module) => {57 fireAndForget(createFunctionRequest(PROCESS_MODULE_UPDATING, request))58 },59 refreshModuleArtifact: (request: number) => {60 fireAndForget(createFunctionRequest(REFRESH_MODULE_ARTIFACT, request))61 },62 updateModulesVersion: (request: UpdateModulesVersionRequest) => {63 fireAndForget(createFunctionRequest(UPDATE_MODULES_VERSION, request))64 },65 stopModule: (id: number) => {66 fireAndForget(createFunctionRequest(STOP_MODULE, id))67 },68 restartModule: (id: number) => {69 fireAndForget(createFunctionRequest(RESTART_MODULE, id))70 },71 deleteModuleFromResource: (id: number) => {72 fireAndForget(createFunctionRequest(DELETE_MODULE_FROM_RESOURCE, id))73 },74 deleteModule: (id: number) => {75 requestResponse(createFunctionRequest(DELETE_MODULE, id))76 },77 subscribeOnModule: (onUpdate: Dispatch<StreamEvent<Module>>) => {78 return infinityRequestStream(79 createFunctionRequest(SUBSCRIBE_ON_MODULE),80 event => (platform.user()?.admin || platform.user()?.availableProjects?.includes(event.data.projectId)) && onUpdate(event),81 actions.errorHandler82 );83 },84 };...
Using AI Code Generation
1var mb = require('mountebank');2var port = 2525;3var imposter = {4 {5 {6 is: {7 headers: {8 },9 }10 }11 }12};13mb.create(imposter, function (error, instance) {14 console.log('imposter created');15 instance.fireAndForget({ port: port, path: '/', method: 'GET' }, function (error, response) {16 });17});
Using AI Code Generation
1var mb = require('mountebank');2var port = 2525;3var imposter = {4 {5 { equals: { method: 'GET', path: '/test' } }6 { is: { statusCode: 200, body: 'Hello, world!' } }7 }8};9mb.create(imposter, function () {10 mb.fireAndForget({11 });12});13var mb = require('mountebank');14var port = 2525;15var proxyImposter = {16 {17 { equals: { method: 'GET', path: '/test' } }18 }19};20mb.create(proxyImposter, function () {21 mb.fireAndForget({22 });23});24var mb = require('mountebank');25var port = 2525;26var imposter = {27 {28 { equals: { method: 'GET', path
Using AI Code Generation
1const mb = require('mountebank');2const port = 2525;3const imposterPort = 3000;4const imposter = {5 stubs: [{6 responses: [{7 is: {8 }9 }]10 }]11};12mb.start({ port, pidfile: 'mb.pid', loglevel: 'debug', logfile: 'mb.log' }, () => {13 mb.createImposter(imposter, () => {14 const request = {15 };16 mb.fireAndForget(request, () => {17 console.log('request sent');18 });19 });20});21const mb = require('mountebank');22const port = 2525;23const imposterPort = 3000;24const imposter = {25 stubs: [{26 responses: [{27 is: {28 }29 }]30 }]31};32mb.start({ port, pidfile: 'mb.pid', loglevel: 'debug', logfile: 'mb.log' }, () => {33 mb.createImposter(imposter, () => {34 const request = {35 };36 mb.fireAndForget(request, () => {37 console.log('request sent');38 });39 });40});41const mb = require('mountebank');42const port = 2525;43const imposterPort = 3000;44const imposter = {45 stubs: [{46 responses: [{47 is: {48 }49 }]50 }]51};52mb.start({ port, pidfile: 'mb.pid', loglevel: 'debug', logfile: 'mb.log' }, () => {53 mb.createImposter(imposter, () => {54 const request = {
Using AI Code Generation
1const mb = require('mountebank').create({ port: 2525, pidfile: 'mb.pid', logfile: 'mb.log', protofile: 'mb.proto', ipWhitelist: ['*'] });2mb.start().then(() => {3 console.log('mountebank started');4 const imposter = {5 {6 {7 is: {8 headers: {9 },10 body: JSON.stringify({ "status": "success" })11 }12 }13 }14 };15 return mb.post('/imposters', imposter);16}).then(() => {17 console.log('imposter created');18 return mb.fireAndForget('/imposters/2525/stubs/0', { responses: [{ is: { body: 'Hello world' } }] });19}).then(() => {20 console.log('stub created');21 return mb.get('/imposters/2525');22}).then(response => {23 console.log('imposter retrieved');24 console.log(response.body);25 return mb.del('/imposters');26}).then(() => {27 console.log('imposter deleted');28 return mb.stop();29}).then(() => {30 console.log('mountebank stopped');31}).catch(error => {32 console.error(error);33});34{35 "scripts": {36 },37 "dependencies": {38 }39}
Using AI Code Generation
1const mb = require('mountebank');2const port = 2525;3mb.start({4}, () => {5 console.log(`mountebank running on port ${port}`);6});7mb.create({8 stubs: [{9 predicates: [{10 equals: {11 }12 }],13 responses: [{14 is: {15 headers: {16 },17 body: JSON.stringify({18 })19 }20 }]21 }]22}, () => {23 console.log('Imposter created!');24});25mb.fireAndForget({26 stubs: [{27 predicates: [{28 equals: {29 }30 }],31 responses: [{32 is: {33 headers: {34 },35 body: JSON.stringify({36 })37 }38 }]39 }]40}, () => {41 console.log('Imposter created!');42});43const rp = require('request-promise');44const mb = require('mountebank');45const port = 2525;46describe('Test', () => {47 it('should return Hello World', () => {48 const options = {49 };50 return rp(options)51 .then((response) => {52 expect(response.message).to.equal('Hello World');53 });54 });55});56const rp = require('request-promise');57const mb = require('mountebank');58const port = 2525;59describe('Test2', () => {60 it('should return Hello World', () => {61 const options = {62 };63 return rp(options)64 .then((response) => {65 expect(response.message).to.equal('Hello World');66 });67 });
Using AI Code Generation
1var mb = require('mountebank');2var imposter = {3 {4 {5 is: {6 headers: { 'Content-Type': 'application/json' },7 body: JSON.stringify({ message: 'Hello World' })8 }9 }10 }11};12mb.start({ port: 2525, pidfile: 'mb.pid', logfile: 'mb.log' }, function (error) {13 mb.post('/imposters', imposter, function (error, response) {14 console.log(response.body);15 mb.stop(function (error) {16 console.log('done');17 });18 });19});20var mb = require('mountebank');21var imposter = {22 {23 {24 is: {25 headers: { 'Content-Type': 'application/json' },26 body: JSON.stringify({ message: 'Hello World' })27 }28 }29 }30};31mb.start({ port: 2525, pidfile: 'mb.pid', logfile: 'mb.log' }, function (error) {32 mb.post('/imposters', imposter, function (error, response) {33 console.log(response.body);34 mb.stop(function (error) {35 console.log('done');36 });37 });38});39var mb = require('mountebank');40var imposter = {
Using AI Code Generation
1var imposter = { port: 3000, protocol: 'http' };2var stub = {3 responses: [{ is: { body: 'Hello world!' } }]4};5var mb = require('mountebank');6mb.create(imposter).then(function (result) {7 return mb.addStub(result.port, stub);8}).then(function (result) {9 return mb.fireAndForget(result.port, { path: '/', method: 'GET' });10}).then(function (result) {11 console.log(result.body);12});13var imposter = { port: 3000, protocol: 'http' };14var mb = require('mountebank');15mb.create(imposter).then(function (result) {16 console.log(result.body);17});18var mb = require('mountebank');19mb.get().then(function (result) {20 console.log(result.body);21});22var mb = require('mountebank');23mb.getImposter(3000).then(function (result) {24 console.log(result.body);25});26var mb = require('mountebank');27mb.deleteImposter(3000).then(function (result) {28 console.log(result.body);29});30var imposter = { port: 3000, protocol: 'http' };31var stub = {32 responses: [{ is: { body: 'Hello world!' } }]33};34var mb = require('mountebank');35mb.create(imposter).then(function (result) {36 return mb.addStub(result.port, stub);37}).then(function (result) {38 console.log(result.body);39});40var imposter = { port: 3000, protocol:
Using AI Code Generation
1var imposter = require('mountebank').create({2});3imposter.post('/test', function (req, res) {4 res.statusCode = 200;5 res.send({ status: 'ok' });6});7imposter.fireAndForget('/test', function (req, res) {8 res.statusCode = 200;9 res.send({ status: 'ok' });10});11imposter.start();12var mb = require('mountebank'),13 imposter = mb.create({14 });15imposter.post('/test', function (req, res) {16 res.statusCode = 200;17 res.send({ status: 'ok' });18});19imposter.fireAndForget('/test', function (req, res) {20 res.statusCode = 200;21 res.send({ status: 'ok' });22});23imposter.start();24var mb = require('mountebank'),25 http = require('mb-http'),26 imposter = mb.create({27 }),28 server = http.createServer(imposter);29imposter.post('/test', function (req, res) {30 res.statusCode = 200;31 res.send({ status: 'ok' });32});33imposter.fireAndForget('/test', function (req, res) {34 res.statusCode = 200;35 res.send({ status: 'ok' });36});37server.listen(2525);
Using AI Code Generation
1var mb = require('mountebank');2var port = 2525;3var host = 'localhost';4var path = 'imposters';5var protocol = 'http';6var imposters = [{7 stubs: [{8 responses: [{9 is: {10 }11 }]12 }]13}];14mb.fireAndForget({15}, function (error) {16 if (error) {17 console.error('Unable to create imposters: ' + error.message);18 }19});20var mb = require('mountebank');21var port = 2525;22var host = 'localhost';23var path = 'imposters';24var protocol = 'http';25var imposters = [{26 stubs: [{27 responses: [{28 is: {29 }30 }]31 }]32}];33mb.fireAndForget({34}, function (error) {35 if (error) {36 console.error('Unable to create imposters: ' + error.message);37 }38});39var mb = require('mountebank');40var port = 2525;41var host = 'localhost';42var path = 'imposters';43var protocol = 'http';44var imposters = [{45 stubs: [{46 responses: [{47 is: {48 }49 }]50 }]51}];52mb.fireAndForget({53}, function (error) {54 if (error) {55 console.error('Unable to create imposters: ' + error.message);56 }57});
Using AI Code Generation
1const imposter = require('mountebank').create({ port: 2525, allowInjection: true });2imposter.post('/test', function (req, res) {3 res.send(200);4});5imposter.fireAndForget('/test', 'POST', { 'Content-Type': 'application/json' }, JSON.stringify({ 'name': 'test' }));6imposter.close();7const imposter = require('mountebank').create({ port: 2525, allowInjection: true });8imposter.post('/test', function (req, res) {9 res.send(200);10});11imposter.fireAndForget('/test', 'POST', { 'Content-Type': 'application/json' }, JSON.stringify({ 'name': 'test' }));12imposter.close();
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!