xhs-mp-core 1.0.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.
- package/dist/api/baseApi.d.ts +27 -0
- package/dist/api/uploadApi.d.ts +72 -0
- package/dist/api/userApi.d.ts +40 -0
- package/dist/config/constant.config.d.ts +9 -0
- package/dist/config/dir.config.d.ts +2 -0
- package/dist/config/env.config.d.ts +4 -0
- package/dist/config/url.config.d.ts +11 -0
- package/dist/core.d.ts +69 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/login.d.ts +37 -0
- package/dist/services/baseService.d.ts +18 -0
- package/dist/services/preview/preview.d.ts +30 -0
- package/dist/services/rx-utils.d.ts +46 -0
- package/dist/services/upload/upload.d.ts +20 -0
- package/dist/utils/axios.d.ts +2 -0
- package/dist/utils/cookie.d.ts +12 -0
- package/dist/utils/qrcode.d.ts +1 -0
- package/dist/utils/storage.d.ts +13 -0
- package/dist/utils/utils.d.ts +12 -0
- package/dist/utils/uuid.d.ts +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { Core } from '../core';
|
|
4
|
+
interface IRequestOpts {
|
|
5
|
+
method: 'post' | 'get' | 'put' | 'delete';
|
|
6
|
+
url: string;
|
|
7
|
+
data?: {
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
};
|
|
10
|
+
config?: {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare class BaseApi extends EventEmitter {
|
|
15
|
+
core: Core;
|
|
16
|
+
constructor(props: any);
|
|
17
|
+
protected getProxyConfig(): false | {
|
|
18
|
+
host: string;
|
|
19
|
+
port: string;
|
|
20
|
+
protocol: string;
|
|
21
|
+
};
|
|
22
|
+
request(opts: IRequestOpts): Promise<import("axios").AxiosResponse<any>>;
|
|
23
|
+
protected handleHttpStatus(res: any): any;
|
|
24
|
+
protected handleStatusCode(res: any): any;
|
|
25
|
+
protected handleCode(res: any): any;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { TokenRequest, TokenResponse } from 'xhs-mp-utils';
|
|
2
|
+
import { BaseApi } from './baseApi';
|
|
3
|
+
import { Project } from 'xhs-mp-project';
|
|
4
|
+
export interface IBusinessRoot<T> {
|
|
5
|
+
code: number;
|
|
6
|
+
msg: string;
|
|
7
|
+
guid: any;
|
|
8
|
+
success: boolean;
|
|
9
|
+
data: T;
|
|
10
|
+
}
|
|
11
|
+
export interface ILongTaskRoot<T> {
|
|
12
|
+
result: number;
|
|
13
|
+
success: boolean;
|
|
14
|
+
data: T;
|
|
15
|
+
error_code: number;
|
|
16
|
+
}
|
|
17
|
+
export interface IGetUploadTokenData {
|
|
18
|
+
bucket: string;
|
|
19
|
+
expired: number;
|
|
20
|
+
key_prefix: string;
|
|
21
|
+
host: string;
|
|
22
|
+
sign: string;
|
|
23
|
+
}
|
|
24
|
+
export type IGetUploadToken = IBusinessRoot<IGetUploadTokenData>;
|
|
25
|
+
export type ICreateUploadTask = IBusinessRoot<{
|
|
26
|
+
task_id: string;
|
|
27
|
+
}>;
|
|
28
|
+
export type IUploadCheckVersion = IBusinessRoot<{
|
|
29
|
+
can_upload: boolean;
|
|
30
|
+
can_upload_ext_json: boolean;
|
|
31
|
+
show_msg: string;
|
|
32
|
+
upload_app_id: string;
|
|
33
|
+
}>;
|
|
34
|
+
export type IQueryTaskDetail = ILongTaskRoot<{
|
|
35
|
+
id: string;
|
|
36
|
+
finished_count: number;
|
|
37
|
+
total_count: number;
|
|
38
|
+
progress: number;
|
|
39
|
+
result: {
|
|
40
|
+
file_url: any;
|
|
41
|
+
msg: string;
|
|
42
|
+
extra_json: string;
|
|
43
|
+
business_status: any;
|
|
44
|
+
success: boolean;
|
|
45
|
+
code: number;
|
|
46
|
+
};
|
|
47
|
+
status: number;
|
|
48
|
+
}>;
|
|
49
|
+
export interface IUploadCheckVersionParams {
|
|
50
|
+
version: 'debug' | 'develop';
|
|
51
|
+
}
|
|
52
|
+
export interface IUploadPackageParams {
|
|
53
|
+
appId: string;
|
|
54
|
+
version: 'debug' | 'develop';
|
|
55
|
+
fileUrl: string;
|
|
56
|
+
userVersion?: string;
|
|
57
|
+
userDesc?: string;
|
|
58
|
+
packageMap: {
|
|
59
|
+
[key: string]: string;
|
|
60
|
+
};
|
|
61
|
+
packageMapV2?: {
|
|
62
|
+
[key: string]: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export declare class UploadApi extends BaseApi {
|
|
66
|
+
project: Project;
|
|
67
|
+
constructor(props: any);
|
|
68
|
+
uploadCheckVersion({ version }: IUploadCheckVersionParams): Promise<any>;
|
|
69
|
+
getUploadToken: (params: TokenRequest) => Promise<TokenResponse>;
|
|
70
|
+
createUploadTask(opts: IUploadPackageParams): Promise<any>;
|
|
71
|
+
queryTaskDetail(taskId: string): Promise<any>;
|
|
72
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BaseApi } from './baseApi';
|
|
2
|
+
export interface IBaseRoot<T> {
|
|
3
|
+
alertMsg: string;
|
|
4
|
+
data: T;
|
|
5
|
+
errorCode: any;
|
|
6
|
+
errorMsg: any;
|
|
7
|
+
statusCode: number;
|
|
8
|
+
success: boolean;
|
|
9
|
+
traceLogId: string;
|
|
10
|
+
}
|
|
11
|
+
export type IGenerateQrCodeData = IBaseRoot<{
|
|
12
|
+
qrId: string;
|
|
13
|
+
qrUrl: string;
|
|
14
|
+
}>;
|
|
15
|
+
export interface IQueryQrCodeStatusData {
|
|
16
|
+
authToken: null | string;
|
|
17
|
+
avatar: null | string;
|
|
18
|
+
customerUserType: null | string;
|
|
19
|
+
status: number;
|
|
20
|
+
ticket: null | string;
|
|
21
|
+
userId: null | string;
|
|
22
|
+
}
|
|
23
|
+
export type IQueryQrCodeStatus = IBaseRoot<IQueryQrCodeStatusData>;
|
|
24
|
+
export type ILoginData = Omit<IQueryQrCodeStatusData, 'status'>;
|
|
25
|
+
export interface IBusinessRoot {
|
|
26
|
+
code: number;
|
|
27
|
+
msg: string;
|
|
28
|
+
guid: any;
|
|
29
|
+
success: boolean;
|
|
30
|
+
data: {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export type IGetUserInfo = IBusinessRoot;
|
|
35
|
+
export declare class UserApi extends BaseApi {
|
|
36
|
+
generateQrCode(): Promise<any>;
|
|
37
|
+
queryQrCodeStatus(qrId: string): Promise<any>;
|
|
38
|
+
login(ticket: string): Promise<any>;
|
|
39
|
+
fetchUserInfo(): Promise<any>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const ProjectEvents: {
|
|
2
|
+
readonly CHANGE_EXT_JSON_PATH: "baba:changeExtJsonPath";
|
|
3
|
+
readonly CHANGE_EXT_JSON: "baba:changeExtJson";
|
|
4
|
+
};
|
|
5
|
+
export declare const MAIN_PKG_ROOT = "xhs-main";
|
|
6
|
+
export declare const MiniMode: {
|
|
7
|
+
miniprogram: string;
|
|
8
|
+
minigame: string;
|
|
9
|
+
};
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface IVerbose {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export interface IGlobalConfig {
|
|
5
|
+
proxy?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface IAppConfig {
|
|
8
|
+
appId: string;
|
|
9
|
+
config: {
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface IAppConfigMap {
|
|
14
|
+
[appId: string]: IAppConfig;
|
|
15
|
+
}
|
|
16
|
+
export type ILoginConfig = IVerbose & {
|
|
17
|
+
type?: 'qrcode' | 'token';
|
|
18
|
+
data?: {
|
|
19
|
+
token?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export interface ILibFeatures {
|
|
23
|
+
supportV2?: boolean;
|
|
24
|
+
supportVdom?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface IBaseActionOpts {
|
|
27
|
+
project: {
|
|
28
|
+
projectPath: string;
|
|
29
|
+
watch?: boolean;
|
|
30
|
+
};
|
|
31
|
+
buildConfig?: {
|
|
32
|
+
compileDir?: string;
|
|
33
|
+
nodeJsPath?: string;
|
|
34
|
+
mpDevJsonPath?: string;
|
|
35
|
+
libFeatures?: ILibFeatures;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export type IPreivewOpts = IBaseActionOpts & IVerbose & {
|
|
39
|
+
entry?: {
|
|
40
|
+
path: string;
|
|
41
|
+
query?: string;
|
|
42
|
+
launchMode?: string;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export type IUploadOpts = IBaseActionOpts & IVerbose & {
|
|
46
|
+
version: string;
|
|
47
|
+
desc: string;
|
|
48
|
+
progressCallback?: any;
|
|
49
|
+
};
|
|
50
|
+
export declare class Core {
|
|
51
|
+
private globalConfig;
|
|
52
|
+
private appConfigMap;
|
|
53
|
+
private currentAppConfig;
|
|
54
|
+
private projectMap;
|
|
55
|
+
private compilerMap;
|
|
56
|
+
private logger;
|
|
57
|
+
private loginManager;
|
|
58
|
+
constructor();
|
|
59
|
+
setGlobalConfig(config?: IGlobalConfig): void;
|
|
60
|
+
getGlobalConfig(): IGlobalConfig;
|
|
61
|
+
setAppConfig(appConfig?: IAppConfig): void;
|
|
62
|
+
getAppConfig(appId: any): IAppConfig;
|
|
63
|
+
private getProject;
|
|
64
|
+
private getCompiler;
|
|
65
|
+
login(opts?: ILoginConfig): Promise<void>;
|
|
66
|
+
logout(): void;
|
|
67
|
+
preview(opts: IPreivewOpts): Promise<unknown>;
|
|
68
|
+
upload(opts: IUploadOpts): Promise<unknown>;
|
|
69
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("xhs-mp-compiler"),t=require("xhs-mp-project"),r=require("xhs-mp-utils"),s=require("events"),o=require("axios"),i=require("path"),a=require("os"),n=require("fs-extra"),l=require("fs"),p=require("rxjs"),c=require("lodash"),h=require("rxjs/operators"),u=require("qrcode-terminal"),d=require("jimp"),g=require("jsqr");function S(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var f=S(i),m=S(l);const v=()=>({isSit:"false"===process.env.XHS_IS_PROD,isProd:"true"===process.env.XHS_IS_PROD}),w=require("process").env.XHS_BUSINESS_SIT_HOST||"https://business.sit.xiaohongshu.com",C=require("process").env.XHS_CUSTOMER_SIT_HOST||"https://customer.sit.xiaohongshu.com",y={BUSINESS_HOST:v().isSit?w:"https://business.xiaohongshu.com",CUSTOMER_HOST:v().isSit?C:"https://customer.xiaohongshu.com",CUSTOMER_SERVICE_ID:v().isSit?C.replace(/https?:\/\/customer/,"file://miniapp-open"):"file://miniapp-open.xiaohongshu.com"},x={generateQrCode:`${y.CUSTOMER_HOST}/api/cas/generateQrCode`,queryQrCodeStatus:`${y.CUSTOMER_HOST}/api/cas/queryQrCodeStatus`,session:`${y.BUSINESS_HOST}/api/eros/mp/red/code/session`,getUserInfo:`${y.BUSINESS_HOST}/api/eros/mp/red/code/user/info`};require("crypto"),require("net");const k=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 b(e){return e.replace(/\\/g,"/")}const _=b(i.join(a.homedir(),"@xhs-toolkit"));n.ensureDirSync(_);const P=b(i.join(_,"xhs-storage"));n.ensureDirSync(P);const j=require("tough-cookie");var I=new class{constructor(){this.cookiePath=i.join(P,"cookie.json");const e=this.getSerializeData();Object.keys(e).length?this.cookieJar=j.CookieJar.deserializeSync(e):this.cookieJar=new j.CookieJar}getSerializeData(){let e={};return n.existsSync(this.cookiePath)&&(e=n.readJSONSync(this.cookiePath)),e}save(){const e=this.cookieJar.serializeSync();n.writeJSONSync(this.cookiePath,e)}clear(){n.removeSync(this.cookiePath)}set(e){const t=e.headers["set-cookie"]||[],r=e.config.url;t.forEach((e=>{const t=j.Cookie.parse(e);if(t.domain){const e=new j.Cookie(t);this.cookieJar.setCookieSync(e,r)}})),this.save()}get(e){return this.cookieJar.getCookieStringSync(e)}};o.defaults.baseURL=y.BUSINESS_HOST,o.interceptors.request.use((e=>{const{url:t,data:r,baseURL:s=""}=e;let i=o.getUri(e);if(/^https?:/.test(i))try{const e=new URL(t);i=i.replace(e.origin,"")}catch(e){i=t}const a=I.get(t);return e.headers={...e.headers,Cookie:a},e.headers["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) @xhs/mp-ide/2.0.0 Chrome/116.0.5845.228 Electron/26.4.0 Safari/537.36 discover/2.0.0 xhsminiapp/latest",e})),o.interceptors.response.use((e=>(I.set(e),e))),o.interceptors.response.use((e=>{var t;const{config:r,data:s}=e;if((null===(t=r.url)||void 0===t?void 0:t.startsWith(`${y.BUSINESS_HOST}/api/eros/mp/red`))&&!s.success)throw new Error(`${s.msg}`);return e}),(async e=>{const{response:t={}}=e;if(401===t.status&&t.data&&-240309===t.data.code)throw new Error("登陆失效,请重新登陆");return t.data&&t.data.msg&&401===t.status&&console.warn("未登录,请先登录!"),Promise.reject(e)}));class q extends s.EventEmitter{constructor(e){super(),this.core=e.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}}return!1}async request(e){const{method:t,url:r,data:s,config:i={}}=e;return await o[t](r,s,{...i,proxy:this.getProxyConfig()})}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 E=require("path"),M=require("fs-extra"),U=e=>{if(!M.existsSync(e))return"";let t="";try{t=JSON.stringify(M.readJSONSync(e))}catch(t){console.warn(`readJson error: ${e}`)}return t};class T extends q{constructor(e){super(e),this.getUploadToken=async e=>{const t=await this.request({method:"get",url:`${y.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 uploadCheckVersion({version:e}){const t=this.project.projectConfig,r=t.entryJsonPath,s=E.resolve(t.extJsonPath),o=U(r),i=U(s),a=t.projectAppId,n=`${y.BUSINESS_HOST}/api/eros/mp/red/code/${a}/validate/version/${e}`,l=await this.request({method:"post",url:n,data:{app_json:o,ext_json:i}});return this.handleCode(this.handleHttpStatus(l))}async createUploadTask(e){const{version:t,fileUrl:r,userVersion:s,userDesc:o,appId:i,packageMap:a,packageMapV2:n}=e,l=`${y.BUSINESS_HOST}/api/eros/mp/red/code/${i}/upload/version/${t}`,p=await this.request({method:"post",url:l,data:{file_url:r,user_version:s,user_desc:o,package_map:a,package_map_v2:n,cloud_type:4}});return this.handleCode(this.handleHttpStatus(p))}async queryTaskDetail(e){const t=await this.request({method:"get",url:`${y.BUSINESS_HOST}/api/eros/mp/red/code/task/detail`,data:{params:{task_id:e}}});return this.handleCode(this.handleHttpStatus(t))}}class O extends s{constructor(e){super(),this.core=e.core,this.project=e.project,this.compiler=e.compiler,this.logger=e.logger}}const D=(e,{zipPath:t,type:s,root:o},i,a)=>{const n=new r.Uploader({bizName:"fe",scene:"fe-platform",getToken:e.getUploadToken});return new p.Observable((e=>{setTimeout((()=>{const r=`${"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`,i=m.readFileSync(f.resolve(t)),l=m.statSync(f.resolve(t));function p(){return new Promise(((e,p)=>{setTimeout((()=>{n.post({Body:i,fileInfo:{name:r,type:"application/octet-stream",size:l.size},FilePath:f.resolve(t)}).then((r=>{var i;return 0!==r.code?p(new Error(`${t}上传失败:${r.msg}`)):(null===(i=null==r?void 0:r.data)||void 0===i?void 0:i.fileId)?(e({fileId:r.data.fileId,type:s,root:o}),void(null==a||a())):p(new Error(`${t}上传失败`))}))}),500)}))}p().catch(p).catch(p).catch(p).catch(p).then((t=>{e.next(t),e.complete()})).catch((t=>{e.error(t)}))}),500)}))},L=(e,t)=>e.reduce(((e,r)=>{let s={};return r.type===t&&(s={[r.root]:r.fileId}),{...e,...s}}),{}),$=({uploadApi:e,uploadRes:t,appId:r,version:s,userDesc:o,userVersion:i})=>{const a=t.filter((e=>"v0"===e.type))[0].fileId,n=L(t,"v1"),l=L(t,"v2");return p.from(e.createUploadTask({version:s,fileUrl:a,appId:r,packageMap:n,packageMapV2:c.isEmpty(l)?void 0:l,userDesc:o,userVersion:i})).pipe(p.switchMap((t=>{const{task_id:r}=t;return p.interval(1500).pipe(p.switchMap((()=>((e,t)=>p.from(e.queryTaskDetail(t)).pipe(p.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}))))(e,r))),p.first((e=>3===e.status)))})))};class z extends O{constructor(t){super(t),this.doUpload=t=>{const{progressCallback:r,userVersion:s,userDesc:o}=t;if(!(null==s?void 0:s.trim()))throw new Error("请填写上传版本号");if(!(null==o?void 0:o.trim()))throw new Error("请填写版本描述");const i=()=>{var t,r;this.compiler.kill(e.COMPILE_ENTRY.upload),null===(t=this.taskSubscription)||void 0===t||t.unsubscribe(),this.taskSubscription=null,null===(r=this.uploadPromise)||void 0===r||r.resolve(null),this.uploadPromise=null,this.logger.log("Upload Done!!!")},a=t=>{var s,o;null==r||r(-1),null===(s=this.taskSubscription)||void 0===s||s.unsubscribe(),this.taskSubscription=null,this.compiler.kill(e.COMPILE_ENTRY.upload),this.logger.log("Upload Error:",t.toString()),null===(o=this.uploadPromise)||void 0===o||o.reject(t),this.uploadPromise=null};try{const t=this.project.projectConfig.projectAppId;this.logger.log("Check appid auth..."),this.taskSubscription=p.from(this.uploadApi.uploadCheckVersion({version:"develop"})).pipe(p.switchMap((t=>{const{can_upload:o,can_upload_ext_json:i,upload_app_id:a,show_msg:n}=t;if(!o)throw new Error(n);if(!a)throw new Error("请检查是否该appid无权限");return null==r||r(5),p.from(this.compiler.compileAndZip({entryType:e.COMPILE_ENTRY.upload,can_upload_ext_json:i,upload_app_id:a,pkgInfo:{version:s}}))})),p.switchMap((e=>{null==r||r(30),this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages to cos...");const t=e.map(((t,s)=>D(this.uploadApi,{zipPath:t.zipPath,type:t.type,root:t.root},0,(()=>{null==r||r(30+45/e.length*(s+1))}))));return p.forkJoin(t)})),p.switchMap((e=>(null==r||r(80),this.logger.log("Upload packages info..."),$({uploadApi:this.uploadApi,uploadRes:e,appId:t,version:"develop",userVersion:s,userDesc:o}))))).subscribe({next:e=>{null==r||r(100),i()},error:e=>{a(e)}})}catch(e){a(e)}},this.uploadApi=new T(t)}upload(e){return new Promise(((t,r)=>{this.uploadPromise={resolve:t,reject:r},this.doUpload(e)}))}}class A extends q{async generateQrCode(){const e=await this.request({method:"post",url:x.generateQrCode,data:{subsystem:"business"}});return this.handleStatusCode(this.handleHttpStatus(e))}async queryQrCodeStatus(e){const t=await this.request({method:"get",url:x.queryQrCodeStatus,data:{params:{qrId:e,service:y.CUSTOMER_SERVICE_ID}}});return this.handleStatusCode(this.handleHttpStatus(t))}async login(e){const t=await this.request({method:"post",url:x.session,data:{ticket:e,clientId:y.CUSTOMER_SERVICE_ID}});return this.handleHttpStatus(t).data}async fetchUserInfo(){const e=await this.request({method:"get",url:x.getUserInfo});return this.handleCode(this.handleHttpStatus(e))}}var H=new class{constructor(){if(this.data={},this.jsonPath=i.join(P,"storage.json"),n.existsSync(this.jsonPath))try{this.data=n.readJSONSync(this.jsonPath)}catch(e){this.data={}}}get(e){return this.data[e]}set(e,t){this.data[e]=t,this.refresh()}refresh(){n.writeJSONSync(this.jsonPath,this.data)}};class N{get isLogin(){return this._isLogin}set isLogin(e){this._isLogin=e}get userInfo(){return this._userInfo}set userInfo(e){this._userInfo=e,H.set("userInfo",e)}constructor(e){var t;this.qrCodeStatusData={},this.startPollingSub=null,this.loginPromise={},this.transformUserInfo=e=>{const{nick:t,avatar:r,desc:s,gender:o}=(i=e,["nick","avatar","desc","gender"].reduce(((e,t)=>({...e,[t]:i[t]})),{}));var i;return{nickName:t,avatar:r,userId:"",desc:s,gender:o}},this.queryQrCodeStatus=e=>p.from(this.userApi.queryQrCodeStatus(e)),this.doLogin=async e=>{const{resolve:t,reject:r}=this.loginPromise;this.loginPromise=null;try{const s=await this.userApi.login(e);if(!s.success)return void r(new Error(s.msg));const o=await this.userApi.fetchUserInfo(),i=this.transformUserInfo(o);i.userInfoData=o,t(i)}catch(e){return void r(new Error(e.message))}},this.startPolling=()=>(this.qrCodeStatusData.isLoading=!0,this.qrCodeStatusData.expired=!1,p.from(p.defer((()=>this.userApi.generateQrCode()))).pipe(h.tap((e=>{this.qrUrl=e.qrUrl,this.qrCodeStatusData.isLoading=!1,this.showQrCode(),setTimeout((()=>{this.qrCodeStatusData.expired=!0,this.stopPolling()}),6e4)})),h.exhaustMap((({qrUrl:e,qrId:t})=>p.interval(2e3).pipe(h.switchMap((()=>this.queryQrCodeStatus(t))),h.tap((e=>{if(4===e.status)throw new Error("retry login");1===e.status&&(this.stopPolling(),this.doLogin(e.ticket))}))))),h.takeWhile((e=>1!==e.status)),h.retry(5))),this.stopPolling=()=>{this.startPollingSub&&(this.startPollingSub.unsubscribe(),this.startPollingSub=null)},this.logger=e.logger,this.userApi=new A(e),this.qrCodeStatusData={isLoading:!1,expired:!1},this._userInfo=H.get("userInfo")||{},this.isLogin=!!(null===(t=this.userInfo)||void 0===t?void 0:t.nickName)}showQrCode(){u.generate(this.qrUrl,{small:!0})}async login(e,t){if(this.isLogin)this.logger.log("Had Login!!!");else{this.isLogin=!1,this.logger.log("Login...");try{let r;r="qrcode"===e?await this.loginByQrcode():await this.loginByToken(t),this.isLogin=!0,this.userInfo=r,this.logger.log("Login success")}catch(e){throw this.logger.log("Login fail:",e.message),this.isLogin=!0,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)}}))}async loginByToken(e){}logout(){this.logger.log("Logout..."),this.isLogin=!1,this.userInfo={},I.clear(),this.logger.log("Logout Success!!!")}}const R=async(e,t={},r,s)=>{let o=e.getCompileEntryPage();o={...o,...t};const{path:i,query:a,launchMode:n}=o;try{let e=await(async e=>{const t=Buffer.from(e.replace(/^data:image\/[a-z]+;base64,/,""),"base64"),r=await d.read(t),s={data:new Uint8ClampedArray(r.bitmap.data),width:r.bitmap.width,height:r.bitmap.height},o=g(s.data,s.width,s.height);if(!o)throw new Error("QR code not found in the image.");return o.data})(r);return i&&(e=e.replace("_develop",`_develop${i.startsWith("/")?"":"/"}${i}`)),a&&(e+=`&${a}`),"halfPageNativeFunctionalized"===n&&(e+="&runtime_mode=2"),e}catch(e){s.error("二维码解码失败:",e)}};class B extends O{constructor(e){super(e),this.progressData={},this.previewData={},this.calcSize=e=>{var t,r;const s=this.project.projectConfig,o=(null===(t=null==s?void 0:s.flags)||void 0===t?void 0:t.enableV2Preivew)?"v2":"v1",i=(null===(r=null==e?void 0:e.filter)||void 0===r?void 0:r.call(e,(e=>e.type===o)).sort(((e,t)=>t.zipSize-e.zipSize)))||[];this.previewData.subPkgs=i.map(((e,t)=>({key:t,path:e.root,size:k(e.zipSize)})));const a=i.reduce(((e,t)=>t.zipSize+e),0)||0;this.previewData.zipSize=k(a)},this.uploadApi=new T(e),this.progressData={},this.previewData={}}preview(e){return new Promise(((t,r)=>{this.previewPromise={resolve:t,reject:r},this.doPreview(e)}))}doPreview(t){this.progressData.previewIsLoading=!0;const r=this.project.projectConfig.projectAppId,s=Date.now(),o=async r=>{var o,i;const a=JSON.parse(r.result.extra_json);this.previewData.qrcodeUrl=await R(this.project.projectConfig,t.entry,a.qrcode,this.logger),this.showQrCode(this.previewData.qrcodeUrl),this.previewData.previewTotalTime=+((Date.now()-s)/1e3).toFixed(1),this.progressData.previewIsLoading=!1,this.compiler.kill(e.COMPILE_ENTRY.preview),null===(o=this.taskSubscription)||void 0===o||o.unsubscribe(),this.taskSubscription=null,null===(i=this.previewPromise)||void 0===i||i.resolve({qrcodeUrl:this.previewData.qrcodeUrl}),this.previewPromise=null,this.logger.log("Preview Done!!!")},i=t=>{var r,s;this.compiler.kill(e.COMPILE_ENTRY.preview),null===(r=this.taskSubscription)||void 0===r||r.unsubscribe(),this.taskSubscription=null,null===(s=this.previewPromise)||void 0===s||s.reject(t),this.previewPromise=null,this.logger.log("Preview Error:",t.toString())};this.logger.log("Check appid auth..."),this.taskSubscription=p.from(p.defer((()=>this.uploadApi.uploadCheckVersion({version:"debug"})))).pipe(p.switchMap((t=>{const{can_upload_ext_json:r,upload_app_id:s}=t;if(!s)throw new Error("请检查是否该appid无权限");return p.from(this.compiler.compileAndZip({entryType:e.COMPILE_ENTRY.preview,can_upload_ext_json:r,upload_app_id:s}))})),p.tap((e=>{this.calcSize(e)})),p.switchMap((e=>{this.emit("compile-and-zip-status",{status:"uploading"}),this.logger.log("Upload packages to cos...");const t=e.map(((e,t)=>D(this.uploadApi,{zipPath:e.zipPath,type:e.type,root:e.root})));return p.forkJoin(t)})),p.switchMap((e=>(this.logger.log("Upload packages info..."),$({uploadApi:this.uploadApi,uploadRes:e,appId:r,version:"debug"}))))).subscribe({next:e=>o(e),error:e=>i(e)})}showQrCode(e){u.generate(e,{small:!0})}}exports.Core=class{constructor(){this.globalConfig={},this.appConfigMap={},this.currentAppConfig={},this.projectMap={},this.compilerMap={},this.globalConfig=H.get("globalConfig")||{},this.logger=new r.Logger("[xhs-mp-core]"),this.loginManager=new N({core:this,logger:this.logger})}setGlobalConfig(e={}){this.logger.log("Set global config..."),this.globalConfig={...this.globalConfig||{},...e},H.set("globalConfig",e),this.logger.log("Set global config done")}getGlobalConfig(){return this.globalConfig||{}}setAppConfig(e={}){const{appId:t,config:r}=e;this.appConfigMap[t]={...this.appConfigMap[t]||{},...r},this.currentAppConfig=e}getAppConfig(e){return this.appConfigMap[e]||{}}getProject(e){const{projectPath:r}=e;if(!r)throw new Error("没有配置projectPath");return this.projectMap[r]||(this.projectMap[r]=new t.Project(e)),this.projectMap[r]}getCompiler(t,r){const{projectPath:s}=t;if(!this.compilerMap[s]){const o=this.getProject(t);this.compilerMap[s]=new e.Compiler({...r,project:o,logger:this.logger})}return this.compilerMap[s]}async login(e={}){e.verbose&&this.logger.setVerbose(!0);const{type:t="qrcode",data:r}=e;await this.loginManager.login(t,{...this.currentAppConfig||{},...r})}logout(){this.loginManager.logout()}async preview(e){e.verbose&&this.logger.setVerbose(!0),this.loginManager.isLogin||await this.login({});const t=e.project||{},r=e.buildConfig||{},s=this.getProject(t),o=this.getCompiler(t,r),i=new B({core:this,project:s,compiler:o,logger:this.logger});return await i.preview({entry:e.entry})}async upload(e){e.verbose&&this.logger.setVerbose(!0),this.loginManager.isLogin||await this.login();const{project:t,buildConfig:r={},version:s,desc:o,progressCallback:i}=e,a=this.getProject(t),n=this.getCompiler(t,r),l=new z({core:this,project:a,compiler:n,logger:this.logger});return await l.upload({userVersion:s,userDesc:o,progressCallback:i})}};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/config/env.config.ts","../src/config/url.config.ts","../src/utils/utils.ts","../src/config/dir.config.ts","../src/utils/cookie.ts","../src/utils/axios.ts","../src/api/baseApi.ts","../src/api/uploadApi.ts","../src/services/baseService.ts","../src/services/rx-utils.ts","../src/utils/uuid.ts","../src/services/upload/upload.ts","../src/api/userApi.ts","../src/utils/storage.ts","../src/login.ts","../src/utils/qrcode.ts","../src/services/preview/preview.ts","../src/core.ts"],"sourcesContent":["\n// 接口环境\nexport const getXHSAPIENV = () => ({\n isSit: process.env.XHS_IS_PROD === 'false',\n isProd: process.env.XHS_IS_PROD === 'true'\n })\n","import { getXHSAPIENV } from './env.config'\nconst BUSINESS_SIT_HOST =\n require('process').env.XHS_BUSINESS_SIT_HOST || 'https://business.sit.xiaohongshu.com'\n\nconst CUSTOMER_SIT_HOST =\n require('process').env.XHS_CUSTOMER_SIT_HOST || 'https://customer.sit.xiaohongshu.com'\n\n\nexport const domain = {\n BUSINESS_HOST: getXHSAPIENV().isSit ? BUSINESS_SIT_HOST : 'https://business.xiaohongshu.com',\n CUSTOMER_HOST: getXHSAPIENV().isSit ? CUSTOMER_SIT_HOST : 'https://customer.xiaohongshu.com',\n CUSTOMER_SERVICE_ID: getXHSAPIENV().isSit\n ? CUSTOMER_SIT_HOST.replace(/https?:\\/\\/customer/, 'file://miniapp-open')\n : 'file://miniapp-open.xiaohongshu.com'\n }\n\n export const api = {\n generateQrCode: `${domain.CUSTOMER_HOST}/api/cas/generateQrCode`,\n queryQrCodeStatus: `${domain.CUSTOMER_HOST}/api/cas/queryQrCodeStatus`,\n session: `${domain.BUSINESS_HOST}/api/eros/mp/red/code/session`,\n getUserInfo: `${domain.BUSINESS_HOST}/api/eros/mp/red/code/user/info`,\n }\n ","import * as path from 'path'\n\nconst crypto = require('crypto')\nconst net = require('net')\n\nexport const throttle = (fn: any, wait = 100) => {\n let time: number | null = null\n return function (...args: any[]) {\n if (!time || Date.now() - time > wait) {\n time = Date.now()\n // @ts-ignore\n fn.apply(this, args)\n }\n }\n}\n\nexport const debounce = (func: any, wait = 300) => {\n let timer: any = null\n return (...args: any[]) => {\n clearTimeout(timer)\n timer = setTimeout(() => {\n func.apply(this, args)\n }, wait)\n }\n}\n\nexport const fileSize = (size: number) => {\n if (!size) return ''\n\n const base = 1024\n\n if (size < base) {\n return `${size}B`\n } if (size < base ** 2) {\n return `${(size / base).toFixed(2)}KB`\n } if (size < base ** 3) {\n return `${(size / base ** 2).toFixed(2)}MB`\n } if (size < base ** 4) {\n return `${(size / base ** 3).toFixed(2)}GB`\n }\n return `${(size / base ** 4).toFixed(2)}T`\n\n}\n\nexport function getMd5(str) {\n const hash = crypto.createHash('md5')\n hash.update(str)\n const md5 = hash.digest('hex')\n return md5\n}\n\nexport function getType(object: any): string {\n return Object.prototype.toString.call(object).toLowerCase().split(' ')[1].replace(']', '')\n}\n\nexport function normalizePath(str) {\n return str.replace(/\\\\/g, '/')\n}\n\nexport const compareVersion = function (v1Str: string, v2Str: string): number {\n if (typeof v1Str === \"undefined\" || typeof v2Str === \"undefined\") {\n console.error('请指定要对比的两个版本号', {v1Str, v2Str})\n return 0\n }\n const v1 = v1Str.split('.')\n const v2 = v2Str.split('.')\n const maxLength = Math.max(v1.length, v2.length)\n // 补全\n while (v1.length < maxLength) {\n v1.push('0')\n }\n while (v2.length < maxLength) {\n v2.push('0')\n }\n for (let i = 0; i < maxLength; i++) {\n const num1 = parseInt(v1[i], 10)\n const num2 = parseInt(v2[i], 10)\n\n if (num1 > num2) {\n return 1\n } if (num1 < num2) {\n return -1\n }\n }\n\n return 0\n}\n\nexport function picker<T>(obj: any, pick: string[]) {\n\treturn pick.reduce(\n\t\t(pre, next) => ({ ...pre, [next]: obj[next] }),\n\t\t{}\n\t) as T\n}\n\nexport const formatPath = (pathStr: string = '') => pathStr.split(path.sep).join(path.posix.sep)\n\nexport const toUnixPath = (pathStr: string = '') => pathStr.split(path.sep).join(path.posix.sep)\n\nexport const unixJoin = (...paths: string[]) => toUnixPath(path.join(...paths))\n\nexport const unixResolve = (...paths: string[]) => toUnixPath(path.resolve(...paths))\n","import { normalizePath } from \"../utils/utils\"\nimport os from 'os'\nimport path from 'path'\nimport fse from 'fs-extra'\n\nexport const baseDirPath = normalizePath(path.join(os.homedir(), '@xhs-toolkit'))\nfse.ensureDirSync(baseDirPath)\n\nexport const mpStoragePath = normalizePath(path.join(baseDirPath, 'xhs-storage'))\nfse.ensureDirSync(mpStoragePath)","const tough = require('tough-cookie')\nimport { mpStoragePath } from 'config/dir.config'\nimport path from 'path'\nimport fse from 'fs-extra'\n\nclass CookieTool {\n cookieJar: any\n cookiePath: string\n\n constructor() {\n this.cookiePath = path.join(mpStoragePath, 'cookie.json')\n const data = this.getSerializeData()\n if (Object.keys(data).length) {\n this.cookieJar = tough.CookieJar.deserializeSync(data)\n } else {\n this.cookieJar = new tough.CookieJar()\n }\n }\n\n getSerializeData() {\n let json = {}\n if (fse.existsSync(this.cookiePath)) {\n json = fse.readJSONSync(this.cookiePath)\n }\n return json\n }\n\n save() {\n const data = this.cookieJar.serializeSync()\n fse.writeJSONSync(this.cookiePath, data)\n }\n\n\n clear() {\n fse.removeSync(this.cookiePath)\n }\n\n set(res) {\n const cookies = res.headers['set-cookie'] || []\n const url = res.config.url\n cookies.forEach(cookieStr => {\n const cookieMap = tough.Cookie.parse(cookieStr)\n if (cookieMap.domain) {\n const cookie = new tough.Cookie(cookieMap)\n this.cookieJar.setCookieSync(cookie, url)\n }\n })\n this.save()\n }\n\n get(url) {\n const cookie = this.cookieJar.getCookieStringSync(url)\n return cookie\n }\n}\n\nexport default new CookieTool()\n","import {domain} from '../config/url.config'\nimport axios, {AxiosRequestConfig} from 'axios'\nimport cookitTook from './cookie'\naxios.defaults.baseURL = domain.BUSINESS_HOST\n\naxios.interceptors.request.use((config: AxiosRequestConfig) => {\n const {url, data, baseURL = ''} = config\n let uri: any = axios.getUri(config)\n // uri 需要拿 path,而不是整个 url\n if (/^https?:/.test(uri)) {\n try {\n const urlObj = new URL(url as string)\n uri = uri.replace(urlObj.origin, '')\n } catch (e) {\n uri = url\n }\n }\n\n\n const cookies = cookitTook.get(url)\n config.headers = {\n ...config.headers,\n Cookie: cookies,\n }\n\n config.headers['User-Agent'] = `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) @xhs/mp-ide/2.0.0 Chrome/116.0.5845.228 Electron/26.4.0 Safari/537.36 discover/2.0.0 xhsminiapp/latest`\n\n return config\n})\n\naxios.interceptors.response.use(\n response => {\n // 保存cookies\n cookitTook.set(response)\n return response\n }\n)\n\n/* 拦截错误的请求 */\naxios.interceptors.response.use(\n response => {\n // Any status code that lie within the range of 2xx cause this function to trigger\n // Do something with response data\n const {config, data} = response\n if (config.url?.startsWith(`${domain.BUSINESS_HOST}/api/eros/mp/red`) && !data.success) {\n throw new Error(`${data.msg}`)\n }\n return response\n },\n async error => {\n const {response = {}} = error\n if (response.status === 401 && response.data && response.data.code === -240309) {\n throw new Error(`登陆失效,请重新登陆`)\n }\n\n if (response.data && response.data.msg) {\n if (response.status === 401) {\n console.warn('未登录,请先登录!')\n }\n }\n return Promise.reject(error)\n }\n)\n\nexport default axios\n","import {EventEmitter} from 'events'\nimport axios from '../utils/axios'\nimport {Core} from '../core'\n\ninterface IRequestOpts {\n method: 'post' | 'get' | 'put' | 'delete'\n url: string\n data?: {\n [key: string]: any\n }\n config?: {\n [key: string]: any\n }\n}\nexport class BaseApi extends EventEmitter {\n core: Core\n constructor(props) {\n super()\n this.core = props.core\n }\n\n protected getProxyConfig() {\n const {proxy} = this.core.getGlobalConfig()\n if (proxy) {\n const urlObj = new URL(proxy)\n const proxyConfig = {\n host: urlObj.hostname,\n port: urlObj.port,\n protocol: urlObj.protocol\n }\n return proxyConfig\n } else {\n return false\n }\n }\n\n async request(opts: IRequestOpts) {\n const {method, url, data, config = {}} = opts\n const res = await axios[method](url, data, {\n ...config,\n // @ts-ignore\n proxy: this.getProxyConfig()\n })\n return res\n }\n\n protected handleHttpStatus(res) {\n if (res.status !== 200) {\n throw new Error(`request fail, code: ${res.status}, errMsg: ${res.status}`)\n }\n return res\n }\n\n protected handleStatusCode(res) {\n const {data} = res\n if (data.statusCode !== 200) {\n throw new Error(`request fail, code: ${data.statusCode}, errMsg: ${data.errorMsg}`)\n }\n return data.data\n }\n\n protected handleCode(res) {\n const {data} = res\n if (data.code !== 0 && data.error_code !== 0) {\n throw new Error(`request fail, code: ${data.code || data.error_code}, errMsg: ${data.msg}`)\n }\n return data.data\n }\n}\n","import {TokenRequest, TokenResponse} from 'xhs-mp-utils'\nimport axios from '../utils/axios'\nimport {BaseApi} from './baseApi'\nimport {Project} from 'xhs-mp-project'\nimport {domain} from '../config/url.config'\n\nconst path = require('path')\nconst fs = require('fs-extra')\n\nexport interface IBusinessRoot<T> {\n code: number\n msg: string\n guid: any\n success: boolean\n data: T\n}\n\nexport interface ILongTaskRoot<T> {\n result: number\n success: boolean\n data: T\n error_code: number\n}\n\nexport interface IGetUploadTokenData {\n bucket: string\n expired: number\n key_prefix: string\n host: string\n sign: string\n}\n\nexport type IGetUploadToken = IBusinessRoot<IGetUploadTokenData>\n\nexport type ICreateUploadTask = IBusinessRoot<{\n task_id: string\n}>\n\nexport type IUploadCheckVersion = IBusinessRoot<{\n can_upload: boolean\n can_upload_ext_json: boolean\n show_msg: string\n upload_app_id: string\n}>\n\nexport type IQueryTaskDetail = ILongTaskRoot<{\n id: string\n finished_count: number\n total_count: number\n progress: number\n result: {\n file_url: any\n msg: string\n extra_json: string\n business_status: any\n success: boolean\n code: number\n }\n status: number\n}>\n\nexport interface IUploadCheckVersionParams {\n version: 'debug' | 'develop'\n // appJson: string;\n // extJson: string;\n // projectConfigJson: string;\n}\n\nexport interface IUploadPackageParams {\n appId: string\n version: 'debug' | 'develop'\n fileUrl: string\n userVersion?: string\n userDesc?: string\n packageMap: {\n [key: string]: string\n }\n packageMapV2?: {\n [key: string]: string\n }\n}\n\nconst readJsonStr = (_path: string) => {\n if (!fs.existsSync(_path)) return ''\n let res = ''\n try {\n res = JSON.stringify(fs.readJSONSync(_path))\n } catch (error) {\n console.warn(`readJson error: ${_path}`)\n }\n return res\n}\n\nexport class UploadApi extends BaseApi {\n project: Project\n\n constructor(props) {\n super(props)\n this.project = props.project\n }\n\n async uploadCheckVersion({version}: IUploadCheckVersionParams) {\n const projectConfig = this.project.projectConfig\n const appJsonPath = projectConfig.entryJsonPath\n const extJsonPath = path.resolve(projectConfig.extJsonPath)\n const appJson = readJsonStr(appJsonPath)\n const extJson = readJsonStr(extJsonPath)\n const appId = projectConfig.projectAppId\n const requestPath = `${domain.BUSINESS_HOST}/api/eros/mp/red/code/${appId}/validate/version/${version}`\n const res = await this.request({\n method: 'post',\n url: requestPath,\n data: {\n app_json: appJson,\n ext_json: extJson\n }\n })\n return this.handleCode(this.handleHttpStatus(res))\n }\n\n getUploadToken = async (params: TokenRequest): Promise<TokenResponse> => {\n const res = await this.request({\n method: 'get',\n url: `${domain.BUSINESS_HOST}/api/eros/mp/red/code/upload/permit`,\n data: {\n params,\n withCredentials: true\n }\n })\n return this.handleCode(this.handleHttpStatus(res))\n }\n\n async createUploadTask(opts: IUploadPackageParams) {\n const {version, fileUrl, userVersion, userDesc, appId, packageMap, packageMapV2} = opts\n const requestPath = `${domain.BUSINESS_HOST}/api/eros/mp/red/code/${appId}/upload/version/${version}`\n const res = await this.request({\n method: 'post',\n url: requestPath,\n data: {\n file_url: fileUrl,\n user_version: userVersion,\n user_desc: userDesc,\n package_map: packageMap,\n package_map_v2: packageMapV2,\n cloud_type: 4\n }\n })\n const data = this.handleCode(this.handleHttpStatus(res))\n return data\n }\n\n async queryTaskDetail(taskId: string) {\n const res = await this.request({\n method: 'get',\n url: `${domain.BUSINESS_HOST}/api/eros/mp/red/code/task/detail`,\n data: {\n params: {task_id: taskId}\n }\n })\n const data = this.handleCode(this.handleHttpStatus(res))\n return data\n }\n}\n","import { Project } from \"xhs-mp-project\";\nimport { Compiler } from \"xhs-mp-compiler\"\nimport EventEmitter from \"events\";\nimport { Core } from \"../core\";\n\nexport interface IBaseServiceProps {\n core: Core\n project: Project\n compiler: Compiler\n logger: any\n}\n\nexport class BaseService extends EventEmitter {\n core: Core;\n project: Project;\n compiler: Compiler\n logger: any;\n\n\n constructor(props: IBaseServiceProps) {\n super();\n this.core = props.core\n this.project = props.project\n this.compiler = props.compiler\n this.logger = props.logger\n }\n}","import * as path from 'path'\nimport * as fs from 'fs'\nimport {Uploader as CosUploader} from 'xhs-mp-utils'\nimport {guid} from '../utils/uuid'\nimport {first, from, interval, map, Observable, switchMap} from 'rxjs'\nimport {isEmpty} from 'lodash'\n\nexport interface IUploadCheckVersionParams {\n version: 'debug' | 'develop'\n // appJson: string;\n // extJson: string;\n // projectConfigJson: string;\n}\n\nexport type ArchType = 'v0' | 'v1' | 'v2'\n\nexport type IZipResult = {\n type: ArchType\n zipPath: string\n zipSize: number\n root: string\n originSize: number\n}\n\nexport type UploadRes = {\n cdnFileUrl?: string\n fileId: string\n type: ArchType\n root: string\n}\n\nexport const uploadFile2 = (\n uploadApi,\n {zipPath, type, root},\n index: number,\n successCallback?: () => void\n) => {\n const uploader = new CosUploader({\n bizName: 'fe', // temp 后端不消费\n scene: 'fe-platform', // temp 后端不消费\n getToken: uploadApi.getUploadToken\n })\n return new Observable<UploadRes>(subscriber => {\n setTimeout(() => {\n const uuid = guid()\n\n const fileName = `${uuid}-xhs-example.zip`\n const file = fs.readFileSync(path.resolve(zipPath))\n const stats = fs.statSync(path.resolve(zipPath))\n // console.log(file, 'uploader:before:::====🚀🚀🚀🚀🚀')\n function upload() {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n uploader\n .post({\n Body: file,\n fileInfo: {\n name: fileName,\n type: 'application/octet-stream',\n size: stats.size\n },\n FilePath: path.resolve(zipPath)\n })\n .then(res => {\n if (res.code !== 0) {\n return reject(new Error(`${zipPath}上传失败:${res.msg}`))\n }\n if (!res?.data?.fileId) {\n return reject(new Error(`${zipPath}上传失败`))\n }\n // console.log(file, zipPath, 'uploader:after:::====🚀🚀🚀🚀🚀', res.data)\n resolve({fileId: res.data.fileId, type, root})\n successCallback?.()\n })\n }, 500)\n })\n }\n // 上次多个文件,可能会出现某个上传失败,624状态码。\n // 根据寤生的验证,这里要这么操作,多次catch重试。\n // 这个服务目前无人维护,暂时这么搞吧。\n upload()\n .catch(upload)\n .catch(upload)\n .catch(upload)\n .catch(upload)\n .then((res: any) => {\n subscriber.next(res)\n subscriber.complete()\n })\n .catch(err => {\n subscriber.error(err)\n })\n }, 500) // 不能乘以index 否则容易报整包解析失败\n })\n}\n\n/* 创建上传长任务 */\nexport const createUploadTask$ = ({\n uploadApi,\n fullPackFileId,\n packageMap,\n packageMapV2,\n appId,\n version,\n userDesc,\n userVersion\n}) => {\n return from(\n uploadApi.createUploadTask({\n version,\n fileUrl: fullPackFileId,\n appId,\n packageMap,\n packageMapV2,\n userDesc,\n userVersion\n })\n )\n}\n\n/* 查询长任务的状态 */\nexport const queryTaskDetail$ = (uploadApi, taskId: string) => {\n return from(uploadApi.queryTaskDetail(taskId)).pipe(\n map((data: any) => {\n if (data.status === 5) {\n throw new Error(data?.result?.msg)\n }\n return data\n })\n )\n}\n\n// 获取分包结构\nconst getSubPackages = (uploadRes: UploadRes[], type: ArchType) =>\n uploadRes.reduce((pre, cur) => {\n let res = {}\n if (cur.type === type) {\n res = {[cur.root]: cur.fileId}\n }\n return {...pre, ...res}\n }, {})\n\n/* 创建提交的任务 */\nexport const submitTask = ({\n uploadApi,\n uploadRes,\n appId,\n version,\n userDesc,\n userVersion\n}: {\n uploadApi: any\n uploadRes: UploadRes[]\n appId: string\n version: IUploadCheckVersionParams['version']\n userDesc?: string\n userVersion?: string\n}) => {\n /* 长任务需要的参数 */\n const fullPackFileId = uploadRes.filter(item => item.type === 'v0')[0].fileId\n\n const packageMap = getSubPackages(uploadRes, 'v1')\n const packageMapV2 = getSubPackages(uploadRes, 'v2')\n\n return from(\n uploadApi.createUploadTask({\n version,\n fileUrl: fullPackFileId,\n appId,\n packageMap,\n packageMapV2: isEmpty(packageMapV2) ? undefined : packageMapV2,\n userDesc,\n userVersion\n })\n ).pipe(\n switchMap((v: any) => {\n const {task_id} = v\n return interval(1500).pipe(\n switchMap(() => queryTaskDetail$(uploadApi, task_id)),\n first(v => v.status === 3)\n )\n })\n )\n}\ntype Res = ReturnType<typeof submitTask>\ntype GetP<T> = T extends Observable<infer P> ? P : never\nexport type FinalRes = GetP<Res>\n","export function guid() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n // eslint-disable-next-line no-bitwise\n const r = (Math.random() * 16) | 0\n // eslint-disable-next-line no-bitwise\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n }\n ","import {UploadApi} from '../../api/uploadApi'\nimport {BaseService, IBaseServiceProps} from '../baseService'\nimport {FinalRes, submitTask, IZipResult, uploadFile2} from '../rx-utils'\nimport {Subscription, switchMap, from, forkJoin} from 'rxjs'\nimport {COMPILE_ENTRY} from 'xhs-mp-compiler'\n\n\ntype IUploaderProps = IBaseServiceProps & {}\n\n\ninterface IUploadData {\n userVersion: string\n userDesc: string\n progressCallback?: any\n}\n\nexport class Uploader extends BaseService {\n taskSubscription: any\n uploadApi: UploadApi\n uploadPromise: { resolve: (value: unknown) => void; reject: (reason?: any) => void }\n\n constructor(props: IUploaderProps) {\n super(props)\n this.uploadApi = new UploadApi(props)\n }\n \n upload(uploadData: IUploadData) {\n return new Promise((resolve, reject) => {\n this.uploadPromise = {\n resolve, \n reject\n }\n this.doUpload(uploadData)\n })\n }\n\n private doUpload = (uploadData: IUploadData) => {\n const { progressCallback, userVersion, userDesc } = uploadData\n if (!userVersion?.trim()) {\n throw new Error('请填写上传版本号')\n }\n if (!userDesc?.trim()) {\n throw new Error('请填写版本描述')\n }\n /* 上传成功 */\n const successHandle = () => {\n this.compiler.kill(COMPILE_ENTRY.upload)\n this.taskSubscription?.unsubscribe()\n this.taskSubscription = null\n this.uploadPromise?.resolve(null)\n // @ts-ignore\n this.uploadPromise = null\n this.logger.log('Upload Done!!!')\n }\n\n /* 上传出现异常 */\n const errorHandle = (err: Error) => {\n progressCallback?.(-1) // 出错时,进度设置为 -1\n this.taskSubscription?.unsubscribe()\n this.taskSubscription = null\n this.compiler.kill(COMPILE_ENTRY.upload)\n this.logger.log('Upload Error:', err.toString())\n this.uploadPromise?.reject(err)\n // @ts-ignore\n this.uploadPromise = null\n }\n try {\n const appId = this.project.projectConfig.projectAppId\n this.logger.log('Check appid auth...')\n this.taskSubscription = from(this.uploadApi.uploadCheckVersion({version: 'develop'}))\n .pipe(\n switchMap((v: any) => {\n const {can_upload, can_upload_ext_json, upload_app_id, show_msg} = v\n if (!can_upload) {\n throw new Error(show_msg)\n }\n if (!upload_app_id) {\n throw new Error('请检查是否该appid无权限')\n }\n progressCallback?.(5) // 进度更新为 15%\n return from(\n this.compiler.compileAndZip({\n entryType: COMPILE_ENTRY.upload,\n can_upload_ext_json,\n upload_app_id,\n pkgInfo: {\n // 上传用户填写的包版本信息。\n version: userVersion\n }\n })\n )\n }),\n switchMap((fileList: IZipResult[]) => {\n progressCallback?.(30) // 进度更新为 30%\n this.emit('compile-and-zip-status', {\n status: 'uploading'\n })\n this.logger.log('Upload packages to cos...')\n const list = fileList.map((item, index) =>\n uploadFile2(\n this.uploadApi,\n {\n zipPath: item.zipPath,\n type: item.type,\n root: item.root\n },\n index,\n () => {\n progressCallback?.(30 + (45 / fileList.length) * (index + 1)) // 在每个文件上传后更新进度\n }\n )\n )\n return forkJoin(list)\n }),\n switchMap(v => {\n progressCallback?.(80) // 所有文件上传完成,进度更新为 80%\n this.logger.log('Upload packages info...')\n return submitTask({\n uploadApi: this.uploadApi,\n uploadRes: v,\n appId,\n version: 'develop',\n userVersion,\n userDesc\n })\n })\n )\n .subscribe({\n next: (fin: FinalRes) => {\n progressCallback?.(100) // 所有文件上传完成,进度更新为 100%\n successHandle()\n },\n error: err => {\n errorHandle(err)\n }\n })\n } catch (err) {\n errorHandle(err)\n }\n }\n}\n","\nimport axios from '../utils/axios'\nimport {domain, api} from '../config/url.config'\nimport { BaseApi } from './baseApi'\n\n\nexport interface IBaseRoot<T> {\n alertMsg: string\n data: T\n errorCode: any\n errorMsg: any\n statusCode: number\n success: boolean\n traceLogId: string\n}\n\nexport type IGenerateQrCodeData = IBaseRoot<{\n qrId: string\n qrUrl: string\n}>\n\nexport interface IQueryQrCodeStatusData {\n authToken: null | string\n avatar: null | string\n customerUserType: null | string\n status: number\n ticket: null | string\n userId: null | string\n}\n\nexport type IQueryQrCodeStatus = IBaseRoot<IQueryQrCodeStatusData>\n\nexport type ILoginData = Omit<IQueryQrCodeStatusData, 'status'>\n\n/* 用户的登录信息 */\nexport interface IBusinessRoot {\n code: number\n msg: string\n guid: any\n success: boolean\n data: {\n [key: string]: any\n }\n}\n\nexport type IGetUserInfo = IBusinessRoot\n\nexport class UserApi extends BaseApi {\n\n async generateQrCode() {\n const res = await this.request({\n method: 'post', \n url: api.generateQrCode, \n data: {\n subsystem: 'business'\n }\n })\n return this.handleStatusCode(this.handleHttpStatus(res))\n }\n\n async queryQrCodeStatus(qrId: string) {\n const res = await this.request({\n method: 'get', \n url: api.queryQrCodeStatus, \n data: {\n params: {\n qrId,\n service: domain.CUSTOMER_SERVICE_ID\n }\n }\n })\n return this.handleStatusCode(this.handleHttpStatus(res))\n }\n\n async login(ticket: string) {\n const res = await this.request({\n method: 'post', \n url: api.session, \n data: {\n ticket,\n clientId: domain.CUSTOMER_SERVICE_ID\n }\n })\n return this.handleHttpStatus(res).data\n }\n\n async fetchUserInfo() {\n const res = await this.request({\n method: 'get', \n url: api.getUserInfo,\n })\n return this.handleCode(this.handleHttpStatus(res))\n }\n\n}\n","import path from 'path'\nimport fse from 'fs-extra'\nimport {mpStoragePath} from '../config/dir.config'\n\nclass Storage {\n jsonPath: string\n data: {\n [key: string]: any\n } = {}\n private timer: any\n\n constructor() {\n this.jsonPath = path.join(mpStoragePath, 'storage.json')\n if (fse.existsSync(this.jsonPath)) {\n try {\n this.data = fse.readJSONSync(this.jsonPath)\n } catch (error) {\n this.data = {}\n }\n }\n }\n\n get(key) {\n return this.data[key]\n }\n\n set(key, val) {\n this.data[key] = val\n this.refresh()\n }\n\n refresh() {\n // this.timer && clearTimeout(this.timer)\n // this.timer = setTimeout(() => {\n fse.writeJSONSync(this.jsonPath, this.data)\n // }, 0)\n }\n}\n\nexport default new Storage()\n","import {picker} from './utils/utils'\nimport {UserApi} from './api/userApi'\nimport {from, interval, defer} from 'rxjs'\nimport {switchMap, map, tap, takeWhile, retry, exhaustMap} from 'rxjs/operators'\nimport qrcode from 'qrcode-terminal'\nimport storage from './utils/storage'\nimport cookie from './utils/cookie'\n\nexport type IUserInfo = {\n nickName: string\n avatar: string\n userId: string\n desc: string\n gender: number\n userInfoData?: any\n}\n\nexport interface IUserInfoData {\n nick: string\n img: string\n}\n\nexport class LoginManager {\n private qrUrl: string\n private userApi: UserApi\n private qrCodeStatusData: {isLoading: boolean; expired: boolean} = {} as any\n private startPollingSub: any = null\n private loginPromise: any = {}\n private logger: any\n private _isLogin: any\n private _userInfo: any\n\n get isLogin() {\n return this._isLogin\n }\n\n set isLogin(isLogin) {\n this._isLogin = isLogin\n }\n\n get userInfo() {\n return this._userInfo\n }\n\n set userInfo(info) {\n this._userInfo = info\n storage.set('userInfo', info)\n }\n\n constructor(props) {\n this.logger = props.logger\n this.userApi = new UserApi(props)\n\n this.qrCodeStatusData = {\n isLoading: false,\n expired: false\n }\n this._userInfo = storage.get('userInfo') || {}\n this.isLogin = !!this.userInfo?.nickName\n }\n\n private transformUserInfo = (data: IUserInfoData): IUserInfo => {\n const {nick, avatar, desc, gender} = picker<any>(data, ['nick', 'avatar', 'desc', 'gender'])\n return {nickName: nick, avatar, userId: '', desc, gender}\n }\n\n showQrCode() {\n qrcode.generate(this.qrUrl, {\n small: true\n })\n }\n\n private queryQrCodeStatus = (qrId: string) => {\n return from(this.userApi.queryQrCodeStatus(qrId))\n }\n\n private doLogin = async (ticket: string) => {\n const {resolve, reject} = this.loginPromise\n this.loginPromise = null\n try {\n const data = await this.userApi.login(ticket)\n if (!data.success) {\n reject(new Error(data.msg))\n return\n }\n const userInfoData = await this.userApi.fetchUserInfo()\n const userInfo: IUserInfo = this.transformUserInfo(userInfoData)\n userInfo.userInfoData = userInfoData\n resolve(userInfo)\n } catch (error) {\n reject(new Error(error.message))\n return\n }\n }\n\n private startPolling = () => {\n this.qrCodeStatusData.isLoading = true\n this.qrCodeStatusData.expired = false\n return from(defer(() => this.userApi.generateQrCode())).pipe(\n tap((data: any) => {\n this.qrUrl = data.qrUrl\n this.qrCodeStatusData.isLoading = false\n this.showQrCode()\n setTimeout(() => {\n this.qrCodeStatusData.expired = true\n // 二维码过期是也需要停止轮询\n this.stopPolling()\n }, 60 * 1000)\n }),\n exhaustMap(({qrUrl, qrId}) =>\n interval(2000).pipe(\n switchMap(() => this.queryQrCodeStatus(qrId)),\n tap((data: any) => {\n if (data.status === 4) {\n throw new Error('retry login')\n }\n if (data.status === 1) {\n this.stopPolling()\n this.doLogin(data.ticket)\n }\n })\n )\n ),\n takeWhile(data => data.status !== 1),\n retry(5)\n )\n }\n\n private stopPolling = () => {\n if (this.startPollingSub) {\n this.startPollingSub.unsubscribe()\n this.startPollingSub = null\n }\n }\n\n async login(type: 'qrcode' | 'token', data) {\n if (this.isLogin) {\n this.logger.log('Had Login!!!')\n return\n }\n this.isLogin = false\n this.logger.log('Login...')\n try {\n let userInfo\n if (type === 'qrcode') {\n userInfo = await this.loginByQrcode()\n } else {\n userInfo = await this.loginByToken(data)\n }\n this.isLogin = true\n this.userInfo = userInfo\n this.logger.log('Login success')\n } catch (error) {\n this.logger.log('Login fail:', error.message)\n this.isLogin = true\n this.userInfo = null\n throw error\n }\n }\n\n loginByQrcode() {\n return new Promise((resolve, reject) => {\n this.loginPromise = {\n resolve,\n reject\n }\n try {\n this.startPollingSub = this.startPolling().subscribe()\n } catch (error) {\n console.error(error)\n }\n })\n }\n\n async loginByToken(token) {}\n\n logout() {\n this.logger.log('Logout...')\n this.isLogin = false\n this.userInfo = {}\n cookie.clear()\n this.logger.log('Logout Success!!!')\n }\n}\n","import Jimp from 'jimp'\nimport jsQR from 'jsqr'\n\nconst decodeQRBase64 = async (base64): Promise<string | undefined> => {\n const qrBuffer = Buffer.from(base64.replace(/^data:image\\/[a-z]+;base64,/, ''), 'base64')\n const image = await Jimp.read(qrBuffer)\n\n // Get the image data\n const imageData = {\n data: new Uint8ClampedArray(image.bitmap.data),\n width: image.bitmap.width,\n height: image.bitmap.height\n }\n\n // Use jsQR to decode the QR code\n const decodedQR = jsQR(imageData.data, imageData.width, imageData.height)\n\n if (!decodedQR) {\n throw new Error('QR code not found in the image.')\n }\n\n return decodedQR.data\n}\n\n/* 前端生成深度链接二维码 */\nexport const genDeeplink = async (projectConfig, entry = {}, qrcode, logger) => {\n let entryData = projectConfig.getCompileEntryPage()\n entryData = {\n ...entryData,\n ...entry\n }\n const {path, query, launchMode} = entryData\n\n try {\n let deepLink = (await decodeQRBase64(qrcode)) as any\n if (path) {\n deepLink = deepLink.replace('_develop', `_develop${path.startsWith('/') ? '' : '/'}${path}`)\n }\n\n if (query) {\n deepLink += `&${query}`\n }\n\n if (launchMode === 'halfPageNativeFunctionalized') {\n deepLink += '&runtime_mode=2'\n }\n return deepLink\n } catch (error) {\n logger.error('二维码解码失败:', error)\n }\n}\n","import {FinalRes, uploadFile2, submitTask} from '../rx-utils'\nimport {genDeeplink} from '../../utils/qrcode'\nimport {BaseService, IBaseServiceProps} from '../baseService'\nimport {from, defer, map, Observable, switchMap, tap, forkJoin} from 'rxjs'\nimport {COMPILE_ENTRY} from 'xhs-mp-compiler'\nimport {UploadApi} from '../../api/uploadApi'\nimport {fileSize} from '../../utils/utils'\nimport qrcode from 'qrcode-terminal'\n\ntype IPreviewProps = IBaseServiceProps & {}\n\ninterface IPreviewData {\n entry?: {\n path: string\n query?: string\n launchMode?: string\n }\n}\n\nexport class Preview extends BaseService {\n uploadApi: UploadApi\n taskSubscription: any\n progressData: {\n [key: string]: any\n } = {}\n previewData: {\n [key: string]: any\n } = {}\n previewPromise: {resolve: (value: unknown) => void; reject: (reason?: any) => void}\n\n constructor(props: IPreviewProps) {\n super(props)\n this.uploadApi = new UploadApi(props)\n this.progressData = {}\n this.previewData = {}\n }\n\n preview(opts: IPreviewData) {\n return new Promise((resolve, reject) => {\n this.previewPromise = {\n resolve,\n reject\n }\n this.doPreview(opts)\n })\n }\n\n doPreview(opts: IPreviewData) {\n this.progressData.previewIsLoading = true\n const appId = this.project.projectConfig.projectAppId\n\n const _startTime = Date.now()\n\n const successHandle = async (fin: FinalRes) => {\n const extra_json = JSON.parse(fin.result.extra_json)\n this.previewData.qrcodeUrl = await genDeeplink(\n this.project.projectConfig,\n opts.entry,\n extra_json.qrcode,\n this.logger\n )\n this.showQrCode(this.previewData.qrcodeUrl)\n\n this.previewData.previewTotalTime = +((Date.now() - _startTime) / 1000).toFixed(1)\n this.progressData.previewIsLoading = false\n\n this.compiler.kill(COMPILE_ENTRY.preview)\n\n this.taskSubscription?.unsubscribe()\n this.taskSubscription = null\n this.previewPromise?.resolve({\n qrcodeUrl: this.previewData.qrcodeUrl\n })\n // @ts-ignore\n this.previewPromise = null\n\n this.logger.log('Preview Done!!!')\n }\n\n const errorHandle = err => {\n this.compiler.kill(COMPILE_ENTRY.preview)\n\n this.taskSubscription?.unsubscribe()\n this.taskSubscription = null\n this.previewPromise?.reject(err)\n // @ts-ignore\n this.previewPromise = null\n\n this.logger.log('Preview Error:', err.toString())\n }\n\n this.logger.log('Check appid auth...')\n this.taskSubscription = from(\n defer(() => this.uploadApi.uploadCheckVersion({version: 'debug'}))\n )\n .pipe(\n switchMap((v: any) => {\n const {can_upload_ext_json, upload_app_id} = v\n if (!upload_app_id) {\n throw new Error('请检查是否该appid无权限')\n }\n return from(\n this.compiler.compileAndZip({\n entryType: COMPILE_ENTRY.preview,\n can_upload_ext_json,\n upload_app_id\n })\n )\n }),\n tap(res => {\n /* 记录下zip包的信息 */\n this.calcSize(res)\n }),\n switchMap(fileList => {\n this.emit('compile-and-zip-status', {status: 'uploading'})\n this.logger.log('Upload packages to cos...')\n const list = fileList.map((item, index) =>\n uploadFile2(\n this.uploadApi,\n {\n zipPath: item.zipPath,\n type: item.type,\n root: item.root\n },\n index\n )\n )\n return forkJoin(list)\n }),\n switchMap((v: any) => {\n this.logger.log('Upload packages info...')\n\n return submitTask({\n uploadApi: this.uploadApi,\n uploadRes: v,\n appId,\n version: 'debug'\n })\n })\n )\n .subscribe({\n next: (fin: FinalRes) => {\n return successHandle(fin)\n },\n error: err => {\n return errorHandle(err)\n }\n })\n\n }\n\n showQrCode(qrUrl) {\n qrcode.generate(qrUrl, {\n small: true\n })\n }\n\n calcSize = zipSizeInfo => {\n const projectConfig = this.project.projectConfig\n // @ts-ignore\n const type = projectConfig?.flags?.enableV2Preivew ? 'v2' : 'v1'\n const rowList = zipSizeInfo?.filter?.(i => i.type === type).sort((a, b) => b.zipSize - a.zipSize) || []\n this.previewData.subPkgs = rowList.map((item, key) => ({\n key,\n path: item.root,\n size: fileSize(item.zipSize)\n }))\n const allZipSize = rowList.reduce((ac, i) => i.zipSize + ac, 0) || 0\n this.previewData.zipSize = fileSize(allZipSize)\n }\n}\n","import {COMPILE_ENTRY, Compiler, ICompileOpts} from 'xhs-mp-compiler'\nimport {Project} from 'xhs-mp-project'\nimport {Logger} from 'xhs-mp-utils'\nimport {Uploader} from './services/upload/upload'\nimport {LoginManager} from './login'\nimport {Preview} from './services/preview/preview'\nimport { IProjectProps } from 'xhs-mp-project'\nimport storage from './utils/storage'\n\nexport interface IVerbose {\n verbose?: boolean\n}\nexport interface IGlobalConfig {\n proxy?: string\n}\n\nexport interface IAppConfig {\n appId: string\n config: {\n [key: string]: any\n }\n}\n\nexport interface IAppConfigMap {\n [appId: string]: IAppConfig\n}\n\nexport type ILoginConfig = IVerbose & {\n type?: 'qrcode' | 'token'\n data?: {\n token?: string\n }\n}\n\nexport interface ILibFeatures {\n supportV2?: boolean\n supportVdom?: boolean\n}\n\nexport interface IBaseActionOpts {\n project: {\n projectPath: string\n watch?: boolean\n }\n buildConfig?: {\n compileDir?: string\n nodeJsPath?: string\n mpDevJsonPath?: string\n libFeatures?: ILibFeatures\n }\n}\n\nexport type IPreivewOpts = IBaseActionOpts & IVerbose & {\n entry?: {\n path: string\n query?: string\n launchMode?: string\n }\n}\n\nexport type IUploadOpts = IBaseActionOpts & IVerbose & {\n version: string\n desc: string\n progressCallback?: any\n}\n\nexport class Core {\n private globalConfig: IGlobalConfig = {}\n private appConfigMap: IAppConfigMap = {}\n private currentAppConfig: IAppConfig = {} as IAppConfig\n private projectMap: {\n [key: string]: Project\n } = {} as any\n private compilerMap: {\n [key: string]: Compiler\n } = {} as any\n private logger: Logger\n private loginManager: LoginManager\n\n constructor() {\n this.globalConfig = storage.get('globalConfig') || {}\n this.logger = new Logger('[xhs-mp-core]')\n this.loginManager = new LoginManager({\n core: this,\n logger: this.logger\n })\n }\n\n setGlobalConfig(config: IGlobalConfig = {}) {\n this.logger.log('Set global config...')\n this.globalConfig = {\n ...(this.globalConfig || {}),\n ...config\n }\n storage.set('globalConfig', config)\n this.logger.log('Set global config done')\n }\n \n getGlobalConfig() {\n return this.globalConfig || {}\n }\n\n setAppConfig(appConfig: IAppConfig = {} as IAppConfig) {\n const {appId, config} = appConfig\n this.appConfigMap[appId] = {\n ...(this.appConfigMap[appId] || {}),\n ...config\n }\n this.currentAppConfig = appConfig\n }\n\n\n getAppConfig(appId) {\n return this.appConfigMap[appId] || {}\n }\n\n private getProject(props: IProjectProps) {\n const { projectPath } = props\n if (!projectPath) {\n throw new Error('没有配置projectPath')\n }\n if (!this.projectMap[projectPath]) {\n this.projectMap[projectPath] = new Project(props)\n }\n return this.projectMap[projectPath]\n }\n\n private getCompiler(props: IProjectProps, config: ICompileOpts) {\n const { projectPath } = props\n if (!this.compilerMap[projectPath]) {\n const project = this.getProject(props)\n this.compilerMap[projectPath] = new Compiler({\n ...config,\n project,\n logger: this.logger\n })\n }\n return this.compilerMap[projectPath]\n }\n\n async login(opts: ILoginConfig = {}) {\n if (opts.verbose) {\n this.logger.setVerbose(true)\n }\n const {type = 'qrcode', data} = opts\n await this.loginManager.login(type, {\n ...(this.currentAppConfig || {}),\n ...data\n })\n }\n\n logout() {\n this.loginManager.logout()\n }\n\n async preview(opts: IPreivewOpts) {\n if (opts.verbose) {\n this.logger.setVerbose(true)\n }\n if (!this.loginManager.isLogin) {\n await this.login({})\n }\n const projectInfo = opts.project || {}\n const buildConfig = opts.buildConfig || {}\n const project = this.getProject(projectInfo)\n const compiler = this.getCompiler(projectInfo, buildConfig)\n const previewService = new Preview({\n core: this,\n project,\n compiler,\n logger: this.logger\n })\n return await previewService.preview({\n entry: opts.entry\n })\n }\n\n async upload(opts: IUploadOpts) {\n if (opts.verbose) {\n this.logger.setVerbose(true)\n }\n if (!this.loginManager.isLogin) {\n await this.login()\n }\n const {project: projectConfig, buildConfig = {}, version, desc, progressCallback} = opts\n const project = this.getProject(projectConfig)\n const compiler = this.getCompiler(projectConfig, buildConfig)\n const uploadService = new Uploader({\n core: this,\n project,\n compiler,\n logger: this.logger\n })\n return await uploadService.upload({\n userVersion: version,\n userDesc: desc,\n progressCallback\n })\n }\n}\n"],"names":["getXHSAPIENV","isSit","process","env","XHS_IS_PROD","isProd","BUSINESS_SIT_HOST","require","XHS_BUSINESS_SIT_HOST","CUSTOMER_SIT_HOST","XHS_CUSTOMER_SIT_HOST","domain","BUSINESS_HOST","CUSTOMER_HOST","CUSTOMER_SERVICE_ID","replace","api","generateQrCode","queryQrCodeStatus","session","getUserInfo","fileSize","size","base","toFixed","normalizePath","str","baseDirPath","path","join","os","homedir","fse","ensureDirSync","mpStoragePath","tough","cookie","constructor","this","cookiePath","data","getSerializeData","Object","keys","length","cookieJar","CookieJar","deserializeSync","json","existsSync","readJSONSync","save","serializeSync","writeJSONSync","clear","removeSync","set","res","cookies","headers","url","config","forEach","cookieStr","cookieMap","Cookie","parse","setCookieSync","get","getCookieStringSync","axios","defaults","baseURL","interceptors","request","use","uri","getUri","test","urlObj","URL","origin","e","cookitTook","response","_a","startsWith","success","Error","msg","async","error","status","code","console","warn","Promise","reject","BaseApi","EventEmitter","props","super","core","getProxyConfig","proxy","getGlobalConfig","host","hostname","port","protocol","opts","method","handleHttpStatus","handleStatusCode","statusCode","errorMsg","handleCode","error_code","fs","readJsonStr","_path","JSON","stringify","UploadApi","getUploadToken","params","withCredentials","project","uploadCheckVersion","version","projectConfig","appJsonPath","entryJsonPath","extJsonPath","resolve","appJson","extJson","appId","projectAppId","requestPath","app_json","ext_json","createUploadTask","fileUrl","userVersion","userDesc","packageMap","packageMapV2","file_url","user_version","user_desc","package_map","package_map_v2","cloud_type","queryTaskDetail","taskId","task_id","BaseService","compiler","logger","uploadFile2","uploadApi","zipPath","type","root","index","successCallback","uploader","CosUploader","bizName","scene","getToken","Observable","subscriber","setTimeout","fileName","c","r","Math","random","toString","file","readFileSync","stats","statSync","upload","post","Body","fileInfo","name","FilePath","then","fileId","catch","next","complete","err","getSubPackages","uploadRes","reduce","pre","cur","submitTask","fullPackFileId","filter","item","from","isEmpty","undefined","pipe","switchMap","v","interval","map","result","queryTaskDetail$","first","Uploader","doUpload","uploadData","progressCallback","trim","successHandle","kill","COMPILE_ENTRY","taskSubscription","unsubscribe","_b","uploadPromise","log","errorHandle","can_upload","can_upload_ext_json","upload_app_id","show_msg","compileAndZip","entryType","pkgInfo","fileList","emit","list","forkJoin","subscribe","fin","UserApi","subsystem","qrId","service","login","ticket","clientId","fetchUserInfo","storage","jsonPath","key","val","refresh","LoginManager","isLogin","_isLogin","userInfo","_userInfo","info","qrCodeStatusData","startPollingSub","loginPromise","transformUserInfo","nick","avatar","desc","gender","obj","nickName","userId","userApi","doLogin","userInfoData","message","startPolling","isLoading","expired","defer","tap","qrUrl","showQrCode","stopPolling","exhaustMap","takeWhile","retry","qrcode","generate","small","loginByQrcode","loginByToken","token","logout","genDeeplink","entry","entryData","getCompileEntryPage","query","launchMode","deepLink","base64","qrBuffer","Buffer","image","Jimp","read","imageData","Uint8ClampedArray","bitmap","width","height","decodedQR","jsQR","decodeQRBase64","Preview","progressData","previewData","calcSize","zipSizeInfo","flags","enableV2Preivew","rowList","i","sort","a","b","zipSize","subPkgs","allZipSize","ac","preview","previewPromise","doPreview","previewIsLoading","_startTime","Date","now","extra_json","qrcodeUrl","previewTotalTime","globalConfig","appConfigMap","currentAppConfig","projectMap","compilerMap","Logger","loginManager","setGlobalConfig","setAppConfig","appConfig","getAppConfig","getProject","projectPath","Project","getCompiler","Compiler","verbose","setVerbose","projectInfo","buildConfig","previewService","uploadService"],"mappings":"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"}
|
package/dist/login.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type IUserInfo = {
|
|
2
|
+
nickName: string;
|
|
3
|
+
avatar: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
desc: string;
|
|
6
|
+
gender: number;
|
|
7
|
+
userInfoData?: any;
|
|
8
|
+
};
|
|
9
|
+
export interface IUserInfoData {
|
|
10
|
+
nick: string;
|
|
11
|
+
img: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class LoginManager {
|
|
14
|
+
private qrUrl;
|
|
15
|
+
private userApi;
|
|
16
|
+
private qrCodeStatusData;
|
|
17
|
+
private startPollingSub;
|
|
18
|
+
private loginPromise;
|
|
19
|
+
private logger;
|
|
20
|
+
private _isLogin;
|
|
21
|
+
private _userInfo;
|
|
22
|
+
get isLogin(): any;
|
|
23
|
+
set isLogin(isLogin: any);
|
|
24
|
+
get userInfo(): any;
|
|
25
|
+
set userInfo(info: any);
|
|
26
|
+
constructor(props: any);
|
|
27
|
+
private transformUserInfo;
|
|
28
|
+
showQrCode(): void;
|
|
29
|
+
private queryQrCodeStatus;
|
|
30
|
+
private doLogin;
|
|
31
|
+
private startPolling;
|
|
32
|
+
private stopPolling;
|
|
33
|
+
login(type: 'qrcode' | 'token', data: any): Promise<void>;
|
|
34
|
+
loginByQrcode(): Promise<unknown>;
|
|
35
|
+
loginByToken(token: any): Promise<void>;
|
|
36
|
+
logout(): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Project } from "xhs-mp-project";
|
|
3
|
+
import { Compiler } from "xhs-mp-compiler";
|
|
4
|
+
import EventEmitter from "events";
|
|
5
|
+
import { Core } from "../core";
|
|
6
|
+
export interface IBaseServiceProps {
|
|
7
|
+
core: Core;
|
|
8
|
+
project: Project;
|
|
9
|
+
compiler: Compiler;
|
|
10
|
+
logger: any;
|
|
11
|
+
}
|
|
12
|
+
export declare class BaseService extends EventEmitter {
|
|
13
|
+
core: Core;
|
|
14
|
+
project: Project;
|
|
15
|
+
compiler: Compiler;
|
|
16
|
+
logger: any;
|
|
17
|
+
constructor(props: IBaseServiceProps);
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseService, IBaseServiceProps } from '../baseService';
|
|
2
|
+
import { UploadApi } from '../../api/uploadApi';
|
|
3
|
+
type IPreviewProps = IBaseServiceProps & {};
|
|
4
|
+
interface IPreviewData {
|
|
5
|
+
entry?: {
|
|
6
|
+
path: string;
|
|
7
|
+
query?: string;
|
|
8
|
+
launchMode?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare class Preview extends BaseService {
|
|
12
|
+
uploadApi: UploadApi;
|
|
13
|
+
taskSubscription: any;
|
|
14
|
+
progressData: {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
};
|
|
17
|
+
previewData: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
};
|
|
20
|
+
previewPromise: {
|
|
21
|
+
resolve: (value: unknown) => void;
|
|
22
|
+
reject: (reason?: any) => void;
|
|
23
|
+
};
|
|
24
|
+
constructor(props: IPreviewProps);
|
|
25
|
+
preview(opts: IPreviewData): Promise<unknown>;
|
|
26
|
+
doPreview(opts: IPreviewData): void;
|
|
27
|
+
showQrCode(qrUrl: any): void;
|
|
28
|
+
calcSize: (zipSizeInfo: any) => void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
export interface IUploadCheckVersionParams {
|
|
3
|
+
version: 'debug' | 'develop';
|
|
4
|
+
}
|
|
5
|
+
export type ArchType = 'v0' | 'v1' | 'v2';
|
|
6
|
+
export type IZipResult = {
|
|
7
|
+
type: ArchType;
|
|
8
|
+
zipPath: string;
|
|
9
|
+
zipSize: number;
|
|
10
|
+
root: string;
|
|
11
|
+
originSize: number;
|
|
12
|
+
};
|
|
13
|
+
export type UploadRes = {
|
|
14
|
+
cdnFileUrl?: string;
|
|
15
|
+
fileId: string;
|
|
16
|
+
type: ArchType;
|
|
17
|
+
root: string;
|
|
18
|
+
};
|
|
19
|
+
export declare const uploadFile2: (uploadApi: any, { zipPath, type, root }: {
|
|
20
|
+
zipPath: any;
|
|
21
|
+
type: any;
|
|
22
|
+
root: any;
|
|
23
|
+
}, index: number, successCallback?: () => void) => Observable<UploadRes>;
|
|
24
|
+
export declare const createUploadTask$: ({ uploadApi, fullPackFileId, packageMap, packageMapV2, appId, version, userDesc, userVersion }: {
|
|
25
|
+
uploadApi: any;
|
|
26
|
+
fullPackFileId: any;
|
|
27
|
+
packageMap: any;
|
|
28
|
+
packageMapV2: any;
|
|
29
|
+
appId: any;
|
|
30
|
+
version: any;
|
|
31
|
+
userDesc: any;
|
|
32
|
+
userVersion: any;
|
|
33
|
+
}) => Observable<unknown>;
|
|
34
|
+
export declare const queryTaskDetail$: (uploadApi: any, taskId: string) => Observable<any>;
|
|
35
|
+
export declare const submitTask: ({ uploadApi, uploadRes, appId, version, userDesc, userVersion }: {
|
|
36
|
+
uploadApi: any;
|
|
37
|
+
uploadRes: UploadRes[];
|
|
38
|
+
appId: string;
|
|
39
|
+
version: IUploadCheckVersionParams['version'];
|
|
40
|
+
userDesc?: string | undefined;
|
|
41
|
+
userVersion?: string | undefined;
|
|
42
|
+
}) => Observable<any>;
|
|
43
|
+
type Res = ReturnType<typeof submitTask>;
|
|
44
|
+
type GetP<T> = T extends Observable<infer P> ? P : never;
|
|
45
|
+
export type FinalRes = GetP<Res>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UploadApi } from '../../api/uploadApi';
|
|
2
|
+
import { BaseService, IBaseServiceProps } from '../baseService';
|
|
3
|
+
type IUploaderProps = IBaseServiceProps & {};
|
|
4
|
+
interface IUploadData {
|
|
5
|
+
userVersion: string;
|
|
6
|
+
userDesc: string;
|
|
7
|
+
progressCallback?: any;
|
|
8
|
+
}
|
|
9
|
+
export declare class Uploader extends BaseService {
|
|
10
|
+
taskSubscription: any;
|
|
11
|
+
uploadApi: UploadApi;
|
|
12
|
+
uploadPromise: {
|
|
13
|
+
resolve: (value: unknown) => void;
|
|
14
|
+
reject: (reason?: any) => void;
|
|
15
|
+
};
|
|
16
|
+
constructor(props: IUploaderProps);
|
|
17
|
+
upload(uploadData: IUploadData): Promise<unknown>;
|
|
18
|
+
private doUpload;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare class CookieTool {
|
|
2
|
+
cookieJar: any;
|
|
3
|
+
cookiePath: string;
|
|
4
|
+
constructor();
|
|
5
|
+
getSerializeData(): {};
|
|
6
|
+
save(): void;
|
|
7
|
+
clear(): void;
|
|
8
|
+
set(res: any): void;
|
|
9
|
+
get(url: any): any;
|
|
10
|
+
}
|
|
11
|
+
declare const _default: CookieTool;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const genDeeplink: (projectConfig: any, entry: {} | undefined, qrcode: any, logger: any) => Promise<any>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare class Storage {
|
|
2
|
+
jsonPath: string;
|
|
3
|
+
data: {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
};
|
|
6
|
+
private timer;
|
|
7
|
+
constructor();
|
|
8
|
+
get(key: any): any;
|
|
9
|
+
set(key: any, val: any): void;
|
|
10
|
+
refresh(): void;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: Storage;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const throttle: (fn: any, wait?: number) => (...args: any[]) => void;
|
|
2
|
+
export declare const debounce: (func: any, wait?: number) => (...args: any[]) => void;
|
|
3
|
+
export declare const fileSize: (size: number) => string;
|
|
4
|
+
export declare function getMd5(str: any): any;
|
|
5
|
+
export declare function getType(object: any): string;
|
|
6
|
+
export declare function normalizePath(str: any): any;
|
|
7
|
+
export declare const compareVersion: (v1Str: string, v2Str: string) => number;
|
|
8
|
+
export declare function picker<T>(obj: any, pick: string[]): T;
|
|
9
|
+
export declare const formatPath: (pathStr?: string) => string;
|
|
10
|
+
export declare const toUnixPath: (pathStr?: string) => string;
|
|
11
|
+
export declare const unixJoin: (...paths: string[]) => string;
|
|
12
|
+
export declare const unixResolve: (...paths: string[]) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function guid(): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xhs-mp-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"typings": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"registry": "https://registry.npmjs.org/",
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"xhs-mp-compiler": "^1.0.0",
|
|
18
|
+
"xhs-mp-project": "^1.0.0",
|
|
19
|
+
"xhs-mp-utils": "^1.0.0",
|
|
20
|
+
"archiver": "^7.0.1",
|
|
21
|
+
"axios": "^0.21.4",
|
|
22
|
+
"debug": "^4.3.4",
|
|
23
|
+
"fs-extra": "^11.2.0",
|
|
24
|
+
"globby": "^14.0.1",
|
|
25
|
+
"jimp": "^0.22.12",
|
|
26
|
+
"jsqr": "^1.4.0",
|
|
27
|
+
"lodash": "^4.17.21",
|
|
28
|
+
"qrcode-terminal": "^0.12.0",
|
|
29
|
+
"query-string": "^8.1.0",
|
|
30
|
+
"querystring": "^0.2.1",
|
|
31
|
+
"rxjs": "^7.8.1",
|
|
32
|
+
"tough-cookie": "^4.1.3"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
36
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
37
|
+
"@types/node": "14",
|
|
38
|
+
"rimraf": "^5.0.5",
|
|
39
|
+
"rollup": "^4.9.6",
|
|
40
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
41
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
42
|
+
"typescript": "^5.4.3"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"clean": "rimraf -rf ./dist",
|
|
46
|
+
"watch": "npm run clean && rollup -c -w --sourcemap true",
|
|
47
|
+
"build": "npm run clean && rollup -c",
|
|
48
|
+
"format": "prettier --write . --config .prettierrc --plugin-search-dir=./../.. --ignore-path .prettierignore",
|
|
49
|
+
"check": "prettier --check . --config .prettierrc --plugin-search-dir=./../.. --ignore-path .prettierignore",
|
|
50
|
+
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx,.vue,svelte ./src",
|
|
51
|
+
"lint:fix": "npm run lint -- --quiet --fix",
|
|
52
|
+
"test": "echo \"todo\"",
|
|
53
|
+
"version:beta": "npm version prerelease --no-git-tag-version"
|
|
54
|
+
}
|
|
55
|
+
}
|