Repository: oclif/core
Pull request #447 (2022-07-20 22:35:48)

feat: min/max for integer flag


Patch:
diff --git a/package.json b/package.json
index e3fff22..3c86612 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,7 @@
     "typescript": "4.5.5"
   },
   "engines": {
-    "node": ">=12.0.0"
+    "node": ">=14.0.0"
   },
   "files": [
     "/lib",
diff --git a/src/parser/flags.ts b/src/parser/flags.ts
index b6bdc8d..4d18c6b 100644
--- a/src/parser/flags.ts
+++ b/src/parser/flags.ts
@@ -35,13 +35,21 @@ export function boolean<T = boolean>(
   } as BooleanFlag<T>
 }
 
-export const integer = build({
-  parse: async input => {
-    if (!/^-?\d+$/.test(input))
-      throw new Error(`Expected an integer but received: ${input}`)
-    return Number.parseInt(input, 10)
-  },
-})
+export const integer = (opts: { min?: number; max?: number} & Partial<OptionFlag<number>> = {}): OptionFlag<number | undefined> => {
+  return build<number>({
+    ...opts,
+    parse: async input => {
+      if (!/^-?\d+$/.test(input))
+        throw new Error(`Expected an integer but received: ${input}`)
+      const num = Number.parseInt(input, 10)
+      if (opts.min !== undefined && num < opts.min)
+        throw new Error(`Expected an integer greater than or equal to ${opts.min} but received: ${input}`)
+      if (opts.max !== undefined && num > opts.max)
+        throw new Error(`Expected an integer less than or equal to ${opts.max} but received: ${input}`)
+      return num
+    },
+  })()
+}
 
 export const directory = (opts: { exists?: boolean } & Partial<OptionFlag<string>> = {}): OptionFlag<string | undefined> => {
   return build<string>({
diff --git a/tsconfig.json b/tsconfig.json
index 4e44a52..c994370 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,8 +9,8 @@
       "./src"
     ],
     "strict": true,
-    "target": "es2019",
-    "lib": ["es2019"],
+    "target": "es2020",
+    "lib": ["es2020"],
     "allowSyntheticDefaultImports": true
   },
   "include": [


Test patch:
diff --git a/test/parser/parse.test.ts b/test/parser/parse.test.ts
index 0fc6d48..35d4900 100644
--- a/test/parser/parse.test.ts
+++ b/test/parser/parse.test.ts
@@ -428,6 +428,58 @@ See more help with --help`)
 
         expect(message).to.equal('Expected an integer but received: s10')
       })
+
+      describe('min/max', () => {
+        it('min pass equal', async () => {
+          const out = await parse(['--int', '10'], {
+            flags: {int: flags.integer({min: 10, max: 20})},
+          })
+          expect(out.flags).to.deep.include({int: 10})
+        })
+        it('min pass gt', async () => {
+          const out = await parse(['--int', '11'], {
+            flags: {int: flags.integer({min: 10, max: 20})},
+          })
+          expect(out.flags).to.deep.include({int: 11})
+        })
+        it('max pass lt', async () => {
+          const out = await parse(['--int', '19'], {
+            flags: {int: flags.integer({min: 10, max: 20})},
+          })
+          expect(out.flags).to.deep.include({int: 19})
+        })
+        it('max pass equal', async () => {
+          const out = await parse(['--int', '20'], {
+            flags: {int: flags.integer({min: 10, max: 20})},
+          })
+          expect(out.flags).to.deep.include({int: 20})
+        })
+
+        it('min fail lt', async () => {
+          let message = ''
+          try {
+            await parse(['--int', '9'], {
+              flags: {int: flags.integer({min: 10, max: 20})},
+            })
+          } catch (error: any) {
+            message = error.message
+          }
+
+          expect(message).to.equal('Expected an integer greater than or equal to 10 but received: 9')
+        })
+        it('max fail gt', async () => {
+          let message = ''
+          try {
+            await parse(['--int', '21'], {
+              flags: {int: flags.integer({min: 10, max: 20})},
+            })
+          } catch (error: any) {
+            message = error.message
+          }
+
+          expect(message).to.equal('Expected an integer less than or equal to 20 but received: 21')
+        })
+      })
     })
   })