ducky
Version:
Duck-Typed Value Handling for JavaScript
1,183 lines (1,096 loc) • 57.2 kB
JavaScript
/*!
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Ducky = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.version = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* global 2: false */
/* global 8: false */
/* global 0: false */
/* global 20230122: false */
/* API version */
const version = {
major: 2,
minor: 8,
micro: 0,
date: 20230122
};
exports.version = version;
},{}],2:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Token = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* custom Token class */
class Token {
constructor() {
this.name = "";
this.text = "";
this.tokens = [];
this.pos = 0;
this.len = 0;
}
/* setter for caller context name */
setName(name) {
this.name = name;
}
/* setter for plain-text input */
setText(text) {
this.text = text;
}
/* setter for additional token symbols */
addToken(b1, b2, e2, e1, symbol) {
this.tokens.push({
b1: b1,
b2: b2,
e2: e2,
e1: e1,
symbol: symbol
});
this.len++;
}
/* peek at the next token or token at particular offset */
peek(offset) {
if (typeof offset === "undefined") offset = 0;
if (offset >= this.len) throw new Error(`${this.name}: parse error: not enough tokens`);
return this.tokens[this.pos + offset].symbol;
}
/* skip one or more tokens */
skip(len) {
if (typeof len === "undefined") len = 1;
if (len > this.len) throw new Error(`${this.name}: parse error: not enough tokens available to skip: ${this.ctx()}`);
this.pos += len;
this.len -= len;
}
/* consume the current token (by expecting it to be a particular symbol) */
consume(symbol) {
if (this.len <= 0) throw new Error(`${this.name}: parse error: no more tokens available to consume: ${this.ctx()}`);
if (this.tokens[this.pos].symbol !== symbol) throw new Error(`${this.name}: parse error: expected token symbol "${symbol}": ${this.ctx()}`);
this.pos++;
this.len--;
}
/* return a textual description of the token parsing context */
ctx(width) {
if (typeof width === "undefined") width = 78;
let tok = this.tokens[this.pos];
/* the current token itself */
let context = "<" + this.text.substr(tok.b2, tok.e2 - tok.b2 + 1) + ">";
context = this.text.substr(tok.b1, tok.b2 - tok.b1) + context;
context = context + this.text.substr(tok.e2 + 1, tok.e1 - tok.e2);
/* the previous and following token(s) */
let k = width - context.length;
if (k > 0) {
k = Math.floor(k / 2);
let i, str;
if (this.pos > 0) {
/* previous token(s) */
let k1 = 0;
for (i = this.pos - 1; i >= 0; i--) {
tok = this.tokens[i];
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1);
k1 += str.length;
if (k1 > k) break;
context = str + context;
}
if (i > 0) context = "[...]" + context;
}
if (this.len > 1) {
/* following token(s) */
let k2 = 0;
for (i = this.pos + 1; i < this.pos + this.len; i++) {
tok = this.tokens[i];
str = this.text.substr(tok.b1, tok.e1 - tok.b1 + 1);
k2 += str.length;
if (k2 > k) break;
context = context + str;
}
if (i < this.pos + this.len) context = context + "[...]";
}
}
/* place everything on a single line through escape sequences */
context = context.replace(/\r/, "\\r").replace(/\n/, "\\n").replace(/\t/, "\\t");
return context;
}
}
exports.Token = Token;
},{}],3:[function(_dereq_,module,exports){
(function (global){(function (){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.registry = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* internal type registry */
const registry = {};
/* pre-fill type registry with JavaScript standard types */
exports.registry = registry;
const std_types = ["Object", "Boolean", "Number", "String", "Function", "RegExp", "Array", "Date", "Error", "Set", "Map", "WeakMap", "Promise", "Proxy", "Iterator"];
for (let i = 0; i < std_types.length; i++) if (typeof global[std_types[i]] === "function") registry[std_types[i]] = global[std_types[i]];
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],4:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.unregister = exports.registered = exports.register = void 0;
var _ducky2Registry1Data = _dereq_("./ducky-2-registry-1-data.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* API function: register a type under a name */
const register = function (name, type) {
/* sanity check arguments */
if (arguments.length !== 2) throw new Error(`register: invalid number of arguments: ${arguments.length} (exactly 2 expected)`);
if (typeof name !== "string") throw new Error(`register: invalid name argument: "${name}" (string expected)`);
if (typeof type !== "function") throw new Error(`register: invalid type argument: "${type}" (function object expected)`);
if (typeof _ducky2Registry1Data.registry[name] !== "undefined") throw new Error(`register: type already registered under name: "${name}"`);
/* add type to registry */
_ducky2Registry1Data.registry[name] = type;
};
/* API function: unregister a type under a name */
exports.register = register;
const unregister = function (name) {
/* sanity check arguments */
if (arguments.length !== 1) throw new Error(`unregister: invalid number of arguments: ${arguments.length} (exactly 1 expected)`);
if (typeof name !== "string") throw new Error(`unregister: invalid name argument: "${name}" (string expected)`);
if (typeof _ducky2Registry1Data.registry[name] === "undefined") throw new Error(`unregister: no type registered under name: "${name}"`);
/* delete type from registry */
delete _ducky2Registry1Data.registry[name];
};
/* API function: check for registered type under a name */
exports.unregister = unregister;
const registered = function (name) {
/* sanity check arguments */
if (arguments.length !== 1) throw new Error(`registered: invalid number of arguments: ${arguments.length} (exactly 1 expected)`);
if (typeof name !== "string") throw new Error(`registered: invalid name argument: "${name}" (string expected)`);
return _ducky2Registry1Data.registry[name];
};
exports.registered = registered;
},{"./ducky-2-registry-1-data.js":3}],5:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.select_compile = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
const select_compile = function (spec) {
/* result and state variables */
let path = [];
let pos = 0;
/* iterate over selection specification */
let m;
let txt = spec;
while (txt !== "") {
/* case 1: standard path segment */
if ((m = txt.match(/^\s*(?:\.)?\s*([a-zA-Z$0-9_][a-zA-Z$0-9_:-]*)/)) !== null) path.push(m[1]);
/* case 2: numerical array-style dereference */else if ((m = txt.match(/^\s*\[\s*(\d+|\*{1,2})\s*\]/)) !== null) path.push(m[1]);
/* case 3: double-quoted string array-style dereference */else if ((m = txt.match(/^\s*\[\s*"((?:\\"|.)*?)"\s*\]/)) !== null) path.push(m[1].replace(/\\"/g, "\""));
/* case 4: single-quoted string array-style dereference */else if ((m = txt.match(/^\s*\[\s*'((?:\\'|.)*?)'\s*\]/)) !== null) path.push(m[1].replace(/\\'/g, "'"));
/* skip all whitespaces between segments */else if ((m = txt.match(/^\s+$/)) !== null) break;else throw new Error("select: parse error: invalid character at: " + spec.substr(0, pos) + "<" + txt.substr(0, 1) + ">" + txt.substr(1));
/* advance parsing position */
pos += m[0].length;
txt = txt.substr(m[0].length);
}
return path;
};
exports.select_compile = select_compile;
},{}],6:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.select_execute = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* execute object selection */
const select_execute = function (obj, path) {
/* handle special case of empty path */
if (path.length === 0) {
if (arguments.length === 3) throw new Error("select: cannot set value on empty path");else return obj;
}
/* step into object graph according to path prefix */
let i = 0;
while (i < path.length - 1) {
if (typeof obj !== "object") throw new Error("select: cannot further dereference: no more intermediate objects in path");
obj = obj[path[i++]];
}
/* get the old value */
if (typeof obj !== "object") throw new Error("select: cannot further dereference: no object at end of path");
let value_old = obj[path[i]];
/* optionally set new value */
if (arguments.length === 3) {
let value_new = arguments[2];
if (value_new === undefined) {
/* delete value from collection */
if (obj instanceof Array) obj.splice(parseInt(path[i], 10), 1);else delete obj[path[i]];
} else /* set value into collection */
obj[path[i]] = value_new;
}
return value_old;
};
exports.select_execute = select_execute;
},{}],7:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.select = void 0;
var _ducky3Select1Compile = _dereq_("./ducky-3-select-1-compile.js");
var _ducky3Select2Execute = _dereq_("./ducky-3-select-2-execute.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* the internal compile cache */
let select_cache = {};
/* API function: select an arbitrary value via a path specification
and either get the current value or set the new value */
const select = function (obj, spec, value) {
/* sanity check arguments */
if (arguments.length < 2) throw new Error(`select: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`);else if (arguments.length > 3) throw new Error(`select: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`);
if (typeof spec !== "string") throw new Error(`select: invalid specification argument: "${spec}" (string expected)`);
/* compile select path from specification
or reuse cached pre-compiled selection path */
let path = select_cache[spec];
if (typeof path === "undefined") {
path = (0, _ducky3Select1Compile.select_compile)(spec);
select_cache[spec] = path;
}
/* execute the object selection */
return arguments.length === 2 ? (0, _ducky3Select2Execute.select_execute)(obj, path) : (0, _ducky3Select2Execute.select_execute)(obj, path, value);
};
/* compile a path specification into array of dereferencing steps */
exports.select = select;
select.compile = function (spec) {
/* sanity check argument */
if (arguments.length !== 1) throw new Error(`select: invalid number of arguments: ${arguments.length} (exactly 1 expected)`);
if (typeof spec !== "string") throw new Error(`select: invalid specification argument: "${spec}" (string expected)`);
return _ducky3Select1Compile.select_compile.apply(undefined, arguments);
};
/* execute object selection */
select.execute = function (obj, path) {
/* sanity check arguments */
if (arguments.length < 2) throw new Error(`select: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`);else if (arguments.length > 3) throw new Error(`select: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`);
if (!(typeof path === "object" && path instanceof Array)) throw new Error(`select: invalid path argument: "${path}" (array expected)`);
return _ducky3Select2Execute.select_execute.apply(undefined, arguments);
};
},{"./ducky-3-select-1-compile.js":5,"./ducky-3-select-2-execute.js":6}],8:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate_tokenize = void 0;
var _ducky1Util = _dereq_("./ducky-1-util.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* tokenize the validation specification */
const validate_tokenize = function (spec) {
/* create new Token abstraction */
const token = new _ducky1Util.Token();
token.setName("validate");
token.setText(spec);
/* determine individual token symbols */
let m;
let b = 0;
while (spec !== "") {
m = spec.match(/^(\s*)([^\\{}[\]:,?*+()!|/\s]+|[\\{}[\]:,?*+()!|/])(\s*)/);
if (m === null) throw new Error(`validate: parse error: cannot further canonicalize: "${spec}"`);
token.addToken(b, b + m[1].length, b + m[1].length + m[2].length - 1, b + m[0].length - 1, m[2]);
spec = spec.substr(m[0].length);
b += m[0].length;
}
token.addToken(b, b, b, b, null);
return token;
};
exports.validate_tokenize = validate_tokenize;
},{"./ducky-1-util.js":2}],9:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate_parse = void 0;
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* parse specification */
const validate_parse = {
parse(token) {
if (token.len <= 0) return null;
let ast = this.parse_spec(token);
let symbol = token.peek();
if (symbol !== null) throw new Error(`validate: parse error: unexpected token (expected end-of-string): "${token.ctx()}"`);
return ast;
},
/* parse a specification */
parse_spec(token) {
if (token.len <= 0) return null;
let ast;
let symbol = token.peek();
if (symbol === "!") ast = this.parse_not(token);else if (symbol === "(") ast = this.parse_group(token);else if (symbol === "{") ast = this.parse_hash(token);else if (symbol === "[") ast = this.parse_array(token);else if (symbol === "/") ast = this.parse_regexp(token);else if (symbol.match(/^(?:null|undefined|boolean|number|string|function|object)$/)) ast = this.parse_primary(token);else if (symbol === "any") ast = this.parse_any(token);else if (symbol.match(/^[_a-zA-Z$][_a-zA-Z$0-9]*(?:\.[_a-zA-Z$][_a-zA-Z$0-9]*)*$/)) ast = this.parse_class(token);else throw new Error(`validate: parse error: invalid token symbol: "${token.ctx()}"`);
return ast;
},
/* parse boolean "not" operation */
parse_not(token) {
token.consume("!");
let ast = this.parse_spec(token); /* RECURSION */
ast = {
type: "not",
op: ast
};
return ast;
},
/* parse group (for boolean "or" operation) */
parse_group(token) {
token.consume("(");
let ast = this.parse_spec(token);
while (token.peek() === "|") {
token.consume("|");
let child = this.parse_spec(token); /* RECURSION */
ast = {
type: "or",
op1: ast,
op2: child
};
}
token.consume(")");
return ast;
},
/* parse hash type specification */
parse_hash(token) {
token.consume("{");
let elements = [];
while (token.peek() !== "}") {
let key = this.parse_key(token);
let arity = this.parse_arity(token, "?");
token.consume(":");
let spec = this.parse_spec(token); /* RECURSION */
elements.push({
type: "element",
key: key,
arity: arity,
element: spec
});
if (token.peek() === ",") token.skip();else break;
}
let ast = {
type: "hash",
elements: elements
};
token.consume("}");
return ast;
},
/* parse array type specification */
parse_array(token) {
token.consume("[");
let elements = [];
while (token.peek() !== "]") {
const spec = this.parse_spec(token); /* RECURSION */
const arity = this.parse_arity(token, "?*+");
elements.push({
type: "element",
element: spec,
arity: arity
});
if (token.peek() === ",") token.skip();else break;
}
let ast = {
type: "array",
elements: elements
};
token.consume("]");
return ast;
},
/* parse regular expression specification */
parse_regexp(token) {
token.consume("/");
let text = "";
while (token.len >= 1) {
if (token.peek(0) === "/") break;else if (token.len >= 2 && token.peek(0) === "\\" && token.peek(1) === "/") {
text += token.peek(1);
token.skip(2);
} else {
text += token.peek(0);
token.skip(1);
}
}
token.consume("/");
let regexp;
try {
regexp = new RegExp(text);
} catch (ex) {
throw new Error(`validate: parse error: invalid regular expression "${text}": ${ex.message}`);
}
let ast = {
type: "regexp",
regexp: regexp
};
return ast;
},
/* parse primary type specification */
parse_primary(token) {
let primary = token.peek();
if (!primary.match(/^(?:null|undefined|boolean|number|string|function|object)$/)) throw new Error(`validate: parse error: invalid primary type "${primary}"`);
token.skip();
return {
type: "primary",
name: primary
};
},
/* parse special "any" type specification */
parse_any(token) {
let any = token.peek();
if (any !== "any") throw new Error(`validate: parse error: invalid any type "${any}"`);
token.skip();
return {
type: "any"
};
},
/* parse JavaScript class specification */
parse_class(token) {
let clazz = token.peek();
if (!clazz.match(/^[_a-zA-Z$][_a-zA-Z$0-9]*(?:\.[_a-zA-Z$][_a-zA-Z$0-9]*)*$/)) throw new Error(`validate: parse error: invalid class type "${clazz}"`);
token.skip();
return {
type: "class",
name: clazz
};
},
/* parse arity specification */
parse_arity(token, charset) {
let arity = [1, 1];
if (token.len >= 5 && token.peek(0) === "{" && token.peek(1).match(/^[0-9]+$/) && token.peek(2) === "," && token.peek(3).match(/^(?:[0-9]+|oo)$/) && token.peek(4) === "}") {
arity = [parseInt(token.peek(1), 10), token.peek(3) === "oo" ? Number.MAX_VALUE : parseInt(token.peek(3), 10)];
token.skip(5);
} else if (token.len >= 3 && token.peek(0) === "{" && token.peek(1).match(/^[0-9]+$/) && token.peek(2) === "}") {
arity = [parseInt(token.peek(1), 10), parseInt(token.peek(1), 10)];
token.skip(3);
} else if (token.len >= 1 && token.peek().length === 1 && charset.indexOf(token.peek()) >= 0) {
let c = token.peek();
switch (c) {
case "?":
arity = [0, 1];
break;
case "*":
arity = [0, Number.MAX_VALUE];
break;
case "+":
arity = [1, Number.MAX_VALUE];
break;
}
token.skip();
}
return arity;
},
/* parse hash key specification */
parse_key(token) {
const key = token.peek();
if (!key.match(/^(?:[_a-zA-Z$][_a-zA-Z$0-9]*|@)$/)) throw new Error(`validate: parse error: invalid key "${key}"`);
token.skip();
return key;
}
};
exports.validate_parse = validate_parse;
},{}],10:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate_execute = void 0;
var _ducky2Registry2Api = _dereq_("./ducky-2-registry-2-api.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* provide a reasonable context information for error messages */
const errCtx = (path, msg) => {
if (path === "") return `mismatch at root-level: ${msg}`;else return `mismatch at path "${path}": ${msg}`;
};
const validate_execute = {
/* validate specification (top-level) */
exec_spec(value, node, path, errors) {
let valid = false;
if (node !== null) {
switch (node.type) {
case "not":
valid = this.exec_not(value, node, path, errors);
break;
case "or":
valid = this.exec_or(value, node, path, errors);
break;
case "hash":
valid = this.exec_hash(value, node, path, errors);
break;
case "array":
valid = this.exec_array(value, node, path, errors);
break;
case "regexp":
valid = this.exec_regexp(value, node, path, errors);
break;
case "primary":
valid = this.exec_primary(value, node, path, errors);
break;
case "class":
valid = this.exec_class(value, node, path, errors);
break;
case "any":
valid = true;
break;
default:
throw new Error(`validate: invalid validation AST: node has unknown type "${node.type}"`);
}
}
return valid;
},
/* validate through boolean "not" operation */
exec_not(value, node, path, errors) {
let err = errors !== null ? [] : null;
let valid = this.exec_spec(value, node.op, path, err); /* RECURSION */
valid = !valid;
if (!valid && errors !== null) err.forEach(e => errors.push(e));
return valid;
},
/* validate through boolean "or" operation */
exec_or(value, node, path, errors) {
let [err1, err2] = errors !== null ? [[], []] : [null, null];
let valid1 = this.exec_spec(value, node.op1, path, err1); /* RECURSION */
let valid2 = this.exec_spec(value, node.op2, path, err2); /* RECURSION */
let valid = valid1 || valid2;
if (!valid && errors !== null) {
err1.forEach(e => errors.push(e));
err2.forEach(e => errors.push(e));
}
return valid;
},
/* validate hash type */
exec_hash(value, node, path, errors) {
let i, el;
let valid = typeof value === "object" && value !== null;
let fields = {};
let field;
if (!valid && errors !== null) {
if (value === null) errors.push(`mismatch at path "${path}": found "null", expected hash`);else errors.push(`mismatch at path "${path}": found type "${typeof value}", expected hash`);
} else if (valid) {
/* pass 1: ensure that all mandatory fields exist
and determine map of valid fields for pass 2 */
let hasAnyKeys = false;
for (field in value) {
if (!Object.hasOwnProperty.call(value, field) || !Object.propertyIsEnumerable.call(value, field) || field === "constructor" || field === "prototype") continue;
hasAnyKeys = true;
break;
}
for (i = 0; i < node.elements.length; i++) {
el = node.elements[i];
fields[el.key] = el.element;
if (el.arity[0] > 0 && (el.key === "@" && !hasAnyKeys || el.key !== "@" && typeof value[el.key] === "undefined")) {
valid = false;
if (errors !== null) {
if (el.key === "@") errors.push(errCtx(path, "mandatory element under arbitrary key not found"));else errors.push(errCtx(path, `mandatory element under key "${el.key}" not found`));
} else break;
}
}
}
if (valid || errors !== null) {
/* pass 2: ensure that no unknown fields exist
and that all existing fields are valid */
let sep = path !== "" ? "." : "";
for (field in value) {
if (!Object.hasOwnProperty.call(value, field) || !Object.propertyIsEnumerable.call(value, field) || field === "constructor" || field === "prototype") continue;
if (typeof fields[field] === "undefined" && typeof fields["@"] === "undefined" && errors !== null) errors.push(errCtx(path, `element under key "${field}" unexpected`));
if (typeof fields[field] !== "undefined" && this.exec_spec(value[field], fields[field], `${path}${sep}${field}`, errors)) /* RECURSION */
continue;
if (typeof fields["@"] !== "undefined" && this.exec_spec(value[field], fields["@"], `${path}${sep}${field}`, errors)) /* RECURSION */
continue;
valid = false;
if (errors === null) break;
}
}
return valid;
},
/* validate array type */
exec_array(value, node, path, errors) {
let i, el;
let valid = typeof value === "object" && value instanceof Array;
if (!valid && errors !== null) errors.push(errCtx(path, `found type "${typeof value}", expected array`));else if (valid) {
let pos = 0;
let err = null;
/* iterate over all AST nodes */
for (i = 0; i < node.elements.length; i++) {
el = node.elements[i];
let found = 0;
err = errors !== null ? [] : null;
/* iterate over remaining value elements
- as long as the maximum value is not still reached and
- as long as there are still elements available
- as long as the elements are still valid */
while (found < el.arity[1] && pos < value.length) {
if (!this.exec_spec(value[pos], el.element, `${path}[${pos}]`, err)) /* RECURSION */
break;
found++;
pos++;
}
if (found < el.arity[0]) {
if (errors !== null) errors.push(errCtx(`${path}[${pos}]`, `found only ${found} elements of array element type #${i}, ` + `expected at least ${el.arity[0]} elements`));
valid = false;
break;
}
}
/* if last AST node matched not successfully, report its errors */
if (!valid && err !== null && err.length > 0) {
if (errors !== null) err.forEach(e => errors.push(e));
}
/* in case more elements are available without matching nodes */else if (pos < value.length) {
if (errors !== null) errors.push(errCtx(path, `matched only ${pos} elements, ` + `but ${value.length} elements found`));
valid = false;
}
}
return valid;
},
/* validate regular expression */
exec_regexp(value, node, path, errors) {
let valid = value !== null && typeof value.toString === "function" ? node.regexp.test(value.toString()) : false;
if (!valid && errors !== null) errors.push(errCtx(path, `value failed to match regular expression ${node.regexp.toString()}`));
return valid;
},
/* validate standard JavaScript type */
exec_primary(value, node, path, errors) {
let valid = node.name === "null" && value === null || typeof value === node.name;
if (!valid && errors !== null) errors.push(errCtx(path, `found type "${typeof value}", expected primary type "${node.name}"`));
return valid;
},
/* validate custom JavaScript type */
exec_class(value, node, path, errors) {
let type = (0, _ducky2Registry2Api.registered)(node.name);
/* eslint indent: off */
let valid = typeof value === "object" && (Object.prototype.toString.call(value) === "[object " + node.name + "]" || typeof type === "function" && value instanceof type);
if (!valid && errors !== null) errors.push(errCtx(path, `found type "${typeof value}", expected class type "${node.name}"`));
return valid;
}
};
exports.validate_execute = validate_execute;
},{"./ducky-2-registry-2-api.js":4}],11:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validate = void 0;
var _ducky4Validate1Tokenize = _dereq_("./ducky-4-validate-1-tokenize.js");
var _ducky4Validate2Parse = _dereq_("./ducky-4-validate-2-parse.js");
var _ducky4Validate3Execute = _dereq_("./ducky-4-validate-3-execute.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* internal compile cache */
let validate_cache = {};
/* API function: validate an arbitrary value against a validation DSL */
const validate = function (value, spec, errors) {
/* sanity check arguments */
if (arguments.length < 2) throw new Error(`validate: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`);else if (arguments.length > 3) throw new Error(`validate: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`);
if (typeof spec !== "string") throw new Error(`validate: invalid specification argument: "${spec}" (string expected)`);
/* compile validation AST from specification
or reuse cached pre-compiled validation AST */
let ast = validate_cache[spec];
if (typeof ast === "undefined") {
ast = validate.compile(spec);
validate_cache[spec] = ast;
}
/* execute validation AST against the value */
return validate.execute(value, ast, errors);
};
exports.validate = validate;
validate.compile = function (spec) {
/* sanity check arguments */
if (arguments.length !== 1) throw new Error(`validate: invalid number of arguments: ${arguments.length} (exactly 1 expected)`);
if (typeof spec !== "string") throw new Error(`validate: invalid specification argument: "${spec}" (string expected)`);
/* tokenize the specification string into a token stream */
const token = (0, _ducky4Validate1Tokenize.validate_tokenize)(spec);
/* parse the token stream into an AST */
const ast = _ducky4Validate2Parse.validate_parse.parse(token);
return ast;
};
validate.execute = function (value, ast, errors) {
/* sanity check arguments */
if (arguments.length < 2) throw new Error(`validate: invalid number of arguments: ${arguments.length} (minimum of 2 expected)`);else if (arguments.length > 3) throw new Error(`validate: invalid number of arguments: ${arguments.length} (maximum of 3 expected)`);
if (arguments.length < 3 || typeof errors === "undefined") errors = null;
/* execute validation AST against the value */
return _ducky4Validate3Execute.validate_execute.exec_spec(value, ast, "", errors);
};
},{"./ducky-4-validate-1-tokenize.js":8,"./ducky-4-validate-2-parse.js":9,"./ducky-4-validate-3-execute.js":10}],12:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.params = void 0;
var _ducky4Validate4Api = _dereq_("./ducky-4-validate-4-api.js");
/*
** Ducky -- Duck-Typed Value Handling for JavaScript
** Copyright (c) 2010-2023 Dr. Ralf S. Engelschall <rse@engelschall.com>
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* determine or at least guess whether we were called with
positional or name-based parameters */
let params_is_name_based = function (args, spec) {
let name_based = false;
if (args.length === 1 && typeof args[0] === "object") {
/* ok, looks like a regular call like
"foo({ foo: ..., bar: ...})" */
name_based = true;
/* ...but do not be mislead by a positional use like
"foo(bar)" where "bar" is an arbitrary object! */
for (let name in args[0]) {
if (!Object.hasOwnProperty.call(args[0], name)) {
if (typeof spec[name] === "undefined") name_based = false;
}
}
}
return name_based;
};
/* common value validity checking */
let params_check_validity = function (func, param, value, valid, what) {
if (typeof valid === "undefined") return;
if (!(0, _ducky4Validate4Api.validate)(value, valid)) throw new Error(`${func}: parameter "${param}" has ` + `${what} ${JSON.stringify(value)}, which does not validate against "${valid}"`);
};
/* API function: flexible parameter handling */
const params = function (func, args, spec) {
/* start with a fresh parameter object */
const params = {};
/* handle parameter defaults */
let name;
for (name in spec) {
if (!Object.hasOwnProperty.call(spec, name)) continue;
if (typeof spec[name].def !== "undefined") {
if (typeof spec[name].valid !== "undefined") params_check_validity(func, name, spec[name].def, spec[name].valid, "default value");
params[name] = spec[name].def;
}
}
/* process parameters */
if (params_is_name_based(args, spec)) {
args = args[0];
/*
* case 1: name-based parameter specification
*/
/* pass 1: check for unknown but extra parameters */
for (name in args) {
if (!Object.hasOwnProperty.call(args, name)) continue;
if (typeof spec[name] === "undefined") throw new Error(`${func}: unknown parameter "${name}"`);
params_check_validity(func, name, args[name], spec[name].valid, "value");
params[name] = args[name];
}
/* pass 2: check for required but missing parameters */
for (name in spec) {
if (!Object.hasOwnProperty.call(spec, name)) continue;
if (typeof spec[name].req !== "undefined" && spec[name].req && typeof args[name] === "undefined") throw new Error(`${func}: required parameter "${name}" missing`);
}
} else {
/*
* case 2: positional parameter specification
*/
/* pass 1: determine number of positional and total required parameters
and the mapping from parameter position to parameter name */
let positional = 0;
let required = 0;
let pos2name = {};
for (name in spec) {
if (!Object.hasOwnProperty.call(spec, name)) continue;
if (typeof spec[name].pos !== "undefined") {
pos2name[spec[name].pos] = name;
if (typeof spec[name].pos === "number") positional++;
if (typeof spec[name].req !== "undefined" && spec[name].req) required++;
}
}
/* check for required parameters */
if (args.length < required) throw new Error(`${func}: invalid number of arguments (at least ${required} required)`);
/* pass 2: process parameters in sequence */
let i = 0;
while (i < positional && i < args.length) {
params_check_validity(func, pos2name[i], args[i], spec[pos2name[i]].valid, "value");
params[pos2name[i]] = args[i];
i++;
}
if (i < args.length) {
if (typeof pos2name["..."] === "undefined") throw new Error(`${func}: too many arguments provided`);
let rest = [];
while (i < args.length) rest.push(args[i++]);
params_check_validity(func, pos2name["..."], rest, spec[pos2name["..."]].valid, "value");
params[pos2name["..."]] = rest;
}
}
/* return prepared parameter object */
return params;
};
exports.params = params;
},{"./ducky-4-validate-4-api.js":11}],13:[function(_dereq_,module,exports){
"use strict";
Object.defineProperty(