From 432625a2789b580ad3d76dc1dc24cb98d69bde33 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Thu, 23 Apr 2020 16:52:33 +0800 Subject: [PATCH] feat(h5): automator --- packages/uni-automator/dist/index.js | 4 ++-- packages/vue-cli-plugin-uni/commands/build.js | 12 +----------- packages/vue-cli-plugin-uni/commands/serve.js | 8 ++++++-- packages/vue-cli-plugin-uni/commands/util.js | 15 +++++++++++++++ packages/vue-cli-plugin-uni/lib/h5/index.js | 5 +++-- packages/vue-cli-plugin-uni/lib/mp/index.js | 7 ++----- packages/vue-cli-plugin-uni/lib/util.js | 4 ++++ 7 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 packages/vue-cli-plugin-uni/commands/util.js diff --git a/packages/uni-automator/dist/index.js b/packages/uni-automator/dist/index.js index 1148b250f..161c6f84e 100644 --- a/packages/uni-automator/dist/index.js +++ b/packages/uni-automator/dist/index.js @@ -1,4 +1,4 @@ -"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}var e=t(require("fs")),n=t(require("path")),s=t(require("debug")),o=require("child_process"),i=t(o),r=t(require("licia/getPort")),a=t(require("licia/toStr")),c=t(require("licia/waitUntil")),l=t(require("licia/concat")),p=t(require("licia/sleep")),u=t(require("licia/isRelative")),h=t(require("licia/dateFormat")),d=t(require("ws")),m=require("events"),y=t(require("licia/uuid")),g=t(require("licia/stringify")),v=t(require("licia/fs")),w=t(require("licia/isFn")),f=t(require("licia/trim")),P=t(require("licia/isStr")),M=t(require("licia/startWith")),E=t(require("licia/isNum")),k=t(require("licia/isUndef"));require("jimp");class C extends m.EventEmitter{constructor(t){super(),this.ws=t,this.ws.addEventListener("message",t=>{this.emit("message",t.data)}),this.ws.addEventListener("close",()=>{this.emit("close")})}send(t){this.ws.send(t)}close(){this.ws.close()}}class b extends m.EventEmitter{constructor(t,e,n){super(),this.puppet=e,this.namespace=n,this.callbacks=new Map,this.transport=t,this.debug=s("automator:protocol:"+this.namespace),this.onMessage=t=>{this.debug(`${h("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${t}`);const{id:e,method:n,error:s,result:o,params:i}=JSON.parse(t);if(!e)return this.puppet.emit(n,i);const{callbacks:r}=this;if(e&&r.has(e)){const t=r.get(e);r.delete(e),s?t.reject(Error(s.message)):t.resolve(o)}},this.onClose=()=>{this.callbacks.forEach(t=>{t.reject(Error("Connection closed"))})},this.transport.on("message",this.onMessage),this.transport.on("close",this.onClose)}send(t,e={},n=!0){if(n&&"devtool"===this.namespace&&this.puppet.adapter.has(t))return this.puppet.adapter.send(this,t,e);const s=y(),o=g({id:s,method:t,params:e});return this.debug(`${h("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${o}`),new Promise((t,e)=>{try{this.transport.send(o)}catch(t){e(Error("Connection closed"))}this.callbacks.set(s,{resolve:t,reject:e})})}dispose(){this.transport.close()}static createDevtoolConnection(t,e){return new Promise((n,s)=>{const o=new d(t);o.addEventListener("open",()=>{n(new b(new C(o),e,"devtool"))}),o.addEventListener("error",s)})}static createRuntimeConnection(t,e,n){return new Promise((o,i)=>{s("automator:runtime")(`${h("yyyy-mm-dd HH:MM:ss:l")} port=${t}`);const r=new d.Server({port:t});c(async()=>{if(e.runtimeConnection)return!0},n,1e3).catch(t=>{throw Error("Failed to connect to runtime, please make sure the project is running")}),r.on("connection",(function(t){s("automator:runtime")(h("yyyy-mm-dd HH:MM:ss:l")+" connected");const n=new b(new C(t),e,"runtime");e.setRuntimeConnection(n),o(n)})),e.setRuntimeServer(r)})}}const T=require("qrcode-terminal");require("qrcode-reader");async function D(t,e){const[n,s]=function(t){return P(t)?[!0,[t]]:[!1,t]}(e),o=await t(s);return n?o[0]:o} +"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}var e=t(require("fs")),n=t(require("path")),s=t(require("debug")),o=require("child_process"),i=t(o),r=t(require("licia/getPort")),a=t(require("licia/toStr")),c=t(require("licia/waitUntil")),l=t(require("licia/concat")),p=t(require("licia/sleep")),u=t(require("licia/isRelative")),h=t(require("licia/dateFormat")),d=t(require("ws")),m=require("events"),y=t(require("licia/uuid")),g=t(require("licia/stringify")),v=t(require("licia/fs")),w=t(require("licia/isFn")),f=t(require("licia/trim")),P=t(require("licia/isStr")),M=t(require("licia/startWith")),E=t(require("licia/isNum")),k=t(require("licia/isUndef"));require("jimp");class C extends m.EventEmitter{constructor(t){super(),this.ws=t,this.ws.addEventListener("message",t=>{this.emit("message",t.data)}),this.ws.addEventListener("close",()=>{this.emit("close")})}send(t){this.ws.send(t)}close(){this.ws.close()}}class b extends m.EventEmitter{constructor(t,e,n){super(),this.puppet=e,this.namespace=n,this.callbacks=new Map,this.transport=t,this.debug=s("automator:protocol:"+this.namespace),this.onMessage=t=>{this.debug(`${h("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${t}`);const{id:e,method:n,error:s,result:o,params:i}=JSON.parse(t);if(!e)return this.puppet.emit(n,i);const{callbacks:r}=this;if(e&&r.has(e)){const t=r.get(e);r.delete(e),s?t.reject(Error(s.message)):t.resolve(o)}},this.onClose=()=>{this.callbacks.forEach(t=>{t.reject(Error("Connection closed"))})},this.transport.on("message",this.onMessage),this.transport.on("close",this.onClose)}send(t,e={},n=!0){if(n&&"devtool"===this.namespace&&this.puppet.adapter.has(t))return this.puppet.adapter.send(this,t,e);const s=y(),o=g({id:s,method:t,params:e});return this.debug(`${h("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${o}`),new Promise((t,e)=>{try{this.transport.send(o)}catch(t){e(Error("Connection closed"))}this.callbacks.set(s,{resolve:t,reject:e})})}dispose(){this.transport.close()}static createDevtoolConnection(t,e){return new Promise((n,s)=>{const o=new d(t);o.addEventListener("open",()=>{n(new b(new C(o),e,"devtool"))}),o.addEventListener("error",s)})}static createRuntimeConnection(t,e,n){return new Promise((o,i)=>{s("automator:runtime")(`${h("yyyy-mm-dd HH:MM:ss:l")} port=${t}`);const r=new d.Server({port:t});c(async()=>{if(e.runtimeConnection)return!0},n,1e3).catch(t=>{throw Error("Failed to connect to runtime, please make sure the project is running")}),r.on("connection",(function(t){s("automator:runtime")(h("yyyy-mm-dd HH:MM:ss:l")+" connected");const n=new b(new C(t),e,"runtime");e.setRuntimeConnection(n),o(n)})),e.setRuntimeServer(r)})}}const D=require("qrcode-terminal");require("qrcode-reader");async function T(t,e){const[n,s]=function(t){return P(t)?[!0,[t]]:[!1,t]}(e),o=await t(s);return n?o[0]:o} /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use @@ -12,4 +12,4 @@ MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. -***************************************************************************** */function I(t,e,n,s){var o,i=arguments.length,r=i<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,n,s);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(r=(i<3?o(r):i>3?o(e,n,r):o(e,n))||r);return i>3&&r&&Object.defineProperty(e,n,r),r}var A,x;function R(t,e){const n=e.value;return e.value=async function(e){return(await(null==n?void 0:n.call(this,e)))(t)},e}function S(t,e,n){return R(A.RUNTIME,n)}function j(t,e,n){return R(A.DEVTOOL,n)}!function(t){t.RUNTIME="runtime",t.DEVTOOL="devtool"}(A||(A={}));class q{constructor(t){this.puppet=t}invoke(t,e){return async n=>this.puppet.devtoolConnection?(n===A.DEVTOOL?this.puppet.devtoolConnection:this.puppet.runtimeConnection).send(t,e):this.puppet.runtimeConnection.send(t,e)}on(t,e){this.puppet.on(t,e)}}class $ extends q{constructor(t,e){super(t),this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId,this.videoId=e.videoId}async getData(t){return this.invokeMethod("Element.getData",t)}async setData(t){return this.invokeMethod("Element.setData",t)}async callMethod(t){return this.invokeMethod("Element.callMethod",t)}async getElement(t){return this.invokeMethod("Element.getElement",t)}async getElements(t){return this.invokeMethod("Element.getElements",t)}async getOffset(){return this.invokeMethod("Element.getOffset")}async getHTML(t){return this.invokeMethod("Element.getHTML",t)}async getAttributes(t){return this.invokeMethod("Element.getAttributes",t)}async getStyles(t){return this.invokeMethod("Element.getStyles",t)}async getDOMProperties(t){return this.invokeMethod("Element.getDOMProperties",t)}async getProperties(t){return this.invokeMethod("Element.getProperties",t)}async tap(){return this.invokeMethod("Element.tap")}async touchstart(t){return this.invokeMethod("Element.touchstart",t)}async touchmove(t){return this.invokeMethod("Element.touchmove",t)}async touchend(t){return this.invokeMethod("Element.touchend",t)}async triggerEvent(t){return this.invokeMethod("Element.triggerEvent",t)}async callFunction(t){return this.invokeMethod("Element.callFunction",t)}async callContextMethod(t){return this.invokeMethod("Element.callContextMethod",t)}invokeMethod(t,e={}){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.invoke(t,e)}}I([S],$.prototype,"getData",null),I([S],$.prototype,"setData",null),I([S],$.prototype,"callMethod",null),I([j],$.prototype,"getElement",null),I([j],$.prototype,"getElements",null),I([j],$.prototype,"getOffset",null),I([j],$.prototype,"getHTML",null),I([j],$.prototype,"getAttributes",null),I([j],$.prototype,"getStyles",null),I([j],$.prototype,"getDOMProperties",null),I([j],$.prototype,"getProperties",null),I([j],$.prototype,"tap",null),I([j],$.prototype,"touchstart",null),I([j],$.prototype,"touchmove",null),I([j],$.prototype,"touchend",null),I([j],$.prototype,"triggerEvent",null),I([j],$.prototype,"callFunction",null),I([j],$.prototype,"callContextMethod",null);class O{constructor(t,e,n){this.puppet=t,this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId||null,this.videoId=e.videoId||null,this.tagName=e.tagName,this.elementMap=n,"body"===this.tagName&&(this.tagName="page"),this.api=new $(t,e)}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({},e,{pageId:this.pageId}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(t=>O.create(this.puppet,Object.assign({},t,{pageId:this.pageId}),this.elementMap))}async size(){const[t,e]=await this.domProperty(["offsetWidth","offsetHeight"]);return{width:t,height:e}}async offset(){return this.api.getOffset()}async text(){return this.domProperty("innerText")}async attribute(t){if(!P(t))throw Error("name must be a string");return(await this.api.getAttributes({names:[t]})).attributes[0]}async value(){return this.property("value")}async property(t){if(!P(t))throw Error("name must be a string");if(this.puppet.checkProperty){let e=this.publicProps;if(e||(this.publicProps=e=await this._property("__propPublic")),!e[t])throw Error(`${this.tagName}.${t} not exists`)}return this._property(t)}async html(){return(await this.api.getHTML({type:"inner"})).html}async outerHtml(){return(await this.api.getHTML({type:"outer"})).html}async style(t){if(!P(t))throw Error("name must be a string");return(await this.api.getStyles({names:[t]})).styles[0]}async tap(){return this.api.tap()}async longpress(){return await this.touchstart(),await p(350),this.touchend()}async trigger(t,e){const n={type:t};return k(e)||(n.detail=e),this.api.triggerEvent(n)}async touchstart(t){return this.api.touchstart(t)}async touchmove(t){return this.api.touchmove(t)}async touchend(t){return this.api.touchend(t)}async domProperty(t){return D(async t=>(await this.api.getDOMProperties({names:t})).properties,t)}_property(t){return D(async t=>(await this.api.getProperties({names:t})).properties,t)}send(t,e){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.puppet.send(t,e)}async callFunction(t,...e){return(await this.api.callFunction({functionName:t,args:e})).result}static create(t,e,n){let s,o=n.get(e.elementId);if(o)return o;if(e.nodeId)s=F;else switch(e.tagName){case"input":s=N;break;case"textarea":s=L;break;case"scroll-view":s=U;break;case"swiper":s=H;break;case"movable-view":s=B;break;case"switch":s=_;break;case"slider":s=W;break;case"video":s=V;break;default:s=O}return o=new s(t,e,n),n.set(e.elementId,o),o}}class F extends O{async setData(t){return this.api.setData({data:t})}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}}class N extends O{async input(t){return this.callFunction("input.input",t)}}class L extends O{async input(t){return this.callFunction("textarea.input",t)}}class U extends O{async scrollTo(t,e){return this.callFunction("scroll-view.scrollTo",t,e)}async property(t){return"scrollTop"===t?this.callFunction("scroll-view.scrollTop"):"scrollLeft"===t?this.callFunction("scroll-view.scrollLeft"):super.property(t)}async scrollWidth(){return this.callFunction("scroll-view.scrollWidth")}async scrollHeight(){return this.callFunction("scroll-view.scrollHeight")}}class H extends O{async swipeTo(t){return this.callFunction("swiper.swipeTo",t)}}class B extends O{async moveTo(t,e){return this.callFunction("movable-view.moveTo",t,e)}async property(t){return"x"===t?this._property("_translateX"):"y"===t?this._property("_translateY"):super.property(t)}}class _ extends O{async tap(){return this.callFunction("switch.tap")}}class W extends O{async slideTo(t){return this.callFunction("slider.slideTo",t)}}class V extends O{async callContextMethod(t,...e){return this.api.callContextMethod({method:t,args:e})}}class z extends q{constructor(t,e){super(t),this.id=e.id}async getData(t){return this.invokeMethod("Page.getData",t)}async setData(t){return this.invokeMethod("Page.setData",t)}async callMethod(t){return this.invokeMethod("Page.callMethod",t)}async getElement(t){return this.invokeMethod("Page.getElement",t)}async getElements(t){return this.invokeMethod("Page.getElements",t)}async getWindowProperties(t){return this.invokeMethod("Page.getWindowProperties",t)}invokeMethod(t,e={}){return e.pageId=this.id,this.invoke(t,e)}}I([S],z.prototype,"getData",null),I([S],z.prototype,"setData",null),I([S],z.prototype,"callMethod",null),I([j],z.prototype,"getElement",null),I([j],z.prototype,"getElements",null),I([j],z.prototype,"getWindowProperties",null);class G{constructor(t,e){this.puppet=t,this.id=e.id,this.path=e.path,this.query=e.query,this.elementMap=new Map,this.api=new z(t,e)}async waitFor(t){return E(t)?await p(t):w(t)?c(t):P(t)?c(async()=>(await this.$$(t)).length>0):void 0}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(e=>O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap))}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async setData(t){return this.api.setData({data:t})}async size(){const[t,e]=await this.windowProperty(["document.documentElement.scrollWidth","document.documentElement.scrollHeight"]);return{width:t,height:e}}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}async scrollTop(){return this.windowProperty("document.documentElement.scrollTop")}async windowProperty(t){const e=P(t);e&&(t=[t]);const{properties:n}=await this.api.getWindowProperties({names:t});return e?n[0]:n}static create(t,e,n){let s=n.get(e.id);return s||(s=new G(t,e),n.set(e.id,s),s)}}class J extends q{async getPageStack(){return this.invoke("App.getPageStack")}async callUniMethod(t){return this.invoke("App.callUniMethod",t)}async getCurrentPage(){return this.invoke("App.getCurrentPage")}async mockUniMethod(t){return this.invoke("App.mockUniMethod",t)}async callFunction(t){return this.invoke("App.callFunction",t)}async captureScreenshot(){return this.invoke("App.captureScreenshot")}async exit(){return this.invoke("App.exit")}async addBinding(t){return this.invoke("App.addBinding",t)}async enableLog(){return this.invoke("App.enableLog")}onLogAdded(t){return this.on("App.logAdded",t)}onBindingCalled(t){return this.on("App.bindingCalled",t)}onExceptionThrown(t){return this.on("App.exceptionThrown",t)}}I([S],J.prototype,"getPageStack",null),I([S],J.prototype,"callUniMethod",null),I([S],J.prototype,"getCurrentPage",null),I([j],J.prototype,"mockUniMethod",null),I([j],J.prototype,"callFunction",null),I([j],J.prototype,"captureScreenshot",null),I([j],J.prototype,"exit",null),I([j],J.prototype,"addBinding",null),I([j],J.prototype,"enableLog",null);class X extends q{async getInfo(){return this.invoke("Tool.getInfo")}async enableRemoteDebug(t){return this.invoke("Tool.enableRemoteDebug")}async close(){return this.invoke("Tool.close")}async getTestAccounts(){return this.invoke("Tool.getTestAccounts")}onRemoteDebugConnected(t){this.puppet.once("Tool.onRemoteDebugConnected",t),this.puppet.once("Tool.onPreviewConnected",t)}}function Y(t){return new Promise(e=>setTimeout(e,t))}I([j],X.prototype,"getInfo",null),I([j],X.prototype,"enableRemoteDebug",null),I([j],X.prototype,"close",null),I([j],X.prototype,"getTestAccounts",null),function(t){t.CLOSE="close",t.DISCONNECT="disconnect"}(x||(x={}));class K extends m.EventEmitter{constructor(t,e){super(),this.puppet=t,this.options=e,this.pageMap=new Map,this.appBindings=new Map,this.appApi=new J(t),this.toolApi=new X(t),this.appApi.onLogAdded(t=>{this.emit("console",t)}),this.appApi.onBindingCalled(({name:t,args:e})=>{try{const n=this.appBindings.get(t);n&&n(...e)}catch(t){}}),this.appApi.onExceptionThrown(t=>{this.emit("exception",t)})}async pageStack(){return(await this.appApi.getPageStack()).pageStack.map(t=>G.create(this.puppet,t,this.pageMap))}async navigateTo(t){return this.changeRoute("navigateTo",t)}async redirectTo(t){return this.changeRoute("redirectTo",t)}async navigateBack(){return this.changeRoute("navigateBack")}async reLaunch(t){return this.changeRoute("reLaunch",t)}async switchTab(t){return this.changeRoute("switchTab",t)}async currentPage(){const{id:t,path:e,query:n}=await this.appApi.getCurrentPage();return G.create(this.puppet,{id:t,path:e,query:n},this.pageMap)}async systemInfo(){return this.callUniMethod("getSystemInfoSync")}async callUniMethod(t,...e){return(await this.appApi.callUniMethod({method:t,args:e})).result}async mockUniMethod(t,e,...n){return w(e)||P(s=e)&&(s=f(s),M(s,"function")||M(s,"() =>"))?this.appApi.mockUniMethod({method:t,functionDeclaration:e.toString(),args:n}):this.appApi.mockUniMethod({method:t,result:e});var s}async restoreUniMethod(t){return this.appApi.mockUniMethod({method:t})}async evaluate(t,...e){return(await this.appApi.callFunction({functionDeclaration:t.toString(),args:e})).result}async pageScrollTo(t){await this.callUniMethod("pageScrollTo",{scrollTop:t,duration:0})}async close(){try{await this.appApi.exit()}catch(t){}await Y(1e3),this.puppet.disposeRuntimeServer(),await this.toolApi.close(),this.disconnect()}async teardown(){return this[this.options.teardown===x.DISCONNECT?x.DISCONNECT:x.CLOSE]()}async remote(t){if(!this.puppet.devtools.remote)return console.warn(`Failed to enable remote, ${this.puppet.devtools.name} is unimplemented`);const{qrCode:e}=await this.toolApi.enableRemoteDebug({auto:t});var n;e&&await(n=e,new Promise(t=>{T.generate(n,{small:!0},e=>{process.stdout.write(e),t()})}));const s=new Promise(t=>{this.toolApi.onRemoteDebugConnected(async()=>{await Y(1e3),t()})}),o=new Promise(t=>{this.puppet.setRemoteRuntimeConnectionCallback(()=>{t()})});return Promise.all([s,o])}disconnect(){this.puppet.dispose()}on(t,e){return"console"===t&&this.appApi.enableLog(),super.on(t,e),this}async exposeFunction(t,e){if(this.appBindings.has(t))throw Error(`Failed to expose function with name ${t}: already exists!`);this.appBindings.set(t,e),await this.appApi.addBinding({name:t})}async checkVersion(){}async screenshot(t){const{data:e}=await this.appApi.captureScreenshot();if(!(null==t?void 0:t.path))return e;await v.writeFile(t.path,e,"base64")}async testAccounts(){return(await this.toolApi.getTestAccounts()).accounts}async changeRoute(t,e){return await this.callUniMethod(t,{url:e}),await Y(3e3),this.currentPage()}}class Q{constructor(t){this.options=t}has(t){return!!this.options[t]}send(t,e,n){const s=this.options[e];if(!s)return Promise.reject(Error(`adapter for ${e} not found`));const o=s.reflect;return o?(s.params&&(n=s.params(n)),"function"==typeof o?o(t.send.bind(t),n):(e=o,t.send(e,n))):Promise.reject(Error(e+"'s reflect is required"))}}class Z extends m.EventEmitter{constructor(t,e){if(super(),this.target=e||require(`@dcloudio/uni-${t}/lib/uni.automator.js`),!this.target)throw Error("puppet is not provided");this.platform=t,this.adapter=new Q(this.target.adapter||{})}setRuntimeServer(t){this.wss=t}setRemoteRuntimeConnectionCallback(t){this.remoteRuntimeConnectionCallback=t}setRuntimeConnection(t){this.runtimeConnection=t,this.remoteRuntimeConnectionCallback&&(this.remoteRuntimeConnectionCallback(),this.remoteRuntimeConnectionCallback=null)}setDevtoolConnection(t){this.devtoolConnection=t}disposeRuntimeServer(){this.wss&&this.wss.close()}disposeRuntime(){this.runtimeConnection.dispose()}disposeDevtool(){this.devtoolConnection&&this.devtoolConnection.dispose()}dispose(){this.disposeRuntime(),this.disposeDevtool(),this.disposeRuntimeServer()}send(t,e){return this.runtimeConnection.send(t,e)}validateProject(t){const s=this.target.devtools.required;return!s||!s.find(s=>!e.existsSync(n.join(t,s)))}get checkProperty(){return"mp-weixin"===this.platform}get defaultPort(){return this.target.devtools.defaultPort}get devtools(){return this.target.devtools}get mode(){const t=this.target.mode;return t||("production"===process.env.NODE_ENV?"build":"dev")}}const tt=s("automator:compiler"),et=/The\s+(.*)\s+directory is ready/;class nt{constructor(t){this.puppet=t}compile(t){const e=this.puppet.mode,s=this.puppet.platform;let i=t.silent;const r=t.port,c=t.host,l=process.env.UNI_NPM_PATH||"npm",p=`${e}:${s}`,u=t.projectPath,h=["run",p,"--","--auto-port",a(r)];c&&(h.push("--auto-host"),h.push(c));const d={cwd:t.cliPath||t.projectPath,env:process.env};return new Promise((t,r)=>{const a=function(o){const r=o.toString().trim();if(!i&&console.log(r),r.includes("App running at:"))t({path:""});else if(r.includes("DONE Build complete")){let o=`unpackage/dist/${e}/${s}`;const a=r.match(et);a&&a.length>1&&(o=a[1]),i=!0,c.kill("SIGTERM"),t({path:n.join(u,o)})}};tt(`${l} ${h.join(" ")}`);const c=o.spawn(l,h,d);c.on("error",(function(t){r(t)})),c.stdout.on("data",a),c.stderr.on("data",a)})}}const st=s("automator:devtool"),ot=1e5;function it(t){throw Error(t)}class rt{async launch(t){const e=t.devtools||{};this.puppet=new Z(t.platform,t.puppet);const{port:n,cliPath:o,projectPath:i}=await this.validate(t);let r;this.puppet.devtools.automator&&(r=await this.validateDevtools(e));let a=i;if(!1!==t.compile){this.compiler=new nt(this.puppet);const e=await this.compiler.compile({host:r&&r.host,port:n,cliPath:o,projectPath:i,silent:!!t.silent});e.path&&(a=e.path)}const c=[];return c.push(this.createRuntimeConnection(n,e)),r&&c.push(this.createDevtoolConnection(a,r)),new Promise((t,n)=>{Promise.all(c).then(([n,o])=>{this.puppet.setRuntimeConnection(n),this.puppet.setDevtoolConnection(o),s("automator:program")("ready");const i=e.teardown||x.DISCONNECT;t(new K(this.puppet,{teardown:i}))}).catch(t=>n(t))})}async connectTool(t){let e;try{e=await b.createDevtoolConnection(t.wsEndpoint,this.puppet)}catch(e){throw Error(`Failed connecting to ${t.wsEndpoint}, check if target project window is opened with automation enabled`)}return e}validateCliPath(t){try{const e=require(n.join(t,"package.json"));if(e.devDependencies&&e.devDependencies["@dcloudio/vue-cli-plugin-uni"])return!0}catch(t){}}resolveCliPath(t){return t?this.validateCliPath(t)?t:void it(`Cli ${t} doesn't exist`):t}resolveProjectPath(t,s){if(t||(t=process.cwd()),u(t)&&(t=n.resolve(t)),e.existsSync(t)||it(`Project path ${t} doesn't exist`),!1===s.compile&&!this.puppet.validateProject(t)){const e=n.join(t,"dist/"+this.puppet.mode+"/"+this.puppet.platform);if(this.puppet.validateProject(e))return e;s.compile=!0}return t}async resolvePort(t,e){const n=await r(t||e);return t&&n!==t&&it(`Port ${t} is in use, please specify another port`),n}async validate(t){const e=this.resolveProjectPath(t.projectPath,t);let n=t.cliPath;return!1!==t.compile&&(n=this.resolveCliPath(t.cliPath||""),!n&&(n=this.resolveCliPath(e))),{port:await this.resolvePort(t.port||9520),cliPath:n,projectPath:e,platform:t.platform}}resolveDevtoolsPath(t){const n=this.puppet.devtools.paths.slice(0);t&&n.unshift(t);for(const t of n)if(e.existsSync(t))return t;it(this.puppet.devtools.name+" not found, please specify devtools.cliPath option")}async validateDevtools(t={}){const e=this.resolveDevtoolsPath(t.cliPath);let n=t.port||this.puppet.defaultPort;if(!1!==t.launch)try{n=await this.resolvePort(n)}catch(e){t.launch=!1}else{n===await r(n)&&(t.launch=!0)}return Object.assign(Object.assign({},t),{port:n,cliPath:e})}async createRuntimeConnection(t,e){return b.createRuntimeConnection(t,this.puppet,e.timeout||ot)}async createDevtoolConnection(t,e){const{port:n,cliPath:s,timeout:o=ot,cwd:r="",account:u="",args:d=[],launch:m=!0}=e;let y=!1,g=!1;if(!1!==m){const e={detached:!0,stdio:"ignore"};r&&(e.cwd=r);let o=l(d,["--auto",t,"--auto-port",a(n)]);u&&(o=l(o,["--auto-account",u]));try{st("%s %o %o",s,o,e);const t=i.spawn(s,o,e);t.on("error",t=>{y=!0}),t.on("exit",()=>{setTimeout(()=>{g=!0},15e3)}),t.unref()}catch(t){y=!1}}else setTimeout(()=>{g=!0},15e3);const v=await c(async()=>{try{if(y||g)return!0;return await this.connectTool({wsEndpoint:"ws://127.0.0.1:"+n})}catch(t){}},o,1e3);return y&&it(`Failed to launch ${this.puppet.devtools.name}, please make sure cliPath is correctly specified`),g&&it(`Failed to launch ${this.puppet.devtools.name} , please make sure http port is open`),await p(5e3),st(h("yyyy-mm-dd HH:MM:ss:l")+" connected"),!1===m&&this.initRuntimeAutomator(v),v}async initRuntimeAutomator(t){return st("initRuntimeAutomator"),t.send("App.callUniMethod",{method:"$$initRuntimeAutomator",args:[]})}}module.exports=class{constructor(){this.launcher=new rt}async launch(t){return this.launcher.launch(t)}}; +***************************************************************************** */function I(t,e,n,s){var o,i=arguments.length,r=i<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,n,s);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(r=(i<3?o(r):i>3?o(e,n,r):o(e,n))||r);return i>3&&r&&Object.defineProperty(e,n,r),r}var A,x;function R(t,e){const n=e.value;return e.value=async function(e){return(await(null==n?void 0:n.call(this,e)))(t)},e}function S(t,e,n){return R(A.RUNTIME,n)}function j(t,e,n){return R(A.DEVTOOL,n)}!function(t){t.RUNTIME="runtime",t.DEVTOOL="devtool"}(A||(A={}));class q{constructor(t){this.puppet=t}invoke(t,e){return async n=>this.puppet.devtoolConnection?(n===A.DEVTOOL?this.puppet.devtoolConnection:this.puppet.runtimeConnection).send(t,e):this.puppet.runtimeConnection.send(t,e)}on(t,e){this.puppet.on(t,e)}}class $ extends q{constructor(t,e){super(t),this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId,this.videoId=e.videoId}async getData(t){return this.invokeMethod("Element.getData",t)}async setData(t){return this.invokeMethod("Element.setData",t)}async callMethod(t){return this.invokeMethod("Element.callMethod",t)}async getElement(t){return this.invokeMethod("Element.getElement",t)}async getElements(t){return this.invokeMethod("Element.getElements",t)}async getOffset(){return this.invokeMethod("Element.getOffset")}async getHTML(t){return this.invokeMethod("Element.getHTML",t)}async getAttributes(t){return this.invokeMethod("Element.getAttributes",t)}async getStyles(t){return this.invokeMethod("Element.getStyles",t)}async getDOMProperties(t){return this.invokeMethod("Element.getDOMProperties",t)}async getProperties(t){return this.invokeMethod("Element.getProperties",t)}async tap(){return this.invokeMethod("Element.tap")}async touchstart(t){return this.invokeMethod("Element.touchstart",t)}async touchmove(t){return this.invokeMethod("Element.touchmove",t)}async touchend(t){return this.invokeMethod("Element.touchend",t)}async triggerEvent(t){return this.invokeMethod("Element.triggerEvent",t)}async callFunction(t){return this.invokeMethod("Element.callFunction",t)}async callContextMethod(t){return this.invokeMethod("Element.callContextMethod",t)}invokeMethod(t,e={}){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.invoke(t,e)}}I([S],$.prototype,"getData",null),I([S],$.prototype,"setData",null),I([S],$.prototype,"callMethod",null),I([j],$.prototype,"getElement",null),I([j],$.prototype,"getElements",null),I([j],$.prototype,"getOffset",null),I([j],$.prototype,"getHTML",null),I([j],$.prototype,"getAttributes",null),I([j],$.prototype,"getStyles",null),I([j],$.prototype,"getDOMProperties",null),I([j],$.prototype,"getProperties",null),I([j],$.prototype,"tap",null),I([j],$.prototype,"touchstart",null),I([j],$.prototype,"touchmove",null),I([j],$.prototype,"touchend",null),I([j],$.prototype,"triggerEvent",null),I([j],$.prototype,"callFunction",null),I([j],$.prototype,"callContextMethod",null);class O{constructor(t,e,n){this.puppet=t,this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId||null,this.videoId=e.videoId||null,this.tagName=e.tagName,this.elementMap=n,"body"===this.tagName&&(this.tagName="page"),this.api=new $(t,e)}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({},e,{pageId:this.pageId}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(t=>O.create(this.puppet,Object.assign({},t,{pageId:this.pageId}),this.elementMap))}async size(){const[t,e]=await this.domProperty(["offsetWidth","offsetHeight"]);return{width:t,height:e}}async offset(){return this.api.getOffset()}async text(){return this.domProperty("innerText")}async attribute(t){if(!P(t))throw Error("name must be a string");return(await this.api.getAttributes({names:[t]})).attributes[0]}async value(){return this.property("value")}async property(t){if(!P(t))throw Error("name must be a string");if(this.puppet.checkProperty){let e=this.publicProps;if(e||(this.publicProps=e=await this._property("__propPublic")),!e[t])throw Error(`${this.tagName}.${t} not exists`)}return this._property(t)}async html(){return(await this.api.getHTML({type:"inner"})).html}async outerHtml(){return(await this.api.getHTML({type:"outer"})).html}async style(t){if(!P(t))throw Error("name must be a string");return(await this.api.getStyles({names:[t]})).styles[0]}async tap(){return this.api.tap()}async longpress(){return await this.touchstart(),await p(350),this.touchend()}async trigger(t,e){const n={type:t};return k(e)||(n.detail=e),this.api.triggerEvent(n)}async touchstart(t){return this.api.touchstart(t)}async touchmove(t){return this.api.touchmove(t)}async touchend(t){return this.api.touchend(t)}async domProperty(t){return T(async t=>(await this.api.getDOMProperties({names:t})).properties,t)}_property(t){return T(async t=>(await this.api.getProperties({names:t})).properties,t)}send(t,e){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.puppet.send(t,e)}async callFunction(t,...e){return(await this.api.callFunction({functionName:t,args:e})).result}static create(t,e,n){let s,o=n.get(e.elementId);if(o)return o;if(e.nodeId)s=F;else switch(e.tagName){case"input":s=N;break;case"textarea":s=L;break;case"scroll-view":s=U;break;case"swiper":s=H;break;case"movable-view":s=B;break;case"switch":s=_;break;case"slider":s=W;break;case"video":s=V;break;default:s=O}return o=new s(t,e,n),n.set(e.elementId,o),o}}class F extends O{async setData(t){return this.api.setData({data:t})}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}}class N extends O{async input(t){return this.callFunction("input.input",t)}}class L extends O{async input(t){return this.callFunction("textarea.input",t)}}class U extends O{async scrollTo(t,e){return this.callFunction("scroll-view.scrollTo",t,e)}async property(t){return"scrollTop"===t?this.callFunction("scroll-view.scrollTop"):"scrollLeft"===t?this.callFunction("scroll-view.scrollLeft"):super.property(t)}async scrollWidth(){return this.callFunction("scroll-view.scrollWidth")}async scrollHeight(){return this.callFunction("scroll-view.scrollHeight")}}class H extends O{async swipeTo(t){return this.callFunction("swiper.swipeTo",t)}}class B extends O{async moveTo(t,e){return this.callFunction("movable-view.moveTo",t,e)}async property(t){return"x"===t?this._property("_translateX"):"y"===t?this._property("_translateY"):super.property(t)}}class _ extends O{async tap(){return this.callFunction("switch.tap")}}class W extends O{async slideTo(t){return this.callFunction("slider.slideTo",t)}}class V extends O{async callContextMethod(t,...e){return this.api.callContextMethod({method:t,args:e})}}class z extends q{constructor(t,e){super(t),this.id=e.id}async getData(t){return this.invokeMethod("Page.getData",t)}async setData(t){return this.invokeMethod("Page.setData",t)}async callMethod(t){return this.invokeMethod("Page.callMethod",t)}async getElement(t){return this.invokeMethod("Page.getElement",t)}async getElements(t){return this.invokeMethod("Page.getElements",t)}async getWindowProperties(t){return this.invokeMethod("Page.getWindowProperties",t)}invokeMethod(t,e={}){return e.pageId=this.id,this.invoke(t,e)}}I([S],z.prototype,"getData",null),I([S],z.prototype,"setData",null),I([S],z.prototype,"callMethod",null),I([j],z.prototype,"getElement",null),I([j],z.prototype,"getElements",null),I([j],z.prototype,"getWindowProperties",null);class G{constructor(t,e){this.puppet=t,this.id=e.id,this.path=e.path,this.query=e.query,this.elementMap=new Map,this.api=new z(t,e)}async waitFor(t){return E(t)?await p(t):w(t)?c(t):P(t)?c(async()=>(await this.$$(t)).length>0):void 0}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(e=>O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap))}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async setData(t){return this.api.setData({data:t})}async size(){const[t,e]=await this.windowProperty(["document.documentElement.scrollWidth","document.documentElement.scrollHeight"]);return{width:t,height:e}}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}async scrollTop(){return this.windowProperty("document.documentElement.scrollTop")}async windowProperty(t){const e=P(t);e&&(t=[t]);const{properties:n}=await this.api.getWindowProperties({names:t});return e?n[0]:n}static create(t,e,n){let s=n.get(e.id);return s||(s=new G(t,e),n.set(e.id,s),s)}}class J extends q{async getPageStack(){return this.invoke("App.getPageStack")}async callUniMethod(t){return this.invoke("App.callUniMethod",t)}async getCurrentPage(){return this.invoke("App.getCurrentPage")}async mockUniMethod(t){return this.invoke("App.mockUniMethod",t)}async callFunction(t){return this.invoke("App.callFunction",t)}async captureScreenshot(){return this.invoke("App.captureScreenshot")}async exit(){return this.invoke("App.exit")}async addBinding(t){return this.invoke("App.addBinding",t)}async enableLog(){return this.invoke("App.enableLog")}onLogAdded(t){return this.on("App.logAdded",t)}onBindingCalled(t){return this.on("App.bindingCalled",t)}onExceptionThrown(t){return this.on("App.exceptionThrown",t)}}I([S],J.prototype,"getPageStack",null),I([S],J.prototype,"callUniMethod",null),I([S],J.prototype,"getCurrentPage",null),I([j],J.prototype,"mockUniMethod",null),I([j],J.prototype,"callFunction",null),I([j],J.prototype,"captureScreenshot",null),I([j],J.prototype,"exit",null),I([j],J.prototype,"addBinding",null),I([j],J.prototype,"enableLog",null);class X extends q{async getInfo(){return this.invoke("Tool.getInfo")}async enableRemoteDebug(t){return this.invoke("Tool.enableRemoteDebug")}async close(){return this.invoke("Tool.close")}async getTestAccounts(){return this.invoke("Tool.getTestAccounts")}onRemoteDebugConnected(t){this.puppet.once("Tool.onRemoteDebugConnected",t),this.puppet.once("Tool.onPreviewConnected",t)}}function Y(t){return new Promise(e=>setTimeout(e,t))}I([j],X.prototype,"getInfo",null),I([j],X.prototype,"enableRemoteDebug",null),I([j],X.prototype,"close",null),I([j],X.prototype,"getTestAccounts",null),function(t){t.CLOSE="close",t.DISCONNECT="disconnect"}(x||(x={}));class K extends m.EventEmitter{constructor(t,e){super(),this.puppet=t,this.options=e,this.pageMap=new Map,this.appBindings=new Map,this.appApi=new J(t),this.toolApi=new X(t),this.appApi.onLogAdded(t=>{this.emit("console",t)}),this.appApi.onBindingCalled(({name:t,args:e})=>{try{const n=this.appBindings.get(t);n&&n(...e)}catch(t){}}),this.appApi.onExceptionThrown(t=>{this.emit("exception",t)})}async pageStack(){return(await this.appApi.getPageStack()).pageStack.map(t=>G.create(this.puppet,t,this.pageMap))}async navigateTo(t){return this.changeRoute("navigateTo",t)}async redirectTo(t){return this.changeRoute("redirectTo",t)}async navigateBack(){return this.changeRoute("navigateBack")}async reLaunch(t){return this.changeRoute("reLaunch",t)}async switchTab(t){return this.changeRoute("switchTab",t)}async currentPage(){const{id:t,path:e,query:n}=await this.appApi.getCurrentPage();return G.create(this.puppet,{id:t,path:e,query:n},this.pageMap)}async systemInfo(){return this.callUniMethod("getSystemInfoSync")}async callUniMethod(t,...e){return(await this.appApi.callUniMethod({method:t,args:e})).result}async mockUniMethod(t,e,...n){return w(e)||P(s=e)&&(s=f(s),M(s,"function")||M(s,"() =>"))?this.appApi.mockUniMethod({method:t,functionDeclaration:e.toString(),args:n}):this.appApi.mockUniMethod({method:t,result:e});var s}async restoreUniMethod(t){return this.appApi.mockUniMethod({method:t})}async evaluate(t,...e){return(await this.appApi.callFunction({functionDeclaration:t.toString(),args:e})).result}async pageScrollTo(t){await this.callUniMethod("pageScrollTo",{scrollTop:t,duration:0})}async close(){try{await this.appApi.exit()}catch(t){}await Y(1e3),this.puppet.disposeRuntimeServer(),await this.toolApi.close(),this.disconnect()}async teardown(){return this[this.options.teardown===x.DISCONNECT?x.DISCONNECT:x.CLOSE]()}async remote(t){if(!this.puppet.devtools.remote)return console.warn(`Failed to enable remote, ${this.puppet.devtools.name} is unimplemented`);const{qrCode:e}=await this.toolApi.enableRemoteDebug({auto:t});var n;e&&await(n=e,new Promise(t=>{D.generate(n,{small:!0},e=>{process.stdout.write(e),t()})}));const s=new Promise(t=>{this.toolApi.onRemoteDebugConnected(async()=>{await Y(1e3),t()})}),o=new Promise(t=>{this.puppet.setRemoteRuntimeConnectionCallback(()=>{t()})});return Promise.all([s,o])}disconnect(){this.puppet.dispose()}on(t,e){return"console"===t&&this.appApi.enableLog(),super.on(t,e),this}async exposeFunction(t,e){if(this.appBindings.has(t))throw Error(`Failed to expose function with name ${t}: already exists!`);this.appBindings.set(t,e),await this.appApi.addBinding({name:t})}async checkVersion(){}async screenshot(t){const{data:e}=await this.appApi.captureScreenshot();if(!(null==t?void 0:t.path))return e;await v.writeFile(t.path,e,"base64")}async testAccounts(){return(await this.toolApi.getTestAccounts()).accounts}async changeRoute(t,e){return await this.callUniMethod(t,{url:e}),await Y(3e3),this.currentPage()}}class Q{constructor(t){this.options=t}has(t){return!!this.options[t]}send(t,e,n){const s=this.options[e];if(!s)return Promise.reject(Error(`adapter for ${e} not found`));const o=s.reflect;return o?(s.params&&(n=s.params(n)),"function"==typeof o?o(t.send.bind(t),n):(e=o,t.send(e,n))):Promise.reject(Error(e+"'s reflect is required"))}}class Z extends m.EventEmitter{constructor(t,e){if(super(),this.target=e||require(`@dcloudio/uni-${t}/lib/uni.automator.js`),!this.target)throw Error("puppet is not provided");this.platform=t,this.adapter=new Q(this.target.adapter||{})}setRuntimeServer(t){this.wss=t}setRemoteRuntimeConnectionCallback(t){this.remoteRuntimeConnectionCallback=t}setRuntimeConnection(t){this.runtimeConnection=t,this.remoteRuntimeConnectionCallback&&(this.remoteRuntimeConnectionCallback(),this.remoteRuntimeConnectionCallback=null)}setDevtoolConnection(t){this.devtoolConnection=t}disposeRuntimeServer(){this.wss&&this.wss.close()}disposeRuntime(){this.runtimeConnection.dispose()}disposeDevtool(){this.devtoolConnection&&this.devtoolConnection.dispose()}dispose(){this.disposeRuntime(),this.disposeDevtool(),this.disposeRuntimeServer()}send(t,e){return this.runtimeConnection.send(t,e)}validateProject(t){const s=this.target.devtools.required;return!s||!s.find(s=>!e.existsSync(n.join(t,s)))}validateDevtools(t){const e=this.target.devtools.validate;e&&e()}createDevtools(){const t=this.target.devtools.create;return t?t():Promise.resolve()}get checkProperty(){return"mp-weixin"===this.platform}get defaultPort(){return this.target.devtools.defaultPort}get devtools(){return this.target.devtools}get mode(){const t=this.target.mode;return t||("production"===process.env.NODE_ENV?"build":"dev")}}const tt=s("automator:compiler"),et=/The\s+(.*)\s+directory is ready/;class nt{constructor(t){this.puppet=t}compile(t){const e=this.puppet.mode,s=this.puppet.platform;let i=t.silent;const r=t.port,c=t.host,l=process.env.UNI_NPM_PATH||"npm",p=`${e}:${s}`,u=t.projectPath,h=["run",p,"--","--auto-port",a(r)];c&&(h.push("--auto-host"),h.push(c));const d={cwd:t.cliPath||t.projectPath,env:process.env};return new Promise((t,r)=>{const a=function(o){const r=o.toString().trim();if(!i&&console.log(r),r.includes("App running at:"))t({path:""});else if(r.includes("DONE Build complete")){let o=`unpackage/dist/${e}/${s}`;const a=r.match(et);a&&a.length>1&&(o=a[1]),i=!0,c.kill("SIGTERM"),t({path:n.join(u,o)})}};tt(`${l} ${h.join(" ")}`);const c=o.spawn(l,h,d);c.on("error",(function(t){r(t)})),c.stdout.on("data",a),c.stderr.on("data",a)})}}const st=s("automator:devtool"),ot=1e5;function it(t){throw Error(t)}class rt{async launch(t){const e=t[t.platform]||{};this.puppet=new Z(t.platform,e.puppet);const{port:n,cliPath:o,projectPath:i}=await this.validate(t);let r;this.puppet.devtools.automator&&(r=await this.validateDevtools(e));let a=i;if(!1!==t.compile){this.compiler=new nt(this.puppet);const e=await this.compiler.compile({host:t.host,port:n,cliPath:o,projectPath:i,silent:!!t.silent});e.path&&(a=e.path)}const c=[];return c.push(this.createRuntimeConnection(n,t.timeout||ot)),r&&c.push(this.createDevtoolConnection(a,r)),new Promise((t,n)=>{Promise.all(c).then(([n,o])=>{this.puppet.setRuntimeConnection(n),this.puppet.setDevtoolConnection(o),s("automator:program")("ready");const i=e.teardown||x.DISCONNECT;t(new K(this.puppet,{teardown:i}))}).catch(t=>n(t))})}async connectTool(t){let e;try{e=await b.createDevtoolConnection(t.wsEndpoint,this.puppet)}catch(e){throw Error(`Failed connecting to ${t.wsEndpoint}, check if target project window is opened with automation enabled`)}return e}validateCliPath(t){try{const e=require(n.join(t,"package.json"));if(e.devDependencies&&e.devDependencies["@dcloudio/vue-cli-plugin-uni"])return!0}catch(t){}}resolveCliPath(t){return t?this.validateCliPath(t)?t:void it(`Cli ${t} doesn't exist`):t}resolveProjectPath(t,s){if(t||(t=process.cwd()),u(t)&&(t=n.resolve(t)),e.existsSync(t)||it(`Project path ${t} doesn't exist`),!1===s.compile&&!this.puppet.validateProject(t)){const e=n.join(t,"dist/"+this.puppet.mode+"/"+this.puppet.platform);if(this.puppet.validateProject(e))return e;s.compile=!0}return t}async resolvePort(t,e){const n=await r(t||e);return t&&n!==t&&it(`Port ${t} is in use, please specify another port`),n}async validate(t){const e=this.resolveProjectPath(t.projectPath,t);let n=t.cliPath;return!1!==t.compile&&(n=this.resolveCliPath(t.cliPath||""),!n&&(n=this.resolveCliPath(e))),{port:await this.resolvePort(t.port||9520),cliPath:n,projectPath:e}}resolveDevtoolsPath(t){const n=this.puppet.devtools.paths.slice(0);t&&n.unshift(t);for(const t of n)if(e.existsSync(t))return t;it(this.puppet.devtools.name+" not found, please specify devtools.cliPath option")}async validateDevtools(t){const e=this.resolveDevtoolsPath(t.cliPath);let n=t.port||this.puppet.defaultPort;if(!1!==t.launch)try{n=await this.resolvePort(n)}catch(e){t.launch=!1}else{n===await r(n)&&(t.launch=!0)}return Object.assign(Object.assign({},t),{port:n,cliPath:e})}async createRuntimeConnection(t,e){return b.createRuntimeConnection(t,this.puppet,e)}async createDevtoolConnection(t,e){const{port:n,cliPath:s,timeout:o=ot,cwd:r="",account:u="",args:d=[],launch:m=!0}=e;let y=!1,g=!1;if(!1!==m){const e={detached:!0,stdio:"ignore"};r&&(e.cwd=r);let o=l(d,["--auto",t,"--auto-port",a(n)]);u&&(o=l(o,["--auto-account",u]));try{st("%s %o %o",s,o,e);const t=i.spawn(s,o,e);t.on("error",t=>{y=!0}),t.on("exit",()=>{setTimeout(()=>{g=!0},15e3)}),t.unref()}catch(t){y=!1}}else setTimeout(()=>{g=!0},15e3);const v=await c(async()=>{try{if(y||g)return!0;return await this.connectTool({wsEndpoint:"ws://127.0.0.1:"+n})}catch(t){}},o,1e3);return y&&it(`Failed to launch ${this.puppet.devtools.name}, please make sure cliPath is correctly specified`),g&&it(`Failed to launch ${this.puppet.devtools.name} , please make sure http port is open`),await p(5e3),st(h("yyyy-mm-dd HH:MM:ss:l")+" connected"),!1===m&&this.initRuntimeAutomator(v),v}async initRuntimeAutomator(t){return st("initRuntimeAutomator"),t.send("App.callUniMethod",{method:"$$initRuntimeAutomator",args:[]})}}module.exports=class{constructor(){this.launcher=new rt}async launch(t){return this.launcher.launch(t)}}; diff --git a/packages/vue-cli-plugin-uni/commands/build.js b/packages/vue-cli-plugin-uni/commands/build.js index dc3f298b3..470a2171c 100644 --- a/packages/vue-cli-plugin-uni/commands/build.js +++ b/packages/vue-cli-plugin-uni/commands/build.js @@ -35,17 +35,7 @@ module.exports = (api, options) => { } } - const port = args['auto-port'] || process.env.UNI_AUTOMATOR_PORT - if (port) { - const host = args['auto-host'] || process.env.UNI_AUTOMATOR_HOST || '0.0.0.0' - const prepareURLs = require('@vue/cli-service/lib/util/prepareURLs') - const urls = prepareURLs('ws', host, port, '') - if (urls.lanUrlForConfig) { - process.env.UNI_AUTOMATOR_WS_ENDPOINT = 'ws://' + urls.lanUrlForConfig + ':' + port - } else { - process.env.UNI_AUTOMATOR_WS_ENDPOINT = urls.localUrlForBrowser - } - } + require('./util').initAutomator(args) args.entry = args.entry || args._[0] diff --git a/packages/vue-cli-plugin-uni/commands/serve.js b/packages/vue-cli-plugin-uni/commands/serve.js index 45191829e..03dd95c7a 100644 --- a/packages/vue-cli-plugin-uni/commands/serve.js +++ b/packages/vue-cli-plugin-uni/commands/serve.js @@ -21,10 +21,14 @@ module.exports = (api, options) => { '--host': `specify host (default: ${defaults.host})`, '--port': `specify port (default: ${defaults.port})`, '--https': `use https (default: ${defaults.https})`, - '--public': 'specify the public network URL for the HMR client' + '--public': 'specify the public network URL for the HMR client', + '--auto-host': 'specify automator host', + '--auto-port': 'specify automator port' } }, async function serve (args) { - info('Starting development server...') + info('Starting development server...') + + require('./util').initAutomator(args) // although this is primarily a dev server, it is possible that we // are running it in a mode with a production env, e.g. in E2E tests. diff --git a/packages/vue-cli-plugin-uni/commands/util.js b/packages/vue-cli-plugin-uni/commands/util.js new file mode 100644 index 000000000..579f0594a --- /dev/null +++ b/packages/vue-cli-plugin-uni/commands/util.js @@ -0,0 +1,15 @@ +module.exports = { + initAutomator (args) { + const port = args['auto-port'] || process.env.UNI_AUTOMATOR_PORT + if (port) { + const host = args['auto-host'] || process.env.UNI_AUTOMATOR_HOST || '0.0.0.0' + const prepareURLs = require('@vue/cli-service/lib/util/prepareURLs') + const urls = prepareURLs('ws', host, port, '') + if (urls.lanUrlForConfig) { + process.env.UNI_AUTOMATOR_WS_ENDPOINT = 'ws://' + urls.lanUrlForConfig + ':' + port + } else { + process.env.UNI_AUTOMATOR_WS_ENDPOINT = urls.localUrlForBrowser + } + } + } +} diff --git a/packages/vue-cli-plugin-uni/lib/h5/index.js b/packages/vue-cli-plugin-uni/lib/h5/index.js index 12e062b20..cb9904420 100644 --- a/packages/vue-cli-plugin-uni/lib/h5/index.js +++ b/packages/vue-cli-plugin-uni/lib/h5/index.js @@ -116,7 +116,8 @@ module.exports = { loader: path.resolve(__dirname, '../../packages/wrap-loader'), options: { before: [ - beforeCode + statCode + getGlobalUsingComponentsCode() + beforeCode + require('../util').getAutomatorCode() + statCode + + getGlobalUsingComponentsCode() ] } }] @@ -179,4 +180,4 @@ module.exports = { require('./cssnano-options')(webpackConfig) } } -} +} diff --git a/packages/vue-cli-plugin-uni/lib/mp/index.js b/packages/vue-cli-plugin-uni/lib/mp/index.js index cf11d0b18..fdaa9914e 100644 --- a/packages/vue-cli-plugin-uni/lib/mp/index.js +++ b/packages/vue-cli-plugin-uni/lib/mp/index.js @@ -81,9 +81,6 @@ module.exports = { const beforeCode = 'import \'uni-pages\';' - const automator = `@dcloudio/uni-${process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM}/dist/automator` - const automatorCode = process.env.UNI_AUTOMATOR_WS_ENDPOINT ? `import '${automator}';` : '' - return { mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', entry () { @@ -112,7 +109,7 @@ module.exports = { loader: path.resolve(__dirname, '../../packages/wrap-loader'), options: { before: [ - beforeCode + automatorCode + statCode + beforeCode + require('../util').getAutomatorCode() + statCode ] } }, { @@ -200,4 +197,4 @@ module.exports = { webpackConfig.plugins.delete('preload') webpackConfig.plugins.delete('prefetch') } -} +} diff --git a/packages/vue-cli-plugin-uni/lib/util.js b/packages/vue-cli-plugin-uni/lib/util.js index 33adcb2bd..72091b883 100644 --- a/packages/vue-cli-plugin-uni/lib/util.js +++ b/packages/vue-cli-plugin-uni/lib/util.js @@ -12,5 +12,9 @@ module.exports = { }) } return partialIdentifier + }, + getAutomatorCode () { + const automator = `@dcloudio/uni-${process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM}/dist/automator` + return process.env.UNI_AUTOMATOR_WS_ENDPOINT ? `import '${automator}';` : '' } } -- GitLab