blob: 327d70a3db16fc436097473d0c45785f41b8cdea [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import semver from 'semver'
import { isPlainObject, typof } from '../util/index'
/**
* Normalize a version string.
* @param {String} Version. ie: 1, 1.0, 1.0.0
* @return {String} Version
*/
export function normalizeVersion (v) {
const isValid = semver.valid(v)
if (isValid) {
return v
}
v = typeof (v) === 'string' ? v : ''
const split = v.split('.')
let i = 0
const result = []
while (i < 3) {
const s = typeof (split[i]) === 'string' && split[i] ? split[i] : '0'
result.push(s)
i++
}
return result.join('.')
}
/**
* Get informations from different error key. Like:
* - code
* - errorMessage
* - errorType
* - isDowngrade
* @param {string} key
* @param {string} val
* @param {string} criteria
* @return {object}
*/
export function getError (key, val, criteria) {
const result = {
isDowngrade: true,
errorType: 1,
code: 1000
}
const getMsg = function (key, val, criteria) {
return 'Downgrade[' + key + '] :: deviceInfo '
+ val + ' matched criteria ' + criteria
}
const _key = key.toLowerCase()
result.errorMessage = getMsg(key, val, criteria)
if (_key.indexOf('osversion') >= 0) {
result.code = 1001
}
else if (_key.indexOf('appversion') >= 0) {
result.code = 1002
}
else if (_key.indexOf('weexversion') >= 0) {
result.code = 1003
}
else if (_key.indexOf('devicemodel') >= 0) {
result.code = 1004
}
return result
}
/**
* WEEX framework input(deviceInfo)
* {
* platform: 'iOS' or 'android'
* osVersion: '1.0.0' or '1.0' or '1'
* appVersion: '1.0.0' or '1.0' or '1'
* weexVersion: '1.0.0' or '1.0' or '1'
* dDeviceModel: 'MODEL_NAME'
* }
*
* downgrade config(config)
* {
* ios: {
* osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* deviceModel: ['modelA', 'modelB', ...]
* },
* android: {
* osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
* deviceModel: ['modelA', 'modelB', ...]
* }
* }
*
*
* @param {object} deviceInfo Weex SDK framework input
* @param {object} config user input
* @return {Object} { isDowngrade: true/false, errorMessage... }
*/
export function check (config, deviceInfo) {
deviceInfo = deviceInfo || global.WXEnvironment
deviceInfo = isPlainObject(deviceInfo) ? deviceInfo : {}
let result = {
isDowngrade: false // defautl is pass
}
if (typof(config) === 'function') {
let customDowngrade = config.call(this, deviceInfo, {
semver: semver,
normalizeVersion
})
customDowngrade = !!customDowngrade
result = customDowngrade ? getError('custom', '', 'custom params') : result
}
else {
config = isPlainObject(config) ? config : {}
const platform = deviceInfo.platform || 'unknow'
const dPlatform = platform.toLowerCase()
const cObj = config[dPlatform] || {}
for (const i in deviceInfo) {
const key = i
const keyLower = key.toLowerCase()
const val = deviceInfo[i]
const isVersion = keyLower.indexOf('version') >= 0
const isDeviceModel = keyLower.indexOf('devicemodel') >= 0
const criteria = cObj[i]
if (criteria && isVersion) {
const c = normalizeVersion(criteria)
const d = normalizeVersion(deviceInfo[i])
if (semver.satisfies(d, c)) {
result = getError(key, val, criteria)
break
}
}
else if (isDeviceModel) {
const _criteria = typof(criteria) === 'array' ? criteria : [criteria]
if (_criteria.indexOf(val) >= 0) {
result = getError(key, val, criteria)
break
}
}
}
}
return result
}