xhs-mp-core 2.0.31 → 2.0.32-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,8 +13,8 @@ export interface IRequestOpts {
13
13
  }
14
14
  export declare class BaseApi extends EventEmitter {
15
15
  core: Core;
16
+ axios: any;
16
17
  constructor(props: any);
17
- get axios(): import("axios").AxiosStatic;
18
18
  protected getProxyConfig(): false | {
19
19
  host: string;
20
20
  port: string;
@@ -86,7 +86,11 @@ export declare class UploadApi extends BaseApi {
86
86
  request(opts: IRequestOpts): Promise<any>;
87
87
  checkUploadAuthV1({ version }: IUploadCheckVersionParamsV1): Promise<any>;
88
88
  checkUploadAuthV2(opts: IUploadCheckVersionParamsV2): Promise<any>;
89
- getUploadToken: (params: TokenRequest) => Promise<TokenResponse>;
89
+ getUploadToken: (params: TokenRequest & {
90
+ app_id?: string;
91
+ nonce?: string;
92
+ cli_token?: string;
93
+ }) => Promise<TokenResponse>;
90
94
  createUploadTaskV1(opts: IUploadPackageParamsV1): Promise<any>;
91
95
  createUploadTaskV2(opts: IUploadPackageParamsV2): Promise<any>;
92
96
  queryTaskDetailV1(opts: IQueryTaskDetailV1): Promise<any>;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("xhs-mp-project"),t=require("xhs-mp-shared"),o=require("events"),r=require("axios"),s=require("path"),i=require("os"),a=require("fs-extra"),n=require("dayjs"),p=require("dayjs/plugin/utc"),c=require("dayjs/plugin/timezone"),l=require("https-proxy-agent"),h=require("querystring"),u=require("fs"),d=require("rxjs"),g=require("lodash"),m=require("rxjs/operators"),f=require("qrcode-terminal"),S=require("jimp"),v=require("jsqr"),k=require("process"),w=require("xhs-mp-compiler-cli");function x(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(o){if("default"!==o){var r=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,r.get?r:{enumerable:!0,get:function(){return e[o]}})}})),t.default=e,Object.freeze(t)}var y=x(s),C=x(u);const b=()=>({isSit:"false"===process.env.XHS_IS_PROD,isProd:"true"===process.env.XHS_IS_PROD}),_=require("process").env.XHS_BUSINESS_SIT_HOST||"http://business-cli.sl.beta.xiaohongshu.com",I=require("process").env.XHS_CUSTOMER_SIT_HOST||"https://customer.sit.xiaohongshu.com",P={BUSINESS_HOST:b().isSit?_:"https://business.xiaohongshu.com",CUSTOMER_HOST:b().isSit?I:"https://customer.xiaohongshu.com",CUSTOMER_SERVICE_ID:b().isSit?I.replace(/https?:\/\/customer/,"file://miniapp-open"):"file://miniapp-open.xiaohongshu.com"},j={generateQrCode:`${P.CUSTOMER_HOST}/api/cas/generateQrCode`,queryQrCodeStatus:`${P.CUSTOMER_HOST}/api/cas/queryQrCodeStatus`,session:`${P.BUSINESS_HOST}/api/eros/mp/red/code/session`,getUserInfo:`${P.BUSINESS_HOST}/api/eros/mp/red/code/user/info`},M=require("crypto");require("net");const q=e=>{if(!e)return"";const t=1024;return e<t?`${e}B`:e<1048576?`${(e/t).toFixed(2)}KB`:e<t**3?`${(e/1048576).toFixed(2)}MB`:e<t**4?`${(e/t**3).toFixed(2)}GB`:`${(e/t**4).toFixed(2)}T`};function T(e){const t=M.createHash("md5");t.update(e);return t.digest("hex")}function U(e){return e.replace(/\\/g,"/")}const A=U(s.join(i.homedir(),".xhs-mp-cli"));a.ensureDirSync(A);const E=U(s.join(A,"xhs-storage"));a.ensureDirSync(E);const $=require("tough-cookie");var O=new class{constructor(){this.cookiePath=s.join(E,"cookie.json");const e=this.getSerializeData();Object.keys(e).length?this.cookieJar=$.CookieJar.deserializeSync(e):this.cookieJar=new $.CookieJar}getSerializeData(){let e={};return a.existsSync(this.cookiePath)&&(e=a.readJSONSync(this.cookiePath)),e}save(){const e=this.cookieJar.serializeSync();a.writeJSONSync(this.cookiePath,e)}clear(){a.removeSync(this.cookiePath)}set(e){const t=e.headers["set-cookie"]||[],o=e.config.url;t.forEach((e=>{const t=$.Cookie.parse(e);if(t.domain){const e=new $.Cookie(t);this.cookieJar.setCookieSync(e,o)}})),this.save()}get(e){return this.cookieJar.getCookieStringSync(e)}};n.extend(p),n.extend(c),n.tz.setDefault("Asia/Shanghai");let D=0;const H=e=>n.tz().add(D,"millisecond").format(e);let z;r.defaults.baseURL=P.BUSINESS_HOST,r.interceptors.request.use((e=>{const{url:o,data:s,baseURL:i=""}=e;let a=r.getUri(e);if(/^https?:/.test(a))try{const e=new URL(o);a=a.replace(e.origin,"")}catch(e){a=o}const n=O.get(o);return e.headers={...e.headers,Cookie:n},e.headers["User-Agent"]=`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ${t.getLegacyBundleVersion()} Chrome/116.0.5845.228 Electron/26.4.0 Safari/537.36 discover/2.0.0 xhsminiapp/latest`,e})),r.interceptors.response.use((e=>(O.set(e),e))),r.interceptors.response.use((e=>{var t;const{config:o,data:r}=e;if((null===(t=o.url)||void 0===t?void 0:t.startsWith(`${P.BUSINESS_HOST}/api/eros/mp/red`))&&!r.success)throw new Error(`${r.msg}`);return e}),(async e=>{var t,o,s;const{response:i={},config:a}=e;if(401===i.status){if(-240309===(null===(t=i.data)||void 0===t?void 0:t.code))return null==z||z.logout({from:"axios"}),Promise.reject(new Error(i.data.msg||"请求失败,请重新登陆或采用 token 免密登陆"));if(-240099===(null===(o=i.data)||void 0===o?void 0:o.code)){const e=i.headers.date,t=n(e).format("YYYYMMDDHHmm"),o=H("YYYYMMDDHHmm");return o!==t?(((e,t)=>{const o=n(e).diff(n(t));D=o})(t,o),console.log("请求失败:客户端与服务端时间不一致,即将重试",t,o),(p=1e3,new Promise((e=>{setTimeout((()=>{e(null)}),p)}))).then((function(){let e=a;return a.fixConfigWhenRetry&&(e=a.fixConfigWhenRetry(a)),r(e)}))):(null==z||z.logout({from:"axios"}),Promise.reject(new Error(i.data.msg||"请求失败,cli token不匹配")))}if(null===(s=i.data)||void 0===s?void 0:s.msg)return null==z||z.logout({from:"axios"}),Promise.reject(new Error(`code:${i.data.code},msg: ${i.data.msg}`))}var p;return Promise.reject(e)}));class V extends o.EventEmitter{constructor(e){super(),this.core=e.core}get axios(){return e=this.core,z=e,r;var e}getProxyConfig(){const{proxy:e}=this.core.getGlobalConfig();if(e){const t=new URL(e);return{host:t.hostname,port:t.port,protocol:t.protocol,auth:{username:t.username,password:t.password}}}return!1}async request(e){const{method:t,url:o,data:r,config:s={}}=e,{proxy:i}=this.core.getGlobalConfig();i&&(s.proxy=!1,s.httpsAgent=new l.HttpsProxyAgent(i));return await this.axios[t](o,r,{...s})}handleHttpStatus(e){if(200!==e.status)throw new Error(`request fail, code: ${e.status}, errMsg: ${e.status}`);return e}handleStatusCode(e){const{data:t}=e;if(200!==t.statusCode)throw new Error(`request fail, code: ${t.statusCode}, errMsg: ${t.errorMsg}`);return t.data}handleCode(e){const{data:t}=e;if(0!==t.code&&0!==t.error_code)throw new Error(`request fail, code: ${t.code||t.error_code}, errMsg: ${t.msg}`);return t.data}}const L=require("path"),N=require("fs-extra"),R=e=>{if(!N.existsSync(e))return"";let t="";try{t=JSON.stringify(N.readJSONSync(e))}catch(t){console.warn(`readJson error: ${e}`)}return t};class B extends V{constructor(e){super(e),this.getUploadToken=async e=>{const t=await this.request({method:"get",url:`${P.BUSINESS_HOST}/api/eros/mp/red/code/upload/permit`,data:{params:e,withCredentials:!0}});return this.handleCode(this.handleHttpStatus(t))},this.project=e.project}async request(e){const{method:t,url:o,data:r,config:s={},fixConfigWhenRetry:i}=e,{proxy:a}=this.core.getGlobalConfig();a&&(s.proxy=!1,s.httpsAgent=new l.HttpsProxyAgent(a));const n=await this.axios[t](o,r,{...s,fixConfigWhenRetry:e=>{let{url:t}=e;if(t.includes("cli_token")){const[o,r=""]=t.split("?"),s=h.parse(r),{cliToken:i,nonce:a,appId:n}=this.core.getTokenParams(this.project.projectAppId),p=o+"?"+h.stringify({...s,cli_token:i,nonce:a,appId:n});e.url=p}return e}});return n}async checkUploadAuthV1({version:e}){const t=this.project,o=t.entryJsonPath,r=L.resolve(t.extJsonPath),s=R(o),i=R(r),a=t.projectAppId,n=`${P.BUSINESS_HOST}/api/eros/mp/red/code/${a}/validate/version/${e}`,p=await this.request({method:"post",url:n,data:{app_json:s,ext_json:i}});return this.handleCode(this.handleHttpStatus(p))}async checkUploadAuthV2(e){const{version:t,appId:o,cliToken:r,nonce:s}=e,i=this.project,a=i.entryJsonPath,n=L.resolve(i.extJsonPath),p=R(a),c=R(n),l=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/validate/version?app_id=${o}&cli_token=${r}&nonce=${s}&version=${t}`,h=await this.request({method:"post",url:l,data:{app_json:p,ext_json:c}});return this.handleCode(this.handleHttpStatus(h))}async createUploadTaskV1(e){const{version:t,userVersion:o,userDesc:r,appId:s,packageMap:i,packageMapSourceMap:a,packageMapV2:n,packageMapV2SourceMap:p}=e,c={method:"post",url:`${P.BUSINESS_HOST}/api/eros/mp/red/code/${s}/upload/version/${t}`,data:{user_version:o,user_desc:r,package_map:i,package_map_v2:n,sourcemap:{package_v1:a,package_v2:p},cloud_type:4}};let l=await this.request(c);return l=this.handleCode(this.handleHttpStatus(l)),l}async createUploadTaskV2(e){const{version:t,userVersion:o,userDesc:r,appId:s,packageMap:i,packageMapSourceMap:a,packageMapV2:n,packageMapV2SourceMap:p,cliToken:c,nonce:l}=e,h=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/upload/version?app_id=${s}&cli_token=${c}&nonce=${l}&version=${t}`,u=await this.request({method:"post",url:h,data:{user_version:o,user_desc:r,package_map:i,package_map_v2:n,sourcemap:{package_v1:a,package_v2:p},cloud_type:4}});return this.handleCode(this.handleHttpStatus(u))}async queryTaskDetailV1(e){const{taskId:t}=e;let o=await this.request({method:"get",url:`${P.BUSINESS_HOST}/api/eros/mp/red/code/task/detail`,data:{params:{task_id:t}}});return o=this.handleCode(this.handleHttpStatus(o)),o}async queryTaskDetailV2(e){const{taskId:t,appId:o,cliToken:r,nonce:s}=e,i=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/task/detail`;let a=await this.request({method:"get",url:i,data:{params:{task_id:t,app_id:o,cli_token:r,nonce:s}}});return a=this.handleCode(this.handleHttpStatus(a)),a}}const J=(e,t)=>e.reduce(((e,o)=>{let r={};return o.type!==t||o.isSourcemap||(r={[o.root]:o.fileId}),{...e,...r}}),{}),Q=(e,t)=>{var o;const r=null===(o=e.filter((e=>e.type===t&&e.isSourcemap)))||void 0===o?void 0:o[0];return JSON.stringify({md5:null==r?void 0:r.md5,cdnFileUrl:null==r?void 0:r.cdnFileUrl})};class F extends o{constructor(e){super(),this.uploadPkgZipOrSourcemap=(e,t,o,r)=>new d.Observable((s=>{setTimeout((()=>{const{zipPath:i,type:a,root:n}=t,p=i.endsWith("-sourcemap.zip");let c;c=p?this.uploadPkgSourcemap(t):this.uploadPkgZip(e,t,o),c.then((e=>{s.next({...e,type:a,root:n,isSourcemap:p}),s.complete(),null==r||r()})).catch((e=>{s.error(e)}))}),500)})),this.uploadPkgSourcemap=async e=>{const{appId:o,version:r,zipPath:s}=e,i=y.basename(s).split("-")[0],a=T(`${o}_${r}_${i}`),n=t.publicCos.getPublicCos(this.core.getGlobalConfig().proxy),p=(await t.publicCos.upload2Qcloud(n,s,`${o}/${r}/${i}/${a}`)).files[0];if(200!==p.data.statusCode)throw new Error(`${s}上传失败:${p.error||"unknown error"}`);return{md5:T(C.readFileSync(s)),fileId:p.data.ETag,cdnFileUrl:`https://${p.data.Location}`}},this.uploadPkgZip=(e,o,r,s)=>{const{zipPath:i,type:a,root:n}=o,{appId:p,cliToken:c,nonce:l}=this.core.getTokenParams(this.project.projectAppId),h=new t.Uploader({bizName:"fe",scene:"fe-platform",getToken:t=>{let o=t;return this.core.isTokenAuth(this.project.projectAppId)&&(o={...t,app_id:p,nonce:l,cli_token:c}),e.getUploadToken(o)},proxy:this.core.getGlobalConfig().proxy});return new Promise(((e,t)=>{setTimeout((()=>{const o=`${"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}))}-xhs-example.zip`,r=C.readFileSync(y.resolve(i)),p=C.statSync(y.resolve(i));function c(){return new Promise(((e,t)=>{setTimeout((()=>{h.post({Body:r,fileInfo:{name:o,type:"application/octet-stream",size:p.size},FilePath:y.resolve(i)}).then((o=>{var r;return 0!==o.code?t(new Error(`${i}上传失败:${o.msg}`)):(null===(r=null==o?void 0:o.data)||void 0===r?void 0:r.fileId)?(e({fileId:o.data.fileId,type:a,root:n,cdnFileUrl:o.data.previewUrl}),void(null==s||s())):t(new Error(`${i}上传失败`))}))}),500)}))}c().catch(c).catch(c).catch(c).catch(c).then((t=>{e(t)})).catch((e=>{t(e)}))}),500)}))},this.submitTask=e=>this.core.isTokenAuth(this.project.projectAppId)?this.submitTaskV2(e):this.submitTaskV1(e),this.submitTaskV1=e=>{const{uploadApi:t}=e,o=this.getCommonSubmitOptions(e);return d.from(t.createUploadTaskV1(o)).pipe(d.switchMap((e=>{const{task_id:o}=e;return d.interval(1500).pipe(d.switchMap((()=>d.from(t.queryTaskDetailV1({taskId:o})).pipe(d.map((e=>{var t;if(5===e.status)throw new Error(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.msg);return e}))))),d.first((e=>3===e.status)))})))},this.submitTaskV2=e=>{const{uploadApi:t}=e,{appId:o,cliToken:r,nonce:s}=this.core.getTokenParams(this.project.projectAppId),i=this.getCommonSubmitOptions(e);return d.from(t.createUploadTaskV2({...i,cliToken:r,nonce:s})).pipe(d.switchMap((e=>{const{task_id:i}=e;return d.interval(1500).pipe(d.switchMap((()=>d.from(t.queryTaskDetailV2({taskId:i,appId:o,cliToken:r,nonce:s})).pipe(d.map((e=>{var t;if(5===e.status)throw new Error(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.msg);return e}))))),d.first((e=>3===e.status)))})))},this.core=e.core,this.project=e.project,this.compilerManager=e.compilerManager,this.logger=e.logger}getCheckUploadAuthFn(e,t){let o;const r=this.core.isTokenAuth(this.project.projectAppId);if(this.logger.debug("Check appid auth..."),r){const{appId:r,cliToken:s,nonce:i}=this.core.getTokenParams(this.project.projectAppId);o=e.checkUploadAuthV2({version:t,appId:r,cliToken:s,nonce:i})}else o=e.checkUploadAuthV1({version:t});return o}getCommonSubmitOptions(e){const{uploadRes:t,appId:o,version:r,userDesc:s,userVersion:i}=e,a=J(t,"v1"),n=Q(t,"v1"),p=J(t,"v2"),c=Q(t,"v2");return{version:r,appId:o,packageMap:a,packageMapSourceMap:n,packageMapV2:g.isEmpty(p)?void 0:p,packageMapV2SourceMap:c,userDesc:s,userVersion:i}}}const{COMPILE_ENTRY:Y}=require("xhs-mp-compiler-cli");class G extends F{constructor(e){super(e),this.doUpload=e=>{const{progressCallback:t,userVersion:o,userDesc:r}=e;if(!(null==o?void 0:o.trim()))throw new Error("请填写上传版本号");if(!(null==r?void 0:r.trim()))throw new Error("请填写版本描述");const s=()=>{var e,t;this.compilerManager.killCompiler(Y.upload),null===(e=this.taskSubscription)||void 0===e||e.unsubscribe(),this.taskSubscription=null,null===(t=this.uploadPromise)||void 0===t||t.resolve(null),this.uploadPromise=null,this.logger.log("Upload Done!!!")},i=e=>{var o,r;null==t||t(-1),null===(o=this.taskSubscription)||void 0===o||o.unsubscribe(),this.taskSubscription=null,this.compilerManager.killCompiler(Y.upload),this.logger.log("Upload Error:",e.message),null===(r=this.uploadPromise)||void 0===r||r.reject(e),this.uploadPromise=null};try{const e=this.project.projectAppId;this.taskSubscription=d.from(this.getCheckUploadAuthFn(this.uploadApi,"develop")).pipe(d.switchMap((e=>{let r=e.can_upload,s=e.can_upload_ext_json,i=e.upload_app_id;if(!r)throw new Error(e.show_msg);if(!i)throw new Error("请检查是否该appid无权限");return null==t||t(5),d.from(this.compilerManager.compileAndZip({entryType:Y.upload,can_upload_ext_json:s,upload_app_id:i,pkgInfo:{version:o}}))})),d.switchMap((o=>{null==t||t(30),this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages...");const r=o.map(((r,s)=>this.uploadPkgZipOrSourcemap(this.uploadApi,{appId:e,zipPath:r.zipPath,type:r.type,root:r.root},s,(()=>{null==t||t(30+45/o.length*(s+1))}))));return d.forkJoin(r)})),d.switchMap((s=>{null==t||t(80),this.logger.log("Upload packages info...");const i={uploadApi:this.uploadApi,uploadRes:s,appId:e,version:"develop",userVersion:o,userDesc:r};return this.submitTask(i)}))).subscribe({next:e=>{null==t||t(100),s()},error:e=>{i(e)}})}catch(e){i(e)}},this.uploadApi=new B(e)}upload(e){return new Promise(((t,o)=>{this.uploadPromise={resolve:t,reject:o},this.doUpload(e)}))}}class W extends V{async generateQrCode(){const e=await this.request({method:"post",url:j.generateQrCode,data:{subsystem:"business"}});return this.handleStatusCode(this.handleHttpStatus(e))}async queryQrCodeStatus(e){const t=await this.request({method:"get",url:j.queryQrCodeStatus,data:{params:{qrId:e,service:P.CUSTOMER_SERVICE_ID}}});return this.handleStatusCode(this.handleHttpStatus(t))}async login(e){const t=await this.request({method:"post",url:j.session,data:{ticket:e,clientId:P.CUSTOMER_SERVICE_ID}});return this.handleHttpStatus(t).data}async fetchUserInfo(){const e=await this.request({method:"get",url:j.getUserInfo});return this.handleCode(this.handleHttpStatus(e))}}class Z{get isLogin(){return this._isLogin}set isLogin(e){this._isLogin=e}get userInfo(){return this._userInfo}set userInfo(e){this._userInfo=e,this.storage.set("xhs-cli-userInfo",e)}constructor(e){var t;this.qrCodeStatusData={},this.startPollingSub=null,this.loginPromise={},this.transformUserInfo=e=>{const{nick:t,avatar:o,desc:r,gender:s}=(i=e,["nick","avatar","desc","gender"].reduce(((e,t)=>({...e,[t]:i[t]})),{}));var i;return{nickName:t,avatar:o,userId:"",desc:r,gender:s}},this.queryQrCodeStatus=e=>d.from(this.userApi.queryQrCodeStatus(e)),this.doLogin=async e=>{const{resolve:t,reject:o}=this.loginPromise;this.loginPromise=null;try{const r=await this.userApi.login(e);if(!r.success)return void o(new Error(r.msg));const s=await this.userApi.fetchUserInfo(),i=this.transformUserInfo(s);i.userInfoData=s,t(i)}catch(e){return void o(new Error(e.message))}},this.startPolling=()=>(this.qrCodeStatusData.isLoading=!0,this.qrCodeStatusData.expired=!1,d.from(d.defer((()=>this.userApi.generateQrCode()))).pipe(m.tap((e=>{this.qrUrl=e.qrUrl,this.qrCodeStatusData.isLoading=!1,this.showQrCode(),setTimeout((()=>{this.qrCodeStatusData.expired=!0,this.stopPolling()}),6e4)})),m.exhaustMap((({qrUrl:e,qrId:t})=>d.interval(2e3).pipe(m.switchMap((()=>this.queryQrCodeStatus(t))),m.tap((e=>{if(4===e.status)throw new Error("retry login");1===e.status&&(this.stopPolling(),this.doLogin(e.ticket))}))))),m.takeWhile((e=>1!==e.status)),m.retry(5))),this.stopPolling=()=>{this.startPollingSub&&(this.startPollingSub.unsubscribe(),this.startPollingSub=null)};const{storage:o,logger:r}=e;this.storage=o,this.logger=r,this.userApi=new W(e),this.qrCodeStatusData={isLoading:!1,expired:!1},this._userInfo=o.get("userInfo")||o.get("xhs-cli-userInfo")||{},this.isLogin=!!(null===(t=this.userInfo)||void 0===t?void 0:t.nickName)}showQrCode(){f.generate(this.qrUrl,{small:!0})}async login(e="qrcode"){if(this.isLogin)this.logger.log("Had Login!!!");else{this.isLogin=!1,this.logger.log("Login...");try{if("qrcode"!==e)throw new Error("暂不支持扫码之外的其他登陆方式");{const e=await this.loginByQrcode();this.userInfo=e}this.isLogin=!0,this.logger.log("Login success")}catch(e){throw this.logger.log("Login fail:",e.message),this.isLogin=!1,this.userInfo=null,e}}}loginByQrcode(){return new Promise(((e,t)=>{this.loginPromise={resolve:e,reject:t};try{this.startPollingSub=this.startPolling().subscribe()}catch(e){console.error(e)}}))}logout(e){"axios"!==e.from&&this.logger.log("Logout..."),this.isLogin=!1,this.userInfo={},O.clear(),"axios"!==e.from&&this.logger.log("Logout Success!!!")}}const X=async(e,t={},o,r)=>{let s=e.getCompileEntryPage();s={...s,...t};const{path:i,query:a,launchMode:n}=s;try{let e=await(async e=>{const t=Buffer.from(e.replace(/^data:image\/[a-z]+;base64,/,""),"base64"),o=await S.read(t),r={data:new Uint8ClampedArray(o.bitmap.data),width:o.bitmap.width,height:o.bitmap.height},s=v(r.data,r.width,r.height);if(!s)throw new Error("QR code not found in the image.");return s.data})(o);return i&&(e=e.replace("_develop",`_develop${i.startsWith("/")?"":"/"}${i}`)),a&&(e+=`&${a}`),"halfPageNativeFunctionalized"===n&&(e+="&runtime_mode=2"),e}catch(e){r.error("二维码解码失败:",e)}},{COMPILE_ENTRY:K}=require("xhs-mp-compiler-cli");class ee extends F{constructor(e){super(e),this.progressData={},this.previewData={},this.calcSize=e=>{var t,o;const r=this.project,s=(null===(t=null==r?void 0:r.flags)||void 0===t?void 0:t.enableV2Preivew)?"v2":"v1",i=(null===(o=null==e?void 0:e.filter)||void 0===o?void 0:o.call(e,(e=>e.type===s)).sort(((e,t)=>t.zipSize-e.zipSize)))||[];this.previewData.subPkgs=i.map(((e,t)=>({key:t,path:e.root,size:q(e.zipSize)})));const a=i.reduce(((e,t)=>t.zipSize+e),0)||0;this.previewData.zipSize=q(a)},this.uploadApi=new B(e),this.progressData={},this.previewData={}}preview(e){return new Promise(((t,o)=>{this.previewPromise={resolve:t,reject:o},this.doPreview(e)}))}doPreview(e){this.progressData.previewIsLoading=!0;const t=this.project.projectAppId,o=Date.now(),r=async t=>{var r,s;const i=JSON.parse(t.result.extra_json);this.previewData.qrcodeUrl=await X(this.project,e.entry,i.qrcode,this.logger),this.showQrCode(this.previewData.qrcodeUrl),this.previewData.previewTotalTime=+((Date.now()-o)/1e3).toFixed(1),this.progressData.previewIsLoading=!1,this.compilerManager.killCompiler(K.preview),null===(r=this.taskSubscription)||void 0===r||r.unsubscribe(),this.taskSubscription=null,null===(s=this.previewPromise)||void 0===s||s.resolve({qrcodeUrl:this.previewData.qrcodeUrl}),this.previewPromise=null,this.logger.log("Preview Done!!!")},s=e=>{var t,o;this.compilerManager.killCompiler(K.preview),null===(t=this.taskSubscription)||void 0===t||t.unsubscribe(),this.taskSubscription=null,null===(o=this.previewPromise)||void 0===o||o.reject(e),this.previewPromise=null,this.logger.log("Preview Error:",e.toString())};this.taskSubscription=d.from(this.getCheckUploadAuthFn(this.uploadApi,"debug")).pipe(d.switchMap((e=>{let t=e.can_upload_ext_json,o=e.upload_app_id;if(!o)throw new Error("请检查是否该appid无权限");return d.from(this.compilerManager.compileAndZip({entryType:K.preview,can_upload_ext_json:t,upload_app_id:o}))})),d.tap((e=>{this.calcSize(e)})),d.switchMap((e=>{this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages...");const o=e.map(((e,o)=>this.uploadPkgZipOrSourcemap(this.uploadApi,{appId:t,zipPath:e.zipPath,type:e.type,root:e.root},o)));return d.forkJoin(o)})),d.switchMap((e=>(this.logger.log("Upload packages info..."),this.submitTask({uploadApi:this.uploadApi,uploadRes:e,appId:t,version:"debug"}))))).subscribe({next:e=>r(e),error:e=>s(e)})}showQrCode(e){f.generate(e,{small:!0})}}const te={code:"code",cli:"cli"};class oe{constructor({core:e}){this.data={},this.core=e,this.extract()}extract(){if(this.core.scene===te.cli){if(this.jsonPath=s.join(E,"storage.json"),a.existsSync(this.jsonPath))try{this.data=a.readJSONSync(this.jsonPath)}catch(e){this.data={}}}else this.data={}}store(){this.core.scene===te.cli&&a.writeJSONSync(this.jsonPath,this.data)}get(e){return this.data[e]}set(e,t){this.data[e]=t,this.refresh()}refresh(){this.store()}}exports.Core=class{constructor(e){this.globalConfig={},this.appConfigMap={},this.projectMap={},this.compilerManagerMap={},this.scene=te.code;const{scene:o=te.code}=e;this.scene=o,this.logger=new t.Logger("[xhs-mp-cli]"),this.storage=new oe({core:this}),this.globalConfig=this.storage.get("xhs-cli-global-config")||{},this.appConfigMap=this.storage.get("xhs-cli-app-config")||{},this.logger.debug("get initial config:",this.globalConfig,this.appConfigMap),globalThis.logger=this.logger,this.loginManager=new Z({core:this,storage:this.storage,logger:this.logger})}setGlobalConfig(e={}){this.globalConfig={...this.globalConfig||{},...e},this.storage.set("xhs-cli-global-config",e),this.logger.log("Set global config done")}getGlobalConfig(){return this.globalConfig||{}}setAppConfig(e={}){const{appId:t,config:o}=e;t?(this.appConfigMap[t]={...this.appConfigMap[t]||{},...o},this.storage.set("xhs-cli-app-config",this.appConfigMap),this.logger.log("Set app config done")):this.logger.error("没有传递 appid 参数")}getAppConfig(e){return this.appConfigMap[e]||{}}createOrGetProject(t){let o=t.projectPath;if(!o)throw new Error("没有配置projectPath");return s.isAbsolute(o)||(o=s.join(k.cwd(),o)),this.projectMap[o]||(this.projectMap[o]=new e.Project(t)),this.projectMap[o]}getCompilerManager(e,t){let o=e.projectPath;if(s.isAbsolute(o)||(o=s.join(k.cwd(),o)),!this.compilerManagerMap[o]){const r=this.createOrGetProject(e);this.compilerManagerMap[o]=new w.ProjectCompilerManager({...t,project:r,logger:this.logger})}return this.compilerManagerMap[o]}async login(e={}){e.verbose&&this.logger.setVerbose(!0);const{type:t="qrcode"}=e;await this.loginManager.login(t)}logout(e){this.loginManager.logout(e)}isTokenAuth(e){return!!this.getAppConfig(e).token}getTokenParams(e){const t=this.getAppConfig(e).token,o="xxxxxxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})),r=e+"#"+t+"#"+o+"#"+H("YYYYMMDDHHmm"),s=T(r);return this.logger.debug("cliToken",r,s),{cliToken:s,nonce:o,appId:e}}checkAppId(e){if(!this.appConfigMap[e])throw new Error(`找不到项目内appId(${e})对应的配置,请先确认appId是否保持一致`)}async preview(e){e.verbose&&this.logger.setVerbose(!0);const t=e.project||{},o=e.buildConfig||{},r=this.createOrGetProject(t);this.checkAppId(r.projectAppId),this.logger.log("Project:",r.projectPath),this.logger.debug("Preview options:",e);const s=this.appConfigMap[r.projectAppId];(null==s?void 0:s.token)?this.logger.debug("Auth by token"):(this.logger.debug("Auth by qrCode"),this.loginManager.isLogin||await this.login());const i=this.getCompilerManager(t,o),a=new ee({core:this,project:r,compilerManager:i,logger:this.logger});try{return await a.preview({entry:e.entry})}finally{i.killAll()}}async upload(e){const{project:t,buildConfig:o={},version:r,desc:s,progressCallback:i}=e;e.verbose&&this.logger.setVerbose(!0);const a=this.createOrGetProject(t);this.checkAppId(a.projectAppId),this.logger.log("ProjectPath:",a.projectPath),this.logger.debug("Upload options:",e);const n=this.appConfigMap[a.projectAppId];(null==n?void 0:n.token)?this.logger.debug("Auth by token"):(this.logger.debug("Auth by login"),this.loginManager.isLogin||await this.login());const p=this.getCompilerManager(t,o),c=new G({core:this,project:a,compilerManager:p,logger:this.logger});try{return await c.upload({userVersion:r,userDesc:s,progressCallback:i})}finally{p.killAll()}}};
1
+ "use strict";var e=require("xhs-mp-project"),t=require("xhs-mp-shared"),o=require("events"),r=require("axios"),s=require("path"),i=require("os"),a=require("fs-extra"),n=require("dayjs"),p=require("dayjs/plugin/utc"),c=require("dayjs/plugin/timezone"),l=require("https-proxy-agent"),h=require("querystring"),u=require("fs"),d=require("rxjs"),g=require("lodash"),m=require("rxjs/operators"),f=require("qrcode-terminal"),S=require("jimp"),v=require("jsqr"),k=require("process"),w=require("xhs-mp-compiler-cli");function x(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(o){if("default"!==o){var r=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,r.get?r:{enumerable:!0,get:function(){return e[o]}})}})),t.default=e,Object.freeze(t)}var y=x(s),C=x(u);const b=()=>({isSit:"false"===process.env.XHS_IS_PROD,isProd:"true"===process.env.XHS_IS_PROD}),_=require("process").env.XHS_BUSINESS_SIT_HOST||"http://business-cli.sl.beta.xiaohongshu.com",I=require("process").env.XHS_CUSTOMER_SIT_HOST||"https://customer.sit.xiaohongshu.com",P={BUSINESS_HOST:b().isSit?_:"https://business.xiaohongshu.com",CUSTOMER_HOST:b().isSit?I:"https://customer.xiaohongshu.com",CUSTOMER_SERVICE_ID:b().isSit?I.replace(/https?:\/\/customer/,"file://miniapp-open"):"file://miniapp-open.xiaohongshu.com"},j={generateQrCode:`${P.CUSTOMER_HOST}/api/cas/generateQrCode`,queryQrCodeStatus:`${P.CUSTOMER_HOST}/api/cas/queryQrCodeStatus`,session:`${P.BUSINESS_HOST}/api/eros/mp/red/code/session`,getUserInfo:`${P.BUSINESS_HOST}/api/eros/mp/red/code/user/info`},M=require("crypto");require("net");const q=e=>{if(!e)return"";const t=1024;return e<t?`${e}B`:e<1048576?`${(e/t).toFixed(2)}KB`:e<t**3?`${(e/1048576).toFixed(2)}MB`:e<t**4?`${(e/t**3).toFixed(2)}GB`:`${(e/t**4).toFixed(2)}T`};function T(e){const t=M.createHash("md5");t.update(e);return t.digest("hex")}function U(e){return e.replace(/\\/g,"/")}const A=U(s.join(i.homedir(),".xhs-mp-cli"));a.ensureDirSync(A);const E=U(s.join(A,"xhs-storage"));a.ensureDirSync(E);const $=require("tough-cookie");var O=new class{constructor(){this.cookiePath=s.join(E,"cookie.json");const e=this.getSerializeData();Object.keys(e).length?this.cookieJar=$.CookieJar.deserializeSync(e):this.cookieJar=new $.CookieJar}getSerializeData(){let e={};return a.existsSync(this.cookiePath)&&(e=a.readJSONSync(this.cookiePath)),e}save(){const e=this.cookieJar.serializeSync();a.writeJSONSync(this.cookiePath,e)}clear(){a.removeSync(this.cookiePath)}set(e){const t=e.headers["set-cookie"]||[],o=e.config.url;t.forEach((e=>{const t=$.Cookie.parse(e);if(t.domain){const e=new $.Cookie(t);this.cookieJar.setCookieSync(e,o)}})),this.save()}get(e){return this.cookieJar.getCookieStringSync(e)}};n.extend(p),n.extend(c),n.tz.setDefault("Asia/Shanghai");let D=0;const H=e=>n.tz().add(D,"millisecond").format(e);let z;function V(e){z=e;const o=r.create({baseURL:P.BUSINESS_HOST});return o.interceptors.request.use((e=>{const{url:r,data:s,baseURL:i=""}=e;let a=o.getUri(e);if(/^https?:/.test(a))try{const e=new URL(r);a=a.replace(e.origin,"")}catch(e){a=r}const n=O.get(r);return e.headers={...e.headers,Cookie:n},e.headers["User-Agent"]=`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ${t.getLegacyBundleVersion()} Chrome/116.0.5845.228 Electron/26.4.0 Safari/537.36 discover/2.0.0 xhsminiapp/latest`,e})),o.interceptors.response.use((e=>(O.set(e),e))),o.interceptors.response.use((e=>{var t;const{config:o,data:r}=e;if((null===(t=o.url)||void 0===t?void 0:t.startsWith(`${P.BUSINESS_HOST}/api/eros/mp/red`))&&!r.success)throw new Error(`${r.msg}`);return e}),(async e=>{var t,o,s;const{response:i={},config:a}=e;if(401===i.status){if(-240309===(null===(t=i.data)||void 0===t?void 0:t.code))return null==z||z.logout({from:"axios"}),Promise.reject(new Error(i.data.msg||"请求失败,请重新登陆或采用 token 免密登陆"));if(-240099===(null===(o=i.data)||void 0===o?void 0:o.code)){const e=i.headers.date,t=n(e).format("YYYYMMDDHHmm"),o=H("YYYYMMDDHHmm");return o!==t?(((e,t)=>{const o=n(e).diff(n(t));D=o})(t,o),console.log("请求失败:客户端与服务端时间不一致,即将重试",t,o),(p=1e3,new Promise((e=>{setTimeout((()=>{e(null)}),p)}))).then((function(){let e=a;return a.fixConfigWhenRetry&&(e=a.fixConfigWhenRetry(a)),r(e)}))):(null==z||z.logout({from:"axios"}),Promise.reject(new Error(i.data.msg||"请求失败,cli token不匹配")))}if(null===(s=i.data)||void 0===s?void 0:s.msg)return null==z||z.logout({from:"axios"}),Promise.reject(new Error(`code:${i.data.code},msg: ${i.data.msg}`))}var p;return Promise.reject(e)})),o}class L extends o.EventEmitter{constructor(e){super(),this.core=e.core,this.axios=V(this.core)}getProxyConfig(){const{proxy:e}=this.core.getGlobalConfig();if(e){const t=new URL(e);return{host:t.hostname,port:t.port,protocol:t.protocol,auth:{username:t.username,password:t.password}}}return!1}async request(e){const{method:t,url:o,data:r,config:s={}}=e,{proxy:i}=this.core.getGlobalConfig();i&&(s.proxy=!1,s.httpsAgent=new l.HttpsProxyAgent(i));return await this.axios[t](o,r,{...s})}handleHttpStatus(e){if(200!==e.status)throw new Error(`request fail, code: ${e.status}, errMsg: ${e.status}`);return e}handleStatusCode(e){const{data:t}=e;if(200!==t.statusCode)throw new Error(`request fail, code: ${t.statusCode}, errMsg: ${t.errorMsg}`);return t.data}handleCode(e){const{data:t}=e;if(0!==t.code&&0!==t.error_code)throw new Error(`request fail, code: ${t.code||t.error_code}, errMsg: ${t.msg}`);return t.data}}const N=require("path"),R=require("fs-extra"),B=e=>{if(!R.existsSync(e))return"";let t="";try{t=JSON.stringify(R.readJSONSync(e))}catch(t){console.warn(`readJson error: ${e}`)}return t};class J extends L{constructor(e){super(e),this.getUploadToken=async e=>{console.log("getUploadToken...",e);const{bizName:t,scene:o,fileCount:r,app_id:s,nonce:i,cli_token:a}=e,n=`${P.BUSINESS_HOST}/api/eros/mp/red/code/upload/permit?bizName=${t}&scene=${o}&fileCount=${r}&app_id=${s}&nonce=${i}&cli_token=${a}`,p=await this.request({method:"get",url:n});return this.handleCode(this.handleHttpStatus(p))},this.project=e.project}async request(e){const{method:t,url:o,data:r,config:s={},fixConfigWhenRetry:i}=e,{proxy:a}=this.core.getGlobalConfig();a&&(s.proxy=!1,s.httpsAgent=new l.HttpsProxyAgent(a)),console.log("request...",e,s);const n=await this.axios[t](o,r,{...s,fixConfigWhenRetry:e=>{let{url:t}=e;if(t.includes("cli_token")){const[o,r=""]=t.split("?"),s=h.parse(r),{cliToken:i,nonce:a,appId:n}=this.core.getTokenParams(this.project.projectAppId),p=o+"?"+h.stringify({...s,cli_token:i,nonce:a,appId:n});e.url=p}return e}});return console.log("request res...",n),n}async checkUploadAuthV1({version:e}){const t=this.project,o=t.entryJsonPath,r=N.resolve(t.extJsonPath),s=B(o),i=B(r),a=t.projectAppId,n=`${P.BUSINESS_HOST}/api/eros/mp/red/code/${a}/validate/version/${e}`,p=await this.request({method:"post",url:n,data:{app_json:s,ext_json:i}});return this.handleCode(this.handleHttpStatus(p))}async checkUploadAuthV2(e){const{version:t,appId:o,cliToken:r,nonce:s}=e,i=this.project,a=i.entryJsonPath,n=N.resolve(i.extJsonPath),p=B(a),c=B(n),l=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/validate/version?app_id=${o}&cli_token=${r}&nonce=${s}&version=${t}`,h=await this.request({method:"post",url:l,data:{app_json:p,ext_json:c}});return this.handleCode(this.handleHttpStatus(h))}async createUploadTaskV1(e){const{version:t,userVersion:o,userDesc:r,appId:s,packageMap:i,packageMapSourceMap:a,packageMapV2:n,packageMapV2SourceMap:p}=e,c={method:"post",url:`${P.BUSINESS_HOST}/api/eros/mp/red/code/${s}/upload/version/${t}`,data:{user_version:o,user_desc:r,package_map:i,package_map_v2:n,sourcemap:{package_v1:a,package_v2:p},cloud_type:4}};let l=await this.request(c);return l=this.handleCode(this.handleHttpStatus(l)),l}async createUploadTaskV2(e){const{version:t,userVersion:o,userDesc:r,appId:s,packageMap:i,packageMapSourceMap:a,packageMapV2:n,packageMapV2SourceMap:p,cliToken:c,nonce:l}=e,h=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/upload/version?app_id=${s}&cli_token=${c}&nonce=${l}&version=${t}`,u=await this.request({method:"post",url:h,data:{user_version:o,user_desc:r,package_map:i,package_map_v2:n,sourcemap:{package_v1:a,package_v2:p},cloud_type:4}});return this.handleCode(this.handleHttpStatus(u))}async queryTaskDetailV1(e){const{taskId:t}=e;let o=await this.request({method:"get",url:`${P.BUSINESS_HOST}/api/eros/mp/red/code/task/detail`,data:{params:{task_id:t}}});return o=this.handleCode(this.handleHttpStatus(o)),o}async queryTaskDetailV2(e){const{taskId:t,appId:o,cliToken:r,nonce:s}=e,i=`${P.BUSINESS_HOST}/api/eros/mp/red/code/v2/task/detail`;let a=await this.request({method:"get",url:i,data:{params:{task_id:t,app_id:o,cli_token:r,nonce:s}}});return a=this.handleCode(this.handleHttpStatus(a)),a}}const Q=(e,t)=>e.reduce(((e,o)=>{let r={};return o.type!==t||o.isSourcemap||(r={[o.root]:o.fileId}),{...e,...r}}),{}),F=(e,t)=>{var o;const r=null===(o=e.filter((e=>e.type===t&&e.isSourcemap)))||void 0===o?void 0:o[0];return JSON.stringify({md5:null==r?void 0:r.md5,cdnFileUrl:null==r?void 0:r.cdnFileUrl})};class Y extends o{constructor(e){super(),this.uploadPkgZipOrSourcemap=(e,t,o,r)=>new d.Observable((s=>{setTimeout((()=>{const{zipPath:i,type:a,root:n}=t,p=i.endsWith("-sourcemap.zip");let c;c=p?this.uploadPkgSourcemap(t):this.uploadPkgZip(e,t,o),c.then((e=>{s.next({...e,type:a,root:n,isSourcemap:p}),s.complete(),null==r||r()})).catch((e=>{s.error(e)}))}),500)})),this.uploadPkgSourcemap=async e=>{const{appId:o,version:r,zipPath:s}=e,i=y.basename(s).split("-")[0],a=T(`${o}_${r}_${i}`),n=t.publicCos.getPublicCos(this.core.getGlobalConfig().proxy),p=(await t.publicCos.upload2Qcloud(n,s,`${o}/${r}/${i}/${a}`)).files[0];if(200!==p.data.statusCode)throw new Error(`${s}上传失败:${p.error||"unknown error"}`);return{md5:T(C.readFileSync(s)),fileId:p.data.ETag,cdnFileUrl:`https://${p.data.Location}`}},this.uploadPkgZip=(e,o,r,s)=>{const{zipPath:i,type:a,root:n}=o,{appId:p,cliToken:c,nonce:l}=this.core.getTokenParams(this.project.projectAppId),h=new t.Uploader({bizName:"fe",scene:"fe-platform",getToken:t=>{let o=t;return console.log(111111,t),this.core.isTokenAuth(this.project.projectAppId)&&(o={...t,app_id:p,nonce:l,cli_token:c}),e.getUploadToken(o)},proxy:this.core.getGlobalConfig().proxy});return new Promise(((e,t)=>{setTimeout((()=>{const o=`${"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}))}-xhs-example.zip`,r=C.readFileSync(y.resolve(i)),p=C.statSync(y.resolve(i));function c(){return new Promise(((e,t)=>{setTimeout((()=>{h.post({Body:r,fileInfo:{name:o,type:"application/octet-stream",size:p.size},FilePath:y.resolve(i)}).then((o=>{var r;return console.log("uploader result:",o),0!==o.code?t(new Error(`${i}上传失败:${o.msg}`)):(null===(r=null==o?void 0:o.data)||void 0===r?void 0:r.fileId)?(e({fileId:o.data.fileId,type:a,root:n,cdnFileUrl:o.data.previewUrl}),void(null==s||s())):t(new Error(`${i}上传失败`))}))}),500)}))}c().catch(c).catch(c).catch(c).catch(c).then((t=>{e(t)})).catch((e=>{t(e)}))}),500)}))},this.submitTask=e=>this.core.isTokenAuth(this.project.projectAppId)?this.submitTaskV2(e):this.submitTaskV1(e),this.submitTaskV1=e=>{const{uploadApi:t}=e,o=this.getCommonSubmitOptions(e);return d.from(t.createUploadTaskV1(o)).pipe(d.switchMap((e=>{const{task_id:o}=e;return d.interval(1500).pipe(d.switchMap((()=>d.from(t.queryTaskDetailV1({taskId:o})).pipe(d.map((e=>{var t;if(5===e.status)throw new Error(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.msg);return e}))))),d.first((e=>3===e.status)))})))},this.submitTaskV2=e=>{const{uploadApi:t}=e,{appId:o,cliToken:r,nonce:s}=this.core.getTokenParams(this.project.projectAppId),i=this.getCommonSubmitOptions(e);return d.from(t.createUploadTaskV2({...i,cliToken:r,nonce:s})).pipe(d.switchMap((e=>{const{task_id:i}=e;return d.interval(1500).pipe(d.switchMap((()=>d.from(t.queryTaskDetailV2({taskId:i,appId:o,cliToken:r,nonce:s})).pipe(d.map((e=>{var t;if(5===e.status)throw new Error(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.msg);return e}))))),d.first((e=>3===e.status)))})))},this.core=e.core,this.project=e.project,this.compilerManager=e.compilerManager,this.logger=e.logger}getCheckUploadAuthFn(e,t){let o;const r=this.core.isTokenAuth(this.project.projectAppId);if(this.logger.debug("Check appid auth..."),r){const{appId:r,cliToken:s,nonce:i}=this.core.getTokenParams(this.project.projectAppId);o=e.checkUploadAuthV2({version:t,appId:r,cliToken:s,nonce:i})}else o=e.checkUploadAuthV1({version:t});return o}getCommonSubmitOptions(e){const{uploadRes:t,appId:o,version:r,userDesc:s,userVersion:i}=e,a=Q(t,"v1"),n=F(t,"v1"),p=Q(t,"v2"),c=F(t,"v2");return{version:r,appId:o,packageMap:a,packageMapSourceMap:n,packageMapV2:g.isEmpty(p)?void 0:p,packageMapV2SourceMap:c,userDesc:s,userVersion:i}}}const{COMPILE_ENTRY:G}=require("xhs-mp-compiler-cli");class W extends Y{constructor(e){super(e),this.doUpload=e=>{const{progressCallback:t,userVersion:o,userDesc:r}=e;if(!(null==o?void 0:o.trim()))throw new Error("请填写上传版本号");if(!(null==r?void 0:r.trim()))throw new Error("请填写版本描述");const s=()=>{var e,t;this.compilerManager.killCompiler(G.upload),null===(e=this.taskSubscription)||void 0===e||e.unsubscribe(),this.taskSubscription=null,null===(t=this.uploadPromise)||void 0===t||t.resolve(null),this.uploadPromise=null,this.logger.log("Upload Done!!!")},i=e=>{var o,r;null==t||t(-1),null===(o=this.taskSubscription)||void 0===o||o.unsubscribe(),this.taskSubscription=null,this.compilerManager.killCompiler(G.upload),this.logger.log("Upload Error:",e.message),null===(r=this.uploadPromise)||void 0===r||r.reject(e),this.uploadPromise=null};try{const e=this.project.projectAppId;this.taskSubscription=d.from(this.getCheckUploadAuthFn(this.uploadApi,"develop")).pipe(d.switchMap((e=>{let r=e.can_upload,s=e.can_upload_ext_json,i=e.upload_app_id;if(!r)throw new Error(e.show_msg);if(!i)throw new Error("请检查是否该appid无权限");return null==t||t(5),d.from(this.compilerManager.compileAndZip({entryType:G.upload,can_upload_ext_json:s,upload_app_id:i,pkgInfo:{version:o}}))})),d.switchMap((o=>{null==t||t(30),this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages...");const r=o.map(((r,s)=>this.uploadPkgZipOrSourcemap(this.uploadApi,{appId:e,zipPath:r.zipPath,type:r.type,root:r.root},s,(()=>{null==t||t(30+45/o.length*(s+1))}))));return d.forkJoin(r)})),d.switchMap((s=>{null==t||t(80),this.logger.log("Upload packages info...");const i={uploadApi:this.uploadApi,uploadRes:s,appId:e,version:"develop",userVersion:o,userDesc:r};return this.submitTask(i)}))).subscribe({next:e=>{null==t||t(100),s()},error:e=>{i(e)}})}catch(e){i(e)}},this.uploadApi=new J(e)}upload(e){return new Promise(((t,o)=>{this.uploadPromise={resolve:t,reject:o},this.doUpload(e)}))}}class Z extends L{async generateQrCode(){const e=await this.request({method:"post",url:j.generateQrCode,data:{subsystem:"business"}});return this.handleStatusCode(this.handleHttpStatus(e))}async queryQrCodeStatus(e){const t=await this.request({method:"get",url:j.queryQrCodeStatus,data:{params:{qrId:e,service:P.CUSTOMER_SERVICE_ID}}});return this.handleStatusCode(this.handleHttpStatus(t))}async login(e){const t=await this.request({method:"post",url:j.session,data:{ticket:e,clientId:P.CUSTOMER_SERVICE_ID}});return this.handleHttpStatus(t).data}async fetchUserInfo(){const e=await this.request({method:"get",url:j.getUserInfo});return this.handleCode(this.handleHttpStatus(e))}}class X{get isLogin(){return this._isLogin}set isLogin(e){this._isLogin=e}get userInfo(){return this._userInfo}set userInfo(e){this._userInfo=e,this.storage.set("xhs-cli-userInfo",e)}constructor(e){var t;this.qrCodeStatusData={},this.startPollingSub=null,this.loginPromise={},this.transformUserInfo=e=>{const{nick:t,avatar:o,desc:r,gender:s}=(i=e,["nick","avatar","desc","gender"].reduce(((e,t)=>({...e,[t]:i[t]})),{}));var i;return{nickName:t,avatar:o,userId:"",desc:r,gender:s}},this.queryQrCodeStatus=e=>d.from(this.userApi.queryQrCodeStatus(e)),this.doLogin=async e=>{const{resolve:t,reject:o}=this.loginPromise;this.loginPromise=null;try{const r=await this.userApi.login(e);if(!r.success)return void o(new Error(r.msg));const s=await this.userApi.fetchUserInfo(),i=this.transformUserInfo(s);i.userInfoData=s,t(i)}catch(e){return void o(new Error(e.message))}},this.startPolling=()=>(this.qrCodeStatusData.isLoading=!0,this.qrCodeStatusData.expired=!1,d.from(d.defer((()=>this.userApi.generateQrCode()))).pipe(m.tap((e=>{this.qrUrl=e.qrUrl,this.qrCodeStatusData.isLoading=!1,this.showQrCode(),setTimeout((()=>{this.qrCodeStatusData.expired=!0,this.stopPolling()}),6e4)})),m.exhaustMap((({qrUrl:e,qrId:t})=>d.interval(2e3).pipe(m.switchMap((()=>this.queryQrCodeStatus(t))),m.tap((e=>{if(4===e.status)throw new Error("retry login");1===e.status&&(this.stopPolling(),this.doLogin(e.ticket))}))))),m.takeWhile((e=>1!==e.status)),m.retry(5))),this.stopPolling=()=>{this.startPollingSub&&(this.startPollingSub.unsubscribe(),this.startPollingSub=null)};const{storage:o,logger:r}=e;this.storage=o,this.logger=r,this.userApi=new Z(e),this.qrCodeStatusData={isLoading:!1,expired:!1},this._userInfo=o.get("userInfo")||o.get("xhs-cli-userInfo")||{},this.isLogin=!!(null===(t=this.userInfo)||void 0===t?void 0:t.nickName)}showQrCode(){f.generate(this.qrUrl,{small:!0})}async login(e="qrcode"){if(this.isLogin)this.logger.log("Had Login!!!");else{this.isLogin=!1,this.logger.log("Login...");try{if("qrcode"!==e)throw new Error("暂不支持扫码之外的其他登陆方式");{const e=await this.loginByQrcode();this.userInfo=e}this.isLogin=!0,this.logger.log("Login success")}catch(e){throw this.logger.log("Login fail:",e.message),this.isLogin=!1,this.userInfo=null,e}}}loginByQrcode(){return new Promise(((e,t)=>{this.loginPromise={resolve:e,reject:t};try{this.startPollingSub=this.startPolling().subscribe()}catch(e){console.error(e)}}))}logout(e){"axios"!==e.from&&this.logger.log("Logout..."),this.isLogin=!1,this.userInfo={},O.clear(),"axios"!==e.from&&this.logger.log("Logout Success!!!")}}const K=async(e,t={},o,r)=>{let s=e.getCompileEntryPage();s={...s,...t};const{path:i,query:a,launchMode:n}=s;try{let e=await(async e=>{const t=Buffer.from(e.replace(/^data:image\/[a-z]+;base64,/,""),"base64"),o=await S.read(t),r={data:new Uint8ClampedArray(o.bitmap.data),width:o.bitmap.width,height:o.bitmap.height},s=v(r.data,r.width,r.height);if(!s)throw new Error("QR code not found in the image.");return s.data})(o);return i&&(e=e.replace("_develop",`_develop${i.startsWith("/")?"":"/"}${i}`)),a&&(e+=`&${a}`),"halfPageNativeFunctionalized"===n&&(e+="&runtime_mode=2"),e}catch(e){r.error("二维码解码失败:",e)}},{COMPILE_ENTRY:ee}=require("xhs-mp-compiler-cli");class te extends Y{constructor(e){super(e),this.progressData={},this.previewData={},this.calcSize=e=>{var t,o;const r=this.project,s=(null===(t=null==r?void 0:r.flags)||void 0===t?void 0:t.enableV2Preivew)?"v2":"v1",i=(null===(o=null==e?void 0:e.filter)||void 0===o?void 0:o.call(e,(e=>e.type===s)).sort(((e,t)=>t.zipSize-e.zipSize)))||[];this.previewData.subPkgs=i.map(((e,t)=>({key:t,path:e.root,size:q(e.zipSize)})));const a=i.reduce(((e,t)=>t.zipSize+e),0)||0;this.previewData.zipSize=q(a)},this.uploadApi=new J(e),this.progressData={},this.previewData={}}preview(e){return new Promise(((t,o)=>{this.previewPromise={resolve:t,reject:o},this.doPreview(e)}))}doPreview(e){this.progressData.previewIsLoading=!0;const t=this.project.projectAppId,o=Date.now(),r=async t=>{var r,s;const i=JSON.parse(t.result.extra_json);this.previewData.qrcodeUrl=await K(this.project,e.entry,i.qrcode,this.logger),this.showQrCode(this.previewData.qrcodeUrl),this.previewData.previewTotalTime=+((Date.now()-o)/1e3).toFixed(1),this.progressData.previewIsLoading=!1,this.compilerManager.killCompiler(ee.preview),null===(r=this.taskSubscription)||void 0===r||r.unsubscribe(),this.taskSubscription=null,null===(s=this.previewPromise)||void 0===s||s.resolve({qrcodeUrl:this.previewData.qrcodeUrl}),this.previewPromise=null,this.logger.log("Preview Done!!!")},s=e=>{var t,o;this.compilerManager.killCompiler(ee.preview),null===(t=this.taskSubscription)||void 0===t||t.unsubscribe(),this.taskSubscription=null,null===(o=this.previewPromise)||void 0===o||o.reject(e),this.previewPromise=null,this.logger.log("Preview Error:",e.toString())};this.taskSubscription=d.from(this.getCheckUploadAuthFn(this.uploadApi,"debug")).pipe(d.switchMap((e=>{let t=e.can_upload_ext_json,o=e.upload_app_id;if(!o)throw new Error("请检查是否该appid无权限");return d.from(this.compilerManager.compileAndZip({entryType:ee.preview,can_upload_ext_json:t,upload_app_id:o}))})),d.tap((e=>{this.calcSize(e)})),d.switchMap((e=>{this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages...");const o=e.map(((e,o)=>this.uploadPkgZipOrSourcemap(this.uploadApi,{appId:t,zipPath:e.zipPath,type:e.type,root:e.root},o)));return d.forkJoin(o)})),d.switchMap((e=>(this.logger.log("Upload packages info..."),this.submitTask({uploadApi:this.uploadApi,uploadRes:e,appId:t,version:"debug"}))))).subscribe({next:e=>r(e),error:e=>s(e)})}showQrCode(e){f.generate(e,{small:!0})}}const oe={code:"code",cli:"cli"};class re{constructor({core:e}){this.data={},this.core=e,this.extract()}extract(){if(this.core.scene===oe.cli){if(this.jsonPath=s.join(E,"storage.json"),a.existsSync(this.jsonPath))try{this.data=a.readJSONSync(this.jsonPath)}catch(e){this.data={}}}else this.data={}}store(){this.core.scene===oe.cli&&a.writeJSONSync(this.jsonPath,this.data)}get(e){return this.data[e]}set(e,t){this.data[e]=t,this.refresh()}refresh(){this.store()}}exports.Core=class{constructor(e){this.globalConfig={},this.appConfigMap={},this.projectMap={},this.compilerManagerMap={},this.scene=oe.code;const{scene:o=oe.code}=e;this.scene=o,this.logger=new t.Logger("[xhs-mp-cli]"),this.storage=new re({core:this}),this.globalConfig=this.storage.get("xhs-cli-global-config")||{},this.appConfigMap=this.storage.get("xhs-cli-app-config")||{},this.logger.debug("get initial config:",this.globalConfig,this.appConfigMap),globalThis.logger=this.logger,this.loginManager=new X({core:this,storage:this.storage,logger:this.logger})}setGlobalConfig(e={}){this.globalConfig={...this.globalConfig||{},...e},this.storage.set("xhs-cli-global-config",e),this.logger.log("Set global config done")}getGlobalConfig(){return this.globalConfig||{}}setAppConfig(e={}){const{appId:t,config:o}=e;t?(this.appConfigMap[t]={...this.appConfigMap[t]||{},...o},this.storage.set("xhs-cli-app-config",this.appConfigMap),this.logger.log("Set app config done")):this.logger.error("没有传递 appid 参数")}getAppConfig(e){return this.appConfigMap[e]||{}}createOrGetProject(t){let o=t.projectPath;if(!o)throw new Error("没有配置projectPath");return s.isAbsolute(o)||(o=s.join(k.cwd(),o)),this.projectMap[o]||(this.projectMap[o]=new e.Project(t)),this.projectMap[o]}getCompilerManager(e,t){let o=e.projectPath;if(s.isAbsolute(o)||(o=s.join(k.cwd(),o)),!this.compilerManagerMap[o]){const r=this.createOrGetProject(e);this.compilerManagerMap[o]=new w.ProjectCompilerManager({...t,project:r,logger:this.logger})}return this.compilerManagerMap[o]}async login(e={}){e.verbose&&this.logger.setVerbose(!0);const{type:t="qrcode"}=e;await this.loginManager.login(t)}logout(e){this.loginManager.logout(e)}isTokenAuth(e){return!!this.getAppConfig(e).token}getTokenParams(e){const t=this.getAppConfig(e).token,o="xxxxxxxxxxxxxxxx".replace(/[xy]/g,(e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})),r=e+"#"+t+"#"+o+"#"+H("YYYYMMDDHHmm"),s=T(r);return this.logger.debug("cliToken",r,s),{cliToken:s,nonce:o,appId:e}}checkAppId(e){if(!this.appConfigMap[e])throw new Error(`找不到项目内appId(${e})对应的配置,请先确认appId是否保持一致`)}async preview(e){e.verbose&&this.logger.setVerbose(!0);const t=e.project||{},o=e.buildConfig||{},r=this.createOrGetProject(t);this.checkAppId(r.projectAppId),this.logger.log("Project:",r.projectPath),this.logger.debug("Preview options:",e);const s=this.appConfigMap[r.projectAppId];(null==s?void 0:s.token)?this.logger.debug("Auth by token"):(this.logger.debug("Auth by qrCode"),this.loginManager.isLogin||await this.login());const i=this.getCompilerManager(t,o),a=new te({core:this,project:r,compilerManager:i,logger:this.logger});try{return await a.preview({entry:e.entry})}finally{i.killAll()}}async upload(e){const{project:t,buildConfig:o={},version:r,desc:s,progressCallback:i}=e;e.verbose&&this.logger.setVerbose(!0);const a=this.createOrGetProject(t);this.checkAppId(a.projectAppId),this.logger.log("ProjectPath:",a.projectPath),this.logger.debug("Upload options:",e);const n=this.appConfigMap[a.projectAppId];(null==n?void 0:n.token)?this.logger.debug("Auth by token"):(this.logger.debug("Auth by login"),this.loginManager.isLogin||await this.login());const p=this.getCompilerManager(t,o),c=new W({core:this,project:a,compilerManager:p,logger:this.logger});try{return await c.upload({userVersion:r,userDesc:s,progressCallback:i})}finally{p.killAll()}}};
@@ -1 +1 @@
1
- export declare function getAxios(core: any): import("axios").AxiosStatic;
1
+ export declare function getAxios(core: any): import("axios").AxiosInstance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xhs-mp-core",
3
- "version": "2.0.31",
3
+ "version": "2.0.32-beta.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -29,9 +29,9 @@
29
29
  "querystring": "^0.2.1",
30
30
  "rxjs": "^7.8.1",
31
31
  "tough-cookie": "^4.1.3",
32
- "xhs-mp-compiler-cli": "2.0.31",
33
- "xhs-mp-project": "2.0.31",
34
- "xhs-mp-shared": "2.0.31"
32
+ "xhs-mp-compiler-cli": "2.0.32-beta.0",
33
+ "xhs-mp-project": "2.0.32-beta.0",
34
+ "xhs-mp-shared": "2.0.32-beta.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@rollup/plugin-commonjs": "^25.0.7",