UNPKG

inflected

Version:

A port of ActiveSupport's inflector to Node.js

602 lines (499 loc) 18.9 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.Inflector = global.Inflector || {}))); }(this, (function (exports) { 'use strict'; var toString = Object.prototype.toString; function isFunc(obj) { return toString.call(obj) === "[object Function]"; } var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function icPart(str) { return str.split("").map(function (c) { return "(?:" + c.toUpperCase() + "|" + c.toLowerCase() + ")"; }).join(""); } function remove(arr, elem) { for (var i = arr.length - 1; i >= 0; i--) { if (arr[i] === elem) { Array.prototype.splice.call(arr, i, 1); } } } function hasProp(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } var instances = {}; var Inflector = function () { createClass(Inflector, null, [{ key: "getInstance", value: function getInstance(locale) { instances[locale] = instances[locale] || new Inflector(); return instances[locale]; } }]); function Inflector() { classCallCheck(this, Inflector); this.plurals = []; this.singulars = []; this.uncountables = []; this.humans = []; this.acronyms = {}; this.acronymRegex = /(?=a)b/; } createClass(Inflector, [{ key: "acronym", value: function acronym(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("|")); } }, { key: "plural", value: function plural(rule, replacement) { if (typeof rule === "string") { remove(this.uncountables, rule); } remove(this.uncountables, replacement); this.plurals.unshift([rule, replacement]); } }, { key: "singular", value: function singular(rule, replacement) { if (typeof rule === "string") { remove(this.uncountables, rule); } remove(this.uncountables, replacement); this.singulars.unshift([rule, replacement]); } }, { key: "irregular", value: function irregular(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); } } }, { key: "uncountable", value: function uncountable() { for (var _len = arguments.length, words = Array(_len), _key = 0; _key < _len; _key++) { words[_key] = arguments[_key]; } this.uncountables = this.uncountables.concat(words); } }, { key: "human", value: function human(rule, replacement) { this.humans.unshift([rule, replacement]); } }, { key: "clear", value: function clear() { var scope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "all"; if (scope === "all") { this.plurals = []; this.singulars = []; this.uncountables = []; this.humans = []; } else { this[scope] = []; } } }]); return Inflector; }(); function en(inflector) { inflector.plural(/$/, "s"); inflector.plural(/s$/i, "s"); inflector.plural(/^(ax|test)is$/i, "$1es"); inflector.plural(/(octop|vir)us$/i, "$1i"); inflector.plural(/(octop|vir)i$/i, "$1i"); inflector.plural(/(alias|status)$/i, "$1es"); inflector.plural(/(bu)s$/i, "$1ses"); inflector.plural(/(buffal|tomat)o$/i, "$1oes"); inflector.plural(/([ti])um$/i, "$1a"); inflector.plural(/([ti])a$/i, "$1a"); inflector.plural(/sis$/i, "ses"); inflector.plural(/(?:([^f])fe|([lr])f)$/i, "$1$2ves"); inflector.plural(/(hive)$/i, "$1s"); inflector.plural(/([^aeiouy]|qu)y$/i, "$1ies"); inflector.plural(/(x|ch|ss|sh)$/i, "$1es"); inflector.plural(/(matr|vert|ind)(?:ix|ex)$/i, "$1ices"); inflector.plural(/^(m|l)ouse$/i, "$1ice"); inflector.plural(/^(m|l)ice$/i, "$1ice"); inflector.plural(/^(ox)$/i, "$1en"); inflector.plural(/^(oxen)$/i, "$1"); inflector.plural(/(quiz)$/i, "$1zes"); inflector.singular(/s$/i, ""); inflector.singular(/(ss)$/i, "$1"); inflector.singular(/(n)ews$/i, "$1ews"); inflector.singular(/([ti])a$/i, "$1um"); inflector.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, "$1sis"); inflector.singular(/(^analy)(sis|ses)$/i, "$1sis"); inflector.singular(/([^f])ves$/i, "$1fe"); inflector.singular(/(hive)s$/i, "$1"); inflector.singular(/(tive)s$/i, "$1"); inflector.singular(/([lr])ves$/i, "$1f"); inflector.singular(/([^aeiouy]|qu)ies$/i, "$1y"); inflector.singular(/(s)eries$/i, "$1eries"); inflector.singular(/(m)ovies$/i, "$1ovie"); inflector.singular(/(x|ch|ss|sh)es$/i, "$1"); inflector.singular(/^(m|l)ice$/i, "$1ouse"); inflector.singular(/(bus)(es)?$/i, "$1"); inflector.singular(/(o)es$/i, "$1"); inflector.singular(/(shoe)s$/i, "$1"); inflector.singular(/(cris|test)(is|es)$/i, "$1is"); inflector.singular(/^(a)x[ie]s$/i, "$1xis"); inflector.singular(/(octop|vir)(us|i)$/i, "$1us"); inflector.singular(/(alias|status)(es)?$/i, "$1"); inflector.singular(/^(ox)en/i, "$1"); inflector.singular(/(vert|ind)ices$/i, "$1ex"); inflector.singular(/(matr)ices$/i, "$1ix"); inflector.singular(/(quiz)zes$/i, "$1"); inflector.singular(/(database)s$/i, "$1"); inflector.irregular("person", "people"); inflector.irregular("man", "men"); inflector.irregular("child", "children"); inflector.irregular("sex", "sexes"); inflector.irregular("move", "moves"); inflector.irregular("zombie", "zombies"); inflector.uncountable("equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "jeans", "police"); } var defaults$1 = { en: en }; function inflections(locale, fn) { if (isFunc(locale)) { fn = locale; locale = null; } locale = locale || "en"; if (fn) { fn(Inflector.getInstance(locale)); } else { return Inflector.getInstance(locale); } } for (var locale in defaults$1) { inflections(locale, defaults$1[locale]); } function applyInflections(word, rules) { var result = "" + word, rule, regex, replacement; if (result.length === 0) { return result; } else { var match = result.toLowerCase().match(/\b\w+$/); if (match && 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; } } } function pluralize(word) { var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "en"; return applyInflections(word, inflections(locale).plurals); } function singularize(word) { var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "en"; return applyInflections(word, inflections(locale).singulars); } function capitalize(str) { var result = str === null || str === undefined ? "" : String(str); return result.charAt(0).toUpperCase() + result.slice(1); } function camelize(term, uppercaseFirstLetter) { if (uppercaseFirstLetter === null || uppercaseFirstLetter === undefined) { uppercaseFirstLetter = true; } var result = "" + term; if (uppercaseFirstLetter) { result = result.replace(/^[a-z\d]*/, function (a) { return inflections().acronyms[a] || capitalize(a); }); } else { result = result.replace(new RegExp("^(?:" + 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 + (inflections().acronyms[b] || capitalize(b)); }); return result; } function underscore(camelCasedWord) { var result = "" + camelCasedWord; result = result.replace(new RegExp("(?:([A-Za-z\\d])|^)(" + 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(); } function humanize(lowerCaseAndUnderscoredWord, options) { var result = "" + lowerCaseAndUnderscoredWord; var humans = inflections().humans; var human = void 0, rule = void 0, replacement = void 0; 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 inflections().acronyms[match] || match.toLowerCase(); }); if (options.capitalize) { result = result.replace(/^\w/, function (match) { return match.toUpperCase(); }); } return result; } function titleize(word) { return humanize(underscore(word)).replace(/(^|[\s¿/]+)([a-z])/g, function (match, boundary, letter, idx, string) { return match.replace(letter, letter.toUpperCase()); }); } function tableize(className) { return pluralize(underscore(className)); } function classify(tableName) { return camelize(singularize(tableName.replace(/.*\./g, ""))); } function dasherize(underscoredWord) { return underscoredWord.replace(/_/g, "-"); } function foreignKey(className) { var separateWithUnderscore = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; return "" + underscore(className) + (separateWithUnderscore ? "_id" : "id"); } function ordinal(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"; } } } function ordinalize(number) { return "" + number + ordinal(number); } // prettier-ignore 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', 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'E', 'Ж': 'ZH', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U', 'Ф': 'F', 'Х': 'KH', 'Ц': 'C', 'Ч': 'CH', 'Ш': 'SH', 'Щ': 'SHCH', 'Ъ': '', 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'YU', 'Я': 'YA', 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'e', 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u', 'ф': 'f', 'х': 'kh', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch', 'ъ': '', 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya' }; var DEFAULT_REPLACEMENT_CHAR = "?"; var instances$1 = {}; var Transliterator = function () { createClass(Transliterator, null, [{ key: 'getInstance', value: function getInstance(locale) { instances$1[locale] = instances$1[locale] || new Transliterator(); return instances$1[locale]; } }]); function Transliterator() { classCallCheck(this, Transliterator); this.approximations = {}; for (var char in DEFAULT_APPROXIMATIONS) { this.approximate(char, DEFAULT_APPROXIMATIONS[char]); } } createClass(Transliterator, [{ key: 'approximate', value: function approximate(char, replacement) { this.approximations[char] = replacement; } }, { key: 'transliterate', value: function transliterate(string, replacement) { var _this = this; return string.replace(/[^\u0000-\u007f]/g, function (c) { return _this.approximations[c] || replacement || DEFAULT_REPLACEMENT_CHAR; }); } }]); return Transliterator; }(); function transliterations(locale, fn) { if (isFunc(locale)) { fn = locale; locale = null; } locale = locale || "en"; if (fn) { fn(Transliterator.getInstance(locale)); } else { return Transliterator.getInstance(locale); } } function transliterate(string) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var locale = options.locale || "en"; var replacement = options.replacement || "?"; return transliterations(locale).transliterate(string, replacement); } function parameterize(string) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (options.separator === undefined) { options.separator = "-"; } if (options.separator === null) { options.separator = ""; } // replace accented chars with their ascii equivalents var result = 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"), ""); } if (options.preserveCase) { return result; } return result.toLowerCase(); } function constantify(word) { return underscore(word).toUpperCase().replace(/\s+/g, "_"); } exports.pluralize = pluralize; exports.singularize = singularize; exports.camelize = camelize; exports.underscore = underscore; exports.humanize = humanize; exports.titleize = titleize; exports.tableize = tableize; exports.classify = classify; exports.dasherize = dasherize; exports.foreignKey = foreignKey; exports.ordinal = ordinal; exports.ordinalize = ordinalize; exports.transliterate = transliterate; exports.parameterize = parameterize; exports.capitalize = capitalize; exports.inflections = inflections; exports.transliterations = transliterations; exports.constantify = constantify; Object.defineProperty(exports, '__esModule', { value: true }); })));