提交 83df53d9 编写于 作者: fxy060608's avatar fxy060608

feat: add types for protocol

上级 fad9df4a
......@@ -41,6 +41,7 @@ declare namespace UniApp {
uploadFile: number
}
tabBar?: TabBarOptions
subPackages?: { root: string }[]
}
interface UniRoute {
......
import { isFunction, isPlainObject } from '@vue/shared'
import { ApiOptions } from '../../protocols/type'
import { tryCatch } from './catch'
......@@ -114,7 +113,7 @@ export function normalizeErrMsg(errMsg: string, name: string) {
export function createAsyncApiCallback(
name: string,
args: Record<string, any> = {},
{ beforeAll, beforeSuccess }: ApiOptions = {}
{ beforeAll, beforeSuccess }: ApiOptions<any> = {}
) {
if (!isPlainObject(args)) {
args = {}
......
import { extend, isString, isPlainObject } from '@vue/shared'
import { ApiOptions, ApiProtocols } from '../../protocols/type'
import { API_TYPE_ON_PROTOCOLS, validateProtocols } from '../protocol'
import {
invokeCallback,
......@@ -11,51 +10,11 @@ import {
removeKeepAliveApiCallback,
} from './callback'
import { promisify } from './promise'
interface AsyncMethodOptionLike {
success?: (...args: any[]) => void
}
type PromisifySuccessResult<P, R> = P extends {
success: any
}
? void
: P extends { fail: any }
? void
: P extends { complete: any }
? void
: Promise<R>
type TaskApiLike = (args: any) => any
type AsyncApiLike = (args: any) => Promise<unknown> | void
type AsyncApiOptions<T extends AsyncApiLike> = Parameters<T>[0]
type AsyncApiRes<T extends AsyncMethodOptionLike> = Parameters<
Exclude<T['success'], undefined>
>[0]
type AsyncApiRequired<T extends AsyncMethodOptionLike> = <P extends T>(
args: P
) => PromisifySuccessResult<P, AsyncApiRes<T>>
type AsyncApiOptional<T extends AsyncMethodOptionLike> = <P extends T>(
args?: P
) => PromisifySuccessResult<P, AsyncApiRes<T>>
interface AsyncApiOptionalOptions {
success?: any
fail?: any
complete?: any
}
type AsyncApi<
T extends AsyncMethodOptionLike
> = AsyncApiOptionalOptions extends T
? AsyncApiOptional<T>
: AsyncApiRequired<T>
function formatApiArgs(args: any[], options?: ApiOptions) {
function formatApiArgs<T extends ApiLike>(
args: any[],
options?: ApiOptions<T>
) {
const params = args[0]
if (
!options ||
......@@ -65,7 +24,7 @@ function formatApiArgs(args: any[], options?: ApiOptions) {
}
const formatArgs = options.formatArgs!
Object.keys(formatArgs).forEach((name) => {
formatArgs[name](args[0][name], params)
formatArgs[name]!(args[0][name], params)
})
return args
}
......@@ -103,7 +62,11 @@ function invokeFail(id: number, name: string, err: string) {
return invokeCallback(id, { errMsg: name + ':fail' + (err ? ' ' + err : '') })
}
function wrapperTaskApi(name: string, fn: Function, options?: ApiOptions) {
function wrapperTaskApi<T extends ApiLike>(
name: string,
fn: Function,
options?: ApiOptions<T>
) {
return (args: Record<string, any>) => {
const id = createAsyncApiCallback(name, args, options)
return fn(args, {
......@@ -117,22 +80,23 @@ function wrapperSyncApi(fn: Function) {
return (...args: any[]) => fn.apply(null, args)
}
function wrapperAsyncApi(name: string, fn: Function, options?: ApiOptions) {
function wrapperAsyncApi<T extends ApiLike>(
name: string,
fn: Function,
options?: ApiOptions<T>
) {
return wrapperTaskApi(name, fn, options)
}
function wrapperApi(
function wrapperApi<T extends ApiLike>(
fn: Function,
name?: string,
protocol?: ApiProtocols,
options?: ApiOptions
protocol?: ApiProtocols<T>,
options?: ApiOptions<T>
) {
return function (...args: any[]) {
if (__DEV__) {
const errMsg = validateProtocols(name!, args, protocol)
if (isString(errMsg)) {
return errMsg
}
validateProtocols(name!, args, protocol)
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args)
......@@ -140,14 +104,14 @@ function wrapperApi(
return errMsg
}
}
return fn.apply(null, formatApiArgs(args, options))
return fn.apply(null, formatApiArgs<T>(args, options))
}
}
export function defineOnApi<T extends Function>(
export function defineOnApi<T extends ApiLike>(
name: string,
fn: () => void,
options?: ApiOptions
options?: ApiOptions<T>
) {
return (wrapperApi(
wrapperOnApi(name, fn),
......@@ -157,10 +121,10 @@ export function defineOnApi<T extends Function>(
) as unknown) as T
}
export function defineOffApi<T extends Function>(
export function defineOffApi<T extends ApiLike>(
name: string,
fn: () => void,
options?: ApiOptions
options?: ApiOptions<T>
) {
return (wrapperApi(
wrapperOffApi(name, fn),
......@@ -179,8 +143,8 @@ export function defineTaskApi<T extends TaskApiLike, P = AsyncApiOptions<T>>(
reject: (err?: string) => void
}
) => ReturnType<T>,
protocol?: ApiProtocols,
options?: ApiOptions
protocol?: ApiProtocols<T>,
options?: ApiOptions<T>
) {
return (promisify(
wrapperApi(
......@@ -192,13 +156,13 @@ export function defineTaskApi<T extends TaskApiLike, P = AsyncApiOptions<T>>(
) as unknown) as T
}
export function defineSyncApi<T extends Function>(
export function defineSyncApi<T extends ApiLike>(
name: string,
fn: T,
protocol?: ApiProtocols,
options?: ApiOptions
protocol?: ApiProtocols<T>,
options?: ApiOptions<T>
) {
return (wrapperApi(
return (wrapperApi<T>(
wrapperSyncApi(fn),
name,
__DEV__ ? protocol : undefined,
......@@ -215,8 +179,8 @@ export function defineAsyncApi<T extends AsyncApiLike, P = AsyncApiOptions<T>>(
reject: (err?: string) => void
}
) => void,
protocol?: ApiProtocols,
options?: ApiOptions
protocol?: ApiProtocols<T>,
options?: ApiOptions<T>
) {
return promisify(
wrapperApi(
......
......@@ -6,28 +6,22 @@ import {
isObject,
toRawType,
capitalize,
isPlainObject,
} from '@vue/shared'
import {
ApiProtocol,
ApiProtocols,
ProtocolConstructor,
ProtocolOptions,
} from '../protocols/type'
export const CHOOSE_SIZE_TYPES = ['original', 'compressed']
export const CHOOSE_SOURCE_TYPES = ['album', 'camera']
export const HTTP_METHODS = {
OPTIONS: 'OPTIONS',
GET: 'GET',
HEAD: 'HEAD',
POST: 'POST',
PUT: 'PUT',
DELETE: 'DELETE',
TRACE: 'TRACE',
CONNECT: 'CONNECT',
}
export const HTTP_METHODS = [
'GET',
'OPTIONS',
'HEAD',
'POST',
'PUT',
'DELETE',
'TRACE',
'CONNECT',
]
export const API_TYPE_ON_PROTOCOLS = [
{
......@@ -37,7 +31,17 @@ export const API_TYPE_ON_PROTOCOLS = [
},
]
export function normalizeStrArray(strArr: string[], optionalVal: string[]) {
export function elemInArray(str: string, arr: string[]) {
if (arr.indexOf(str) === -1) {
return arr[0]
}
return str
}
export function elemsInArray(
strArr: string[] | string | undefined,
optionalVal: string[]
) {
if (
!isArray(strArr) ||
strArr.length === 0 ||
......@@ -49,29 +53,23 @@ export function normalizeStrArray(strArr: string[], optionalVal: string[]) {
}
function validateProtocolFail(name: string, msg: string) {
const errMsg = `${name}:fail ${msg}`
if (!__TEST__) {
console.error(errMsg)
}
return {
errMsg,
}
console.warn(`${name}:fail ${msg}`)
}
function validateProtocol(
name: string,
data: Record<string, any>,
protocol?: ApiProtocol
protocol?: ApiProtocol<any>
) {
for (const key in protocol) {
const errMsg = validateProp(
key,
data[key],
protocol[key],
protocol[key as keyof typeof protocol],
!hasOwn(data, key)
)
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg)
validateProtocolFail(name, errMsg)
}
}
}
......@@ -79,47 +77,46 @@ function validateProtocol(
export function validateProtocols(
name: string,
args: any[],
protocol?: ApiProtocols
protocol?: ApiProtocols<any>
) {
if (!protocol) {
return
}
if (isArray(protocol)) {
const len = protocol.length
const argsLen = args.length
for (let i = 0; i < len; i++) {
const opts = protocol[i]
const data = Object.create(null)
if (argsLen > i) {
data[opts.name!] = args[i]
}
const errMsg = validateProtocol(name, data, { [opts.name!]: opts })
if (errMsg) {
return errMsg
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol)
}
const len = protocol.length
const argsLen = args.length
for (let i = 0; i < len; i++) {
const opts = protocol[i]
const data = Object.create(null)
if (argsLen > i) {
data[opts.name!] = args[i]
}
return
validateProtocol(name, data, { [opts.name!]: opts })
}
return validateProtocol(name, args[0] || Object.create(null), protocol)
}
function validateProp(
name: string,
value: unknown,
prop: ProtocolOptions,
prop: ProtocolOptions | ProtocolType<any>,
isAbsent: boolean
) {
const { type, required, validator } = prop
if (!isPlainObject(prop)) {
prop = { type: prop }
}
const { type, required, validator } = prop as ProtocolOptions
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"'
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false
const types = isArray(type) ? type : [type]
const expectedTypes = []
......
import { ProtocolOptions } from '../type'
export const API_BASE64_TO_ARRAY_BUFFER = 'base64ToArrayBuffer'
export const API_ARRAY_BUFFER_TO_BASE64 = 'arrayBufferToBase64'
export type API_TYPE_BASE64_TO_ARRAY_BUFFER = typeof uni.base64ToArrayBuffer
export const Base64ToArrayBufferProtocol: ProtocolOptions<String>[] = [
{
name: 'base64',
......@@ -10,6 +8,8 @@ export const Base64ToArrayBufferProtocol: ProtocolOptions<String>[] = [
},
]
export const API_ARRAY_BUFFER_TO_BASE64 = 'arrayBufferToBase64'
export type API_TYPE_ARRAY_BUFFER_TO_BASE64 = typeof uni.arrayBufferToBase64
export const ArrayBufferToBase64Protocol: ProtocolOptions<
ArrayBuffer | Uint8Array
>[] = [
......
import { ProtocolOptions } from '../type'
export const API_CAN_I_USE = 'canIUse'
export type API_TYPE_CAN_I_USE = typeof uni.canIUse
export const CanIUseProtocol: ProtocolOptions<String>[] = [
{
name: 'schema',
......
import { ProtocolOptions } from '../type'
export const $on: ProtocolOptions<String | Array<String> | Function>[] = [
{
name: 'event',
......
import { ProtocolOptions } from '../type'
export const API_ADD_INTERCEPTOR = 'addInterceptor'
export const API_REMOVE_INTERCEPTOR = 'removeInterceptor'
export const AddInterceptorProtocol: ProtocolOptions<String | Object>[] = [
......
import { ProtocolOptions } from '../type'
export const API_UPX2PX = 'upx2px'
export type API_TYPE_UPX2PX = typeof uni.upx2px
export const Upx2pxProtocol: ProtocolOptions<Number | String>[] = [
{
name: 'upx',
......
import { extend } from '@vue/shared'
import { ApiProtocol, ApiOptions, Data } from '../type'
function getInt(name: string) {
return function (value: number, params: Data) {
function getInt(name: string, defaultValue?: number) {
return function (value: number | undefined, params: any) {
if (value) {
params[name] = Math.round(value)
} else if (typeof defaultValue !== 'undefined') {
params[name] = defaultValue
}
}
}
export const CanvasGetImageDataOptions: ApiOptions = {
const formatWidth = getInt('width')
const formatHeight = getInt('height')
export const API_CANVAS_GET_IMAGE_DATA = 'canvasGetImageData'
export type API_TYPE_CANVAS_GET_IMAGE_DATA = typeof uni.canvasGetImageData
export const CanvasGetImageDataOptions: ApiOptions<API_TYPE_CANVAS_GET_IMAGE_DATA> = {
formatArgs: {
x: getInt('x'),
y: getInt('y'),
width: getInt('width'),
height: getInt('height'),
width: formatWidth,
height: formatHeight,
},
}
export const CanvasGetImageDataProtocol: ApiProtocol = {
export const CanvasGetImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_GET_IMAGE_DATA> = {
canvasId: {
type: String,
required: true,
......@@ -41,97 +45,67 @@ export const CanvasGetImageDataProtocol: ApiProtocol = {
required: true,
},
}
export const API_CANVAS_PUT_IMAGE_DATA = 'canvasPutImageData'
export type API_TYPE_CANVAS_PUT_IMAGE_DATA = typeof uni.canvasPutImageData
export const CanvasPutImageDataOptions = CanvasGetImageDataOptions
export const CanvasPutImageDataProtocol: ApiProtocol = {
canvasId: {
type: String,
required: true,
},
data: {
type: Uint8ClampedArray,
required: true,
},
x: {
type: Number,
required: true,
},
y: {
type: Number,
required: true,
},
width: {
type: Number,
required: true,
},
height: {
type: Number,
export const CanvasPutImageDataProtocol: ApiProtocol<API_TYPE_CANVAS_PUT_IMAGE_DATA> = extend(
{
data: {
type: Uint8ClampedArray as any,
required: true,
},
},
}
CanvasGetImageDataProtocol
)
const fileTypes = {
PNG: 'png',
JPG: 'jpg',
JPEG: 'jpg',
}
export const API_CANVAS_TO_TEMP_FILE_PATH = 'canvasToTempFilePath'
export type API_TYPE_CANVAS_TO_TEMP_FILE_PATH = typeof uni.canvasToTempFilePath
export const CanvasToTempFilePathOptions: ApiOptions = {
formatArgs: extend(
{
destWidth: getInt('destWidth'),
destHeight: getInt('destHeight'),
fileType(value: string, params: Data) {
value = (value || '').toUpperCase()
let type = fileTypes[value as keyof typeof fileTypes]
if (!type) {
type = fileTypes.PNG
}
params.fileType = type
},
quality(value: number, params: Data) {
value = Math.floor(value)
params.quality = value > 0 && value < 1 ? value : 1
},
export const CanvasToTempFilePathOptions: ApiOptions<API_TYPE_CANVAS_TO_TEMP_FILE_PATH> = {
formatArgs: {
x: getInt('x', 0),
y: getInt('y', 0),
width: formatWidth,
height: formatHeight,
destWidth: getInt('destWidth'),
destHeight: getInt('destHeight'),
fileType(value, params) {
value = (value || '').toUpperCase()
let type = fileTypes[value as keyof typeof fileTypes]
if (!type) {
type = fileTypes.PNG
}
params.fileType = type
},
quality(value, params) {
params.quality = value && value > 0 && value < 1 ? value : 1
},
CanvasGetImageDataOptions.formatArgs
),
},
}
export const CanvasToTempFilePathProtocol: ApiProtocol = {
x: {
type: Number,
default: 0,
},
y: {
type: Number,
default: 0,
},
width: {
type: Number,
},
height: {
type: Number,
},
destWidth: {
type: Number,
},
destHeight: {
type: Number,
},
export const CanvasToTempFilePathProtocol: ApiProtocol<API_TYPE_CANVAS_TO_TEMP_FILE_PATH> = {
x: Number,
y: Number,
width: Number,
height: Number,
destWidth: Number,
destHeight: Number,
canvasId: {
type: String,
required: true,
},
fileType: {
type: String,
},
quality: {
type: Number,
},
fileType: String,
quality: Number,
}
export const DrawCanvasProtocol: ApiProtocol = {
export const DrawCanvasProtocol: ApiProtocol<any> = {
canvasId: {
type: String,
required: true,
......
import { ProtocolOptions } from '../type'
const validator: ProtocolOptions<String>[] = [
{
name: 'id',
......@@ -7,10 +5,20 @@ const validator: ProtocolOptions<String>[] = [
required: true,
},
]
export const API_CREATE_AUDIO_CONTEXT = 'createAudioContext'
export type API_TYPE_CREATE_AUDIO_CONTEXT = typeof uni.createAudioContext
export const CreateAudioContextProtocol = validator
export const API_CREATE_VIDEO_CONTEXT = 'createVideoContext'
export type API_TYPE_CREATE_VIDEO_CONTEXT = typeof uni.createVideoContext
export const CreateVideoContextProtocol = validator
export const API_CREATE_MAP_CONTEXT = 'createMapContext'
export type API_TYPE_CREATE_MAP_CONTEXT = typeof uni.createMapContext
export const CreateMapContextProtocol = validator
export const API_CREATE_CANVAS_CONTEXT = 'createCanvasContext'
export type API_TYPE_CREATE_CANVAS_CONTEXT = typeof uni.createCanvasContext
export const CreateCanvasContextProtocol: ProtocolOptions<String | Object>[] = [
{
name: 'canvasId',
......
import { ApiProtocol } from '../type'
export const API_MAKE_PHONE_CALL = 'makePhoneCall'
export type API_TYPE_MAKE_PHONE_CALL = typeof uni.makePhoneCall
export const MakePhoneCallProtocol: ApiProtocol = {
phoneNumber: {
type: String,
required: true,
validator(phoneNumber: string) {
if (!phoneNumber) {
return 'parameter error: parameter.phoneNumber should not be empty String;'
}
},
},
export const MakePhoneCallProtocol: ApiProtocol<API_TYPE_MAKE_PHONE_CALL> = {
phoneNumber: String,
}
import { ApiOptions } from '../type'
export const SetClipboardDataOptions: ApiOptions = {
export const API_SET_CLIPBOARD_DATA = 'setClipboardData'
export type API_TYPE_SET_CLIPBOARD_DATA = typeof uni.setClipboardData
export const SetClipboardDataOptions: ApiOptions<API_TYPE_SET_CLIPBOARD_DATA> = {
beforeSuccess() {
uni.showToast({
title: '内容已复制',
......
import { ApiProtocol } from '../type'
export const API_OPEN_DOCUMENT = 'openDocument'
export type API_TYPE_OPEN_DOCUMENT = typeof uni.openDocument
export const OpenDocumentProtocol: ApiProtocol = {
export const OpenDocumentProtocol: ApiProtocol<API_TYPE_OPEN_DOCUMENT> = {
filePath: {
type: String,
required: true,
},
fileType: {
type: String,
},
fileType: String,
}
import { ApiProtocol } from '../type'
export const ChooseLocationProtocol: ApiProtocol = {
keyword: {
type: String,
},
export const API_CHOOSE_LOCATION = 'chooseLocation'
export type API_TYPE_CHOOSE_LOCATION = typeof uni.chooseLocation
export const ChooseLocationProtocol: ApiProtocol<API_TYPE_CHOOSE_LOCATION> = {
keyword: String,
}
import { ApiProtocol, ApiOptions } from '../type'
export const API_GET_LOCATION = 'getLocation'
export type API_TYPE_GET_LOCATION = typeof uni.getLocation
const coordTypes = {
WGS84: 'WGS84',
GCJ02: 'GCJ02',
}
const coordTypes = ['WGS84', 'GCJ02']
export const GetLocationOptions: ApiOptions = {
export const GetLocationOptions: ApiOptions<API_TYPE_GET_LOCATION> = {
formatArgs: {
type(value, params) {
value = (value || '').toUpperCase()
let type = coordTypes[value as keyof typeof coordTypes]
if (!type) {
type = coordTypes.WGS84
if (coordTypes.indexOf(value) === -1) {
params.type = coordTypes[0]
} else {
params.type = value
}
params.type = type
},
altitude(value, params) {
params.altitude = value ? value : false
},
},
}
export const GetLocationProtocol: ApiProtocol = {
type: {
type: String,
default: coordTypes.WGS84,
},
altitude: {
type: Boolean,
default: false,
},
export const GetLocationProtocol: ApiProtocol<API_TYPE_GET_LOCATION> = {
type: String,
altitude: Boolean,
}
import { ApiProtocol, ApiOptions } from '../type'
export const API_OPEN_LOCATION = 'openLocation'
export type API_TYPE_OPEN_LOCATION = typeof uni.openLocation
export const OpenLocationOptions: ApiOptions = {
export const OpenLocationOptions: ApiOptions<API_TYPE_OPEN_LOCATION> = {
formatArgs: {
type(value, params) {
value = Math.floor(value)
scale(value, params) {
value = Math.floor(value!)
params.scale = value >= 5 && value <= 18 ? value : 18
},
},
}
export const OpenLocationProtocol: ApiProtocol = {
export const OpenLocationProtocol: ApiProtocol<API_TYPE_OPEN_LOCATION> = {
latitude: {
type: Number,
required: true,
......@@ -18,14 +19,7 @@ export const OpenLocationProtocol: ApiProtocol = {
type: Number,
required: true,
},
scale: {
type: Number,
default: 18,
},
name: {
type: String,
},
address: {
type: String,
},
scale: Number,
name: String,
address: String,
}
import { ApiOptions, ApiProtocol } from '../type'
import {
CHOOSE_SIZE_TYPES,
CHOOSE_SOURCE_TYPES,
normalizeStrArray,
elemsInArray,
} from '../../helpers/protocol'
export const API_CHOOSE_IMAGE = 'chooseImage'
export type API_TYPE_CHOOSE_IMAGE = typeof uni.chooseImage
export const ChooseImageOptions: ApiOptions = {
export const ChooseImageOptions: ApiOptions<API_TYPE_CHOOSE_IMAGE> = {
formatArgs: {
count(value, params) {
if (value <= 0) {
if (value! <= 0) {
params.count = 9
}
},
sizeType(sizeType, params) {
params.sizeType = normalizeStrArray(sizeType, CHOOSE_SIZE_TYPES)
params.sizeType = elemsInArray(sizeType, CHOOSE_SIZE_TYPES)
},
sourceType(sourceType, params) {
params.sourceType = normalizeStrArray(sourceType, CHOOSE_SOURCE_TYPES)
params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES)
},
},
}
export const ChooseImageProtocol: ApiProtocol = {
count: {
type: Number,
default: 9,
},
sizeType: {
type: [Array, String],
default: CHOOSE_SIZE_TYPES,
},
sourceType: {
type: Array,
default: CHOOSE_SOURCE_TYPES,
},
export const ChooseImageProtocol: ApiProtocol<API_TYPE_CHOOSE_IMAGE> = {
count: Number,
sizeType: [Array, String],
sourceType: Array,
}
import { CHOOSE_SOURCE_TYPES, normalizeStrArray } from '../../helpers/protocol'
import { ApiOptions, ApiProtocol } from '../type'
import { CHOOSE_SOURCE_TYPES, elemsInArray } from '../../helpers/protocol'
export const API_CHOOSE_VIDEO = 'chooseVideo'
export type API_TYPE_CHOOSE_VIDEO = typeof uni.chooseVideo
export const ChooseVideoOptions: ApiOptions = {
export const ChooseVideoOptions: ApiOptions<API_TYPE_CHOOSE_VIDEO> = {
formatArgs: {
sourceType(sourceType, params) {
params.sourceType = normalizeStrArray(sourceType, CHOOSE_SOURCE_TYPES)
params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES)
},
},
}
export const ChooseVideoProtocol: ApiProtocol = {
sourceType: {
type: Array,
default: CHOOSE_SOURCE_TYPES,
},
export const ChooseVideoProtocol: ApiProtocol<API_TYPE_CHOOSE_VIDEO> = {
sourceType: Array,
}
import { getRealPath } from '@dcloudio/uni-platform'
import { ApiOptions, ApiProtocol } from '../type'
export const API_GET_IMAGE_INFO = 'getImageInfo'
export type API_TYPE_GET_IMAGE_INFO = typeof uni.getImageInfo
export const GetImageInfoOptions: ApiOptions = {
export const GetImageInfoOptions: ApiOptions<API_TYPE_GET_IMAGE_INFO> = {
formatArgs: {
src(src, params) {
params.src = getRealPath(src)
......@@ -11,7 +11,7 @@ export const GetImageInfoOptions: ApiOptions = {
},
}
export const GetImageInfoProtocol: ApiProtocol = {
export const GetImageInfoProtocol: ApiProtocol<API_TYPE_GET_IMAGE_INFO> = {
src: {
type: String,
required: true,
......
import { ApiOptions, ApiProtocol } from '../type'
export const DownloadFileOptions: ApiOptions = {
export const API_DOWNLOAD_FILE = 'downloadFile'
export type API_TYPE_DOWNLOAD_FILE = typeof uni.downloadFile
export const DownloadFileOptions: ApiOptions<API_TYPE_DOWNLOAD_FILE> = {
formatArgs: {
header(value, params) {
params.header = value || {}
......@@ -8,12 +8,10 @@ export const DownloadFileOptions: ApiOptions = {
},
}
export const DownloadFileProtocol: ApiProtocol = {
export const DownloadFileProtocol: ApiProtocol<API_TYPE_DOWNLOAD_FILE> = {
url: {
type: String,
required: true,
},
header: {
type: Object,
},
header: Object,
}
import { hasOwn, isPlainObject } from '@vue/shared'
import { ApiOptions, ApiProtocol } from '../type'
import { elemInArray, HTTP_METHODS } from '../../helpers/protocol'
export const API_REQUEST = 'request'
const METHOD = [
'GET',
'OPTIONS',
'HEAD',
'POST',
'PUT',
'DELETE',
'TRACE',
'CONNECT',
]
const DEFAULT_METHOD = 'GET'
export type API_TYPE_REQUEST = typeof uni.request
const dataType = {
JSON: 'json',
......@@ -54,9 +42,9 @@ function stringifyQuery(url: string, data: Record<string, any>) {
return url + (query ? '?' + query : '') + (hash ? '#' + hash : '')
}
export const RequestProtocol: ApiProtocol = {
export const RequestProtocol: ApiProtocol<API_TYPE_REQUEST> = {
method: {
type: String,
type: String as any,
},
data: {
type: [Object, String, Array, ArrayBuffer],
......@@ -79,20 +67,20 @@ export const RequestProtocol: ApiProtocol = {
},
}
export const RequestOptions: ApiOptions = {
export const RequestOptions: ApiOptions<API_TYPE_REQUEST> = {
formatArgs: {
method(value, params) {
params.method = (value || '').toUpperCase()
if (METHOD.indexOf(params.method) === -1) {
params.method = DEFAULT_METHOD
}
params.method = elemInArray(
(value || '').toUpperCase(),
HTTP_METHODS
) as any
},
data(value, params) {
params.data = value || ''
},
url(value, params) {
if (
params.method === DEFAULT_METHOD &&
params.method === HTTP_METHODS[0] &&
isPlainObject(params.data) &&
Object.keys(params.data).length
) {
......@@ -102,7 +90,7 @@ export const RequestOptions: ApiOptions = {
},
header(value, params) {
const header = (params.header = value || {})
if (params.method !== DEFAULT_METHOD) {
if (params.method !== HTTP_METHODS[0]) {
if (
!Object.keys(header).find(
(key) => key.toLowerCase() === 'content-type'
......
import { HTTP_METHODS } from '../../helpers/protocol'
import { ApiOptions, ApiProtocol } from '../type'
export const ConnectSocketOptions: ApiOptions = {
import { elemInArray, HTTP_METHODS } from '../../helpers/protocol'
export const API_CONNECT_SOCKET = 'connectSocket'
export type API_TYPE_CONNECT_SOCKET = typeof uni.connectSocket
export const ConnectSocketOptions: ApiOptions<API_TYPE_CONNECT_SOCKET> = {
formatArgs: {
header(value, params) {
params.header = value || {}
},
method(value, params) {
value = (value || '').toUpperCase()
if (!HTTP_METHODS[value as keyof typeof HTTP_METHODS]) {
value = HTTP_METHODS.GET
}
params.method = value
params.method = elemInArray(
(value || '').toUpperCase(),
HTTP_METHODS
) as any
},
protocols(protocols, params) {
if (typeof protocols === 'string') {
......@@ -21,7 +20,7 @@ export const ConnectSocketOptions: ApiOptions = {
},
}
export const ConnectSocketProtocol: ApiProtocol = {
export const ConnectSocketProtocol: ApiProtocol<API_TYPE_CONNECT_SOCKET> = {
url: {
type: String,
required: true,
......@@ -29,23 +28,20 @@ export const ConnectSocketProtocol: ApiProtocol = {
header: {
type: Object,
},
method: {
type: String,
},
protocols: {
type: [Array, String], // 微信文档虽然写的是数组,但是可以正常传递字符串
},
method: String as any,
protocols: [Array, String] as any,
}
export const sendSocketMessage = {
data: {
type: [String, ArrayBuffer],
},
export const API_SEND_SOCKET_MESSAGE = 'sendSocketMessage'
export type API_TYPE_SEND_SOCKET_MESSAGE = typeof uni.sendSocketMessage
export const sendSocketMessage: ApiProtocol<API_TYPE_SEND_SOCKET_MESSAGE> = {
data: [String, ArrayBuffer],
}
export const closeSocket = {
code: {
type: Number,
},
reason: {
type: String,
},
export const API_CLOSE_SOCKET = 'closeSocket'
export type API_TYPE_CLOSE_SOCKET = typeof uni.closeSocket
export const closeSocket: ApiProtocol<API_TYPE_CLOSE_SOCKET> = {
code: Number,
reason: String,
}
import { ApiProtocol } from '../type'
export const GetProviderProtocol: ApiProtocol = {
export const API_GET_PROVIDER = 'getProvider'
export type API_TYPE_GET_PROVIDER = typeof uni.getProvider
export const GetProviderProtocol: ApiProtocol<API_TYPE_GET_PROVIDER> = {
service: {
type: String,
type: String as any,
required: true,
},
}
import { ApiProtocol } from '../type'
import { isArray } from '@vue/shared'
export const LoadSubPackageProtocol: ApiProtocol = {
export const API_LOAD_SUB_PACKAGE = 'loadSubPackage'
// export type API_TYPE_LOAD_SUB_PACKAGE = typeof uni.loadSubPackage
export const LoadSubPackageProtocol: ApiProtocol<any> = {
root: {
type: String,
required: true,
validator(value) {
},
}
export const LoadSubPackageOptions: ApiOptions<any> = {
formatArgs: {
root(value: string | undefined) {
const subPackages = __uniConfig.subPackages
if (!Array.isArray(subPackages) || subPackages.length === 0) {
if (!isArray(subPackages) || subPackages.length === 0) {
return 'no subPackages'
}
if (!subPackages.find((subPackage) => subPackage.root === value)) {
......
import { extend } from '@vue/shared'
import { getRealRoute } from '@dcloudio/uni-core'
import { ApiOptions, ApiProtocol } from '../type'
import { encodeQueryString } from './encodeQueryString'
const ANIMATION_IN = [
......@@ -27,7 +26,7 @@ const ANIMATION_OUT = [
'none',
]
const BaseRouteProtocol: ApiProtocol = {
const BaseRouteProtocol: ApiProtocol<API_TYPE_NAVIGATE_TO> = {
url: {
type: String,
required: true,
......@@ -35,21 +34,26 @@ const BaseRouteProtocol: ApiProtocol = {
}
export const API_NAVIGATE_TO = 'navigateTo'
export type API_TYPE_NAVIGATE_TO = typeof uni.navigateTo
export const API_REDIRECT_TO = 'redirectTo'
export type API_TYPE_REDIRECT_TO = typeof uni.redirectTo
export const API_RE_LAUNCH = 'reLaunch'
export type API_TYPE_RE_LAUNCH = typeof uni.reLaunch
export const API_SWITCH_TAB = 'switchTab'
export type API_TYPE_SWITCH_TAB = typeof uni.switchTab
export const API_NAVIGATE_BACK = 'navigateBack'
export type API_TYPE_NAVIGATE_BACK = typeof uni.navigateBack
export const API_PRELOAD_PAGE = 'preloadPage'
export type API_TYPE_PRELOAD_PAGE = typeof uni.preloadPage
export const API_UN_PRELOAD_PAGE = 'unPreloadPage'
export const NavigateToProtocol: ApiProtocol = extend(
export type API_TYPE_UN_PRELOAD_PAGE = typeof uni.unPreloadPage
export const NavigateToProtocol: ApiProtocol<API_TYPE_NAVIGATE_TO> = extend(
{},
BaseRouteProtocol,
createAnimationProtocol(ANIMATION_IN)
)
export const NavigateBackProtocol: ApiProtocol = extend(
export const NavigateBackProtocol: ApiProtocol<API_TYPE_NAVIGATE_BACK> = extend(
{
delta: {
type: Number,
......@@ -68,24 +72,24 @@ export const PreloadPageProtocol = BaseRouteProtocol
export const UnPreloadPageProtocol = BaseRouteProtocol
export const NavigateToOptions: ApiOptions = /*#__PURE__*/ createRouteOptions(
export const NavigateToOptions: ApiOptions<API_TYPE_NAVIGATE_TO> = /*#__PURE__*/ createRouteOptions(
API_NAVIGATE_TO
)
export const RedirectToOptions: ApiOptions = /*#__PURE__*/ createRouteOptions(
export const RedirectToOptions: ApiOptions<API_TYPE_REDIRECT_TO> = /*#__PURE__*/ createRouteOptions(
API_REDIRECT_TO
)
export const ReLaunchOptions: ApiOptions = /*#__PURE__*/ createRouteOptions(
export const ReLaunchOptions: ApiOptions<API_TYPE_RE_LAUNCH> = /*#__PURE__*/ createRouteOptions(
API_RE_LAUNCH
)
export const SwitchTabOptions: ApiOptions = /*#__PURE__*/ createRouteOptions(
export const SwitchTabOptions: ApiOptions<API_TYPE_SWITCH_TAB> = /*#__PURE__*/ createRouteOptions(
API_SWITCH_TAB
)
export const NavigateBackOptions: ApiOptions = {
export const NavigateBackOptions: ApiOptions<API_TYPE_NAVIGATE_BACK> = {
formatArgs: {
delta(delta, params) {
delta = parseInt(delta) || 1
params.delta = Math.min(getCurrentPages().length - 1, delta)
delta(value, params) {
value = parseInt(value + '') || 1
params.delta = Math.min(getCurrentPages().length - 1, value)
},
},
}
......@@ -93,8 +97,8 @@ export const NavigateBackOptions: ApiOptions = {
function createAnimationProtocol(animationTypes: string[]) {
return {
animationType: {
type: String,
validator(type: string) {
type: String as any,
validator(type?: string) {
if (type && animationTypes.indexOf(type) === -1) {
return (
'`' +
......@@ -118,7 +122,7 @@ function beforeRoute() {
navigatorLock = ''
}
function createRouteOptions(type: string): ApiOptions {
function createRouteOptions(type: string): ApiOptions<API_TYPE_NAVIGATE_TO> {
return {
formatArgs: {
url: createNormalizeUrl(type),
......
import { ApiProtocol, ProtocolOptions } from '../type'
export const GetStorageProtocol: ApiProtocol = {
export const API_GET_STORAGE = 'getStorage'
export type API_TYPE_GET_STORAGE = typeof uni.getStorage
export const GetStorageProtocol: ApiProtocol<API_TYPE_GET_STORAGE> = {
key: {
type: String,
required: true,
},
}
export const API_GET_STORAGE_SYNC = 'getStorageSync'
export type API_TYPE_GET_STORAGE_SYNC = typeof uni.getStorageSync
export const GetStorageSyncProtocol: ProtocolOptions[] = [
{
name: 'key',
......@@ -14,8 +15,9 @@ export const GetStorageSyncProtocol: ProtocolOptions[] = [
required: true,
},
]
export const SetStorageProtocol: ApiProtocol = {
export const API_SET_STORAGE = 'setStorage'
export type API_TYPE_SET_STORAGE = typeof uni.setStorage
export const SetStorageProtocol: ApiProtocol<API_TYPE_SET_STORAGE> = {
key: {
type: String,
required: true,
......@@ -24,7 +26,8 @@ export const SetStorageProtocol: ApiProtocol = {
required: true,
},
}
export const API_SET_STORAGE_SYNC = 'setStorageSync'
export type API_TYPE_SET_STORAGE_SYNC = typeof uni.setStorageSync
export const SetStorageSyncProtocol: ProtocolOptions[] = [
{
name: 'key',
......@@ -36,6 +39,10 @@ export const SetStorageSyncProtocol: ProtocolOptions[] = [
required: true,
},
]
export const API_REMOVE_STORAGE = 'removeStorage'
export type API_TYPE_REMOVE_STORAGE = typeof uni.removeStorage
export const RemoveStorageProtocol = GetStorageProtocol
export const API_REMOVE_STORAGE_SYNC = 'removeStorageSync'
export type API_TYPE_REMOVE_STORAGE_SYNC = typeof uni.removeStorageSync
export const RemoveStorageSyncProtocol = GetStorageSyncProtocol
export type Data = Record<string, unknown>
type DefaultFactory<T> = (protocols: Data) => T | null | undefined
export type ProtocolConstructor<T = any> =
| { new (...args: any[]): T & object }
| { (): T }
| ProtocolMethod<T>
type ProtocolMethod<T, TConstructor = any> = T extends (...args: any) => any
? { new (): TConstructor; (): T; readonly prototype: TConstructor }
: never
type ProtocolType<T> = ProtocolConstructor<T> | ProtocolConstructor<T>[]
type ApiArgsValidator = (value: any, params: Record<string, any>) => void
export interface ApiProtocol {
[name: string]: ProtocolOptions
}
export type ApiProtocols = ApiProtocol | ProtocolOptions[]
export interface ApiOptions {
beforeInvoke?: (args: unknown) => boolean | void | string
beforeAll?: (res: unknown) => void
beforeSuccess?: (res: unknown) => void
formatArgs?: {
[name: string]: ApiArgsValidator
}
}
export interface ProtocolOptions<T = any, D = T> {
name?: string
type?: ProtocolType<T> | true | null
required?: boolean
default?: D | DefaultFactory<D> | null | undefined | object
validator?(value: any): boolean | undefined | string
}
import { ApiProtocol } from '../type'
export const LoadFontFaceProtocol: ApiProtocol = {
export const API_LOAD_FONT_FACE = 'loadFontFace'
export type API_TYPE_LOAD_FONT_FACE = typeof uni.loadFontFace
export const LoadFontFaceProtocol: ApiProtocol<API_TYPE_LOAD_FONT_FACE> = {
family: {
type: String,
required: true,
......@@ -9,7 +9,5 @@ export const LoadFontFaceProtocol: ApiProtocol = {
type: String,
required: true,
},
desc: {
type: Object,
},
desc: Object,
}
import { ApiOptions, ApiProtocol } from '../type'
const FRONT_COLORS = ['#ffffff', '#000000']
export const SetNavigationBarColorOptions: ApiOptions = {
export const API_SET_NAVIGATION_BAR_COLOR = 'setNavigationBarColor'
export type API_TYPE_SET_NAVIGATION_BAR_COLOR = typeof uni.setNavigationBarColor
export const SetNavigationBarColorOptions: ApiOptions<API_TYPE_SET_NAVIGATION_BAR_COLOR> = {
formatArgs: {
animation(animation = {}, params) {
animation(animation, params) {
if (!animation) {
animation = { duration: 0, timingFunc: 'linear' }
}
params.animation = {
duration: animation.duration || 0,
timingFunc: animation.timingFunc || 'linear',
......@@ -13,12 +15,12 @@ export const SetNavigationBarColorOptions: ApiOptions = {
},
}
export const SetNavigationBarColorProtocol: ApiProtocol = {
export const SetNavigationBarColorProtocol: ApiProtocol<API_TYPE_SET_NAVIGATION_BAR_COLOR> = {
frontColor: {
type: String,
required: true,
validator(frontColor) {
if (FRONT_COLORS.indexOf(frontColor) === -1) {
if (FRONT_COLORS.indexOf(frontColor!) === -1) {
return `invalid frontColor "${frontColor}"`
}
},
......@@ -27,20 +29,19 @@ export const SetNavigationBarColorProtocol: ApiProtocol = {
type: String,
required: true,
},
animation: {
type: Object,
default() {
return {
duration: 0,
timingFunc: 'linear',
}
},
},
animation: Object,
}
export const SetNavigationBarTitleProtocol: ApiProtocol = {
export const API_SET_NAVIGATION_BAR_TITLE = 'setNavigationBarTitle'
export type API_TYPE_SET_NAVIGATION_BAR_TITLE = typeof uni.setNavigationBarTitle
export const SetNavigationBarTitleProtocol: ApiProtocol<API_TYPE_SET_NAVIGATION_BAR_TITLE> = {
title: {
type: String,
required: true,
},
}
export const API_SHOW_NAVIGATION_BAR_LOADING = 'showNavigationBarLoading'
export type API_TYPE_SHOW_NAVIGATION_BAR_LOADING = typeof uni.showNavigationBarLoading
export const API_HIDE_NAVIGATION_BAR_LOADING = 'hideNavigationBarLoading'
export type API_TYPE_HIDE_NAVIGATION_BAR_LOADING = typeof uni.hideNavigationBarLoading
import { ApiProtocol } from '../type'
import { hasOwn } from '@vue/shared'
export const PageScrollToProtocol: ApiProtocol = {
export const API_PAGE_SCROLL_TO = 'pageScrollTo'
export type API_TYPE_PAGE_SCROLL_TO = typeof uni.pageScrollTo
export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = {
scrollTop: {
type: Number,
required: true,
},
duration: {
type: Number,
default: 300,
},
}
const DEFAULT_DURATION = 400
export const PageScrollToOptions: ApiOptions<API_TYPE_PAGE_SCROLL_TO> = {
formatArgs: {
duration(value, params) {
if (!hasOwn(params, 'duration')) {
return (params.duration = DEFAULT_DURATION)
}
value = parseInt(value + '')
if (isNaN(value)) {
value = DEFAULT_DURATION
} else {
value = Math.max(0, value)
}
params.duration = value
},
},
}
......@@ -4,16 +4,14 @@ import { getRealPath } from '@dcloudio/uni-platform'
import { getCurrentPageMeta } from '@dcloudio/uni-core'
import { removeLeadingSlash } from '@dcloudio/uni-shared'
import { ApiOptions, ApiProtocol } from '../type'
const IndexProtocol: ApiProtocol = {
const IndexProtocol: ApiProtocol<API_TYPE_SET_TAB_BAR_ITEM> = {
index: {
type: Number,
required: true,
},
}
const IndexOptions: ApiOptions = {
const IndexOptions: ApiOptions<API_TYPE_REMOVE_TAB_BAR_BADGE> = {
beforeInvoke() {
const pageMeta = getCurrentPageMeta()
if (pageMeta && !pageMeta.isTabBar) {
......@@ -28,26 +26,19 @@ const IndexOptions: ApiOptions = {
},
},
}
export const SetTabBarItemProtocol: ApiProtocol = extend(
export const API_SET_TAB_BAR_ITEM = 'setTabBarItem'
export type API_TYPE_SET_TAB_BAR_ITEM = typeof uni.setTabBarItem
export const SetTabBarItemProtocol: ApiProtocol<API_TYPE_SET_TAB_BAR_ITEM> = extend(
{
text: {
type: String,
},
iconPath: {
type: String,
},
selectedIconPath: {
type: String,
},
pagePath: {
type: String,
},
text: String,
iconPath: String,
selectedIconPath: String,
pagePath: String,
},
IndexProtocol
)
export const SetTabBarItemOptions: ApiOptions = {
export const SetTabBarItemOptions: ApiOptions<API_TYPE_SET_TAB_BAR_ITEM> = {
beforeInvoke: IndexOptions.beforeInvoke,
formatArgs: extend(
{
......@@ -56,33 +47,22 @@ export const SetTabBarItemOptions: ApiOptions = {
params.pagePath = removeLeadingSlash(value)
}
},
} as ApiOptions['formatArgs'],
} as ApiOptions<API_TYPE_SET_TAB_BAR_ITEM>['formatArgs'],
IndexOptions.formatArgs
),
}
export const SetTabBarStyleProtocol: ApiProtocol = {
color: {
type: String,
},
selectedColor: {
type: String,
},
backgroundColor: {
type: String,
},
backgroundImage: {
type: String,
},
backgroundRepeat: {
type: String,
},
borderStyle: {
type: String,
},
export const API_SET_TAB_BAR_STYLE = 'setTabBarStyle'
export type API_TYPE_SET_TAB_BAR_STYLE = typeof uni.setTabBarStyle
export const SetTabBarStyleProtocol: ApiProtocol<API_TYPE_SET_TAB_BAR_STYLE> = {
color: String,
selectedColor: String,
backgroundColor: String,
backgroundImage: String,
backgroundRepeat: String as any,
borderStyle: String,
}
const GRADIENT_RE = /^(linear|radial)-gradient\(.+?\);?$/
export const SetTabBarStyleOptions: ApiOptions = {
export const SetTabBarStyleOptions: ApiOptions<API_TYPE_SET_TAB_BAR_STYLE> = {
beforeInvoke: IndexOptions.beforeInvoke,
formatArgs: {
backgroundImage(value, params) {
......@@ -97,24 +77,35 @@ export const SetTabBarStyleOptions: ApiOptions = {
},
},
}
export const HideTabBarProtocol: ApiProtocol = {
animation: {
type: Boolean,
default: false,
},
export const API_HIDE_TAB_BAR = 'hideTabBar'
export type API_TYPE_HIDE_TAB_BAR = typeof uni.hideTabBar
export const HideTabBarProtocol: ApiProtocol<API_TYPE_HIDE_TAB_BAR> = {
animation: Boolean,
}
export const ShowTabBarProtocol: ApiProtocol = HideTabBarProtocol
export const HideTabBarRedDotProtocol: ApiProtocol = IndexProtocol
export const HideTabBarRedDotOptions: ApiOptions = IndexOptions
export const API_SHOW_TAB_BAR = 'showTabBar'
export type API_TYPE_SHOW_TAB_BAR = typeof uni.showTabBar
// TODO uni.showTabBar 的 animation 应该是可选,
export const ShowTabBarProtocol: ApiProtocol<API_TYPE_HIDE_TAB_BAR> = HideTabBarProtocol
export const ShowTabBarRedDotProtocol: ApiProtocol = IndexProtocol
export const ShowTabBarRedDotOptions: ApiOptions = IndexOptions
export const API_HIDE_TAB_BAR_RED_DOT = 'hideTabBarRedDot'
export type API_TYPE_HIDE_TAB_BAR_RED_DOT = typeof uni.hideTabBarRedDot
export const HideTabBarRedDotProtocol: ApiProtocol<API_TYPE_HIDE_TAB_BAR_RED_DOT> = IndexProtocol
export const HideTabBarRedDotOptions: ApiOptions<API_TYPE_HIDE_TAB_BAR_RED_DOT> = IndexOptions
export const RemoveTabBarBadgeProtocol: ApiProtocol = IndexProtocol
export const RemoveTabBarBadgeOptions: ApiOptions = IndexOptions
export const API_SHOW_TAB_BAR_RED_DOT = 'showTabBarRedDot'
export type API_TYPE_SHOW_TAB_BAR_RED_DOT = typeof uni.showTabBarRedDot
export const ShowTabBarRedDotProtocol: ApiProtocol<API_TYPE_SHOW_TAB_BAR_RED_DOT> = IndexProtocol
export const ShowTabBarRedDotOptions: ApiOptions<API_TYPE_SHOW_TAB_BAR_RED_DOT> = IndexOptions
export const SetTabBarBadgeProtocol: ApiProtocol = extend(
export const API_REMOVE_TAB_BAR_BADGE = 'removeTabBarBadge'
export type API_TYPE_REMOVE_TAB_BAR_BADGE = typeof uni.removeTabBarBadge
export const RemoveTabBarBadgeProtocol: ApiProtocol<API_TYPE_REMOVE_TAB_BAR_BADGE> = IndexProtocol
export const RemoveTabBarBadgeOptions: ApiOptions<API_TYPE_REMOVE_TAB_BAR_BADGE> = IndexOptions
export const API_SET_TAB_BAR_BADGE = 'setTabBarBadge'
export type API_TYPE_SET_TAB_BAR_BADGE = typeof uni.setTabBarBadge
export const SetTabBarBadgeProtocol: ApiProtocol<API_TYPE_SET_TAB_BAR_BADGE> = extend(
{
text: {
type: String,
......@@ -123,8 +114,7 @@ export const SetTabBarBadgeProtocol: ApiProtocol = extend(
},
IndexProtocol
)
export const SetTabBarBadgeOptions: ApiOptions = {
export const SetTabBarBadgeOptions: ApiOptions<API_TYPE_SET_TAB_BAR_BADGE> = {
beforeInvoke: IndexOptions.beforeInvoke,
formatArgs: extend(
{
......@@ -133,7 +123,7 @@ export const SetTabBarBadgeOptions: ApiOptions = {
params.text = '...'
}
},
} as ApiOptions['formatArgs'],
} as ApiOptions<API_TYPE_SET_TAB_BAR_BADGE>['formatArgs'],
IndexOptions.formatArgs
),
}
......@@ -8,11 +8,11 @@ import {
ArrayBufferToBase64Protocol,
API_BASE64_TO_ARRAY_BUFFER,
API_ARRAY_BUFFER_TO_BASE64,
API_TYPE_BASE64_TO_ARRAY_BUFFER,
API_TYPE_ARRAY_BUFFER_TO_BASE64,
} from '../../protocols/base/base64'
export const base64ToArrayBuffer = defineSyncApi<
typeof uni.base64ToArrayBuffer
>(
export const base64ToArrayBuffer = defineSyncApi<API_TYPE_BASE64_TO_ARRAY_BUFFER>(
API_BASE64_TO_ARRAY_BUFFER,
(base64) => {
return decode(base64) as ArrayBuffer
......@@ -20,9 +20,7 @@ export const base64ToArrayBuffer = defineSyncApi<
Base64ToArrayBufferProtocol
)
export const arrayBufferToBase64 = defineSyncApi<
typeof uni.arrayBufferToBase64
>(
export const arrayBufferToBase64 = defineSyncApi<API_TYPE_ARRAY_BUFFER_TO_BASE64>(
API_ARRAY_BUFFER_TO_BASE64,
(arrayBuffer) => {
return encode(arrayBuffer) as string
......
import { getBaseSystemInfo } from '@dcloudio/uni-platform'
import { defineSyncApi } from '../../helpers/api'
import { API_UPX2PX, Upx2pxProtocol } from '../../protocols/base/upx2px'
import {
API_TYPE_UPX2PX,
API_UPX2PX,
Upx2pxProtocol,
} from '../../protocols/base/upx2px'
const EPS = 1e-4
const BASE_DEVICE_WIDTH = 750
......@@ -15,7 +19,7 @@ function checkDeviceWidth() {
isIOS = platform === 'ios'
}
export const upx2px = defineSyncApi<typeof uni.upx2px>(
export const upx2px = defineSyncApi<API_TYPE_UPX2PX>(
API_UPX2PX,
(number, newDeviceWidth?: number) => {
if (deviceWidth === 0) {
......
import { ComponentPublicInstance } from 'vue'
import { getCurrentPageVm } from '@dcloudio/uni-core'
import { operateVideoPlayer } from '@dcloudio/uni-platform'
import { defineSyncApi } from '../../helpers/api'
import {
API_CREATE_VIDEO_CONTEXT,
API_TYPE_CREATE_VIDEO_CONTEXT,
} from '../../protocols/context/context'
const RATES = [0.5, 0.8, 1.0, 1.25, 1.5, 2.0]
......@@ -24,7 +29,7 @@ export class VideoContext {
operateVideoPlayer(this.id, this.vm, 'stop')
}
seek(position: number) {
seek(position?: number) {
operateVideoPlayer(this.id, this.vm, 'seek', {
position,
})
......@@ -62,12 +67,12 @@ export class VideoContext {
}
}
export function createVideoContext(
id: string,
context: ComponentPublicInstance
) {
if (context) {
return new VideoContext(id, context)
export const createVideoContext = defineSyncApi<API_TYPE_CREATE_VIDEO_CONTEXT>(
API_CREATE_VIDEO_CONTEXT,
(id, context) => {
if (context) {
return new VideoContext(id, context) as any
}
return new VideoContext(id, getCurrentPageVm()!) as any
}
return new VideoContext(id, getCurrentPageVm()!)
}
)
type Data = Record<string, unknown>
type ProtocolConstructor<T = any> =
| { new (...args: any[]): T & object }
| { (): T }
| ProtocolMethod<T>
type ProtocolMethod<T, TConstructor = any> = T extends (...args: any) => any
? { new (): TConstructor; (): T; readonly prototype: TConstructor }
: never
type ProtocolType<T> = ProtocolConstructor<T> | ProtocolConstructor<T>[]
type ApiArgsValidator<T, P> = (value: T, params: P) => void
type ApiProtocol<T extends ApiLike, P = AsyncApiOptions<T>> = {
[K in keyof P]: ProtocolType<P[K]> | ProtocolOptions<P[K]>
}
type ApiProtocols<T extends ApiLike> = ApiProtocol<T> | ProtocolOptions[]
interface ApiOptions<T extends ApiLike, P = AsyncApiOptions<T>> {
beforeInvoke?: (args: unknown) => boolean | void | string
beforeAll?: (res: unknown) => void
beforeSuccess?: (res: unknown) => void
formatArgs?: {
[K in keyof P]?: ApiArgsValidator<P[K], P>
}
}
interface ProtocolOptions<T = any> {
name?: string
type?: ProtocolType<T>
required?: boolean
validator?(value: T): boolean | undefined | string
}
interface AsyncMethodOptionLike {
success?: (...args: any[]) => void
}
type PromisifySuccessResult<P, R> = P extends {
success: any
}
? void
: P extends { fail: any }
? void
: P extends { complete: any }
? void
: Promise<R>
type ApiLike = (...args: any[]) => any
type TaskApiLike = ApiLike
type AsyncApiLike = (args: any) => Promise<unknown> | void
type AsyncApiOptions<T extends ApiLike> = Parameters<T>[0]
type AsyncApiRes<T extends AsyncMethodOptionLike> = Parameters<
Exclude<T['success'], undefined>
>[0]
type AsyncApiRequired<T extends AsyncMethodOptionLike> = <P extends T>(
args: P
) => PromisifySuccessResult<P, AsyncApiRes<T>>
type AsyncApiOptional<T extends AsyncMethodOptionLike> = <P extends T>(
args?: P
) => PromisifySuccessResult<P, AsyncApiRes<T>>
interface AsyncApiOptionalOptions {
success?: any
fail?: any
complete?: any
}
type AsyncApi<
T extends AsyncMethodOptionLike
> = AsyncApiOptionalOptions extends T
? AsyncApiOptional<T>
: AsyncApiRequired<T>
......@@ -1464,6 +1464,16 @@ function decode(base64) {
}
return arraybuffer;
}
const HTTP_METHODS = [
"GET",
"OPTIONS",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT"
];
const API_TYPE_ON_PROTOCOLS = [
{
name: "callback",
......@@ -1471,20 +1481,20 @@ const API_TYPE_ON_PROTOCOLS = [
required: true
}
];
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
function elemInArray(str, arr) {
if (arr.indexOf(str) === -1) {
return arr[0];
}
return {
errMsg
};
return str;
}
function validateProtocolFail(name, msg) {
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn$1(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -1492,33 +1502,32 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i2 = 0; i2 < len; i2++) {
const opts = protocol[i2];
const data = Object.create(null);
if (argsLen > i2) {
data[opts.name] = args[i2];
}
const errMsg = validateProtocol(name, data, {[opts.name]: opts});
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i2 = 0; i2 < len; i2++) {
const opts = protocol[i2];
const data = Object.create(null);
if (argsLen > i2) {
data[opts.name] = args[i2];
}
return;
validateProtocol(name, data, {[opts.name]: opts});
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = {type: prop};
}
const {type, required, validator} = prop;
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -1781,10 +1790,7 @@ function wrapperAsyncApi(name, fn, options) {
function wrapperApi(fn, name, protocol, options) {
return function(...args) {
if (process.env.NODE_ENV !== "production") {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......@@ -1811,7 +1817,6 @@ function defineAsyncApi(name, fn, protocol, options) {
return promisify(wrapperApi(wrapperAsyncApi(name, fn, options), name, process.env.NODE_ENV !== "production" ? protocol : void 0, options));
}
const API_BASE64_TO_ARRAY_BUFFER = "base64ToArrayBuffer";
const API_ARRAY_BUFFER_TO_BASE64 = "arrayBufferToBase64";
const Base64ToArrayBufferProtocol = [
{
name: "base64",
......@@ -1819,6 +1824,7 @@ const Base64ToArrayBufferProtocol = [
required: true
}
];
const API_ARRAY_BUFFER_TO_BASE64 = "arrayBufferToBase64";
const ArrayBufferToBase64Protocol = [
{
name: "arrayBuffer",
......@@ -2046,6 +2052,7 @@ const promiseInterceptor = {
});
}
};
const API_CREATE_VIDEO_CONTEXT = "createVideoContext";
const RATES = [0.5, 0.8, 1, 1.25, 1.5, 2];
class VideoContext {
constructor(id2, vm) {
......@@ -2090,12 +2097,12 @@ class VideoContext {
operateVideoPlayer(this.id, this.vm, "hideStatusBar");
}
}
function createVideoContext(id2, context) {
const createVideoContext = /* @__PURE__ */ defineSyncApi(API_CREATE_VIDEO_CONTEXT, (id2, context) => {
if (context) {
return new VideoContext(id2, context);
}
return new VideoContext(id2, getCurrentPageVm());
}
});
const defaultOptions = {
thresholds: [0],
initialRatio: 0,
......@@ -2164,15 +2171,7 @@ const CanIUseProtocol = [
];
const API_MAKE_PHONE_CALL = "makePhoneCall";
const MakePhoneCallProtocol = {
phoneNumber: {
type: String,
required: true,
validator(phoneNumber) {
if (!phoneNumber) {
return "parameter error: parameter.phoneNumber should not be empty String;";
}
}
}
phoneNumber: String
};
const API_OPEN_DOCUMENT = "openDocument";
const OpenDocumentProtocol = {
......@@ -2180,9 +2179,7 @@ const OpenDocumentProtocol = {
type: String,
required: true
},
fileType: {
type: String
}
fileType: String
};
const API_GET_IMAGE_INFO = "getImageInfo";
const GetImageInfoOptions = {
......@@ -2199,17 +2196,6 @@ const GetImageInfoProtocol = {
}
};
const API_REQUEST = "request";
const METHOD = [
"GET",
"OPTIONS",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT"
];
const DEFAULT_METHOD = "GET";
const dataType = {
JSON: "json"
};
......@@ -2269,22 +2255,19 @@ const RequestProtocol = {
const RequestOptions = {
formatArgs: {
method(value, params) {
params.method = (value || "").toUpperCase();
if (METHOD.indexOf(params.method) === -1) {
params.method = DEFAULT_METHOD;
}
params.method = elemInArray((value || "").toUpperCase(), HTTP_METHODS);
},
data(value, params) {
params.data = value || "";
},
url(value, params) {
if (params.method === DEFAULT_METHOD && isPlainObject(params.data) && Object.keys(params.data).length) {
if (params.method === HTTP_METHODS[0] && isPlainObject(params.data) && Object.keys(params.data).length) {
params.url = stringifyQuery(value, params.data);
}
},
header(value, params) {
const header = params.header = value || {};
if (params.method !== DEFAULT_METHOD) {
if (params.method !== HTTP_METHODS[0]) {
if (!Object.keys(header).find((key) => key.toLowerCase() === "content-type")) {
header["Content-Type"] = "application/json";
}
......@@ -2373,9 +2356,9 @@ const ReLaunchOptions = /* @__PURE__ */ createRouteOptions(API_RE_LAUNCH);
const SwitchTabOptions = /* @__PURE__ */ createRouteOptions(API_SWITCH_TAB);
const NavigateBackOptions = {
formatArgs: {
delta(delta, params) {
delta = parseInt(delta) || 1;
params.delta = Math.min(getCurrentPages().length - 1, delta);
delta(value, params) {
value = parseInt(value + "") || 1;
params.delta = Math.min(getCurrentPages().length - 1, value);
}
}
};
......@@ -2474,19 +2457,12 @@ const IndexOptions = {
}
}
};
const API_SET_TAB_BAR_ITEM = "setTabBarItem";
const SetTabBarItemProtocol = extend({
text: {
type: String
},
iconPath: {
type: String
},
selectedIconPath: {
type: String
},
pagePath: {
type: String
}
text: String,
iconPath: String,
selectedIconPath: String,
pagePath: String
}, IndexProtocol);
const SetTabBarItemOptions = {
beforeInvoke: IndexOptions.beforeInvoke,
......@@ -2498,25 +2474,14 @@ const SetTabBarItemOptions = {
}
}, IndexOptions.formatArgs)
};
const API_SET_TAB_BAR_STYLE = "setTabBarStyle";
const SetTabBarStyleProtocol = {
color: {
type: String
},
selectedColor: {
type: String
},
backgroundColor: {
type: String
},
backgroundImage: {
type: String
},
backgroundRepeat: {
type: String
},
borderStyle: {
type: String
}
color: String,
selectedColor: String,
backgroundColor: String,
backgroundImage: String,
backgroundRepeat: String,
borderStyle: String
};
const GRADIENT_RE = /^(linear|radial)-gradient\(.+?\);?$/;
const SetTabBarStyleOptions = {
......@@ -2534,19 +2499,22 @@ const SetTabBarStyleOptions = {
}
}
};
const API_HIDE_TAB_BAR = "hideTabBar";
const HideTabBarProtocol = {
animation: {
type: Boolean,
default: false
}
animation: Boolean
};
const API_SHOW_TAB_BAR = "showTabBar";
const ShowTabBarProtocol = HideTabBarProtocol;
const API_HIDE_TAB_BAR_RED_DOT = "hideTabBarRedDot";
const HideTabBarRedDotProtocol = IndexProtocol;
const HideTabBarRedDotOptions = IndexOptions;
const API_SHOW_TAB_BAR_RED_DOT = "showTabBarRedDot";
const ShowTabBarRedDotProtocol = IndexProtocol;
const ShowTabBarRedDotOptions = IndexOptions;
const API_REMOVE_TAB_BAR_BADGE = "removeTabBarBadge";
const RemoveTabBarBadgeProtocol = IndexProtocol;
const RemoveTabBarBadgeOptions = IndexOptions;
const API_SET_TAB_BAR_BADGE = "setTabBarBadge";
const SetTabBarBadgeProtocol = extend({
text: {
type: String,
......@@ -10911,7 +10879,7 @@ const openDocument = /* @__PURE__ */ defineAsyncApi(API_OPEN_DOCUMENT, ({filePat
window.open(filePath);
return resolve();
}, OpenDocumentProtocol);
function _getServiceAddress() {
function getServiceAddress() {
return window.location.protocol + "//" + window.location.host;
}
const getImageInfo = /* @__PURE__ */ defineAsyncApi(API_GET_IMAGE_INFO, ({src}, {resolve, reject}) => {
......@@ -10920,7 +10888,7 @@ const getImageInfo = /* @__PURE__ */ defineAsyncApi(API_GET_IMAGE_INFO, ({src},
resolve({
width: img.naturalWidth,
height: img.naturalHeight,
path: src.indexOf("/") === 0 ? _getServiceAddress() + src : src
path: src.indexOf("/") === 0 ? getServiceAddress() + src : src
});
};
img.onerror = function() {
......@@ -11109,13 +11077,13 @@ function normalizeRoute(index2, oldPagePath, newPagePath) {
function setTabBar(type, args, resolve) {
const tabBar2 = useTabBar();
switch (type) {
case "showTabBar":
case API_SHOW_TAB_BAR:
tabBar2.shown = true;
break;
case "hideTabBar":
case API_HIDE_TAB_BAR:
tabBar2.shown = false;
break;
case "setTabBarItem":
case API_SET_TAB_BAR_ITEM:
const {index: index2} = args;
const tabBarItem = tabBar2.list[index2];
const oldPagePath = tabBarItem.pagePath;
......@@ -11125,23 +11093,23 @@ function setTabBar(type, args, resolve) {
normalizeRoute(index2, oldPagePath, pagePath);
}
break;
case "setTabBarStyle":
case API_SET_TAB_BAR_STYLE:
setProperties(tabBar2, setTabBarStyleProps, args);
break;
case "showTabBarRedDot":
case API_SHOW_TAB_BAR_RED_DOT:
setProperties(tabBar2.list[args.index], setTabBarBadgeProps, {
badge: "",
redDot: true
});
break;
case "setTabBarBadge":
case API_SET_TAB_BAR_BADGE:
setProperties(tabBar2.list[args.index], setTabBarBadgeProps, {
badge: args.text,
redDot: true
});
break;
case "hideTabBarRedDot":
case "removeTabBarBadge":
case API_HIDE_TAB_BAR_RED_DOT:
case API_REMOVE_TAB_BAR_BADGE:
setProperties(tabBar2.list[args.index], setTabBarBadgeProps, {
badge: "",
redDot: false
......@@ -11150,29 +11118,29 @@ function setTabBar(type, args, resolve) {
}
resolve();
}
const setTabBarItem = /* @__PURE__ */ defineAsyncApi("setTabBarItem", (args, {resolve}) => {
setTabBar("setTabBarItem", args, resolve);
const setTabBarItem = /* @__PURE__ */ defineAsyncApi(API_SET_TAB_BAR_ITEM, (args, {resolve}) => {
setTabBar(API_SET_TAB_BAR_ITEM, args, resolve);
}, SetTabBarItemProtocol, SetTabBarItemOptions);
const setTabBarStyle = /* @__PURE__ */ defineAsyncApi("setTabBarStyle", (args, {resolve}) => {
setTabBar("setTabBarStyle", args, resolve);
const setTabBarStyle = /* @__PURE__ */ defineAsyncApi(API_SET_TAB_BAR_STYLE, (args, {resolve}) => {
setTabBar(API_SET_TAB_BAR_STYLE, args, resolve);
}, SetTabBarStyleProtocol, SetTabBarStyleOptions);
const hideTabBar = /* @__PURE__ */ defineAsyncApi("hideTabBar", (args, {resolve}) => {
setTabBar("hideTabBar", args, resolve);
const hideTabBar = /* @__PURE__ */ defineAsyncApi(API_HIDE_TAB_BAR, (args, {resolve}) => {
setTabBar(API_HIDE_TAB_BAR, args, resolve);
}, HideTabBarProtocol);
const showTabBar = /* @__PURE__ */ defineAsyncApi("showTabBar", (args, {resolve}) => {
setTabBar("showTabBar", args, resolve);
const showTabBar = /* @__PURE__ */ defineAsyncApi(API_SHOW_TAB_BAR, (args, {resolve}) => {
setTabBar(API_SHOW_TAB_BAR, args, resolve);
}, ShowTabBarProtocol);
const hideTabBarRedDot = /* @__PURE__ */ defineAsyncApi("hideTabBarRedDot", (args, {resolve}) => {
setTabBar("hideTabBarRedDot", args, resolve);
const hideTabBarRedDot = /* @__PURE__ */ defineAsyncApi(API_HIDE_TAB_BAR_RED_DOT, (args, {resolve}) => {
setTabBar(API_HIDE_TAB_BAR_RED_DOT, args, resolve);
}, HideTabBarRedDotProtocol, HideTabBarRedDotOptions);
const showTabBarRedDot = /* @__PURE__ */ defineAsyncApi("showTabBarRedDot", (args, {resolve}) => {
setTabBar("showTabBarRedDot", args, resolve);
const showTabBarRedDot = /* @__PURE__ */ defineAsyncApi(API_SHOW_TAB_BAR_RED_DOT, (args, {resolve}) => {
setTabBar(API_SHOW_TAB_BAR_RED_DOT, args, resolve);
}, ShowTabBarRedDotProtocol, ShowTabBarRedDotOptions);
const removeTabBarBadge = /* @__PURE__ */ defineAsyncApi("removeTabBarBadge", (args, {resolve}) => {
setTabBar("removeTabBarBadge", args, resolve);
const removeTabBarBadge = /* @__PURE__ */ defineAsyncApi(API_REMOVE_TAB_BAR_BADGE, (args, {resolve}) => {
setTabBar(API_REMOVE_TAB_BAR_BADGE, args, resolve);
}, RemoveTabBarBadgeProtocol, RemoveTabBarBadgeOptions);
const setTabBarBadge = /* @__PURE__ */ defineAsyncApi("setTabBarBadge", (args, {resolve}) => {
setTabBar("setTabBarBadge", args, resolve);
const setTabBarBadge = /* @__PURE__ */ defineAsyncApi(API_SET_TAB_BAR_BADGE, (args, {resolve}) => {
setTabBar(API_SET_TAB_BAR_BADGE, args, resolve);
}, SetTabBarBadgeProtocol, SetTabBarBadgeOptions);
var api = /* @__PURE__ */ Object.freeze({
__proto__: null,
......
......@@ -2,6 +2,7 @@ import { hasOwn } from '@vue/shared'
import {
API_CAN_I_USE,
API_TYPE_CAN_I_USE,
CanIUseProtocol,
defineSyncApi,
} from '@dcloudio/uni-api'
......@@ -29,7 +30,7 @@ const SCHEMA_CSS = {
'css.backdrop-filter': cssBackdropFilter,
}
export const canIUse = defineSyncApi<typeof uni.canIUse>(
export const canIUse = defineSyncApi<API_TYPE_CAN_I_USE>(
API_CAN_I_USE,
(schema: string) => {
if (hasOwn(SCHEMA_CSS, schema)) {
......
import {
API_MAKE_PHONE_CALL,
API_TYPE_MAKE_PHONE_CALL,
defineAsyncApi,
MakePhoneCallProtocol,
} from '@dcloudio/uni-api'
export const makePhoneCall = defineAsyncApi<typeof uni.makePhoneCall>(
export const makePhoneCall = defineAsyncApi<API_TYPE_MAKE_PHONE_CALL>(
API_MAKE_PHONE_CALL,
({ phoneNumber }, { resolve }) => {
window.location.href = `tel:${phoneNumber}`
......
import {
API_OPEN_DOCUMENT,
API_TYPE_OPEN_DOCUMENT,
defineAsyncApi,
OpenDocumentProtocol,
} from '@dcloudio/uni-api'
export const openDocument = defineAsyncApi<typeof uni.openDocument>(
export const openDocument = defineAsyncApi<API_TYPE_OPEN_DOCUMENT>(
API_OPEN_DOCUMENT,
({ filePath }, { resolve }) => {
window.open(filePath)
......
import {
API_GET_IMAGE_INFO,
API_TYPE_GET_IMAGE_INFO,
defineAsyncApi,
GetImageInfoOptions,
GetImageInfoProtocol,
} from '@dcloudio/uni-api'
function _getServiceAddress() {
function getServiceAddress() {
return window.location.protocol + '//' + window.location.host
}
export const getImageInfo = defineAsyncApi<typeof uni.getImageInfo>(
export const getImageInfo = defineAsyncApi<API_TYPE_GET_IMAGE_INFO>(
API_GET_IMAGE_INFO,
({ src }, { resolve, reject }) => {
const img = new Image()
......@@ -17,7 +18,7 @@ export const getImageInfo = defineAsyncApi<typeof uni.getImageInfo>(
resolve({
width: img.naturalWidth,
height: img.naturalHeight,
path: src.indexOf('/') === 0 ? _getServiceAddress() + src : src,
path: src.indexOf('/') === 0 ? getServiceAddress() + src : src,
} as UniApp.GetImageInfoSuccessData) // orientation和type是可选的,但GetImageInfoSuccessData定义的不对,暂时强制转换
}
img.onerror = function () {
......
import {
API_REQUEST,
API_TYPE_REQUEST,
defineTaskApi,
RequestOptions,
RequestProtocol,
} from '@dcloudio/uni-api'
import { hasOwn } from '@vue/shared'
export const request = defineTaskApi<typeof uni.request>(
export const request = defineTaskApi<API_TYPE_REQUEST>(
API_REQUEST,
(
{
......
import { invokeHook } from '@dcloudio/uni-core'
import {
API_NAVIGATE_BACK,
API_TYPE_NAVIGATE_BACK,
defineAsyncApi,
NavigateBackOptions,
NavigateBackProtocol,
} from '@dcloudio/uni-api'
export const navigateBack = defineAsyncApi<typeof uni.navigateBack>(
export const navigateBack = defineAsyncApi<API_TYPE_NAVIGATE_BACK>(
API_NAVIGATE_BACK,
({ delta }, { resolve, reject }) => {
let canBack = true
......
import {
API_NAVIGATE_TO,
API_TYPE_NAVIGATE_TO,
defineAsyncApi,
NavigateToOptions,
NavigateToProtocol,
} from '@dcloudio/uni-api'
import { navigate } from './utils'
export const navigateTo = defineAsyncApi<typeof uni.navigateTo>(
export const navigateTo = defineAsyncApi<API_TYPE_NAVIGATE_TO>(
API_NAVIGATE_TO,
({ url }, { resolve, reject }) =>
navigate(API_NAVIGATE_TO, url).then(resolve).catch(reject),
......
import {
API_RE_LAUNCH,
API_TYPE_RE_LAUNCH,
defineAsyncApi,
ReLaunchOptions,
ReLaunchProtocol,
} from '@dcloudio/uni-api'
import { navigate } from './utils'
export const reLaunch = defineAsyncApi<typeof uni.reLaunch>(
export const reLaunch = defineAsyncApi<API_TYPE_RE_LAUNCH>(
API_RE_LAUNCH,
({ url }, { resolve, reject }) =>
navigate(API_RE_LAUNCH, url).then(resolve).catch(reject),
......
import {
API_REDIRECT_TO,
API_TYPE_REDIRECT_TO,
defineAsyncApi,
RedirectToOptions,
RedirectToProtocol,
} from '@dcloudio/uni-api'
import { navigate } from './utils'
export const redirectTo = defineAsyncApi<typeof uni.redirectTo>(
export const redirectTo = defineAsyncApi<API_TYPE_REDIRECT_TO>(
API_REDIRECT_TO,
({ url }, { resolve, reject }) =>
navigate(API_REDIRECT_TO, url).then(resolve).catch(reject),
......
import {
API_SWITCH_TAB,
API_TYPE_SWITCH_TAB,
defineAsyncApi,
SwitchTabOptions,
SwitchTabProtocol,
} from '@dcloudio/uni-api'
import { navigate } from './utils'
export const switchTab = defineAsyncApi<typeof uni.switchTab>(
export const switchTab = defineAsyncApi<API_TYPE_SWITCH_TAB>(
API_SWITCH_TAB,
({ url }, { resolve, reject }) =>
navigate(API_SWITCH_TAB, url).then(resolve).catch(reject),
......
import { defineAsyncApi } from '@dcloudio/uni-api'
import { getCurrentPageMeta } from '@dcloudio/uni-core'
import {
API_SET_NAVIGATION_BAR_COLOR,
API_SET_NAVIGATION_BAR_TITLE,
API_SHOW_NAVIGATION_BAR_LOADING,
API_HIDE_NAVIGATION_BAR_LOADING,
API_TYPE_SET_NAVIGATION_BAR_COLOR,
API_TYPE_SET_NAVIGATION_BAR_TITLE,
API_TYPE_SHOW_NAVIGATION_BAR_LOADING,
API_TYPE_HIDE_NAVIGATION_BAR_LOADING,
SetNavigationBarColorOptions,
SetNavigationBarColorProtocol,
SetNavigationBarTitleProtocol,
} from 'packages/uni-api/src/protocols/ui/navigationBar'
function setNavigationBar(
pageMeta: UniApp.PageRouteMeta | undefined,
type: string,
args: Record<string, any>,
resolve: () => void,
reject: (err: string) => void
) {
if (!pageMeta) {
return reject('page not found')
}
const { navigationBar } = pageMeta
switch (type) {
case API_SET_NAVIGATION_BAR_COLOR:
const { frontColor, backgroundColor, animation } = args
const { duration, timingFunc } = animation
if (frontColor) {
navigationBar.titleColor = frontColor === '#000000' ? '#000' : '#fff'
}
if (backgroundColor) {
navigationBar.backgroundColor = backgroundColor
}
navigationBar.duration = duration + 'ms'
navigationBar.timingFunc = timingFunc
// TODO
// UniServiceJSBridge.emit('onNavigationBarChange', {
// textColor: frontColor === '#000000' ? '#000' : '#fff',
// backgroundColor: navigationBar.backgroundColor,
// })
break
case API_SHOW_NAVIGATION_BAR_LOADING:
navigationBar.loading = true
break
case API_HIDE_NAVIGATION_BAR_LOADING:
navigationBar.loading = false
break
case API_SET_NAVIGATION_BAR_TITLE:
const { title } = args
navigationBar.titleText = title
// TODO isCurrentPage逻辑主要是navigationBar组件使用
// if (isCurrentPage(page)) {
// // 仅当前页面
// document.title = title
// }
// TODO
// UniServiceJSBridge.emit('onNavigationBarChange', {
// titleText: title,
// })
break
}
}
export const setNavigationBarColor = defineAsyncApi<API_TYPE_SET_NAVIGATION_BAR_COLOR>(
API_SET_NAVIGATION_BAR_COLOR,
(args, { resolve, reject }) => {
setNavigationBar(
getCurrentPageMeta(),
API_SET_NAVIGATION_BAR_COLOR,
args,
resolve,
reject
)
},
SetNavigationBarColorProtocol,
SetNavigationBarColorOptions
)
export const showNavigationBarLoading = defineAsyncApi<API_TYPE_SHOW_NAVIGATION_BAR_LOADING>(
API_SHOW_NAVIGATION_BAR_LOADING,
(args, { resolve, reject }) => {
setNavigationBar(
getCurrentPageMeta(),
API_SHOW_NAVIGATION_BAR_LOADING,
args,
resolve,
reject
)
}
)
export const hideNavigationBarLoading = defineAsyncApi<API_TYPE_HIDE_NAVIGATION_BAR_LOADING>(
API_HIDE_NAVIGATION_BAR_LOADING,
(args, { resolve, reject }) => {
setNavigationBar(
getCurrentPageMeta(),
API_HIDE_NAVIGATION_BAR_LOADING,
args,
resolve,
reject
)
}
)
export const setNavigationBarTitle = defineAsyncApi<API_TYPE_SET_NAVIGATION_BAR_TITLE>(
API_SET_NAVIGATION_BAR_TITLE,
(args, { resolve, reject }) => {
setNavigationBar(
getCurrentPageMeta(),
API_SET_NAVIGATION_BAR_TITLE,
args,
resolve,
reject
)
},
SetNavigationBarTitleProtocol
)
import { hasOwn } from '@vue/shared'
import {
API_HIDE_TAB_BAR,
API_HIDE_TAB_BAR_RED_DOT,
API_REMOVE_TAB_BAR_BADGE,
API_SET_TAB_BAR_BADGE,
API_SET_TAB_BAR_ITEM,
API_SET_TAB_BAR_STYLE,
API_SHOW_TAB_BAR,
API_SHOW_TAB_BAR_RED_DOT,
API_TYPE_HIDE_TAB_BAR,
API_TYPE_HIDE_TAB_BAR_RED_DOT,
API_TYPE_REMOVE_TAB_BAR_BADGE,
API_TYPE_SET_TAB_BAR_BADGE,
API_TYPE_SET_TAB_BAR_ITEM,
API_TYPE_SET_TAB_BAR_STYLE,
API_TYPE_SHOW_TAB_BAR,
API_TYPE_SHOW_TAB_BAR_RED_DOT,
defineAsyncApi,
HideTabBarProtocol,
HideTabBarRedDotOptions,
......@@ -68,13 +84,13 @@ function setTabBar(
) {
const tabBar = useTabBar()!
switch (type) {
case 'showTabBar':
case API_SHOW_TAB_BAR:
tabBar.shown = true
break
case 'hideTabBar':
case API_HIDE_TAB_BAR:
tabBar.shown = false
break
case 'setTabBarItem':
case API_SET_TAB_BAR_ITEM:
const { index } = args
const tabBarItem = tabBar.list[index]
const oldPagePath = tabBarItem.pagePath
......@@ -84,23 +100,23 @@ function setTabBar(
normalizeRoute(index, oldPagePath, pagePath)
}
break
case 'setTabBarStyle':
case API_SET_TAB_BAR_STYLE:
setProperties(tabBar, setTabBarStyleProps, args)
break
case 'showTabBarRedDot':
case API_SHOW_TAB_BAR_RED_DOT:
setProperties(tabBar.list[args.index], setTabBarBadgeProps, {
badge: '',
redDot: true,
})
break
case 'setTabBarBadge':
case API_SET_TAB_BAR_BADGE:
setProperties(tabBar.list[args.index], setTabBarBadgeProps, {
badge: args.text,
redDot: true,
})
break
case 'hideTabBarRedDot':
case 'removeTabBarBadge':
case API_HIDE_TAB_BAR_RED_DOT:
case API_REMOVE_TAB_BAR_BADGE:
setProperties(tabBar.list[args.index], setTabBarBadgeProps, {
badge: '',
redDot: false,
......@@ -110,70 +126,70 @@ function setTabBar(
resolve()
}
export const setTabBarItem = defineAsyncApi<typeof uni.setTabBarItem>(
'setTabBarItem',
export const setTabBarItem = defineAsyncApi<API_TYPE_SET_TAB_BAR_ITEM>(
API_SET_TAB_BAR_ITEM,
(args, { resolve }) => {
setTabBar('setTabBarItem', args, resolve)
setTabBar(API_SET_TAB_BAR_ITEM, args, resolve)
},
SetTabBarItemProtocol,
SetTabBarItemOptions
)
export const setTabBarStyle = defineAsyncApi<typeof uni.setTabBarStyle>(
'setTabBarStyle',
export const setTabBarStyle = defineAsyncApi<API_TYPE_SET_TAB_BAR_STYLE>(
API_SET_TAB_BAR_STYLE,
(args, { resolve }) => {
setTabBar('setTabBarStyle', args, resolve)
setTabBar(API_SET_TAB_BAR_STYLE, args, resolve)
},
SetTabBarStyleProtocol,
SetTabBarStyleOptions
)
export const hideTabBar = defineAsyncApi<typeof uni.hideTabBar>(
'hideTabBar',
export const hideTabBar = defineAsyncApi<API_TYPE_HIDE_TAB_BAR>(
API_HIDE_TAB_BAR,
(args, { resolve }) => {
setTabBar('hideTabBar', args, resolve)
setTabBar(API_HIDE_TAB_BAR, args, resolve)
},
HideTabBarProtocol
)
export const showTabBar = defineAsyncApi<typeof uni.showTabBar>(
'showTabBar',
export const showTabBar = defineAsyncApi<API_TYPE_SHOW_TAB_BAR>(
API_SHOW_TAB_BAR,
(args, { resolve }) => {
setTabBar('showTabBar', args, resolve)
setTabBar(API_SHOW_TAB_BAR, args, resolve)
},
ShowTabBarProtocol
)
export const hideTabBarRedDot = defineAsyncApi<typeof uni.hideTabBarRedDot>(
'hideTabBarRedDot',
export const hideTabBarRedDot = defineAsyncApi<API_TYPE_HIDE_TAB_BAR_RED_DOT>(
API_HIDE_TAB_BAR_RED_DOT,
(args, { resolve }) => {
setTabBar('hideTabBarRedDot', args, resolve)
setTabBar(API_HIDE_TAB_BAR_RED_DOT, args, resolve)
},
HideTabBarRedDotProtocol,
HideTabBarRedDotOptions
)
export const showTabBarRedDot = defineAsyncApi<typeof uni.showTabBarRedDot>(
'showTabBarRedDot',
export const showTabBarRedDot = defineAsyncApi<API_TYPE_SHOW_TAB_BAR_RED_DOT>(
API_SHOW_TAB_BAR_RED_DOT,
(args, { resolve }) => {
setTabBar('showTabBarRedDot', args, resolve)
setTabBar(API_SHOW_TAB_BAR_RED_DOT, args, resolve)
},
ShowTabBarRedDotProtocol,
ShowTabBarRedDotOptions
)
export const removeTabBarBadge = defineAsyncApi<typeof uni.removeTabBarBadge>(
'removeTabBarBadge',
export const removeTabBarBadge = defineAsyncApi<API_TYPE_REMOVE_TAB_BAR_BADGE>(
API_REMOVE_TAB_BAR_BADGE,
(args, { resolve }) => {
setTabBar('removeTabBarBadge', args, resolve)
setTabBar(API_REMOVE_TAB_BAR_BADGE, args, resolve)
},
RemoveTabBarBadgeProtocol,
RemoveTabBarBadgeOptions
)
export const setTabBarBadge = defineAsyncApi<typeof uni.setTabBarBadge>(
'setTabBarBadge',
export const setTabBarBadge = defineAsyncApi<API_TYPE_SET_TAB_BAR_BADGE>(
API_SET_TAB_BAR_BADGE,
(args, { resolve }) => {
setTabBar('setTabBarBadge', args, resolve)
setTabBar(API_SET_TAB_BAR_BADGE, args, resolve)
},
SetTabBarBadgeProtocol,
SetTabBarBadgeOptions
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
import { isArray, hasOwn, isString, isObject, capitalize, toRawType, makeMap, isPlainObject, isPromise, isFunction } from '@vue/shared';
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction } from '@vue/shared';
function validateProtocolFail(name, msg) {
const errMsg = `${name}:fail ${msg}`;
{
console.error(errMsg);
}
return {
errMsg,
};
console.warn(`${name}:fail ${msg}`);
}
function validateProtocol(name, data, protocol) {
for (const key in protocol) {
const errMsg = validateProp(key, data[key], protocol[key], !hasOwn(data, key));
if (isString(errMsg)) {
return validateProtocolFail(name, errMsg);
validateProtocolFail(name, errMsg);
}
}
}
......@@ -21,36 +15,35 @@ function validateProtocols(name, args, protocol) {
if (!protocol) {
return;
}
if (isArray(protocol)) {
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
const errMsg = validateProtocol(name, data, { [opts.name]: opts });
if (errMsg) {
return errMsg;
}
if (!isArray(protocol)) {
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
const len = protocol.length;
const argsLen = args.length;
for (let i = 0; i < len; i++) {
const opts = protocol[i];
const data = Object.create(null);
if (argsLen > i) {
data[opts.name] = args[i];
}
return;
validateProtocol(name, data, { [opts.name]: opts });
}
return validateProtocol(name, args[0] || Object.create(null), protocol);
}
function validateProp(name, value, prop, isAbsent) {
if (!isPlainObject(prop)) {
prop = { type: prop };
}
const { type, required, validator } = prop;
// required!
if (required && isAbsent) {
return 'Missing required args: "' + name + '"';
}
// missing but optional
if (value == null && !prop.required) {
if (value == null && !required) {
return;
}
// type check
if (type != null && type !== true) {
if (type != null) {
let isValid = false;
const types = isArray(type) ? type : [type];
const expectedTypes = [];
......@@ -169,10 +162,7 @@ function wrapperSyncApi(fn) {
function wrapperApi(fn, name, protocol, options) {
return function (...args) {
if ((process.env.NODE_ENV !== 'production')) {
const errMsg = validateProtocols(name, args, protocol);
if (isString(errMsg)) {
return errMsg;
}
validateProtocols(name, args, protocol);
}
if (options && options.beforeInvoke) {
const errMsg = options.beforeInvoke(args);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册