Comparing version 2.0.2 to 2.0.3
/** | ||
* Base type that handlers extend from | ||
*/ | ||
export type Handler = (...props: unknown[]) => unknown | ||
/** | ||
* Handle values based on a property. | ||
* Handle values based on a field. | ||
* | ||
* @param key key | ||
* @param options options | ||
* @returns handler | ||
* @template {InvalidHandler} [Invalid=InvalidHandler] | ||
* @template {UnknownHandler} [Unknown=UnknownHandler] | ||
* @template {Record<string, Handler>} [Handlers=Record<string, Handler>] | ||
* @param {string} key | ||
* Field to switch on. | ||
* @param {Options<Invalid, Unknown, Handlers>} [options] | ||
* Configuration (required). | ||
* @returns {{unknown: Unknown, invalid: Invalid, handlers: Handlers, (...parameters: Parameters<Handlers[keyof Handlers]>): ReturnType<Handlers[keyof Handlers]>, (...parameters: Parameters<Unknown>): ReturnType<Unknown>}} | ||
*/ | ||
export declare function zwitch< | ||
KnownHandler extends Handler = (...parameters: unknown[]) => void, | ||
UnknownHandler extends Handler = (...parameters: unknown[]) => void, | ||
InvalidHandler extends Handler = (...parameters: unknown[]) => void | ||
export function zwitch< | ||
Invalid extends InvalidHandler = InvalidHandler, | ||
Unknown extends UnknownHandler = UnknownHandler, | ||
Handlers extends Record<string, Handler> = Record<string, Handler> | ||
>( | ||
key: string, | ||
options?: { | ||
unknown?: UnknownHandler | ||
invalid?: InvalidHandler | ||
handlers?: Record<string, KnownHandler> | ||
} | ||
options?: Options<Invalid, Unknown, Handlers> | undefined | ||
): { | ||
unknown: UnknownHandler | ||
invalid: InvalidHandler | ||
handlers: Record<string, KnownHandler> | ||
(...parameters: Parameters<UnknownHandler>): ReturnType<UnknownHandler> | ||
(...parameters: Parameters<InvalidHandler>): ReturnType<InvalidHandler> | ||
(...parameters: Parameters<KnownHandler>): ReturnType<KnownHandler> | ||
(...parameters: Parameters<Handlers[keyof Handlers]>): ReturnType< | ||
Handlers[keyof Handlers] | ||
> | ||
(...parameters: Parameters<Unknown>): ReturnType<Unknown> | ||
unknown: Unknown | ||
invalid: Invalid | ||
handlers: Handlers | ||
} | ||
/** | ||
* Handle a value, with a certain ID field set to a certain value. | ||
* The ID field is passed to `zwitch`, and it’s value is this function’s | ||
* place on the `handlers` record. | ||
*/ | ||
export type Handler = (...parameters: any[]) => any | ||
/** | ||
* Handle values that do have a certain ID field, but it’s set to a value | ||
* that is not listed in the `handlers` record. | ||
*/ | ||
export type UnknownHandler = (value: unknown, ...rest: any[]) => any | ||
/** | ||
* Handle values that do not have a certain ID field. | ||
*/ | ||
export type InvalidHandler = ( | ||
value: unknown, | ||
...rest: any[] | ||
) => void | null | undefined | never | ||
/** | ||
* Configuration (required). | ||
*/ | ||
export type Options< | ||
Invalid extends InvalidHandler = InvalidHandler, | ||
Unknown extends UnknownHandler = UnknownHandler, | ||
Handlers extends Record<string, Handler> = Record<string, Handler> | ||
> = { | ||
/** | ||
* Handler to use for invalid values. | ||
*/ | ||
invalid?: Invalid | undefined | ||
/** | ||
* Handler to use for unknown values. | ||
*/ | ||
unknown?: Unknown | undefined | ||
/** | ||
* Handlers to use. | ||
*/ | ||
handlers?: Handlers | undefined | ||
} |
100
index.js
@@ -1,27 +0,70 @@ | ||
var own = {}.hasOwnProperty | ||
/** | ||
* @callback Handler | ||
* Handle a value, with a certain ID field set to a certain value. | ||
* The ID field is passed to `zwitch`, and it’s value is this function’s | ||
* place on the `handlers` record. | ||
* @param {...any} parameters | ||
* Arbitrary parameters passed to the zwitch. | ||
* The first will be an object with a certain ID field set to a certain value. | ||
* @returns {any} | ||
* Anything! | ||
*/ | ||
/** | ||
* @callback Handler | ||
* @param {...unknown} value | ||
* @return {unknown} | ||
* | ||
* @typedef {Record<string, Handler>} Handlers | ||
* | ||
* @typedef {Object} Options | ||
* @property {Handler} [unknown] | ||
* @property {Handler} [invalid] | ||
* @callback UnknownHandler | ||
* Handle values that do have a certain ID field, but it’s set to a value | ||
* that is not listed in the `handlers` record. | ||
* @param {unknown} value | ||
* An object with a certain ID field set to an unknown value. | ||
* @param {...any} rest | ||
* Arbitrary parameters passed to the zwitch. | ||
* @returns {any} | ||
* Anything! | ||
*/ | ||
/** | ||
* @callback InvalidHandler | ||
* Handle values that do not have a certain ID field. | ||
* @param {unknown} value | ||
* Any unknown value. | ||
* @param {...any} rest | ||
* Arbitrary parameters passed to the zwitch. | ||
* @returns {void|null|undefined|never} | ||
* This should crash or return nothing. | ||
*/ | ||
/** | ||
* @template {InvalidHandler} [Invalid=InvalidHandler] | ||
* @template {UnknownHandler} [Unknown=UnknownHandler] | ||
* @template {Record<string, Handler>} [Handlers=Record<string, Handler>] | ||
* @typedef Options | ||
* Configuration (required). | ||
* @property {Invalid} [invalid] | ||
* Handler to use for invalid values. | ||
* @property {Unknown} [unknown] | ||
* Handler to use for unknown values. | ||
* @property {Handlers} [handlers] | ||
* Handlers to use. | ||
*/ | ||
const own = {}.hasOwnProperty | ||
/** | ||
* Handle values based on a property. | ||
* Handle values based on a field. | ||
* | ||
* @template {InvalidHandler} [Invalid=InvalidHandler] | ||
* @template {UnknownHandler} [Unknown=UnknownHandler] | ||
* @template {Record<string, Handler>} [Handlers=Record<string, Handler>] | ||
* @param {string} key | ||
* @param {Options} [options] | ||
* Field to switch on. | ||
* @param {Options<Invalid, Unknown, Handlers>} [options] | ||
* Configuration (required). | ||
* @returns {{unknown: Unknown, invalid: Invalid, handlers: Handlers, (...parameters: Parameters<Handlers[keyof Handlers]>): ReturnType<Handlers[keyof Handlers]>, (...parameters: Parameters<Unknown>): ReturnType<Unknown>}} | ||
*/ | ||
export function zwitch(key, options) { | ||
var settings = options || {} | ||
const settings = options || {} | ||
/** | ||
* Handle one value. | ||
* | ||
* Based on the bound `key`, a respective handler will be called. | ||
@@ -36,19 +79,35 @@ * If `value` is not an object, or doesn’t have a `key` property, the special | ||
* | ||
* @param {...unknown} [value] | ||
* @this {unknown} | ||
* @returns {unknown} | ||
* Any context object. | ||
* @param {unknown} [value] | ||
* Any value. | ||
* @param {...unknown} parameters | ||
* Arbitrary parameters passed to the zwitch. | ||
* @property {Handler} invalid | ||
* Handle for values that do not have a certain ID field. | ||
* @property {Handler} unknown | ||
* Handle values that do have a certain ID field, but it’s set to a value | ||
* that is not listed in the `handlers` record. | ||
* @property {Handlers} handlers | ||
* Record of handlers. | ||
* @returns {unknown} | ||
* Anything. | ||
*/ | ||
function one(value) { | ||
var fn = one.invalid | ||
var handlers = one.handlers | ||
function one(value, ...parameters) { | ||
/** @type {Handler|undefined} */ | ||
let fn = one.invalid | ||
const handlers = one.handlers | ||
if (value && own.call(value, key)) { | ||
fn = own.call(handlers, value[key]) ? handlers[value[key]] : one.unknown | ||
// @ts-expect-error: indexable. | ||
const id = value[key] | ||
fn = | ||
typeof id === 'string' && own.call(handlers, id) | ||
? // @ts-expect-error: assume function. | ||
handlers[id] | ||
: one.unknown | ||
} | ||
if (fn) { | ||
return fn.apply(this, arguments) | ||
return fn.call(this, value, ...parameters) | ||
} | ||
@@ -61,3 +120,4 @@ } | ||
// @ts-expect-error: matches! | ||
return one | ||
} |
{ | ||
"name": "zwitch", | ||
"version": "2.0.2", | ||
"version": "2.0.3", | ||
"description": "Handle values based on a property", | ||
@@ -30,19 +30,18 @@ "license": "MIT", | ||
"devDependencies": { | ||
"@types/tape": "^4.0.0", | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
"prettier": "^2.0.0", | ||
"remark-cli": "^9.0.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"remark-cli": "^11.0.0", | ||
"remark-preset-wooorm": "^9.0.0", | ||
"tsd": "^0.24.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"xo": "^0.38.0" | ||
"xo": "^0.52.0" | ||
}, | ||
"scripts": { | ||
"prepack": "npm run build && npm run format", | ||
"build": "tsc && type-coverage", | ||
"build": "tsc --build --clean && tsc --build && tsd && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"test-api": "node test.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js", | ||
"test-api": "node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
@@ -59,8 +58,3 @@ }, | ||
"xo": { | ||
"prettier": true, | ||
"rules": { | ||
"no-var": "off", | ||
"prefer-arrow-callback": "off", | ||
"unicorn/prefer-reflect-apply": "off" | ||
} | ||
"prettier": true | ||
}, | ||
@@ -75,4 +69,7 @@ "remarkConfig": { | ||
"detail": true, | ||
"strict": true | ||
"strict": true, | ||
"ignoreFiles": [ | ||
"index.d.ts" | ||
] | ||
} | ||
} |
133
readme.md
@@ -8,11 +8,35 @@ # zwitch | ||
Handle values based on a property. | ||
Handle values based on a field. | ||
## Contents | ||
* [What is this?](#what-is-this) | ||
* [When should I use this?](#when-should-i-use-this) | ||
* [Install](#install) | ||
* [Use](#use) | ||
* [API](#api) | ||
* [`zwitch(key[, options])`](#zwitchkey-options) | ||
* [`one(value[, rest…])`](#onevalue-rest) | ||
* [`function handler(value[, rest…])`](#function-handlervalue-rest) | ||
* [Types](#types) | ||
* [Compatibility](#compatibility) | ||
* [Related](#related) | ||
* [Contribute](#contribute) | ||
* [Security](#security) | ||
* [License](#license) | ||
## What is this? | ||
This is a tiny package that lets you `switch` between some field on objects. | ||
## When should I use this? | ||
This package is very useful when mapping one AST to another. | ||
It’s a lot like a `switch` statement on one field, but it’s extensible. | ||
## Install | ||
This package is ESM only: Node 12+ is needed to use it and it must be `import`ed | ||
instead of `require`d. | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+, 16.0+), install with [npm][]: | ||
[npm][]: | ||
```sh | ||
@@ -22,2 +46,16 @@ npm install zwitch | ||
In Deno with [`esm.sh`][esmsh]: | ||
```js | ||
import {zwitch} from 'https://esm.sh/zwitch@2' | ||
``` | ||
In browsers with [`esm.sh`][esmsh]: | ||
```html | ||
<script type="module"> | ||
import {zwitch} from 'https://esm.sh/zwitch@2?bundle' | ||
</script> | ||
``` | ||
## Use | ||
@@ -28,3 +66,3 @@ | ||
var handle = zwitch('type', {invalid, unknown, handlers: {alpha: handleAlpha}}) | ||
const handle = zwitch('type', {invalid, unknown, handlers: {alpha: handleAlpha}}) | ||
@@ -39,10 +77,8 @@ handle({type: 'alpha'}) | ||
```js | ||
var field = 'type' | ||
const field = 'type' | ||
function handle(value) { | ||
var fn | ||
let fn = invalid | ||
if (!value || typeof value !== 'object' || !(field in value)) { | ||
fn = invalid | ||
} else { | ||
if (value && typeof value === 'object' && field in value) { | ||
switch (value[field]) { | ||
@@ -64,2 +100,4 @@ case 'alpha': | ||
function handleAlpha() { /* … */ } | ||
function unknown() { /* … */ } | ||
function invalid() { /* … */ } | ||
``` | ||
@@ -69,3 +107,3 @@ | ||
This package exports the following identifiers: `zwitch`. | ||
This package exports the identifier `zwitch`. | ||
There is no default export. | ||
@@ -75,20 +113,28 @@ | ||
Create a functional switch, based on a `key` (`string`). | ||
Create a switch, based on a `key` (`string`). | ||
###### `options` | ||
##### `options` | ||
Options can be omitted and added later to `one`. | ||
* `handlers` (`Object.<Function>`, optional) | ||
— Object mapping values to handle, stored on `one.handlers` | ||
* `invalid` (`Function`, optional) | ||
— Handle values without `key`, stored on `one.invalid` | ||
* `unknown` (`Function`, optional) | ||
— Handle values with an unhandled `key`, stored on `one.unknown` | ||
###### `options.handlers` | ||
Handlers to use, stored on `one.handlers` (`Record<string, Function>`, | ||
optional). | ||
###### `options.unknown` | ||
Handler to use for unknown values, stored on `one.unknown` (`Function`, | ||
optional). | ||
###### `options.invalid` | ||
Handler to use for invalid values, stored on `one.invalid` (`Function`, | ||
optional). | ||
###### Returns | ||
`Function` — See [`one`][one]. | ||
See [`one`][one] (`Function`). | ||
#### `one(value[, rest…])` | ||
### `one(value[, rest…])` | ||
@@ -101,10 +147,10 @@ Handle one value. | ||
All arguments, and the context object, are passed through to the [handler][], | ||
and it’s result is returned. | ||
All arguments, and the context object (`this`), are passed through to the | ||
[handler][], and it’s result is returned. | ||
#### `one.handlers` | ||
###### `one.handlers` | ||
Map of [handler][]s (`Object.<string, Function>`). | ||
Map of [handler][]s (`Record<string, Function>`). | ||
#### `one.invalid` | ||
###### `one.invalid` | ||
@@ -114,3 +160,3 @@ Special [`handler`][handler] called if a value doesn’t have a `key` property. | ||
#### `one.unknown` | ||
###### `one.unknown` | ||
@@ -125,7 +171,28 @@ Special [`handler`][handler] called if a value does not have a matching | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
It exports the types `Handler`, `UnknownHandler`, `InvalidHandler`, and | ||
`Options`. | ||
## Compatibility | ||
This package is at least compatible with all maintained versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
It also works in Deno and modern browsers. | ||
## Related | ||
* [`mapz`](https://github.com/wooorm/mapz) | ||
— Functional map | ||
— functional map | ||
## Contribute | ||
Yes please! | ||
See [How to Contribute to Open Source][contribute]. | ||
## Security | ||
This package is safe. | ||
## License | ||
@@ -155,2 +222,10 @@ | ||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[esmsh]: https://esm.sh | ||
[typescript]: https://www.typescriptlang.org | ||
[contribute]: https://opensource.guide/how-to-contribute/ | ||
[license]: license | ||
@@ -157,0 +232,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
13812
9
178
227
1