Fix: version ordering (#1161)

* fix: version ordering

* Update tools/bin/gen_versions.js

Co-authored-by: エリス <erisu@users.noreply.github.com>

Co-authored-by: エリス <erisu@users.noreply.github.com>
diff --git a/package-lock.json b/package-lock.json
index 153c78f..0ee12d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -97,6 +97,11 @@
           "requires": {
             "safe-buffer": "~5.1.1"
           }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
         }
       }
     },
@@ -3062,6 +3067,12 @@
           "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
           "dev": true
         },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
         "strip-ansi": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -7173,6 +7184,13 @@
         "resolve": "^1.10.0",
         "semver": "2 || 3 || 4 || 5",
         "validate-npm-package-license": "^3.0.1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+        }
       }
     },
     "normalize-path": {
@@ -8547,9 +8565,30 @@
       }
     },
     "semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+      "version": "7.3.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+      "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "^6.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
     },
     "semver-greatest-satisfied-range": {
       "version": "1.1.0",
diff --git a/package.json b/package.json
index 25ba849..bdb944a 100644
--- a/package.json
+++ b/package.json
@@ -41,8 +41,8 @@
     "vinyl-source-stream": "^2.0.0"
   },
   "devDependencies": {
-    "babel-plugin-transform-react-jsx": "^6.24.1",
     "babel-plugin-transform-h-jsx": "^1.0.0",
+    "babel-plugin-transform-react-jsx": "^6.24.1",
     "babel-preset-react": "^6.24.1",
     "babelify": "^7.3.0",
     "eslint": "^5.16.0",
@@ -54,6 +54,7 @@
     "eslint-plugin-standard": "^4.0.0",
     "glob": "^7.0.3",
     "gulp-htmllint": "^0.0.5",
+    "semver": "^7.3.4",
     "simplecrawler": "^0.5.2"
   },
   "repository": "github:apache/cordova-docs",
diff --git a/tools/bin/gen_versions.js b/tools/bin/gen_versions.js
index 9b51259..dc06ec9 100644
--- a/tools/bin/gen_versions.js
+++ b/tools/bin/gen_versions.js
@@ -19,7 +19,7 @@
 
 var path = require('path');
 var yaml = require('js-yaml');
-
+const semver = require('semver');
 var util = require('./util');
 
 // constants
@@ -55,6 +55,26 @@
         var langPath = path.join(rootDir, langId);
         var versionNames = util.listdirsSync(langPath);
 
+        // Remove dev version for semver sort. We'll add it back later.
+        versionNames.splice(versionNames.indexOf('dev'), 1);
+
+        // semver doesn't like a value of 10.x, so we'll coerce the values into proper 10.0.0,
+        // and store a map to easily convert map our sorted away back to our desired text.
+        let coercionMap = {};
+        versionNames = versionNames.map((v) => {
+            let coerced = semver.coerce(v).toString();
+            coercionMap[coerced] = v;
+            return coerced;
+        });
+
+        versionNames = semver.sort(versionNames);
+
+        // Now we can restore our desired labelling
+        versionNames = versionNames.map((v) => coercionMap[v]);
+
+        // Finally, don't forget to restore our dev version
+        versionNames.push('dev');
+
         // get language ID
         var langName = LANGUAGE_MAP[langId];
         if (!langName) {