( param: Param<Kind, A> )
| 1269 | * @since 4.0.0 |
| 1270 | */ |
| 1271 | export const optional = <Kind extends ParamKind, A>( |
| 1272 | param: Param<Kind, A> |
| 1273 | ): Param<Kind, Option.Option<A>> => { |
| 1274 | const parse: Parse<Option.Option<A>> = Effect.fnUntraced(function*(args) { |
| 1275 | const single = getUnderlyingSingleOrThrow(param) |
| 1276 | |
| 1277 | // Handle boolean params that are explicitly marked as optional (i.e. the |
| 1278 | // end user wants to return `Option.none()` instead of `false` when the |
| 1279 | // flag (or its negated variant) are not present on the command line |
| 1280 | if ( |
| 1281 | isFlagParam(single) && |
| 1282 | Primitive.isBoolean(single.primitiveType) && |
| 1283 | ![single.name, ...single.aliases].some((name) => (args.flags[name] ?? []).length > 0) |
| 1284 | ) { |
| 1285 | return [args.arguments, Option.none()] as const |
| 1286 | } |
| 1287 | |
| 1288 | return yield* param.parse(args).pipe( |
| 1289 | Effect.map(([leftover, value]) => [leftover, Option.some(value)] as const), |
| 1290 | // Catch both MissingOption (for flags) and MissingArgument (for positional arguments) |
| 1291 | Effect.catchTags({ |
| 1292 | MissingOption: () => Effect.succeed([args.arguments, Option.none()] as const), |
| 1293 | MissingArgument: () => Effect.succeed([args.arguments, Option.none()] as const) |
| 1294 | }) |
| 1295 | ) |
| 1296 | }) |
| 1297 | return Object.assign(Object.create(Proto), { |
| 1298 | _tag: "Optional", |
| 1299 | kind: param.kind, |
| 1300 | param, |
| 1301 | parse |
| 1302 | }) |
| 1303 | } |
| 1304 | |
| 1305 | /** |
| 1306 | * Makes a flag or positional argument optional by supplying a fallback value. |
no test coverage detected