'use strict'; var sequences = {}; var DEFAULTS = { timestamp: function() { return Date.now(); }, datetime: function() { return (new Date).toISOString(); }, date: function() { return (new Date).toISOString().slice(0, 10); }, time: function() { return (new Date).toISOString().slice(11); }, random: function() { return Math.random(); }, randomint: function (args) { var limit = args && args.max || 2; return function() { return Math.floor(Math.random() * limit); }; }, seq: function (args) { var name = args && args.name || ''; sequences[name] = sequences[name] || 0; return function() { return sequences[name]++; }; } }; module.exports = function defFunc(ajv) { defFunc.definition = { compile: function (schema, parentSchema, it) { var funcs = {}; for (var key in schema) { var d = schema[key]; var func = getDefault(typeof d == 'string' ? d : d.func); funcs[key] = func.length ? func(d.args) : func; } return it.opts.useDefaults && !it.compositeRule ? assignDefaults : noop; function assignDefaults(data) { for (var prop in schema) if (data[prop] === undefined) data[prop] = funcs[prop](); return true; } function noop() { return true; } }, DEFAULTS: DEFAULTS, metaSchema: { type: 'object', additionalProperties: { type: ['string', 'object'], additionalProperties: false, required: ['func', 'args'], properties: { func: { type: 'string' }, args: { type: 'object' } } } } }; ajv.addKeyword('dynamicDefaults', defFunc.definition); return ajv; function getDefault(d) { var def = DEFAULTS[d]; if (def) return def; throw new Error('invalid "dynamicDefaults" keyword property value: ' + d); } };