No Description

index.js 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * Copyright (c) 2016, David Voiss <davidvoiss@gmail.com>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any purpose
  5. * with or without fee is hereby granted, provided that the above copyright notice
  6. * and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  10. * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  12. * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  13. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
  14. * THIS SOFTWARE.
  15. */
  16. /* jshint node: true */
  17. "use strict";
  18. /**
  19. * A module to get Android versions by API level, NDK level, semantic version, or version name.
  20. *
  21. * Versions are referenced from here:
  22. * {@link https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases}
  23. * {@link https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/Build.java}
  24. *
  25. * The version for "Current Development Build" ("CUR_DEVELOPMENT") is not included.
  26. *
  27. * @module android-versions
  28. */
  29. var VERSIONS = {
  30. BASE: { api: 1, ndk: 0, semver: "1.0", name: "(no code name)", },
  31. BASE_1_1: { api: 2, ndk: 0, semver: "1.1", name: "(no code name)", },
  32. CUPCAKE: { api: 3, ndk: 1, semver: "1.5", name: "Cupcake", },
  33. DONUT: { api: 4, ndk: 2, semver: "1.6", name: "Donut", },
  34. ECLAIR: { api: 5, ndk: 2, semver: "2.0", name: "Eclair", },
  35. ECLAIR_0_1: { api: 6, ndk: 2, semver: "2.0.1", name: "Eclair", },
  36. ECLAIR_MR1: { api: 7, ndk: 3, semver: "2.1", name: "Eclair", },
  37. FROYO: { api: 8, ndk: 4, semver: "2.2.x", name: "Froyo", },
  38. GINGERBREAD: { api: 9, ndk: 5, semver: "2.3.0 - 2.3.2", name: "Gingerbread", },
  39. GINGERBREAD_MR1: { api: 10, ndk: 5, semver: "2.3.3 - 2.3.7", name: "Gingerbread", },
  40. HONEYCOMB: { api: 11, ndk: 5, semver: "3.0", name: "Honeycomb", },
  41. HONEYCOMB_MR1: { api: 12, ndk: 6, semver: "3.1", name: "Honeycomb", },
  42. HONEYCOMB_MR2: { api: 13, ndk: 6, semver: "3.2.x", name: "Honeycomb", },
  43. ICE_CREAM_SANDWICH: { api: 14, ndk: 7, semver: "4.0.1 - 4.0.2", name: "Ice Cream Sandwich", },
  44. ICE_CREAM_SANDWICH_MR1: { api: 15, ndk: 8, semver: "4.0.3 - 4.0.4", name: "Ice Cream Sandwich", },
  45. JELLY_BEAN: { api: 16, ndk: 8, semver: "4.1.x", name: "Jellybean", },
  46. JELLY_BEAN_MR1: { api: 17, ndk: 8, semver: "4.2.x", name: "Jellybean", },
  47. JELLY_BEAN_MR2: { api: 18, ndk: 8, semver: "4.3.x", name: "Jellybean", },
  48. KITKAT: { api: 19, ndk: 8, semver: "4.4.0 - 4.4.4", name: "KitKat", },
  49. KITKAT_WATCH: { api: 20, ndk: 8, semver: "4.4", name: "KitKat Watch", },
  50. LOLLIPOP: { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", },
  51. LOLLIPOP_MR1: { api: 22, ndk: 8, semver: "5.1", name: "Lollipop", },
  52. M: { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", },
  53. N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", },
  54. N_MR1: { api: 25, ndk: 8, semver: "7.1", name: "Nougat", },
  55. O: { api: 26, ndk: 8, semver: "8.0.0", name: "Oreo", },
  56. O_MR1: { api: 27, ndk: 8, semver: "8.1.0", name: "Oreo", },
  57. P: { api: 28, ndk: 8, semver: "9", name: "Pie", },
  58. Q: { api: 29, ndk: 8, semver: "10", name: "Android10", },
  59. R: { api: 30, ndk: 8, semver: "11", name: "Android11", },
  60. S: { api: 31, ndk: 8, semver: "12", name: "Android12", }
  61. }
  62. // Add a key to each version of Android for the "versionCode".
  63. // This is the same key we use in the VERSIONS map above.
  64. Object.keys(VERSIONS).forEach(function(version) {
  65. VERSIONS[version].versionCode = version
  66. })
  67. var semver = require('semver');
  68. // semver format requires <major>.<minor>.<patch> but we allow just <major>.<minor> format.
  69. // Coerce <major>.<minor> to <major>.<minor>.0
  70. function formatSemver(semver) {
  71. if (semver.match(/^\d+.\d+$/)) {
  72. return semver + '.0'
  73. } else {
  74. return semver
  75. }
  76. }
  77. // The default predicate compares against API level, semver, name, or code.
  78. function getFromDefaultPredicate(arg) {
  79. // Coerce arg to string for comparisons below.
  80. arg = arg.toString()
  81. return getFromPredicate(function(version) {
  82. // Check API level before all else.
  83. if (arg === version.api.toString()) {
  84. return true
  85. }
  86. var argSemver = formatSemver(arg)
  87. if (semver.valid(argSemver) && semver.satisfies(argSemver, version.semver)) {
  88. return true
  89. }
  90. // Compare version name and code.
  91. return arg === version.name || arg === version.versionCode
  92. })
  93. }
  94. // The function to allow passing a predicate.
  95. function getFromPredicate(predicate) {
  96. if (predicate === null) {
  97. return null
  98. }
  99. return Object.keys(VERSIONS).filter(function(version) {
  100. return predicate(VERSIONS[version])
  101. }).map(function(key) { return VERSIONS[key] })
  102. }
  103. /**
  104. * The Android version codes available as keys for easier look-up.
  105. */
  106. Object.keys(VERSIONS).forEach(function(name) {
  107. exports[name] = VERSIONS[name]
  108. })
  109. /**
  110. * The complete reference of Android versions for easier look-up.
  111. */
  112. exports.VERSIONS = VERSIONS
  113. /**
  114. * Retrieve a single Android version.
  115. *
  116. * @param {object | Function} arg - The value or predicate to use to retrieve values.
  117. *
  118. * @return {object} An object representing the version found or null if none found.
  119. */
  120. exports.get = function(arg) {
  121. var result = exports.getAll(arg)
  122. if (result === null || result.length === 0) {
  123. return null
  124. }
  125. return result[0]
  126. }
  127. /**
  128. * Retrieve all Android versions that meet the criteria of the argument.
  129. *
  130. * @param {object | Function} arg - The value or predicate to use to retrieve values.
  131. *
  132. * @return {object} An object representing the version found or null if none found.
  133. */
  134. exports.getAll = function(arg) {
  135. if (arg === null) {
  136. return null
  137. }
  138. if (typeof arg === "function") {
  139. return getFromPredicate(arg)
  140. } else {
  141. return getFromDefaultPredicate(arg)
  142. }
  143. }