@optique/core 1.0.0-dev.705 → 1.0.0-dev.721

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.
@@ -308,6 +308,15 @@ function integer(options) {
308
308
  }
309
309
  const metavar = options?.metavar ?? "INTEGER";
310
310
  require_nonempty.ensureNonEmptyString(metavar);
311
+ const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
312
+ const minSafe = BigInt(Number.MIN_SAFE_INTEGER);
313
+ const unsafeIntegerError = options?.errors?.unsafeInteger;
314
+ function makeUnsafeIntegerError(input) {
315
+ return {
316
+ success: false,
317
+ error: unsafeIntegerError ? typeof unsafeIntegerError === "function" ? unsafeIntegerError(input) : unsafeIntegerError : require_message.message`Expected a safe integer between ${require_message.text(Number.MIN_SAFE_INTEGER.toLocaleString("en"))} and ${require_message.text(Number.MAX_SAFE_INTEGER.toLocaleString("en"))}, but got ${input}. Use type: "bigint" for large values.`
318
+ };
319
+ }
311
320
  return {
312
321
  $mode: "sync",
313
322
  metavar,
@@ -316,7 +325,14 @@ function integer(options) {
316
325
  success: false,
317
326
  error: options?.errors?.invalidInteger ? typeof options.errors.invalidInteger === "function" ? options.errors.invalidInteger(input) : options.errors.invalidInteger : require_message.message`Expected a valid integer, but got ${input}.`
318
327
  };
319
- const value = Number.parseInt(input);
328
+ let n;
329
+ try {
330
+ n = BigInt(input);
331
+ } catch {
332
+ return makeUnsafeIntegerError(input);
333
+ }
334
+ if (n > maxSafe || n < minSafe) return makeUnsafeIntegerError(input);
335
+ const value = Number(input);
320
336
  if (options?.min != null && value < options.min) return {
321
337
  success: false,
322
338
  error: options.errors?.belowMinimum ? typeof options.errors.belowMinimum === "function" ? options.errors.belowMinimum(value, options.min) : options.errors.belowMinimum : require_message.message`Expected a value greater than or equal to ${require_message.text(options.min.toLocaleString("en"))}, but got ${input}.`
@@ -279,6 +279,13 @@ interface IntegerOptionsNumber {
279
279
  * @since 0.5.0
280
280
  */
281
281
  invalidInteger?: Message | ((input: string) => Message);
282
+ /**
283
+ * Custom error message when integer is outside the safe integer range
284
+ * (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`).
285
+ * Can be a static message or a function that receives the input string.
286
+ * @since 1.0.0
287
+ */
288
+ unsafeInteger?: Message | ((input: string) => Message);
282
289
  /**
283
290
  * Custom error message when integer is below minimum value.
284
291
  * Can be a static message or a function that receives the value and minimum.
@@ -279,6 +279,13 @@ interface IntegerOptionsNumber {
279
279
  * @since 0.5.0
280
280
  */
281
281
  invalidInteger?: Message | ((input: string) => Message);
282
+ /**
283
+ * Custom error message when integer is outside the safe integer range
284
+ * (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`).
285
+ * Can be a static message or a function that receives the input string.
286
+ * @since 1.0.0
287
+ */
288
+ unsafeInteger?: Message | ((input: string) => Message);
282
289
  /**
283
290
  * Custom error message when integer is below minimum value.
284
291
  * Can be a static message or a function that receives the value and minimum.
@@ -308,6 +308,15 @@ function integer(options) {
308
308
  }
309
309
  const metavar = options?.metavar ?? "INTEGER";
310
310
  ensureNonEmptyString(metavar);
311
+ const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
312
+ const minSafe = BigInt(Number.MIN_SAFE_INTEGER);
313
+ const unsafeIntegerError = options?.errors?.unsafeInteger;
314
+ function makeUnsafeIntegerError(input) {
315
+ return {
316
+ success: false,
317
+ error: unsafeIntegerError ? typeof unsafeIntegerError === "function" ? unsafeIntegerError(input) : unsafeIntegerError : message`Expected a safe integer between ${text(Number.MIN_SAFE_INTEGER.toLocaleString("en"))} and ${text(Number.MAX_SAFE_INTEGER.toLocaleString("en"))}, but got ${input}. Use type: "bigint" for large values.`
318
+ };
319
+ }
311
320
  return {
312
321
  $mode: "sync",
313
322
  metavar,
@@ -316,7 +325,14 @@ function integer(options) {
316
325
  success: false,
317
326
  error: options?.errors?.invalidInteger ? typeof options.errors.invalidInteger === "function" ? options.errors.invalidInteger(input) : options.errors.invalidInteger : message`Expected a valid integer, but got ${input}.`
318
327
  };
319
- const value = Number.parseInt(input);
328
+ let n;
329
+ try {
330
+ n = BigInt(input);
331
+ } catch {
332
+ return makeUnsafeIntegerError(input);
333
+ }
334
+ if (n > maxSafe || n < minSafe) return makeUnsafeIntegerError(input);
335
+ const value = Number(input);
320
336
  if (options?.min != null && value < options.min) return {
321
337
  success: false,
322
338
  error: options.errors?.belowMinimum ? typeof options.errors.belowMinimum === "function" ? options.errors.belowMinimum(value, options.min) : options.errors.belowMinimum : message`Expected a value greater than or equal to ${text(options.min.toLocaleString("en"))}, but got ${input}.`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.705+5cb74130",
3
+ "version": "1.0.0-dev.721+1fa3c379",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",