diff --git a/package-lock.json b/package-lock.json index 3436e21f..cf15c09b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,9 @@ "colors": "1.4.0", "common-env": "^6.4.0", "curlconverter": "^3.21.0", + "duration-js": "^4.0.0", "eventsource": "^1.1.0", + "iso8601-duration": "^2.1.2", "isomorphic-git": "^1.25.3", "linux-release-info": "^3.0.0", "lodash": "^4.17.21", @@ -2238,6 +2240,11 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, + "node_modules/duration-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/duration-js/-/duration-js-4.0.0.tgz", + "integrity": "sha512-qoXjOsH97r+NrOa6sK5V2cwBOouVG/LI9jwgwKvjVkyqGpZ72yilWjjzFJYPqqbvNZDwpRMaLEUFE+PTefvOEA==" + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -4566,6 +4573,11 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "node_modules/iso8601-duration": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/iso8601-duration/-/iso8601-duration-2.1.2.tgz", + "integrity": "sha512-yXteYUiKv6x8seaDzyBwnZtPpmx766KfvQuaVNyPifYOjmPdOo3ajd4phDNa7Y5mTQGnXsNEcXFtVun1FjYXxQ==" + }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", @@ -9929,6 +9941,11 @@ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, + "duration-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/duration-js/-/duration-js-4.0.0.tgz", + "integrity": "sha512-qoXjOsH97r+NrOa6sK5V2cwBOouVG/LI9jwgwKvjVkyqGpZ72yilWjjzFJYPqqbvNZDwpRMaLEUFE+PTefvOEA==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -11638,6 +11655,11 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "iso8601-duration": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/iso8601-duration/-/iso8601-duration-2.1.2.tgz", + "integrity": "sha512-yXteYUiKv6x8seaDzyBwnZtPpmx766KfvQuaVNyPifYOjmPdOo3ajd4phDNa7Y5mTQGnXsNEcXFtVun1FjYXxQ==" + }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", diff --git a/package.json b/package.json index 93edb377..f0ac3d10 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ "colors": "1.4.0", "common-env": "^6.4.0", "curlconverter": "^3.21.0", + "duration-js": "^4.0.0", "eventsource": "^1.1.0", + "iso8601-duration": "^2.1.2", "isomorphic-git": "^1.25.3", "linux-release-info": "^3.0.0", "lodash": "^4.17.21", diff --git a/src/parsers.js b/src/parsers.js index eed14a8f..2d628326 100644 --- a/src/parsers.js +++ b/src/parsers.js @@ -3,6 +3,8 @@ const cliparse = require('cliparse'); const Application = require('./models/application.js'); +const ISO8601 = require('iso8601-duration'); +const Duration = require('duration-js'); function flavor (flavor) { const flavors = Application.listAvailableFlavors(); @@ -143,6 +145,40 @@ function portNumber (number) { return cliparse.parsers.error(`Invalid port number '${number}'. Should match ${portNumberRegex}`); } +/** + * Parse a duration into seconds + * A Zero seconds duration is allowed + * @param {string} durationStr an ISO8601, 1h or a positive number + * @returns {number} number of seconds + */ +function durationInSeconds (durationStr = '') { + const failed = cliparse.parsers.error(`Invalid duration: "${durationStr}", expect (IS0 8601 duration / a "1h, 1m, 30s" like duration / a positive number in seconds)`); + + if (durationStr.startsWith('P')) { + try { + const d = ISO8601.parse(durationStr); + return cliparse.parsers.success(ISO8601.toSeconds(d)); + } + catch (err) { + return failed; + } + } + + try { + const duration = Duration.parse(durationStr); + return cliparse.parsers.success(duration.seconds()); + } + catch (err) { + const n = Number.parseInt(durationStr); + console.log(`N: ${n}`); + if (isNaN(n) || n < 0) { + return failed; + } + + return cliparse.parsers.success(n); + } +} + module.exports = { buildFlavor, flavor, @@ -162,4 +198,5 @@ module.exports = { ipAddress, portNumberRegex, portNumber, + durationInSeconds, };