🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

type-flag

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

type-flag - npm Package Compare versions

Comparing version
5.0.0-beta.17
to
5.0.0-beta.18
+1
dist/internal-D2WkZDO3.mjs
var V=Object.defineProperty;var o=(e,n)=>V(e,"name",{value:n,configurable:!0});const F="flag",P="unknown-flag",O="argument",h=o(e=>(typeof e=="object"||typeof e=="function")&&e!==null&&"~standard"in e,"isStandardSchema"),L=o(e=>(n=>{const t=e["~standard"].validate(n);if(t instanceof Promise)throw new TypeError("Async schemas are not supported");if(t.issues)throw new Error(t.issues[0]?.message??"Validation failed");return t.value}),"schemaToParser"),g="--",k=3,j=/^-{1,2}\w/,C=/^-(?:\d+(?:\.\d*)?|\.\d+)(?:e[-+]?\d+)?$/i,D=o((e,n)=>{if(!C.test(e))return!1;for(let t=1;t<e.length;t+=1)if(!n.has(e[t]))return!0;return!1},"isNegativeNumberValue"),E=o(e=>{if(!j.test(e))return;const n=!e.startsWith(g);let t=e.slice(n?1:2),r,s=-1;for(const l of["=",":","."]){const i=t.indexOf(l);i!==-1&&(s===-1||i<s)&&(s=i)}return s!==-1&&(r=t.slice(s+1),t=t.slice(0,s)),[t,r,n]},"parseFlagArgv"),T=o((e,{onFlag:n,onValue:t,onArgument:r,knownFlags:s})=>{let l=!1;const i=o((a,c)=>{if(!l)return!0;l=!1,t?.(a,c)},"triggerValueCallback");for(let a=0;a<e.length;a+=1){const c=e[a];if(c===g){i();const u=e.slice(a+1);r?.(u,[a],!0);break}if(l&&s&&D(c,s)){i(c,[a]);continue}const f=E(c);if(f){if(i(),!n)continue;const[u,y,x]=f;if(x)for(let p=0;p<u.length;p+=1){i();const A=p===u.length-1;l=n(u[p],A?y:void 0,[a,p+1,A])===!0}else l=n(u,y,[a])===!0}else i(c,[a])&&r?.([c],[a])}i()},"argvIterator"),I=o((e,n)=>{for(let t=n.length-1;t>=0;t-=1){const[r,s,l]=n[t];if(s){const i=e[r];let a=i.slice(0,s);if(l||(a+=i.slice(s+1)),a!=="-"){e[r]=a;continue}}e.splice(r,1)}},"spliceFromArgv"),w=o((e,n)=>Object.assign(e,{[g]:n}),"createPositionalArgumentsFromParts"),U=o(e=>{const n=e.indexOf(g);if(n===-1)return w([...e],[]);const t=e.slice(0,n),r=e.slice(n+1);return w([...t,...r],r)},"createPositionalArguments"),_=/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g,z=/[A-Z]/,N=o(e=>z.test(e)?e.replaceAll(_,"-").toLowerCase():e.toLowerCase(),"flagNameToKebab"),{hasOwnProperty:G}=Object.prototype,b=o((e,n)=>G.call(e,n),"hasOwn"),d=o(e=>h(e)?[L(e),!1]:typeof e=="function"?[e,!1]:Array.isArray(e)?[d(e[0])[0],!0]:d(e.type),"parseFlagType"),Z=o((e,n)=>e===Boolean?n!=="false":n,"normalizeBoolean");class $ extends TypeError{static{o(this,"FlagParseError")}flagName;constructor(n,t){super(`Flag "--${n}": ${t instanceof Error?t.message:t}`,{cause:t}),this.name="FlagParseError",this.flagName=n}}const B=o((e,n,t)=>{if(typeof n=="boolean")return n;if(e===Number&&n==="")return Number.NaN;try{return e(n)}catch(r){throw new $(t,r)}},"applyParser"),M=/[\s.:=]/,R=o(e=>{const n=`Flag name "${e}"`;if(e.length===0)throw new Error(`${n} cannot be empty`);const t=e.match(M);if(t)throw new Error(`${n} cannot contain "${t?.[0]}"`)},"validateFlagName"),m=o((e,n,t)=>{if(e.has(n))throw new Error(`Duplicate flags named "${n}"`);e.set(n,t)},"setFlag"),H=o(e=>{const n=new Map;for(const t in e){if(!b(e,t))continue;R(t);const r=e[t],s=[t,...d(r),r];m(n,t,s);const l=N(t);if(t!==l&&m(n,l,s),"alias"in r&&typeof r.alias=="string"){const{alias:i}=r,a=`Flag alias "${i}" for flag "${t}"`;if(t.length===1)throw new Error(`${a} cannot be defined for a single-character flag`);if(i.length===0)throw new Error(`${a} cannot be empty`);if(i.length>1)throw new Error(`${a} must be a single character`);m(n,i,s)}}return n},"createRegistry"),K=o(e=>{const n=new Map,t=Object.create(null),r=[];for(const s of e)if(s.type===F){let l=n.get(s.name);l||(l=[],n.set(s.name,l)),l.push(s.value)}else s.type===P?(b(t,s.name)||(t[s.name]=[]),t[s.name].push(s.value)):r.push(s.value);return{knownFlagValues:n,unknownFlags:t,positionals:r}},"groupEntries"),W=o((e,n,t)=>{if((!t||t.length===0)&&!h(e)&&"default"in e){const{default:r}=e;return typeof r=="function"?r():r}return n?t??[]:t&&t.at(-1)},"resolveFlagValue"),X=o((e,n,t,r)=>{const{knownFlagValues:s,unknownFlags:l,positionals:i}=K(t),a=Object.create(null);for(const c in e){if(!b(e,c))continue;const f=n.get(c);f&&(a[c]=W(f[3],f[2],s.get(c)))}return{flags:a,unknownFlags:l,_:w([...i,...r],r)}},"finalizeParsed");export{k as A,F,P as U,T as a,O as b,H as c,B as d,d as e,X as f,$ as g,U as h,N as i,h as j,Z as n,E as p,I as s};
/**
* Standard Schema (https://standardschema.dev) support: the vendored v1 spec
* types plus the runtime helpers type-flag uses to detect and adapt schemas.
* The spec is vendored rather than depended on to keep type-flag zero-dependency.
*/
/**
* Minimal vendored subset of the Standard Schema spec, v1. Mirrors
* `@standard-schema/spec`. Kept byte-compatible with upstream, which relies on a
* namespace merged with an interface of the same name, so the conflicting
* stylistic rules are disabled here.
*/
declare namespace StandardSchemaV1 {
interface Props<Input = unknown, Output = Input> {
readonly version: 1;
readonly vendor: string;
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
readonly types?: Types<Input, Output> | undefined;
}
type Result<Output> = SuccessResult<Output> | FailureResult;
interface SuccessResult<Output> {
readonly value: Output;
readonly issues?: undefined;
}
interface FailureResult {
readonly issues: ReadonlyArray<Issue>;
}
interface Issue {
readonly message: string;
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
}
interface PathSegment {
readonly key: PropertyKey;
}
interface Types<Input = unknown, Output = Input> {
readonly input: Input;
readonly output: Output;
}
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
}
interface StandardSchemaV1<Input = unknown, Output = Input> {
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
}
/**
* Detect a Standard Schema (Zod, Valibot, ArkType, ...). Used to accept schemas
* directly as flag types, and exported so tools built on type-flag can apply the
* same check when introspecting flag definitions.
*/
declare const isStandardSchema: (value: unknown) => value is StandardSchemaV1;
type Simplify<T> = {
[Key in keyof T]: T[Key];
} & {};
/**
* A function that processes a command-line argument and returns a typed value.
*
* @example
* ```ts
* const toUpperCase = (value: string) => value.toUpperCase();
* ```
*/
type TypeFunction<ReturnType = unknown> = (...args: any[]) => ReturnType;
/**
* The value used to type a flag: a parser function or a Standard Schema.
*/
type FlagTypeValue = TypeFunction | StandardSchemaV1;
/**
* A shorthand for defining a flag's type.
*
* - Use a single `TypeFunction` or Standard Schema to accept one value.
* - Use a readonly tuple (e.g. `[TypeFunction]`) to accept multiple values (as an array).
*
* @see FlagSchema
*/
type FlagType = (FlagTypeValue | readonly [FlagTypeValue]);
/**
* Workaround for TypeScript bug where `Readonly<T>` in parameter position breaks
* conditional type matching in return type. Adding `& AnyObject` to extends clauses
* fixes the matcher.
*
* @see https://github.com/microsoft/TypeScript/issues/62720
*/
type AnyObject = Record<PropertyKey, unknown>;
/**
* Defines the complete schema for a command-line flag.
*/
type FlagSchema = {
/**
* The function or tuple of functions that parse the `argv` string into a typed value.
*
* @example
* ```ts
* type: String
* ```
* @example
* ```ts
* type: [Boolean]
* ```
* @example
* ```ts
* type: (value: string) => moment(value).toDate()
* ```
*/
type: FlagType;
/**
* A single-character alias for the flag.
*
* @example
* ```ts
* alias: 's'
* ```
*/
alias?: string;
/**
* The default value for the flag if not provided.
* Can also be a function that returns the default.
*
* @example
* ```ts
* default: 'hello'
* ```
* @example
* ```ts
* default: () => [1, 2, 3]
* ```
*/
default?: unknown | (() => unknown);
} & AnyObject;
/**
* A flag definition can either be a `FlagType` or a full `FlagSchema` object.
*/
type FlagTypeOrSchema<ExtraOptions = Record<string, unknown>> = FlagType | (FlagSchema & ExtraOptions);
/**
* A map of flag names to their definitions.
*/
type Flags<ExtraOptions = Record<string, unknown>> = {
[flagName: string]: FlagTypeOrSchema<ExtraOptions>;
};
/**
* Positional arguments with post-`--` values exposed separately.
*/
type PositionalArguments = string[] & {
/** Arguments that appeared after the `--` separator. */
'--': string[];
};
type InferDefaultType<Flag extends FlagTypeOrSchema, Fallback> = Flag extends {
default: infer DefaultType | (() => infer DefaultType);
} & AnyObject ? DefaultType : Fallback;
/**
* Resolves the output type of a single flag-type element: a parser function's
* return type, or a Standard Schema's output type.
*/
type InferType<Element> = (Element extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Element> : Element extends TypeFunction<infer Return> ? Return : never);
type FlagTypeOf<Flag> = (Flag extends {
type: infer Type extends FlagType;
} & AnyObject ? Type : Flag);
/**
* Infers the final JavaScript type of a flag from its schema.
*
* `FlagTypeOf` unwraps the `{ type }` object form first, so only the two
* underlying shapes (array vs scalar) need matching. `InferType` then resolves
* each element whether it is a function or a schema.
*/
type InferFlagType<Flag extends FlagTypeOrSchema> = (FlagTypeOf<Flag> extends readonly [infer Element extends FlagTypeValue] ? InferArrayType<Flag, Element> : FlagTypeOf<Flag> extends infer Element extends FlagTypeValue ? InferScalarType<Flag, Element> : unknown);
type InferArrayType<Flag extends FlagTypeOrSchema, Element> = (InferType<Element> extends infer Output ? (Output[] | InferDefaultType<Flag, never>) : never);
type InferScalarType<Flag extends FlagTypeOrSchema, Element> = (InferType<Element> extends infer Output ? ([
Output
] extends [never] ? Output : (Output | InferDefaultType<Flag, undefined>)) : never);
/**
* The fully inferred return type from a given flag schema configuration.
*/
type TypeFlag<Schemas extends Flags = Flags> = {
/** Parsed values keyed by flag name. */
flags: {
[flag in keyof Schemas]: InferFlagType<Schemas[flag]>;
};
/** Flags that were passed but not defined in the schema. */
unknownFlags: {
[flagName: string]: (string | boolean)[];
};
/**
* Positional arguments (non-flag values).
* Includes a special `"--"` key for arguments after the double dash.
*/
_: PositionalArguments;
/**
* Every interpreted argv element, in the order it appeared on the command
* line. Unlike `flags` (which groups values by flag name), this preserves the
* relative order across different flags and positional arguments.
*
* Only covers what the parser interprets: elements after the `--` delimiter
* are not parsed, so they are excluded here (find them in `_['--']`).
*
* Advanced: most CLIs only need `flags`. Reach for `entries` when the order
* of operations across different flags matters — e.g. assembling a curl-style
* request body from interleaved `-d` and `--data-urlencode`.
*/
entries: ParsedArgvEntry[];
};
/** Constant indicating a defined (schema) flag token type. */
declare const FLAG = "flag";
/** Constant indicating an unknown flag token type. */
declare const UNKNOWN_FLAG = "unknown-flag";
/** Constant indicating a positional argument token type. */
declare const ARGUMENT = "argument";
/**
* A single interpreted argv element from {@link TypeFlag.entries}, discriminated
* by `type`.
*/
type ParsedArgvEntry = {
type: typeof FLAG;
/**
* Canonical schema key — always the name as declared in the schema
* (e.g. `dataUrlencode`), regardless of whether the alias (`-d`),
* kebab-case (`--data-urlencode`), or camelCase form was used in argv.
*/
name: string;
/** Parsed value for this single occurrence. */
value: unknown;
} | {
type: typeof UNKNOWN_FLAG;
/** Raw flag name as it appeared in argv (not camelCased). */
name: string;
/** Explicit value, or `true` when the flag had no value. */
value: string | boolean;
} | {
type: typeof ARGUMENT;
/** The positional argument value. */
value: string;
};
/**
* A function to dynamically ignore specific elements during parsing.
* Return `true` to skip the element, or `false`/`undefined` to process it normally.
*
* @param type - The type of element being processed:
* - `'argument'`: A positional argument (non-flag value)
* - `'flag'`: A flag defined in the schema
* - `'unknown-flag'`: A flag not defined in the schema
* @param argvElement - The raw argv string. For arguments, this is the value itself.
* For flags, this is the flag name (e.g., `'--verbose'` or `'-v'`).
* @param flagValue - The value associated with a flag, if any.
* - For flags with explicit values: the string value (e.g., `'--port=3000'` → `'3000'`)
* - For boolean flags or flags without values: `undefined`
* - For arguments (`type === 'argument'`): always `undefined`
* @returns `true` to ignore/skip this element, `false` or `undefined` to process it
*
* @example
* ```ts
* // Ignore all unknown flags
* ignore: (type) => type === 'unknown-flag'
* ```
*
* @example
* ```ts
* // Ignore arguments starting with a dot
* ignore: (type, argvElement) => type === 'argument' && argvElement.startsWith('.')
* ```
*
* @example
* ```ts
* // Ignore a specific flag
* ignore: (type, argvElement) => argvElement === '--internal-only'
* ```
*/
type IgnoreFunction = (type: typeof ARGUMENT | typeof FLAG | typeof UNKNOWN_FLAG, argvElement: string, flagValue?: string) => boolean | void;
/**
* Options to customize the flag parsing behavior.
*/
type TypeFlagOptions = {
/**
* Optional function to skip certain argv elements from parsing.
*/
ignore?: IgnoreFunction;
/**
* Enable `--no-<flag>` negation for boolean flags.
*
* When enabled, `--no-verbose` is equivalent to `--verbose=false`.
* Only applies to flags defined as `Boolean` in the schema.
* Last-wins semantics apply between `--flag` and `--no-flag`.
*/
booleanNegation?: boolean;
};
/**
* Normalize a schema-declared flag name (e.g. `orgID`, `apiURL`, `fooBar`,
* `oauth2Bearer`) to the kebab-case form that matches argv tokens
* (`--org-id`, `--api-url`, `--foo-bar`, `--oauth2-bearer`).
* Preserves acronyms as single segments.
*
* @example
* ```ts
* flagNameToKebab('orgID') // => 'org-id'
* flagNameToKebab('apiURL') // => 'api-url'
* flagNameToKebab('parseJSONData') // => 'parse-json-data'
* flagNameToKebab('fooBar') // => 'foo-bar'
* flagNameToKebab('oauth2Bearer') // => 'oauth2-bearer'
* ```
*/
declare const flagNameToKebab: (name: string) => string;
/**
* Thrown when a flag's parser/validator (a custom type function or a Standard
* Schema) rejects the value. Extends `TypeError` for backward compatibility, so
* `instanceof TypeError` keeps working while `instanceof FlagParseError` gives a
* precise handle. The original error is preserved on `cause`.
*/
declare class FlagParseError extends TypeError {
/** The flag whose value failed to parse, without the `--` prefix (e.g. `sort`). */
flagName: string;
constructor(flagName: string, cause: unknown);
}
export { FlagParseError as c, StandardSchemaV1 as f, flagNameToKebab as g, isStandardSchema as i };
export type { Flags as F, InferFlagType as I, ParsedArgvEntry as P, Simplify as S, TypeFlagOptions as T, TypeFlag as a, FlagType as b, IgnoreFunction as d, PositionalArguments as e };
+2
-2

@@ -1,3 +0,3 @@

import { F as Flags, T as TypeFlagOptions, S as Simplify, a as TypeFlag, b as FlagType, I as InferFlagType } from './types-56gEijE9.js';
export { c as IgnoreFunction, P as ParsedArgvEntry, d as PositionalArguments } from './types-56gEijE9.js';
import { F as Flags, T as TypeFlagOptions, S as Simplify, a as TypeFlag, b as FlagType, I as InferFlagType } from './utils-CTDTTfMI.js';
export { c as FlagParseError, d as IgnoreFunction, P as ParsedArgvEntry, e as PositionalArguments } from './utils-CTDTTfMI.js';

@@ -4,0 +4,0 @@ /**

@@ -1,1 +0,1 @@

var E=Object.defineProperty;var l=(u,n)=>E(u,"name",{value:n,configurable:!0});import{c as P,a as D,s as G,f as T,A as U,F as m,U as L,n as R,b,d as B,p as _,e as k}from"./internal-DXo-neGg.mjs";const z=l((u,n=process.argv.slice(2),{ignore:c,booleanNegation:v}={})=>{const r=[],p=P(u),a=[];let i=[],h,f,F,t;const o=l((s,e)=>{r.push(F),e&&r.push(e),a.push({type:m,name:h,value:B(f,s||"",t)})},"flushFlagValue");return D(n,{knownFlags:p,onFlag(s,e,g){const N=g.length===U,d=N||s.length>1?p.get(s):void 0;let y;if(!d&&v&&!N&&s.length>3&&s.startsWith("no-")){const A=p.get(s.slice(3));A&&A[1]===Boolean&&([y]=A)}if(!c?.(d||y?m:L,s,e)){if(d){const[A,V]=d;h=A,f=V,F=g,t=s;const w=R(V,e);if(w===void 0)return!0;o(w);return}if(y){a.push({type:m,name:y,value:!1}),r.push(g);return}a.push({type:L,name:s,value:e===void 0?!0:e}),r.push(g)}},onValue:o,onArgument:l((s,e,g)=>{if(!c?.(b,n[e[0]])){if(g){i=s,n.splice(e[0]);return}for(const N of s)a.push({type:b,value:N});r.push(e)}},"onArgument")}),G(n,r),{...T(u,p,a,i),entries:a}},"typeFlag"),S=l((u,n,c=process.argv.slice(2))=>{const v=new Set(u.split(",").map(t=>_(t)?.[0])),[r,p]=k(n),a=[],i=[];let h,f;const F=l((t,o,s,e)=>{i.push(t),e&&i.push(e),a.push(B(r,s||"",o))},"pushValue");return D(c,{knownFlags:v,onFlag:l((t,o,s)=>{if(!v.has(t)||!p&&a.length>0)return;const e=R(r,o);if(e===void 0)return h=s,f=t,!0;F(s,t,e)},"onFlag"),onValue:l((t,o)=>{F(h,f,t,o)},"onValue")}),G(c,i),p?a:a[0]},"getFlag");export{S as getFlag,z as typeFlag};
var b=Object.defineProperty;var l=(u,n)=>b(u,"name",{value:n,configurable:!0});import{c as B,a as D,s as E,f as T,A as U,F as m,U as G,n as L,b as P,d as R,p as _,e as k}from"./internal-D2WkZDO3.mjs";import{g as X}from"./internal-D2WkZDO3.mjs";const z=l((u,n=process.argv.slice(2),{ignore:c,booleanNegation:v}={})=>{const a=[],p=B(u),r=[];let g=[],f,h,F,t;const o=l((s,e)=>{a.push(F),e&&a.push(e),r.push({type:m,name:f,value:R(h,s||"",t)})},"flushFlagValue");return D(n,{knownFlags:p,onFlag(s,e,i){const N=i.length===U,d=N||s.length>1?p.get(s):void 0;let y;if(!d&&v&&!N&&s.length>3&&s.startsWith("no-")){const A=p.get(s.slice(3));A&&A[1]===Boolean&&([y]=A)}if(!c?.(d||y?m:G,s,e)){if(d){const[A,V]=d;f=A,h=V,F=i,t=s;const w=L(V,e);if(w===void 0)return!0;o(w);return}if(y){r.push({type:m,name:y,value:!1}),a.push(i);return}r.push({type:G,name:s,value:e===void 0?!0:e}),a.push(i)}},onValue:o,onArgument:l((s,e,i)=>{if(!c?.(P,n[e[0]])){if(i){g=s,n.splice(e[0]);return}for(const N of s)r.push({type:P,value:N});a.push(e)}},"onArgument")}),E(n,a),{...T(u,p,r,g),entries:r}},"typeFlag"),S=l((u,n,c=process.argv.slice(2))=>{const v=new Set(u.split(",").map(t=>_(t)?.[0])),[a,p]=k(n),r=[],g=[];let f,h;const F=l((t,o,s,e)=>{g.push(t),e&&g.push(e),r.push(R(a,s||"",o))},"pushValue");return D(c,{knownFlags:v,onFlag:l((t,o,s)=>{if(!v.has(t)||!p&&r.length>0)return;const e=L(a,o);if(e===void 0)return f=s,h=t,!0;F(s,t,e)},"onFlag"),onValue:l((t,o)=>{F(f,h,t,o)},"onValue")}),E(c,g),p?r:r[0]},"getFlag");export{X as FlagParseError,S as getFlag,z as typeFlag};

@@ -1,22 +0,5 @@

import { d as PositionalArguments } from './types-56gEijE9.js';
export { e as StandardSchemaV1, i as isStandardSchema } from './types-56gEijE9.js';
import { e as PositionalArguments } from './utils-CTDTTfMI.js';
export { f as StandardSchemaV1, g as flagNameToKebab, i as isStandardSchema } from './utils-CTDTTfMI.js';
/**
* Normalize a schema-declared flag name (e.g. `orgID`, `apiURL`, `fooBar`,
* `oauth2Bearer`) to the kebab-case form that matches argv tokens
* (`--org-id`, `--api-url`, `--foo-bar`, `--oauth2-bearer`).
* Preserves acronyms as single segments.
*
* @example
* ```ts
* flagNameToKebab('orgID') // => 'org-id'
* flagNameToKebab('apiURL') // => 'api-url'
* flagNameToKebab('parseJSONData') // => 'parse-json-data'
* flagNameToKebab('fooBar') // => 'foo-bar'
* flagNameToKebab('oauth2Bearer') // => 'oauth2-bearer'
* ```
*/
declare const flagNameToKebab: (name: string) => string;
/**
* Build a {@link PositionalArguments} array from raw argv, splitting on the

@@ -27,2 +10,2 @@ * `--` delimiter so tokens after `--` are also exposed on the `'--'` property.

export { createPositionalArguments, flagNameToKebab };
export { createPositionalArguments };

@@ -1,1 +0,1 @@

import{g as s,h as o,i as r}from"./internal-DXo-neGg.mjs";export{s as createPositionalArguments,o as flagNameToKebab,r as isStandardSchema};
import{h as s,i as o,j as r}from"./internal-D2WkZDO3.mjs";export{s as createPositionalArguments,o as flagNameToKebab,r as isStandardSchema};
{
"name": "type-flag",
"version": "5.0.0-beta.17",
"version": "5.0.0-beta.18",
"description": "Typed command-line arguments parser",

@@ -5,0 +5,0 @@ "keywords": [

@@ -444,11 +444,18 @@ <p align="center">

When a custom type parser throws, the error is wrapped in a `TypeError` whose message identifies the flag by name. The original error is preserved on `.cause`.
When a custom type parser (or [Standard Schema](#standard-schema-zod-valibot-arktype)) throws, the error is wrapped in a `FlagParseError` whose message identifies the flag by name. The original error is preserved on `.cause`, and the flag name on `.flagName`.
`FlagParseError extends TypeError`, so existing `instanceof TypeError` checks keep working while `instanceof FlagParseError` lets you handle a bad flag value precisely.
```ts
import { typeFlag, FlagParseError } from 'type-flag'
// $ node ./cli --size huge
try {
typeFlag({ size: Size })
} catch {
// thrown TypeError message => 'Flag "--size": Invalid size: "huge"'
// .cause.message => 'Invalid size: "huge"'
} catch (error) {
if (error instanceof FlagParseError) {
error.flagName // 'size'
error.message // 'Flag "--size": Invalid size: "huge"'
error.cause // the original thrown error
}
}

@@ -455,0 +462,0 @@ ```

@@ -72,3 +72,3 @@ ---

- Booleans: keep native `Boolean` (a schema loses `--no-` negation and short grouping).
- Sync only: async schemas throw. A failed schema is wrapped as `Flag "--<name>": <message>` (original on `.cause`).
- Sync only: async schemas throw. A failed schema throws `FlagParseError` as `Flag "--<name>": <message>` (original on `.cause`).

@@ -191,4 +191,4 @@ ## Return shape

| kebab schema key | If schema key is `'some-flag'`, only `--some-flag` / `--someFlag` both map to it, but output key stays kebab. |
| Default functions throw | A throwing `default: () => ...` propagates. |
| Parser/schema errors wrap | A throwing parser (or failed schema) is wrapped in a `TypeError` as `Flag "--<name>": <message>`; the original is on `.cause`. |
| Default functions throw | A throwing `default: () => ...` propagates raw (NOT a `FlagParseError`). |
| Parser/schema errors wrap | A throwing parser (or failed schema) throws `FlagParseError` (extends `TypeError`) as `Flag "--<name>": <message>`, with `.flagName` and the original on `.cause`. Exported from `type-flag`. |

@@ -195,0 +195,0 @@ ## Related

var x=Object.defineProperty;var a=(e,n)=>x(e,"name",{value:n,configurable:!0});const F="flag",N="unknown-flag",V="argument",w=a(e=>(typeof e=="object"||typeof e=="function")&&e!==null&&"~standard"in e,"isStandardSchema"),O=a(e=>(n=>{const t=e["~standard"].validate(n);if(t instanceof Promise)throw new TypeError("Async schemas are not supported");if(t.issues)throw new Error(t.issues[0]?.message??"Validation failed");return t.value}),"schemaToParser"),g="--",L=3,k=/^-{1,2}\w/,C=/^-(?:\d+(?:\.\d*)?|\.\d+)(?:e[-+]?\d+)?$/i,D=a((e,n)=>{if(!C.test(e))return!1;for(let t=1;t<e.length;t+=1)if(!n.has(e[t]))return!0;return!1},"isNegativeNumberValue"),P=a(e=>{if(!k.test(e))return;const n=!e.startsWith(g);let t=e.slice(n?1:2),r,s=-1;for(const c of["=",":","."]){const i=t.indexOf(c);i!==-1&&(s===-1||i<s)&&(s=i)}return s!==-1&&(r=t.slice(s+1),t=t.slice(0,s)),[t,r,n]},"parseFlagArgv"),T=a((e,{onFlag:n,onValue:t,onArgument:r,knownFlags:s})=>{let c=!1;const i=a((o,l)=>{if(!c)return!0;c=!1,t?.(o,l)},"triggerValueCallback");for(let o=0;o<e.length;o+=1){const l=e[o];if(l===g){i();const u=e.slice(o+1);r?.(u,[o],!0);break}if(c&&s&&D(l,s)){i(l,[o]);continue}const f=P(l);if(f){if(i(),!n)continue;const[u,m,$]=f;if($)for(let p=0;p<u.length;p+=1){i();const A=p===u.length-1;c=n(u[p],A?m:void 0,[o,p+1,A])===!0}else c=n(u,m,[o])===!0}else i(l,[o])&&r?.([l],[o])}i()},"argvIterator"),j=a((e,n)=>{for(let t=n.length-1;t>=0;t-=1){const[r,s,c]=n[t];if(s){const i=e[r];let o=i.slice(0,s);if(c||(o+=i.slice(s+1)),o!=="-"){e[r]=o;continue}}e.splice(r,1)}},"spliceFromArgv"),h=a((e,n)=>Object.assign(e,{[g]:n}),"createPositionalArgumentsFromParts"),I=a(e=>{const n=e.indexOf(g);if(n===-1)return h([...e],[]);const t=e.slice(0,n),r=e.slice(n+1);return h([...t,...r],r)},"createPositionalArguments"),U=/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g,_=/[A-Z]/,E=a(e=>_.test(e)?e.replaceAll(U,"-").toLowerCase():e.toLowerCase(),"flagNameToKebab"),{hasOwnProperty:z}=Object.prototype,b=a((e,n)=>z.call(e,n),"hasOwn"),d=a(e=>w(e)?[O(e),!1]:typeof e=="function"?[e,!1]:Array.isArray(e)?[d(e[0])[0],!0]:d(e.type),"parseFlagType"),G=a((e,n)=>e===Boolean?n!=="false":n,"normalizeBoolean"),Z=a((e,n,t)=>{if(typeof n=="boolean")return n;if(e===Number&&n==="")return Number.NaN;try{return e(n)}catch(r){throw new TypeError(`Flag "--${t}": ${r instanceof Error?r.message:r}`,{cause:r})}},"applyParser"),B=/[\s.:=]/,M=a(e=>{const n=`Flag name "${e}"`;if(e.length===0)throw new Error(`${n} cannot be empty`);const t=e.match(B);if(t)throw new Error(`${n} cannot contain "${t?.[0]}"`)},"validateFlagName"),y=a((e,n,t)=>{if(e.has(n))throw new Error(`Duplicate flags named "${n}"`);e.set(n,t)},"setFlag"),R=a(e=>{const n=new Map;for(const t in e){if(!b(e,t))continue;M(t);const r=e[t],s=[t,...d(r),r];y(n,t,s);const c=E(t);if(t!==c&&y(n,c,s),"alias"in r&&typeof r.alias=="string"){const{alias:i}=r,o=`Flag alias "${i}" for flag "${t}"`;if(t.length===1)throw new Error(`${o} cannot be defined for a single-character flag`);if(i.length===0)throw new Error(`${o} cannot be empty`);if(i.length>1)throw new Error(`${o} must be a single character`);y(n,i,s)}}return n},"createRegistry"),H=a(e=>{const n=new Map,t=Object.create(null),r=[];for(const s of e)if(s.type===F){let c=n.get(s.name);c||(c=[],n.set(s.name,c)),c.push(s.value)}else s.type===N?(b(t,s.name)||(t[s.name]=[]),t[s.name].push(s.value)):r.push(s.value);return{knownFlagValues:n,unknownFlags:t,positionals:r}},"groupEntries"),K=a((e,n,t)=>{if((!t||t.length===0)&&!w(e)&&"default"in e){const{default:r}=e;return typeof r=="function"?r():r}return n?t??[]:t&&t.at(-1)},"resolveFlagValue"),W=a((e,n,t,r)=>{const{knownFlagValues:s,unknownFlags:c,positionals:i}=H(t),o=Object.create(null);for(const l in e){if(!b(e,l))continue;const f=n.get(l);f&&(o[l]=K(f[3],f[2],s.get(l)))}return{flags:o,unknownFlags:c,_:h([...i,...r],r)}},"finalizeParsed");export{L as A,F,N as U,T as a,V as b,R as c,Z as d,d as e,W as f,I as g,E as h,w as i,G as n,P as p,j as s};
/**
* Standard Schema (https://standardschema.dev) support: the vendored v1 spec
* types plus the runtime helpers type-flag uses to detect and adapt schemas.
* The spec is vendored rather than depended on to keep type-flag zero-dependency.
*/
/**
* Minimal vendored subset of the Standard Schema spec, v1. Mirrors
* `@standard-schema/spec`. Kept byte-compatible with upstream, which relies on a
* namespace merged with an interface of the same name, so the conflicting
* stylistic rules are disabled here.
*/
declare namespace StandardSchemaV1 {
interface Props<Input = unknown, Output = Input> {
readonly version: 1;
readonly vendor: string;
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
readonly types?: Types<Input, Output> | undefined;
}
type Result<Output> = SuccessResult<Output> | FailureResult;
interface SuccessResult<Output> {
readonly value: Output;
readonly issues?: undefined;
}
interface FailureResult {
readonly issues: ReadonlyArray<Issue>;
}
interface Issue {
readonly message: string;
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
}
interface PathSegment {
readonly key: PropertyKey;
}
interface Types<Input = unknown, Output = Input> {
readonly input: Input;
readonly output: Output;
}
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
}
interface StandardSchemaV1<Input = unknown, Output = Input> {
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
}
/**
* Detect a Standard Schema (Zod, Valibot, ArkType, ...). Used to accept schemas
* directly as flag types, and exported so tools built on type-flag can apply the
* same check when introspecting flag definitions.
*/
declare const isStandardSchema: (value: unknown) => value is StandardSchemaV1;
type Simplify<T> = {
[Key in keyof T]: T[Key];
} & {};
/**
* A function that processes a command-line argument and returns a typed value.
*
* @example
* ```ts
* const toUpperCase = (value: string) => value.toUpperCase();
* ```
*/
type TypeFunction<ReturnType = unknown> = (...args: any[]) => ReturnType;
/**
* The value used to type a flag: a parser function or a Standard Schema.
*/
type FlagTypeValue = TypeFunction | StandardSchemaV1;
/**
* A shorthand for defining a flag's type.
*
* - Use a single `TypeFunction` or Standard Schema to accept one value.
* - Use a readonly tuple (e.g. `[TypeFunction]`) to accept multiple values (as an array).
*
* @see FlagSchema
*/
type FlagType = (FlagTypeValue | readonly [FlagTypeValue]);
/**
* Workaround for TypeScript bug where `Readonly<T>` in parameter position breaks
* conditional type matching in return type. Adding `& AnyObject` to extends clauses
* fixes the matcher.
*
* @see https://github.com/microsoft/TypeScript/issues/62720
*/
type AnyObject = Record<PropertyKey, unknown>;
/**
* Defines the complete schema for a command-line flag.
*/
type FlagSchema = {
/**
* The function or tuple of functions that parse the `argv` string into a typed value.
*
* @example
* ```ts
* type: String
* ```
* @example
* ```ts
* type: [Boolean]
* ```
* @example
* ```ts
* type: (value: string) => moment(value).toDate()
* ```
*/
type: FlagType;
/**
* A single-character alias for the flag.
*
* @example
* ```ts
* alias: 's'
* ```
*/
alias?: string;
/**
* The default value for the flag if not provided.
* Can also be a function that returns the default.
*
* @example
* ```ts
* default: 'hello'
* ```
* @example
* ```ts
* default: () => [1, 2, 3]
* ```
*/
default?: unknown | (() => unknown);
} & AnyObject;
/**
* A flag definition can either be a `FlagType` or a full `FlagSchema` object.
*/
type FlagTypeOrSchema<ExtraOptions = Record<string, unknown>> = FlagType | (FlagSchema & ExtraOptions);
/**
* A map of flag names to their definitions.
*/
type Flags<ExtraOptions = Record<string, unknown>> = {
[flagName: string]: FlagTypeOrSchema<ExtraOptions>;
};
/**
* Positional arguments with post-`--` values exposed separately.
*/
type PositionalArguments = string[] & {
/** Arguments that appeared after the `--` separator. */
'--': string[];
};
type InferDefaultType<Flag extends FlagTypeOrSchema, Fallback> = Flag extends {
default: infer DefaultType | (() => infer DefaultType);
} & AnyObject ? DefaultType : Fallback;
/**
* Resolves the output type of a single flag-type element: a parser function's
* return type, or a Standard Schema's output type.
*/
type InferType<Element> = (Element extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Element> : Element extends TypeFunction<infer Return> ? Return : never);
type FlagTypeOf<Flag> = (Flag extends {
type: infer Type extends FlagType;
} & AnyObject ? Type : Flag);
/**
* Infers the final JavaScript type of a flag from its schema.
*
* `FlagTypeOf` unwraps the `{ type }` object form first, so only the two
* underlying shapes (array vs scalar) need matching. `InferType` then resolves
* each element whether it is a function or a schema.
*/
type InferFlagType<Flag extends FlagTypeOrSchema> = (FlagTypeOf<Flag> extends readonly [infer Element extends FlagTypeValue] ? InferArrayType<Flag, Element> : FlagTypeOf<Flag> extends infer Element extends FlagTypeValue ? InferScalarType<Flag, Element> : unknown);
type InferArrayType<Flag extends FlagTypeOrSchema, Element> = (InferType<Element> extends infer Output ? (Output[] | InferDefaultType<Flag, never>) : never);
type InferScalarType<Flag extends FlagTypeOrSchema, Element> = (InferType<Element> extends infer Output ? ([
Output
] extends [never] ? Output : (Output | InferDefaultType<Flag, undefined>)) : never);
/**
* The fully inferred return type from a given flag schema configuration.
*/
type TypeFlag<Schemas extends Flags = Flags> = {
/** Parsed values keyed by flag name. */
flags: {
[flag in keyof Schemas]: InferFlagType<Schemas[flag]>;
};
/** Flags that were passed but not defined in the schema. */
unknownFlags: {
[flagName: string]: (string | boolean)[];
};
/**
* Positional arguments (non-flag values).
* Includes a special `"--"` key for arguments after the double dash.
*/
_: PositionalArguments;
/**
* Every interpreted argv element, in the order it appeared on the command
* line. Unlike `flags` (which groups values by flag name), this preserves the
* relative order across different flags and positional arguments.
*
* Only covers what the parser interprets: elements after the `--` delimiter
* are not parsed, so they are excluded here (find them in `_['--']`).
*
* Advanced: most CLIs only need `flags`. Reach for `entries` when the order
* of operations across different flags matters — e.g. assembling a curl-style
* request body from interleaved `-d` and `--data-urlencode`.
*/
entries: ParsedArgvEntry[];
};
/** Constant indicating a defined (schema) flag token type. */
declare const FLAG = "flag";
/** Constant indicating an unknown flag token type. */
declare const UNKNOWN_FLAG = "unknown-flag";
/** Constant indicating a positional argument token type. */
declare const ARGUMENT = "argument";
/**
* A single interpreted argv element from {@link TypeFlag.entries}, discriminated
* by `type`.
*/
type ParsedArgvEntry = {
type: typeof FLAG;
/**
* Canonical schema key — always the name as declared in the schema
* (e.g. `dataUrlencode`), regardless of whether the alias (`-d`),
* kebab-case (`--data-urlencode`), or camelCase form was used in argv.
*/
name: string;
/** Parsed value for this single occurrence. */
value: unknown;
} | {
type: typeof UNKNOWN_FLAG;
/** Raw flag name as it appeared in argv (not camelCased). */
name: string;
/** Explicit value, or `true` when the flag had no value. */
value: string | boolean;
} | {
type: typeof ARGUMENT;
/** The positional argument value. */
value: string;
};
/**
* A function to dynamically ignore specific elements during parsing.
* Return `true` to skip the element, or `false`/`undefined` to process it normally.
*
* @param type - The type of element being processed:
* - `'argument'`: A positional argument (non-flag value)
* - `'flag'`: A flag defined in the schema
* - `'unknown-flag'`: A flag not defined in the schema
* @param argvElement - The raw argv string. For arguments, this is the value itself.
* For flags, this is the flag name (e.g., `'--verbose'` or `'-v'`).
* @param flagValue - The value associated with a flag, if any.
* - For flags with explicit values: the string value (e.g., `'--port=3000'` → `'3000'`)
* - For boolean flags or flags without values: `undefined`
* - For arguments (`type === 'argument'`): always `undefined`
* @returns `true` to ignore/skip this element, `false` or `undefined` to process it
*
* @example
* ```ts
* // Ignore all unknown flags
* ignore: (type) => type === 'unknown-flag'
* ```
*
* @example
* ```ts
* // Ignore arguments starting with a dot
* ignore: (type, argvElement) => type === 'argument' && argvElement.startsWith('.')
* ```
*
* @example
* ```ts
* // Ignore a specific flag
* ignore: (type, argvElement) => argvElement === '--internal-only'
* ```
*/
type IgnoreFunction = (type: typeof ARGUMENT | typeof FLAG | typeof UNKNOWN_FLAG, argvElement: string, flagValue?: string) => boolean | void;
/**
* Options to customize the flag parsing behavior.
*/
type TypeFlagOptions = {
/**
* Optional function to skip certain argv elements from parsing.
*/
ignore?: IgnoreFunction;
/**
* Enable `--no-<flag>` negation for boolean flags.
*
* When enabled, `--no-verbose` is equivalent to `--verbose=false`.
* Only applies to flags defined as `Boolean` in the schema.
* Last-wins semantics apply between `--flag` and `--no-flag`.
*/
booleanNegation?: boolean;
};
export { StandardSchemaV1 as e, isStandardSchema as i };
export type { Flags as F, InferFlagType as I, ParsedArgvEntry as P, Simplify as S, TypeFlagOptions as T, TypeFlag as a, FlagType as b, IgnoreFunction as c, PositionalArguments as d };