[6a3a178] | 1 | aproba
|
---|
| 2 | ======
|
---|
| 3 |
|
---|
| 4 | A ridiculously light-weight function argument validator
|
---|
| 5 |
|
---|
| 6 | ```
|
---|
| 7 | var validate = require("aproba")
|
---|
| 8 |
|
---|
| 9 | function myfunc(a, b, c) {
|
---|
| 10 | // `a` must be a string, `b` a number, `c` a function
|
---|
| 11 | validate('SNF', arguments) // [a,b,c] is also valid
|
---|
| 12 | }
|
---|
| 13 |
|
---|
| 14 | myfunc('test', 23, function () {}) // ok
|
---|
| 15 | myfunc(123, 23, function () {}) // type error
|
---|
| 16 | myfunc('test', 23) // missing arg error
|
---|
| 17 | myfunc('test', 23, function () {}, true) // too many args error
|
---|
| 18 |
|
---|
| 19 | ```
|
---|
| 20 |
|
---|
| 21 | Valid types are:
|
---|
| 22 |
|
---|
| 23 | | type | description
|
---|
| 24 | | :--: | :----------
|
---|
| 25 | | * | matches any type
|
---|
| 26 | | A | `Array.isArray` OR an `arguments` object
|
---|
| 27 | | S | typeof == string
|
---|
| 28 | | N | typeof == number
|
---|
| 29 | | F | typeof == function
|
---|
| 30 | | O | typeof == object and not type A and not type E
|
---|
| 31 | | B | typeof == boolean
|
---|
| 32 | | E | `instanceof Error` OR `null` **(special: see below)**
|
---|
| 33 | | Z | == `null`
|
---|
| 34 |
|
---|
| 35 | Validation failures throw one of three exception types, distinguished by a
|
---|
| 36 | `code` property of `EMISSINGARG`, `EINVALIDTYPE` or `ETOOMANYARGS`.
|
---|
| 37 |
|
---|
| 38 | If you pass in an invalid type then it will throw with a code of
|
---|
| 39 | `EUNKNOWNTYPE`.
|
---|
| 40 |
|
---|
| 41 | If an **error** argument is found and is not null then the remaining
|
---|
| 42 | arguments are optional. That is, if you say `ESO` then that's like using a
|
---|
| 43 | non-magical `E` in: `E|ESO|ZSO`.
|
---|
| 44 |
|
---|
| 45 | ### But I have optional arguments?!
|
---|
| 46 |
|
---|
| 47 | You can provide more than one signature by separating them with pipes `|`.
|
---|
| 48 | If any signature matches the arguments then they'll be considered valid.
|
---|
| 49 |
|
---|
| 50 | So for example, say you wanted to write a signature for
|
---|
| 51 | `fs.createWriteStream`. The docs for it describe it thusly:
|
---|
| 52 |
|
---|
| 53 | ```
|
---|
| 54 | fs.createWriteStream(path[, options])
|
---|
| 55 | ```
|
---|
| 56 |
|
---|
| 57 | This would be a signature of `SO|S`. That is, a string and and object, or
|
---|
| 58 | just a string.
|
---|
| 59 |
|
---|
| 60 | Now, if you read the full `fs` docs, you'll see that actually path can ALSO
|
---|
| 61 | be a buffer. And options can be a string, that is:
|
---|
| 62 | ```
|
---|
| 63 | path <String> | <Buffer>
|
---|
| 64 | options <String> | <Object>
|
---|
| 65 | ```
|
---|
| 66 |
|
---|
| 67 | To reproduce this you have to fully enumerate all of the possible
|
---|
| 68 | combinations and that implies a signature of `SO|SS|OO|OS|S|O`. The
|
---|
| 69 | awkwardness is a feature: It reminds you of the complexity you're adding to
|
---|
| 70 | your API when you do this sort of thing.
|
---|
| 71 |
|
---|
| 72 |
|
---|
| 73 | ### Browser support
|
---|
| 74 |
|
---|
| 75 | This has no dependencies and should work in browsers, though you'll have
|
---|
| 76 | noisier stack traces.
|
---|
| 77 |
|
---|
| 78 | ### Why this exists
|
---|
| 79 |
|
---|
| 80 | I wanted a very simple argument validator. It needed to do two things:
|
---|
| 81 |
|
---|
| 82 | 1. Be more concise and easier to use than assertions
|
---|
| 83 |
|
---|
| 84 | 2. Not encourage an infinite bikeshed of DSLs
|
---|
| 85 |
|
---|
| 86 | This is why types are specified by a single character and there's no such
|
---|
| 87 | thing as an optional argument.
|
---|
| 88 |
|
---|
| 89 | This is not intended to validate user data. This is specifically about
|
---|
| 90 | asserting the interface of your functions.
|
---|
| 91 |
|
---|
| 92 | If you need greater validation, I encourage you to write them by hand or
|
---|
| 93 | look elsewhere.
|
---|
| 94 |
|
---|