UNPKG

jsonapi-serializer

Version:

A Node.js framework agnostic library for serializing your data to JSON API

1,682 lines (1,377 loc) 192 kB
require=(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(require,module,exports){ 'use strict'; var isPlainObject = require('lodash/isPlainObject'); var isFunction = require('lodash/isFunction'); var _find = require('lodash/find'); var _extend = require('lodash/extend'); var _transform = require('lodash/transform'); var Inflector = require('./inflector'); module.exports = function (jsonapi, data, opts) { var alreadyIncluded = []; function isComplexType(obj) { return Array.isArray(obj) || isPlainObject(obj); } function getValueForRelationship(relationshipData, included) { if (opts && relationshipData && opts[relationshipData.type]) { var valueForRelationshipFct = opts[relationshipData.type] .valueForRelationship; return valueForRelationshipFct(relationshipData, included); } else { return included; } } function findIncluded(relationshipData, ancestry) { return new Promise(function (resolve) { if (!jsonapi.included || !relationshipData) { resolve(null); } var included = _find(jsonapi.included, { id: relationshipData.id, type: relationshipData.type }); if (included) { // To prevent circular references, check if the record type // has already been processed in this thread if (ancestry.indexOf(included.type) > -1) { return Promise .all([extractAttributes(included)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; resolve(_extend(attributes, relationships)); }); } return Promise .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; resolve(_extend(attributes, relationships)); }); } else { return resolve(null); } }); } function keyForAttribute(attribute) { if (isPlainObject(attribute)) { return _transform(attribute, function (result, value, key) { if (isComplexType(value)) { result[keyForAttribute(key)] = keyForAttribute(value); } else { result[keyForAttribute(key)] = value; } }); } else if (Array.isArray(attribute)) { return attribute.map(function (attr) { if (isComplexType(attr)) { return keyForAttribute(attr); } else { return attr; } }); } else { if (isFunction(opts.keyForAttribute)) { return opts.keyForAttribute(attribute); } else { return Inflector.caserize(attribute, opts); } } } function extractAttributes(from) { var dest = keyForAttribute(from.attributes || {}); if ('id' in from) { dest[opts.id || 'id'] = from.id; } if (opts.typeAsAttribute) { if ('type' in from) { dest.type = from.type; } } if ('meta' in from) { dest.meta = keyForAttribute(from.meta || {}) } return dest; } function extractRelationships(from, ancestry) { if (!from.relationships) { return; } var dest = {}; return Promise .all(Object.keys(from.relationships).map(function (key) { var relationship = from.relationships[key]; if (relationship.data === null) { dest[keyForAttribute(key)] = null; } else if (Array.isArray(relationship.data)) { return Promise .all(relationship.data.map(function (relationshipData) { return extractIncludes(relationshipData, ancestry); })) .then(function (includes) { if (includes) { dest[keyForAttribute(key)] = includes; } }); } else { return extractIncludes(relationship.data, ancestry) .then(function (includes) { if (includes) { dest[keyForAttribute(key)] = includes; } }); } })) .then(function() { return dest; }); } function extractIncludes(relationshipData, ancestry) { return findIncluded(relationshipData, ancestry) .then(function (included) { var valueForRelationship = getValueForRelationship(relationshipData, included); if (valueForRelationship && isFunction(valueForRelationship.then)) { return valueForRelationship.then(function (value) { return value; }); } else { return valueForRelationship; } }); } this.perform = function () { return Promise .all([extractAttributes(data), extractRelationships(data, data.type + data.id)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; var record = _extend(attributes, relationships); // Links if (jsonapi.links) { record.links = jsonapi.links; } // If option is present, transform record if (opts && opts.transform) { record = opts.transform(record); } return record; }); }; }; },{"./inflector":5,"lodash/extend":158,"lodash/find":159,"lodash/isFunction":171,"lodash/isPlainObject":176,"lodash/transform":195}],2:[function(require,module,exports){ 'use strict'; var isFunction = require('lodash/isFunction'); var DeserializerUtils = require('./deserializer-utils'); module.exports = function (opts) { if (!opts) { opts = {}; } this.deserialize = function (jsonapi, callback) { function collection() { return Promise .all(jsonapi.data.map(function (d) { return new DeserializerUtils(jsonapi, d, opts).perform(); })) .then(function (result) { if (isFunction(callback)) { callback(null, result); } return result }); } function resource() { return new DeserializerUtils(jsonapi, jsonapi.data, opts) .perform() .then(function (result) { if (isFunction(callback)) { callback(null, result); } return result }); } if (Array.isArray(jsonapi.data)) { return collection(); } else { return resource(); } }; }; },{"./deserializer-utils":1,"lodash/isFunction":171}],3:[function(require,module,exports){ 'use strict'; module.exports = function (errors) { var jsonapi = { errors: [] }; errors.forEach(function (error) { var opts = {}; if (error.id) { opts.id = error.id; } if (error.status) { opts.status = error.status; } if (error.code) { opts.code = error.code; } if (error.title) { opts.title = error.title; } if (error.detail) { opts.detail = error.detail; } if (error.source) { opts.source = {}; if (error.source.pointer) { opts.source.pointer = error.source.pointer; } if (error.source.parameter) { opts.source.parameter = error.source.parameter; } } if (error.links) { opts.links = { about: error.links.about }; } if (error.meta) { opts.meta = error.meta; } jsonapi.errors.push(opts); }); return jsonapi; }; },{}],4:[function(require,module,exports){ 'use strict'; var ErrorUtils = require('./error-utils'); module.exports = function (opts) { if (!opts) { opts = []; } if (Array.isArray(opts)) { return new ErrorUtils(opts); } else { return new ErrorUtils([opts]); } }; },{"./error-utils":3}],5:[function(require,module,exports){ 'use strict'; var Inflector = require('inflected'); module.exports = { caserize: function (attribute, opts) { attribute = Inflector.underscore(attribute); switch (opts.keyForAttribute) { case 'dash-case': case 'lisp-case': case 'spinal-case': case 'kebab-case': return Inflector.dasherize(attribute); case 'underscore_case': case 'snake_case': return attribute; case 'CamelCase': return Inflector.camelize(attribute); case 'camelCase': return Inflector.camelize(attribute, false); default: return Inflector.dasherize(attribute); } }, pluralize: function (type) { return Inflector.pluralize(type); } }; },{"inflected":8}],6:[function(require,module,exports){ 'use strict'; var isPlainObject = require('lodash/isPlainObject'); var isFunction = require('lodash/isFunction'); var _merge = require('lodash/merge'); var _identity = require('lodash/identity'); var _transform = require('lodash/transform'); var _mapValues = require('lodash/mapValues'); var _mapKeys = require('lodash/mapKeys'); var _pick = require('lodash/pick'); var _pickBy = require('lodash/pickBy'); var _each = require('lodash/each'); var _isNil = require('lodash/isNil'); var Inflector = require('./inflector'); module.exports = function (collectionName, record, payload, opts, includedSet) { function isComplexType(obj) { return Array.isArray(obj) || isPlainObject(obj); } function transformFunction(result, value, key) { if (isComplexType(value)) { result[keyForAttribute(key)] = keyForAttribute(value); } else { result[keyForAttribute(key)] = value; } } function attributeFunction(attr) { if (isComplexType(attr)) { return keyForAttribute(attr); } else { return attr; } } const keyForAttributeFunction = isFunction(opts.keyForAttribute) ? opts.keyForAttribute : (attribute) => Inflector.caserize(attribute, opts); function keyForAttribute(attribute) { if (isPlainObject(attribute)) { return _transform(attribute, transformFunction); } else if (Array.isArray(attribute)) { return attribute.map(attributeFunction); } else { return keyForAttributeFunction(attribute); } } function getId() { return opts.id || 'id'; } function getRef(current, item, opts) { if (isFunction(opts.ref)) { return opts.ref(current, item); } else if (opts.ref === true) { if (Array.isArray(item)) { return item.map(function (val) { return String(val); }); } else if (item) { return String(item); } } else if (item && item[opts.ref]){ return String(item[opts.ref]); } } function getType(str, attrVal) { var type; attrVal = attrVal || {}; if (isFunction(opts.typeForAttribute)) { type = opts.typeForAttribute(str, attrVal); } // If the pluralize option is on, typeForAttribute returned undefined or wasn't used if ((opts.pluralizeType === undefined || opts.pluralizeType) && type === undefined) { type = Inflector.pluralize(str); } if (type === undefined) { type = str; } return type; } function getLinks(current, links, dest) { return _mapValues(links, function (value) { if (isFunction(value)) { return value(record, current, dest); } else { return value; } }); } function getMeta(current, meta) { if (isFunction(meta)) { return meta(record); } else { return _mapValues(meta, function (value) { if (isFunction(value)) { return value(record, current); } else { return value; } }); } } function pickFunction (value, key) { return keyForAttribute(key); } function pick(obj, attributes) { return _mapKeys(_pick(obj, attributes), pickFunction); } function isCompoundDocumentIncluded(setKey) { return includedSet.get(setKey); } function pushToIncluded(payload, item) { const setKey = `${item.type}-${item.id}`; var included = isCompoundDocumentIncluded(setKey); if (included) { // Merge relationships included.relationships = _merge(included.relationships, _pickBy(item.relationships, _identity)); // Merge attributes included.attributes = _merge(included.attributes, _pickBy(item.attributes, _identity)); } else { if (!payload.included) { payload.included = []; } includedSet.set(setKey, item); payload.included.push(item); } } this.serialize = function (dest, current, attribute, opts) { var data = null; if (opts && opts.ref) { if (!dest.relationships) { dest.relationships = {}; } if (Array.isArray(current[attribute])) { data = current[attribute].map((item) => this.serializeRef(item, current, attribute, opts)); } else { data = this.serializeRef(current[attribute], current, attribute, opts); } dest.relationships[keyForAttribute(attribute)] = {}; if (!opts.ignoreRelationshipData) { dest.relationships[keyForAttribute(attribute)].data = data; } if (opts.relationshipLinks) { var links = getLinks(current[attribute], opts.relationshipLinks, dest); if (links.related) { dest.relationships[keyForAttribute(attribute)].links = links; } } if (opts.relationshipMeta) { dest.relationships[keyForAttribute(attribute)].meta = getMeta(current[attribute], opts.relationshipMeta); } } else { if (Array.isArray(current[attribute])) { if (current[attribute].length && isPlainObject(current[attribute][0])) { data = current[attribute].map((item) => this.serializeNested(item, current, attribute, opts)); } else { data = current[attribute]; } dest.attributes[keyForAttribute(attribute)] = data; } else if (isPlainObject(current[attribute])) { data = this.serializeNested(current[attribute], current, attribute, opts); dest.attributes[keyForAttribute(attribute)] = data; } else { dest.attributes[keyForAttribute(attribute)] = current[attribute]; } } }; this.serializeRef = function (dest, current, attribute, opts) { var id = getRef(current, dest, opts); var type = getType(attribute, dest); var relationships = []; var includedAttrs = []; if (opts.attributes) { if (dest) { opts.attributes.forEach(function (attr) { if (opts[attr] && !dest[attr] && opts[attr].nullIfMissing) { dest[attr] = null; } }); } relationships = opts.attributes.filter(function (attr) { return opts[attr]; }); includedAttrs = opts.attributes.filter(function (attr) { return !opts[attr]; }); } var included = { type: type, id: id }; if (includedAttrs) { included.attributes = pick(dest, includedAttrs); } const relationShipsFunction = (relationship) => { if (dest && (isComplexType(dest[relationship]) || dest[relationship] === null)) { this.serialize(included, dest, relationship, opts[relationship]); } } relationships.forEach(relationShipsFunction); if (includedAttrs.length && (opts.included === undefined || opts.included)) { if (opts.includedLinks) { included.links = getLinks(dest, opts.includedLinks); } if (typeof id !== 'undefined') { pushToIncluded(payload, included); } } return typeof id !== 'undefined' ? { type: type, id: id } : null; }; this.serializeNested = function (dest, current, attribute, opts) { var embeds = []; var attributes = []; var ret = {}; if (opts && opts.attributes) { embeds = opts.attributes.filter(function (attr) { return opts[attr]; }); attributes = opts.attributes.filter(function (attr) { return !opts[attr]; }); if (attributes) { ret.attributes = pick(dest, attributes); } const embedsFunction = (embed) => { if (isComplexType(dest[embed])) { this.serialize(ret, dest, embed, opts[embed]); } } embeds.forEach(embedsFunction); } else { ret.attributes = dest; } return ret.attributes; }; this.perform = function () { if( record === null ){ return null; } // If option is present, transform record if (opts && opts.transform) { record = opts.transform(record); } // Top-level data. var data = { type: getType(collectionName, record) }; if (!_isNil(record[getId()])) { data.id = String(record[getId()]); } // Data links. if (opts.dataLinks) { data.links = getLinks(record, opts.dataLinks); } // Data meta if (opts.dataMeta) { data.meta = getMeta(record, opts.dataMeta); } _each(opts.attributes, (attribute) => { var splittedAttributes = attribute.split(':'); if (opts[attribute] && !record[attribute] && opts[attribute].nullIfMissing) { record[attribute] = null; } if (splittedAttributes[0] in record) { if (!data.attributes) { data.attributes = {}; } var attributeMap = attribute; if (splittedAttributes.length > 1) { attribute = splittedAttributes[0]; attributeMap = splittedAttributes[1]; } this.serialize(data, record, attribute, opts[attributeMap]); } }); return data; }; }; },{"./inflector":5,"lodash/each":156,"lodash/identity":165,"lodash/isFunction":171,"lodash/isNil":173,"lodash/isPlainObject":176,"lodash/mapKeys":181,"lodash/mapValues":182,"lodash/merge":184,"lodash/pick":185,"lodash/pickBy":186,"lodash/transform":195}],7:[function(require,module,exports){ 'use strict'; var isFunction = require('lodash/isFunction'); var _mapValues = require('lodash/mapValues'); var SerializerUtils = require('./serializer-utils'); module.exports = function (collectionName, records, opts) { this.serialize = function (records) { var that = this; var payload = {}; const includedSet = new Map(); function getLinksFunction(value) { if (isFunction(value)) { return value(records); } else { return value; } } function getLinks(links) { return _mapValues(links, getLinksFunction); } function collection() { payload.data = []; records.forEach(function (record) { var serializerUtils = new SerializerUtils(that.collectionName, record, payload, that.opts, includedSet); payload.data.push(serializerUtils.perform()); }); return payload; } function resource() { payload.data = new SerializerUtils(that.collectionName, records, payload, that.opts, includedSet).perform(records); return payload; } if (that.opts.topLevelLinks) { payload.links = getLinks(that.opts.topLevelLinks); } if (that.opts.meta) { payload.meta = _mapValues(that.opts.meta, function (value) { if (isFunction(value)) { return value(records); } else { return value; } }); } if (Array.isArray(records)) { return collection(records); } else { return resource(records); } }; if (arguments.length === 3) { // legacy behavior this.collectionName = collectionName; this.opts = opts; return this.serialize(records); } else { // treat as a reusable serializer this.collectionName = collectionName; this.opts = records; } }; },{"./serializer-utils":6,"lodash/isFunction":171,"lodash/mapValues":182}],8:[function(require,module,exports){ "use strict"; module.exports = require('./lib/Inflector'); },{"./lib/Inflector":10}],9:[function(require,module,exports){ (function (process,global){ 'use strict'; var hasProp = require('./hasProp'); var remove = require('./remove'); var icPart = require('./icPart'); function Inflections() { this.plurals = []; this.singulars = []; this.uncountables = []; this.humans = []; this.acronyms = {}; this.acronymRegex = /(?=a)b/; } Inflections.getInstance = function(locale) { var storage = typeof process !== 'undefined' ? process : global; storage.__Inflector_Inflections = storage.__Inflector_Inflections || {}; storage.__Inflector_Inflections[locale] = storage.__Inflector_Inflections[locale] || new Inflections(); return storage.__Inflector_Inflections[locale]; }; Inflections.prototype.acronym = function(word) { this.acronyms[word.toLowerCase()] = word; var values = []; for (var key in this.acronyms) { if (hasProp(this.acronyms, key)) { values.push(this.acronyms[key]); } } this.acronymRegex = new RegExp(values.join('|')); }; Inflections.prototype.plural = function(rule, replacement) { if (typeof rule === 'string') { remove(this.uncountables, rule); } remove(this.uncountables, replacement); this.plurals.unshift([rule, replacement]); }; Inflections.prototype.singular = function(rule, replacement) { if (typeof rule === 'string') { remove(this.uncountables, rule); } remove(this.uncountables, replacement); this.singulars.unshift([rule, replacement]); }; Inflections.prototype.irregular = function(singular, plural) { remove(this.uncountables, singular); remove(this.uncountables, plural); var s0 = singular[0]; var sRest = singular.substr(1); var p0 = plural[0]; var pRest = plural.substr(1); if (s0.toUpperCase() === p0.toUpperCase()) { this.plural(new RegExp('(' + s0 + ')' + sRest + '$', 'i'), '$1' + pRest); this.plural(new RegExp('(' + p0 + ')' + pRest + '$', 'i'), '$1' + pRest); this.singular(new RegExp('(' + s0 + ')' + sRest + '$', 'i'), '$1' + sRest); this.singular(new RegExp('(' + p0 + ')' + pRest + '$', 'i'), '$1' + sRest); } else { var sRestIC = icPart(sRest); var pRestIC = icPart(pRest); this.plural(new RegExp(s0.toUpperCase() + sRestIC + '$'), p0.toUpperCase() + pRest); this.plural(new RegExp(s0.toLowerCase() + sRestIC + '$'), p0.toLowerCase() + pRest); this.plural(new RegExp(p0.toUpperCase() + pRestIC + '$'), p0.toUpperCase() + pRest); this.plural(new RegExp(p0.toLowerCase() + pRestIC + '$'), p0.toLowerCase() + pRest); this.singular(new RegExp(s0.toUpperCase() + sRestIC + '$'), s0.toUpperCase() + sRest); this.singular(new RegExp(s0.toLowerCase() + sRestIC + '$'), s0.toLowerCase() + sRest); this.singular(new RegExp(p0.toUpperCase() + pRestIC + '$'), s0.toUpperCase() + sRest); this.singular(new RegExp(p0.toLowerCase() + pRestIC + '$'), s0.toLowerCase() + sRest); } }; Inflections.prototype.uncountable = function() { var words = Array.prototype.slice.call(arguments, 0); this.uncountables = this.uncountables.concat(words); }; Inflections.prototype.human = function(rule, replacement) { this.humans.unshift([rule, replacement]); }; Inflections.prototype.clear = function(scope) { scope = scope || 'all'; if (scope === 'all') { this.plurals = []; this.singulars = []; this.uncountables = []; this.humans = []; } else { this[scope] = []; } }; module.exports = Inflections; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./hasProp":14,"./icPart":15,"./remove":17,"_process":196}],10:[function(require,module,exports){ 'use strict'; var Inflections = require('./Inflections'); var Transliterator = require('./Transliterator'); var Methods = require('./Methods'); var defaults = require('./defaults'); var isFunc = require('./isFunc'); var Inflector = Methods; Inflector.inflections = function(locale, fn) { if (isFunc(locale)) { fn = locale; locale = null; } locale = locale || 'en'; if (fn) { fn(Inflections.getInstance(locale)); } else { return Inflections.getInstance(locale); } }; Inflector.transliterations = function(locale, fn) { if (isFunc(locale)) { fn = locale; locale = null; } locale = locale || 'en'; if (fn) { fn(Transliterator.getInstance(locale)); } else { return Transliterator.getInstance(locale); } } for (var locale in defaults) { Inflector.inflections(locale, defaults[locale]); } module.exports = Inflector; },{"./Inflections":9,"./Methods":11,"./Transliterator":12,"./defaults":13,"./isFunc":16}],11:[function(require,module,exports){ 'use strict'; var Methods = { pluralize: function(word, locale) { locale = locale || 'en'; return this._applyInflections(word, this.inflections(locale).plurals); }, singularize: function(word, locale) { locale = locale || 'en'; return this._applyInflections(word, this.inflections(locale).singulars); }, camelize: function(term, uppercaseFirstLetter) { if (uppercaseFirstLetter === null || uppercaseFirstLetter === undefined) { uppercaseFirstLetter = true; } var result = '' + term, self = this; if (uppercaseFirstLetter) { result = result.replace(/^[a-z\d]*/, function(a) { return self.inflections().acronyms[a] || self.capitalize(a); }); } else { result = result.replace(new RegExp('^(?:' + this.inflections().acronymRegex.source + '(?=\\b|[A-Z_])|\\w)'), function(a) { return a.toLowerCase(); }); } result = result.replace(/(?:_|(\/))([a-z\d]*)/gi, function(match, a, b, idx, string) { a || (a = ''); return '' + a + (self.inflections().acronyms[b] || self.capitalize(b)); }); return result; }, underscore: function(camelCasedWord) { var result = '' + camelCasedWord; result = result.replace(new RegExp('(?:([A-Za-z\\d])|^)(' + this.inflections().acronymRegex.source + ')(?=\\b|[^a-z])', 'g'), function(match, $1, $2) { return '' + ($1 || '') + ($1 ? '_' : '') + $2.toLowerCase(); }); result = result.replace(/([A-Z\d]+)([A-Z][a-z])/g, '$1_$2'); result = result.replace(/([a-z\d])([A-Z])/g, '$1_$2'); result = result.replace(/-/g, '_'); return result.toLowerCase(); }, humanize: function(lowerCaseAndUnderscoredWord, options) { var result = '' + lowerCaseAndUnderscoredWord; var humans = this.inflections().humans; var human, rule, replacement; var self = this; options = options || {}; if (options.capitalize === null || options.capitalize === undefined) { options.capitalize = true; } for (var i = 0, ii = humans.length; i < ii; i++) { human = humans[i]; rule = human[0]; replacement = human[1]; if (rule.test && rule.test(result) || result.indexOf(rule) > -1) { result = result.replace(rule, replacement); break; } } result = result.replace(/_id$/, ''); result = result.replace(/_/g, ' '); result = result.replace(/([a-z\d]*)/gi, function(match) { return self.inflections().acronyms[match] || match.toLowerCase(); }); if (options.capitalize) { result = result.replace(/^\w/, function(match) { return match.toUpperCase(); }); } return result; }, capitalize: function(str) { var result = str === null || str === undefined ? '' : String(str); return result.charAt(0).toUpperCase() + result.slice(1); }, titleize: function(word) { return this.humanize(this.underscore(word)).replace(/(^|[\s¿\/]+)([a-z])/g, function(match, boundary, letter, idx, string) { return match.replace(letter, letter.toUpperCase()); }); }, tableize: function(className) { return this.pluralize(this.underscore(className)); }, classify: function(tableName) { return this.camelize(this.singularize(tableName.replace(/.*\./g, ''))); }, dasherize: function(underscoredWord) { return underscoredWord.replace(/_/g, '-'); }, foreignKey: function(className, separateWithUnderscore) { if (separateWithUnderscore === null || separateWithUnderscore === undefined) { separateWithUnderscore = true; } return this.underscore(className) + (separateWithUnderscore ? '_id' : 'id'); }, ordinal: function(number) { var absNumber = Math.abs(Number(number)); var mod100 = absNumber % 100; if (mod100 === 11 || mod100 === 12 || mod100 === 13) { return 'th'; } else { switch (absNumber % 10) { case 1: return 'st'; case 2: return 'nd'; case 3: return 'rd'; default: return 'th'; } } }, ordinalize: function(number) { return '' + number + this.ordinal(number); }, transliterate: function(string, options) { options = options || {}; var locale = options.locale || 'en'; var replacement = options.replacement || '?'; return this.transliterations(locale).transliterate(string, replacement); }, parameterize: function(string, options) { options = options || {}; if (options.separator === undefined) { options.separator = '-'; } if (options.separator === null) { options.separator = ''; } // replace accented chars with their ascii equivalents var result = this.transliterate(string, options); result = result.replace(/[^a-z0-9\-_]+/ig, options.separator); if (options.separator.length) { var separatorRegex = new RegExp(options.separator); // no more than one of the separator in a row result = result.replace(new RegExp(separatorRegex.source + '{2,}'), options.separator); // remove leading/trailing separator result = result.replace(new RegExp('^' + separatorRegex.source + '|' + separatorRegex.source + '$', 'i'), ''); } return result.toLowerCase(); }, _applyInflections: function(word, rules) { var result = '' + word, rule, regex, replacement; if (result.length === 0) { return result; } else { var match = result.toLowerCase().match(/\b\w+$/); if (match && this.inflections().uncountables.indexOf(match[0]) > -1) { return result; } else { for (var i = 0, ii = rules.length; i < ii; i++) { rule = rules[i]; regex = rule[0]; replacement = rule[1]; if (result.match(regex)) { result = result.replace(regex, replacement); break; } } return result; } } } }; module.exports = Methods; },{}],12:[function(require,module,exports){ (function (process,global){ 'use strict'; var DEFAULT_APPROXIMATIONS = { 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 'O', '×': 'x', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ý': 'Y', 'Þ': 'Th', 'ß': 'ss', 'à': 'a', 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y', 'Ā': 'A', 'ā': 'a', 'Ă': 'A', 'ă': 'a', 'Ą': 'A', 'ą': 'a', 'Ć': 'C', 'ć': 'c', 'Ĉ': 'C', 'ĉ': 'c', 'Ċ': 'C', 'ċ': 'c', 'Č': 'C', 'č': 'c', 'Ď': 'D', 'ď': 'd', 'Đ': 'D', 'đ': 'd', 'Ē': 'E', 'ē': 'e', 'Ĕ': 'E', 'ĕ': 'e', 'Ė': 'E', 'ė': 'e', 'Ę': 'E', 'ę': 'e', 'Ě': 'E', 'ě': 'e', 'Ĝ': 'G', 'ĝ': 'g', 'Ğ': 'G', 'ğ': 'g', 'Ġ': 'G', 'ġ': 'g', 'Ģ': 'G', 'ģ': 'g', 'Ĥ': 'H', 'ĥ': 'h', 'Ħ': 'H', 'ħ': 'h', 'Ĩ': 'I', 'ĩ': 'i', 'Ī': 'I', 'ī': 'i', 'Ĭ': 'I', 'ĭ': 'i', 'Į': 'I', 'į': 'i', 'İ': 'I', 'ı': 'i', 'IJ': 'IJ', 'ij': 'ij', 'Ĵ': 'J', 'ĵ': 'j', 'Ķ': 'K', 'ķ': 'k', 'ĸ': 'k', 'Ĺ': 'L', 'ĺ': 'l', 'Ļ': 'L', 'ļ': 'l', 'Ľ': 'L', 'ľ': 'l', 'Ŀ': 'L', 'ŀ': 'l', 'Ł': 'L', 'ł': 'l', 'Ń': 'N', 'ń': 'n', 'Ņ': 'N', 'ņ': 'n', 'Ň': 'N', 'ň': 'n', 'ʼn': '\'n', 'Ŋ': 'NG', 'ŋ': 'ng', 'Ō': 'O', 'ō': 'o', 'Ŏ': 'O', 'ŏ': 'o', 'Ő': 'O', 'ő': 'o', 'Œ': 'OE', 'œ': 'oe', 'Ŕ': 'R', 'ŕ': 'r', 'Ŗ': 'R', 'ŗ': 'r', 'Ř': 'R', 'ř': 'r', 'Ś': 'S', 'ś': 's', 'Ŝ': 'S', 'ŝ': 's', 'Ş': 'S', 'ş': 's', 'Š': 'S', 'š': 's', 'Ţ': 'T', 'ţ': 't', 'Ť': 'T', 'ť': 't', 'Ŧ': 'T', 'ŧ': 't', 'Ũ': 'U', 'ũ': 'u', 'Ū': 'U', 'ū': 'u', 'Ŭ': 'U', 'ŭ': 'u', 'Ů': 'U', 'ů': 'u', 'Ű': 'U', 'ű': 'u', 'Ų': 'U', 'ų': 'u', 'Ŵ': 'W', 'ŵ': 'w', 'Ŷ': 'Y', 'ŷ': 'y', 'Ÿ': 'Y', 'Ź': 'Z', 'ź': 'z', 'Ż': 'Z', 'ż': 'z', 'Ž': 'Z', 'ž': 'z' }; var DEFAULT_REPLACEMENT_CHAR = '?'; function Transliterator() { this.approximations = {}; for (var c in DEFAULT_APPROXIMATIONS) { this.approximate(c, DEFAULT_APPROXIMATIONS[c]); } } Transliterator.getInstance = function(locale) { var storage = typeof process !== 'undefined' ? process : global; storage.__Inflector_Transliterator = storage.__Inflector_Transliterator || {}; storage.__Inflector_Transliterator[locale] = storage.__Inflector_Transliterator[locale] || new Transliterator(); return storage.__Inflector_Transliterator[locale]; }; Transliterator.prototype.approximate = function(string, replacement) { this.approximations[string] = replacement; }; Transliterator.prototype.transliterate = function(string, replacement) { var self = this; return string.replace(/[^\u0000-\u007f]/g, function(c) { return self.approximations[c] || replacement || DEFAULT_REPLACEMENT_CHAR; }); }; module.exports = Transliterator; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"_process":196}],13:[function(require,module,exports){ 'use strict'; function enDefaults(inflect) { inflect.plural(/$/, 's'); inflect.plural(/s$/i, 's'); inflect.plural(/^(ax|test)is$/i, '$1es'); inflect.plural(/(octop|vir)us$/i, '$1i'); inflect.plural(/(octop|vir)i$/i, '$1i'); inflect.plural(/(alias|status)$/i, '$1es'); inflect.plural(/(bu)s$/i, '$1ses'); inflect.plural(/(buffal|tomat)o$/i, '$1oes'); inflect.plural(/([ti])um$/i, '$1a'); inflect.plural(/([ti])a$/i, '$1a'); inflect.plural(/sis$/i, 'ses'); inflect.plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves'); inflect.plural(/(hive)$/i, '$1s'); inflect.plural(/([^aeiouy]|qu)y$/i, '$1ies'); inflect.plural(/(x|ch|ss|sh)$/i, '$1es'); inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices'); inflect.plural(/^(m|l)ouse$/i, '$1ice'); inflect.plural(/^(m|l)ice$/i, '$1ice'); inflect.plural(/^(ox)$/i, '$1en'); inflect.plural(/^(oxen)$/i, '$1'); inflect.plural(/(quiz)$/i, '$1zes'); inflect.singular(/s$/i, ''); inflect.singular(/(ss)$/i, '$1'); inflect.singular(/(n)ews$/i, '$1ews'); inflect.singular(/([ti])a$/i, '$1um'); inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis'); inflect.singular(/(^analy)(sis|ses)$/i, '$1sis'); inflect.singular(/([^f])ves$/i, '$1fe'); inflect.singular(/(hive)s$/i, '$1'); inflect.singular(/(tive)s$/i, '$1'); inflect.singular(/([lr])ves$/i, '$1f'); inflect.singular(/([^aeiouy]|qu)ies$/i, '$1y'); inflect.singular(/(s)eries$/i, '$1eries'); inflect.singular(/(m)ovies$/i, '$1ovie'); inflect.singular(/(x|ch|ss|sh)es$/i, '$1'); inflect.singular(/^(m|l)ice$/i, '$1ouse'); inflect.singular(/(bus)(es)?$/i, '$1'); inflect.singular(/(o)es$/i, '$1'); inflect.singular(/(shoe)s$/i, '$1'); inflect.singular(/(cris|test)(is|es)$/i, '$1is'); inflect.singular(/^(a)x[ie]s$/i, '$1xis'); inflect.singular(/(octop|vir)(us|i)$/i, '$1us'); inflect.singular(/(alias|status)(es)?$/i, '$1'); inflect.singular(/^(ox)en/i, '$1'); inflect.singular(/(vert|ind)ices$/i, '$1ex'); inflect.singular(/(matr)ices$/i, '$1ix'); inflect.singular(/(quiz)zes$/i, '$1'); inflect.singular(/(database)s$/i, '$1'); inflect.irregular('person', 'people'); inflect.irregular('man', 'men'); inflect.irregular('child', 'children'); inflect.irregular('sex', 'sexes'); inflect.irregular('move', 'moves'); inflect.irregular('zombie', 'zombies'); inflect.uncountable('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'jeans', 'police'); } module.exports = { en: enDefaults }; },{}],14:[function(require,module,exports){ 'use strict'; var hasOwnProp = Object.prototype.hasOwnProperty; function hasProp(obj, key) { return hasOwnProp.call(obj, key); } module.exports = hasProp; },{}],15:[function(require,module,exports){ 'use strict'; function icPart(str) { return str.split('').map(function(c) { return '(?:' + [c.toUpperCase(), c.toLowerCase()].join('|') + ')'; }).join('') } module.exports = icPart; },{}],16:[function(require,module,exports){ 'use strict'; var toString = Object.prototype.toString; function isFunc(obj) { return toString.call(obj) === '[object Function]'; } module.exports = isFunc; },{}],17:[function(require,module,exports){ 'use strict'; var splice = Array.prototype.splice; function remove(arr, elem) { for (var i = arr.length - 1; i >= 0; i--) { if (arr[i] === elem) { splice.call(arr, i, 1); } } } module.exports = remove; },{}],18:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var DataView = getNative(root, 'DataView'); module.exports = DataView; },{"./_getNative":97,"./_root":139}],19:[function(require,module,exports){ var hashClear = require('./_hashClear'), hashDelete = require('./_hashDelete'), hashGet = require('./_hashGet'), hashHas = require('./_hashHas'), hashSet = require('./_hashSet'); /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; module.exports = Hash; },{"./_hashClear":105,"./_hashDelete":106,"./_hashGet":107,"./_hashHas":108,"./_hashSet":109}],20:[function(require,module,exports){ var listCacheClear = require('./_listCacheClear'), listCacheDelete = require('./_listCacheDelete'), listCacheGet = require('./_listCacheGet'), listCacheHas = require('./_listCacheHas'), listCacheSet = require('./_listCacheSet'); /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; module.exports = ListCache; },{"./_listCacheClear":119,"./_listCacheDelete":120,"./_listCacheGet":121,"./_listCacheHas":122,"./_listCacheSet":123}],21:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Map = getNative(root, 'Map'); module.exports = Map; },{"./_getNative":97,"./_root":139}],22:[function(require,module,exports){ var mapCacheClear = require('./_mapCacheClear'), mapCacheDelete = require('./_mapCacheDelete'), mapCacheGet = require('./_mapCacheGet'), mapCacheHas = require('./_mapCacheHas'), mapCacheSet = require('./_mapCacheSet'); /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; module.exports = MapCache; },{"./_mapCacheClear":124,"./_mapCacheDelete":125,"./_mapCacheGet":126,"./_mapCacheHas":127,"./_mapCacheSet":128}],23:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Promise = getNative(root, 'Promise'); module.exports = Promise; },{"./_getNative":97,"./_root":139}],24:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Set = getNative(root, 'Set'); module.exports = Set; },{"./_getNative":97,"./_root":139}],25:[function(require,module,exports){ var MapCache = require('./_MapCache'), setCacheAdd = require('./_setCacheAdd'), setCacheHas = require('./_setCacheHas'); /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache; while (++index < length) { this.add(values[index]); } } // Add methods to `SetCache`. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; module.exports = SetCache; },{"./_MapCache":22,"./_setCacheAdd":141,"./_setCacheHas":142}],26:[function(require,module,exports){ var ListCache = require('./_ListCache'), stackClear = require('./_stackClear'), stackDelete = require('./_stackDelete'), stackGet = require('./_stackGet'), stackHas = require('./_stackHas'), stackSet = require('./_stackSet'); /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = this.__data__ = new ListCache(entries); this.size = data.size; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; module.exports = Stack; },{"./_ListCache":20,"./_stackClear":146,"./_stackDelete":147,"./_stackGet":148,"./_stackHas":149,"./_stackSet":150}],27:[function(require,module,exports){ var root = require('./_root'); /** Built-in value references. */ var Symbol = root.Symbol; module.exports = Symbol; },{"./_root":139}],28:[function(require,module,exports){ var root = require('./_root'); /** Built-in value references. */ var Uint8Array = root.Uint8Array; module.exports = Uint8Array; },{"./_root":139}],29:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var WeakMap = getNative(root, 'WeakMap'); module.exports = WeakMap; },{"./_getNative":97,"./_root":139}],30:[function(require,module,exports){ /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } module.exports = apply; },{}],31:[function(require,module,exports){ /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } module.exports = arrayEach; },{}],32:[function(require,module,exports){ /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } module.exports = arrayFilter; },{}],33:[function(require,module,exports){ var baseTimes = require('./_baseTimes'), isArguments = require('./isArguments'), isArray = require('./isArray'), isBuffer = require('./isBuffer'), isIndex = require('./_isIndex'), isTypedArray = require('./isTypedArray'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; for (var key in value) { if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. (isBuff && (key == 'offset' || key == 'parent')) || // PhantomJS 2 has enumerable non-index properties on typed arrays. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties. isIndex(key, length) ))) { result.push(key); } } return result; } module.exports = arrayLikeKeys; },{"./_baseTimes":71,"./_isIndex":112,"./isArguments":166,"./isArray":167,"./isBuffer":170,"./isTypedArray":178}],34:[function(require,module,exports){ /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } module.exports = arrayMap; },{}],35:[function(require,module,exports){ /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } module.exports = arrayPush; },{}],36:[function(require,module,exports){ /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } module.exports = arraySome; },{}],37:[function(require,module,exports){ var baseAssignValue = require('./_baseAssignValue'), eq = require('./eq'); /** * This function is like `assignValue` except that it doesn't assign * `undefined` values. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */