@reliverse/rempts 1.7.8 → 1.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -910,7 +910,7 @@ $ bun example/launcher/modern.ts build --entry "[foo.ts," "bar.ts]"
910
910
  ⚠ If you intended to pass a bracketed list, quote the whole value like: --entry "[a, b, c]"
911
911
  ```
912
912
 
913
- #### 6. All together
913
+ #### 7. All together
914
914
 
915
915
  ```bash
916
916
  mycli input.txt --verbose --name Alice --count 3 --tags foo --tags bar
@@ -923,6 +923,66 @@ mycli input.txt --verbose --name Alice --count 3 --tags foo --tags bar
923
923
  # }
924
924
  ```
925
925
 
926
+ #### 8. Value Validation with `allowed`
927
+
928
+ All argument types support an optional `allowed` property that restricts which values can be passed:
929
+
930
+ ```ts
931
+ const main = defineCommand({
932
+ args: {
933
+ // Only allow specific string values
934
+ mode: {
935
+ type: "string",
936
+ allowed: ["development", "production", "test"],
937
+ description: "The mode to run in"
938
+ },
939
+
940
+ // Only allow specific boolean values (e.g. if you only want true)
941
+ force: {
942
+ type: "boolean",
943
+ allowed: [true],
944
+ description: "Force the operation"
945
+ },
946
+
947
+ // Only allow specific numbers
948
+ level: {
949
+ type: "number",
950
+ allowed: [1, 2, 3],
951
+ description: "The level to use"
952
+ },
953
+
954
+ // Only allow specific values in an array
955
+ tags: {
956
+ type: "array",
957
+ allowed: ["web", "api", "mobile"],
958
+ description: "Tags to apply"
959
+ },
960
+
961
+ // Only allow specific positional values
962
+ action: {
963
+ type: "positional",
964
+ allowed: ["build", "serve", "test"],
965
+ description: "The action to perform"
966
+ }
967
+ }
968
+ });
969
+ ```
970
+
971
+ If someone tries to pass a value that's not in the `allowed` list, they'll get a helpful error message:
972
+
973
+ ```bash
974
+ mycli --mode staging
975
+ # Error: Invalid value for --mode: staging. Allowed values are: development, production, test
976
+
977
+ mycli --level 4
978
+ # Error: Invalid value for --level: 4. Allowed values are: 1, 2, 3
979
+
980
+ mycli --tags desktop
981
+ # Error: Invalid value in array --tags: desktop. Allowed values are: web, api, mobile
982
+ ```
983
+
984
+ The validation happens after type casting, so for example with numbers, the input will first be converted to a number and then checked against the allowed list.
985
+
926
986
  ## Contributing
927
987
 
928
988
  Bug report? Prompt idea? Want to build the best DX possible?
@@ -960,7 +1020,7 @@ All APIs are fully typed. See [`src/types.ts`](./src/types.ts) for advanced cust
960
1020
  ## Related
961
1021
 
962
1022
  - [`@reliverse/cli`](https://npmjs.com/package/@reliverse/cli) – CLI-first toolkit for fullstack workflows
963
- - [`@reliverse/reliarg`](https://npmjs.com/package/@reliverse/reliarg) – Tiny, strict, zero-dep argument parser
1023
+ - [`@reliverse/reliarg`](https://npmjs.com/package/@reliverse/reliarg) – Tiny, strict, zero-dep argument parser with value validation support (`allowed` property for restricting argument values)
964
1024
  - [`@reliverse/reglob`](https://npmjs.com/package/@reliverse/reglob) – Fast, minimal file matcher
965
1025
  - [`@reliverse/relinka`](https://npmjs.com/package/@reliverse/relinka) – Styled CLI logs, steps, and symbols
966
1026
 
@@ -3,6 +3,7 @@ type EmptyArgs = Record<string, never>;
3
3
  type BaseArgProps = {
4
4
  description?: string;
5
5
  required?: boolean;
6
+ allowed?: string[];
6
7
  };
7
8
  type PositionalArgDefinition = {
8
9
  type: "positional";
@@ -11,6 +12,7 @@ type PositionalArgDefinition = {
11
12
  type BooleanArgDefinition = {
12
13
  type: "boolean";
13
14
  default?: boolean;
15
+ allowed?: boolean[];
14
16
  } & BaseArgProps;
15
17
  type StringArgDefinition = {
16
18
  type: "string";
@@ -19,6 +21,7 @@ type StringArgDefinition = {
19
21
  type NumberArgDefinition = {
20
22
  type: "number";
21
23
  default?: number;
24
+ allowed?: number[];
22
25
  } & BaseArgProps;
23
26
  type ArrayArgDefinition = {
24
27
  type: "array";
@@ -654,25 +654,51 @@ function castArgValue(def, rawVal, argName) {
654
654
  }
655
655
  return def.default ?? void 0;
656
656
  }
657
+ let castedValue;
657
658
  switch (def.type) {
658
659
  case "boolean":
659
660
  if (typeof rawVal === "string") {
660
661
  const lower = rawVal.toLowerCase();
661
- if (lower === "true") return true;
662
- if (lower === "false") return false;
662
+ if (lower === "true") castedValue = true;
663
+ else if (lower === "false") castedValue = false;
664
+ else castedValue = Boolean(rawVal);
665
+ } else {
666
+ castedValue = Boolean(rawVal);
667
+ }
668
+ if (def.allowed && !def.allowed.includes(castedValue)) {
669
+ throw new Error(
670
+ `Invalid value for --${argName}: ${rawVal}. Allowed values are: ${def.allowed.join(", ")}`
671
+ );
663
672
  }
664
- return Boolean(rawVal);
673
+ return castedValue;
665
674
  case "string":
666
- return typeof rawVal === "string" ? rawVal : String(rawVal);
675
+ castedValue = typeof rawVal === "string" ? rawVal : String(rawVal);
676
+ if (def.allowed && !def.allowed.includes(castedValue)) {
677
+ throw new Error(
678
+ `Invalid value for --${argName}: ${rawVal}. Allowed values are: ${def.allowed.join(", ")}`
679
+ );
680
+ }
681
+ return castedValue;
667
682
  case "number": {
668
683
  const n = Number(rawVal);
669
684
  if (Number.isNaN(n)) {
670
685
  throw new Error(`Invalid number provided for --${argName}: ${rawVal}`);
671
686
  }
687
+ if (def.allowed && !def.allowed.includes(n)) {
688
+ throw new Error(
689
+ `Invalid value for --${argName}: ${rawVal}. Allowed values are: ${def.allowed.join(", ")}`
690
+ );
691
+ }
672
692
  return n;
673
693
  }
674
694
  case "positional":
675
- return String(rawVal);
695
+ castedValue = String(rawVal);
696
+ if (def.allowed && !def.allowed.includes(castedValue)) {
697
+ throw new Error(
698
+ `Invalid value for <${argName}>: ${rawVal}. Allowed values are: ${def.allowed.join(", ")}`
699
+ );
700
+ }
701
+ return castedValue;
676
702
  case "array": {
677
703
  const arrVal = Array.isArray(rawVal) ? rawVal : [String(rawVal)];
678
704
  const result = [];
@@ -705,6 +731,11 @@ function castArgValue(def, rawVal, argName) {
705
731
  `Array argument --${argName}: Quoted values are not supported due to shell parsing limitations. Please avoid using single or double quotes around array elements.`
706
732
  );
707
733
  }
734
+ if (def.allowed && !def.allowed.includes(p)) {
735
+ throw new Error(
736
+ `Invalid value in array --${argName}: ${p}. Allowed values are: ${def.allowed.join(", ")}`
737
+ );
738
+ }
708
739
  });
709
740
  result.push(...parts);
710
741
  }
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "license": "MIT",
29
29
  "name": "@reliverse/rempts",
30
30
  "type": "module",
31
- "version": "1.7.8",
31
+ "version": "1.7.10",
32
32
  "author": "reliverse",
33
33
  "bugs": {
34
34
  "email": "blefnk@gmail.com",
@@ -44,7 +44,7 @@
44
44
  "devDependencies": {
45
45
  "@biomejs/biome": "1.9.4",
46
46
  "@eslint/js": "^9.26.0",
47
- "@reliverse/dler": "^1.2.3",
47
+ "@reliverse/dler": "^1.2.4",
48
48
  "@reliverse/relidler-cfg": "^1.1.3",
49
49
  "@stylistic/eslint-plugin": "^4.2.0",
50
50
  "@total-typescript/ts-reset": "^0.6.1",