diff --git a/packages/global.d.ts b/packages/global.d.ts index bb3930bc80960889cac7481bb57ca72b6455468e..3e9a69d124749668823e25f2f845cac4198afc42 100644 --- a/packages/global.d.ts +++ b/packages/global.d.ts @@ -44,7 +44,3 @@ declare var __uniRoutes: UniApp.UniRoutes declare var __uniConfig: UniApp.UniConfig declare var UniViewJSBridge: UniApp.UniViewJSBridge declare var UniServiceJSBridge: UniApp.UniServiceJSBridge - -declare const getCurrentPages: ( - isAll?: boolean -) => Array & T> diff --git a/packages/uni-api/src/protocols/route/route.ts b/packages/uni-api/src/protocols/route/route.ts index 41bbbfcbbf6bdb0ccc2f574ccdc9b735ac519de6..1859bd725fdd9e599b949093d695e6f6304979ad 100644 --- a/packages/uni-api/src/protocols/route/route.ts +++ b/packages/uni-api/src/protocols/route/route.ts @@ -184,7 +184,7 @@ function createNormalizeUrl(type: string) { } } if (routeOptions.meta.isTabBar) { - const pages = getCurrentPages(true) + const pages = getCurrentPages() const tabBarPagePath = routeOptions.path.substr(1) if (pages.find((page) => page.route === tabBarPagePath)) { return 'tabBar page `' + tabBarPagePath + '` already exists' diff --git a/packages/uni-app/dist/uni-app.cjs.js b/packages/uni-app/dist/uni-app.cjs.js index 1b114ca5313dc3ffe6228c17c98b186d9ec90224..0c2ca954ca532b8c2a4985ccedc4356889d4c9f6 100644 --- a/packages/uni-app/dist/uni-app.cjs.js +++ b/packages/uni-app/dist/uni-app.cjs.js @@ -3,6 +3,72 @@ Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); +var shared = require('@vue/shared'); + +const sanitise = (val) => (val && JSON.parse(JSON.stringify(val))) || val; +const UNI_SSR = '__uniSSR'; +const UNI_SSR_DATA = 'data'; +const UNI_SSR_GLOBAL_DATA = 'globalData'; + +function getSSRDataType() { + return vue.getCurrentInstance() ? UNI_SSR_DATA : UNI_SSR_GLOBAL_DATA; +} +function assertKey(key, shallow = false) { + if (!key) { + throw new Error(`${shallow ? 'shallowSsrRef' : 'ssrRef'}: You must provide a key.`); + } +} +function proxy(target, track, trigger) { + return new Proxy(target, { + get(target, prop) { + track(); + if (shared.isObject(target[prop])) { + return proxy(target[prop], track, trigger); + } + return Reflect.get(target, prop); + }, + set(obj, prop, newVal) { + const result = Reflect.set(obj, prop, newVal); + trigger(); + return result; + }, + }); +} +const ssrServerRef = (value, key, shallow = false) => { + const type = getSSRDataType(); + assertKey(key, shallow); + const ctx = vue.useSSRContext(); + const __uniSSR = ctx[UNI_SSR] || (ctx[UNI_SSR] = {}); + const state = __uniSSR[type] || (__uniSSR[type] = {}); + // SSR 模式下 watchEffect 不生效 https://github.com/vuejs/vue-next/blob/master/packages/runtime-core/src/apiWatch.ts#L253 + // 故自定义ref + return vue.customRef((track, trigger) => { + const customTrigger = () => (trigger(), (state[key] = sanitise(value))); + return { + get: () => { + track(); + if (!shallow && shared.isObject(value)) { + return proxy(value, track, customTrigger); + } + return value; + }, + set: (v) => { + value = v; + customTrigger(); + }, + }; + }); +}; +const ssrRef = (value, key) => { + { + return ssrServerRef(value, key); + } +}; +const shallowSsrRef = (value, key) => { + { + return ssrServerRef(value, key, true); + } +}; // @ts-ignore // App and Page @@ -82,3 +148,5 @@ exports.onTabItemTap = onTabItemTap; exports.onThemeChange = onThemeChange; exports.onUnhandledRejection = onUnhandledRejection; exports.onUnload = onUnload; +exports.shallowSsrRef = shallowSsrRef; +exports.ssrRef = ssrRef; diff --git a/packages/uni-app/dist/uni-app.d.ts b/packages/uni-app/dist/uni-app.d.ts index 74b26df1799b0972826ff8f35aa5b04e94dbdb64..f07894a9fb55662f0a8ee5364ba59c160c73514a 100644 --- a/packages/uni-app/dist/uni-app.d.ts +++ b/packages/uni-app/dist/uni-app.d.ts @@ -1,4 +1,6 @@ import { ComponentInternalInstance } from 'vue'; +import { ref } from 'vue'; +import { shallowRef } from 'vue'; export declare const onAddToFavorites: (hook: () => any, target?: ComponentInternalInstance | null) => any; @@ -46,4 +48,10 @@ export declare const onUnhandledRejection: (hook: () => any, target?: ComponentI export declare const onUnload: (hook: () => any, target?: ComponentInternalInstance | null) => any; +export declare const shallowSsrRef: SSRRef; + +declare type SSRRef = (value: unknown, key?: string, shallow?: boolean) => ReturnType | ReturnType; + +export declare const ssrRef: SSRRef; + export { } diff --git a/packages/uni-app/dist/uni-app.es.js b/packages/uni-app/dist/uni-app.es.js index 1c0e5461e5727285d18b77528e8318a595e64a5f..703a7a1b957718805a12fe75ac2ed94c4abd2c5f 100644 --- a/packages/uni-app/dist/uni-app.es.js +++ b/packages/uni-app/dist/uni-app.es.js @@ -1,4 +1,34 @@ -import { getCurrentInstance, isInSSRComponentSetup, injectHook } from 'vue'; +import { shallowRef, ref, getCurrentInstance, isInSSRComponentSetup, injectHook } from 'vue'; + +const UNI_SSR = '__uniSSR'; +const UNI_SSR_DATA = 'data'; +const UNI_SSR_GLOBAL_DATA = 'globalData'; + +function getSSRDataType() { + return getCurrentInstance() ? UNI_SSR_DATA : UNI_SSR_GLOBAL_DATA; +} +function assertKey(key, shallow = false) { + if (!key) { + throw new Error(`${shallow ? 'shallowSsrRef' : 'ssrRef'}: You must provide a key.`); + } +} +const ssrClientRef = (value, key, shallow = false) => { + const valRef = shallow ? shallowRef(value) : ref(value); + const __uniSSR = window[UNI_SSR]; + if (!__uniSSR) { + return valRef; + } + const type = getSSRDataType(); + assertKey(key, shallow); + valRef.value = __uniSSR[type][key]; + return valRef; +}; +const ssrRef = (value, key) => { + return ssrClientRef(value, key); +}; +const shallowSsrRef = (value, key) => { + return ssrClientRef(value, key, true); +}; // @ts-ignore // App and Page @@ -55,4 +85,4 @@ const onNavigationBarSearchInputClicked = /*#__PURE__*/ createHook(ON_NAVIGATION const onNavigationBarSearchInputConfirmed = /*#__PURE__*/ createHook(ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED); const onNavigationBarSearchInputFocusChanged = /*#__PURE__*/ createHook(ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED); -export { onAddToFavorites, onBackPress, onError, onHide, onLaunch, onNavigationBarButtonTap, onNavigationBarSearchInputChanged, onNavigationBarSearchInputClicked, onNavigationBarSearchInputConfirmed, onNavigationBarSearchInputFocusChanged, onPageNotFound, onPageScroll, onPullDownRefresh, onReachBottom, onReady, onResize, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onThemeChange, onUnhandledRejection, onUnload }; +export { onAddToFavorites, onBackPress, onError, onHide, onLaunch, onNavigationBarButtonTap, onNavigationBarSearchInputChanged, onNavigationBarSearchInputClicked, onNavigationBarSearchInputConfirmed, onNavigationBarSearchInputFocusChanged, onPageNotFound, onPageScroll, onPullDownRefresh, onReachBottom, onReady, onResize, onShareAppMessage, onShareTimeline, onShow, onTabItemTap, onThemeChange, onUnhandledRejection, onUnload, shallowSsrRef, ssrRef }; diff --git a/packages/uni-app/src/index.ts b/packages/uni-app/src/index.ts index 1f34a7f9fa71df9ced5e5791e3a184f1810919d5..beea5d62a510ca1988cbc4b357d1a592f262435f 100644 --- a/packages/uni-app/src/index.ts +++ b/packages/uni-app/src/index.ts @@ -1 +1,2 @@ +export * from './ssr' export * from './apiLifecycle' diff --git a/packages/uni-app/src/ssr.ts b/packages/uni-app/src/ssr.ts new file mode 100644 index 0000000000000000000000000000000000000000..4c8383a0d6f5c2a5e30c632f8f0ece0a0d85a3af --- /dev/null +++ b/packages/uni-app/src/ssr.ts @@ -0,0 +1,108 @@ +import { + ref, + shallowRef, + customRef, + useSSRContext, + getCurrentInstance, +} from 'vue' +import { isObject } from '@vue/shared' +import { + sanitise, + UNI_SSR, + UNI_SSR_DATA, + UNI_SSR_GLOBAL_DATA, +} from '@dcloudio/uni-shared' + +type SSRRef = ( + value: unknown, + key?: string, + shallow?: boolean +) => ReturnType | ReturnType + +function getSSRDataType() { + return getCurrentInstance() ? UNI_SSR_DATA : UNI_SSR_GLOBAL_DATA +} + +function assertKey(key?: string, shallow = false) { + if (!key) { + throw new Error( + `${shallow ? 'shallowSsrRef' : 'ssrRef'}: You must provide a key.` + ) + } +} + +const ssrClientRef: SSRRef = (value, key, shallow = false) => { + const valRef = shallow ? shallowRef(value) : ref(value) + if (__PLATFORM__ !== 'h5') { + return valRef + } + const __uniSSR = (window as any)[UNI_SSR] + if (!__uniSSR) { + return valRef + } + const type = getSSRDataType() + assertKey(key, shallow) + valRef.value = (__uniSSR[type] as any)[key!] + return valRef +} + +function proxy( + target: Record, + track: () => void, + trigger: () => void +): Record { + return new Proxy(target, { + get(target, prop: string) { + track() + if (isObject(target[prop])) { + return proxy(target[prop], track, trigger) + } + return Reflect.get(target, prop) + }, + set(obj, prop, newVal) { + const result = Reflect.set(obj, prop, newVal) + trigger() + return result + }, + }) +} + +const ssrServerRef: SSRRef = (value, key, shallow = false) => { + const type = getSSRDataType() + assertKey(key, shallow) + const ctx = useSSRContext()! + const __uniSSR = ctx[UNI_SSR] || (ctx[UNI_SSR] = {}) + const state = __uniSSR[type] || (__uniSSR[type] = {}) + // SSR 模式下 watchEffect 不生效 https://github.com/vuejs/vue-next/blob/master/packages/runtime-core/src/apiWatch.ts#L253 + // 故自定义ref + return customRef((track, trigger) => { + const customTrigger = () => (trigger(), (state[key!] = sanitise(value))) + return { + get: () => { + track() + if (!shallow && isObject(value)) { + return proxy(value, track, customTrigger) + } + return value + }, + set: (v) => { + value = v + customTrigger() + }, + } + }) +} + +export const ssrRef: SSRRef = (value, key) => { + if (__NODE_JS__) { + return ssrServerRef(value, key) + } + return ssrClientRef(value, key) +} + +export const shallowSsrRef: SSRRef = (value, key) => { + if (__NODE_JS__) { + return ssrServerRef(value, key, true) + } + return ssrClientRef(value, key, true) +} diff --git a/packages/uni-app/tsconfig.json b/packages/uni-app/tsconfig.json index 843865ac8e5c79908de8488d54f23acc636dd966..778a1e5e5add90ed59efa40e7a66bb076597e365 100644 --- a/packages/uni-app/tsconfig.json +++ b/packages/uni-app/tsconfig.json @@ -14,5 +14,5 @@ "removeComments": false, "lib": ["ESNext", "DOM"] }, - "include": ["src"] + "include": ["src", "../global.d.ts", "../shims-uni-app.d.ts"] } diff --git a/packages/uni-cloud/dist/uni-cloud.cjs.js b/packages/uni-cloud/dist/uni-cloud.cjs.js index 8ac8716e36d7ccacf813a677d15ac7b52a1c4b32..0b1649e0e279e9c871d853b6d07ef324a3517160 100644 --- a/packages/uni-cloud/dist/uni-cloud.cjs.js +++ b/packages/uni-cloud/dist/uni-cloud.cjs.js @@ -1 +1,5655 @@ -import{initVueI18n as e}from"@dcloudio/uni-i18n";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function s(e,t,s){return e(s={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&s.path)}},s.exports),s.exports}var n=s((function(e,t){var s;e.exports=(s=s||function(e,t){var s=Object.create||function(){function e(){}return function(t){var s;return e.prototype=t,s=new e,e.prototype=null,s}}(),n={},r=n.lib={},o=r.Base={extend:function(e){var t=s(this);return e&&t.mixIn(e),t.hasOwnProperty("init")&&this.init!==t.init||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=r.WordArray=o.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||c).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes,r=e.sigBytes;if(this.clamp(),n%4)for(var o=0;o>>2]>>>24-o%4*8&255;t[n+o>>>2]|=i<<24-(n+o)%4*8}else for(o=0;o>>2]=s[o>>>2];return this.sigBytes+=r,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=o.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s,n=[],r=function(t){t=t;var s=987654321,n=4294967295;return function(){var r=((s=36969*(65535&s)+(s>>16)&n)<<16)+(t=18e3*(65535&t)+(t>>16)&n)&n;return r/=4294967296,(r+=.5)*(e.random()>.5?1:-1)}},o=0;o>>2]>>>24-r%4*8&255;n.push((o>>>4).toString(16)),n.push((15&o).toString(16))}return n.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},u=a.Latin1={stringify:function(e){for(var t=e.words,s=e.sigBytes,n=[],r=0;r>>2]>>>24-r%4*8&255;n.push(String.fromCharCode(o))}return n.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},h=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(u.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return u.parse(unescape(encodeURIComponent(e)))}},l=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=h.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,o=this.blockSize,a=r/(4*o),c=(a=t?e.ceil(a):e.max((0|a)-this._minBufferSize,0))*o,u=e.min(4*c,r);if(c){for(var h=0;h>>24)|4278255360&(r<<24|r>>>8)}var o=this._hash.words,i=e[t+0],c=e[t+1],f=e[t+2],p=e[t+3],g=e[t+4],m=e[t+5],y=e[t+6],_=e[t+7],v=e[t+8],w=e[t+9],S=e[t+10],T=e[t+11],k=e[t+12],A=e[t+13],P=e[t+14],I=e[t+15],E=o[0],O=o[1],U=o[2],b=o[3];E=u(E,O,U,b,i,7,a[0]),b=u(b,E,O,U,c,12,a[1]),U=u(U,b,E,O,f,17,a[2]),O=u(O,U,b,E,p,22,a[3]),E=u(E,O,U,b,g,7,a[4]),b=u(b,E,O,U,m,12,a[5]),U=u(U,b,E,O,y,17,a[6]),O=u(O,U,b,E,_,22,a[7]),E=u(E,O,U,b,v,7,a[8]),b=u(b,E,O,U,w,12,a[9]),U=u(U,b,E,O,S,17,a[10]),O=u(O,U,b,E,T,22,a[11]),E=u(E,O,U,b,k,7,a[12]),b=u(b,E,O,U,A,12,a[13]),U=u(U,b,E,O,P,17,a[14]),E=h(E,O=u(O,U,b,E,I,22,a[15]),U,b,c,5,a[16]),b=h(b,E,O,U,y,9,a[17]),U=h(U,b,E,O,T,14,a[18]),O=h(O,U,b,E,i,20,a[19]),E=h(E,O,U,b,m,5,a[20]),b=h(b,E,O,U,S,9,a[21]),U=h(U,b,E,O,I,14,a[22]),O=h(O,U,b,E,g,20,a[23]),E=h(E,O,U,b,w,5,a[24]),b=h(b,E,O,U,P,9,a[25]),U=h(U,b,E,O,p,14,a[26]),O=h(O,U,b,E,v,20,a[27]),E=h(E,O,U,b,A,5,a[28]),b=h(b,E,O,U,f,9,a[29]),U=h(U,b,E,O,_,14,a[30]),E=l(E,O=h(O,U,b,E,k,20,a[31]),U,b,m,4,a[32]),b=l(b,E,O,U,v,11,a[33]),U=l(U,b,E,O,T,16,a[34]),O=l(O,U,b,E,P,23,a[35]),E=l(E,O,U,b,c,4,a[36]),b=l(b,E,O,U,g,11,a[37]),U=l(U,b,E,O,_,16,a[38]),O=l(O,U,b,E,S,23,a[39]),E=l(E,O,U,b,A,4,a[40]),b=l(b,E,O,U,i,11,a[41]),U=l(U,b,E,O,p,16,a[42]),O=l(O,U,b,E,y,23,a[43]),E=l(E,O,U,b,w,4,a[44]),b=l(b,E,O,U,k,11,a[45]),U=l(U,b,E,O,I,16,a[46]),E=d(E,O=l(O,U,b,E,f,23,a[47]),U,b,i,6,a[48]),b=d(b,E,O,U,_,10,a[49]),U=d(U,b,E,O,P,15,a[50]),O=d(O,U,b,E,m,21,a[51]),E=d(E,O,U,b,k,6,a[52]),b=d(b,E,O,U,p,10,a[53]),U=d(U,b,E,O,S,15,a[54]),O=d(O,U,b,E,c,21,a[55]),E=d(E,O,U,b,v,6,a[56]),b=d(b,E,O,U,I,10,a[57]),U=d(U,b,E,O,y,15,a[58]),O=d(O,U,b,E,A,21,a[59]),E=d(E,O,U,b,g,6,a[60]),b=d(b,E,O,U,T,10,a[61]),U=d(U,b,E,O,f,15,a[62]),O=d(O,U,b,E,w,21,a[63]),o[0]=o[0]+E|0,o[1]=o[1]+O|0,o[2]=o[2]+U|0,o[3]=o[3]+b|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var o=e.floor(n/4294967296),i=n;s[15+(r+64>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),s[14+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),t.sigBytes=4*(s.length+1),this._process();for(var a=this._hash,c=a.words,u=0;u<4;u++){var h=c[u];c[u]=16711935&(h<<8|h>>>24)|4278255360&(h<<24|h>>>8)}return a},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}});function u(e,t,s,n,r,o,i){var a=e+(t&s|~t&n)+r+i;return(a<>>32-o)+t}function h(e,t,s,n,r,o,i){var a=e+(t&n|s&~n)+r+i;return(a<>>32-o)+t}function l(e,t,s,n,r,o,i){var a=e+(t^s^n)+r+i;return(a<>>32-o)+t}function d(e,t,s,n,r,o,i){var a=e+(s^(t|~n))+r+i;return(a<>>32-o)+t}t.MD5=o._createHelper(c),t.HmacMD5=o._createHmacHelper(c)}(Math),s.MD5)})),s((function(e,t){var s,r,o;e.exports=(r=(s=n).lib.Base,o=s.enc.Utf8,void(s.algo.HMAC=r.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=o.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,c=i.words,u=0;u{t.success&&t.success(e),t.complete&&t.complete(e)},e=>{t.fail&&t.fail(e),t.complete&&t.complete(e)})}}class i extends Error{constructor(e){super(e.message),this.errMsg=e.message||"",Object.defineProperties(this,{code:{get:()=>e.code},requestId:{get:()=>e.requestId},message:{get(){return this.errMsg},set(e){this.errMsg=e}}})}}const{t:a,setLocale:c,getLocale:u}=e({"zh-Hans":{"uniCloud.init.paramRequired":"缺少参数:{param}","uniCloud.uploadFile.fileError":"filePath应为File对象"},"zh-Hant":{"uniCloud.init.paramRequired":"缺少参数:{param}","uniCloud.uploadFile.fileError":"filePath应为File对象"},en:{"uniCloud.init.paramRequired":"{param} required","uniCloud.uploadFile.fileError":"filePath should be instance of File"},fr:{"uniCloud.init.paramRequired":"{param} required","uniCloud.uploadFile.fileError":"filePath should be instance of File"},es:{"uniCloud.init.paramRequired":"{param} required","uniCloud.uploadFile.fileError":"filePath should be instance of File"}},"zh-Hans");let h,l,d;try{h=require("uni-stat-config").default||require("uni-stat-config")}catch(e){h={appid:""}}function f(e=8){let t="";for(;t.length{t(Object.assign(e,{complete(e){e||(e={}),"h5"===process.env.VUE_APP_PLATFORM&&"development"===process.env.NODE_ENV&&e.errMsg&&0===e.errMsg.indexOf("request:fail")&&console.warn("发布H5,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5");const t=e.data&&e.data.header&&e.data.header["x-serverless-request-id"]||e.header&&e.header["request-id"];if(!e.statusCode||e.statusCode>=400)return n(new i({code:"SYS_ERR",message:e.errMsg||"request:fail",requestId:t}));const r=e.data;if(r.error)return n(new i({code:r.error.code,message:r.error.message,requestId:t}));r.result=r.data,r.requestId=t,delete r.data,s(r)}}))})}};const y={request:e=>uni.request(e),uploadFile:e=>uni.uploadFile(e),setStorageSync:(e,t)=>uni.setStorageSync(e,t),getStorageSync:e=>uni.getStorageSync(e),removeStorageSync:e=>uni.removeStorageSync(e),clearStorageSync:()=>uni.clearStorageSync()};class _{constructor(e){["spaceId","clientSecret"].forEach(t=>{if(!Object.prototype.hasOwnProperty.call(e,t))throw new Error(a("uniCloud.init.paramRequired",{param:t}))}),this.config=Object.assign({},{endpoint:"https://api.bspapp.com"},e),this.config.provider="aliyun",this.config.requestUrl=this.config.endpoint+"/client",this.config.envType=this.config.envType||"public",this.config.accessTokenKey="access_token_"+this.config.spaceId,this.adapter=y}get hasAccessToken(){return!!this.accessToken}setAccessToken(e){this.accessToken=e}requestWrapped(e){return m.wrappedRequest(e,this.adapter.request)}requestAuth(e){return this.requestWrapped(e)}request(e,t){return Promise.resolve().then(()=>this.hasAccessToken?t?this.requestWrapped(e):this.requestWrapped(e).catch(t=>new Promise((e,s)=>{!t||"GATEWAY_INVALID_TOKEN"!==t.code&&"InvalidParameter.InvalidToken"!==t.code?s(t):e()}).then(()=>this.getAccessToken()).then(()=>{const t=this.rebuildRequest(e);return this.request(t,!0)})):this.getAccessToken().then(()=>{const t=this.rebuildRequest(e);return this.request(t,!0)}))}rebuildRequest(e){const t=Object.assign({},e);return t.data.token=this.accessToken,t.header["x-basement-token"]=this.accessToken,t.header["x-serverless-sign"]=m.sign(t.data,this.config.clientSecret),t}setupRequest(e,t){const s=Object.assign({},e,{spaceId:this.config.spaceId,timestamp:Date.now()}),n={"Content-Type":"application/json"};return"auth"!==t&&(s.token=this.accessToken,n["x-basement-token"]=this.accessToken),n["x-serverless-sign"]=m.sign(s,this.config.clientSecret),{url:this.config.requestUrl,method:"POST",data:s,dataType:"json",header:n}}getAccessToken(){return this.requestAuth(this.setupRequest({method:"serverless.auth.user.anonymousAuthorize",params:"{}"},"auth")).then(e=>new Promise((t,s)=>{e.result&&e.result.accessToken?(this.setAccessToken(e.result.accessToken),t(this.accessToken)):s(new i({code:"AUTH_FAILED",message:"获取accessToken失败"}))}))}authorize(){this.getAccessToken()}callFunction(e){const t={method:"serverless.function.runtime.invoke",params:JSON.stringify({functionTarget:e.name,functionArgs:e.data||{}})};return this.request(this.setupRequest(t))}getOSSUploadOptionsFromPath(e){const t={method:"serverless.file.resource.generateProximalSign",params:JSON.stringify(e)};return this.request(this.setupRequest(t))}uploadFileToOSS({url:e,formData:t,name:s,filePath:n,fileType:r,onUploadProgress:o}){return new Promise((a,c)=>{const u=this.adapter.uploadFile({url:e,formData:t,name:s,filePath:n,fileType:r,header:{"X-OSS-server-side-encrpytion":"AES256"},success(e){e&&e.statusCode<400?a(e):c(new i({code:"UPLOAD_FAILED",message:"文件上传失败"}))},fail(e){c(new i({code:e.code||"UPLOAD_FAILED",message:e.message||e.errMsg||"文件上传失败"}))}});"function"==typeof o&&u&&"function"==typeof u.onProgressUpdate&&u.onProgressUpdate(e=>{o({loaded:e.totalBytesSent,total:e.totalBytesExpectedToSend})})})}reportOSSUpload(e){const t={method:"serverless.file.resource.report",params:JSON.stringify(e)};return this.request(this.setupRequest(t))}uploadFile({filePath:e,cloudPath:t,fileType:s="image",onUploadProgress:n,config:r}){if(!t)throw new i({code:"CLOUDPATH_REQUIRED",message:"cloudPath不可为空"});const o=r&&r.envType||this.config.envType;let a,c;return this.getOSSUploadOptionsFromPath({env:o,filename:t}).then(t=>{const r=t.result;a=r.id,c="https://"+r.cdnDomain+"/"+r.ossPath;const o={url:"https://"+r.host,formData:{"Cache-Control":"max-age=2592000","Content-Disposition":"attachment",OSSAccessKeyId:r.accessKeyId,Signature:r.signature,host:r.host,id:a,key:r.ossPath,policy:r.policy,success_action_status:200},fileName:"file",name:"file",filePath:e,fileType:s};return this.uploadFileToOSS(Object.assign({},o,{onUploadProgress:n}))}).then(()=>this.reportOSSUpload({id:a})).then(t=>new Promise((s,n)=>{t.success?s({success:!0,filePath:e,fileID:c}):n(new i({code:"UPLOAD_FAILED",message:"文件上传失败"}))}))}deleteFile({fileList:e}){const t={method:"serverless.file.resource.delete",params:JSON.stringify({id:e[0]})};return this.request(this.setupRequest(t))}getTempFileURL({fileList:e}={}){return new Promise((t,s)=>{Array.isArray(e)&&0!==e.length||s(new i({code:"INVALID_PARAM",message:"fileList的元素必须是非空的字符串"})),t({fileList:e.map(e=>({fileID:e,tempFileURL:e}))})})}}const v={init(e){const t=new _(e);["deleteFile","getTempFileURL"].forEach(e=>{t[e]=o(t[e]).bind(t)});const s={signInAnonymously:function(){return t.authorize()},getLoginState:function(){return Promise.resolve(!1)}};return t.auth=function(){return s},t.customAuth=t.auth,t}},w="undefined"!=typeof location&&"http:"===location.protocol?"http:":"https:",S="undefined"!=typeof process&&"e2e"===process.env.NODE_ENV&&"pre"===process.env.END_POINT?"//tcb-pre.tencentcloudapi.com/web":"//tcb-api.tencentcloudapi.com/web";var T;!function(e){e.local="local",e.none="none",e.session="session"}(T||(T={}));var k=function(){};s((function(e,t){var s;e.exports=(s=n,function(e){var t=s,n=t.lib,r=n.WordArray,o=n.Hasher,i=t.algo,a=[],c=[];!function(){function t(t){for(var s=e.sqrt(t),n=2;n<=s;n++)if(!(t%n))return!1;return!0}function s(e){return 4294967296*(e-(0|e))|0}for(var n=2,r=0;r<64;)t(n)&&(r<8&&(a[r]=s(e.pow(n,.5))),c[r]=s(e.pow(n,1/3)),r++),n++}();var u=[],h=i.SHA256=o.extend({_doReset:function(){this._hash=new r.init(a.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],o=s[2],i=s[3],a=s[4],h=s[5],l=s[6],d=s[7],f=0;f<64;f++){if(f<16)u[f]=0|e[t+f];else{var p=u[f-15],g=(p<<25|p>>>7)^(p<<14|p>>>18)^p>>>3,m=u[f-2],y=(m<<15|m>>>17)^(m<<13|m>>>19)^m>>>10;u[f]=g+u[f-7]+y+u[f-16]}var _=n&r^n&o^r&o,v=(n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22),w=d+((a<<26|a>>>6)^(a<<21|a>>>11)^(a<<7|a>>>25))+(a&h^~a&l)+c[f]+u[f];d=l,l=h,h=a,a=i+w|0,i=o,o=r,r=n,n=w+(v+_)|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+o|0,s[3]=s[3]+i|0,s[4]=s[4]+a|0,s[5]=s[5]+h|0,s[6]=s[6]+l|0,s[7]=s[7]+d|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=o._createHelper(h),t.HmacSHA256=o._createHmacHelper(h)}(Math),s.SHA256)})),s((function(e,t){e.exports=n.HmacSHA256})),s((function(e,t){var s,r,o;e.exports=(r=(s=o=n).lib.WordArray,s.enc.Base64={stringify:function(e){var t=e.words,s=e.sigBytes,n=this._map;e.clamp();for(var r=[],o=0;o>>2]>>>24-o%4*8&255)<<16|(t[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|t[o+2>>>2]>>>24-(o+2)%4*8&255,a=0;a<4&&o+.75*a>>6*(3-a)&63));var c=n.charAt(64);if(c)for(;r.length%4;)r.push(c);return r.join("")},parse:function(e){var t=e.length,s=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var o=0;o>>6-i%4*2;n[o>>>2]|=(a|c)<<24-o%4*8,o++}return r.create(n,o)}(e,t,n)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},o.enc.Base64)})),s((function(e,t){e.exports=n.enc.Utf8}));const A=()=>{let e;if(!Promise){e=()=>{},e.promise={};const t=()=>{throw new Error('Your Node runtime does support ES6 Promises. Set "global.Promise" to your preferred implementation of promises.')};return Object.defineProperty(e.promise,"then",{get:t}),Object.defineProperty(e.promise,"catch",{get:t}),e}const t=new Promise((t,s)=>{e=(e,n)=>e?s(e):t(n)});return e.promise=t,e};function P(e){return void 0===e}function I(e){return"[object Null]"===Object.prototype.toString.call(e)}var E;function O(e){const t=(s=e,"[object Array]"===Object.prototype.toString.call(s)?e:[e]);var s;for(const e of t){const{isMatch:t,genAdapter:s,runtime:n}=e;if(t())return{adapter:s(),runtime:n}}}!function(e){e.WEB="web",e.WX_MP="wx_mp"}(E||(E={}));const U={adapter:null,runtime:void 0},b=["anonymousUuidKey"];class D extends k{constructor(){super(),U.adapter.root.tcbObject||(U.adapter.root.tcbObject={})}setItem(e,t){U.adapter.root.tcbObject[e]=t}getItem(e){return U.adapter.root.tcbObject[e]}removeItem(e){delete U.adapter.root.tcbObject[e]}clear(){delete U.adapter.root.tcbObject}}function C(e,t){switch(e){case"local":return t.localStorage||new D;case"none":return new D;default:return t.sessionStorage||new D}}class R{constructor(e){if(!this._storage){this._persistence=U.adapter.primaryStorage||e.persistence,this._storage=C(this._persistence,U.adapter);const t="access_token_"+e.env,s="access_token_expire_"+e.env,n="refresh_token_"+e.env,r="anonymous_uuid_"+e.env,o="login_type_"+e.env,i="user_info_"+e.env;this.keys={accessTokenKey:t,accessTokenExpireKey:s,refreshTokenKey:n,anonymousUuidKey:r,loginTypeKey:o,userInfoKey:i}}}updatePersistence(e){if(e===this._persistence)return;const t="local"===this._persistence;this._persistence=e;const s=C(e,U.adapter);for(const e in this.keys){const n=this.keys[e];if(t&&b.includes(e))continue;const r=this._storage.getItem(n);P(r)||I(r)||(s.setItem(n,r),this._storage.removeItem(n))}this._storage=s}setStore(e,t,s){if(!this._storage)return;const n={version:s||"localCachev1",content:t},r=JSON.stringify(n);try{this._storage.setItem(e,r)}catch(e){throw e}}getStore(e,t){try{if(!this._storage)return}catch(e){return""}t=t||"localCachev1";const s=this._storage.getItem(e);if(!s)return"";if(s.indexOf(t)>=0){return JSON.parse(s).content}return""}removeStore(e){this._storage.removeItem(e)}}const x={},q={};function F(e){return x[e]}class L{constructor(e,t){this.data=t||null,this.name=e}}class N extends L{constructor(e,t){super("error",{error:e,data:t}),this.error=e}}const M=new class{constructor(){this._listeners={}}on(e,t){return function(e,t,s){s[e]=s[e]||[],s[e].push(t)}(e,t,this._listeners),this}off(e,t){return function(e,t,s){if(s&&s[e]){const n=s[e].indexOf(t);-1!==n&&s[e].splice(n,1)}}(e,t,this._listeners),this}fire(e,t){if(e instanceof N)return console.error(e.error),this;const s="string"==typeof e?new L(e,t||{}):e;const n=s.name;if(this._listens(n)){s.target=this;const e=this._listeners[n]?[...this._listeners[n]]:[];for(const t of e)t.call(this,s)}return this}_listens(e){return this._listeners[e]&&this._listeners[e].length>0}};function $(e,t){M.on(e,t)}function K(e,t={}){M.fire(e,t)}function B(e,t){M.off(e,t)}const j="loginStateChanged",H="loginStateExpire",W="loginTypeChanged",V="anonymousConverted",z="refreshAccessToken";var Y;!function(e){e.ANONYMOUS="ANONYMOUS",e.WECHAT="WECHAT",e.WECHAT_PUBLIC="WECHAT-PUBLIC",e.WECHAT_OPEN="WECHAT-OPEN",e.CUSTOM="CUSTOM",e.EMAIL="EMAIL",e.USERNAME="USERNAME",e.NULL="NULL"}(Y||(Y={}));const J=["auth.getJwt","auth.logout","auth.signInWithTicket","auth.signInAnonymously","auth.signIn","auth.fetchAccessTokenWithRefreshToken","auth.signUpWithEmailAndPassword","auth.activateEndUserMail","auth.sendPasswordResetEmail","auth.resetPasswordWithToken","auth.isUsernameRegistered"],X={"X-SDK-Version":"1.3.5"};function G(e,t,s){const n=e[t];e[t]=function(t){const r={},o={};s.forEach(s=>{const{data:n,headers:i}=s.call(e,t);Object.assign(r,n),Object.assign(o,i)});const i=t.data;return i&&(()=>{var e;if(e=i,"[object FormData]"!==Object.prototype.toString.call(e))t.data={...i,...r};else for(const e in r)i.append(e,r[e])})(),t.headers={...t.headers||{},...o},n.call(e,t)}}function Q(){const e=Math.random().toString(16).slice(2);return{data:{seqId:e},headers:{...X,"x-seqid":e}}}class Z{constructor(e={}){var t;this.config=e,this._reqClass=new U.adapter.reqClass({timeout:this.config.timeout,timeoutMsg:`请求在${this.config.timeout/1e3}s内未完成,已中断`,restrictedMethods:["post"]}),this._cache=F(this.config.env),this._localCache=(t=this.config.env,q[t]),G(this._reqClass,"post",[Q]),G(this._reqClass,"upload",[Q]),G(this._reqClass,"download",[Q])}async post(e){return await this._reqClass.post(e)}async upload(e){return await this._reqClass.upload(e)}async download(e){return await this._reqClass.download(e)}async refreshAccessToken(){let e,t;this._refreshAccessTokenPromise||(this._refreshAccessTokenPromise=this._refreshAccessToken());try{e=await this._refreshAccessTokenPromise}catch(e){t=e}if(this._refreshAccessTokenPromise=null,this._shouldRefreshAccessTokenHook=null,t)throw t;return e}async _refreshAccessToken(){const{accessTokenKey:e,accessTokenExpireKey:t,refreshTokenKey:s,loginTypeKey:n,anonymousUuidKey:r}=this._cache.keys;this._cache.removeStore(e),this._cache.removeStore(t);let o=this._cache.getStore(s);if(!o)throw new Error("未登录CloudBase");const i={refresh_token:o},a=await this.request("auth.fetchAccessTokenWithRefreshToken",i);if(a.data.code){const{code:e}=a.data;if("SIGN_PARAM_INVALID"===e||"REFRESH_TOKEN_EXPIRED"===e||"INVALID_REFRESH_TOKEN"===e){if(this._cache.getStore(n)===Y.ANONYMOUS&&"INVALID_REFRESH_TOKEN"===e){const e=this._cache.getStore(r),t=this._cache.getStore(s),n=await this.send("auth.signInAnonymously",{anonymous_uuid:e,refresh_token:t});return this.setRefreshToken(n.refresh_token),this._refreshAccessToken()}K(H),this._cache.removeStore(s)}throw new Error("刷新access token失败:"+a.data.code)}if(a.data.access_token)return K(z),this._cache.setStore(e,a.data.access_token),this._cache.setStore(t,a.data.access_token_expire+Date.now()),{accessToken:a.data.access_token,accessTokenExpire:a.data.access_token_expire};a.data.refresh_token&&(this._cache.removeStore(s),this._cache.setStore(s,a.data.refresh_token),this._refreshAccessToken())}async getAccessToken(){const{accessTokenKey:e,accessTokenExpireKey:t,refreshTokenKey:s}=this._cache.keys;if(!this._cache.getStore(s))throw new Error("refresh token不存在,登录状态异常");let n=this._cache.getStore(e),r=this._cache.getStore(t),o=!0;return this._shouldRefreshAccessTokenHook&&!await this._shouldRefreshAccessTokenHook(n,r)&&(o=!1),(!n||!r||r{e.wxOpenId&&e.wxPublicId&&(t=!0)}),{users:s,hasPrimaryUid:t}}setPrimaryUid(e){return this._request.send("auth.setPrimaryUid",{uid:e})}unlink(e){return this._request.send("auth.unlink",{platform:e})}async update(e){const{nickName:t,gender:s,avatarUrl:n,province:r,country:o,city:i}=e,{data:a}=await this._request.send("auth.updateUserInfo",{nickName:t,gender:s,avatarUrl:n,province:r,country:o,city:i});this.setLocalUserInfo(a)}async refresh(){const{data:e}=await this._request.send("auth.getUserInfo",{});return this.setLocalUserInfo(e),e}setUserInfo(){const{userInfoKey:e}=this._cache.keys,t=this._cache.getStore(e);["uid","loginType","openid","wxOpenId","wxPublicId","unionId","qqMiniOpenId","email","hasPassword","customUserId","nickName","gender","avatarUrl"].forEach(e=>{this[e]=t[e]}),this.location={country:t.country,province:t.province,city:t.city}}setLocalUserInfo(e){const{userInfoKey:t}=this._cache.keys;this._cache.setStore(t,e),this.setUserInfo()}}class re{constructor(e){if(!e)throw new Error("envId is not defined");this._cache=F(e);const{refreshTokenKey:t,accessTokenKey:s,accessTokenExpireKey:n}=this._cache.keys,r=this._cache.getStore(t),o=this._cache.getStore(s),i=this._cache.getStore(n);this.credential={refreshToken:r,accessToken:o,accessTokenExpire:i},this.user=new ne(e)}get isAnonymousAuth(){return this.loginType===Y.ANONYMOUS}get isCustomAuth(){return this.loginType===Y.CUSTOM}get isWeixinAuth(){return this.loginType===Y.WECHAT||this.loginType===Y.WECHAT_OPEN||this.loginType===Y.WECHAT_PUBLIC}get loginType(){return this._cache.getStore(this._cache.keys.loginTypeKey)}}class oe extends se{async signIn(){this._cache.updatePersistence("local");const{anonymousUuidKey:e,refreshTokenKey:t}=this._cache.keys,s=this._cache.getStore(e)||void 0,n=this._cache.getStore(t)||void 0,r=await this._request.send("auth.signInAnonymously",{anonymous_uuid:s,refresh_token:n});if(r.uuid&&r.refresh_token){this._setAnonymousUUID(r.uuid),this.setRefreshToken(r.refresh_token),await this._request.refreshAccessToken(),K(j),K(W,{env:this.config.env,loginType:Y.ANONYMOUS,persistence:"local"});const e=new re(this.config.env);return await e.user.refresh(),e}throw new Error("匿名登录失败")}async linkAndRetrieveDataWithTicket(e){const{anonymousUuidKey:t,refreshTokenKey:s}=this._cache.keys,n=this._cache.getStore(t),r=this._cache.getStore(s),o=await this._request.send("auth.linkAndRetrieveDataWithTicket",{anonymous_uuid:n,refresh_token:r,ticket:e});if(o.refresh_token)return this._clearAnonymousUUID(),this.setRefreshToken(o.refresh_token),await this._request.refreshAccessToken(),K(V,{env:this.config.env}),K(W,{loginType:Y.CUSTOM,persistence:"local"}),{credential:{refreshToken:o.refresh_token}};throw new Error("匿名转化失败")}_setAnonymousUUID(e){const{anonymousUuidKey:t,loginTypeKey:s}=this._cache.keys;this._cache.removeStore(t),this._cache.setStore(t,e),this._cache.setStore(s,Y.ANONYMOUS)}_clearAnonymousUUID(){this._cache.removeStore(this._cache.keys.anonymousUuidKey)}}class ie extends se{async signIn(e){if("string"!=typeof e)throw new Error("ticket must be a string");const{refreshTokenKey:t}=this._cache.keys,s=await this._request.send("auth.signInWithTicket",{ticket:e,refresh_token:this._cache.getStore(t)||""});if(s.refresh_token)return this.setRefreshToken(s.refresh_token),await this._request.refreshAccessToken(),K(j),K(W,{env:this.config.env,loginType:Y.CUSTOM,persistence:this.config.persistence}),await this.refreshUserInfo(),new re(this.config.env);throw new Error("自定义登录失败")}}class ae extends se{async signIn(e,t){if("string"!=typeof e)throw new Error("email must be a string");const{refreshTokenKey:s}=this._cache.keys,n=await this._request.send("auth.signIn",{loginType:"EMAIL",email:e,password:t,refresh_token:this._cache.getStore(s)||""}),{refresh_token:r,access_token:o,access_token_expire:i}=n;if(r)return this.setRefreshToken(r),o&&i?this.setAccessToken(o,i):await this._request.refreshAccessToken(),await this.refreshUserInfo(),K(j),K(W,{env:this.config.env,loginType:Y.EMAIL,persistence:this.config.persistence}),new re(this.config.env);throw n.code?new Error(`邮箱登录失败: [${n.code}] ${n.message}`):new Error("邮箱登录失败")}async activate(e){return this._request.send("auth.activateEndUserMail",{token:e})}async resetPasswordWithToken(e,t){return this._request.send("auth.resetPasswordWithToken",{token:e,newPassword:t})}}class ce extends se{async signIn(e,t){if("string"!=typeof e)throw new Error("username must be a string");"string"!=typeof t&&(t="",console.warn("password is empty"));const{refreshTokenKey:s}=this._cache.keys,n=await this._request.send("auth.signIn",{loginType:Y.USERNAME,username:e,password:t,refresh_token:this._cache.getStore(s)||""}),{refresh_token:r,access_token_expire:o,access_token:i}=n;if(r)return this.setRefreshToken(r),i&&o?this.setAccessToken(i,o):await this._request.refreshAccessToken(),await this.refreshUserInfo(),K(j),K(W,{env:this.config.env,loginType:Y.USERNAME,persistence:this.config.persistence}),new re(this.config.env);throw n.code?new Error(`用户名密码登录失败: [${n.code}] ${n.message}`):new Error("用户名密码登录失败")}}class ue{constructor(e){this.config=e,this._cache=F(e.env),this._request=te(e.env),this._onAnonymousConverted=this._onAnonymousConverted.bind(this),this._onLoginTypeChanged=this._onLoginTypeChanged.bind(this),$(W,this._onLoginTypeChanged)}get currentUser(){const e=this.hasLoginState();return e&&e.user||null}get loginType(){return this._cache.getStore(this._cache.keys.loginTypeKey)}anonymousAuthProvider(){return new oe(this.config)}customAuthProvider(){return new ie(this.config)}emailAuthProvider(){return new ae(this.config)}usernameAuthProvider(){return new ce(this.config)}async signInAnonymously(){return new oe(this.config).signIn()}async signInWithEmailAndPassword(e,t){return new ae(this.config).signIn(e,t)}signInWithUsernameAndPassword(e,t){return new ce(this.config).signIn(e,t)}async linkAndRetrieveDataWithTicket(e){this._anonymousAuthProvider||(this._anonymousAuthProvider=new oe(this.config)),$(V,this._onAnonymousConverted);return await this._anonymousAuthProvider.linkAndRetrieveDataWithTicket(e)}async signOut(){if(this.loginType===Y.ANONYMOUS)throw new Error("匿名用户不支持登出操作");const{refreshTokenKey:e,accessTokenKey:t,accessTokenExpireKey:s}=this._cache.keys,n=this._cache.getStore(e);if(!n)return;const r=await this._request.send("auth.logout",{refresh_token:n});return this._cache.removeStore(e),this._cache.removeStore(t),this._cache.removeStore(s),K(j),K(W,{env:this.config.env,loginType:Y.NULL,persistence:this.config.persistence}),r}async signUpWithEmailAndPassword(e,t){return this._request.send("auth.signUpWithEmailAndPassword",{email:e,password:t})}async sendPasswordResetEmail(e){return this._request.send("auth.sendPasswordResetEmail",{email:e})}onLoginStateChanged(e){$(j,()=>{const t=this.hasLoginState();e.call(this,t)});const t=this.hasLoginState();e.call(this,t)}onLoginStateExpired(e){$(H,e.bind(this))}onAccessTokenRefreshed(e){$(z,e.bind(this))}onAnonymousConverted(e){$(V,e.bind(this))}onLoginTypeChanged(e){$(W,()=>{const t=this.hasLoginState();e.call(this,t)})}async getAccessToken(){return{accessToken:(await this._request.getAccessToken()).accessToken,env:this.config.env}}hasLoginState(){const{refreshTokenKey:e}=this._cache.keys;return this._cache.getStore(e)?new re(this.config.env):null}async isUsernameRegistered(e){if("string"!=typeof e)throw new Error("username must be a string");const{data:t}=await this._request.send("auth.isUsernameRegistered",{username:e});return t&&t.isRegistered}getLoginState(){return Promise.resolve(this.hasLoginState())}async signInWithTicket(e){return new ie(this.config).signIn(e)}shouldRefreshAccessToken(e){this._request._shouldRefreshAccessTokenHook=e.bind(this)}getUserInfo(){return this._request.send("auth.getUserInfo",{}).then(e=>e.code?e:{...e.data,requestId:e.seqId})}getAuthHeader(){const{refreshTokenKey:e,accessTokenKey:t}=this._cache.keys,s=this._cache.getStore(e);return{"x-cloudbase-credentials":this._cache.getStore(t)+"/@@/"+s}}_onAnonymousConverted(e){const{env:t}=e.data;t===this.config.env&&this._cache.updatePersistence(this.config.persistence)}_onLoginTypeChanged(e){const{loginType:t,persistence:s,env:n}=e.data;n===this.config.env&&(this._cache.updatePersistence(s),this._cache.setStore(this._cache.keys.loginTypeKey,t))}}const he=function(e,t){t=t||A();const s=te(this.config.env),{cloudPath:n,filePath:r,onUploadProgress:o,fileType:i="image"}=e;return s.send("storage.getUploadMetadata",{path:n}).then(e=>{const{data:{url:a,authorization:c,token:u,fileId:h,cosFileId:l},requestId:d}=e,f={key:n,signature:c,"x-cos-meta-fileid":l,success_action_status:"201","x-cos-security-token":u};s.upload({url:a,data:f,file:r,name:n,fileType:i,onUploadProgress:o}).then(e=>{201===e.statusCode?t(null,{fileID:h,requestId:d}):t(new Error("STORAGE_REQUEST_FAIL: "+e.data))}).catch(e=>{t(e)})}).catch(e=>{t(e)}),t.promise},le=function(e,t){t=t||A();const s=te(this.config.env),{cloudPath:n}=e;return s.send("storage.getUploadMetadata",{path:n}).then(e=>{t(null,e)}).catch(e=>{t(e)}),t.promise},de=function({fileList:e},t){if(t=t||A(),!e||!Array.isArray(e))return{code:"INVALID_PARAM",message:"fileList必须是非空的数组"};for(let t of e)if(!t||"string"!=typeof t)return{code:"INVALID_PARAM",message:"fileList的元素必须是非空的字符串"};const s={fileid_list:e};return te(this.config.env).send("storage.batchDeleteFile",s).then(e=>{e.code?t(null,e):t(null,{fileList:e.data.delete_list,requestId:e.requestId})}).catch(e=>{t(e)}),t.promise},fe=function({fileList:e},t){t=t||A(),e&&Array.isArray(e)||t(null,{code:"INVALID_PARAM",message:"fileList必须是非空的数组"});let s=[];for(let n of e)"object"==typeof n?(n.hasOwnProperty("fileID")&&n.hasOwnProperty("maxAge")||t(null,{code:"INVALID_PARAM",message:"fileList的元素必须是包含fileID和maxAge的对象"}),s.push({fileid:n.fileID,max_age:n.maxAge})):"string"==typeof n?s.push({fileid:n}):t(null,{code:"INVALID_PARAM",message:"fileList的元素必须是字符串"});const n={file_list:s};return te(this.config.env).send("storage.batchGetDownloadUrl",n).then(e=>{e.code?t(null,e):t(null,{fileList:e.data.download_list,requestId:e.requestId})}).catch(e=>{t(e)}),t.promise},pe=async function({fileID:e},t){const s=(await fe.call(this,{fileList:[{fileID:e,maxAge:600}]})).fileList[0];if("SUCCESS"!==s.code)return t?t(s):new Promise(e=>{e(s)});const n=te(this.config.env);let r=s.download_url;if(r=encodeURI(r),!t)return n.download({url:r});t(await n.download({url:r}))},ge=function({name:e,data:t,query:s,parse:n,search:r},o){const i=o||A();let a;try{a=t?JSON.stringify(t):""}catch(e){return Promise.reject(e)}if(!e)return Promise.reject(new Error("函数名不能为空"));const c={inQuery:s,parse:n,search:r,function_name:e,request_data:a};return te(this.config.env).send("functions.invokeFunction",c).then(e=>{if(e.code)i(null,e);else{let t=e.data.response_data;if(n)i(null,{result:t,requestId:e.requestId});else try{t=JSON.parse(e.data.response_data),i(null,{result:t,requestId:e.requestId})}catch(e){i(new Error("response data must be json"))}}return i.promise}).catch(e=>{i(e)}),i.promise},me={timeout:15e3,persistence:"session"},ye={};class _e{constructor(e){this.config=e||this.config,this.authObj=void 0}init(e){switch(U.adapter||(this.requestClient=new U.adapter.reqClass({timeout:e.timeout||5e3,timeoutMsg:`请求在${(e.timeout||5e3)/1e3}s内未完成,已中断`})),this.config={...me,...e},!0){case this.config.timeout>6e5:console.warn("timeout大于可配置上限[10分钟],已重置为上限数值"),this.config.timeout=6e5;break;case this.config.timeout<100:console.warn("timeout小于可配置下限[100ms],已重置为下限数值"),this.config.timeout=100}return new _e(this.config)}auth({persistence:e}={}){if(this.authObj)return this.authObj;const t=e||U.adapter.primaryStorage||me.persistence;var s;return t!==this.config.persistence&&(this.config.persistence=t),function(e){const{env:t}=e;x[t]=new R(e),q[t]=new R({...e,persistence:"local"})}(this.config),s=this.config,ee[s.env]=new Z(s),this.authObj=new ue(this.config),this.authObj}on(e,t){return $.apply(this,[e,t])}off(e,t){return B.apply(this,[e,t])}callFunction(e,t){return ge.apply(this,[e,t])}deleteFile(e,t){return de.apply(this,[e,t])}getTempFileURL(e,t){return fe.apply(this,[e,t])}downloadFile(e,t){return pe.apply(this,[e,t])}uploadFile(e,t){return he.apply(this,[e,t])}getUploadMetadata(e,t){return le.apply(this,[e,t])}registerExtension(e){ye[e.name]=e}async invokeExtension(e,t){const s=ye[e];if(!s)throw Error(`扩展${e} 必须先注册`);return await s.invoke(t,this)}useAdapters(e){const{adapter:t,runtime:s}=O(e)||{};t&&(U.adapter=t),s&&(U.runtime=s)}}const ve=new _e;function we(e,t,s){void 0===s&&(s={});var n=/\?/.test(t),r="";for(var o in s)""===r?!n&&(t+="?"):r+="&",r+=o+"="+encodeURIComponent(s[o]);return/^http(s)?:\/\//.test(t+=r)?t:""+e+t}class Se{post(e){const{url:t,data:s,headers:n}=e;return new Promise((e,r)=>{y.request({url:we("https:",t),data:s,method:"POST",header:n,success(t){e(t)},fail(e){r(e)}})})}upload(e){return new Promise((t,s)=>{const{url:n,file:r,data:o,headers:i,fileType:a}=e,c=y.uploadFile({url:we("https:",n),name:"file",formData:Object.assign({},o),filePath:r,fileType:a,header:i,success(e){const s={statusCode:e.statusCode,data:e.data||{}};200===e.statusCode&&o.success_action_status&&(s.statusCode=parseInt(o.success_action_status,10)),t(s)},fail(e){"mp-alipay"===process.env.VUE_APP_PLATFORM&&"development"===process.env.NODE_ENV&&console.warn("支付宝小程序开发工具上传腾讯云时无法准确判断是否上传成功,请使用真机测试"),s(new Error(e.errMsg||"uploadFile:fail"))}});"function"==typeof e.onUploadProgress&&c&&"function"==typeof c.onProgressUpdate&&c.onProgressUpdate(t=>{e.onUploadProgress({loaded:t.totalBytesSent,total:t.totalBytesExpectedToSend})})})}}const Te={setItem(e,t){y.setStorageSync(e,t)},getItem:e=>y.getStorageSync(e),removeItem(e){y.removeStorageSync(e)},clear(){y.clearStorageSync()}};const ke={genAdapter:function(){return{root:{},reqClass:Se,localStorage:Te,primaryStorage:"local"}},isMatch:function(){return!0},runtime:"uni_app"};ve.useAdapters(ke);const Ae=ve,Pe=Ae.init;Ae.init=function(e){e.env=e.spaceId;const t=Pe.call(this,e);t.config.provider="tencent",t.config.spaceId=e.spaceId;const s=t.auth;t.auth=function(e){const t=s.call(this,e);return["linkAndRetrieveDataWithTicket","signInAnonymously","signOut","getAccessToken","getLoginState","signInWithTicket","getUserInfo"].forEach(e=>{t[e]=o(t[e]).bind(t)}),t},t.customAuth=t.auth;return["deleteFile","getTempFileURL","downloadFile"].forEach(e=>{t[e]=o(t[e]).bind(t)}),t};class Ie extends _{getAccessToken(){return new Promise((e,t)=>{this.setAccessToken("Anonymous_Access_token"),e("Anonymous_Access_token")})}uploadFileToOSS({url:e,formData:t,name:s,filePath:n,fileType:r,onUploadProgress:o}){return new Promise((a,c)=>{const u=this.adapter.uploadFile({url:e,formData:t,name:s,filePath:n,fileType:r,success(e){e&&e.statusCode<400?a(e):c(new i({code:"UPLOAD_FAILED",message:"文件上传失败"}))},fail(e){c(new i({code:e.code||"UPLOAD_FAILED",message:e.message||e.errMsg||"文件上传失败"}))}});"function"==typeof o&&u&&"function"==typeof u.onProgressUpdate&&u.onProgressUpdate(e=>{o({loaded:e.totalBytesSent,total:e.totalBytesExpectedToSend})})})}uploadFile({filePath:e,cloudPath:t,fileType:s="image",onUploadProgress:n}){if(!t)throw new i({code:"CLOUDPATH_REQUIRED",message:"cloudPath不可为空"});let r;return this.getOSSUploadOptionsFromPath({filename:t}).then(t=>{const{url:o,formData:i,name:a,fileUrl:c}=t.result;r=c;const u={url:o,formData:i,name:a,filePath:e,fileType:s};return this.uploadFileToOSS(Object.assign({},u,{onUploadProgress:n}))}).then(()=>this.reportOSSUpload({id:t})).then(t=>new Promise((s,n)=>{t.success?s({success:!0,filePath:e,fileID:r}):n(new i({code:"UPLOAD_FAILED",message:"文件上传失败"}))}))}}const Ee={init(e){const t=new Ie(e);["deleteFile","getTempFileURL"].forEach(e=>{t[e]=o(t[e]).bind(t)});const s={signInAnonymously:function(){return t.authorize()},getLoginState:function(){return Promise.resolve(!1)}};return t.auth=function(){return s},t.customAuth=t.auth,t}};let Oe,Ue;function be({name:e,data:t,spaceId:s,provider:n}){Oe||(Oe=function(){const{deviceId:e}=uni.getSystemInfoSync();return{PLATFORM:process.env.VUE_APP_PLATFORM,OS:d,APPID:h.appid,LOCALE:u(),DEVICEID:e,CLIENT_SDK_VERSION:"1.0.1"}}(),Ue={ak:h.appid,p:"android"===d?"a":"i",ut:g(),uuid:p()});const r=JSON.parse(JSON.stringify(t||{})),o=e,i=s,a={tencent:"t",aliyun:"a"}[n];{const e=Object.assign({},Ue,{fn:o,sid:i,pvd:a});Object.assign(r,{clientInfo:Oe,uniCloudClientInfo:encodeURIComponent(JSON.stringify(e))});const{deviceId:t}=uni.getSystemInfoSync();r.uniCloudDeviceId=t}if(!r.uniIdToken){const e=y.getStorageSync("uni_id_token")||y.getStorageSync("uniIdToken");e&&(r.uniIdToken=e)}return r}function De({name:e,data:t}){const{localAddress:s,localPort:n}=this,r={aliyun:"aliyun",tencent:"tcb"}[this.config.provider],o=this.config.spaceId,a=`http://${s}:${n}/system/check-function`,c=`http://${s}:${n}/cloudfunctions/${e}`;return new Promise((t,s)=>{y.request({method:"POST",url:a,data:{name:e,platform:process.env.VUE_APP_PLATFORM,provider:r,spaceId:o},timeout:3e3,success(e){t(e)},fail(){t({data:{code:"NETWORK_ERROR",message:"连接本地调试服务失败,请检查客户端是否和主机在同一局域网下,自动切换为已部署的云函数。"}})}})}).then(({data:e}={})=>{const{code:t,message:s}=e||{};return{code:0===t?0:t||"SYS_ERR",message:s||"SYS_ERR"}}).then(({code:s,message:n})=>{if(0!==s){switch(s){case"MODULE_ENCRYPTED":console.error(`此云函数(${e})依赖加密公共模块不可本地调试,自动切换为云端已部署的云函数`);break;case"FUNCTION_ENCRYPTED":console.error(`此云函数(${e})已加密不可本地调试,自动切换为云端已部署的云函数`);break;case"ACTION_ENCRYPTED":console.error(n||"需要访问加密的uni-clientDB-action,自动切换为云端环境");break;case"NETWORK_ERROR":{const e="连接本地调试服务失败,请检查客户端是否和主机在同一局域网下";throw console.error(e),new Error(e)}case"SWITCH_TO_CLOUD":break;default:{const e=`检测本地调试服务出现错误:${n},请检查网络环境或重启客户端再试`;throw console.error(e),new Error(e)}}return this.originCallFunction({name:e,data:t})}return new Promise((s,n)=>{const a=be({name:e,data:t,provider:this.config.provider,spaceId:o});y.request({method:"POST",url:c,data:{provider:r,platform:process.env.VUE_APP_PLATFORM,param:a},success:({statusCode:e,data:t}={})=>!e||e>=400?n(new i({code:t.code||"SYS_ERR",message:t.message||"request:fail"})):s({result:t}),fail(e){n(new i({code:e.code||e.errCode||"SYS_ERR",message:e.message||e.errMsg||"request:fail"}))}})})})}const Ce=[{rule:/fc_function_not_found|FUNCTION_NOT_FOUND/,content:",云函数[{functionName}]在云端不存在,请检查此云函数名称是否正确已经是否已上传到服务空间",mode:"append"}];var Re=/[\\^$.*+?()[\]{}|]/g,xe=RegExp(Re.source);function qe(e,t,s){return e.replace(new RegExp((n=t)&&xe.test(n)?n.replace(Re,"\\$&"):n,"g"),s);var n}function Fe(e){const t=e.callFunction;e.callFunction=function(e){let s;s=this.isReady?Promise.resolve():this.initUniCloud;const n=e.name;return s.then(()=>{e.data=be({name:n,data:e.data,provider:this.config.provider,spaceId:this.config.spaceId});const s={aliyun:"aliyun",tencent:"tcb"}[this.config.provider];return new Promise((r,o)=>{t.call(this,e).then(e=>{if(this.config.useDebugFunction&&e&&e.requestId){const t=JSON.stringify({spaceId:this.config.spaceId,functionName:n,requestId:e.requestId});console.log(`[${s}-request]${t}[/${s}-request]`)}r(e)}).catch(t=>{if(this.config.useDebugFunction&&t&&t.requestId){const e=JSON.stringify({spaceId:this.config.spaceId,functionName:n,requestId:t.requestId});console.log(`[${s}-request]${e}[/${s}-request]`)}t&&t.message&&(t.message=function({message:e="",extraInfo:t={},formatter:s=[]}={}){for(let n=0;n"development"===process.env.NODE_ENV&&e.debugInfo&&!e.debugInfo.forceRemote&&process.env.UNI_CLOUD_PROVIDER?De.call(this,t):s.call(this,t))})).call(this,t)}}const Le=Symbol("CLIENT_DB_INTERNAL");function Ne(e,t){return e.then="DoNotReturnProxyWithAFunctionNamedThen",e._internalType=Le,new Proxy(e,{get:(e,s,n)=>function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}(e,s)||e[s]||"string"!=typeof s?e[s]:t.get(e,s,n)})}class Me extends Error{constructor(e,t){super(e),this.code=t}}function $e(e){switch(t=e,Object.prototype.toString.call(t).slice(8,-1).toLowerCase()){case"array":return e.map(e=>$e(e));case"object":return e._internalType===Le||Object.keys(e).forEach(t=>{e[t]=$e(e[t])}),e;case"regexp":return{$regexp:{source:e.source,flags:e.flags}};case"date":return{$date:e.toISOString()};default:return e}var t}function Ke(){const e=y.getStorageSync("uni_id_token")||"",t=e.split(".");if(!e||3!==t.length)return{uid:null,role:[],permission:[]};let s;try{s=JSON.parse((n=t[1],decodeURIComponent(atob(n).split("").map((function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})).join(""))))}catch(e){throw new Error("获取当前用户信息出错,详细错误信息为:"+e.message)}var n;return s}var Be=t(s((function(e,t){Object.defineProperty(t,"__esModule",{value:!0});const s="chooseAndUploadFile:fail";function n(e,t){return e.tempFiles.forEach((e,s)=>{e.name||(e.name=e.path.substring(e.path.lastIndexOf("/")+1)),t&&(e.fileType=t),e.cloudPath=Date.now()+"_"+s+e.name.substring(e.name.lastIndexOf("."))}),e.tempFilePaths||(e.tempFilePaths=e.tempFiles.map(e=>e.path)),e}function r(e,t,{onChooseFile:s,onUploadProgress:n}){return t.then(e=>{if(s){const t=s(e);if(void 0!==t)return Promise.resolve(t).then(t=>void 0===t?e:t)}return e}).then(t=>!1===t?{errMsg:"chooseAndUploadFile:ok",tempFilePaths:[],tempFiles:[]}:function(e,t,s=5,n){(t=Object.assign({},t)).errMsg="chooseAndUploadFile:ok";const r=t.tempFiles,o=r.length;let i=0;return new Promise(a=>{for(;i=o)return void(!r.find(e=>!e.url&&!e.errMsg)&&a(t));const u=r[s];e.uploadFile({filePath:u.path,cloudPath:u.cloudPath,fileType:u.fileType,onUploadProgress(e){e.index=s,e.tempFile=u,e.tempFilePath=u.path,n&&n(e)}}).then(e=>{u.url=e.fileID,s{u.errMsg=e.errMsg||e.message,s{uni.chooseImage({count:t,sizeType:r,sourceType:o,extension:i,success(t){e(n(t,"image"))},fail(e){a({errMsg:e.errMsg.replace("chooseImage:fail",s)})}})})}(t),t):"video"===t.type?r(e,function(e){const{camera:t,compressed:r,maxDuration:o,sourceType:i,extension:a}=e;return new Promise((e,c)=>{uni.chooseVideo({camera:t,compressed:r,maxDuration:o,sourceType:i,extension:a,success(t){const{tempFilePath:s,duration:r,size:o,height:i,width:a}=t;e(n({errMsg:"chooseVideo:ok",tempFilePaths:[s],tempFiles:[{name:t.tempFile&&t.tempFile.name||"",path:s,size:o,type:t.tempFile&&t.tempFile.type||"",width:a,height:i,duration:r,fileType:"video",cloudPath:""}]},"video"))},fail(e){c({errMsg:e.errMsg.replace("chooseVideo:fail",s)})}})})}(t),t):r(e,function(e){const{count:t,extension:r}=e;return new Promise((e,o)=>{let i=uni.chooseFile;if("undefined"!=typeof wx&&"function"==typeof wx.chooseMessageFile&&(i=wx.chooseMessageFile),"function"!=typeof i)return o({errMsg:s+" 请指定 type 类型,该平台仅支持选择 image 或 video。"});i({type:"all",count:t,extension:r,success(t){e(n(t))},fail(e){o({errMsg:e.errMsg.replace("chooseFile:fail",s)})}})})}(t),t)}}})));const je="manual";async function He(e,t){const s=`http://${e}:${t}/system/ping`;try{const e=await(n={url:s,timeout:500},new Promise((e,t)=>{y.request({...n,success(t){e(t)},fail(e){t(e)}})}));return!(!e.data||0!==e.data.code)}catch(e){return!1}var n}let We=new class{init(e){let t={};const s=!1!==e.debugFunction&&"development"===process.env.NODE_ENV&&("h5"===process.env.VUE_APP_PLATFORM&&navigator.userAgent.indexOf("HBuilderX")>0||"app-plus"===process.env.VUE_APP_PLATFORM);switch(e.provider){case"tencent":t=Ae.init(Object.assign(e,{useDebugFunction:s}));break;case"aliyun":t=v.init(Object.assign(e,{useDebugFunction:s}));break;case"private":t=Ee.init(Object.assign(e,{useDebugFunction:s}));break;default:throw new Error("未提供正确的provider参数")}const n=process.env.UNICLOUD_DEBUG;"development"===process.env.NODE_ENV&&n&&!n.code&&(t.debugInfo=n),t.isReady=!1;const r=t.auth();return t.initUniCloud=r.getLoginState().then(e=>e?Promise.resolve():r.signInAnonymously()).then(()=>{if("development"===process.env.NODE_ENV&&t.debugInfo){const{address:e,servePort:s}=t.debugInfo;return async function(e,t){let s;for(let n=0;n{if(e)t.localAddress=e,t.localPort=s;else if(t.debugInfo){const e="app-plus"===process.env.VUE_APP_PLATFORM?"error":"warn",s=console[e];"remote"===t.debugInfo.initialLaunchType?(t.debugInfo.forceRemote=!0,s("当前客户端和HBuilderX不在同一局域网下(或其他网络原因无法连接HBuilderX),uniCloud本地调试服务不对当前客户端生效。\n- 如果不使用uniCloud本地调试服务,请直接忽略此信息。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。\n- 如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试")):s("无法连接uniCloud本地调试服务,请检查当前客户端是否与主机在同一局域网下。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。\n- 如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试")}}).then(()=>(function(){if("h5"!==process.env.VUE_APP_PLATFORM||"development"!==process.env.NODE_ENV)return;if(uni.getStorageSync("__LAST_DCLOUD_APPID")===h.appid)return;uni.setStorageSync("__LAST_DCLOUD_APPID",h.appid),uni.removeStorageSync("uni_id_token")&&(console.warn("检测到当前项目与上次运行到此端口的项目不一致,自动清理uni-id保存的token信息(仅开发调试时生效)"),uni.removeStorageSync("uni_id_token"),uni.removeStorageSync("uni_id_token_expired"))}(),new Promise(e=>{"quickapp-native"===process.env.VUE_APP_PLATFORM?(d="android",uni.getStorage({key:"__DC_CLOUD_UUID",success(t){l=t.data?t.data:f(32),e()}})):setTimeout(()=>{d=uni.getSystemInfoSync().platform,l=uni.getStorageSync("__DC_CLOUD_UUID")||f(32),e()},0)}))).then(()=>{t.isReady=!0}),Fe(t),function(e){const t=e.uploadFile;e.uploadFile=function(e){let s;return s=this.isReady?Promise.resolve():this.initUniCloud,s.then(()=>t.call(this,e))};const s=e.uploadFile;e.uploadFile=function(e){return o(s).call(this,e)}}(t),function(e){e.database=function(){if(this._database)return this._database;const t={},s={};class n{constructor(e,t,s){this.content=e,this.prevStage=t,this.actionName=s}toJSON(){let e=this;const t=[e.content];for(;e.prevStage;)e=e.prevStage,t.push(e.content);return{$db:t.reverse().map(e=>({$method:e.$method,$param:e.$param}))}}get useAggregate(){let e=this,t=!1;for(;e.prevStage;){e=e.prevStage;const s=e.content.$method;if("aggregate"===s||"pipeline"===s){t=!0;break}}return t}get count(){if(!this.useAggregate)return function(){return this._send("count",Array.from(arguments))};const e=this;return function(){return i({$method:"count",$param:$e(Array.from(arguments))},e,e.actionName)}}get(){return this._send("get",Array.from(arguments))}add(){return this._send("add",Array.from(arguments))}remove(){return this._send("remove",Array.from(arguments))}update(){return this._send("update",Array.from(arguments))}end(){return this._send("end",Array.from(arguments))}set(){throw new Error("clientDB禁止使用set方法")}_send(n,r){const o=this.toJSON();return o.$db.push({$method:n,$param:r}),e.callFunction({name:"DCloud-clientDB",data:{action:this.actionName,command:o}}).then(e=>{const{code:n,message:r,token:o,tokenExpired:i,systemInfo:a=[]}=e.result;if(a)for(let e=0;e{e({token:o,tokenExpired:i})}),o&&i&&s.refreshToken&&s.refreshToken.forEach(e=>{e({token:o,tokenExpired:i})}),Promise.resolve(e))}).catch(e=>{const t=new Me(e.message,e.code||"SYSTEM_ERROR");return s.error&&s.error.forEach(e=>{e(t)}),/fc_function_not_found|FUNCTION_NOT_FOUND/g.test(e.message)&&console.warn("clientDB未初始化,请在web控制台保存一次schema以开启clientDB"),Promise.reject(e)})}}const r=["db.Geo","db.command","command.aggregate"];function o(e,t){return r.indexOf(`${e}.${t}`)>-1}function i(e,t,s){return Ne(new n(e,t,s),{get(e,t){let n="db";return e&&e.content&&(n=e.content.$method),o(n,t)?i({$method:t},e,s):function(){return i({$method:t,$param:$e(Array.from(arguments))},e,s)}}})}function a({path:e,method:t}){return class{constructor(){this.param=Array.from(arguments)}toJSON(){return{$newDb:[...e.map(e=>({$method:e})),{$method:t,$param:this.param}]}}}}const c={auth:{on:(e,s)=>{t[e]=t[e]||[],t[e].indexOf(s)>-1||t[e].push(s)},off:(e,s)=>{t[e]=t[e]||[];const n=t[e].indexOf(s);-1!==n&&t[e].splice(n,1)}},on:(e,t)=>{s[e]=s[e]||[],s[e].indexOf(t)>-1||s[e].push(t)},off:(e,t)=>{s[e]=s[e]||[];const n=s[e].indexOf(t);-1!==n&&s[e].splice(n,1)},env:Ne({},{get:(e,t)=>({$env:t})}),action:e=>Ne({},{get:(t,s)=>o("db",s)?i({$method:s},null,e):function(){return i({$method:s,$param:$e(Array.from(arguments))},null,e)}}),Geo:Ne({},{get:(e,t)=>a({path:["Geo"],method:t})}),getCloudEnv:function(e){if("string"!=typeof e||!e.trim())throw new Error("getCloudEnv参数错误");return{$env:e.replace("$cloudEnv_","")}},get serverDate(){return a({path:[],method:"serverDate"})},get RegExp(){return a({path:[],method:"RegExp"})}},u=Ne(c,{get:(e,t)=>o("db",t)?i({$method:t}):function(){return i({$method:t,$param:$e(Array.from(arguments))})}});return this._database=u,u}}(t),function(e){e.getCurrentUserInfo=Ke,e.chooseAndUploadFile=o(Be.initChooseAndUploadFile(e))}(t),t.init=this.init,t}};(()=>{{let e={};if(1===process.env.UNI_CLOUD_PROVIDER.length)e=process.env.UNI_CLOUD_PROVIDER[0],We=We.init(e);else{const e=["auth","callFunction","uploadFile","deleteFile","getTempFileURL","downloadFile","database","getCurrentUSerInfo"],t=process.env.UNI_CLOUD_PROVIDER.length>0?"应用有多个服务空间,请通过uniCloud.init方法指定要使用的服务空间":"应用未关联服务空间,请在cloudfunctions目录右键关联服务空间";e.forEach(e=>{We[e]=function(){return console.error(t),Promise.reject(new i({code:"SYS_ERR",message:t}))}})}Object.assign(We,{get mixinDatacom(){return e=We,{props:{localdata:{type:Array,default:()=>[]},options:{type:[Object,Array],default:()=>({})},collection:{type:String,default:""},action:{type:String,default:""},field:{type:String,default:""},orderby:{type:String,default:""},where:{type:[String,Object],default:""},pageData:{type:String,default:"add"},pageCurrent:{type:Number,default:1},pageSize:{type:Number,default:20},getcount:{type:[Boolean,String],default:!1},gettree:{type:[Boolean,String],default:!1},gettreepath:{type:[Boolean,String],default:!1},startwith:{type:String,default:""},limitlevel:{type:Number,default:10},groupby:{type:String,default:""},groupField:{type:String,default:""},distinct:{type:[Boolean,String],default:!1},foreignKey:{type:String,default:""},loadtime:{type:String,default:"auto"},manual:{type:Boolean,default:!1}},data:()=>({mixinDatacomLoading:!1,mixinDatacomHasMore:!1,mixinDatacomResData:[],mixinDatacomErrorMessage:"",mixinDatacomPage:{}}),created(){this.mixinDatacomPage={current:this.pageCurrent,size:this.pageSize,count:0},this.$watch(()=>{var e=[];return["pageCurrent","pageSize","localdata","collection","action","field","orderby","where","getont","getcount","gettree","groupby","groupField","distinct"].forEach(t=>{e.push(this[t])}),e},(e,t)=>{if(this.loadtime===je)return;let s=!1;const n=[];for(let r=2;r{this.mixinDatacomLoading=!1;const{data:n,count:r}=s.result;this.getcount&&(this.mixinDatacomPage.count=r),this.mixinDatacomHasMore=n.length{this.mixinDatacomLoading=!1,this.mixinDatacomErrorMessage=e,s&&s(e)}))},mixinDatacomGet(t={}){let s=e.database();const n=t.action||this.action;n&&(s=s.action(n));const r=t.collection||this.collection;s=s.collection(r);const o=t.where||this.where;o&&Object.keys(o).length&&(s=s.where(o));const i=t.field||this.field;i&&(s=s.field(i));const a=t.foreignKey||this.foreignKey;a&&(s=s.foreignKey(a));const c=t.groupby||this.groupby;c&&(s=s.groupBy(c));const u=t.groupField||this.groupField;u&&(s=s.groupField(u)),!0===(void 0!==t.distinct?t.distinct:this.distinct)&&(s=s.distinct());const h=t.orderby||this.orderby;h&&(s=s.orderBy(h));const l=void 0!==t.pageCurrent?t.pageCurrent:this.mixinDatacomPage.current,d=void 0!==t.pageSize?t.pageSize:this.mixinDatacomPage.size,f=void 0!==t.getcount?t.getcount:this.getcount,p=void 0!==t.gettree?t.gettree:this.gettree,g=void 0!==t.gettreepath?t.gettreepath:this.gettreepath,m={getCount:f},y={limitLevel:void 0!==t.limitlevel?t.limitlevel:this.limitlevel,startWith:void 0!==t.startwith?t.startwith:this.startwith};return p&&(m.getTree=y),g&&(m.getTreePath=y),s=s.skip(d*(l-1)).limit(d).get(m),s}}};var e}})}})();var Ve=We;export default Ve; +'use strict'; + +var uniI18n = require('@dcloudio/uni-i18n'); + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +function createCommonjsModule(fn, basedir, module) { + return module = { + path: basedir, + exports: {}, + require: function (path, base) { + return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); + } + }, fn(module, module.exports), module.exports; +} + +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); +} + +var core = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(); + } +}(commonjsGlobal, function () { + + /** + * CryptoJS core components. + */ + var CryptoJS = CryptoJS || (function (Math, undefined$1) { + /* + * Local polyfil of Object.create + */ + var create = Object.create || (function () { + function F() {} + return function (obj) { + var subtype; + + F.prototype = obj; + + subtype = new F(); + + F.prototype = null; + + return subtype; + }; + }()); + + /** + * CryptoJS namespace. + */ + var C = {}; + + /** + * Library namespace. + */ + var C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + var Base = C_lib.Base = (function () { + + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + var subtype = create(this); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + var instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (var propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty('toString')) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + } + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined$1) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + var thisWords = this.words; + var thatWords = wordArray.words; + var thisSigBytes = this.sigBytes; + var thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else { + // Copy one word at a time + for (var i = 0; i < thatSigBytes; i += 4) { + thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; + } + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + var words = this.words; + var sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + var words = []; + + var r = (function (m_w) { + var m_w = m_w; + var m_z = 0x3ade68b1; + var mask = 0xffffffff; + + return function () { + m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; + m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; + var result = ((m_z << 0x10) + m_w) & mask; + result /= 0x100000000; + result += 0.5; + return result * (Math.random() > .5 ? 1 : -1); + } + }); + + for (var i = 0, rcache; i < nBytes; i += 4) { + var _r = r((rcache || Math.random()) * 0x100000000); + + rcache = _r() * 0x3ade67b7; + words.push((_r() * 0x100000000) | 0); + } + + return new WordArray.init(words, nBytes); + } + }); + + /** + * Encoder namespace. + */ + var C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var hexChars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(''); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + var hexStrLength = hexStr.length; + + // Convert + var words = []; + for (var i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + } + }; + + /** + * Latin1 encoding strategy. + */ + var Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var latin1Chars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(''); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + var latin1StrLength = latin1Str.length; + + // Convert + var words = []; + for (var i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + } + }; + + /** + * UTF-8 encoding strategy. + */ + var Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error('Malformed UTF-8 data'); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + } + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == 'string') { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var dataSigBytes = data.sigBytes; + var blockSize = this.blockSize; + var blockSizeBytes = blockSize * 4; + + // Count blocks ready + var nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + var nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (var offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + var processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0 + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + var hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512/32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + } + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; + }(Math)); + + + return CryptoJS; + +})); +}); + +var md5 = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(core); + } +}(commonjsGlobal, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var T = []; + + // Compute constants + (function () { + for (var i = 0; i < 64; i++) { + T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; + } + }()); + + /** + * MD5 hash algorithm. + */ + var MD5 = C_algo.MD5 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Shortcuts + var H = this._hash.words; + + var M_offset_0 = M[offset + 0]; + var M_offset_1 = M[offset + 1]; + var M_offset_2 = M[offset + 2]; + var M_offset_3 = M[offset + 3]; + var M_offset_4 = M[offset + 4]; + var M_offset_5 = M[offset + 5]; + var M_offset_6 = M[offset + 6]; + var M_offset_7 = M[offset + 7]; + var M_offset_8 = M[offset + 8]; + var M_offset_9 = M[offset + 9]; + var M_offset_10 = M[offset + 10]; + var M_offset_11 = M[offset + 11]; + var M_offset_12 = M[offset + 12]; + var M_offset_13 = M[offset + 13]; + var M_offset_14 = M[offset + 14]; + var M_offset_15 = M[offset + 15]; + + // Working varialbes + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + + // Computation + a = FF(a, b, c, d, M_offset_0, 7, T[0]); + d = FF(d, a, b, c, M_offset_1, 12, T[1]); + c = FF(c, d, a, b, M_offset_2, 17, T[2]); + b = FF(b, c, d, a, M_offset_3, 22, T[3]); + a = FF(a, b, c, d, M_offset_4, 7, T[4]); + d = FF(d, a, b, c, M_offset_5, 12, T[5]); + c = FF(c, d, a, b, M_offset_6, 17, T[6]); + b = FF(b, c, d, a, M_offset_7, 22, T[7]); + a = FF(a, b, c, d, M_offset_8, 7, T[8]); + d = FF(d, a, b, c, M_offset_9, 12, T[9]); + c = FF(c, d, a, b, M_offset_10, 17, T[10]); + b = FF(b, c, d, a, M_offset_11, 22, T[11]); + a = FF(a, b, c, d, M_offset_12, 7, T[12]); + d = FF(d, a, b, c, M_offset_13, 12, T[13]); + c = FF(c, d, a, b, M_offset_14, 17, T[14]); + b = FF(b, c, d, a, M_offset_15, 22, T[15]); + + a = GG(a, b, c, d, M_offset_1, 5, T[16]); + d = GG(d, a, b, c, M_offset_6, 9, T[17]); + c = GG(c, d, a, b, M_offset_11, 14, T[18]); + b = GG(b, c, d, a, M_offset_0, 20, T[19]); + a = GG(a, b, c, d, M_offset_5, 5, T[20]); + d = GG(d, a, b, c, M_offset_10, 9, T[21]); + c = GG(c, d, a, b, M_offset_15, 14, T[22]); + b = GG(b, c, d, a, M_offset_4, 20, T[23]); + a = GG(a, b, c, d, M_offset_9, 5, T[24]); + d = GG(d, a, b, c, M_offset_14, 9, T[25]); + c = GG(c, d, a, b, M_offset_3, 14, T[26]); + b = GG(b, c, d, a, M_offset_8, 20, T[27]); + a = GG(a, b, c, d, M_offset_13, 5, T[28]); + d = GG(d, a, b, c, M_offset_2, 9, T[29]); + c = GG(c, d, a, b, M_offset_7, 14, T[30]); + b = GG(b, c, d, a, M_offset_12, 20, T[31]); + + a = HH(a, b, c, d, M_offset_5, 4, T[32]); + d = HH(d, a, b, c, M_offset_8, 11, T[33]); + c = HH(c, d, a, b, M_offset_11, 16, T[34]); + b = HH(b, c, d, a, M_offset_14, 23, T[35]); + a = HH(a, b, c, d, M_offset_1, 4, T[36]); + d = HH(d, a, b, c, M_offset_4, 11, T[37]); + c = HH(c, d, a, b, M_offset_7, 16, T[38]); + b = HH(b, c, d, a, M_offset_10, 23, T[39]); + a = HH(a, b, c, d, M_offset_13, 4, T[40]); + d = HH(d, a, b, c, M_offset_0, 11, T[41]); + c = HH(c, d, a, b, M_offset_3, 16, T[42]); + b = HH(b, c, d, a, M_offset_6, 23, T[43]); + a = HH(a, b, c, d, M_offset_9, 4, T[44]); + d = HH(d, a, b, c, M_offset_12, 11, T[45]); + c = HH(c, d, a, b, M_offset_15, 16, T[46]); + b = HH(b, c, d, a, M_offset_2, 23, T[47]); + + a = II(a, b, c, d, M_offset_0, 6, T[48]); + d = II(d, a, b, c, M_offset_7, 10, T[49]); + c = II(c, d, a, b, M_offset_14, 15, T[50]); + b = II(b, c, d, a, M_offset_5, 21, T[51]); + a = II(a, b, c, d, M_offset_12, 6, T[52]); + d = II(d, a, b, c, M_offset_3, 10, T[53]); + c = II(c, d, a, b, M_offset_10, 15, T[54]); + b = II(b, c, d, a, M_offset_1, 21, T[55]); + a = II(a, b, c, d, M_offset_8, 6, T[56]); + d = II(d, a, b, c, M_offset_15, 10, T[57]); + c = II(c, d, a, b, M_offset_6, 15, T[58]); + b = II(b, c, d, a, M_offset_13, 21, T[59]); + a = II(a, b, c, d, M_offset_4, 6, T[60]); + d = II(d, a, b, c, M_offset_11, 10, T[61]); + c = II(c, d, a, b, M_offset_2, 15, T[62]); + b = II(b, c, d, a, M_offset_9, 21, T[63]); + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + + var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); + var nBitsTotalL = nBitsTotal; + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( + (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | + (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) + ); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | + (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) + ); + + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 4; i++) { + // Shortcut + var H_i = H[i]; + + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + function FF(a, b, c, d, x, s, t) { + var n = a + ((b & c) | (~b & d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function GG(a, b, c, d, x, s, t) { + var n = a + ((b & d) | (c & ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function HH(a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function II(a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.MD5('message'); + * var hash = CryptoJS.MD5(wordArray); + */ + C.MD5 = Hasher._createHelper(MD5); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacMD5(message, key); + */ + C.HmacMD5 = Hasher._createHmacHelper(MD5); + }(Math)); + + + return CryptoJS.MD5; + +})); +}); + +var hmac = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(core); + } +}(commonjsGlobal, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var C_algo = C.algo; + + /** + * HMAC algorithm. + */ + var HMAC = C_algo.HMAC = Base.extend({ + /** + * Initializes a newly created HMAC. + * + * @param {Hasher} hasher The hash algorithm to use. + * @param {WordArray|string} key The secret key. + * + * @example + * + * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); + */ + init: function (hasher, key) { + // Init hasher + hasher = this._hasher = new hasher.init(); + + // Convert string to WordArray, else assume WordArray already + if (typeof key == 'string') { + key = Utf8.parse(key); + } + + // Shortcuts + var hasherBlockSize = hasher.blockSize; + var hasherBlockSizeBytes = hasherBlockSize * 4; + + // Allow arbitrary length keys + if (key.sigBytes > hasherBlockSizeBytes) { + key = hasher.finalize(key); + } + + // Clamp excess bits + key.clamp(); + + // Clone key for inner and outer pads + var oKey = this._oKey = key.clone(); + var iKey = this._iKey = key.clone(); + + // Shortcuts + var oKeyWords = oKey.words; + var iKeyWords = iKey.words; + + // XOR keys with pad constants + for (var i = 0; i < hasherBlockSize; i++) { + oKeyWords[i] ^= 0x5c5c5c5c; + iKeyWords[i] ^= 0x36363636; + } + oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; + + // Set initial values + this.reset(); + }, + + /** + * Resets this HMAC to its initial state. + * + * @example + * + * hmacHasher.reset(); + */ + reset: function () { + // Shortcut + var hasher = this._hasher; + + // Reset + hasher.reset(); + hasher.update(this._iKey); + }, + + /** + * Updates this HMAC with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {HMAC} This HMAC instance. + * + * @example + * + * hmacHasher.update('message'); + * hmacHasher.update(wordArray); + */ + update: function (messageUpdate) { + this._hasher.update(messageUpdate); + + // Chainable + return this; + }, + + /** + * Finalizes the HMAC computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The HMAC. + * + * @example + * + * var hmac = hmacHasher.finalize(); + * var hmac = hmacHasher.finalize('message'); + * var hmac = hmacHasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Shortcut + var hasher = this._hasher; + + // Compute HMAC + var innerHash = hasher.finalize(messageUpdate); + hasher.reset(); + var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); + + return hmac; + } + }); + }()); + + +})); +}); + +var hmacMd5 = createCommonjsModule(function (module, exports) { +(function (root, factory, undef) { + { + // CommonJS + module.exports = exports = factory(core, md5, hmac); + } +}(commonjsGlobal, function (CryptoJS) { + + return CryptoJS.HmacMD5; + +})); +}); + +function callbackify (method) { + return function (options) { + options = options || {}; + if (options.success || options.fail || options.complete) { + method + .call(this, options) + .then((res) => { + options.success && options.success(res); + options.complete && options.complete(res); + }, (err) => { + options.fail && options.fail(err); + options.complete && options.complete(err); + }); + return + } + return method.call(this, options) + } +} + +class UniCloudError extends Error { + constructor (options) { + super(options.message); + this.errMsg = options.message || ''; + Object.defineProperties(this, { + code: { + get () { + return options.code + } + }, + requestId: { + get () { + return options.requestId + } + }, + message: { + get () { + return this.errMsg + }, + set (msg) { + this.errMsg = msg; + } + } + }); + } +} + +var version = "1.0.1"; + +var zhHans = { + // uni-app + 'uniCloud.init.paramRequired': '缺少参数:{param}', + // h5 + 'uniCloud.uploadFile.fileError': 'filePath应为File对象' +}; + +var zhHant = { + // uni-app + 'uniCloud.init.paramRequired': '缺少参数:{param}', + // h5 + 'uniCloud.uploadFile.fileError': 'filePath应为File对象' +}; + +var en = { + // uni-app + 'uniCloud.init.paramRequired': '{param} required', + // h5 + 'uniCloud.uploadFile.fileError': 'filePath should be instance of File' +}; + +var fr = { + // uni-app + 'uniCloud.init.paramRequired': '{param} required', + // h5 + 'uniCloud.uploadFile.fileError': 'filePath should be instance of File' +}; + +var es = { + // uni-app + 'uniCloud.init.paramRequired': '{param} required', + // h5 + 'uniCloud.uploadFile.fileError': 'filePath should be instance of File' +}; + +const { + t, + setLocale, + getLocale +} = uniI18n.initVueI18n({ + 'zh-Hans': zhHans, + 'zh-Hant': zhHant, + en, + fr, + es +}, 'zh-Hans'); + +const UUID_KEY = '__DC_CLOUD_UUID'; +const LAST_DCLOUD_APPID_KEY = '__LAST_DCLOUD_APPID'; +const UNI_ID_TOKEN_KEY = 'uni_id_token'; +const UNI_ID_TOKEN_EXPIRED_KEY = 'uni_id_token_expired'; +const UNI_ID_TOKEN_KEY_DEP = 'uniIdToken'; + +let statConfig; +try { + statConfig = require('uni-stat-config').default || require('uni-stat-config'); +} catch (e) { + statConfig = { + appid: '' + }; +} + +let uuid, clientOS; + +function getRandomUuid (length = 8) { + let str = ''; + while (str.length < length) { + str += Math.random().toString(32).substring(2); + } + return str.substring(0, length) +} + +// process.env.VUE_APP_PLATFORM +// 'app-plus' +// h5: +// 'mp-weixin' +// 'mp-alipay' +// 'mp-baidu' +// 'mp-toutiao' +// 'mp-qq' +// 'quickapp-native' + +function initStat () { + return new Promise(resolve => { + if (process.env.VUE_APP_PLATFORM === 'quickapp-native') { + clientOS = 'android'; + uni.getStorage({ + key: UUID_KEY, + success (res) { + if (res.data) { + uuid = res.data; + } else { + uuid = getRandomUuid(32); + } + resolve(); + } + }); + } else { + setTimeout(() => { + clientOS = uni.getSystemInfoSync().platform; + uuid = uni.getStorageSync(UUID_KEY) || getRandomUuid(32); + resolve(); + }, 0); + } + }) +} + +function getClientInfo () { + const { + deviceId + } = uni.getSystemInfoSync(); + return { + PLATFORM: process.env.VUE_APP_PLATFORM, + OS: clientOS, + APPID: statConfig.appid, + LOCALE: getLocale(), + DEVICEID: deviceId, + // ID: uuid || (uuid = getRandomUuid(32)), + CLIENT_SDK_VERSION: version + } +} + +function getUuid () { + if (getPlatformName() === 'n') { + try { + uuid = plus.runtime.getDCloudId(); + } catch (e) { + uuid = ''; + } + return uuid + } + + if (!uuid) { + uuid = getRandomUuid(32); + uni.setStorage({ + key: UUID_KEY, + data: uuid + }); + } + return uuid +} + +function getPlatformName () { + const aliArr = ['y', 'a', 'p', 'mp-ali']; + const platformList = { + 'app-plus': 'n', + h5: 'h5', + 'mp-weixin': 'wx', + [aliArr.reverse().join('')]: 'ali', + 'mp-baidu': 'bd', + 'mp-toutiao': 'tt', + 'mp-qq': 'qq', + 'quickapp-native': 'qn' + }; + return platformList[process.env.VUE_APP_PLATFORM] +} + +function clearDirtyUniIdToken () { + // 仅在uni-app h5端运行到浏览器执行此逻辑 + if (process.env.VUE_APP_PLATFORM !== 'h5' || process.env.NODE_ENV !== 'development') { + return + } + const lastDcloudAppId = uni.getStorageSync(LAST_DCLOUD_APPID_KEY); + if (lastDcloudAppId === statConfig.appid) { + return + } + uni.setStorageSync(LAST_DCLOUD_APPID_KEY, statConfig.appid); + const uniIdToken = uni.removeStorageSync(UNI_ID_TOKEN_KEY); + if (!uniIdToken) { + return + } + console.warn('检测到当前项目与上次运行到此端口的项目不一致,自动清理uni-id保存的token信息(仅开发调试时生效)'); + uni.removeStorageSync(UNI_ID_TOKEN_KEY); + uni.removeStorageSync(UNI_ID_TOKEN_EXPIRED_KEY); +} + +function getUniCloudClientInfo () { + return { + ak: statConfig.appid, + p: clientOS === 'android' ? 'a' : 'i', + ut: getPlatformName(), // 平台 + uuid: getUuid() + } +} + +function sign (data, clientSecret) { + let signString = ''; + Object.keys(data).sort().forEach(function (key) { + if (data[key]) { + signString = signString + '&' + key + '=' + data[key]; + } + }); + signString = signString.slice(1); + return hmacMd5(signString, clientSecret).toString() +} + +function wrappedRequest (args, request) { + return new Promise((resolve, reject) => { + request(Object.assign(args, { + complete (res) { + if (!res) { + res = {}; + } + if (process.env.VUE_APP_PLATFORM === 'h5' && process.env.NODE_ENV === + 'development' && res.errMsg && res.errMsg.indexOf('request:fail') === 0) { + console.warn('发布H5,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.io/uniCloud/quickstart?id=useinh5'); + } + const requestId = (res.data && res.data.header && res.data.header['x-serverless-request-id']) || (res.header && res.header['request-id']); + if (!res.statusCode || res.statusCode >= 400) { + return reject(new UniCloudError({ + code: 'SYS_ERR', + message: res.errMsg || 'request:fail', + requestId + })) + } + const response = res.data; + if (response.error) { + return reject(new UniCloudError({ + code: response.error.code, + message: response.error.message, + requestId + })) + } + // 拉齐云开发返回值 + response.result = response.data; + response.requestId = requestId; + delete response.data; + resolve(response); + } + })); + }) +} + +var codec = { + sign, + wrappedRequest +}; + +// 适配器需实现的功能 +const defaultAdapter = { + request (options) { + // { + // url, + // method, + // data, + // dataType, + // header, + // success, + // fail, + // complete + // } + return uni.request(options) + }, + uploadFile (options) { + // { + // url, + // formData, + // name, + // filePath, + // fileType, + // header, + // success, + // fail + // } + return uni.uploadFile(options) + }, + // quickapp-native 不支持同步接口setStorageSync和getStorageSync + setStorageSync (key, data) { + return uni.setStorageSync(key, data) + }, + getStorageSync (key) { + return uni.getStorageSync(key) + }, + removeStorageSync (key) { + return uni.removeStorageSync(key) + }, + clearStorageSync () { + return uni.clearStorageSync() + } +}; + +class Client { + constructor (args) { + const argsRequired = ['spaceId', 'clientSecret']; + argsRequired.forEach((item) => { + if (!Object.prototype.hasOwnProperty.call(args, item)) { + throw new Error(t('uniCloud.init.paramRequired', { param: item })) + } + }); + this.config = Object.assign({}, { + endpoint: 'https://api.bspapp.com' + }, args); + this.config.provider = 'aliyun'; + this.config.requestUrl = this.config.endpoint + '/client'; + this.config.envType = this.config.envType || 'public'; + this.config.accessTokenKey = 'access_token_' + this.config.spaceId; + this.adapter = defaultAdapter; + } + + get hasAccessToken () { + return !!this.accessToken + } + + setAccessToken (accessToken) { + // 阿里云token有效期只有十分钟,没必要持久化存储 + // uni.setStorage(this.config.accessTokenKey, accessToken) + this.accessToken = accessToken; + } + + requestWrapped (options) { + return codec.wrappedRequest(options, this.adapter.request) + } + + requestAuth (options) { + return this.requestWrapped(options) + } + + request (options, retried) { + // 阻塞callFunction等的执行 + return Promise.resolve().then(() => { + if (!this.hasAccessToken) { + return this.getAccessToken().then(() => { + const optionsCloned = this.rebuildRequest(options); + return this.request(optionsCloned, true) + }) + } + if (retried) { + return this.requestWrapped(options) + } else { + return this.requestWrapped(options).catch((err) => { + return new Promise((resolve, reject) => { + if (err && (err.code === 'GATEWAY_INVALID_TOKEN' || err.code === 'InvalidParameter.InvalidToken')) { + resolve(); + } else { + reject(err); + } + }).then(() => { + return this.getAccessToken() + }).then(() => { + const optionsCloned = this.rebuildRequest(options); + return this.request(optionsCloned, true) + }) + }) + } + }) + } + + rebuildRequest (options) { + const optionsCloned = Object.assign({}, options); + optionsCloned.data.token = this.accessToken; + optionsCloned.header['x-basement-token'] = this.accessToken; + optionsCloned.header['x-serverless-sign'] = codec.sign(optionsCloned.data, this.config.clientSecret); + return optionsCloned + } + + setupRequest (body, type) { + const data = Object.assign({}, body, { + spaceId: this.config.spaceId, + timestamp: Date.now() + }); + const header = { + 'Content-Type': 'application/json' + }; + + if (type !== 'auth') { + data.token = this.accessToken; + header['x-basement-token'] = this.accessToken; + } + + header['x-serverless-sign'] = codec.sign(data, this.config.clientSecret); + + return { + url: this.config.requestUrl, + method: 'POST', + data, + dataType: 'json', + header + } + } + + getAccessToken () { + const body = { + method: 'serverless.auth.user.anonymousAuthorize', + params: '{}' + }; + return this.requestAuth(this.setupRequest(body, 'auth')).then((res) => { + return new Promise((resolve, reject) => { + if (res.result && res.result.accessToken) { + this.setAccessToken(res.result.accessToken); + resolve(this.accessToken); + } else { + reject(new UniCloudError({ + code: 'AUTH_FAILED', + message: '获取accessToken失败' + })); + } + }) + }) + } + + authorize () { + this.getAccessToken(); + } + + callFunction (options) { + const body = { + method: 'serverless.function.runtime.invoke', + params: JSON.stringify({ + functionTarget: options.name, + functionArgs: options.data || {} + }) + }; + return this.request(this.setupRequest(body)) + } + + getOSSUploadOptionsFromPath (options) { + const body = { + method: 'serverless.file.resource.generateProximalSign', + params: JSON.stringify(options) + }; + return this.request(this.setupRequest(body)) + } + + uploadFileToOSS ({ + url, + formData, + name, + filePath, + fileType, + onUploadProgress + }) { + return new Promise((resolve, reject) => { + const uploadTask = this.adapter.uploadFile({ + url, + formData, + name, + filePath, + fileType, + header: { + 'X-OSS-server-side-encrpytion': 'AES256' + }, + success (res) { + if (res && res.statusCode < 400) { + resolve(res); + } else { + reject(new UniCloudError({ + code: 'UPLOAD_FAILED', + message: '文件上传失败' + })); + } + }, + fail (err) { + reject(new UniCloudError({ + code: err.code || 'UPLOAD_FAILED', + message: err.message || err.errMsg || '文件上传失败' + })); + } + }); + if (typeof onUploadProgress === 'function' && uploadTask && typeof uploadTask.onProgressUpdate === 'function') { + uploadTask.onProgressUpdate((res) => { + onUploadProgress({ + loaded: res.totalBytesSent, + total: res.totalBytesExpectedToSend + }); + }); + } + }) + } + + reportOSSUpload (params) { + const body = { + method: 'serverless.file.resource.report', + params: JSON.stringify(params) + }; + return this.request(this.setupRequest(body)) + } + + uploadFile ({ + filePath, + cloudPath, + fileType = 'image', + onUploadProgress, + config + }) { + if (!cloudPath) { + throw new UniCloudError({ + code: 'CLOUDPATH_REQUIRED', + message: 'cloudPath不可为空' + }) + } + const env = (config && config.envType) || this.config.envType; + let uploadId, fileUrl; + return this.getOSSUploadOptionsFromPath({ + env, + filename: cloudPath + }).then((res) => { + const uploadOptionsResult = res.result; + uploadId = uploadOptionsResult.id; + fileUrl = 'https://' + uploadOptionsResult.cdnDomain + '/' + uploadOptionsResult.ossPath; + const uploadFileToOSSOptions = { + url: 'https://' + uploadOptionsResult.host, + formData: { + 'Cache-Control': 'max-age=2592000', + 'Content-Disposition': 'attachment', + OSSAccessKeyId: uploadOptionsResult.accessKeyId, + Signature: uploadOptionsResult.signature, + host: uploadOptionsResult.host, + id: uploadId, + key: uploadOptionsResult.ossPath, + policy: uploadOptionsResult.policy, + success_action_status: 200 + }, + fileName: 'file', + name: 'file', + filePath: filePath, + fileType + }; + return this.uploadFileToOSS(Object.assign({}, uploadFileToOSSOptions, { + onUploadProgress + })) + }).then(() => { + return this.reportOSSUpload({ + id: uploadId + }) + }).then((res) => { + return new Promise((resolve, reject) => { + if (res.success) { + resolve({ + success: true, + filePath, + fileID: fileUrl + }); + } else { + reject(new UniCloudError({ + code: 'UPLOAD_FAILED', + message: '文件上传失败' + })); + } + }) + }) + } + + deleteFile ({ + fileList + }) { + const body = { + method: 'serverless.file.resource.delete', + params: JSON.stringify({ + id: fileList[0] + }) + }; + return this.request(this.setupRequest(body)) + } + + getTempFileURL ({ + fileList + } = {}) { + return new Promise((resolve, reject) => { + if (!Array.isArray(fileList) || fileList.length === 0) { + reject(new UniCloudError({ + code: 'INVALID_PARAM', + message: 'fileList的元素必须是非空的字符串' + })); + } + resolve({ + fileList: fileList.map(item => { + return { + fileID: item, + tempFileURL: item + } + }) + }); + }) + } +} + +const uniCloud = { + init (config) { + const uniClient = new Client(config); + // callFunction、uploadFile 在 core 内 callbackify + const callbackifyListClient = ['deleteFile', 'getTempFileURL']; + callbackifyListClient.forEach((item) => { + uniClient[item] = callbackify(uniClient[item]).bind(uniClient); + }); + + const authObj = { + signInAnonymously: function () { + return uniClient.authorize() + }, + // 阿里云暂时这么实现 + getLoginState: function () { + return Promise.resolve(false) + } + }; + + uniClient.auth = function () { + return authObj + }; + uniClient.customAuth = uniClient.auth; + + return uniClient + } +}; + +// import * as packageInfo from './package.json'; +const SDK_VERISON = '1.3.5'; +const ACCESS_TOKEN = 'access_token'; +const ACCESS_TOKEN_Expire = 'access_token_expire'; +const REFRESH_TOKEN = 'refresh_token'; +const ANONYMOUS_UUID = 'anonymous_uuid'; +const LOGIN_TYPE_KEY = 'login_type'; +const USER_INFO_KEY = 'user_info'; +const protocol = typeof location !== 'undefined' && location.protocol === 'http:' ? 'http:' : 'https:'; +// debug +// export const protocol = 'http:' +// export const BASE_URL = '//118.126.68.63/web'; +const BASE_URL = typeof process !== 'undefined' && process.env.NODE_ENV === 'e2e' && process.env.END_POINT === 'pre' + ? '//tcb-pre.tencentcloudapi.com/web' + : '//tcb-api.tencentcloudapi.com/web'; +// debug +// export const BASE_URL = '//localhost:8002/web'; +// export const BASE_URL = '//9.88.239.245/web'; +// export const BASE_URL = '//tcb-api.tencentcloudapi.com:8002/web'; +// export const BASE_URL = '//212.129.229.68/web'; +// export const dataVersion = '2020-01-10'; + +var StorageType; +(function (StorageType) { + StorageType["local"] = "local"; + StorageType["none"] = "none"; + StorageType["session"] = "session"; +})(StorageType || (StorageType = {})); +var AbstractStorage = (function () { + function AbstractStorage() { + } + return AbstractStorage; +}()); + +var sha256 = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(core); + } +}(commonjsGlobal, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Initialization and round constants tables + var H = []; + var K = []; + + // Compute constants + (function () { + function isPrime(n) { + var sqrtN = Math.sqrt(n); + for (var factor = 2; factor <= sqrtN; factor++) { + if (!(n % factor)) { + return false; + } + } + + return true; + } + + function getFractionalBits(n) { + return ((n - (n | 0)) * 0x100000000) | 0; + } + + var n = 2; + var nPrime = 0; + while (nPrime < 64) { + if (isPrime(n)) { + if (nPrime < 8) { + H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); + } + K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); + + nPrime++; + } + + n++; + } + }()); + + // Reusable object + var W = []; + + /** + * SHA-256 hash algorithm. + */ + var SHA256 = C_algo.SHA256 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init(H.slice(0)); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + var f = H[5]; + var g = H[6]; + var h = H[7]; + + // Computation + for (var i = 0; i < 64; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var gamma0x = W[i - 15]; + var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ + ((gamma0x << 14) | (gamma0x >>> 18)) ^ + (gamma0x >>> 3); + + var gamma1x = W[i - 2]; + var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ + ((gamma1x << 13) | (gamma1x >>> 19)) ^ + (gamma1x >>> 10); + + W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; + } + + var ch = (e & f) ^ (~e & g); + var maj = (a & b) ^ (a & c) ^ (b & c); + + var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); + var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); + + var t1 = h + sigma1 + ch + K[i] + W[i]; + var t2 = sigma0 + maj; + + h = g; + g = f; + f = e; + e = (d + t1) | 0; + d = c; + c = b; + b = a; + a = (t1 + t2) | 0; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + H[5] = (H[5] + f) | 0; + H[6] = (H[6] + g) | 0; + H[7] = (H[7] + h) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA256('message'); + * var hash = CryptoJS.SHA256(wordArray); + */ + C.SHA256 = Hasher._createHelper(SHA256); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA256(message, key); + */ + C.HmacSHA256 = Hasher._createHmacHelper(SHA256); + }(Math)); + + + return CryptoJS.SHA256; + +})); +}); + +var hmacSha256 = createCommonjsModule(function (module, exports) { +(function (root, factory, undef) { + { + // CommonJS + module.exports = exports = factory(core, sha256, hmac); + } +}(commonjsGlobal, function (CryptoJS) { + + return CryptoJS.HmacSHA256; + +})); +}); + +var encBase64 = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(core); + } +}(commonjsGlobal, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64 encoding strategy. + */ + var Base64 = C_enc.Base64 = { + /** + * Converts a word array to a Base64 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Base64 string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64 string to a word array. + * + * @param {string} base64Str The Base64 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64.parse(base64String); + */ + parse: function (base64Str) { + // Shortcuts + var base64StrLength = base64Str.length; + var map = this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + return CryptoJS.enc.Base64; + +})); +}); + +var encUtf8 = createCommonjsModule(function (module, exports) { +(function (root, factory) { + { + // CommonJS + module.exports = exports = factory(core); + } +}(commonjsGlobal, function (CryptoJS) { + + return CryptoJS.enc.Utf8; + +})); +}); + +const createPromiseCallback = () => { + let cb; + if (!Promise) { + cb = () => { }; + cb.promise = {}; + const throwPromiseNotDefined = () => { + throw new Error('Your Node runtime does support ES6 Promises. ' + + 'Set "global.Promise" to your preferred implementation of promises.'); + }; + Object.defineProperty(cb.promise, 'then', { get: throwPromiseNotDefined }); + Object.defineProperty(cb.promise, 'catch', { get: throwPromiseNotDefined }); + return cb; + } + const promise = new Promise((resolve, reject) => { + cb = (err, data) => { + if (err) + return reject(err); + return resolve(data); + }; + }); + cb.promise = promise; + return cb; +}; +function isArray(val) { + return Object.prototype.toString.call(val) === '[object Array]'; +} +function isString(val) { + return typeof val === 'string'; +} +function isUndefined(val) { + return typeof val === 'undefined'; +} +function isNull(val) { + return Object.prototype.toString.call(val) === '[object Null]'; +} +function isInstanceOf(instance, construct) { + return instance instanceof construct; +} +function isFormData(val) { + return Object.prototype.toString.call(val) === '[object FormData]'; +} +function genSeqId() { + return Math.random().toString(16).slice(2); +} +function formatUrl(protocol, url, query = {}) { + const urlHasQuery = /\?/.test(url); + let queryString = ''; + for (let key in query) { + if (queryString === '') { + !urlHasQuery && (url += '?'); + } + else { + queryString += '&'; + } + queryString += `${key}=${encodeURIComponent(query[key])}`; + } + url += queryString; + if (/^http(s)?\:\/\//.test(url)) { + return url; + } + return `${protocol}${url}`; +} + +// import * as Web from './platforms/web'; +var RUNTIME; +(function (RUNTIME) { + RUNTIME["WEB"] = "web"; + RUNTIME["WX_MP"] = "wx_mp"; // 微信小程序 +})(RUNTIME || (RUNTIME = {})); +function useAdapters(adapters) { + const adapterList = isArray(adapters) ? adapters : [adapters]; + for (const adapter of adapterList) { + const { isMatch, genAdapter, runtime } = adapter; + if (isMatch()) { + return { + adapter: genAdapter(), + runtime + }; + } + } +} +// export function useDefaultAdapter() { +// return { +// adapter: Web.genAdapter(), +// runtime: RUNTIME.WEB +// }; +// } +const Adapter = { + adapter: null, + runtime: undefined +}; + +/** + * @constant 始终存储在localstorage中的key集合 + */ +const alwaysLocalKeys = ['anonymousUuidKey']; +class TcbObject extends AbstractStorage { + constructor() { + super(); + if (!Adapter.adapter.root['tcbObject']) { + Adapter.adapter.root['tcbObject'] = {}; + } + } + // 保存数据到 + setItem(key, value) { + Adapter.adapter.root['tcbObject'][key] = value; + } + // 获取数据 + getItem(key) { + return Adapter.adapter.root['tcbObject'][key]; + } + // 删除保存的数据 + removeItem(key) { + delete Adapter.adapter.root['tcbObject'][key]; + } + // 删除所有保存的数据 + clear() { + delete Adapter.adapter.root['tcbObject']; + } +} +function createStorage(persistence, adapter) { + switch (persistence) { + case 'local': + return adapter.localStorage || new TcbObject(); + case 'none': + return new TcbObject(); + default: + return adapter.sessionStorage || new TcbObject(); + } +} +class ICache { + constructor(config) { + if (!this._storage) { + this._persistence = Adapter.adapter.primaryStorage || config.persistence; + this._storage = createStorage(this._persistence, Adapter.adapter); + const accessTokenKey = `${ACCESS_TOKEN}_${config.env}`; + const accessTokenExpireKey = `${ACCESS_TOKEN_Expire}_${config.env}`; + const refreshTokenKey = `${REFRESH_TOKEN}_${config.env}`; + const anonymousUuidKey = `${ANONYMOUS_UUID}_${config.env}`; + const loginTypeKey = `${LOGIN_TYPE_KEY}_${config.env}`; + const userInfoKey = `${USER_INFO_KEY}_${config.env}`; + this.keys = { + accessTokenKey, + accessTokenExpireKey, + refreshTokenKey, + anonymousUuidKey, + loginTypeKey, + userInfoKey + }; + } + } + updatePersistence(persistence) { + if (persistence === this._persistence) { + return; + } + const isCurrentLocal = this._persistence === 'local'; + this._persistence = persistence; + const storage = createStorage(persistence, Adapter.adapter); + // 切换persistence重新创建storage对象 + for (const key in this.keys) { + const name = this.keys[key]; + // 如果当前为local并且key被设定为始终存储在localstorage中,则不迁移 + if (isCurrentLocal && alwaysLocalKeys.includes(key)) { + continue; + } + const val = this._storage.getItem(name); + if (!isUndefined(val) && !isNull(val)) { + storage.setItem(name, val); + this._storage.removeItem(name); + } + } + this._storage = storage; + } + setStore(key, value, version) { + if (!this._storage) { + return; + } + const d = { + version: version || 'localCachev1', + content: value + }; + const content = JSON.stringify(d); + try { + this._storage.setItem(key, content); + } + catch (e) { + throw e; + } + return; + } + /* + *获取缓存 + */ + getStore(key, version) { + // forceLocal强制取localstory + try { + //测试用例使用 + // if (typeof process !== 'undefined' && process.env && process.env.tcb_token) { + // return process.env.tcb_token; + // } + if (!this._storage) { + return; + } + } + catch (e) { + return ''; + } + version = version || 'localCachev1'; + const content = this._storage.getItem(key); + if (!content) { + return ''; + } + if (content.indexOf(version) >= 0) { + const d = JSON.parse(content); + return d.content; + } + else { + return ''; + } + } + /* + *删除缓存 + */ + removeStore(key) { + this._storage.removeItem(key); + } +} +const cacheMap = {}; +// 本地存储 +const localCacheMap = {}; +function initCache(config) { + const { env } = config; + cacheMap[env] = new ICache(config); + localCacheMap[env] = new ICache({ + ...config, + persistence: 'local' + }); +} +function getCache(env) { + return cacheMap[env]; +} +function getLocalCache(env) { + return localCacheMap[env]; +} + +/** + * @private + * @function _addEventListener - 添加监听 + * @param {string} name - event名称 + * @param {Function} listener - 响应函数 + * @param {Listeners} listeners - 已存响应函数集合 + */ +function _addEventListener(name, listener, listeners) { + listeners[name] = listeners[name] || []; + listeners[name].push(listener); +} +/** + * @private + * @function _removeEventListener - 移除监听 + * @param {string} name - event名称 + * @param {Function} listener - 响应函数 + * @param {Listeners} listeners - 已存响应函数集合 + */ +function _removeEventListener(name, listener, listeners) { + if (listeners && listeners[name]) { + const index = listeners[name].indexOf(listener); + if (index !== -1) { + listeners[name].splice(index, 1); + } + } +} +/** + * 自定义事件 + * @class IEvent + * @param {string} name - 类型 + * @param {any} data - 数据 + */ +class IEvent { + constructor(name, data) { + this.data = data || null; + this.name = name; + } +} +/** + * 自定义错误事件 + * @class IErrorEvent + * @extends IEvent + * @param {Error} error - 错误信息对象 + * @param {any} data - 数据 + */ +class IErrorEvent extends IEvent { + constructor(error, data) { + super('error', { error, data }); + this.error = error; + } +} +/** + * @class IEventEmitter + */ +class IEventEmitter { + constructor() { + /** + * @private + * @readonly + * @property {Listeners} _listeners - 响应函数集合 + * @default `{}` + */ + this._listeners = {}; + } + /** + * @public + * @method on - 添加监听 + * @param {string} name - event名称 + * @param {Function} listener - 响应函数 + * @return `this` + */ + on(name, listener) { + _addEventListener(name, listener, this._listeners); + return this; + } + /** + * @public + * @method off - 移除监听 + * @param {string} name - event名称 + * @param {Function} listener - 响应函数 + * @return `this` + */ + off(name, listener) { + _removeEventListener(name, listener, this._listeners); + return this; + } + /** + * @public + * @method fire - 触发事件 + * @param {string|IEvent} event - event + * @return `this` + */ + fire(event, data) { + // 打印错误信息 + if (isInstanceOf(event, IErrorEvent)) { + console.error(event.error); + return this; + } + const ev = isString(event) ? new IEvent(event, data || {}) : event; + const name = ev.name; + if (this._listens(name)) { + ev.target = this; + const handlers = this._listeners[name] ? [...this._listeners[name]] : []; + for (const fn of handlers) { + fn.call(this, ev); + } + } + return this; + } + /** + * @private + * @method _listens - 判断是否监听了name事件 + * @param {string} name - event名称 + * @return `boolean` + */ + _listens(name) { + return this._listeners[name] && this._listeners[name].length > 0; + } +} +const iEventEmitter = new IEventEmitter(); +function addEventListener(event, callback) { + iEventEmitter.on(event, callback); +} +function activateEvent(event, data = {}) { + iEventEmitter.fire(event, data); +} +function removeEventListener(event, callback) { + iEventEmitter.off(event, callback); +} +const EVENTS = { + LOGIN_STATE_CHANGED: 'loginStateChanged', + LOGIN_STATE_EXPIRED: 'loginStateExpire', + LOGIN_TYPE_CHANGED: 'loginTypeChanged', + ANONYMOUS_CONVERTED: 'anonymousConverted', + ACCESS_TOKEN_REFRESHD: 'refreshAccessToken' +}; + +var LOGINTYPE; +(function (LOGINTYPE) { + LOGINTYPE["ANONYMOUS"] = "ANONYMOUS"; + LOGINTYPE["WECHAT"] = "WECHAT"; + LOGINTYPE["WECHAT_PUBLIC"] = "WECHAT-PUBLIC"; + LOGINTYPE["WECHAT_OPEN"] = "WECHAT-OPEN"; + LOGINTYPE["CUSTOM"] = "CUSTOM"; + LOGINTYPE["EMAIL"] = "EMAIL"; + LOGINTYPE["USERNAME"] = "USERNAME"; + LOGINTYPE["NULL"] = "NULL"; // 保留字,代表未登录 +})(LOGINTYPE || (LOGINTYPE = {})); + +const actionsWithoutAccessToken = [ + 'auth.getJwt', + 'auth.logout', + 'auth.signInWithTicket', + 'auth.signInAnonymously', + 'auth.signIn', + 'auth.fetchAccessTokenWithRefreshToken', + 'auth.signUpWithEmailAndPassword', + 'auth.activateEndUserMail', + 'auth.sendPasswordResetEmail', + 'auth.resetPasswordWithToken', + 'auth.isUsernameRegistered' +]; +const commonHeader = { + // 'X-SDK-Version': `tcb-js-sdk/${SDK_VERISON}` + 'X-SDK-Version': SDK_VERISON +}; +function bindHooks(instance, name, hooks) { + const originMethod = instance[name]; + instance[name] = function (options) { + const data = {}; + const headers = {}; + hooks.forEach(hook => { + const { data: appendedData, headers: appendedHeaders } = hook.call(instance, options); + Object.assign(data, appendedData); + Object.assign(headers, appendedHeaders); + }); + const originData = options.data; + originData && (() => { + if (isFormData(originData)) { + for (const key in data) { + originData.append(key, data[key]); + } + return; + } + options.data = { + ...originData, + ...data + }; + })(); + options.headers = { + ...(options.headers || {}), + ...headers + }; + return originMethod.call(instance, options); + }; +} +function beforeEach() { + const seqId = genSeqId(); + return { + data: { + seqId + }, + headers: { + ...commonHeader, + 'x-seqid': seqId + } + }; +} +/** + * @class IRequest + */ +class IRequest { + /** + * 初始化 + * @param config + */ + constructor(config = {}) { + this.config = config; + // eslint-disable-next-line + this._reqClass = new Adapter.adapter.reqClass({ + timeout: this.config.timeout, + timeoutMsg: `请求在${this.config.timeout / 1000}s内未完成,已中断`, + restrictedMethods: ['post'] + }); + this._cache = getCache(this.config.env); + this._localCache = getLocalCache(this.config.env); + bindHooks(this._reqClass, 'post', [beforeEach]); + bindHooks(this._reqClass, 'upload', [beforeEach]); + bindHooks(this._reqClass, 'download', [beforeEach]); + } + async post(options) { + const res = await this._reqClass.post(options); + return res; + } + async upload(options) { + const res = await this._reqClass.upload(options); + return res; + } + async download(options) { + const res = await this._reqClass.download(options); + return res; + } + async refreshAccessToken() { + // 可能会同时调用多次刷新access token,这里把它们合并成一个 + if (!this._refreshAccessTokenPromise) { + // 没有正在刷新,那么正常执行刷新逻辑 + this._refreshAccessTokenPromise = this._refreshAccessToken(); + } + let result; + let err; + try { + result = await this._refreshAccessTokenPromise; + } + catch (e) { + err = e; + } + this._refreshAccessTokenPromise = null; + this._shouldRefreshAccessTokenHook = null; + if (err) { + throw err; + } + return result; + } + // 调用接口刷新access token,并且返回 + async _refreshAccessToken() { + const { accessTokenKey, accessTokenExpireKey, refreshTokenKey, loginTypeKey, anonymousUuidKey } = this._cache.keys; + this._cache.removeStore(accessTokenKey); + this._cache.removeStore(accessTokenExpireKey); + let refreshToken = this._cache.getStore(refreshTokenKey); + if (!refreshToken) { + throw new Error('未登录CloudBase'); + } + const params = { + refresh_token: refreshToken, + }; + const response = await this.request('auth.fetchAccessTokenWithRefreshToken', params); + if (response.data.code) { + const { code } = response.data; + if (code === 'SIGN_PARAM_INVALID' || code === 'REFRESH_TOKEN_EXPIRED' || code === 'INVALID_REFRESH_TOKEN') { + // 这里处理以下逻辑: + // 匿名登录时,如果刷新access token报错refresh token过期,此时应该: + // 1. 再用 uuid 拿一次新的refresh token + // 2. 拿新的refresh token换access token + const isAnonymous = this._cache.getStore(loginTypeKey) === LOGINTYPE.ANONYMOUS; + if (isAnonymous && code === 'INVALID_REFRESH_TOKEN') { + // 获取新的 refresh token + const anonymous_uuid = this._cache.getStore(anonymousUuidKey); + // 此处cache为基类property + const refresh_token = this._cache.getStore(refreshTokenKey); + const res = await this.send('auth.signInAnonymously', { + anonymous_uuid, + refresh_token + }); + this.setRefreshToken(res.refresh_token); + return this._refreshAccessToken(); + } + activateEvent(EVENTS.LOGIN_STATE_EXPIRED); + this._cache.removeStore(refreshTokenKey); + } + throw new Error(`刷新access token失败:${response.data.code}`); + } + if (response.data.access_token) { + activateEvent(EVENTS.ACCESS_TOKEN_REFRESHD); + this._cache.setStore(accessTokenKey, response.data.access_token); + // 本地时间可能没有同步 + this._cache.setStore(accessTokenExpireKey, response.data.access_token_expire + Date.now()); + return { + accessToken: response.data.access_token, + accessTokenExpire: response.data.access_token_expire + }; + } + // 匿名登录refresh_token过期情况下返回refresh_token + // 此场景下使用新的refresh_token获取access_token + if (response.data.refresh_token) { + this._cache.removeStore(refreshTokenKey); + this._cache.setStore(refreshTokenKey, response.data.refresh_token); + this._refreshAccessToken(); + } + } + // 获取access token + async getAccessToken() { + const { accessTokenKey, accessTokenExpireKey, refreshTokenKey } = this._cache.keys; + const refreshToken = this._cache.getStore(refreshTokenKey); + if (!refreshToken) { + // 不该出现的状态:有 access token 却没有 refresh token + throw new Error('refresh token不存在,登录状态异常'); + } + // 如果没有access token或者过期,那么刷新 + let accessToken = this._cache.getStore(accessTokenKey); + let accessTokenExpire = this._cache.getStore(accessTokenExpireKey); + // 调用钩子函数 + let shouldRefreshAccessToken = true; + if (this._shouldRefreshAccessTokenHook && !(await this._shouldRefreshAccessTokenHook(accessToken, accessTokenExpire))) { + shouldRefreshAccessToken = false; + } + if ((!accessToken || !accessTokenExpire || accessTokenExpire < Date.now()) && shouldRefreshAccessToken) { + // 返回新的access tolen + return this.refreshAccessToken(); + } + else { + // 返回本地的access token + return { + accessToken, + accessTokenExpire + }; + } + } + /* eslint-disable complexity */ + async request(action, params, options) { + const tcbTraceKey = `x-tcb-trace_${this.config.env}`; + let contentType = 'application/x-www-form-urlencoded'; + // const webDeviceId = await getTcbFingerprintId(); + const tmpObj = { + action, + // webDeviceId, + env: this.config.env, + dataVersion: '2019-08-16', + ...params + }; + // 下面几种 action 不需要 access token + if (actionsWithoutAccessToken.indexOf(action) === -1) { + const { refreshTokenKey } = this._cache.keys; + // 若有 refreshToken 则任务有登录态 刷 accessToken + let refreshToken = this._cache.getStore(refreshTokenKey); + if (refreshToken) { + tmpObj.access_token = (await this.getAccessToken()).accessToken; + } + } + // 拼body和content-type + let payload; + if (action === 'storage.uploadFile') { + payload = new FormData(); + for (let key in payload) { + if (payload.hasOwnProperty(key) && payload[key] !== undefined) { + payload.append(key, tmpObj[key]); + } + } + contentType = 'multipart/form-data'; + } + else { + contentType = 'application/json;charset=UTF-8'; + payload = {}; + for (let key in tmpObj) { + if (tmpObj[key] !== undefined) { + payload[key] = tmpObj[key]; + } + } + } + let opts = { + headers: { + 'content-type': contentType + } + }; + if (options && options['onUploadProgress']) { + opts.onUploadProgress = options['onUploadProgress']; + } + const traceHeader = this._localCache.getStore(tcbTraceKey); + if (traceHeader) { + opts.headers['X-TCB-Trace'] = traceHeader; + } + // 非web平台使用凭证检验有效性 + // if (Adapter.runtime !== RUNTIME.WEB) { + // const { appSign, appSecret } = this.config; + // const timestamp = Date.now(); + // const { appAccessKey, appAccessKeyId } = appSecret; + // const sign = createSign({ + // data: payload, + // timestamp, + // appAccessKeyId, + // appSign + // }, appAccessKey); + // opts.headers['X-TCB-App-Source'] = `timestamp=${timestamp};appAccessKeyId=${appAccessKeyId};appSign=${appSign};sign=${sign}`; + // } + // 发出请求 + // 新的 url 需要携带 env 参数进行 CORS 校验 + // 请求链接支持添加动态 query 参数,方便用户调试定位请求 + const { parse, inQuery, search } = params; + let formatQuery = { + env: this.config.env + }; + // 尝试解析响应数据为 JSON + parse && (formatQuery.parse = true); + inQuery && (formatQuery = { + ...inQuery, + ...formatQuery + }); + // 生成请求 url + let newUrl = formatUrl(protocol, BASE_URL, formatQuery); + if (search) { + newUrl += search; + } + const res = await this.post({ + url: newUrl, + data: payload, + ...opts + }); + // 保存 trace header + const resTraceHeader = res.header && res.header['x-tcb-trace']; + if (resTraceHeader) { + this._localCache.setStore(tcbTraceKey, resTraceHeader); + } + if ((Number(res.status) !== 200 && Number(res.statusCode) !== 200) || !res.data) { + throw new Error('network request error'); + } + return res; + } + async send(action, data = {}) { + const response = await this.request(action, data, { onUploadProgress: data.onUploadProgress }); + if (response.data.code === 'ACCESS_TOKEN_EXPIRED' && actionsWithoutAccessToken.indexOf(action) === -1) { + // access_token过期,重新获取 + await this.refreshAccessToken(); + const response = await this.request(action, data, { onUploadProgress: data.onUploadProgress }); + if (response.data.code) { + throw new Error(`[${response.data.code}] ${response.data.message}`); + } + return response.data; + } + if (response.data.code) { + throw new Error(`[${response.data.code}] ${response.data.message}`); + } + return response.data; + } + setRefreshToken(refreshToken) { + const { accessTokenKey, accessTokenExpireKey, refreshTokenKey } = this._cache.keys; + // refresh token设置前,先清掉 access token + this._cache.removeStore(accessTokenKey); + this._cache.removeStore(accessTokenExpireKey); + this._cache.setStore(refreshTokenKey, refreshToken); + } +} +const requestMap = {}; +function initRequest(config) { + requestMap[config.env] = new IRequest(config); +} +function getRequestByEnvId(env) { + return requestMap[env]; +} + +class AuthProvider { + constructor(config) { + this.config = config; + this._cache = getCache(config.env); + this._request = getRequestByEnvId(config.env); + } + setRefreshToken(refreshToken) { + const { accessTokenKey, accessTokenExpireKey, refreshTokenKey } = this._cache.keys; + // refresh token设置前,先清掉 access token + this._cache.removeStore(accessTokenKey); + this._cache.removeStore(accessTokenExpireKey); + this._cache.setStore(refreshTokenKey, refreshToken); + } + setAccessToken(accessToken, accessTokenExpire) { + const { accessTokenKey, accessTokenExpireKey } = this._cache.keys; + this._cache.setStore(accessTokenKey, accessToken); + this._cache.setStore(accessTokenExpireKey, accessTokenExpire); + } + async refreshUserInfo() { + const action = 'auth.getUserInfo'; + const { data: userInfo } = await this._request.send(action, {}); + this.setLocalUserInfo(userInfo); + return userInfo; + } + setLocalUserInfo(userInfo) { + const { userInfoKey } = this._cache.keys; + this._cache.setStore(userInfoKey, userInfo); + } +} +class User { + constructor(envId) { + if (!envId) { + throw new Error('envId is not defined'); + } + this._envId = envId; + this._cache = getCache(this._envId); + this._request = getRequestByEnvId(this._envId); + this.setUserInfo(); + } + linkWithTicket(ticket) { + if (typeof ticket !== 'string') { + throw new Error('ticket must be string'); + } + return this._request.send('auth.linkWithTicket', { ticket }); + } + linkWithRedirect(provider) { + provider.signInWithRedirect(); + } + updatePassword(newPassword, oldPassword) { + return this._request.send('auth.updatePassword', { + oldPassword, + newPassword + }); + } + updateEmail(newEmail) { + return this._request.send('auth.updateEmail', { + newEmail + }); + } + updateUsername(username) { + if (typeof username !== 'string') { + throw new Error('username must be a string'); + } + return this._request.send('auth.updateUsername', { + username + }); + } + async getLinkedUidList() { + const { data } = await this._request.send('auth.getLinkedUidList', {}); + let hasPrimaryUid = false; + const { users } = data; + users.forEach(user => { + if (user.wxOpenId && user.wxPublicId) { + hasPrimaryUid = true; + } + }); + return { + users, + hasPrimaryUid + }; + } + setPrimaryUid(uid) { + return this._request.send('auth.setPrimaryUid', { uid }); + } + unlink(platform) { + return this._request.send('auth.unlink', { platform }); + } + async update(userInfo) { + const { nickName, gender, avatarUrl, province, country, city } = userInfo; + const { data: newUserInfo } = await this._request.send('auth.updateUserInfo', { nickName, gender, avatarUrl, province, country, city }); + this.setLocalUserInfo(newUserInfo); + } + async refresh() { + const action = 'auth.getUserInfo'; + const { data: userInfo } = await this._request.send(action, {}); + this.setLocalUserInfo(userInfo); + return userInfo; + } + setUserInfo() { + const { userInfoKey } = this._cache.keys; + const userInfo = this._cache.getStore(userInfoKey); + [ + 'uid', + 'loginType', + 'openid', + 'wxOpenId', + 'wxPublicId', + 'unionId', + 'qqMiniOpenId', + 'email', + 'hasPassword', + 'customUserId', + 'nickName', + 'gender', + 'avatarUrl', + ].forEach(infoKey => { + this[infoKey] = userInfo[infoKey]; + }); + this.location = { + country: userInfo['country'], + province: userInfo['province'], + city: userInfo['city'] + }; + } + setLocalUserInfo(userInfo) { + const { userInfoKey } = this._cache.keys; + this._cache.setStore(userInfoKey, userInfo); + this.setUserInfo(); + } +} +class LoginState { + // private _request: IRequest; + constructor(envId) { + if (!envId) { + throw new Error('envId is not defined'); + } + this._cache = getCache(envId); + // this._request = getRequestByEnvId(envId); + const { refreshTokenKey, accessTokenKey, accessTokenExpireKey } = this._cache.keys; + const refreshToken = this._cache.getStore(refreshTokenKey); + const accessToken = this._cache.getStore(accessTokenKey); + const accessTokenExpire = this._cache.getStore(accessTokenExpireKey); + this.credential = { + refreshToken, + accessToken, + accessTokenExpire + }; + this.user = new User(envId); + } + get isAnonymousAuth() { + return this.loginType === LOGINTYPE.ANONYMOUS; + } + get isCustomAuth() { + return this.loginType === LOGINTYPE.CUSTOM; + } + get isWeixinAuth() { + return this.loginType === LOGINTYPE.WECHAT || this.loginType === LOGINTYPE.WECHAT_OPEN || this.loginType === LOGINTYPE.WECHAT_PUBLIC; + } + get loginType() { + return this._cache.getStore(this._cache.keys.loginTypeKey); + } +} + +class AnonymousAuthProvider extends AuthProvider { + async signIn() { + // 匿名登录前迁移cache到localstorage + this._cache.updatePersistence('local'); + const { anonymousUuidKey, refreshTokenKey } = this._cache.keys; + // 如果本地存有uuid则匿名登录时传给server + const anonymous_uuid = this._cache.getStore(anonymousUuidKey) || undefined; + // 此处cache为基类property + const refresh_token = this._cache.getStore(refreshTokenKey) || undefined; + const res = await this._request.send('auth.signInAnonymously', { + anonymous_uuid, + refresh_token + }); + if (res.uuid && res.refresh_token) { + this._setAnonymousUUID(res.uuid); + this.setRefreshToken(res.refresh_token); + await this._request.refreshAccessToken(); + activateEvent(EVENTS.LOGIN_STATE_CHANGED); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { + env: this.config.env, + loginType: LOGINTYPE.ANONYMOUS, + persistence: 'local' + }); + const loginState = new LoginState(this.config.env); + await loginState.user.refresh(); + return loginState; + } + else { + throw new Error('匿名登录失败'); + } + } + async linkAndRetrieveDataWithTicket(ticket) { + const { anonymousUuidKey, refreshTokenKey } = this._cache.keys; + const uuid = this._cache.getStore(anonymousUuidKey); + const refresh_token = this._cache.getStore(refreshTokenKey); + const res = await this._request.send('auth.linkAndRetrieveDataWithTicket', { + anonymous_uuid: uuid, + refresh_token, + ticket + }); + if (res.refresh_token) { + // 转正后清除本地保存的匿名uuid + this._clearAnonymousUUID(); + this.setRefreshToken(res.refresh_token); + await this._request.refreshAccessToken(); + activateEvent(EVENTS.ANONYMOUS_CONVERTED, { env: this.config.env }); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { loginType: LOGINTYPE.CUSTOM, persistence: 'local' }); + return { + credential: { + refreshToken: res.refresh_token + } + }; + } + else { + throw new Error('匿名转化失败'); + } + } + _setAnonymousUUID(id) { + const { anonymousUuidKey, loginTypeKey } = this._cache.keys; + this._cache.removeStore(anonymousUuidKey); + this._cache.setStore(anonymousUuidKey, id); + this._cache.setStore(loginTypeKey, LOGINTYPE.ANONYMOUS); + } + _clearAnonymousUUID() { + this._cache.removeStore(this._cache.keys.anonymousUuidKey); + } +} + +class CustomAuthProvider extends AuthProvider { + async signIn(ticket) { + if (typeof ticket !== 'string') { + throw new Error('ticket must be a string'); + } + const { refreshTokenKey } = this._cache.keys; + const res = await this._request.send('auth.signInWithTicket', { + ticket, + refresh_token: this._cache.getStore(refreshTokenKey) || '' + }); + if (res.refresh_token) { + this.setRefreshToken(res.refresh_token); + await this._request.refreshAccessToken(); + activateEvent(EVENTS.LOGIN_STATE_CHANGED); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { + env: this.config.env, + loginType: LOGINTYPE.CUSTOM, + persistence: this.config.persistence + }); + // set user info + await this.refreshUserInfo(); + return new LoginState(this.config.env); + } + else { + throw new Error('自定义登录失败'); + } + } +} + +class EmailAuthProvider extends AuthProvider { + async signIn(email, password) { + if (typeof email !== 'string') { + throw new Error('email must be a string'); + } + const { refreshTokenKey } = this._cache.keys; + const res = await this._request.send('auth.signIn', { + loginType: 'EMAIL', + email, + password, + refresh_token: this._cache.getStore(refreshTokenKey) || '' + }); + const { refresh_token, access_token, access_token_expire } = res; + if (refresh_token) { + this.setRefreshToken(refresh_token); + if (access_token && access_token_expire) { + this.setAccessToken(access_token, access_token_expire); + } + else { + await this._request.refreshAccessToken(); + } + // set user info + await this.refreshUserInfo(); + activateEvent(EVENTS.LOGIN_STATE_CHANGED); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { + env: this.config.env, + loginType: LOGINTYPE.EMAIL, + persistence: this.config.persistence + }); + return new LoginState(this.config.env); + } + else if (res.code) { + throw new Error(`邮箱登录失败: [${res.code}] ${res.message}`); + } + else { + throw new Error('邮箱登录失败'); + } + } + async activate(token) { + return this._request.send('auth.activateEndUserMail', { + token + }); + } + async resetPasswordWithToken(token, newPassword) { + return this._request.send('auth.resetPasswordWithToken', { + token, + newPassword + }); + } +} + +class UsernameAuthProvider extends AuthProvider { + async signIn(username, password) { + if (typeof username !== 'string') { + throw new Error('username must be a string'); + } + // 用户不设置密码 + if (typeof password !== 'string') { + password = ''; + console.warn('password is empty'); + } + const { refreshTokenKey } = this._cache.keys; + const res = await this._request.send('auth.signIn', { + loginType: LOGINTYPE.USERNAME, + username, + password, + refresh_token: this._cache.getStore(refreshTokenKey) || '' + }); + const { refresh_token, access_token_expire, access_token } = res; + if (refresh_token) { + this.setRefreshToken(refresh_token); + if (access_token && access_token_expire) { + this.setAccessToken(access_token, access_token_expire); + } + else { + await this._request.refreshAccessToken(); + } + // set user info + await this.refreshUserInfo(); + activateEvent(EVENTS.LOGIN_STATE_CHANGED); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { + env: this.config.env, + loginType: LOGINTYPE.USERNAME, + persistence: this.config.persistence + }); + return new LoginState(this.config.env); + } + else if (res.code) { + throw new Error(`用户名密码登录失败: [${res.code}] ${res.message}`); + } + else { + throw new Error(`用户名密码登录失败`); + } + } +} + +// import { WeixinAuthProvider } from './weixinAuthProvider'; +// export interface UserInfo { +// openid: string; +// nickname?: string; +// sex?: number; +// province?: string; +// city?: string; +// country?: string; +// headimgurl?: string; +// privilege?: [string]; +// unionid?: string; +// } +class Auth { + constructor(config) { + this.config = config; + this._cache = getCache(config.env); + this._request = getRequestByEnvId(config.env); + this._onAnonymousConverted = this._onAnonymousConverted.bind(this); + this._onLoginTypeChanged = this._onLoginTypeChanged.bind(this); + addEventListener(EVENTS.LOGIN_TYPE_CHANGED, this._onLoginTypeChanged); + } + get currentUser() { + const loginState = this.hasLoginState(); + if (loginState) { + return loginState.user || null; + } + else { + return null; + } + } + get loginType() { + return this._cache.getStore(this._cache.keys.loginTypeKey); + } + // weixinAuthProvider({ appid, scope, state }) { + // return new WeixinAuthProvider(this.config, appid, scope, state); + // } + anonymousAuthProvider() { + return new AnonymousAuthProvider(this.config); + } + customAuthProvider() { + return new CustomAuthProvider(this.config); + } + emailAuthProvider() { + return new EmailAuthProvider(this.config); + } + usernameAuthProvider() { + return new UsernameAuthProvider(this.config); + } + async signInAnonymously() { + return new AnonymousAuthProvider(this.config).signIn(); + } + async signInWithEmailAndPassword(email, password) { + return new EmailAuthProvider(this.config).signIn(email, password); + } + signInWithUsernameAndPassword(username, password) { + return new UsernameAuthProvider(this.config).signIn(username, password); + } + async linkAndRetrieveDataWithTicket(ticket) { + if (!this._anonymousAuthProvider) { + this._anonymousAuthProvider = new AnonymousAuthProvider(this.config); + } + addEventListener(EVENTS.ANONYMOUS_CONVERTED, this._onAnonymousConverted); + const result = await this._anonymousAuthProvider.linkAndRetrieveDataWithTicket(ticket); + return result; + } + async signOut() { + if (this.loginType === LOGINTYPE.ANONYMOUS) { + throw new Error('匿名用户不支持登出操作'); + } + const { refreshTokenKey, accessTokenKey, accessTokenExpireKey } = this._cache.keys; + const action = 'auth.logout'; + const refresh_token = this._cache.getStore(refreshTokenKey); + if (!refresh_token) { + return; + } + const res = await this._request.send(action, { refresh_token }); + this._cache.removeStore(refreshTokenKey); + this._cache.removeStore(accessTokenKey); + this._cache.removeStore(accessTokenExpireKey); + activateEvent(EVENTS.LOGIN_STATE_CHANGED); + activateEvent(EVENTS.LOGIN_TYPE_CHANGED, { + env: this.config.env, + loginType: LOGINTYPE.NULL, + persistence: this.config.persistence + }); + return res; + } + async signUpWithEmailAndPassword(email, password) { + return this._request.send('auth.signUpWithEmailAndPassword', { + email, password + }); + } + async sendPasswordResetEmail(email) { + return this._request.send('auth.sendPasswordResetEmail', { + email + }); + } + onLoginStateChanged(callback) { + addEventListener(EVENTS.LOGIN_STATE_CHANGED, () => { + const loginState = this.hasLoginState(); + callback.call(this, loginState); + }); + // 立刻执行一次回调 + const loginState = this.hasLoginState(); + callback.call(this, loginState); + } + onLoginStateExpired(callback) { + addEventListener(EVENTS.LOGIN_STATE_EXPIRED, callback.bind(this)); + } + onAccessTokenRefreshed(callback) { + addEventListener(EVENTS.ACCESS_TOKEN_REFRESHD, callback.bind(this)); + } + onAnonymousConverted(callback) { + addEventListener(EVENTS.ANONYMOUS_CONVERTED, callback.bind(this)); + } + onLoginTypeChanged(callback) { + addEventListener(EVENTS.LOGIN_TYPE_CHANGED, () => { + const loginState = this.hasLoginState(); + callback.call(this, loginState); + }); + } + async getAccessToken() { + return { + accessToken: (await this._request.getAccessToken()).accessToken, + env: this.config.env + }; + } + hasLoginState() { + const { refreshTokenKey } = this._cache.keys; + const refreshToken = this._cache.getStore(refreshTokenKey); + if (refreshToken) { + return new LoginState(this.config.env); + } + else { + return null; + } + } + async isUsernameRegistered(username) { + if (typeof username !== 'string') { + throw new Error('username must be a string'); + } + const { data } = await this._request.send('auth.isUsernameRegistered', { + username + }); + return data && data.isRegistered; + } + getLoginState() { + return Promise.resolve(this.hasLoginState()); + } + async signInWithTicket(ticket) { + return new CustomAuthProvider(this.config).signIn(ticket); + } + shouldRefreshAccessToken(hook) { + this._request._shouldRefreshAccessTokenHook = hook.bind(this); + } + getUserInfo() { + const action = 'auth.getUserInfo'; + // console.warn('Auth.getUserInfo() 将会在下个主版本下线,请使用 Auth.currentUser 来获取用户信息'); + return this._request.send(action, {}).then(res => { + if (res.code) { + return res; + } + else { + return { + ...res.data, + requestId: res.seqId + }; + } + }); + } + getAuthHeader() { + const { refreshTokenKey, accessTokenKey } = this._cache.keys; + const refreshToken = this._cache.getStore(refreshTokenKey); + const accessToken = this._cache.getStore(accessTokenKey); + return { + 'x-cloudbase-credentials': accessToken + '/@@/' + refreshToken + }; + } + _onAnonymousConverted(ev) { + const { env } = ev.data; + if (env !== this.config.env) { + return; + } + // 匿名转正后迁移cache + this._cache.updatePersistence(this.config.persistence); + // removeEventListener(EVENTS.ANONYMOUS_CONVERTED, this._onAnonymousConverted); + } + _onLoginTypeChanged(ev) { + const { loginType, persistence, env } = ev.data; + if (env !== this.config.env) { + return; + } + // 登录态转变后迁移cache,防止在匿名登录状态下cache混用 + this._cache.updatePersistence(persistence); + this._cache.setStore(this._cache.keys.loginTypeKey, loginType); + } +} + +/* + * 上传文件 + * @param {string} cloudPath 上传后的文件路径 + * @param {fs.ReadStream} filePath 上传文件的临时路径 + */ +const uploadFile = function (params, callback) { + callback = callback || createPromiseCallback(); + const request = getRequestByEnvId(this.config.env); + const metaData = 'storage.getUploadMetadata'; + const { cloudPath, filePath, onUploadProgress, fileType = 'image' } = params; + request + .send(metaData, { + path: cloudPath + }) + .then(metaData => { + const { data: { url, authorization, token, fileId, cosFileId }, requestId } = metaData; + // 使用临时密匙上传文件 + // https://cloud.tencent.com/document/product/436/14048 + const data = { + key: cloudPath, + signature: authorization, + 'x-cos-meta-fileid': cosFileId, + 'success_action_status': '201', + 'x-cos-security-token': token + }; + // @ts-ignore + request.upload({ + url, + data, + file: filePath, + name: cloudPath, + fileType, + onUploadProgress + }).then((res) => { + if (res.statusCode === 201) { + callback(null, { + fileID: fileId, + requestId + }); + } + else { + callback(new Error(`STORAGE_REQUEST_FAIL: ${res.data}`)); + } + }) + .catch(err => { + callback(err); + }); + }) + .catch(err => { + callback(err); + }); + return callback.promise; +}; +const getUploadMetadata = function (params, callback) { + callback = callback || createPromiseCallback(); + const request = getRequestByEnvId(this.config.env); + const metaData = 'storage.getUploadMetadata'; + const { cloudPath } = params; + request + .send(metaData, { + path: cloudPath + }) + .then(metaData => { + callback(null, metaData); + }) + .catch(err => { + callback(err); + }); + return callback.promise; +}; +/** + * 删除文件 + * @param {Array.} fileList 文件id数组 + */ +const deleteFile = function ({ fileList }, callback) { + callback = callback || createPromiseCallback(); + if (!fileList || !Array.isArray(fileList)) { + return { + code: 'INVALID_PARAM', + message: 'fileList必须是非空的数组' + }; + } + for (let file of fileList) { + if (!file || typeof file !== 'string') { + return { + code: 'INVALID_PARAM', + message: 'fileList的元素必须是非空的字符串' + }; + } + } + const action = 'storage.batchDeleteFile'; + const params = { + fileid_list: fileList + }; + const request = getRequestByEnvId(this.config.env); + request + .send(action, params) + .then(res => { + if (res.code) { + callback(null, res); + } + else { + callback(null, { + fileList: res.data.delete_list, + requestId: res.requestId + }); + } + }) + .catch(err => { + callback(err); + }); + return callback.promise; +}; +/** + * 获取文件下载链接 + * @param {Array.} fileList + */ +const getTempFileURL = function ({ fileList }, callback) { + callback = callback || createPromiseCallback(); + if (!fileList || !Array.isArray(fileList)) { + callback(null, { + code: 'INVALID_PARAM', + message: 'fileList必须是非空的数组' + }); + } + let file_list = []; + for (let file of fileList) { + if (typeof file === 'object') { + if (!file.hasOwnProperty('fileID') || !file.hasOwnProperty('maxAge')) { + callback(null, { + code: 'INVALID_PARAM', + message: 'fileList的元素必须是包含fileID和maxAge的对象' + }); + } + file_list.push({ + fileid: file.fileID, + max_age: file.maxAge + }); + } + else if (typeof file === 'string') { + file_list.push({ + fileid: file + }); + } + else { + callback(null, { + code: 'INVALID_PARAM', + message: 'fileList的元素必须是字符串' + }); + } + } + const action = 'storage.batchGetDownloadUrl'; + const params = { + file_list + }; + // console.log(params); + const request = getRequestByEnvId(this.config.env); + request + .send(action, params) + .then(res => { + // console.log(res); + if (res.code) { + callback(null, res); + } + else { + callback(null, { + fileList: res.data.download_list, + requestId: res.requestId + }); + } + }) + .catch(err => { + callback(err); + }); + return callback.promise; +}; +const downloadFile = async function ({ fileID }, callback) { + const tmpUrlRes = await getTempFileURL.call(this, { + fileList: [ + { + fileID, + maxAge: 600 + } + ] + }); + const res = tmpUrlRes.fileList[0]; + if (res.code !== 'SUCCESS') { + return callback ? callback(res) : new Promise(resolve => { resolve(res); }); + } + const request = getRequestByEnvId(this.config.env); + let tmpUrl = res.download_url; + tmpUrl = encodeURI(tmpUrl); + if (callback) { + const result = await request.download({ url: tmpUrl }); + callback(result); + } + else { + return request.download({ url: tmpUrl }); + } +}; + +const callFunction = function ({ name, data, query, parse, search }, callback) { + const promisedCallback = callback || createPromiseCallback(); + let jsonData; + try { + jsonData = data ? JSON.stringify(data) : ''; + } + catch (e) { + return Promise.reject(e); + } + if (!name) { + return Promise.reject(new Error('函数名不能为空')); + } + const action = 'functions.invokeFunction'; + const params = { + inQuery: query, + parse, + search, + function_name: name, + request_data: jsonData + }; + const request = getRequestByEnvId(this.config.env); + request + .send(action, params) + .then((res) => { + if (res.code) { + promisedCallback(null, res); + } + else { + let result = res.data.response_data; + // parse 为 true 时服务端解析 JSON,SDK 不再次解析 + if (parse) { + promisedCallback(null, { + result, + requestId: res.requestId + }); + } + else { + try { + result = JSON.parse(res.data.response_data); + promisedCallback(null, { + result, + requestId: res.requestId + }); + } + catch (e) { + promisedCallback(new Error('response data must be json')); + } + } + } + return promisedCallback.promise; + }) + .catch((err) => { + promisedCallback(err); + }); + return promisedCallback.promise; +}; + +// import { Db } from '@cloudbase/database'; +/** + * @constant 默认配置 + */ +const DEFAULT_INIT_CONFIG = { + timeout: 15000, + persistence: 'session' +}; +// timeout上限10分钟 +const MAX_TIMEOUT = 1000 * 60 * 10; +// timeout下限100ms +const MIN_TIMEOUT = 100; +const extensionMap = {}; +class TCB { + constructor(config) { + this.config = config ? config : this.config; + this.authObj = undefined; + // if (Adapter.adapter) { + // // eslint-disable-next-line + // this.requestClient = new Adapter.adapter.reqClass({ + // timeout: this.config.timeout, + // timeoutMsg: `请求在${this.config.timeout / 1000}s内未完成,已中断` + // }); + // } + } + init(config) { + // 调用初始化时若未兼容平台,则使用默认adapter + if (!Adapter.adapter) { + // this._useDefaultAdapter(); + // eslint-disable-next-line + this.requestClient = new Adapter.adapter.reqClass({ + timeout: config.timeout || 5000, + timeoutMsg: `请求在${(config.timeout || 5000) / 1000}s内未完成,已中断` + }); + } + // if (Adapter.runtime !== RUNTIME.WEB) { + // if (!config.appSecret) { + // throw new Error('参数错误:请正确配置appSecret'); + // } + // // adapter提供获取应用标识的接口 + // const appSign = Adapter.adapter.getAppSign ? Adapter.adapter.getAppSign() : ''; + // if (config.appSign && appSign && config.appSign !== appSign) { + // // 传入的appSign与sdk获取的不一致 + // throw new Error('参数错误:非法的应用标识'); + // } + // appSign && (config.appSign = appSign); + // if (!config.appSign) { + // throw new Error('参数错误:请正确配置应用标识'); + // } + // } + this.config = { + ...DEFAULT_INIT_CONFIG, + ...config + }; + switch (true) { + case this.config.timeout > MAX_TIMEOUT: + console.warn('timeout大于可配置上限[10分钟],已重置为上限数值'); + this.config.timeout = MAX_TIMEOUT; + break; + case this.config.timeout < MIN_TIMEOUT: + console.warn('timeout小于可配置下限[100ms],已重置为下限数值'); + this.config.timeout = MIN_TIMEOUT; + break; + } + return new TCB(this.config); + } + // database(dbConfig?: object) { + // Db.reqClass = IRequest; + // // @ts-ignore + // Db.wsClass = Adapter.adapter.wsClass; + // if (!this.authObj) { + // console.warn('需要app.auth()授权'); + // return; + // } + // Db.getAccessToken = this.authObj.getAccessToken.bind(this.authObj); + // Db.runtime = Adapter.runtime; + // if (!Db.ws) { + // Db.ws = null; + // } + // return new Db({ ...this.config, ...dbConfig }); + // } + auth({ persistence } = {}) { + if (this.authObj) { + // console.warn('tcb实例只存在一个auth对象'); + return this.authObj; + } + // 如不明确指定persistence则优先取各平台adapter首选,其次session + const _persistence = persistence || Adapter.adapter.primaryStorage || DEFAULT_INIT_CONFIG.persistence; + if (_persistence !== this.config.persistence) { + this.config.persistence = _persistence; + } + // 初始化cache + initCache(this.config); + // 初始化request + initRequest(this.config); + this.authObj = new Auth(this.config); + return this.authObj; + } + on(eventName, callback) { + return addEventListener.apply(this, [eventName, callback]); + } + off(eventName, callback) { + return removeEventListener.apply(this, [eventName, callback]); + } + callFunction(params, callback) { + return callFunction.apply(this, [params, callback]); + } + deleteFile(params, callback) { + return deleteFile.apply(this, [params, callback]); + } + getTempFileURL(params, callback) { + return getTempFileURL.apply(this, [params, callback]); + } + downloadFile(params, callback) { + return downloadFile.apply(this, [params, callback]); + } + uploadFile(params, callback) { + return uploadFile.apply(this, [params, callback]); + } + getUploadMetadata(params, callback) { + return getUploadMetadata.apply(this, [params, callback]); + } + registerExtension(ext) { + extensionMap[ext.name] = ext; + } + async invokeExtension(name, opts) { + const ext = extensionMap[name]; + if (!ext) { + throw Error(`扩展${name} 必须先注册`); + } + let res = await ext.invoke(opts, this); + return res; + } + useAdapters(adapters) { + const { adapter, runtime } = useAdapters(adapters) || {}; + adapter && (Adapter.adapter = adapter); + runtime && (Adapter.runtime = runtime); + } +} +const tcb = new TCB(); + +function isMatch () { + return true +} + +function formatUrl$1 (protocol, url, query) { + if (query === undefined) { query = {}; } + var urlHasQuery = /\?/.test(url); + var queryString = ''; + for (var key in query) { + if (queryString === '') { + !urlHasQuery && (url += '?'); + } else { + queryString += '&'; + } + queryString += key + '=' + encodeURIComponent(query[key]); + } + url += queryString; + if (/^http(s)?:\/\//.test(url)) { + return url + } + return '' + protocol + url +} + +class UniRequest { + post (options) { + const { url, data, headers } = options; + return new Promise((resolve, reject) => { + defaultAdapter.request({ + url: formatUrl$1('https:', url), + data, + method: 'POST', + header: headers, + success (res) { + resolve(res); + }, + fail (err) { + reject(err); + } + }); + }) + } + + upload (options) { + return new Promise((resolve, reject) => { + const { url, file, data, headers, fileType } = options; + const uploadTask = defaultAdapter.uploadFile({ + url: formatUrl$1('https:', url), + name: 'file', + formData: Object.assign({}, data), + filePath: file, + fileType, + header: headers, + success (res) { + const result = { + statusCode: res.statusCode, + data: res.data || {} + }; + // 200转化为201(如果指定) + if (res.statusCode === 200 && data.success_action_status) { + result.statusCode = parseInt(data.success_action_status, 10); + } + resolve(result); + }, + fail (err) { + if (process.env.VUE_APP_PLATFORM === 'mp-alipay' && process.env.NODE_ENV === 'development') { + // 支付宝小程序开发工具上传腾讯云时会进入fail回调,但是可能已经上传成功 + console.warn('支付宝小程序开发工具上传腾讯云时无法准确判断是否上传成功,请使用真机测试'); + } + reject(new Error(err.errMsg || 'uploadFile:fail')); + } + }); + // 钉钉小程序不支持uploadTask + if (typeof options.onUploadProgress === 'function' && uploadTask && typeof uploadTask.onProgressUpdate === 'function') { + uploadTask.onProgressUpdate((res) => { + options.onUploadProgress({ + loaded: res.totalBytesSent, + total: res.totalBytesExpectedToSend + }); + }); + } + }) + } +} + +const uniMpStorage = { + setItem (key, value) { + defaultAdapter.setStorageSync(key, value); + }, + getItem (key) { + return defaultAdapter.getStorageSync(key) + }, + removeItem (key) { + defaultAdapter.removeStorageSync(key); + }, + clear () { + defaultAdapter.clearStorageSync(); + } +}; + +function genAdapter () { + const adapter = { + root: {}, + reqClass: UniRequest, + localStorage: uniMpStorage, + primaryStorage: 'local' + }; + return adapter +} + +const adapter = { + genAdapter, + isMatch, + runtime: 'uni_app' +}; + +tcb.useAdapters(adapter); + +const uniCloud$1 = tcb; +const oldInit = uniCloud$1.init; +uniCloud$1.init = function (options) { + options.env = options.spaceId; + const uniClient = oldInit.call(this, options); + uniClient.config.provider = 'tencent'; + uniClient.config.spaceId = options.spaceId; + const oldAuth = uniClient.auth; + uniClient.auth = function (options) { + const uniAuth = oldAuth.call(this, options); + const callbackifyListAuth = ['linkAndRetrieveDataWithTicket', 'signInAnonymously', 'signOut', 'getAccessToken', 'getLoginState', 'signInWithTicket', 'getUserInfo']; + callbackifyListAuth.forEach((item) => { + uniAuth[item] = callbackify(uniAuth[item]).bind(uniAuth); + }); + return uniAuth + }; + uniClient.customAuth = uniClient.auth; + + // callFunction、uploadFile 在 core 内 callbackify + const callbackifyListClient = ['deleteFile', 'getTempFileURL', 'downloadFile']; + callbackifyListClient.forEach((item) => { + uniClient[item] = callbackify(uniClient[item]).bind(uniClient); + }); + + return uniClient +}; + +class Client$1 extends Client { + getAccessToken () { + return new Promise((resolve, reject) => { + const accessToken = 'Anonymous_Access_token'; + this.setAccessToken(accessToken); + resolve(accessToken); + }) + } + + setupRequest (body, type) { + const data = Object.assign({}, body, { + spaceId: this.config.spaceId, + timestamp: Date.now() + }); + const header = { + 'Content-Type': 'application/json' + }; + + if (type !== 'auth') { + data.token = this.accessToken; + header['x-basement-token'] = this.accessToken; + } + + header['x-serverless-sign'] = codec.sign(data, this.config.clientSecret); + + const clientInfo = getClientInfo() ; + const { + APPID, + PLATFORM, + DEVICEID, + CLIENT_SDK_VERSION + } = clientInfo; + + // 私有化专属头信息 + header['x-client-platform'] = PLATFORM; + header['x-client-appid'] = APPID; + header['x-client-device-id'] = DEVICEID; + header['x-client-version'] = CLIENT_SDK_VERSION; + header['x-client-token'] = defaultAdapter.getStorageSync('uni_id_token'); + + return { + url: this.config.requestUrl, + method: 'POST', + data, + dataType: 'json', + header: JSON.parse(JSON.stringify(header)) // 过滤undefined值 + } + } + + uploadFileToOSS ({ + url, + formData, + name, + filePath, + fileType, + onUploadProgress + }) { + return new Promise((resolve, reject) => { + const uploadTask = this.adapter.uploadFile({ + url, + formData, + name, + filePath, + fileType, + success (res) { + if (res && res.statusCode < 400) { + resolve(res); + } else { + reject(new UniCloudError({ + code: 'UPLOAD_FAILED', + message: '文件上传失败' + })); + } + }, + fail (err) { + reject(new UniCloudError({ + code: err.code || 'UPLOAD_FAILED', + message: err.message || err.errMsg || '文件上传失败' + })); + } + }); + if (typeof onUploadProgress === 'function' && uploadTask && typeof uploadTask.onProgressUpdate === 'function') { + uploadTask.onProgressUpdate((res) => { + onUploadProgress({ + loaded: res.totalBytesSent, + total: res.totalBytesExpectedToSend + }); + }); + } + }) + } + + uploadFile ({ + filePath, + cloudPath, + fileType = 'image', + onUploadProgress + }) { + if (!cloudPath) { + throw new UniCloudError({ + code: 'CLOUDPATH_REQUIRED', + message: 'cloudPath不可为空' + }) + } + let fileUrl; + return this.getOSSUploadOptionsFromPath({ + cloudPath: cloudPath + }).then((res) => { + const { + url, + formData, + name, + fileUrl: cloudUrl + } = res.result; + fileUrl = cloudUrl; + const uploadFileToOSSOptions = { + url, + formData, + name, + filePath: filePath, + fileType + }; + return this.uploadFileToOSS(Object.assign({}, uploadFileToOSSOptions, { + onUploadProgress + })) + }).then(() => { + return this.reportOSSUpload({ + cloudPath: cloudPath + }) + }).then((res) => { + return new Promise((resolve, reject) => { + if (res.success) { + resolve({ + success: true, + filePath, + fileID: fileUrl + }); + } else { + reject(new UniCloudError({ + code: 'UPLOAD_FAILED', + message: '文件上传失败' + })); + } + }) + }) + } +} + +const uniCloud$2 = { + init (config) { + const uniClient = new Client$1(config); + // callFunction、uploadFile 在 core 内 callbackify + const callbackifyListClient = ['deleteFile', 'getTempFileURL']; + callbackifyListClient.forEach((item) => { + uniClient[item] = callbackify(uniClient[item]).bind(uniClient); + }); + + const authObj = { + signInAnonymously: function () { + return uniClient.authorize() + }, + // 阿里云暂时这么实现 + getLoginState: function () { + return Promise.resolve(false) + } + }; + + uniClient.auth = function () { + return authObj + }; + uniClient.customAuth = uniClient.auth; + + return uniClient + } +}; + +let clientInfo, uniCloudClientInfo; + +function getRealFunctionData ({ + name, + data, + spaceId, + provider +}) { + if (!clientInfo && true) { + clientInfo = getClientInfo(); + uniCloudClientInfo = getUniCloudClientInfo(); + } + const optionsDataCopy = JSON.parse(JSON.stringify(data || {})); + const fn = name; + const sid = spaceId; + const providerList = { + tencent: 't', + aliyun: 'a' + }; + const pvd = providerList[provider]; + { + const uniCloudClientInfoCopy = Object.assign({}, uniCloudClientInfo, { + fn, + sid, + pvd + }); + Object.assign(optionsDataCopy, { + clientInfo, + uniCloudClientInfo: encodeURIComponent(JSON.stringify(uniCloudClientInfoCopy)) + }); + + // 遗留问题 + const { + deviceId + } = uni.getSystemInfoSync(); + optionsDataCopy.uniCloudDeviceId = deviceId; + } + if (!optionsDataCopy.uniIdToken) { + const uniIdToken = defaultAdapter.getStorageSync(UNI_ID_TOKEN_KEY) || defaultAdapter.getStorageSync(UNI_ID_TOKEN_KEY_DEP); + if (uniIdToken) { + optionsDataCopy.uniIdToken = uniIdToken; + } + } + return optionsDataCopy +} + +function callFunction$1 ({ + name, + data +}) { + const { + localAddress: address, + localPort: port + } = this; + const pvdList = { + aliyun: 'aliyun', + tencent: 'tcb' + }; + const provider = pvdList[this.config.provider]; + const spaceId = this.config.spaceId; + const checkUrl = `http://${address}:${port}/system/check-function`; + const requestUrl = `http://${address}:${port}/cloudfunctions/${name}`; + return new Promise((resolve, reject) => { + defaultAdapter.request({ + method: 'POST', + url: checkUrl, + data: { + name, + platform: process.env.VUE_APP_PLATFORM, + provider, + spaceId + }, + timeout: 3000, + success (res) { + resolve(res); + }, + fail () { + resolve({ + data: { + code: 'NETWORK_ERROR', + message: '连接本地调试服务失败,请检查客户端是否和主机在同一局域网下,自动切换为已部署的云函数。' + } + }); + } + }); + }).then(({ + data + } = {}) => { + const { + code, + message + } = data || {}; + return { + code: code === 0 ? 0 : code || 'SYS_ERR', + message: message || 'SYS_ERR' + } + }).then(({ + code, + message + }) => { + if (code !== 0) { + switch (code) { + case 'MODULE_ENCRYPTED': + console.error(`此云函数(${name})依赖加密公共模块不可本地调试,自动切换为云端已部署的云函数`); + break + case 'FUNCTION_ENCRYPTED': + console.error(`此云函数(${name})已加密不可本地调试,自动切换为云端已部署的云函数`); + break + case 'ACTION_ENCRYPTED': + console.error(message || '需要访问加密的uni-clientDB-action,自动切换为云端环境'); + break + case 'NETWORK_ERROR': { + const msg = '连接本地调试服务失败,请检查客户端是否和主机在同一局域网下'; + console.error(msg); + throw new Error(msg) + } + case 'SWITCH_TO_CLOUD': + break + default: { + const msg = `检测本地调试服务出现错误:${message},请检查网络环境或重启客户端再试`; + console.error(msg); + throw new Error(msg) + } + } + return this.originCallFunction({ name, data }) + } + return new Promise((resolve, reject) => { + const param = getRealFunctionData({ + name, + data, + provider: this.config.provider, + spaceId: spaceId + }); + defaultAdapter.request({ + method: 'POST', + url: requestUrl, + data: { + provider, + platform: process.env.VUE_APP_PLATFORM, + param + }, + success ({ + statusCode, + data + } = {}) { + if (!statusCode || statusCode >= 400) { + return reject(new UniCloudError({ + code: data.code || 'SYS_ERR', + message: data.message || 'request:fail' + })) + } + return resolve({ + result: data + }) + }, + fail (err) { + reject(new UniCloudError({ + code: err.code || err.errCode || 'SYS_ERR', + message: err.message || err.errMsg || 'request:fail' + })); + } + }); + }) + }) +} + +const ErrorFormatter = [{ + rule: /fc_function_not_found|FUNCTION_NOT_FOUND/, + content: ',云函数[{functionName}]在云端不存在,请检查此云函数名称是否正确以及该云函数是否已上传到服务空间', + mode: 'append' +}]; + +// copy from lodash +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +var reHasRegExpChar = RegExp(reRegExpChar.source); + +/** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ +function escapeRegExp (string) { + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string +} + +function replaceAll (str, substr, newSubstr) { + return str.replace(new RegExp(escapeRegExp(substr), 'g'), newSubstr) +} + +function formatMessage ({ + message = '', + extraInfo = {}, + formatter = [] +} = {}) { + for (let i = 0; i < formatter.length; i++) { + const { + rule, + content, + mode + } = formatter[i]; + const matched = message.match(rule); + if (!matched) { + continue + } + let contentParsed = content; + for (let i = 1; i < matched.length; i++) { + contentParsed = replaceAll(contentParsed, `{$${i}}`, matched[i]); + } + for (const key in extraInfo) { + contentParsed = replaceAll(contentParsed, `{${key}}`, extraInfo[key]); + } + switch (mode) { + case 'replace': + return contentParsed + case 'append': + default: + return message + contentParsed + } + } + return message +} + +function initCallFunction (uniClient) { + const oldCallFunction = uniClient.callFunction; + + uniClient.callFunction = function (options) { + let preRequest; + if (this.isReady) { + preRequest = Promise.resolve(); + } else { + preRequest = this.initUniCloud; + } + const functionName = options.name; + return preRequest.then(() => { + options.data = getRealFunctionData({ + name: functionName, + data: options.data, + provider: this.config.provider, + spaceId: this.config.spaceId + }); + const pvdList = { + aliyun: 'aliyun', + tencent: 'tcb' + }; + const logPvd = pvdList[this.config.provider]; + return new Promise((resolve, reject) => { + oldCallFunction.call(this, options).then((res) => { + if (this.config.useDebugFunction && res && res.requestId) { + const log = JSON.stringify({ + spaceId: this.config.spaceId, + functionName, + requestId: res.requestId + }); + console.log(`[${logPvd}-request]${log}[/${logPvd}-request]`); + } + resolve(res); + }).catch((err) => { + if (this.config.useDebugFunction && err && err.requestId) { + const log = JSON.stringify({ + spaceId: this.config.spaceId, + functionName, + requestId: err.requestId + }); + console.log(`[${logPvd}-request]${log}[/${logPvd}-request]`); + } + if (err && err.message) { + err.message = formatMessage({ + message: `[${options.name}]: ${err.message}`, + formatter: ErrorFormatter, + extraInfo: { + functionName + } + }); + } + reject(err); + }); + }) + }) + }; + + const callFunction = uniClient.callFunction; + // uniClient.callFunction = function (options) { + // return callbackify(callFunction).call(this, options) + // } + uniClient.originCallFunction = uniClient.callFunction; + + uniClient.callFunction = function (options) { + const newCallFunction = function (options) { + let preRequest; + if (uniClient.isReady) { + preRequest = Promise.resolve(); + } else { + preRequest = uniClient.initUniCloud; + } + const callFunctionPromise = preRequest.then(() => { + if (process.env.NODE_ENV === 'development' && uniClient.debugInfo && !uniClient.debugInfo.forceRemote && process.env.UNI_CLOUD_PROVIDER) { + return callFunction$1.call(this, options) + } else { + return callFunction.call(this, options) + } + }); + Object.defineProperty(callFunctionPromise, 'result', { + get () { + console.warn('当前返回结果为Promise类型,不可直接访问其result属性,详情请参考:https://uniapp.dcloud.net.cn/uniCloud/faq?id=promise'); + return {} + } + }); + return callFunctionPromise + }; + return callbackify(newCallFunction).call(this, options) + }; +} + +function initUploadFile (uniClient) { + const oldUploadFile = uniClient.uploadFile; + + uniClient.uploadFile = function (options) { + let preRequest; + if (this.isReady) { + preRequest = Promise.resolve(); + } else { + preRequest = this.initUniCloud; + } + return preRequest.then(() => { + return oldUploadFile.call(this, options) + }) + }; + + const uploadFile = uniClient.uploadFile; + uniClient.uploadFile = function (options) { + return callbackify(uploadFile).call(this, options) + }; +} + +const SYMBOL_CLIENT_DB_INTERNAL = Symbol('CLIENT_DB_INTERNAL'); + +function getType (val) { + return Object.prototype.toString.call(val).slice(8, -1).toLowerCase() +} + +// handler内先只实现get +function getSafeProxy (target, handler) { + target.then = 'DoNotReturnProxyWithAFunctionNamedThen'; + target._internalType = SYMBOL_CLIENT_DB_INTERNAL; + return new Proxy(target, { + get (obj, key, rec) { + if (hasOwn(obj, key) || obj[key] || typeof key !== 'string') { + return obj[key] + } + return handler.get(obj, key, rec) + } + }) +} + +function hasOwn (obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key) +} + +class ErrorWithCode extends Error { + constructor (message, code) { + super(message); + this.code = code; + } +} + +function parse (param) { + switch (getType(param)) { + case 'array': + return param.map(item => parse(item)) + case 'object': + if (param._internalType === SYMBOL_CLIENT_DB_INTERNAL) { + return param + } + Object.keys(param).forEach(key => { + param[key] = parse(param[key]); + }); + return param + case 'regexp': + return { + $regexp: { + source: param.source, + flags: param.flags + } + } + case 'date': + return { + $date: param.toISOString() + } + default: + return param + } +} + +function initDatabase (uniClient) { + uniClient.database = function () { + if (this._database) { + return this._database + } + const authCallBacks = {}; + const dbCallBacks = {}; + + class Stage { + constructor (content, prevStage, actionName) { + this.content = content; + this.prevStage = prevStage; + this.actionName = actionName; + } + + toJSON () { + let tempStage = this; + const stages = [tempStage.content]; + while (tempStage.prevStage) { + tempStage = tempStage.prevStage; + stages.push(tempStage.content); + } + return { + $db: stages.reverse().map((item) => { + return { + $method: item.$method, + $param: item.$param + } + }) + } + } + + get useAggregate () { + let tempStage = this; + let useAggregate = false; + while (tempStage.prevStage) { + tempStage = tempStage.prevStage; + const methodName = tempStage.content.$method; + if (methodName === 'aggregate' || methodName === 'pipeline') { + useAggregate = true; + break + } + } + return useAggregate + } + + // 聚合count特殊处理 + get count () { + if (!this.useAggregate) { + return function () { + return this._send('count', Array.from(arguments)) + } + } + const that = this; + return function () { + return getDbIns({ + $method: 'count', + $param: parse(Array.from(arguments)) + }, that, that.actionName) + } + } + + get () { + return this._send('get', Array.from(arguments)) + } + + add () { + return this._send('add', Array.from(arguments)) + } + + remove () { + return this._send('remove', Array.from(arguments)) + } + + update () { + return this._send('update', Array.from(arguments)) + } + + end () { + return this._send('end', Array.from(arguments)) + } + + set () { + throw new Error('clientDB禁止使用set方法') + } + + _send (method, param) { + const command = this.toJSON(); + command.$db.push({ + $method: method, + $param: parse(param) + }); + return uniClient.callFunction({ + name: 'DCloud-clientDB', + data: { + action: this.actionName, + command + } + }).then(res => { + const { + code, + message, + token, + tokenExpired, + systemInfo = [] + } = res.result; + if (systemInfo) { + for (let i = 0; i < systemInfo.length; i++) { + const { + level, + message, + detail + } = systemInfo[i]; + const realLevel = process.env.VUE_APP_PLATFORM === 'app-plus' && level === 'warn' ? 'error' : level; + const log = console[realLevel] || console.log; + let logMsg = '[System Info]' + message; + if (detail) { + logMsg = `${logMsg}\n详细信息:${detail}`; + } + log(logMsg); + } + } + if (code) { + return Promise.reject(new ErrorWithCode(message, code)) + } + // 保持旧版兼容authCallBacks + if (token && tokenExpired && authCallBacks.refreshToken) { + authCallBacks.refreshToken.forEach(func => { + func({ + token, + tokenExpired + }); + }); + } + // 新版支持dbCallBacks + if (token && tokenExpired && dbCallBacks.refreshToken) { + dbCallBacks.refreshToken.forEach(func => { + func({ + token, + tokenExpired + }); + }); + } + return Promise.resolve(res) + }).catch(err => { + const error = new ErrorWithCode(err.message, err.code || 'SYSTEM_ERROR'); + if (dbCallBacks.error) { + dbCallBacks.error.forEach(func => { + func(error); + }); + } + if (/fc_function_not_found|FUNCTION_NOT_FOUND/g.test(err.message)) { + console.warn('clientDB未初始化,请在web控制台保存一次schema以开启clientDB'); + } + return Promise.reject(err) + }) + } + } + + const propList = ['db.Geo', 'db.command', 'command.aggregate']; + + function isProp (prev, key) { + return propList.indexOf(`${prev}.${key}`) > -1 + } + + function getDbIns (content, prevStage, actionName) { + const stage = new Stage(content, prevStage, actionName); + return getSafeProxy(stage, { + get (stage, key) { + let prevMethod = 'db'; + if (stage && stage.content) { + prevMethod = stage.content.$method; + } + if (isProp(prevMethod, key)) { + return getDbIns({ + $method: key + }, stage, actionName) + } + return function () { + return getDbIns({ + $method: key, + $param: parse(Array.from(arguments)) + }, stage, actionName) + } + } + }) + } + + function getDbClass ({ + path, + method + }) { + return class { + constructor () { + this.param = Array.from(arguments); + } + + toJSON () { + return { + $newDb: [ + ...path.map(prop => { return { $method: prop } }), + { + $method: method, + $param: this.param + }] + } + } + } + } + + const db = { + auth: { + on: (event, func) => { + authCallBacks[event] = authCallBacks[event] || []; + if (authCallBacks[event].indexOf(func) > -1) { + return + } + authCallBacks[event].push(func); + }, + off: (event, func) => { + authCallBacks[event] = authCallBacks[event] || []; + const index = authCallBacks[event].indexOf(func); + if (index === -1) { + return + } + authCallBacks[event].splice(index, 1); + } + }, + on: (event, func) => { + dbCallBacks[event] = dbCallBacks[event] || []; + if (dbCallBacks[event].indexOf(func) > -1) { + return + } + dbCallBacks[event].push(func); + }, + off: (event, func) => { + dbCallBacks[event] = dbCallBacks[event] || []; + const index = dbCallBacks[event].indexOf(func); + if (index === -1) { + return + } + dbCallBacks[event].splice(index, 1); + }, + env: getSafeProxy({}, { + get (env, prop) { + return { + $env: prop + } + } + }), + action (actionName) { + return getSafeProxy({}, { + get (db, key) { + if (isProp('db', key)) { + return getDbIns({ + $method: key + }, null, actionName) + } + return function () { + return getDbIns({ + $method: key, + $param: parse(Array.from(arguments)) + }, null, actionName) + } + } + }) + }, + Geo: getSafeProxy({}, { + get (Geo, key) { + return getDbClass({ + path: ['Geo'], + method: key + }) + } + }), + getCloudEnv: function (envStr) { + if (typeof envStr !== 'string' || !envStr.trim()) { + throw new Error('getCloudEnv参数错误') + } + return { + $env: envStr.replace('$cloudEnv_', '') + } + }, + get serverDate () { + return getDbClass({ + path: [], + method: 'serverDate' + }) + }, + get RegExp () { + return getDbClass({ + path: [], + method: 'RegExp' + }) + } + }; + + const database = getSafeProxy(db, { + get (db, key) { + if (isProp('db', key)) { + return getDbIns({ + $method: key + }) + } + return function () { + return getDbIns({ + $method: key, + $param: parse(Array.from(arguments)) + }) + } + } + }); + + this._database = database; + + return database + }; +} + +function b64DecodeUnicode (str) { + return decodeURIComponent(atob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')) +} + +function getCurrentUserInfo () { + const token = defaultAdapter.getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + } + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo +} + +var chooseAndUploadFile = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, '__esModule', { value: true }); + +const ERR_MSG_OK = 'chooseAndUploadFile:ok'; +const ERR_MSG_FAIL = 'chooseAndUploadFile:fail'; +function chooseImage (opts) { + const { count, sizeType, sourceType = ['album', 'camera'], extension } = opts; + return new Promise((resolve, reject) => { + uni.chooseImage({ + count, + sizeType, + sourceType, + extension, + success (res) { + resolve(normalizeChooseAndUploadFileRes(res, 'image')); + }, + fail (res) { + reject({ + errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL) + }); + } + }); + }) +} +function chooseVideo (opts) { + const { camera, compressed, maxDuration, sourceType, extension } = opts; + return new Promise((resolve, reject) => { + uni.chooseVideo({ + camera, + compressed, + maxDuration, + sourceType, + extension, + success (res) { + const { tempFilePath, duration, size, height, width } = res; + resolve(normalizeChooseAndUploadFileRes({ + errMsg: 'chooseVideo:ok', + tempFilePaths: [tempFilePath], + tempFiles: [ + { + name: (res.tempFile && res.tempFile.name) || '', + path: tempFilePath, + size, + type: (res.tempFile && res.tempFile.type) || '', + width, + height, + duration, + fileType: 'video', + cloudPath: '' + } + ] + }, 'video')); + }, + fail (res) { + reject({ + errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL) + }); + } + }); + }) +} +function chooseAll (opts) { + const { count, extension } = opts; + return new Promise((resolve, reject) => { + let chooseFile = uni.chooseFile; + if (typeof wx !== 'undefined' && + typeof wx.chooseMessageFile === 'function') { + chooseFile = wx.chooseMessageFile; + } + if (typeof chooseFile !== 'function') { + return reject({ + errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。' + }) + } + chooseFile({ + type: 'all', + count, + extension, + success (res) { + resolve(normalizeChooseAndUploadFileRes(res)); + }, + fail (res) { + reject({ + errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL) + }); + } + }); + }) +} +function normalizeChooseAndUploadFileRes (res, fileType) { + res.tempFiles.forEach((item, index) => { + if (!item.name) { + item.name = item.path.substring(item.path.lastIndexOf('/') + 1); + } + if (fileType) { + item.fileType = fileType; + } + item.cloudPath = + Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.')); + }); + // wx.chooseMessageFile + if (!res.tempFilePaths) { + res.tempFilePaths = res.tempFiles.map((file) => file.path); + } + return res +} +function uploadCloudFiles (uniClient, res, max = 5, onUploadProgress) { + res = Object.assign({}, res); + res.errMsg = ERR_MSG_OK; + const files = res.tempFiles; + const len = files.length; + let count = 0; + return new Promise((resolve) => { + while (count < max) { + next(); + } + function next () { + const cur = count++; + if (cur >= len) { + !files.find((item) => !item.url && !item.errMsg) && resolve(res); + return + } + const fileItem = files[cur]; + uniClient + .uploadFile({ + filePath: fileItem.path, + cloudPath: fileItem.cloudPath, + fileType: fileItem.fileType, + onUploadProgress (res) { + res.index = cur; + res.tempFile = fileItem; + res.tempFilePath = fileItem.path; + onUploadProgress && + onUploadProgress(res); + } + }) + .then((res) => { + fileItem.url = res.fileID; + if (cur < len) { + next(); + } + }) + .catch((res) => { + fileItem.errMsg = res.errMsg || res.message; + if (cur < len) { + next(); + } + }); + } + }) +} +function uploadFiles (uniClient, choosePromise, { onChooseFile, onUploadProgress }) { + return choosePromise + .then((res) => { + if (onChooseFile) { + const customChooseRes = onChooseFile(res); + if (typeof customChooseRes !== 'undefined') { + return Promise.resolve(customChooseRes).then((chooseRes) => typeof chooseRes === 'undefined' ? res : chooseRes) + } + } + return res + }) + .then((res) => { + if (res === false) { + return { + errMsg: ERR_MSG_OK, + tempFilePaths: [], + tempFiles: [] + } + } + return uploadCloudFiles(uniClient, res, 5, onUploadProgress) + }) +} +function initChooseAndUploadFile (uniClient) { + return function chooseAndUploadFile (opts = { type: 'all' }) { + if (opts.type === 'image') { + return uploadFiles(uniClient, chooseImage(opts), opts) + } else if (opts.type === 'video') { + return uploadFiles(uniClient, chooseVideo(opts), opts) + } + return uploadFiles(uniClient, chooseAll(opts), opts) + } +} + +exports.initChooseAndUploadFile = initChooseAndUploadFile; +}); + +var chooseAndUploadFile$1 = /*@__PURE__*/unwrapExports(chooseAndUploadFile); + +function initCommonMethod (uniClient) { + uniClient.getCurrentUserInfo = getCurrentUserInfo; + { + uniClient.chooseAndUploadFile = callbackify(chooseAndUploadFile$1.initChooseAndUploadFile(uniClient)); + } +} + +const loadMode = { + auto: 'auto', + onready: 'onready', + manual: 'manual' +}; + +function getMixinDatacom (uniClient) { + return { + props: { + localdata: { + type: Array, + default () { + return [] + } + }, + options: { + type: [Object, Array], + default () { + return {} + } + }, + collection: { + type: String, + default: '' + }, + action: { + type: String, + default: '' + }, + field: { + type: String, + default: '' + }, + orderby: { + type: String, + default: '' + }, + where: { + type: [String, Object], + default: '' + }, + pageData: { + type: String, + default: 'add' + }, + pageCurrent: { + type: Number, + default: 1 + }, + pageSize: { + type: Number, + default: 20 + }, + getcount: { + type: [Boolean, String], + default: false + }, + gettree: { + type: [Boolean, String], + default: false + }, + gettreepath: { + type: [Boolean, String], + default: false + }, + startwith: { + type: String, + default: '' + }, + limitlevel: { + type: Number, + default: 10 + }, + groupby: { + type: String, + default: '' + }, + groupField: { + type: String, + default: '' + }, + distinct: { + type: [Boolean, String], + default: false + }, + foreignKey: { + type: String, + default: '' + }, + loadtime: { + type: String, + default: 'auto' + }, + manual: { + type: Boolean, + default: false + } + }, + data () { + return { + mixinDatacomLoading: false, + mixinDatacomHasMore: false, + mixinDatacomResData: [], + mixinDatacomErrorMessage: '', + mixinDatacomPage: {} + } + }, + created () { + this.mixinDatacomPage = { + current: this.pageCurrent, + size: this.pageSize, + count: 0 + }; + this.$watch(() => { + var al = []; + ['pageCurrent', + 'pageSize', + 'localdata', + 'collection', + 'action', + 'field', + 'orderby', + 'where', + 'getont', + 'getcount', + 'gettree', + 'groupby', + 'groupField', + 'distinct' + ].forEach(key => { + al.push(this[key]); + }); + return al + }, (newValue, oldValue) => { + if (this.loadtime === loadMode.manual) { + return + } + + let needReset = false; + const changed = []; + for (let i = 2; i < newValue.length; i++) { + if (newValue[i] !== oldValue[i]) { + changed.push(newValue[i]); + needReset = true; + } + } + if (newValue[0] !== oldValue[0]) { + this.mixinDatacomPage.current = this.pageCurrent; + } + this.mixinDatacomPage.size = this.pageSize; + + this.onMixinDatacomPropsChange(needReset, changed); + }); + }, + methods: { + onMixinDatacomPropsChange (needReset, changed) {}, + mixinDatacomEasyGet ({ + getone = false, + success, + fail + } = {}) { + if (this.mixinDatacomLoading) { + return + } + this.mixinDatacomLoading = true; + + this.mixinDatacomErrorMessage = ''; + + this.mixinDatacomGet().then((res) => { + this.mixinDatacomLoading = false; + const { + data, + count + } = res.result; + if (this.getcount) { + this.mixinDatacomPage.count = count; + } + this.mixinDatacomHasMore = data.length < this.pageSize; + const responseData = getone ? (data.length ? data[0] : undefined) : data; + this.mixinDatacomResData = responseData; + + if (success) { + success(responseData); + } + }).catch((err) => { + this.mixinDatacomLoading = false; + this.mixinDatacomErrorMessage = err; + fail && fail(err); + }); + }, + mixinDatacomGet (options = {}) { + let db = uniClient.database(); + + const action = options.action || this.action; + if (action) { + db = db.action(action); + } + + const collection = options.collection || this.collection; + db = db.collection(collection); + + const where = options.where || this.where; + if (!(!where || !Object.keys(where).length)) { + db = db.where(where); + } + + const field = options.field || this.field; + if (field) { + db = db.field(field); + } + + const foreignKey = options.foreignKey || this.foreignKey; + if (foreignKey) { + db = db.foreignKey(foreignKey); + } + + const groupby = options.groupby || this.groupby; + if (groupby) { + db = db.groupBy(groupby); + } + + const groupField = options.groupField || this.groupField; + if (groupField) { + db = db.groupField(groupField); + } + + const distinct = options.distinct !== undefined ? options.distinct : this.distinct; + if (distinct === true) { + db = db.distinct(); + } + + const orderby = options.orderby || this.orderby; + if (orderby) { + db = db.orderBy(orderby); + } + + const current = options.pageCurrent !== undefined ? options.pageCurrent : this.mixinDatacomPage.current; + const size = options.pageSize !== undefined ? options.pageSize : this.mixinDatacomPage.size; + const getCount = options.getcount !== undefined ? options.getcount : this.getcount; + const gettree = options.gettree !== undefined ? options.gettree : this.gettree; + const gettreepath = options.gettreepath !== undefined ? options.gettreepath : this.gettreepath; + const limitLevel = options.limitlevel !== undefined ? options.limitlevel : this.limitlevel; + const startWith = options.startwith !== undefined ? options.startwith : this.startwith; + + const getOptions = { + getCount + }; + const treeOptions = { + limitLevel, + startWith + }; + + if (gettree) { + getOptions.getTree = treeOptions; + } + if (gettreepath) { + getOptions.getTreePath = treeOptions; + } + + db = db.skip(size * (current - 1)).limit(size).get(getOptions); + + return db + } + } + } +} + +function request (options) { + return new Promise((resolve, reject) => { + defaultAdapter.request({ + ...options, + success (res) { + resolve(res); + }, + fail (err) { + reject(err); + } + }); + }) +} + +async function ping (address, port) { + const pingUrl = `http://${address}:${port}/system/ping`; + try { + const pingRes = await request({ + url: pingUrl, + timeout: 500 + }); + if (pingRes.data && pingRes.data.code === 0) { + return true + } + return false + } catch (error) { + return false + } +} + +async function getServerAddr (addressList, port) { + let addressRes; + for (let i = 0; i < addressList.length; i++) { + const address = addressList[i]; + if (await ping(address, port)) { + addressRes = address; + break + } + } + return { + address: addressRes, + port + } +} + +// 需要的环境变量 +// process.env.UNICLOUD_DEBUG = JSON.stringify({ +// address: [ +// '192.168.12.121', +// '127.0.0.1', +// '172.17.144.129', +// '192.168.74.97' +// ], +// servePort: 5001, +// provider: 'tcb', +// initialLaunchType: 'remote', +// }) + +class UniCloud { + init (config) { + let uniClient = {}; + + const useDebugFunction = + config.debugFunction !== false && + process.env.NODE_ENV === 'development' && + ((process.env.VUE_APP_PLATFORM === 'h5' && + navigator.userAgent.indexOf('HBuilderX') > 0) || + process.env.VUE_APP_PLATFORM === 'app-plus'); + + switch (config.provider) { + case 'tencent': + uniClient = uniCloud$1.init( + Object.assign(config, { + useDebugFunction + }) + ); + break + case 'aliyun': + uniClient = uniCloud.init( + Object.assign(config, { + useDebugFunction + }) + ); + break + case 'private': + uniClient = uniCloud$2.init( + Object.assign(config, { + useDebugFunction + }) + ); + break + default: + throw new Error('未提供正确的provider参数') + } + + // 附加调试信息 + const debugInfo = process.env.UNICLOUD_DEBUG; + if (process.env.NODE_ENV === 'development' && debugInfo && !debugInfo.code) { + uniClient.debugInfo = debugInfo; + } + + // uniClient.isReady = true + + // 判断登录状态无效,自动使用匿名登录 + // if (true) { + uniClient.isReady = false; + const authObj = uniClient.auth(); + uniClient.initUniCloud = authObj.getLoginState().then((loginState) => { + if (!loginState) { + return authObj.signInAnonymously() + } else { + return Promise.resolve() + } + }).then(() => { + // 测试云函数本地运行地址 + if (process.env.NODE_ENV === 'development' && uniClient.debugInfo) { + const { + address: addressList, + servePort: port + } = uniClient.debugInfo; + return getServerAddr(addressList, port) + } + return Promise.resolve() + }).then(({ address, port } = {}) => { + // 设置服务地址 + if (address) { + uniClient.localAddress = address; + uniClient.localPort = port; + } else if (uniClient.debugInfo) { + const warnMethod = process.env.VUE_APP_PLATFORM === 'app-plus' ? 'error' : 'warn'; + const warn = console[warnMethod]; + // 启动时不在同一局域网且初始值为访问remote云函数,则直接切换云端。否则提示连接不到本地调试服务。 + if (uniClient.debugInfo.initialLaunchType === 'remote') { + uniClient.debugInfo.forceRemote = true; + warn('当前客户端和HBuilderX不在同一局域网下(或其他网络原因无法连接HBuilderX),uniCloud本地调试服务不对当前客户端生效。\n- 如果不使用uniCloud本地调试服务,请直接忽略此信息。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。\n- 如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试'); + } else { + warn('无法连接uniCloud本地调试服务,请检查当前客户端是否与主机在同一局域网下。\n- 如需使用uniCloud本地调试服务,请将客户端与主机连接到同一局域网下并重新运行到客户端。\n- 如果在HBuilderX开启的状态下切换过网络环境,请重启HBuilderX后再试'); + } + } + }).then(() => { + { + clearDirtyUniIdToken(); + return initStat() + } + }).then(() => { + uniClient.isReady = true; + }); + // } + + initCallFunction(uniClient); + initUploadFile(uniClient); + initDatabase(uniClient); + initCommonMethod(uniClient); + + uniClient.init = this.init; + + return uniClient + } +} + +let uniCloud$3 = new UniCloud(); + +// uni-app内{let e = {}}处理有点问题,暂时包裹一层 +(() => { + { + let defaultSpace = {}; + const providers = process.env.UNI_CLOUD_PROVIDER&&JSON.parse(process.env.UNI_CLOUD_PROVIDER)||[] + if (providers.length === 1) { + defaultSpace = providers[0]; + uniCloud$3 = uniCloud$3.init(defaultSpace); + } else { + const defaultMethodList = [ + 'auth', + 'callFunction', + 'uploadFile', + 'deleteFile', + 'getTempFileURL', + 'downloadFile', + 'database', + 'getCurrentUSerInfo' + ]; + + let spaceErrMessage; + + if (providers.length > 0) { + spaceErrMessage = '应用有多个服务空间,请通过uniCloud.init方法指定要使用的服务空间'; + } else if (process.env.RUN_BY_HBUILDERX) { + spaceErrMessage = '应用未关联服务空间,请在uniCloud目录右键关联服务空间'; + } else { + spaceErrMessage = 'uni-app cli项目内使用uniCloud需要使用HBuilderX的运行菜单运行项目,且需要在uniCloud目录关联服务空间'; + } + defaultMethodList.forEach((item) => { + uniCloud$3[item] = function () { + console.error(spaceErrMessage); + return Promise.reject( + new UniCloudError({ + code: 'SYS_ERR', + message: spaceErrMessage + }) + ) + }; + }); + } + Object.assign(uniCloud$3, { + get mixinDatacom () { + return getMixinDatacom(uniCloud$3) + } + }); + } +})(); + +var uniCloud$4 = uniCloud$3; + +module.exports = uniCloud$4; diff --git a/packages/uni-components/index.js b/packages/uni-components/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/packages/uni-components/lib/navigation-bar/navigation-bar.vue b/packages/uni-components/lib/navigation-bar/navigation-bar.vue new file mode 100644 index 0000000000000000000000000000000000000000..bce547cdb43b214a2451b973298e2973fcc1f1e2 --- /dev/null +++ b/packages/uni-components/lib/navigation-bar/navigation-bar.vue @@ -0,0 +1,159 @@ + + + diff --git a/packages/uni-components/lib/page-meta/page-meta.vue b/packages/uni-components/lib/page-meta/page-meta.vue new file mode 100644 index 0000000000000000000000000000000000000000..730e70c08a29f6e0998fbf56992f5f13b61d3d5e --- /dev/null +++ b/packages/uni-components/lib/page-meta/page-meta.vue @@ -0,0 +1,190 @@ + + diff --git a/packages/uni-components/lib/uni-match-media/uni-match-media.vue b/packages/uni-components/lib/uni-match-media/uni-match-media.vue new file mode 100644 index 0000000000000000000000000000000000000000..e1fe689dad0afed9dc80c20fc83adb9ec46925f3 --- /dev/null +++ b/packages/uni-components/lib/uni-match-media/uni-match-media.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/packages/uni-components/lib/unicloud-db/i18n/en.json b/packages/uni-components/lib/unicloud-db/i18n/en.json new file mode 100644 index 0000000000000000000000000000000000000000..60b1345c9dacb0afbc512831663198dfcf33f1f8 --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/en.json @@ -0,0 +1,6 @@ +{ + "uniCloud.component.add.success": "Success", + "uniCloud.component.update.success": "Success", + "uniCloud.component.remove.showModal.title": "Tips", + "uniCloud.component.remove.showModal.content": "是否删除该数据" +} diff --git a/packages/uni-components/lib/unicloud-db/i18n/es.json b/packages/uni-components/lib/unicloud-db/i18n/es.json new file mode 100644 index 0000000000000000000000000000000000000000..798b85fd1fb8c3f58a397a3c6ccd54cfcdb96e2e --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/es.json @@ -0,0 +1,6 @@ +{ + "uniCloud.component.add.success": "新增成功", + "uniCloud.component.update.success": "修改成功", + "uniCloud.component.remove.showModal.title": "提示", + "uniCloud.component.remove.showModal.content": "是否删除该数据" +} diff --git a/packages/uni-components/lib/unicloud-db/i18n/fr.json b/packages/uni-components/lib/unicloud-db/i18n/fr.json new file mode 100644 index 0000000000000000000000000000000000000000..798b85fd1fb8c3f58a397a3c6ccd54cfcdb96e2e --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/fr.json @@ -0,0 +1,6 @@ +{ + "uniCloud.component.add.success": "新增成功", + "uniCloud.component.update.success": "修改成功", + "uniCloud.component.remove.showModal.title": "提示", + "uniCloud.component.remove.showModal.content": "是否删除该数据" +} diff --git a/packages/uni-components/lib/unicloud-db/i18n/index.js b/packages/uni-components/lib/unicloud-db/i18n/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c0634a1ba5e8901fffb12bbb8371ab7f9226a366 --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/index.js @@ -0,0 +1,12 @@ +import en from './en.json' +import es from './es.json' +import fr from './fr.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' +export default { + en, + es, + fr, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} diff --git a/packages/uni-components/lib/unicloud-db/i18n/zh-Hans.json b/packages/uni-components/lib/unicloud-db/i18n/zh-Hans.json new file mode 100644 index 0000000000000000000000000000000000000000..798b85fd1fb8c3f58a397a3c6ccd54cfcdb96e2e --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/zh-Hans.json @@ -0,0 +1,6 @@ +{ + "uniCloud.component.add.success": "新增成功", + "uniCloud.component.update.success": "修改成功", + "uniCloud.component.remove.showModal.title": "提示", + "uniCloud.component.remove.showModal.content": "是否删除该数据" +} diff --git a/packages/uni-components/lib/unicloud-db/i18n/zh-Hant.json b/packages/uni-components/lib/unicloud-db/i18n/zh-Hant.json new file mode 100644 index 0000000000000000000000000000000000000000..1469682b649f9c912649fbbda9fc2a3993295177 --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/i18n/zh-Hant.json @@ -0,0 +1,6 @@ +{ + "uniCloud.component.add.success": "新增成功", + "uniCloud.component.update.success": "修改成功", + "uniCloud.component.remove.showModal.title": "提示", + "uniCloud.component.remove.showModal.content": "是否刪除數據" +} diff --git a/packages/uni-components/lib/unicloud-db/unicloud-db.vue b/packages/uni-components/lib/unicloud-db/unicloud-db.vue new file mode 100644 index 0000000000000000000000000000000000000000..78607f50f3ec3320da5cac8e74244f9514e8d646 --- /dev/null +++ b/packages/uni-components/lib/unicloud-db/unicloud-db.vue @@ -0,0 +1,575 @@ + + + diff --git a/packages/uni-components/package.json b/packages/uni-components/package.json index 7299f49aeabb6d55f3b5416879909730b4b7ec59..6bb673c848475218eef7f08877e3a09e3b920b9a 100644 --- a/packages/uni-components/package.json +++ b/packages/uni-components/package.json @@ -2,6 +2,7 @@ "name": "@dcloudio/uni-components", "version": "3.0.0", "description": "@dcloudio/uni-components", + "main": "index.js", "files": [ "style" ], diff --git a/packages/uni-h5/dist/uni-h5.cjs.js b/packages/uni-h5/dist/uni-h5.cjs.js index 36e6b0a0254a424400a8bcd8f7cb1ceb2b1ab5e4..a25931641483c91234adf0673d09d9af19b80044 100644 --- a/packages/uni-h5/dist/uni-h5.cjs.js +++ b/packages/uni-h5/dist/uni-h5.cjs.js @@ -653,9 +653,27 @@ function wrapperTaskApi(name, fn, protocol, options) { }); }; } +function wrapperSyncApi(name, fn, protocol, options) { + return (...args) => { + const errMsg = beforeInvokeApi(name, args, protocol, options); + if (errMsg) { + throw new Error(errMsg); + } + return fn.apply(null, args); + }; +} +function wrapperAsyncApi(name, fn, protocol, options) { + return wrapperTaskApi(name, fn, protocol, options); +} function defineTaskApi(name, fn, protocol, options) { return promisify(wrapperTaskApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options)); } +function defineSyncApi(name, fn, protocol, options) { + return wrapperSyncApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options); +} +function defineAsyncApi(name, fn, protocol, options) { + return promisify(wrapperAsyncApi(name, fn, process.env.NODE_ENV !== "production" ? protocol : void 0, options)); +} const SCHEME_RE = /^([a-z-]+:)?\/\//i; const DATA_RE = /^data:.*,.*/; function addBase(filePath) { @@ -691,6 +709,46 @@ function getRealPath(filePath) { return filePath; } const API_ON_TAB_BAR_MID_BUTTON_TAP = "onTabBarMidButtonTap"; +const API_GET_STORAGE = "getStorage"; +const GetStorageProtocol = { + key: { + type: String, + required: true + } +}; +const API_GET_STORAGE_SYNC = "getStorageSync"; +const GetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + } +]; +const API_SET_STORAGE = "setStorage"; +const SetStorageProtocol = { + key: { + type: String, + required: true + }, + data: { + required: true + } +}; +const API_SET_STORAGE_SYNC = "setStorageSync"; +const SetStorageSyncProtocol = [ + { + name: "key", + type: String, + required: true + }, + { + name: "data", + required: true + } +]; +const API_REMOVE_STORAGE = "removeStorage"; +const RemoveStorageProtocol = GetStorageProtocol; +const RemoveStorageSyncProtocol = GetStorageSyncProtocol; const API_REQUEST = "request"; const dataType = { JSON: "json" @@ -8350,10 +8408,141 @@ function parseHeaders(headers) { }); return headersObject; } +const STORAGE_KEYS = "uni-storage-keys"; +function parseValue(value) { + const types = ["object", "string", "number", "boolean", "undefined"]; + try { + const object = typeof value === "string" ? JSON.parse(value) : value; + const type = object.type; + if (types.indexOf(type) >= 0) { + const keys = Object.keys(object); + if (keys.length === 2 && "data" in object) { + if (typeof object.data === type) { + return object.data; + } + if (type === "object" && /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { + return new Date(object.data); + } + } else if (keys.length === 1) { + return ""; + } + } + } catch (error) { + } +} +const setStorageSync = /* @__PURE__ */ defineSyncApi(API_SET_STORAGE_SYNC, (key, data) => { + const type = typeof data; + const value = type === "string" ? data : JSON.stringify({ + type, + data + }); + localStorage.setItem(key, value); +}, SetStorageSyncProtocol); +const setStorage = /* @__PURE__ */ defineAsyncApi(API_SET_STORAGE, ({key, data}, {resolve, reject}) => { + try { + setStorageSync(key, data); + resolve(); + } catch (error) { + reject(error.message); + } +}, SetStorageProtocol); +function getStorageOrigin(key) { + const value = localStorage && localStorage.getItem(key); + if (typeof value !== "string") { + throw new Error("data not found"); + } + let data = value; + try { + const object = JSON.parse(value); + const result = parseValue(object); + if (result !== void 0) { + data = result; + } + } catch (error) { + } + return data; +} +const getStorageSync = /* @__PURE__ */ defineSyncApi(API_GET_STORAGE_SYNC, (key, t2) => { + try { + return getStorageOrigin(key); + } catch (error) { + return ""; + } +}, GetStorageSyncProtocol); +const getStorage = /* @__PURE__ */ defineAsyncApi(API_GET_STORAGE, ({key}, {resolve, reject}) => { + try { + const data = getStorageOrigin(key); + resolve({ + data + }); + } catch (error) { + reject(error.message); + } +}, GetStorageProtocol); +const removeStorageSync = /* @__PURE__ */ defineSyncApi(API_REMOVE_STORAGE, (key) => { + if (localStorage) { + localStorage.removeItem(key); + } +}, RemoveStorageSyncProtocol); +const removeStorage = /* @__PURE__ */ defineAsyncApi(API_REMOVE_STORAGE, ({key}, {resolve}) => { + removeStorageSync(key); + resolve(); +}, RemoveStorageProtocol); +const clearStorageSync = /* @__PURE__ */ defineSyncApi("clearStorageSync", () => { + if (localStorage) { + localStorage.clear(); + } +}); +const clearStorage = /* @__PURE__ */ defineAsyncApi("clearStorage", (_, {resolve}) => { + clearStorageSync(); + resolve(); +}); +const getStorageInfoSync = /* @__PURE__ */ defineSyncApi("getStorageInfoSync", () => { + const length = localStorage && localStorage.length || 0; + const keys = []; + let currentSize = 0; + for (let index2 = 0; index2 < length; index2++) { + const key = localStorage.key(index2); + const value = localStorage.getItem(key) || ""; + currentSize += key.length + value.length; + if (key !== STORAGE_KEYS) { + keys.push(key); + } + } + return { + keys, + currentSize: Math.ceil(currentSize * 2 / 1024), + limitSize: Number.MAX_VALUE + }; +}); +const getStorageInfo = /* @__PURE__ */ defineAsyncApi("getStorageInfo", (_, {resolve}) => { + resolve(getStorageInfoSync()); +}); +const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", () => { + { + return { + deviceId: Date.now() + "" + Math.floor(Math.random() * 1e7), + platform: "nodejs" + }; + } +}); +require("localstorage-polyfill"); +global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var api = /* @__PURE__ */ Object.freeze({ __proto__: null, [Symbol.toStringTag]: "Module", - request + request, + setStorageSync, + setStorage, + getStorageSync, + getStorage, + removeStorageSync, + removeStorage, + clearStorageSync, + clearStorage, + getStorageInfoSync, + getStorageInfo, + getSystemInfoSync }); const uni$1 = api; const UniServiceJSBridge$1 = /* @__PURE__ */ shared.extend(ServiceJSBridge, { @@ -9236,10 +9425,21 @@ exports.UniViewJSBridge = UniViewJSBridge$1; exports.Video = index$5; exports.View = index$6; exports.WebView = index$4; +exports.clearStorage = clearStorage; +exports.clearStorageSync = clearStorageSync; exports.getApp = getApp$1; exports.getCurrentPages = getCurrentPages$1; +exports.getStorage = getStorage; +exports.getStorageInfo = getStorageInfo; +exports.getStorageInfoSync = getStorageInfoSync; +exports.getStorageSync = getStorageSync; +exports.getSystemInfoSync = getSystemInfoSync; exports.plugin = index$m; +exports.removeStorage = removeStorage; +exports.removeStorageSync = removeStorageSync; exports.request = request; +exports.setStorage = setStorage; +exports.setStorageSync = setStorageSync; exports.setupApp = setupApp; exports.setupPage = setupPage; exports.uni = uni$1; diff --git a/packages/uni-h5/dist/uni-h5.es.js b/packages/uni-h5/dist/uni-h5.es.js index 4dac470cb475263054ad7d77a6a091a2fdd7b340..2904434c969bb965bbc4256c4f7ceda9cf37171b 100644 --- a/packages/uni-h5/dist/uni-h5.es.js +++ b/packages/uni-h5/dist/uni-h5.es.js @@ -2516,7 +2516,7 @@ function createNormalizeUrl(type) { return; } else if (type === API_PRELOAD_PAGE) { if (routeOptions.meta.isTabBar) { - const pages = getCurrentPages(true); + const pages = getCurrentPages(); const tabBarPagePath = routeOptions.path.substr(1); if (pages.find((page) => page.route === tabBarPagePath)) { return "tabBar page `" + tabBarPagePath + "` already exists"; diff --git a/packages/uni-h5/package.json b/packages/uni-h5/package.json index 507b5eb7d26bcd74817f60fd6aa9994a7bc231dd..a3407281006be412f71558e82599d6df42392b08 100644 --- a/packages/uni-h5/package.json +++ b/packages/uni-h5/package.json @@ -22,7 +22,9 @@ "url": "https://github.com/dcloudio/uni-app/issues" }, "dependencies": { + "localstorage-polyfill": "^1.0.1", "safe-area-insets": "^1.4.1", - "vue-router": "^4.0.6" + "vue-router": "^4.0.6", + "xmlhttprequest": "^1.8.0" } } diff --git a/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts b/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts index c8665069d1a776ed1f2b9fe9e1e37288a1491bd7..c05401b9bfa737a5596fdcdb4dbcd231d07e514b 100644 --- a/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts +++ b/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts @@ -25,6 +25,13 @@ import { export const getSystemInfoSync = defineSyncApi( 'getSystemInfoSync', () => { + if (__NODE_JS__) { + //TODO 临时搞一下配合 uniCloud 测试 + return ({ + deviceId: Date.now() + '' + Math.floor(Math.random() * 1e7), + platform: 'nodejs', + } as unknown) as UniApp.GetSystemInfoResult + } const pixelRatio = window.devicePixelRatio // 横屏时 iOS 获取的屏幕宽高颠倒,进行纠正 const screenFix = getScreenFix() diff --git a/packages/uni-h5/src/service/api/index.ts b/packages/uni-h5/src/service/api/index.ts index 1e2b69b4eb30b100287d88ed9d8e84727059c642..a15885296b255910d7b7ff637df9e39d84acf2a1 100644 --- a/packages/uni-h5/src/service/api/index.ts +++ b/packages/uni-h5/src/service/api/index.ts @@ -1,5 +1,12 @@ //#if _NODE_JS_ +// 目前这几个接口主要是 uniCloud 使用了 +// 目前采用 polyfill 解决 xhr 和 storage +/* eslint-disable no-restricted-globals */ +require('localstorage-polyfill') +global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest export * from './network/request' +export * from './storage/storage' +export * from './device/getSystemInfoSync' //#else export * from './base/canIUse' diff --git a/packages/uni-h5/vite.config.ts b/packages/uni-h5/vite.config.ts index 44aa27a1a256ece8b9e6dfe9703fa11bc4033fb7..6eadab5d2d77edf4010aa2025ed9955527d80349 100644 --- a/packages/uni-h5/vite.config.ts +++ b/packages/uni-h5/vite.config.ts @@ -47,7 +47,7 @@ if (FORMAT === 'cjs') { export default defineConfig({ root: __dirname, define: { - global: 'window', + global: FORMAT === 'cjs' ? 'global' : 'window', __DEV__: `(process.env.NODE_ENV !== 'production')`, __TEST__: false, __PLATFORM__: JSON.stringify('h5'), diff --git a/packages/uni-i18n/dist/uni-i18n.cjs.js b/packages/uni-i18n/dist/uni-i18n.cjs.js index a9a51cd1d066a80585e65db14f3d059085269c99..d67cb0d32b9004ea47042863ae4b1ea0b769ffa9 100644 --- a/packages/uni-i18n/dist/uni-i18n.cjs.js +++ b/packages/uni-i18n/dist/uni-i18n.cjs.js @@ -226,6 +226,9 @@ function initVueI18n(locale = LOCALE_EN, messages = {}, fallbackLocale = LOCALE_ if (typeof locale !== 'string') { [locale, messages] = [messages, locale]; } + if (typeof locale !== 'string') { + locale = fallbackLocale; + } const i18n = new I18n({ locale: locale || fallbackLocale, fallbackLocale, diff --git a/packages/uni-i18n/dist/uni-i18n.es.js b/packages/uni-i18n/dist/uni-i18n.es.js index 9602ad2593eefe474b4388d93b79536889a0e27c..a72729922253f8162d4b0c4f954386f1464b6f63 100644 --- a/packages/uni-i18n/dist/uni-i18n.es.js +++ b/packages/uni-i18n/dist/uni-i18n.es.js @@ -222,6 +222,9 @@ function initVueI18n(locale = LOCALE_EN, messages = {}, fallbackLocale = LOCALE_ if (typeof locale !== 'string') { [locale, messages] = [messages, locale]; } + if (typeof locale !== 'string') { + locale = fallbackLocale; + } const i18n = new I18n({ locale: locale || fallbackLocale, fallbackLocale, diff --git a/packages/uni-i18n/src/vue-i18n.ts b/packages/uni-i18n/src/vue-i18n.ts index 8ba42d66ccbc75192e5540de65114fd6837fea15..70b443f084bf231ad04ca2836707de57ac9048e7 100644 --- a/packages/uni-i18n/src/vue-i18n.ts +++ b/packages/uni-i18n/src/vue-i18n.ts @@ -38,6 +38,9 @@ export function initVueI18n( if (typeof locale !== 'string') { ;[locale, messages] = [messages as BuiltInLocale, locale as LocaleMessages] } + if (typeof locale !== 'string') { + locale = fallbackLocale + } const i18n = new I18n({ locale: locale || fallbackLocale, fallbackLocale, diff --git a/packages/uni-mp-vue/dist/vue.runtime.esm.js b/packages/uni-mp-vue/dist/vue.runtime.esm.js index 92db82528c4040b83130a13bfd63f566cfceda5b..77b43d91f026ae50d1715bdd16d2ca1c7dce7be7 100644 --- a/packages/uni-mp-vue/dist/vue.runtime.esm.js +++ b/packages/uni-mp-vue/dist/vue.runtime.esm.js @@ -2239,7 +2239,7 @@ function createAppAPI() { if (__VUE_OPTIONS_API__) { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin); - // global mixin with props/emits de-optimizes props/emits + // window mixin with props/emits de-optimizes props/emits // normalization caching. if (mixin.props || mixin.emits) { context.deopt = true; @@ -2337,7 +2337,7 @@ function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false // local registration // check instance[type] first for components with mixin or extends. resolve(instance[type] || Component[type], name) || - // global registration + // window registration resolve(instance.appContext[type], name); if (!res && maybeSelfReference) { // fallback to implicit self-reference @@ -2734,7 +2734,7 @@ function applyOptions(instance, options, deferredData = [], deferredWatch = [], shouldCacheAccess = false; callSyncHook('beforeCreate', "bc" /* BEFORE_CREATE */, options, instance, globalMixins); shouldCacheAccess = true; - // global mixins are applied first + // window mixins are applied first applyMixins(instance, globalMixins, deferredData, deferredWatch, deferredProvide); } // extending a base component... @@ -3215,7 +3215,7 @@ const PublicInstanceProxyHandlers = { return ctx[key]; } else if ( - // global properties + // window properties ((globalProperties = appContext.config.globalProperties), hasOwn(globalProperties, key))) { return globalProperties[key]; @@ -3327,7 +3327,7 @@ function createRenderContext(instance) { set: NOOP }); }); - // expose global properties + // expose window properties const { globalProperties } = instance.appContext.config; Object.keys(globalProperties).forEach(key => { Object.defineProperty(target, key, { diff --git a/packages/uni-shared/dist/uni-shared.cjs.js b/packages/uni-shared/dist/uni-shared.cjs.js index 5c20a0c59c2d7bc2d883e6fccf6a3d59040cba4c..638094f4e6741ac4201251a40996e0dd705ae078 100644 --- a/packages/uni-shared/dist/uni-shared.cjs.js +++ b/packages/uni-shared/dist/uni-shared.cjs.js @@ -192,7 +192,8 @@ function once(fn, ctx = null) { } return res; }); -} +} +const sanitise = (val) => (val && JSON.parse(JSON.stringify(val))) || val; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -295,7 +296,10 @@ const TABBAR_HEIGHT = 50; const ON_REACH_BOTTOM_DISTANCE = 50; const RESPONSIVE_MIN_WIDTH = 768; const COMPONENT_NAME_PREFIX = 'VUni'; -const PRIMARY_COLOR = '#007aff'; +const PRIMARY_COLOR = '#007aff'; +const UNI_SSR = '__uniSSR'; +const UNI_SSR_DATA = 'data'; +const UNI_SSR_GLOBAL_DATA = 'globalData'; function getEnvLocale() { const { env } = process; @@ -314,6 +318,9 @@ exports.PRIMARY_COLOR = PRIMARY_COLOR; exports.RESPONSIVE_MIN_WIDTH = RESPONSIVE_MIN_WIDTH; exports.TABBAR_HEIGHT = TABBAR_HEIGHT; exports.TAGS = TAGS; +exports.UNI_SSR = UNI_SSR; +exports.UNI_SSR_DATA = UNI_SSR_DATA; +exports.UNI_SSR_GLOBAL_DATA = UNI_SSR_GLOBAL_DATA; exports.addFont = addFont; exports.debounce = debounce; exports.decode = decode; @@ -331,6 +338,7 @@ exports.parseQuery = parseQuery; exports.passive = passive; exports.plusReady = plusReady; exports.removeLeadingSlash = removeLeadingSlash; +exports.sanitise = sanitise; exports.scrollTo = scrollTo; exports.stringifyQuery = stringifyQuery; exports.updateElementStyle = updateElementStyle; diff --git a/packages/uni-shared/dist/uni-shared.d.ts b/packages/uni-shared/dist/uni-shared.d.ts index 396d131fd5796b49ef8683bacf64815f120e5d84..fccad2ab446672287aae78bc02a6809db85f6f1e 100644 --- a/packages/uni-shared/dist/uni-shared.d.ts +++ b/packages/uni-shared/dist/uni-shared.d.ts @@ -76,6 +76,8 @@ export declare function removeLeadingSlash(str: string): string; export declare const RESPONSIVE_MIN_WIDTH = 768; +export declare const sanitise: (val: unknown) => any; + declare function scrollTo_2(scrollTop: number | string, duration: number): void; export { scrollTo_2 as scrollTo } @@ -85,6 +87,12 @@ export declare const TABBAR_HEIGHT = 50; export declare const TAGS: string[]; +export declare const UNI_SSR = "__uniSSR"; + +export declare const UNI_SSR_DATA = "data"; + +export declare const UNI_SSR_GLOBAL_DATA = "globalData"; + export declare function updateElementStyle(element: HTMLElement, styles: Partial): void; export { } diff --git a/packages/uni-shared/dist/uni-shared.es.js b/packages/uni-shared/dist/uni-shared.es.js index bd0137cf204149328da34809193e047ebf5caa8c..4785dc7cccae2ebd632037bcbf0230274a21fb6a 100644 --- a/packages/uni-shared/dist/uni-shared.es.js +++ b/packages/uni-shared/dist/uni-shared.es.js @@ -188,7 +188,8 @@ function once(fn, ctx = null) { } return res; }); -} +} +const sanitise = (val) => (val && JSON.parse(JSON.stringify(val))) || val; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -291,7 +292,10 @@ const TABBAR_HEIGHT = 50; const ON_REACH_BOTTOM_DISTANCE = 50; const RESPONSIVE_MIN_WIDTH = 768; const COMPONENT_NAME_PREFIX = 'VUni'; -const PRIMARY_COLOR = '#007aff'; +const PRIMARY_COLOR = '#007aff'; +const UNI_SSR = '__uniSSR'; +const UNI_SSR_DATA = 'data'; +const UNI_SSR_GLOBAL_DATA = 'globalData'; function getEnvLocale() { const { env } = process; @@ -299,4 +303,4 @@ function getEnvLocale() { return (lang && lang.replace(/[.:].*/, '')) || 'en'; } -export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getEnvLocale, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, scrollTo, stringifyQuery, updateElementStyle }; +export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, addFont, debounce, decode, decodedQuery, getEnvLocale, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, sanitise, scrollTo, stringifyQuery, updateElementStyle }; diff --git a/packages/uni-shared/src/constants.ts b/packages/uni-shared/src/constants.ts index 3fd8275234966aec6cedfe73be8b6d02fe829a68..5dccd5768edc0e41faeebafba42aae3344e9f71d 100644 --- a/packages/uni-shared/src/constants.ts +++ b/packages/uni-shared/src/constants.ts @@ -6,3 +6,7 @@ export const RESPONSIVE_MIN_WIDTH = 768 export const COMPONENT_NAME_PREFIX = 'VUni' export const PRIMARY_COLOR = '#007aff' + +export const UNI_SSR = '__uniSSR' +export const UNI_SSR_DATA = 'data' +export const UNI_SSR_GLOBAL_DATA = 'globalData' diff --git a/packages/uni-shared/src/utils.ts b/packages/uni-shared/src/utils.ts index d9935c9ada9be02723933bd94e85037c7a7d027a..e9505e72329079fb94aaae7dbfd969d17da0940c 100644 --- a/packages/uni-shared/src/utils.ts +++ b/packages/uni-shared/src/utils.ts @@ -36,3 +36,6 @@ export function once any>( return res }) as T } + +export const sanitise = (val: unknown) => + (val && JSON.parse(JSON.stringify(val))) || val diff --git a/packages/vite-plugin-uni/lib/ssr/render.js b/packages/vite-plugin-uni/lib/ssr/render.js index cea99ebafd4d5788a695811ea3ffe682ff6f5aae..46935ae9aec2040f5f6a87900270ec591e847239 100644 --- a/packages/vite-plugin-uni/lib/ssr/render.js +++ b/packages/vite-plugin-uni/lib/ssr/render.js @@ -1,3 +1,4 @@ +import { UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA } from '@dcloudio/uni-shared' import { renderToString } from '@vue/server-renderer' let AppInstance @@ -27,7 +28,16 @@ export async function render(url, manifest = {}) { // which we can then use to determine what files need to be preloaded for this // request. const preloadLinks = renderPreloadLinks(ctx.modules, manifest) - return [html, preloadLinks] + // the SSR context + const __uniSSR = ctx[UNI_SSR] || (ctx[UNI_SSR] = {}) + if(!__uniSSR[UNI_SSR_DATA]){ + __uniSSR[UNI_SSR_DATA] = {} + } + if(!__uniSSR[UNI_SSR_GLOBAL_DATA]){ + __uniSSR[UNI_SSR_GLOBAL_DATA] = {} + } + const appContext = renderAppContext(ctx) + return [html, preloadLinks, appContext] } function renderPreloadLinks(modules, manifest) { @@ -57,3 +67,7 @@ function renderPreloadLink(file) { return '' } } + +function renderAppContext(ctx){ + return `` +} diff --git a/packages/vite-plugin-uni/package.json b/packages/vite-plugin-uni/package.json index ff64570de6f5fcc46b362c39f92b0a881bb6271e..5bda93c7931fdcf78bc5b90c5409ecfd4254d344 100644 --- a/packages/vite-plugin-uni/package.json +++ b/packages/vite-plugin-uni/package.json @@ -24,6 +24,7 @@ }, "license": "Apache-2.0", "dependencies": { + "@vue/compiler-sfc": "^3.0.11", "@rollup/pluginutils": "^4.1.0", "autoprefixer": "^10.2.5", "cac": "^6.7.3", @@ -33,7 +34,6 @@ "express": "^4.17.1", "fs-extra": "^9.0.1", "jsonc-parser": "^3.0.0", - "magic-string": "^0.25.7", "mime": "^2.5.2", "module-alias": "^2.2.2", "postcss-selector-parser": "^6.0.4", @@ -50,8 +50,7 @@ "@types/express": "^4.17.11", "@types/mime": "^2.0.3", "@types/module-alias": "^2.0.0", - "@types/sass": "^1.16.0", - "@vue/compiler-sfc": "^3.0.11" + "@types/sass": "^1.16.0" }, "uni-app": { "compilerVersion": "3.1.2" diff --git a/packages/vite-plugin-uni/src/cli/server.ts b/packages/vite-plugin-uni/src/cli/server.ts index fb7a79471395897c383ce4e84bf6ef5517b92d16..bfbe8376c4c213925c78b5336e3fd2da0515e52e 100644 --- a/packages/vite-plugin-uni/src/cli/server.ts +++ b/packages/vite-plugin-uni/src/cli/server.ts @@ -59,11 +59,12 @@ export async function createSSRServer(options: CliOptions & ServerOptions) { await vite.ssrLoadModule(resolveMainPathOnce(process.env.UNI_INPUT_DIR)) ).render - const [appHtml, preloadLinks] = await render(url) + const [appHtml, preloadLinks, appContext] = await render(url) const html = template .replace(``, preloadLinks) .replace(``, appHtml) + .replace(``, appContext) res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { vite && vite.ssrFixStacktrace(e) diff --git a/packages/vite-plugin-uni/src/configResolved/plugins/index.ts b/packages/vite-plugin-uni/src/configResolved/plugins/index.ts index dbbae0b5c8fd20e65af7c1b78a59e95b825344f2..77a3542dfd1bcd2cdc31e979ee08198a63e85419 100644 --- a/packages/vite-plugin-uni/src/configResolved/plugins/index.ts +++ b/packages/vite-plugin-uni/src/configResolved/plugins/index.ts @@ -18,6 +18,7 @@ import { uniStaticPlugin } from './static' import { uniCssScopedPlugin } from './cssScoped' import { uniRenderjsPlugin } from './renderjs' import { uniPreVuePlugin } from './preVue' +import { uniSSRPlugin } from './ssr' const debugPlugin = debug('vite:uni:plugin') @@ -137,6 +138,12 @@ export function initPlugins( } } + addPlugin( + plugins, + uniSSRPlugin(extend({ exclude: [...COMMON_EXCLUDE] }, options)), + 'vite:vue' + ) + addPlugin( plugins, uniEasycomPlugin(extend(uniEasycomPluginOptions, options)), diff --git a/packages/vite-plugin-uni/src/configResolved/plugins/inject.ts b/packages/vite-plugin-uni/src/configResolved/plugins/inject.ts index 1959fc6cdd8c87cf16a9fd45d01e318da80681a8..91ff12b5b14107c44bd8284b8353f226fe438b72 100644 --- a/packages/vite-plugin-uni/src/configResolved/plugins/inject.ts +++ b/packages/vite-plugin-uni/src/configResolved/plugins/inject.ts @@ -2,15 +2,7 @@ import path, { sep } from 'path' import debug from 'debug' import { Plugin } from 'vite' -import { - BaseNode, - Program, - Property, - Identifier, - MemberExpression, - MethodDefinition, - ExportSpecifier, -} from 'estree' +import { BaseNode, Program, Identifier } from 'estree' import { attachScopes, @@ -22,7 +14,7 @@ import { AcornNode } from 'rollup' import { walk } from 'estree-walker' -import MagicString from 'magic-string' +import { MagicString } from '@vue/compiler-sfc' import { EXTNAME_JS, @@ -32,6 +24,8 @@ import { import { UniPluginFilterOptions } from '.' +import { isProperty, isReference, isMemberExpression } from '../../utils' + interface Scope { parent: Scope contains: (name: string) => boolean @@ -231,39 +225,6 @@ export function uniInjectPlugin(options: InjectOptions): Plugin { const escape = (str: string) => str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') -const isProperty = (node: BaseNode): node is Property => - node.type === 'Property' - -const isIdentifier = (node: BaseNode): node is Identifier => - node.type === 'Identifier' - -const isMemberExpression = (node: BaseNode): node is MemberExpression => - node.type === 'MemberExpression' - -const isMethodDefinition = (node: BaseNode): node is MethodDefinition => - node.type === 'MethodDefinition' - -const isExportSpecifier = (node: BaseNode): node is ExportSpecifier => - node.type === 'ExportSpecifier' - -const isReference = (node: BaseNode, parent: BaseNode): boolean => { - if (isMemberExpression(node)) { - return !node.computed && isReference(node.object, node) - } - if (isIdentifier(node)) { - if (isMemberExpression(parent)) - return parent.computed || node === parent.object - // `bar` in { bar: foo } - if (isProperty(parent) && node !== parent.value) return false - // `bar` in `class Foo { bar () {...} }` - if (isMethodDefinition(parent)) return false - // `bar` in `export { foo as bar }` - if (isExportSpecifier(parent) && node !== parent.local) return false - return true - } - return false -} - const flatten = (startNode: BaseNode) => { const parts = [] let node = startNode diff --git a/packages/vite-plugin-uni/src/configResolved/plugins/ssr.ts b/packages/vite-plugin-uni/src/configResolved/plugins/ssr.ts new file mode 100644 index 0000000000000000000000000000000000000000..d76929a08a0555d1b5c7bfcfacde2adbf839df4f --- /dev/null +++ b/packages/vite-plugin-uni/src/configResolved/plugins/ssr.ts @@ -0,0 +1,64 @@ +import debug from 'debug' +import crypto from 'crypto' +import { Plugin } from 'vite' + +import { walk } from 'estree-walker' + +import { CallExpression } from 'estree' +import { createFilter } from '@rollup/pluginutils' +import { UniPluginFilterOptions } from '.' +import { isIdentifier, isCallExpression, isMemberExpression } from '../../utils' +import { MagicString } from '@vue/compiler-sfc' + +const debugSSR = debug('vite:uni:ssr') + +const KEYED_FUNC_RE = /(ssrRef|shallowSsrRef)/ + +export function uniSSRPlugin(options: UniPluginFilterOptions): Plugin { + const filter = createFilter(options.include, options.exclude) + return { + name: 'vite:uni-ssr', + transform(code, id) { + if (!filter(id)) return null + if (!KEYED_FUNC_RE.test(code)) { + return code + } + debugSSR('try', id) + const ast = this.parse(code) + const s = new MagicString(code) + walk(ast, { + enter(node) { + if (!isCallExpression(node)) { + return + } + const { callee, arguments: args } = node as CallExpression + if (args.length !== 1) { + return + } + const name = isIdentifier(callee) + ? callee.name + : isMemberExpression(callee) && isIdentifier(callee.property) + ? callee.property.name + : '' + if (name !== 'ssrRef' && name !== 'shallowSsrRef') { + return + } + const { end } = (node as unknown) as { end: number } + const key = id + '-' + (node as any).end + debugSSR(key, name) + s.appendLeft(end - 1, ", '" + createKey(`${id}-${end}`) + "'") + }, + }) + return { + code: s.toString(), + map: s.generateMap().toString(), + } + }, + } +} + +function createKey(source: string) { + const hash = crypto.createHash('md5') + hash.update(source) + return hash.digest('base64').toString() +} diff --git a/packages/vite-plugin-uni/src/utils/ast.ts b/packages/vite-plugin-uni/src/utils/ast.ts new file mode 100644 index 0000000000000000000000000000000000000000..1efcefcb1c4b24dfd602380ea762fa596f2500ed --- /dev/null +++ b/packages/vite-plugin-uni/src/utils/ast.ts @@ -0,0 +1,54 @@ +import { + Literal, + BaseNode, + Property, + Identifier, + CallExpression, + MemberExpression, + MethodDefinition, + ExportSpecifier, +} from 'estree' + +export const isProperty = (node: BaseNode): node is Property => + node.type === 'Property' + +export const isIdentifier = (node: BaseNode): node is Identifier => + node.type === 'Identifier' + +export const isCallExpression = (node: BaseNode): node is CallExpression => + node.type === 'CallExpression' + +export const isMemberExpression = (node: BaseNode): node is MemberExpression => + node.type === 'MemberExpression' + +export const isMethodDefinition = (node: BaseNode): node is MethodDefinition => + node.type === 'MethodDefinition' + +export const isExportSpecifier = (node: BaseNode): node is ExportSpecifier => + node.type === 'ExportSpecifier' + +export const isReference = (node: BaseNode, parent: BaseNode): boolean => { + if (isMemberExpression(node)) { + return !node.computed && isReference(node.object, node) + } + if (isIdentifier(node)) { + if (isMemberExpression(parent)) + return parent.computed || node === parent.object + // `bar` in { bar: foo } + if (isProperty(parent) && node !== parent.value) return false + // `bar` in `class Foo { bar () {...} }` + if (isMethodDefinition(parent)) return false + // `bar` in `export { foo as bar }` + if (isExportSpecifier(parent) && node !== parent.local) return false + return true + } + return false +} + +export function createLiteral(value: string) { + return { + type: 'Literal', + value, + raw: `'${value}'`, + } as Literal +} diff --git a/packages/vite-plugin-uni/src/utils/easycom.ts b/packages/vite-plugin-uni/src/utils/easycom.ts index c51ab4861a493653c715b7303f504293c8092a9a..d8723dc67fb37bbf6d60e7d6196b19e0ab2268f4 100644 --- a/packages/vite-plugin-uni/src/utils/easycom.ts +++ b/packages/vite-plugin-uni/src/utils/easycom.ts @@ -40,6 +40,10 @@ function clearEasycom() { export const initEasycomsOnce = once( (inputDir: string, platform: UniApp.PLATFORM) => { + const buildInComponentsDir = path.resolve( + require.resolve('@dcloudio/uni-components'), + '../lib' + ) const componentsDir = path.resolve(inputDir, 'components') const uniModulesDir = path.resolve(inputDir, 'uni_modules') const initEasycomOptions = (pagesJson?: UniApp.PagesJson) => { @@ -48,8 +52,12 @@ export const initEasycomsOnce = once( const easycomOptions: EasycomOption = { dirs: easycom && easycom.autoscan === false - ? [] // 禁止自动扫描 - : [componentsDir, ...initUniModulesEasycomDirs(uniModulesDir)], + ? [buildInComponentsDir] // 禁止自动扫描 + : [ + buildInComponentsDir, + componentsDir, + ...initUniModulesEasycomDirs(uniModulesDir), + ], rootDir: inputDir, autoscan: !!(easycom && easycom.autoscan), custom: (easycom && easycom.custom) || {}, diff --git a/packages/vite-plugin-uni/src/utils/index.ts b/packages/vite-plugin-uni/src/utils/index.ts index 7b9cb7b656de284da4385e01da494f04c318aef0..32b21aaae29c526cbd2312ec41f89905b7e48d1b 100644 --- a/packages/vite-plugin-uni/src/utils/index.ts +++ b/packages/vite-plugin-uni/src/utils/index.ts @@ -1,3 +1,4 @@ +export * from './ast' export * from './ssr' export * from './filter' export * from './features' diff --git a/rollup.config.js b/rollup.config.js index 282d17b2cfb7c7f03bd8f7e82b783ae770289d2b..e414850fe17da5de00989708651ddcca185fa0f0 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -115,8 +115,10 @@ function createAliasPlugin(buildOptions) { function createReplacePlugin(buildOptions, format) { const replacements = { + global: format === 'cjs' ? 'global' : 'window', __DEV__: `(process.env.NODE_ENV !== 'production')`, __TEST__: false, + __PLATFORM__: JSON.stringify('h5'), __NODE_JS__: format === 'cjs', } if (buildOptions.replacements) { diff --git a/yarn.lock b/yarn.lock index 104c46d9fb290c704be89b98bbc0f8580231607b..f1d3c981f4ed0d9959a5729a0dda467bb30035db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1803,9 +1803,9 @@ camelcase@^6.0.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001219: - version "1.0.30001222" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001222.tgz#2789b8487282cbbe1700924f53951303d28086a9" - integrity sha512-rPmwUK0YMjfMlZVmH6nVB5U3YJ5Wnx3vmT5lnRO3nIKO8bJ+TRWMbGuuiSugDJqESy/lz+1hSrlQEagCtoOAWQ== + version "1.0.30001223" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz#39b49ff0bfb3ee3587000d2f66c47addc6e14443" + integrity sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA== capture-exit@^2.0.0: version "2.0.0" @@ -3102,9 +3102,9 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: is-glob "^4.0.1" glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -4430,6 +4430,11 @@ loader-utils@^1.1.0: emojis-list "^3.0.0" json5 "^1.0.1" +localstorage-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/localstorage-polyfill/-/localstorage-polyfill-1.0.1.tgz#4b3083d4bc51d23b4158537e66816137413fd31a" + integrity sha1-SzCD1LxR0jtBWFN+ZoFhN0E/0xo= + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -4447,11 +4452,6 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - lodash.get@^4.0.0: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -6230,13 +6230,12 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^6.0.4: - version "6.6.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.6.0.tgz#905654b79df98d9e9a973de1dd58682532c40e8e" - integrity sha512-iZMtp5tUvcnAdtHpZTWLPF0M7AgiQsURR2DwmxnJwSy8I3+cY+ozzVvYha3BOLG2TB+L0CqjIz+91htuj6yCXg== + version "6.7.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.0.tgz#26274751f0ee099c547f6cb91d3eff0d61d155b2" + integrity sha512-SAM+5p6V99gYiiy2gT5ArdzgM1dLDed0nkrWmG6Fry/bUS/m9x83BwpJUOf1Qj/x2qJd+thL6IkIx7qPGRxqBw== dependencies: ajv "^8.0.1" lodash.clonedeep "^4.5.0" - lodash.flatten "^4.4.0" lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.0" @@ -6785,6 +6784,11 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmlhttprequest@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + xregexp@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-3.1.0.tgz#14d8461e0bdd38224bfee5039a0898fc42fcd336"