android-versions
Version:
Get the name, API level, version level, or version code from any version of Android.
151 lines (133 loc) • 7.61 kB
JavaScript
/* jshint node: true */
;
var semver = require("semver");
/**
* A node module to get Android versions by API level, semantic version, or version name.
*
* Versions are referenced from here:
* {@link https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases}
* {@link https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/Build.java}
*
* The version for "Current Development Build" ("CUR_DEVELOPMENT") is not included.
*
* @module android-versions
*/
var VERSIONS = {
BASE: { api: 1, semver: "1.0", name: "(no code name)", releaseDate: "23 Sep 2008" },
BASE_1_1: { api: 2, semver: "1.1", name: "(no code name)", releaseDate: "09 Feb 2009" },
CUPCAKE: { api: 3, semver: "1.5", name: "Cupcake", releaseDate: "27 Apr 2009" },
DONUT: { api: 4, semver: "1.6", name: "Donut", releaseDate: "15 Sep 2009" },
ECLAIR: { api: 5, semver: "2.0", name: "Eclair", releaseDate: "27 Oct 2009" },
ECLAIR_0_1: { api: 6, semver: "2.0.1", name: "Eclair", releaseDate: "03 Dec 2009" },
ECLAIR_MR1: { api: 7, semver: "2.1", name: "Eclair", releaseDate: "11 Jan 2010" },
FROYO: { api: 8, semver: "2.2.x", name: "Froyo", releaseDate: "20 May 2010" },
GINGERBREAD: { api: 9, semver: "2.3.0 - 2.3.2", name: "Gingerbread", releaseDate: "06 Dec 2010" },
GINGERBREAD_MR1: { api: 10, semver: "2.3.3 - 2.3.7", name: "Gingerbread", releaseDate: "09 Feb 2011" },
HONEYCOMB: { api: 11, semver: "3.0", name: "Honeycomb", releaseDate: "22 Feb 2011" },
HONEYCOMB_MR1: { api: 12, semver: "3.1", name: "Honeycomb", releaseDate: "10 May 2011" },
HONEYCOMB_MR2: { api: 13, semver: "3.2.x", name: "Honeycomb", releaseDate: "15 Jul 2011" },
ICE_CREAM_SANDWICH: { api: 14, semver: "4.0.1 - 4.0.2", name: "Ice Cream Sandwich", releaseDate: "18 Oct 2011" },
ICE_CREAM_SANDWICH_MR1: { api: 15, semver: "4.0.3 - 4.0.4", name: "Ice Cream Sandwich", releaseDate: "16 Dec 2011" },
JELLY_BEAN: { api: 16, semver: "4.1.x", name: "Jellybean", releaseDate: "09 Jul 2012" },
JELLY_BEAN_MR1: { api: 17, semver: "4.2.x", name: "Jellybean", releaseDate: "13 Nov 2012" },
JELLY_BEAN_MR2: { api: 18, semver: "4.3.x", name: "Jellybean", releaseDate: "24 Jul 2013" },
KITKAT: { api: 19, semver: "4.4.0 - 4.4.4", name: "KitKat", releaseDate: "31 Oct 2013" },
KITKAT_WATCH: { api: 20, semver: "4.4", name: "KitKat Watch", releaseDate: "25 Jun 2014" },
LOLLIPOP: { api: 21, semver: "5.0", name: "Lollipop", releaseDate: "04 Nov 2014" },
LOLLIPOP_MR1: { api: 22, semver: "5.1", name: "Lollipop", releaseDate: "02 Mar 2015" },
M: { api: 23, semver: "6.0", name: "Marshmallow", releaseDate: "02 Oct 2015" },
N: { api: 24, semver: "7.0", name: "Nougat", releaseDate: "22 Aug 2016" },
N_MR1: { api: 25, semver: "7.1", name: "Nougat", releaseDate: "04 Oct 2016" },
O: { api: 26, semver: "8.0.0", name: "Oreo", releaseDate: "21 Aug 2017" },
O_MR1: { api: 27, semver: "8.1.0", name: "Oreo", releaseDate: "05 Dec 2017" },
P: { api: 28, semver: "9", name: "Pie", releaseDate: "06 Aug 2018" },
Q: { api: 29, semver: "10", name: "Android10", releaseDate: "03 Sep 2019" },
R: { api: 30, semver: "11", name: "Android11", releaseDate: "08 Sep 2020" },
S: { api: 31, semver: "12", name: "Android12", releaseDate: "04 Oct 2021" },
S_V2: { api: 32, semver: "12", name: "Android12L", releaseDate: "07 Oct 2022" },
TIRAMISU: { api: 33, semver: "13", name: "Android13", releaseDate: "15 Oct 2022" },
UPSIDE_DOWN_CAKE: { api: 34, semver: "14", name: "Android14", releaseDate: "04 Oct 2023" },
VANILLA_ICE_CREAM: { api: 35, semver: "15", name: "Android15", releaseDate: "03 Sep 2024" },
BAKLAVA: { api: 36, semver: "16", name: "Android16", releaseDate: "23 Jan 2025" }
}
// Add a key to each version of Android for the "versionCode".
// This is the same key we use in the VERSIONS map above.
Object.keys(VERSIONS).forEach(function(version) {
VERSIONS[version].versionCode = version
})
// semver format requires <major>.<minor>.<patch> but we allow just <major>.<minor> format.
// Coerce <major>.<minor> to <major>.<minor>.0
function formatSemver(semver) {
if (semver.match(/^\d+.\d+$/)) {
return semver + '.0'
} else {
return semver
}
}
// The default predicate compares against API level, semver, name, or code.
function getFromDefaultPredicate(arg) {
// Coerce arg to string for comparisons below.
arg = arg.toString()
return getFromPredicate(function(version) {
// Check API level before all else.
if (arg === version.api.toString()) {
return true
}
var argSemver = formatSemver(arg)
if (semver.valid(argSemver) && semver.satisfies(argSemver, version.semver)) {
return true
}
// Compare version name and code.
return arg === version.name || arg === version.versionCode
})
}
// The function to allow passing a predicate.
function getFromPredicate(predicate) {
if (predicate === null) {
return null
}
return Object.keys(VERSIONS).filter(function(version) {
return predicate(VERSIONS[version])
}).map(function(key) { return VERSIONS[key] })
}
/**
* The Android version codes available as keys for easier look-up.
*/
Object.keys(VERSIONS).forEach(function(name) {
exports[name] = VERSIONS[name]
})
/**
* The complete reference of Android versions for easier look-up.
*/
exports.VERSIONS = VERSIONS
/**
* Retrieve a single Android version.
*
* @param {object | Function} arg - The value or predicate to use to retrieve values.
*
* @return {object} An object representing the version found or null if none found.
*/
exports.get = function(arg) {
var result = exports.getAll(arg)
if (result === null || result.length === 0) {
return null
}
return result[0]
}
/**
* Retrieve all Android versions that meet the criteria of the argument.
*
* @param {object | Function} arg - The value or predicate to use to retrieve values.
*
* @return {object} An object representing the version found or null if none found.
*/
exports.getAll = function(arg) {
if (arg === null) {
return null
}
if (typeof arg === "function") {
return getFromPredicate(arg)
} else {
return getFromDefaultPredicate(arg)
}
}