Fork me on GitHub
concise and powerful!
Ducky is a small Open-Source JavaScript library, providing Duck-Typed Value Validation, Value Selection and Flexible Function Parameter Handling.
Example Usage: Object Deep Validation

const config = { foo: "TheFoo", bar: [ "TheBar", true, 1, 7, 42 ], quux: [ { id: 1, name: "One", enabled: true }, { id: 2, name: "Two" }, { id: 3, name: "Three" }, { id: 4, name: "Four" } { id: 5, name: "Five" } ] };
ducky.validate(config, `{ foo: string, bar: [ string, boolean{0,2}, number+ ], quux: [ { id: number, name: string, enabled?: boolean, }* ] }`) // → true;
Let's define an arbitrary complex JavaScript object graph and then assume you get this object graph as input and you want to sanity check its structure and typing before working with it.

Ducky uses a validation syntax which is a mixture of JavaScript Object Notation (for the structure) and Regular Expressions (for the arities).

Ducky is efficient: it compiles the validation specification into an Abstract Syntax Tree (AST), caches this AST for potential subsequent validations and executes this AST against the passed object graph.

Example Usage: Object Deep Selection

const config = { foo: "TheFoo", bar: [ "TheBar", true, 1, 7, 42 ], quux: [ { id: 1, name: "One", enabled: true }, { id: 2, name: "Two" }, { id: 3, name: "Three" }, { id: 4, name: "Four" } { id: 5, name: "Five" } ] };
ducky.select(config, "quux[2].name") // → "Three" ducky.select(config, "quux[2].name", "NewValue") // → "Three" ducky.select(config, "quux.2.name") // → "NewValue" ducky.select(config, "['quux'][2][\"name\"]") // → "NewValue"
Let's define the arbitrary complex JavaScript object graph again, but now deep select various values and get or set them.

Ducky uses a selection syntax which follows the known JavaScript syntax for object dereferencing with the difference that the dot-notation can be even used for numeric keys.

Once again, Ducky is efficient: it compiles the selection specification into an Abstract Syntax Tree (AST), caches this AST for potential subsequent selections and executes this AST against the passed object graph.

Example Usage: Function Parameter Handling

const greet = function () { const params = ducky.params("foo", arguments, { hello: { def: "Hello", valid: "string" }, what: { pos: 0, def: "World", valid: "string" }, more: { pos: "...", def: [], valid: "[ number* ]" }, }); let result = params.hello + " " + params.what; params.more.forEach(function (num) { result += ", " + num; }); return result; };
greet() // → "Hello World" greet("Hackers") // → "Hello Hackers" greet({ what: "Hackers" }) // → "Hello Hackers" greet("Hackers", 1, 2, 3) // → "Hello Hackers, 1, 2, 3" greet({ what: "Hackers", more: [ 1, 2, 3 ] }) // → "Hello Hackers, 1, 2, 3" greet(42) // → throw Error greet("Foo", "Bar") // → throw Error
Let's define a function which should greet. With the help of Ducky its parameter handling is both concise and strict.

The parameter handling provided by Ducky support positional and named parameters at the same time. Additionally, it supports optional parameters (those with default values and not in the middle of a list of positional parameters), a powerful value validation based on ducky.validate() specifications and even the special scenario of rest parameters.

Downloading Ducky

Via Node Package Manager (NPM):
$ npm install ducky

Via Git Version Control System:
$ git clone https://github.com/rse/ducky.git

Via cURL Client:
$ curl -O https://raw.github.com/rse/ducky/master/lib/ducky.js