├── tsup.config.js ├── .gitignore ├── .github └── workflows │ └── release.yml ├── package.json ├── LICENSE ├── test ├── test2.js ├── test1.js └── index.html ├── readme.md ├── dist ├── index.js ├── index.d.cts ├── index.d.ts ├── index.cjs └── index.global.js └── src └── index.js /tsup.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.js'], 5 | format: ['esm', 'cjs', 'iife'], 6 | outDir: 'dist', 7 | dts: true, 8 | globalName: 'Inflector', // 👈 ini yang akan membuat window.Inflector tersedia 9 | clean: true, 10 | }); 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node modules 2 | node_modules/ 3 | 4 | # Build output 5 | # dist/ 6 | build/ 7 | .esbuild/ 8 | 9 | # Logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # Env files 16 | .env 17 | .env.* 18 | 19 | # System files 20 | .DS_Store 21 | Thumbs.db 22 | 23 | # Editor directories and files 24 | .vscode/ 25 | .idea/ 26 | *.sublime-project 27 | *.sublime-workspace 28 | 29 | # TypeScript 30 | *.tsbuildinfo 31 | 32 | # Coverage and test output 33 | coverage/ 34 | .nyc_output/ 35 | 36 | # Optional: lockfiles if using one type only 37 | # package-lock.json 38 | # yarn.lock 39 | # pnpm-lock.yaml 40 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build and Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build-and-publish: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Node.js 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: '20' 19 | registry-url: 'https://registry.npmjs.org' 20 | 21 | # - name: Install dependencies 22 | # run: npm install 23 | 24 | # - name: Build project 25 | # run: npm run build 26 | 27 | # - name: Show folder contents 28 | # run: ls -R 29 | 30 | - name: Publish to NPM 31 | run: npm publish 32 | env: 33 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inflector-js", 3 | "version": "2.0.1", 4 | "description": "A lightweight JavaScript utility for smart word transformations – from singular to plural, snake_case to camelCase, and everything in between.", 5 | "type": "module", 6 | "main": "./dist/index.cjs", 7 | "exports": { 8 | "import": "./dist/index.js", 9 | "require": "./dist/index.cjs" 10 | }, 11 | "types": "./dist/index.d.ts", 12 | "scripts": { 13 | "test": "node test/test1.js", 14 | "test2": "node test/test2.js", 15 | "build": "tsup" 16 | }, 17 | "author": "Dida Nurwanda ", 18 | "license": "MIT", 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/didanurwanda/inflector-js.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/didanurwanda/inflector-js/issues" 25 | }, 26 | "homepage": "https://github.com/didanurwanda/inflector-js", 27 | "keywords": [ 28 | "javascript", 29 | "nodejs", 30 | "inflector", 31 | "inflector-js", 32 | "requirejs" 33 | ], 34 | "devDependencies": { 35 | "tsup": "^8.5.0", 36 | "typescript": "^5.8.3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Dida Nurwanda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/test2.js: -------------------------------------------------------------------------------- 1 | import Inflector from '../dist/index.js'; 2 | 3 | console.log('--- Inflector Tests ---'); 4 | 5 | console.log('pluralize("person") =>', Inflector.pluralize('person')); 6 | console.log('singularize("people") =>', Inflector.singularize('people')); 7 | console.log('camelize("message_properties") =>', Inflector.camelize('message_properties')); 8 | console.log('camelize("message_properties", true) =>', Inflector.camelize('message_properties', true)); 9 | console.log('underscore("MessageProperties") =>', Inflector.underscore('MessageProperties')); 10 | console.log('humanize("message_properties") =>', Inflector.humanize('message_properties')); 11 | console.log('humanize("message_properties", true) =>', Inflector.humanize('message_properties', true)); 12 | console.log('capitalize("message properties") =>', Inflector.capitalize('message properties')); 13 | console.log('dasherize("message_properties") =>', Inflector.dasherize('message_properties')); 14 | console.log('dasherize("message properties") =>', Inflector.dasherize('message properties')); 15 | console.log('camel2words("message_properties") =>', Inflector.camel2words('message_properties')); 16 | console.log('camel2words("Message_propertyId", true) =>', Inflector.camel2words('Message_propertyId', true)); 17 | console.log('demodulize("Message::Bus::Properties") =>', Inflector.demodulize('Message::Bus::Properties')); 18 | console.log('tableize("MessageBusProperty") =>', Inflector.tableize('MessageBusProperty')); 19 | console.log('classify("message_bus_properties") =>', Inflector.classify('message_bus_properties')); 20 | console.log('foreignKey("MessageBusProperty") =>', Inflector.foreignKey('MessageBusProperty')); 21 | console.log('foreignKey("MessageBusProperty", true) =>', Inflector.foreignKey('MessageBusProperty', true)); 22 | console.log('ordinalize("the 1 pitch") =>', Inflector.ordinalize('the 1 pitch')); 23 | -------------------------------------------------------------------------------- /test/test1.js: -------------------------------------------------------------------------------- 1 | import { 2 | pluralize, 3 | singularize, 4 | camelize, 5 | underscore, 6 | humanize, 7 | capitalize, 8 | dasherize, 9 | camel2words, 10 | demodulize, 11 | tableize, 12 | classify, 13 | foreignKey, 14 | ordinalize 15 | } from '../dist/index.js'; 16 | 17 | console.log('--- Inflector Tests ---'); 18 | 19 | console.log('pluralize("person") =>', pluralize('person')); 20 | console.log('singularize("people") =>', singularize('people')); 21 | console.log('camelize("message_properties") =>', camelize('message_properties')); 22 | console.log('camelize("message_properties", true) =>', camelize('message_properties', true)); 23 | console.log('underscore("MessageProperties") =>', underscore('MessageProperties')); 24 | console.log('humanize("message_properties") =>', humanize('message_properties')); 25 | console.log('humanize("message_properties", true) =>', humanize('message_properties', true)); 26 | console.log('capitalize("message properties") =>', capitalize('message properties')); 27 | console.log('dasherize("message_properties") =>', dasherize('message_properties')); 28 | console.log('dasherize("message properties") =>', dasherize('message properties')); 29 | console.log('camel2words("message_properties") =>', camel2words('message_properties')); 30 | console.log('camel2words("Message_propertyId", true) =>', camel2words('Message_propertyId', true)); 31 | console.log('demodulize("Message::Bus::Properties") =>', demodulize('Message::Bus::Properties')); 32 | console.log('tableize("MessageBusProperty") =>', tableize('MessageBusProperty')); 33 | console.log('classify("message_bus_properties") =>', classify('message_bus_properties')); 34 | console.log('foreignKey("MessageBusProperty") =>', foreignKey('MessageBusProperty')); 35 | console.log('foreignKey("MessageBusProperty", true) =>', foreignKey('MessageBusProperty', true)); 36 | console.log('ordinalize("the 1 pitch") =>', ordinalize('the 1 pitch')); 37 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Inflector JS Test (IIFE) 7 | 39 | 40 | 41 |

Inflector JS Test Results

42 | 45 | 46 | 47 | 48 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # INFLECTOR-JS 2 | 3 | A lightweight JavaScript utility for smart word transformations – from singular to plural, snake_case to camelCase, and everything in between. 4 | 5 | ## Installation 6 | 7 | ### Install via NPM 8 | 9 | ``` 10 | npm install inflector-js 11 | ``` 12 | 13 | ### Manual Download 14 | 15 | [Last Release](https://github.com/didanurwanda/inflector-js/releases) 16 | 17 | ## How to use 18 | 19 | Node JS 20 | 21 | ### Common JS 22 | 23 | ```js 24 | var Inflector = require('inflector-js'); 25 | ``` 26 | 27 | ### ESM 28 | 29 | ```js 30 | import Inflector from 'inflector-js'; 31 | console.log(Inflector.camelize('message_properties')); 32 | 33 | import { humanize } from 'inflector-js'; 34 | console.log(humanize('message_properties')); 35 | ``` 36 | 37 | ### Browser 38 | 39 | ```html 40 | 44 | 45 | console.log(Inflector.camelize('message_properties')); 46 | ``` 47 | 48 | ## API 49 | 50 | - pluralize 51 | 52 | ``` 53 | 54 | Inflector.pluralize('person') -> 'people' 55 | Inflector.pluralize('octopus') -> 'octopi' 56 | Inflector.pluralize('Hat') -> 'Hats' 57 | Inflector.pluralize('person', 'guys') -> 'guys' 58 | 59 | ``` 60 | 61 | - singularize 62 | 63 | ``` 64 | Inflector.singularize('person') -> 'person' 65 | Inflector.singularize('octopi') -> 'octopus' 66 | Inflector.singularize('hats') -> 'hat' 67 | Inflector.singularize('guys', 'person') -> 'person' 68 | ``` 69 | 70 | - camelize 71 | 72 | ``` 73 | Inflector.camelize('message_properties') -> 'MessageProperties' 74 | Inflector.camelize('message_properties', true) -> 'messageProperties' 75 | ``` 76 | 77 | - underscore 78 | 79 | ``` 80 | Inflector.underscore('MessageProperties') -> 'message_properties' 81 | Inflector.underscore('messageProperties') -> 'message_properties' 82 | ``` 83 | 84 | - humanize 85 | 86 | ``` 87 | Inflector.humanize('message_properties') -> 'Message properties' 88 | Inflector.humanize('message_properties') -> 'message properties' 89 | ``` 90 | 91 | - capitalize 92 | 93 | ``` 94 | Inflector.capitalize('message_properties') -> 'Message_properties' 95 | Inflector.capitalize('message properties') -> 'Message properties' 96 | ``` 97 | 98 | - dasherize 99 | 100 | ``` 101 | Inflector.dasherize('message_properties') -> 'message-properties' 102 | Inflector.dasherize('message properties') -> 'message-properties' 103 | ``` 104 | 105 | - camel2words 106 | 107 | ``` 108 | Inflector.camel2words('message_properties') -> 'Message Properties' 109 | Inflector.camel2words('message properties') -> 'Message Properties' 110 | Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 111 | ``` 112 | 113 | - demodulize 114 | 115 | ``` 116 | Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 117 | ``` 118 | 119 | - tableize 120 | 121 | ``` 122 | Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 123 | ``` 124 | 125 | - classify 126 | 127 | ``` 128 | Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 129 | ``` 130 | 131 | - foreignKey 132 | 133 | ``` 134 | Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 135 | Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 136 | ``` 137 | 138 | - ordinalize 139 | 140 | ``` 141 | Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 142 | ``` 143 | 144 | ## Author 145 | 146 | Created and maintained by **Dida Nurwanda** 147 | [didanurwanda@gmail.com](mailto:didanurwanda@gmail.com) 148 | 149 | --- 150 | 151 | ## License 152 | 153 | This project is licensed under the **MIT**. See the [LICENSE](./LICENSE) file for more details. 154 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | // src/index.js 2 | var Inflector = { 3 | uncountableWords: [ 4 | "equipment", 5 | "information", 6 | "rice", 7 | "money", 8 | "species", 9 | "series", 10 | "fish", 11 | "sheep", 12 | "moose", 13 | "deer", 14 | "news" 15 | ], 16 | pluralRules: [ 17 | [new RegExp("(m)an$", "gi"), "$1en"], 18 | [new RegExp("(pe)rson$", "gi"), "$1ople"], 19 | [new RegExp("(child)$", "gi"), "$1ren"], 20 | [new RegExp("^(ox)$", "gi"), "$1en"], 21 | [new RegExp("(ax|test)is$", "gi"), "$1es"], 22 | [new RegExp("(octop|vir)us$", "gi"), "$1i"], 23 | [new RegExp("(alias|status)$", "gi"), "$1es"], 24 | [new RegExp("(bu)s$", "gi"), "$1ses"], 25 | [new RegExp("(buffal|tomat|potat)o$", "gi"), "$1oes"], 26 | [new RegExp("([ti])um$", "gi"), "$1a"], 27 | [new RegExp("sis$", "gi"), "ses"], 28 | [new RegExp("(?:([^f])fe|([lr])f)$", "gi"), "$1$2ves"], 29 | [new RegExp("(hive)$", "gi"), "$1s"], 30 | [new RegExp("([^aeiouy]|qu)y$", "gi"), "$1ies"], 31 | [new RegExp("(x|ch|ss|sh)$", "gi"), "$1es"], 32 | [new RegExp("(matr|vert|ind)ix|ex$", "gi"), "$1ices"], 33 | [new RegExp("([m|l])ouse$", "gi"), "$1ice"], 34 | [new RegExp("(quiz)$", "gi"), "$1zes"], 35 | [new RegExp("s$", "gi"), "s"], 36 | [new RegExp("$", "gi"), "s"] 37 | ], 38 | singularRules: [ 39 | [new RegExp("(m)en$", "gi"), "$1an"], 40 | [new RegExp("(pe)ople$", "gi"), "$1rson"], 41 | [new RegExp("(child)ren$", "gi"), "$1"], 42 | [new RegExp("([ti])a$", "gi"), "$1um"], 43 | [ 44 | new RegExp( 45 | "((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", 46 | "gi" 47 | ), 48 | "$1$2sis" 49 | ], 50 | [new RegExp("(hive)s$", "gi"), "$1"], 51 | [new RegExp("(tive)s$", "gi"), "$1"], 52 | [new RegExp("(curve)s$", "gi"), "$1"], 53 | [new RegExp("([lr])ves$", "gi"), "$1f"], 54 | [new RegExp("([^fo])ves$", "gi"), "$1fe"], 55 | [new RegExp("([^aeiouy]|qu)ies$", "gi"), "$1y"], 56 | [new RegExp("(s)eries$", "gi"), "$1eries"], 57 | [new RegExp("(m)ovies$", "gi"), "$1ovie"], 58 | [new RegExp("(x|ch|ss|sh)es$", "gi"), "$1"], 59 | [new RegExp("([m|l])ice$", "gi"), "$1ouse"], 60 | [new RegExp("(bus)es$", "gi"), "$1"], 61 | [new RegExp("(o)es$", "gi"), "$1"], 62 | [new RegExp("(shoe)s$", "gi"), "$1"], 63 | [new RegExp("(cris|ax|test)es$", "gi"), "$1is"], 64 | [new RegExp("(octop|vir)i$", "gi"), "$1us"], 65 | [new RegExp("(alias|status)es$", "gi"), "$1"], 66 | [new RegExp("^(ox)en", "gi"), "$1"], 67 | [new RegExp("(vert|ind)ices$", "gi"), "$1ex"], 68 | [new RegExp("(matr)ices$", "gi"), "$1ix"], 69 | [new RegExp("(quiz)zes$", "gi"), "$1"], 70 | [new RegExp("s$", "gi"), ""] 71 | ], 72 | nonTitlecasedWords: [ 73 | "and", 74 | "or", 75 | "nor", 76 | "a", 77 | "an", 78 | "the", 79 | "so", 80 | "but", 81 | "to", 82 | "of", 83 | "at", 84 | "by", 85 | "from", 86 | "into", 87 | "on", 88 | "onto", 89 | "off", 90 | "out", 91 | "in", 92 | "over", 93 | "with", 94 | "for" 95 | ], 96 | idSuffix: new RegExp("(_ids|_id)$", "g"), 97 | underbar: new RegExp("_", "g"), 98 | spaceOrUnderbar: new RegExp("[ _]", "g"), 99 | applyRules: function(str, rules, skip, override) { 100 | if (override) { 101 | str = override; 102 | } else { 103 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 104 | if (!ignore) { 105 | for (var x = 0; x < rules.length; x++) { 106 | if (str.match(rules[x][0])) { 107 | str = str.replace(rules[x][0], rules[x][1]); 108 | break; 109 | } 110 | } 111 | } 112 | } 113 | return str; 114 | }, 115 | /** 116 | * Return the plural form of a word. 117 | * 118 | * @param {String} str 119 | * @param {String} [plural] 120 | * @return {String} 121 | * @example 122 | * Inflector.pluralize('person') -> 'people' 123 | * Inflector.pluralize('octopus') -> 'octopi' 124 | * Inflector.pluralize('Hat') -> 'Hats' 125 | * Inflector.pluralize('person', 'guys') -> 'guys' 126 | */ 127 | pluralize: function(str, plural) { 128 | return Inflector.applyRules( 129 | str, 130 | Inflector.pluralRules, 131 | Inflector.uncountableWords, 132 | plural 133 | ); 134 | }, 135 | /** 136 | * Return the singular form of a word. 137 | * 138 | * @param {String} str 139 | * @param {String} [singular] 140 | * @return {String} 141 | * @example 142 | * Inflector.singularize('person') -> 'person' 143 | * Inflector.singularize('octopi') -> 'octopus' 144 | * Inflector.singularize('hats') -> 'hat' 145 | * Inflector.singularize('guys', 'person') -> 'person' 146 | */ 147 | singularize: function(str, singular) { 148 | return Inflector.applyRules( 149 | str, 150 | Inflector.singularRules, 151 | Inflector.uncountableWords, 152 | singular 153 | ); 154 | }, 155 | /** 156 | * Return the camelized form of a string. 157 | * 158 | * @param {String} str 159 | * @param {Boolean} [lowFirstLetter] 160 | * @return {String} 161 | * @example 162 | * Inflector.camelize('message_properties') -> 'MessageProperties' 163 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 164 | */ 165 | camelize: function(str, lowFirstLetter = false) { 166 | str = str.replace(/\s+/g, "_"); 167 | var str_path = str.split("/"); 168 | for (var i = 0; i < str_path.length; i++) { 169 | var str_arr = str_path[i].split("_"); 170 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 171 | for (var x = initX; x < str_arr.length; x++) { 172 | str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 173 | } 174 | str_path[i] = str_arr.join(""); 175 | } 176 | str = str_path.join("::"); 177 | if (lowFirstLetter === true) { 178 | var first = str.charAt(0).toLowerCase(); 179 | var last = str.slice(1); 180 | str = first + last; 181 | } 182 | return str; 183 | }, 184 | /* 185 | * Return the underscored form of a string. 186 | * 187 | * @param {String} str 188 | * @return {String} 189 | * @example 190 | * Inflector.underscore('MessageProperties') -> 'message_properties' 191 | * Inflector.underscore('messageProperties') -> 'message_properties' 192 | */ 193 | underscore: function(str) { 194 | let withSpaces = str.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase(); 195 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, " "); 196 | let formatted = cleaned.trim().replace(/\s+/g, "_"); 197 | return formatted; 198 | }, 199 | /** 200 | * Converts a string to a human-readable format. 201 | * 202 | * @param {String} str - The string to be humanized. 203 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 204 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 205 | * @example 206 | * Inflector.humanize('message_properties') -> 'Message properties' 207 | * Inflector.humanize('message_properties', true) -> 'message properties' 208 | */ 209 | humanize: function(str, lowFirstLetter) { 210 | var str = str.toLowerCase(); 211 | str = str.replace(Inflector.idSuffix, ""); 212 | str = str.replace(Inflector.underbar, " "); 213 | if (!lowFirstLetter) { 214 | str = Inflector.capitalize(str); 215 | } 216 | return str; 217 | }, 218 | /** 219 | * Capitalizes the first letter of a string, converting the rest to lowercase. 220 | * 221 | * @param {String} str - The string to be capitalized. 222 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 223 | * @example 224 | * Inflector.capitalize('message_properties') -> 'Message_properties' 225 | * Inflector.capitalize('message properties') -> 'Message properties' 226 | */ 227 | capitalize: function(str) { 228 | var str = str.toLowerCase(); 229 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 230 | return str; 231 | }, 232 | /** 233 | * Replaces spaces or underscores in a string with dashes. 234 | * 235 | * @param {String} str - The string to be transformed. 236 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 237 | * @example 238 | * Inflector.dasherize('message_properties') -> 'message-properties' 239 | * Inflector.dasherize('message properties') -> 'message-properties' 240 | */ 241 | dasherize: function(str) { 242 | str = str.replace(Inflector.spaceOrUnderbar, "-"); 243 | return str; 244 | }, 245 | /** 246 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 247 | * 248 | * @param {String} str - The input string to be transformed. 249 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 250 | * ensuring all words are capitalized. 251 | * @return {String} - The transformed string with words separated by spaces, 252 | * and optionally capitalized according to the given parameter. 253 | * @example 254 | * Inflector.camel2words('message_properties') -> 'Message Properties' 255 | * Inflector.camel2words('message properties') -> 'Message Properties' 256 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 257 | */ 258 | camel2words: function(str, allFirstUpper) { 259 | if (allFirstUpper === true) { 260 | str = Inflector.camelize(str); 261 | str = Inflector.underscore(str); 262 | } else { 263 | str = str.toLowerCase(); 264 | } 265 | str = str.replace(Inflector.underbar, " "); 266 | var str_arr = str.split(" "); 267 | for (var x = 0; x < str_arr.length; x++) { 268 | var d = str_arr[x].split("-"); 269 | for (var i = 0; i < d.length; i++) { 270 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 271 | d[i] = Inflector.capitalize(d[i]); 272 | } 273 | } 274 | str_arr[x] = d.join("-"); 275 | } 276 | str = str_arr.join(" "); 277 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 278 | return str; 279 | }, 280 | /** 281 | * Removes the module part of a qualified name. 282 | * 283 | * @param {String} str - The qualified name to be transformed. 284 | * @return {String} - The transformed string without the module part. 285 | * @example 286 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 287 | */ 288 | demodulize: function(str) { 289 | var str_arr = str.split("::"); 290 | str = str_arr[str_arr.length - 1]; 291 | return str; 292 | }, 293 | /** 294 | * Converts a string to its table name form by underscoring and pluralizing it. 295 | * 296 | * @param {String} str - The class name to be converted. 297 | * @return {String} - The table name form of the class name. 298 | * @example 299 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 300 | */ 301 | tableize: function(str) { 302 | str = Inflector.pluralize(Inflector.underscore(str)); 303 | return str; 304 | }, 305 | /** 306 | * Converts a string to its camelCase form and then singularizes it. 307 | * 308 | * @param {String} str - The string to be converted. 309 | * @return {String} - The camelCase singularized string. 310 | * @example 311 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 312 | */ 313 | classify: function(str) { 314 | str = Inflector.singularize(Inflector.camelize(str)); 315 | return str; 316 | }, 317 | /** 318 | * Converts a class name to its foreign key form. 319 | * 320 | * @param {String} str - The class name to be converted. 321 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 322 | * @return {String} - The foreign key form of the class name. 323 | * @example 324 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 325 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 326 | */ 327 | foreignKey: function(str, dropIdUbar) { 328 | str = Inflector.underscore(Inflector.demodulize(str)) + (dropIdUbar ? "" : "_") + "id"; 329 | return str; 330 | }, 331 | /** 332 | * Ordinalizes a given string. 333 | * 334 | * @param {String} str - The string to be ordinalized. 335 | * @return {String} - The ordinalized string. 336 | * @example 337 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 338 | */ 339 | ordinalize: function(str) { 340 | var str_arr = str.split(" "); 341 | for (var x = 0; x < str_arr.length; x++) { 342 | var i = parseInt(str_arr[x], 10); 343 | if (!Number.isNaN(i)) { 344 | var ltd = str_arr[x].slice(-2); 345 | var ld = str_arr[x].slice(-1); 346 | var suf = "th"; 347 | if (ltd !== "11" && ltd !== "12" && ltd !== "13") { 348 | if (ld === "1") { 349 | suf = "st"; 350 | } else if (ld === "2") { 351 | suf = "nd"; 352 | } else if (ld === "3") { 353 | suf = "rd"; 354 | } 355 | } 356 | str_arr[x] = str_arr[x] + suf; 357 | } 358 | } 359 | return str_arr.join(" "); 360 | } 361 | }; 362 | var index_default = Inflector; 363 | var pluralize = Inflector.pluralize; 364 | var singularize = Inflector.singularize; 365 | var camelize = Inflector.camelize; 366 | var underscore = Inflector.underscore; 367 | var humanize = Inflector.humanize; 368 | var capitalize = Inflector.capitalize; 369 | var dasherize = Inflector.dasherize; 370 | var camel2words = Inflector.camel2words; 371 | var demodulize = Inflector.demodulize; 372 | var tableize = Inflector.tableize; 373 | var classify = Inflector.classify; 374 | var foreignKey = Inflector.foreignKey; 375 | var ordinalize = Inflector.ordinalize; 376 | export { 377 | camel2words, 378 | camelize, 379 | capitalize, 380 | classify, 381 | dasherize, 382 | index_default as default, 383 | demodulize, 384 | foreignKey, 385 | humanize, 386 | ordinalize, 387 | pluralize, 388 | singularize, 389 | tableize, 390 | underscore 391 | }; 392 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript inflector 3 | * 4 | * @author Dida Nurwanda 5 | * @since 1.0 6 | */ 7 | 8 | var Inflector = { 9 | uncountableWords: [ 10 | 'equipment', 11 | 'information', 12 | 'rice', 13 | 'money', 14 | 'species', 15 | 'series', 16 | 'fish', 17 | 'sheep', 18 | 'moose', 19 | 'deer', 20 | 'news', 21 | ], 22 | 23 | pluralRules: [ 24 | [new RegExp('(m)an$', 'gi'), '$1en'], 25 | [new RegExp('(pe)rson$', 'gi'), '$1ople'], 26 | [new RegExp('(child)$', 'gi'), '$1ren'], 27 | [new RegExp('^(ox)$', 'gi'), '$1en'], 28 | [new RegExp('(ax|test)is$', 'gi'), '$1es'], 29 | [new RegExp('(octop|vir)us$', 'gi'), '$1i'], 30 | [new RegExp('(alias|status)$', 'gi'), '$1es'], 31 | [new RegExp('(bu)s$', 'gi'), '$1ses'], 32 | [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'], 33 | [new RegExp('([ti])um$', 'gi'), '$1a'], 34 | [new RegExp('sis$', 'gi'), 'ses'], 35 | [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'], 36 | [new RegExp('(hive)$', 'gi'), '$1s'], 37 | [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'], 38 | [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'], 39 | [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'], 40 | [new RegExp('([m|l])ouse$', 'gi'), '$1ice'], 41 | [new RegExp('(quiz)$', 'gi'), '$1zes'], 42 | [new RegExp('s$', 'gi'), 's'], 43 | [new RegExp('$', 'gi'), 's'], 44 | ], 45 | 46 | singularRules: [ 47 | [new RegExp('(m)en$', 'gi'), '$1an'], 48 | [new RegExp('(pe)ople$', 'gi'), '$1rson'], 49 | [new RegExp('(child)ren$', 'gi'), '$1'], 50 | [new RegExp('([ti])a$', 'gi'), '$1um'], 51 | [ 52 | new RegExp( 53 | '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$', 54 | 'gi' 55 | ), 56 | '$1$2sis', 57 | ], 58 | [new RegExp('(hive)s$', 'gi'), '$1'], 59 | [new RegExp('(tive)s$', 'gi'), '$1'], 60 | [new RegExp('(curve)s$', 'gi'), '$1'], 61 | [new RegExp('([lr])ves$', 'gi'), '$1f'], 62 | [new RegExp('([^fo])ves$', 'gi'), '$1fe'], 63 | [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'], 64 | [new RegExp('(s)eries$', 'gi'), '$1eries'], 65 | [new RegExp('(m)ovies$', 'gi'), '$1ovie'], 66 | [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'], 67 | [new RegExp('([m|l])ice$', 'gi'), '$1ouse'], 68 | [new RegExp('(bus)es$', 'gi'), '$1'], 69 | [new RegExp('(o)es$', 'gi'), '$1'], 70 | [new RegExp('(shoe)s$', 'gi'), '$1'], 71 | [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'], 72 | [new RegExp('(octop|vir)i$', 'gi'), '$1us'], 73 | [new RegExp('(alias|status)es$', 'gi'), '$1'], 74 | [new RegExp('^(ox)en', 'gi'), '$1'], 75 | [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'], 76 | [new RegExp('(matr)ices$', 'gi'), '$1ix'], 77 | [new RegExp('(quiz)zes$', 'gi'), '$1'], 78 | [new RegExp('s$', 'gi'), ''], 79 | ], 80 | 81 | nonTitlecasedWords: [ 82 | 'and', 83 | 'or', 84 | 'nor', 85 | 'a', 86 | 'an', 87 | 'the', 88 | 'so', 89 | 'but', 90 | 'to', 91 | 'of', 92 | 'at', 93 | 'by', 94 | 'from', 95 | 'into', 96 | 'on', 97 | 'onto', 98 | 'off', 99 | 'out', 100 | 'in', 101 | 'over', 102 | 'with', 103 | 'for', 104 | ], 105 | 106 | idSuffix: new RegExp('(_ids|_id)$', 'g'), 107 | underbar: new RegExp('_', 'g'), 108 | spaceOrUnderbar: new RegExp('[ _]', 'g'), 109 | 110 | applyRules: function (str, rules, skip, override) { 111 | if (override) { 112 | str = override; 113 | } else { 114 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 115 | if (!ignore) { 116 | for (var x = 0; x < rules.length; x++) { 117 | if (str.match(rules[x][0])) { 118 | str = str.replace(rules[x][0], rules[x][1]); 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | return str; 125 | }, 126 | 127 | /** 128 | * Return the plural form of a word. 129 | * 130 | * @param {String} str 131 | * @param {String} [plural] 132 | * @return {String} 133 | * @example 134 | * Inflector.pluralize('person') -> 'people' 135 | * Inflector.pluralize('octopus') -> 'octopi' 136 | * Inflector.pluralize('Hat') -> 'Hats' 137 | * Inflector.pluralize('person', 'guys') -> 'guys' 138 | */ 139 | pluralize: function (str, plural) { 140 | return Inflector.applyRules( 141 | str, 142 | Inflector.pluralRules, 143 | Inflector.uncountableWords, 144 | plural 145 | ); 146 | }, 147 | 148 | /** 149 | * Return the singular form of a word. 150 | * 151 | * @param {String} str 152 | * @param {String} [singular] 153 | * @return {String} 154 | * @example 155 | * Inflector.singularize('person') -> 'person' 156 | * Inflector.singularize('octopi') -> 'octopus' 157 | * Inflector.singularize('hats') -> 'hat' 158 | * Inflector.singularize('guys', 'person') -> 'person' 159 | */ 160 | singularize: function (str, singular) { 161 | return Inflector.applyRules( 162 | str, 163 | Inflector.singularRules, 164 | Inflector.uncountableWords, 165 | singular 166 | ); 167 | }, 168 | 169 | /** 170 | * Return the camelized form of a string. 171 | * 172 | * @param {String} str 173 | * @param {Boolean} [lowFirstLetter] 174 | * @return {String} 175 | * @example 176 | * Inflector.camelize('message_properties') -> 'MessageProperties' 177 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 178 | */ 179 | camelize: function (str, lowFirstLetter = false) { 180 | // var str = str.toLowerCase(); 181 | str = str.replace(/\s+/g, '_'); // Ubah spasi jadi underscore 182 | 183 | var str_path = str.split('/'); 184 | for (var i = 0; i < str_path.length; i++) { 185 | var str_arr = str_path[i].split('_'); 186 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 187 | for (var x = initX; x < str_arr.length; x++) { 188 | str_arr[x] = 189 | str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 190 | } 191 | str_path[i] = str_arr.join(''); 192 | } 193 | str = str_path.join('::'); 194 | 195 | // fix 196 | if (lowFirstLetter === true) { 197 | var first = str.charAt(0).toLowerCase(); 198 | var last = str.slice(1); 199 | str = first + last; 200 | } 201 | 202 | return str; 203 | }, 204 | 205 | /* 206 | * Return the underscored form of a string. 207 | * 208 | * @param {String} str 209 | * @return {String} 210 | * @example 211 | * Inflector.underscore('MessageProperties') -> 'message_properties' 212 | * Inflector.underscore('messageProperties') -> 'message_properties' 213 | */ 214 | underscore: function (str) { 215 | let withSpaces = str.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase(); 216 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, ' '); 217 | let formatted = cleaned.trim().replace(/\s+/g, '_'); 218 | return formatted; 219 | }, 220 | 221 | /** 222 | * Converts a string to a human-readable format. 223 | * 224 | * @param {String} str - The string to be humanized. 225 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 226 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 227 | * @example 228 | * Inflector.humanize('message_properties') -> 'Message properties' 229 | * Inflector.humanize('message_properties', true) -> 'message properties' 230 | */ 231 | humanize: function (str, lowFirstLetter) { 232 | var str = str.toLowerCase(); 233 | str = str.replace(Inflector.idSuffix, ''); 234 | str = str.replace(Inflector.underbar, ' '); 235 | if (!lowFirstLetter) { 236 | str = Inflector.capitalize(str); 237 | } 238 | return str; 239 | }, 240 | 241 | /** 242 | * Capitalizes the first letter of a string, converting the rest to lowercase. 243 | * 244 | * @param {String} str - The string to be capitalized. 245 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 246 | * @example 247 | * Inflector.capitalize('message_properties') -> 'Message_properties' 248 | * Inflector.capitalize('message properties') -> 'Message properties' 249 | */ 250 | capitalize: function (str) { 251 | var str = str.toLowerCase(); 252 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 253 | return str; 254 | }, 255 | 256 | /** 257 | * Replaces spaces or underscores in a string with dashes. 258 | * 259 | * @param {String} str - The string to be transformed. 260 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 261 | * @example 262 | * Inflector.dasherize('message_properties') -> 'message-properties' 263 | * Inflector.dasherize('message properties') -> 'message-properties' 264 | */ 265 | dasherize: function (str) { 266 | str = str.replace(Inflector.spaceOrUnderbar, '-'); 267 | return str; 268 | }, 269 | 270 | /** 271 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 272 | * 273 | * @param {String} str - The input string to be transformed. 274 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 275 | * ensuring all words are capitalized. 276 | * @return {String} - The transformed string with words separated by spaces, 277 | * and optionally capitalized according to the given parameter. 278 | * @example 279 | * Inflector.camel2words('message_properties') -> 'Message Properties' 280 | * Inflector.camel2words('message properties') -> 'Message Properties' 281 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 282 | */ 283 | camel2words: function (str, allFirstUpper) { 284 | //var str = str.toLowerCase(); 285 | if (allFirstUpper === true) { 286 | str = Inflector.camelize(str); 287 | str = Inflector.underscore(str); 288 | } else { 289 | str = str.toLowerCase(); 290 | } 291 | 292 | str = str.replace(Inflector.underbar, ' '); 293 | var str_arr = str.split(' '); 294 | for (var x = 0; x < str_arr.length; x++) { 295 | var d = str_arr[x].split('-'); 296 | for (var i = 0; i < d.length; i++) { 297 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 298 | d[i] = Inflector.capitalize(d[i]); 299 | } 300 | } 301 | str_arr[x] = d.join('-'); 302 | } 303 | str = str_arr.join(' '); 304 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 305 | return str; 306 | }, 307 | 308 | /** 309 | * Removes the module part of a qualified name. 310 | * 311 | * @param {String} str - The qualified name to be transformed. 312 | * @return {String} - The transformed string without the module part. 313 | * @example 314 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 315 | */ 316 | demodulize: function (str) { 317 | var str_arr = str.split('::'); 318 | str = str_arr[str_arr.length - 1]; 319 | return str; 320 | }, 321 | 322 | /** 323 | * Converts a string to its table name form by underscoring and pluralizing it. 324 | * 325 | * @param {String} str - The class name to be converted. 326 | * @return {String} - The table name form of the class name. 327 | * @example 328 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 329 | */ 330 | tableize: function (str) { 331 | str = Inflector.pluralize(Inflector.underscore(str)); 332 | return str; 333 | }, 334 | 335 | /** 336 | * Converts a string to its camelCase form and then singularizes it. 337 | * 338 | * @param {String} str - The string to be converted. 339 | * @return {String} - The camelCase singularized string. 340 | * @example 341 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 342 | */ 343 | classify: function (str) { 344 | str = Inflector.singularize(Inflector.camelize(str)); 345 | return str; 346 | }, 347 | 348 | /** 349 | * Converts a class name to its foreign key form. 350 | * 351 | * @param {String} str - The class name to be converted. 352 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 353 | * @return {String} - The foreign key form of the class name. 354 | * @example 355 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 356 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 357 | */ 358 | foreignKey: function (str, dropIdUbar) { 359 | str = 360 | Inflector.underscore(Inflector.demodulize(str)) + 361 | (dropIdUbar ? '' : '_') + 362 | 'id'; 363 | return str; 364 | }, 365 | 366 | /** 367 | * Ordinalizes a given string. 368 | * 369 | * @param {String} str - The string to be ordinalized. 370 | * @return {String} - The ordinalized string. 371 | * @example 372 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 373 | */ 374 | ordinalize: function (str) { 375 | var str_arr = str.split(' '); 376 | for (var x = 0; x < str_arr.length; x++) { 377 | var i = parseInt(str_arr[x], 10); 378 | if (!Number.isNaN(i)) { 379 | var ltd = str_arr[x].slice(-2); 380 | var ld = str_arr[x].slice(-1); 381 | var suf = 'th'; 382 | 383 | if (ltd !== '11' && ltd !== '12' && ltd !== '13') { 384 | if (ld === '1') { 385 | suf = 'st'; 386 | } else if (ld === '2') { 387 | suf = 'nd'; 388 | } else if (ld === '3') { 389 | suf = 'rd'; 390 | } 391 | } 392 | 393 | str_arr[x] = str_arr[x] + suf; 394 | } 395 | } 396 | return str_arr.join(' '); 397 | }, 398 | }; 399 | 400 | export default Inflector; 401 | export const pluralize = Inflector.pluralize; 402 | export const singularize = Inflector.singularize; 403 | export const camelize = Inflector.camelize; 404 | export const underscore = Inflector.underscore; 405 | export const humanize = Inflector.humanize; 406 | export const capitalize = Inflector.capitalize; 407 | export const dasherize = Inflector.dasherize; 408 | export const camel2words = Inflector.camel2words; 409 | export const demodulize = Inflector.demodulize; 410 | export const tableize = Inflector.tableize; 411 | export const classify = Inflector.classify; 412 | export const foreignKey = Inflector.foreignKey; 413 | export const ordinalize = Inflector.ordinalize; 414 | -------------------------------------------------------------------------------- /dist/index.d.cts: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript inflector 3 | * 4 | * @author Dida Nurwanda 5 | * @since 1.0 6 | */ 7 | 8 | var Inflector = { 9 | uncountableWords: [ 10 | 'equipment', 11 | 'information', 12 | 'rice', 13 | 'money', 14 | 'species', 15 | 'series', 16 | 'fish', 17 | 'sheep', 18 | 'moose', 19 | 'deer', 20 | 'news', 21 | ], 22 | 23 | pluralRules: [ 24 | [new RegExp('(m)an$', 'gi'), '$1en'], 25 | [new RegExp('(pe)rson$', 'gi'), '$1ople'], 26 | [new RegExp('(child)$', 'gi'), '$1ren'], 27 | [new RegExp('^(ox)$', 'gi'), '$1en'], 28 | [new RegExp('(ax|test)is$', 'gi'), '$1es'], 29 | [new RegExp('(octop|vir)us$', 'gi'), '$1i'], 30 | [new RegExp('(alias|status)$', 'gi'), '$1es'], 31 | [new RegExp('(bu)s$', 'gi'), '$1ses'], 32 | [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'], 33 | [new RegExp('([ti])um$', 'gi'), '$1a'], 34 | [new RegExp('sis$', 'gi'), 'ses'], 35 | [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'], 36 | [new RegExp('(hive)$', 'gi'), '$1s'], 37 | [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'], 38 | [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'], 39 | [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'], 40 | [new RegExp('([m|l])ouse$', 'gi'), '$1ice'], 41 | [new RegExp('(quiz)$', 'gi'), '$1zes'], 42 | [new RegExp('s$', 'gi'), 's'], 43 | [new RegExp('$', 'gi'), 's'], 44 | ], 45 | 46 | singularRules: [ 47 | [new RegExp('(m)en$', 'gi'), '$1an'], 48 | [new RegExp('(pe)ople$', 'gi'), '$1rson'], 49 | [new RegExp('(child)ren$', 'gi'), '$1'], 50 | [new RegExp('([ti])a$', 'gi'), '$1um'], 51 | [ 52 | new RegExp( 53 | '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$', 54 | 'gi' 55 | ), 56 | '$1$2sis', 57 | ], 58 | [new RegExp('(hive)s$', 'gi'), '$1'], 59 | [new RegExp('(tive)s$', 'gi'), '$1'], 60 | [new RegExp('(curve)s$', 'gi'), '$1'], 61 | [new RegExp('([lr])ves$', 'gi'), '$1f'], 62 | [new RegExp('([^fo])ves$', 'gi'), '$1fe'], 63 | [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'], 64 | [new RegExp('(s)eries$', 'gi'), '$1eries'], 65 | [new RegExp('(m)ovies$', 'gi'), '$1ovie'], 66 | [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'], 67 | [new RegExp('([m|l])ice$', 'gi'), '$1ouse'], 68 | [new RegExp('(bus)es$', 'gi'), '$1'], 69 | [new RegExp('(o)es$', 'gi'), '$1'], 70 | [new RegExp('(shoe)s$', 'gi'), '$1'], 71 | [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'], 72 | [new RegExp('(octop|vir)i$', 'gi'), '$1us'], 73 | [new RegExp('(alias|status)es$', 'gi'), '$1'], 74 | [new RegExp('^(ox)en', 'gi'), '$1'], 75 | [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'], 76 | [new RegExp('(matr)ices$', 'gi'), '$1ix'], 77 | [new RegExp('(quiz)zes$', 'gi'), '$1'], 78 | [new RegExp('s$', 'gi'), ''], 79 | ], 80 | 81 | nonTitlecasedWords: [ 82 | 'and', 83 | 'or', 84 | 'nor', 85 | 'a', 86 | 'an', 87 | 'the', 88 | 'so', 89 | 'but', 90 | 'to', 91 | 'of', 92 | 'at', 93 | 'by', 94 | 'from', 95 | 'into', 96 | 'on', 97 | 'onto', 98 | 'off', 99 | 'out', 100 | 'in', 101 | 'over', 102 | 'with', 103 | 'for', 104 | ], 105 | 106 | idSuffix: new RegExp('(_ids|_id)$', 'g'), 107 | underbar: new RegExp('_', 'g'), 108 | spaceOrUnderbar: new RegExp('[ _]', 'g'), 109 | 110 | applyRules: function (str, rules, skip, override) { 111 | if (override) { 112 | str = override; 113 | } else { 114 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 115 | if (!ignore) { 116 | for (var x = 0; x < rules.length; x++) { 117 | if (str.match(rules[x][0])) { 118 | str = str.replace(rules[x][0], rules[x][1]); 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | return str; 125 | }, 126 | 127 | /** 128 | * Return the plural form of a word. 129 | * 130 | * @param {String} str 131 | * @param {String} [plural] 132 | * @return {String} 133 | * @example 134 | * Inflector.pluralize('person') -> 'people' 135 | * Inflector.pluralize('octopus') -> 'octopi' 136 | * Inflector.pluralize('Hat') -> 'Hats' 137 | * Inflector.pluralize('person', 'guys') -> 'guys' 138 | */ 139 | pluralize: function (str, plural) { 140 | return Inflector.applyRules( 141 | str, 142 | Inflector.pluralRules, 143 | Inflector.uncountableWords, 144 | plural 145 | ); 146 | }, 147 | 148 | /** 149 | * Return the singular form of a word. 150 | * 151 | * @param {String} str 152 | * @param {String} [singular] 153 | * @return {String} 154 | * @example 155 | * Inflector.singularize('person') -> 'person' 156 | * Inflector.singularize('octopi') -> 'octopus' 157 | * Inflector.singularize('hats') -> 'hat' 158 | * Inflector.singularize('guys', 'person') -> 'person' 159 | */ 160 | singularize: function (str, singular) { 161 | return Inflector.applyRules( 162 | str, 163 | Inflector.singularRules, 164 | Inflector.uncountableWords, 165 | singular 166 | ); 167 | }, 168 | 169 | /** 170 | * Return the camelized form of a string. 171 | * 172 | * @param {String} str 173 | * @param {Boolean} [lowFirstLetter] 174 | * @return {String} 175 | * @example 176 | * Inflector.camelize('message_properties') -> 'MessageProperties' 177 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 178 | */ 179 | camelize: function (str, lowFirstLetter = false) { 180 | // var str = str.toLowerCase(); 181 | str = str.replace(/\s+/g, '_'); // Ubah spasi jadi underscore 182 | 183 | var str_path = str.split('/'); 184 | for (var i = 0; i < str_path.length; i++) { 185 | var str_arr = str_path[i].split('_'); 186 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 187 | for (var x = initX; x < str_arr.length; x++) { 188 | str_arr[x] = 189 | str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 190 | } 191 | str_path[i] = str_arr.join(''); 192 | } 193 | str = str_path.join('::'); 194 | 195 | // fix 196 | if (lowFirstLetter === true) { 197 | var first = str.charAt(0).toLowerCase(); 198 | var last = str.slice(1); 199 | str = first + last; 200 | } 201 | 202 | return str; 203 | }, 204 | 205 | /* 206 | * Return the underscored form of a string. 207 | * 208 | * @param {String} str 209 | * @return {String} 210 | * @example 211 | * Inflector.underscore('MessageProperties') -> 'message_properties' 212 | * Inflector.underscore('messageProperties') -> 'message_properties' 213 | */ 214 | underscore: function (str) { 215 | let withSpaces = str.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase(); 216 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, ' '); 217 | let formatted = cleaned.trim().replace(/\s+/g, '_'); 218 | return formatted; 219 | }, 220 | 221 | /** 222 | * Converts a string to a human-readable format. 223 | * 224 | * @param {String} str - The string to be humanized. 225 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 226 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 227 | * @example 228 | * Inflector.humanize('message_properties') -> 'Message properties' 229 | * Inflector.humanize('message_properties', true) -> 'message properties' 230 | */ 231 | humanize: function (str, lowFirstLetter) { 232 | var str = str.toLowerCase(); 233 | str = str.replace(Inflector.idSuffix, ''); 234 | str = str.replace(Inflector.underbar, ' '); 235 | if (!lowFirstLetter) { 236 | str = Inflector.capitalize(str); 237 | } 238 | return str; 239 | }, 240 | 241 | /** 242 | * Capitalizes the first letter of a string, converting the rest to lowercase. 243 | * 244 | * @param {String} str - The string to be capitalized. 245 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 246 | * @example 247 | * Inflector.capitalize('message_properties') -> 'Message_properties' 248 | * Inflector.capitalize('message properties') -> 'Message properties' 249 | */ 250 | capitalize: function (str) { 251 | var str = str.toLowerCase(); 252 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 253 | return str; 254 | }, 255 | 256 | /** 257 | * Replaces spaces or underscores in a string with dashes. 258 | * 259 | * @param {String} str - The string to be transformed. 260 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 261 | * @example 262 | * Inflector.dasherize('message_properties') -> 'message-properties' 263 | * Inflector.dasherize('message properties') -> 'message-properties' 264 | */ 265 | dasherize: function (str) { 266 | str = str.replace(Inflector.spaceOrUnderbar, '-'); 267 | return str; 268 | }, 269 | 270 | /** 271 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 272 | * 273 | * @param {String} str - The input string to be transformed. 274 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 275 | * ensuring all words are capitalized. 276 | * @return {String} - The transformed string with words separated by spaces, 277 | * and optionally capitalized according to the given parameter. 278 | * @example 279 | * Inflector.camel2words('message_properties') -> 'Message Properties' 280 | * Inflector.camel2words('message properties') -> 'Message Properties' 281 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 282 | */ 283 | camel2words: function (str, allFirstUpper) { 284 | //var str = str.toLowerCase(); 285 | if (allFirstUpper === true) { 286 | str = Inflector.camelize(str); 287 | str = Inflector.underscore(str); 288 | } else { 289 | str = str.toLowerCase(); 290 | } 291 | 292 | str = str.replace(Inflector.underbar, ' '); 293 | var str_arr = str.split(' '); 294 | for (var x = 0; x < str_arr.length; x++) { 295 | var d = str_arr[x].split('-'); 296 | for (var i = 0; i < d.length; i++) { 297 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 298 | d[i] = Inflector.capitalize(d[i]); 299 | } 300 | } 301 | str_arr[x] = d.join('-'); 302 | } 303 | str = str_arr.join(' '); 304 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 305 | return str; 306 | }, 307 | 308 | /** 309 | * Removes the module part of a qualified name. 310 | * 311 | * @param {String} str - The qualified name to be transformed. 312 | * @return {String} - The transformed string without the module part. 313 | * @example 314 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 315 | */ 316 | demodulize: function (str) { 317 | var str_arr = str.split('::'); 318 | str = str_arr[str_arr.length - 1]; 319 | return str; 320 | }, 321 | 322 | /** 323 | * Converts a string to its table name form by underscoring and pluralizing it. 324 | * 325 | * @param {String} str - The class name to be converted. 326 | * @return {String} - The table name form of the class name. 327 | * @example 328 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 329 | */ 330 | tableize: function (str) { 331 | str = Inflector.pluralize(Inflector.underscore(str)); 332 | return str; 333 | }, 334 | 335 | /** 336 | * Converts a string to its camelCase form and then singularizes it. 337 | * 338 | * @param {String} str - The string to be converted. 339 | * @return {String} - The camelCase singularized string. 340 | * @example 341 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 342 | */ 343 | classify: function (str) { 344 | str = Inflector.singularize(Inflector.camelize(str)); 345 | return str; 346 | }, 347 | 348 | /** 349 | * Converts a class name to its foreign key form. 350 | * 351 | * @param {String} str - The class name to be converted. 352 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 353 | * @return {String} - The foreign key form of the class name. 354 | * @example 355 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 356 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 357 | */ 358 | foreignKey: function (str, dropIdUbar) { 359 | str = 360 | Inflector.underscore(Inflector.demodulize(str)) + 361 | (dropIdUbar ? '' : '_') + 362 | 'id'; 363 | return str; 364 | }, 365 | 366 | /** 367 | * Ordinalizes a given string. 368 | * 369 | * @param {String} str - The string to be ordinalized. 370 | * @return {String} - The ordinalized string. 371 | * @example 372 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 373 | */ 374 | ordinalize: function (str) { 375 | var str_arr = str.split(' '); 376 | for (var x = 0; x < str_arr.length; x++) { 377 | var i = parseInt(str_arr[x], 10); 378 | if (!Number.isNaN(i)) { 379 | var ltd = str_arr[x].slice(-2); 380 | var ld = str_arr[x].slice(-1); 381 | var suf = 'th'; 382 | 383 | if (ltd !== '11' && ltd !== '12' && ltd !== '13') { 384 | if (ld === '1') { 385 | suf = 'st'; 386 | } else if (ld === '2') { 387 | suf = 'nd'; 388 | } else if (ld === '3') { 389 | suf = 'rd'; 390 | } 391 | } 392 | 393 | str_arr[x] = str_arr[x] + suf; 394 | } 395 | } 396 | return str_arr.join(' '); 397 | }, 398 | }; 399 | const pluralize = Inflector.pluralize; 400 | const singularize = Inflector.singularize; 401 | const camelize = Inflector.camelize; 402 | const underscore = Inflector.underscore; 403 | const humanize = Inflector.humanize; 404 | const capitalize = Inflector.capitalize; 405 | const dasherize = Inflector.dasherize; 406 | const camel2words = Inflector.camel2words; 407 | const demodulize = Inflector.demodulize; 408 | const tableize = Inflector.tableize; 409 | const classify = Inflector.classify; 410 | const foreignKey = Inflector.foreignKey; 411 | const ordinalize = Inflector.ordinalize; 412 | 413 | export { camel2words, camelize, capitalize, classify, dasherize, Inflector as default, demodulize, foreignKey, humanize, ordinalize, pluralize, singularize, tableize, underscore }; 414 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript inflector 3 | * 4 | * @author Dida Nurwanda 5 | * @since 1.0 6 | */ 7 | 8 | var Inflector = { 9 | uncountableWords: [ 10 | 'equipment', 11 | 'information', 12 | 'rice', 13 | 'money', 14 | 'species', 15 | 'series', 16 | 'fish', 17 | 'sheep', 18 | 'moose', 19 | 'deer', 20 | 'news', 21 | ], 22 | 23 | pluralRules: [ 24 | [new RegExp('(m)an$', 'gi'), '$1en'], 25 | [new RegExp('(pe)rson$', 'gi'), '$1ople'], 26 | [new RegExp('(child)$', 'gi'), '$1ren'], 27 | [new RegExp('^(ox)$', 'gi'), '$1en'], 28 | [new RegExp('(ax|test)is$', 'gi'), '$1es'], 29 | [new RegExp('(octop|vir)us$', 'gi'), '$1i'], 30 | [new RegExp('(alias|status)$', 'gi'), '$1es'], 31 | [new RegExp('(bu)s$', 'gi'), '$1ses'], 32 | [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'], 33 | [new RegExp('([ti])um$', 'gi'), '$1a'], 34 | [new RegExp('sis$', 'gi'), 'ses'], 35 | [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'), '$1$2ves'], 36 | [new RegExp('(hive)$', 'gi'), '$1s'], 37 | [new RegExp('([^aeiouy]|qu)y$', 'gi'), '$1ies'], 38 | [new RegExp('(x|ch|ss|sh)$', 'gi'), '$1es'], 39 | [new RegExp('(matr|vert|ind)ix|ex$', 'gi'), '$1ices'], 40 | [new RegExp('([m|l])ouse$', 'gi'), '$1ice'], 41 | [new RegExp('(quiz)$', 'gi'), '$1zes'], 42 | [new RegExp('s$', 'gi'), 's'], 43 | [new RegExp('$', 'gi'), 's'], 44 | ], 45 | 46 | singularRules: [ 47 | [new RegExp('(m)en$', 'gi'), '$1an'], 48 | [new RegExp('(pe)ople$', 'gi'), '$1rson'], 49 | [new RegExp('(child)ren$', 'gi'), '$1'], 50 | [new RegExp('([ti])a$', 'gi'), '$1um'], 51 | [ 52 | new RegExp( 53 | '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$', 54 | 'gi' 55 | ), 56 | '$1$2sis', 57 | ], 58 | [new RegExp('(hive)s$', 'gi'), '$1'], 59 | [new RegExp('(tive)s$', 'gi'), '$1'], 60 | [new RegExp('(curve)s$', 'gi'), '$1'], 61 | [new RegExp('([lr])ves$', 'gi'), '$1f'], 62 | [new RegExp('([^fo])ves$', 'gi'), '$1fe'], 63 | [new RegExp('([^aeiouy]|qu)ies$', 'gi'), '$1y'], 64 | [new RegExp('(s)eries$', 'gi'), '$1eries'], 65 | [new RegExp('(m)ovies$', 'gi'), '$1ovie'], 66 | [new RegExp('(x|ch|ss|sh)es$', 'gi'), '$1'], 67 | [new RegExp('([m|l])ice$', 'gi'), '$1ouse'], 68 | [new RegExp('(bus)es$', 'gi'), '$1'], 69 | [new RegExp('(o)es$', 'gi'), '$1'], 70 | [new RegExp('(shoe)s$', 'gi'), '$1'], 71 | [new RegExp('(cris|ax|test)es$', 'gi'), '$1is'], 72 | [new RegExp('(octop|vir)i$', 'gi'), '$1us'], 73 | [new RegExp('(alias|status)es$', 'gi'), '$1'], 74 | [new RegExp('^(ox)en', 'gi'), '$1'], 75 | [new RegExp('(vert|ind)ices$', 'gi'), '$1ex'], 76 | [new RegExp('(matr)ices$', 'gi'), '$1ix'], 77 | [new RegExp('(quiz)zes$', 'gi'), '$1'], 78 | [new RegExp('s$', 'gi'), ''], 79 | ], 80 | 81 | nonTitlecasedWords: [ 82 | 'and', 83 | 'or', 84 | 'nor', 85 | 'a', 86 | 'an', 87 | 'the', 88 | 'so', 89 | 'but', 90 | 'to', 91 | 'of', 92 | 'at', 93 | 'by', 94 | 'from', 95 | 'into', 96 | 'on', 97 | 'onto', 98 | 'off', 99 | 'out', 100 | 'in', 101 | 'over', 102 | 'with', 103 | 'for', 104 | ], 105 | 106 | idSuffix: new RegExp('(_ids|_id)$', 'g'), 107 | underbar: new RegExp('_', 'g'), 108 | spaceOrUnderbar: new RegExp('[ _]', 'g'), 109 | 110 | applyRules: function (str, rules, skip, override) { 111 | if (override) { 112 | str = override; 113 | } else { 114 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 115 | if (!ignore) { 116 | for (var x = 0; x < rules.length; x++) { 117 | if (str.match(rules[x][0])) { 118 | str = str.replace(rules[x][0], rules[x][1]); 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | return str; 125 | }, 126 | 127 | /** 128 | * Return the plural form of a word. 129 | * 130 | * @param {String} str 131 | * @param {String} [plural] 132 | * @return {String} 133 | * @example 134 | * Inflector.pluralize('person') -> 'people' 135 | * Inflector.pluralize('octopus') -> 'octopi' 136 | * Inflector.pluralize('Hat') -> 'Hats' 137 | * Inflector.pluralize('person', 'guys') -> 'guys' 138 | */ 139 | pluralize: function (str, plural) { 140 | return Inflector.applyRules( 141 | str, 142 | Inflector.pluralRules, 143 | Inflector.uncountableWords, 144 | plural 145 | ); 146 | }, 147 | 148 | /** 149 | * Return the singular form of a word. 150 | * 151 | * @param {String} str 152 | * @param {String} [singular] 153 | * @return {String} 154 | * @example 155 | * Inflector.singularize('person') -> 'person' 156 | * Inflector.singularize('octopi') -> 'octopus' 157 | * Inflector.singularize('hats') -> 'hat' 158 | * Inflector.singularize('guys', 'person') -> 'person' 159 | */ 160 | singularize: function (str, singular) { 161 | return Inflector.applyRules( 162 | str, 163 | Inflector.singularRules, 164 | Inflector.uncountableWords, 165 | singular 166 | ); 167 | }, 168 | 169 | /** 170 | * Return the camelized form of a string. 171 | * 172 | * @param {String} str 173 | * @param {Boolean} [lowFirstLetter] 174 | * @return {String} 175 | * @example 176 | * Inflector.camelize('message_properties') -> 'MessageProperties' 177 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 178 | */ 179 | camelize: function (str, lowFirstLetter = false) { 180 | // var str = str.toLowerCase(); 181 | str = str.replace(/\s+/g, '_'); // Ubah spasi jadi underscore 182 | 183 | var str_path = str.split('/'); 184 | for (var i = 0; i < str_path.length; i++) { 185 | var str_arr = str_path[i].split('_'); 186 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 187 | for (var x = initX; x < str_arr.length; x++) { 188 | str_arr[x] = 189 | str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 190 | } 191 | str_path[i] = str_arr.join(''); 192 | } 193 | str = str_path.join('::'); 194 | 195 | // fix 196 | if (lowFirstLetter === true) { 197 | var first = str.charAt(0).toLowerCase(); 198 | var last = str.slice(1); 199 | str = first + last; 200 | } 201 | 202 | return str; 203 | }, 204 | 205 | /* 206 | * Return the underscored form of a string. 207 | * 208 | * @param {String} str 209 | * @return {String} 210 | * @example 211 | * Inflector.underscore('MessageProperties') -> 'message_properties' 212 | * Inflector.underscore('messageProperties') -> 'message_properties' 213 | */ 214 | underscore: function (str) { 215 | let withSpaces = str.replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase(); 216 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, ' '); 217 | let formatted = cleaned.trim().replace(/\s+/g, '_'); 218 | return formatted; 219 | }, 220 | 221 | /** 222 | * Converts a string to a human-readable format. 223 | * 224 | * @param {String} str - The string to be humanized. 225 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 226 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 227 | * @example 228 | * Inflector.humanize('message_properties') -> 'Message properties' 229 | * Inflector.humanize('message_properties', true) -> 'message properties' 230 | */ 231 | humanize: function (str, lowFirstLetter) { 232 | var str = str.toLowerCase(); 233 | str = str.replace(Inflector.idSuffix, ''); 234 | str = str.replace(Inflector.underbar, ' '); 235 | if (!lowFirstLetter) { 236 | str = Inflector.capitalize(str); 237 | } 238 | return str; 239 | }, 240 | 241 | /** 242 | * Capitalizes the first letter of a string, converting the rest to lowercase. 243 | * 244 | * @param {String} str - The string to be capitalized. 245 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 246 | * @example 247 | * Inflector.capitalize('message_properties') -> 'Message_properties' 248 | * Inflector.capitalize('message properties') -> 'Message properties' 249 | */ 250 | capitalize: function (str) { 251 | var str = str.toLowerCase(); 252 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 253 | return str; 254 | }, 255 | 256 | /** 257 | * Replaces spaces or underscores in a string with dashes. 258 | * 259 | * @param {String} str - The string to be transformed. 260 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 261 | * @example 262 | * Inflector.dasherize('message_properties') -> 'message-properties' 263 | * Inflector.dasherize('message properties') -> 'message-properties' 264 | */ 265 | dasherize: function (str) { 266 | str = str.replace(Inflector.spaceOrUnderbar, '-'); 267 | return str; 268 | }, 269 | 270 | /** 271 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 272 | * 273 | * @param {String} str - The input string to be transformed. 274 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 275 | * ensuring all words are capitalized. 276 | * @return {String} - The transformed string with words separated by spaces, 277 | * and optionally capitalized according to the given parameter. 278 | * @example 279 | * Inflector.camel2words('message_properties') -> 'Message Properties' 280 | * Inflector.camel2words('message properties') -> 'Message Properties' 281 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 282 | */ 283 | camel2words: function (str, allFirstUpper) { 284 | //var str = str.toLowerCase(); 285 | if (allFirstUpper === true) { 286 | str = Inflector.camelize(str); 287 | str = Inflector.underscore(str); 288 | } else { 289 | str = str.toLowerCase(); 290 | } 291 | 292 | str = str.replace(Inflector.underbar, ' '); 293 | var str_arr = str.split(' '); 294 | for (var x = 0; x < str_arr.length; x++) { 295 | var d = str_arr[x].split('-'); 296 | for (var i = 0; i < d.length; i++) { 297 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 298 | d[i] = Inflector.capitalize(d[i]); 299 | } 300 | } 301 | str_arr[x] = d.join('-'); 302 | } 303 | str = str_arr.join(' '); 304 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 305 | return str; 306 | }, 307 | 308 | /** 309 | * Removes the module part of a qualified name. 310 | * 311 | * @param {String} str - The qualified name to be transformed. 312 | * @return {String} - The transformed string without the module part. 313 | * @example 314 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 315 | */ 316 | demodulize: function (str) { 317 | var str_arr = str.split('::'); 318 | str = str_arr[str_arr.length - 1]; 319 | return str; 320 | }, 321 | 322 | /** 323 | * Converts a string to its table name form by underscoring and pluralizing it. 324 | * 325 | * @param {String} str - The class name to be converted. 326 | * @return {String} - The table name form of the class name. 327 | * @example 328 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 329 | */ 330 | tableize: function (str) { 331 | str = Inflector.pluralize(Inflector.underscore(str)); 332 | return str; 333 | }, 334 | 335 | /** 336 | * Converts a string to its camelCase form and then singularizes it. 337 | * 338 | * @param {String} str - The string to be converted. 339 | * @return {String} - The camelCase singularized string. 340 | * @example 341 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 342 | */ 343 | classify: function (str) { 344 | str = Inflector.singularize(Inflector.camelize(str)); 345 | return str; 346 | }, 347 | 348 | /** 349 | * Converts a class name to its foreign key form. 350 | * 351 | * @param {String} str - The class name to be converted. 352 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 353 | * @return {String} - The foreign key form of the class name. 354 | * @example 355 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 356 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 357 | */ 358 | foreignKey: function (str, dropIdUbar) { 359 | str = 360 | Inflector.underscore(Inflector.demodulize(str)) + 361 | (dropIdUbar ? '' : '_') + 362 | 'id'; 363 | return str; 364 | }, 365 | 366 | /** 367 | * Ordinalizes a given string. 368 | * 369 | * @param {String} str - The string to be ordinalized. 370 | * @return {String} - The ordinalized string. 371 | * @example 372 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 373 | */ 374 | ordinalize: function (str) { 375 | var str_arr = str.split(' '); 376 | for (var x = 0; x < str_arr.length; x++) { 377 | var i = parseInt(str_arr[x], 10); 378 | if (!Number.isNaN(i)) { 379 | var ltd = str_arr[x].slice(-2); 380 | var ld = str_arr[x].slice(-1); 381 | var suf = 'th'; 382 | 383 | if (ltd !== '11' && ltd !== '12' && ltd !== '13') { 384 | if (ld === '1') { 385 | suf = 'st'; 386 | } else if (ld === '2') { 387 | suf = 'nd'; 388 | } else if (ld === '3') { 389 | suf = 'rd'; 390 | } 391 | } 392 | 393 | str_arr[x] = str_arr[x] + suf; 394 | } 395 | } 396 | return str_arr.join(' '); 397 | }, 398 | }; 399 | const pluralize = Inflector.pluralize; 400 | const singularize = Inflector.singularize; 401 | const camelize = Inflector.camelize; 402 | const underscore = Inflector.underscore; 403 | const humanize = Inflector.humanize; 404 | const capitalize = Inflector.capitalize; 405 | const dasherize = Inflector.dasherize; 406 | const camel2words = Inflector.camel2words; 407 | const demodulize = Inflector.demodulize; 408 | const tableize = Inflector.tableize; 409 | const classify = Inflector.classify; 410 | const foreignKey = Inflector.foreignKey; 411 | const ordinalize = Inflector.ordinalize; 412 | 413 | export { camel2words, camelize, capitalize, classify, dasherize, Inflector as default, demodulize, foreignKey, humanize, ordinalize, pluralize, singularize, tableize, underscore }; 414 | -------------------------------------------------------------------------------- /dist/index.cjs: -------------------------------------------------------------------------------- 1 | var __defProp = Object.defineProperty; 2 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 3 | var __getOwnPropNames = Object.getOwnPropertyNames; 4 | var __hasOwnProp = Object.prototype.hasOwnProperty; 5 | var __export = (target, all) => { 6 | for (var name in all) 7 | __defProp(target, name, { get: all[name], enumerable: true }); 8 | }; 9 | var __copyProps = (to, from, except, desc) => { 10 | if (from && typeof from === "object" || typeof from === "function") { 11 | for (let key of __getOwnPropNames(from)) 12 | if (!__hasOwnProp.call(to, key) && key !== except) 13 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 14 | } 15 | return to; 16 | }; 17 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 18 | 19 | // src/index.js 20 | var index_exports = {}; 21 | __export(index_exports, { 22 | camel2words: () => camel2words, 23 | camelize: () => camelize, 24 | capitalize: () => capitalize, 25 | classify: () => classify, 26 | dasherize: () => dasherize, 27 | default: () => index_default, 28 | demodulize: () => demodulize, 29 | foreignKey: () => foreignKey, 30 | humanize: () => humanize, 31 | ordinalize: () => ordinalize, 32 | pluralize: () => pluralize, 33 | singularize: () => singularize, 34 | tableize: () => tableize, 35 | underscore: () => underscore 36 | }); 37 | module.exports = __toCommonJS(index_exports); 38 | var Inflector = { 39 | uncountableWords: [ 40 | "equipment", 41 | "information", 42 | "rice", 43 | "money", 44 | "species", 45 | "series", 46 | "fish", 47 | "sheep", 48 | "moose", 49 | "deer", 50 | "news" 51 | ], 52 | pluralRules: [ 53 | [new RegExp("(m)an$", "gi"), "$1en"], 54 | [new RegExp("(pe)rson$", "gi"), "$1ople"], 55 | [new RegExp("(child)$", "gi"), "$1ren"], 56 | [new RegExp("^(ox)$", "gi"), "$1en"], 57 | [new RegExp("(ax|test)is$", "gi"), "$1es"], 58 | [new RegExp("(octop|vir)us$", "gi"), "$1i"], 59 | [new RegExp("(alias|status)$", "gi"), "$1es"], 60 | [new RegExp("(bu)s$", "gi"), "$1ses"], 61 | [new RegExp("(buffal|tomat|potat)o$", "gi"), "$1oes"], 62 | [new RegExp("([ti])um$", "gi"), "$1a"], 63 | [new RegExp("sis$", "gi"), "ses"], 64 | [new RegExp("(?:([^f])fe|([lr])f)$", "gi"), "$1$2ves"], 65 | [new RegExp("(hive)$", "gi"), "$1s"], 66 | [new RegExp("([^aeiouy]|qu)y$", "gi"), "$1ies"], 67 | [new RegExp("(x|ch|ss|sh)$", "gi"), "$1es"], 68 | [new RegExp("(matr|vert|ind)ix|ex$", "gi"), "$1ices"], 69 | [new RegExp("([m|l])ouse$", "gi"), "$1ice"], 70 | [new RegExp("(quiz)$", "gi"), "$1zes"], 71 | [new RegExp("s$", "gi"), "s"], 72 | [new RegExp("$", "gi"), "s"] 73 | ], 74 | singularRules: [ 75 | [new RegExp("(m)en$", "gi"), "$1an"], 76 | [new RegExp("(pe)ople$", "gi"), "$1rson"], 77 | [new RegExp("(child)ren$", "gi"), "$1"], 78 | [new RegExp("([ti])a$", "gi"), "$1um"], 79 | [ 80 | new RegExp( 81 | "((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", 82 | "gi" 83 | ), 84 | "$1$2sis" 85 | ], 86 | [new RegExp("(hive)s$", "gi"), "$1"], 87 | [new RegExp("(tive)s$", "gi"), "$1"], 88 | [new RegExp("(curve)s$", "gi"), "$1"], 89 | [new RegExp("([lr])ves$", "gi"), "$1f"], 90 | [new RegExp("([^fo])ves$", "gi"), "$1fe"], 91 | [new RegExp("([^aeiouy]|qu)ies$", "gi"), "$1y"], 92 | [new RegExp("(s)eries$", "gi"), "$1eries"], 93 | [new RegExp("(m)ovies$", "gi"), "$1ovie"], 94 | [new RegExp("(x|ch|ss|sh)es$", "gi"), "$1"], 95 | [new RegExp("([m|l])ice$", "gi"), "$1ouse"], 96 | [new RegExp("(bus)es$", "gi"), "$1"], 97 | [new RegExp("(o)es$", "gi"), "$1"], 98 | [new RegExp("(shoe)s$", "gi"), "$1"], 99 | [new RegExp("(cris|ax|test)es$", "gi"), "$1is"], 100 | [new RegExp("(octop|vir)i$", "gi"), "$1us"], 101 | [new RegExp("(alias|status)es$", "gi"), "$1"], 102 | [new RegExp("^(ox)en", "gi"), "$1"], 103 | [new RegExp("(vert|ind)ices$", "gi"), "$1ex"], 104 | [new RegExp("(matr)ices$", "gi"), "$1ix"], 105 | [new RegExp("(quiz)zes$", "gi"), "$1"], 106 | [new RegExp("s$", "gi"), ""] 107 | ], 108 | nonTitlecasedWords: [ 109 | "and", 110 | "or", 111 | "nor", 112 | "a", 113 | "an", 114 | "the", 115 | "so", 116 | "but", 117 | "to", 118 | "of", 119 | "at", 120 | "by", 121 | "from", 122 | "into", 123 | "on", 124 | "onto", 125 | "off", 126 | "out", 127 | "in", 128 | "over", 129 | "with", 130 | "for" 131 | ], 132 | idSuffix: new RegExp("(_ids|_id)$", "g"), 133 | underbar: new RegExp("_", "g"), 134 | spaceOrUnderbar: new RegExp("[ _]", "g"), 135 | applyRules: function(str, rules, skip, override) { 136 | if (override) { 137 | str = override; 138 | } else { 139 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 140 | if (!ignore) { 141 | for (var x = 0; x < rules.length; x++) { 142 | if (str.match(rules[x][0])) { 143 | str = str.replace(rules[x][0], rules[x][1]); 144 | break; 145 | } 146 | } 147 | } 148 | } 149 | return str; 150 | }, 151 | /** 152 | * Return the plural form of a word. 153 | * 154 | * @param {String} str 155 | * @param {String} [plural] 156 | * @return {String} 157 | * @example 158 | * Inflector.pluralize('person') -> 'people' 159 | * Inflector.pluralize('octopus') -> 'octopi' 160 | * Inflector.pluralize('Hat') -> 'Hats' 161 | * Inflector.pluralize('person', 'guys') -> 'guys' 162 | */ 163 | pluralize: function(str, plural) { 164 | return Inflector.applyRules( 165 | str, 166 | Inflector.pluralRules, 167 | Inflector.uncountableWords, 168 | plural 169 | ); 170 | }, 171 | /** 172 | * Return the singular form of a word. 173 | * 174 | * @param {String} str 175 | * @param {String} [singular] 176 | * @return {String} 177 | * @example 178 | * Inflector.singularize('person') -> 'person' 179 | * Inflector.singularize('octopi') -> 'octopus' 180 | * Inflector.singularize('hats') -> 'hat' 181 | * Inflector.singularize('guys', 'person') -> 'person' 182 | */ 183 | singularize: function(str, singular) { 184 | return Inflector.applyRules( 185 | str, 186 | Inflector.singularRules, 187 | Inflector.uncountableWords, 188 | singular 189 | ); 190 | }, 191 | /** 192 | * Return the camelized form of a string. 193 | * 194 | * @param {String} str 195 | * @param {Boolean} [lowFirstLetter] 196 | * @return {String} 197 | * @example 198 | * Inflector.camelize('message_properties') -> 'MessageProperties' 199 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 200 | */ 201 | camelize: function(str, lowFirstLetter = false) { 202 | str = str.replace(/\s+/g, "_"); 203 | var str_path = str.split("/"); 204 | for (var i = 0; i < str_path.length; i++) { 205 | var str_arr = str_path[i].split("_"); 206 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 207 | for (var x = initX; x < str_arr.length; x++) { 208 | str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 209 | } 210 | str_path[i] = str_arr.join(""); 211 | } 212 | str = str_path.join("::"); 213 | if (lowFirstLetter === true) { 214 | var first = str.charAt(0).toLowerCase(); 215 | var last = str.slice(1); 216 | str = first + last; 217 | } 218 | return str; 219 | }, 220 | /* 221 | * Return the underscored form of a string. 222 | * 223 | * @param {String} str 224 | * @return {String} 225 | * @example 226 | * Inflector.underscore('MessageProperties') -> 'message_properties' 227 | * Inflector.underscore('messageProperties') -> 'message_properties' 228 | */ 229 | underscore: function(str) { 230 | let withSpaces = str.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase(); 231 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, " "); 232 | let formatted = cleaned.trim().replace(/\s+/g, "_"); 233 | return formatted; 234 | }, 235 | /** 236 | * Converts a string to a human-readable format. 237 | * 238 | * @param {String} str - The string to be humanized. 239 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 240 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 241 | * @example 242 | * Inflector.humanize('message_properties') -> 'Message properties' 243 | * Inflector.humanize('message_properties', true) -> 'message properties' 244 | */ 245 | humanize: function(str, lowFirstLetter) { 246 | var str = str.toLowerCase(); 247 | str = str.replace(Inflector.idSuffix, ""); 248 | str = str.replace(Inflector.underbar, " "); 249 | if (!lowFirstLetter) { 250 | str = Inflector.capitalize(str); 251 | } 252 | return str; 253 | }, 254 | /** 255 | * Capitalizes the first letter of a string, converting the rest to lowercase. 256 | * 257 | * @param {String} str - The string to be capitalized. 258 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 259 | * @example 260 | * Inflector.capitalize('message_properties') -> 'Message_properties' 261 | * Inflector.capitalize('message properties') -> 'Message properties' 262 | */ 263 | capitalize: function(str) { 264 | var str = str.toLowerCase(); 265 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 266 | return str; 267 | }, 268 | /** 269 | * Replaces spaces or underscores in a string with dashes. 270 | * 271 | * @param {String} str - The string to be transformed. 272 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 273 | * @example 274 | * Inflector.dasherize('message_properties') -> 'message-properties' 275 | * Inflector.dasherize('message properties') -> 'message-properties' 276 | */ 277 | dasherize: function(str) { 278 | str = str.replace(Inflector.spaceOrUnderbar, "-"); 279 | return str; 280 | }, 281 | /** 282 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 283 | * 284 | * @param {String} str - The input string to be transformed. 285 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 286 | * ensuring all words are capitalized. 287 | * @return {String} - The transformed string with words separated by spaces, 288 | * and optionally capitalized according to the given parameter. 289 | * @example 290 | * Inflector.camel2words('message_properties') -> 'Message Properties' 291 | * Inflector.camel2words('message properties') -> 'Message Properties' 292 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 293 | */ 294 | camel2words: function(str, allFirstUpper) { 295 | if (allFirstUpper === true) { 296 | str = Inflector.camelize(str); 297 | str = Inflector.underscore(str); 298 | } else { 299 | str = str.toLowerCase(); 300 | } 301 | str = str.replace(Inflector.underbar, " "); 302 | var str_arr = str.split(" "); 303 | for (var x = 0; x < str_arr.length; x++) { 304 | var d = str_arr[x].split("-"); 305 | for (var i = 0; i < d.length; i++) { 306 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 307 | d[i] = Inflector.capitalize(d[i]); 308 | } 309 | } 310 | str_arr[x] = d.join("-"); 311 | } 312 | str = str_arr.join(" "); 313 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 314 | return str; 315 | }, 316 | /** 317 | * Removes the module part of a qualified name. 318 | * 319 | * @param {String} str - The qualified name to be transformed. 320 | * @return {String} - The transformed string without the module part. 321 | * @example 322 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 323 | */ 324 | demodulize: function(str) { 325 | var str_arr = str.split("::"); 326 | str = str_arr[str_arr.length - 1]; 327 | return str; 328 | }, 329 | /** 330 | * Converts a string to its table name form by underscoring and pluralizing it. 331 | * 332 | * @param {String} str - The class name to be converted. 333 | * @return {String} - The table name form of the class name. 334 | * @example 335 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 336 | */ 337 | tableize: function(str) { 338 | str = Inflector.pluralize(Inflector.underscore(str)); 339 | return str; 340 | }, 341 | /** 342 | * Converts a string to its camelCase form and then singularizes it. 343 | * 344 | * @param {String} str - The string to be converted. 345 | * @return {String} - The camelCase singularized string. 346 | * @example 347 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 348 | */ 349 | classify: function(str) { 350 | str = Inflector.singularize(Inflector.camelize(str)); 351 | return str; 352 | }, 353 | /** 354 | * Converts a class name to its foreign key form. 355 | * 356 | * @param {String} str - The class name to be converted. 357 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 358 | * @return {String} - The foreign key form of the class name. 359 | * @example 360 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 361 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 362 | */ 363 | foreignKey: function(str, dropIdUbar) { 364 | str = Inflector.underscore(Inflector.demodulize(str)) + (dropIdUbar ? "" : "_") + "id"; 365 | return str; 366 | }, 367 | /** 368 | * Ordinalizes a given string. 369 | * 370 | * @param {String} str - The string to be ordinalized. 371 | * @return {String} - The ordinalized string. 372 | * @example 373 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 374 | */ 375 | ordinalize: function(str) { 376 | var str_arr = str.split(" "); 377 | for (var x = 0; x < str_arr.length; x++) { 378 | var i = parseInt(str_arr[x], 10); 379 | if (!Number.isNaN(i)) { 380 | var ltd = str_arr[x].slice(-2); 381 | var ld = str_arr[x].slice(-1); 382 | var suf = "th"; 383 | if (ltd !== "11" && ltd !== "12" && ltd !== "13") { 384 | if (ld === "1") { 385 | suf = "st"; 386 | } else if (ld === "2") { 387 | suf = "nd"; 388 | } else if (ld === "3") { 389 | suf = "rd"; 390 | } 391 | } 392 | str_arr[x] = str_arr[x] + suf; 393 | } 394 | } 395 | return str_arr.join(" "); 396 | } 397 | }; 398 | var index_default = Inflector; 399 | var pluralize = Inflector.pluralize; 400 | var singularize = Inflector.singularize; 401 | var camelize = Inflector.camelize; 402 | var underscore = Inflector.underscore; 403 | var humanize = Inflector.humanize; 404 | var capitalize = Inflector.capitalize; 405 | var dasherize = Inflector.dasherize; 406 | var camel2words = Inflector.camel2words; 407 | var demodulize = Inflector.demodulize; 408 | var tableize = Inflector.tableize; 409 | var classify = Inflector.classify; 410 | var foreignKey = Inflector.foreignKey; 411 | var ordinalize = Inflector.ordinalize; 412 | // Annotate the CommonJS export names for ESM import in node: 413 | 0 && (module.exports = { 414 | camel2words, 415 | camelize, 416 | capitalize, 417 | classify, 418 | dasherize, 419 | demodulize, 420 | foreignKey, 421 | humanize, 422 | ordinalize, 423 | pluralize, 424 | singularize, 425 | tableize, 426 | underscore 427 | }); 428 | -------------------------------------------------------------------------------- /dist/index.global.js: -------------------------------------------------------------------------------- 1 | var Inflector = (() => { 2 | var __defProp = Object.defineProperty; 3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 4 | var __getOwnPropNames = Object.getOwnPropertyNames; 5 | var __hasOwnProp = Object.prototype.hasOwnProperty; 6 | var __export = (target, all) => { 7 | for (var name in all) 8 | __defProp(target, name, { get: all[name], enumerable: true }); 9 | }; 10 | var __copyProps = (to, from, except, desc) => { 11 | if (from && typeof from === "object" || typeof from === "function") { 12 | for (let key of __getOwnPropNames(from)) 13 | if (!__hasOwnProp.call(to, key) && key !== except) 14 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 15 | } 16 | return to; 17 | }; 18 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 19 | 20 | // src/index.js 21 | var index_exports = {}; 22 | __export(index_exports, { 23 | camel2words: () => camel2words, 24 | camelize: () => camelize, 25 | capitalize: () => capitalize, 26 | classify: () => classify, 27 | dasherize: () => dasherize, 28 | default: () => index_default, 29 | demodulize: () => demodulize, 30 | foreignKey: () => foreignKey, 31 | humanize: () => humanize, 32 | ordinalize: () => ordinalize, 33 | pluralize: () => pluralize, 34 | singularize: () => singularize, 35 | tableize: () => tableize, 36 | underscore: () => underscore 37 | }); 38 | var Inflector = { 39 | uncountableWords: [ 40 | "equipment", 41 | "information", 42 | "rice", 43 | "money", 44 | "species", 45 | "series", 46 | "fish", 47 | "sheep", 48 | "moose", 49 | "deer", 50 | "news" 51 | ], 52 | pluralRules: [ 53 | [new RegExp("(m)an$", "gi"), "$1en"], 54 | [new RegExp("(pe)rson$", "gi"), "$1ople"], 55 | [new RegExp("(child)$", "gi"), "$1ren"], 56 | [new RegExp("^(ox)$", "gi"), "$1en"], 57 | [new RegExp("(ax|test)is$", "gi"), "$1es"], 58 | [new RegExp("(octop|vir)us$", "gi"), "$1i"], 59 | [new RegExp("(alias|status)$", "gi"), "$1es"], 60 | [new RegExp("(bu)s$", "gi"), "$1ses"], 61 | [new RegExp("(buffal|tomat|potat)o$", "gi"), "$1oes"], 62 | [new RegExp("([ti])um$", "gi"), "$1a"], 63 | [new RegExp("sis$", "gi"), "ses"], 64 | [new RegExp("(?:([^f])fe|([lr])f)$", "gi"), "$1$2ves"], 65 | [new RegExp("(hive)$", "gi"), "$1s"], 66 | [new RegExp("([^aeiouy]|qu)y$", "gi"), "$1ies"], 67 | [new RegExp("(x|ch|ss|sh)$", "gi"), "$1es"], 68 | [new RegExp("(matr|vert|ind)ix|ex$", "gi"), "$1ices"], 69 | [new RegExp("([m|l])ouse$", "gi"), "$1ice"], 70 | [new RegExp("(quiz)$", "gi"), "$1zes"], 71 | [new RegExp("s$", "gi"), "s"], 72 | [new RegExp("$", "gi"), "s"] 73 | ], 74 | singularRules: [ 75 | [new RegExp("(m)en$", "gi"), "$1an"], 76 | [new RegExp("(pe)ople$", "gi"), "$1rson"], 77 | [new RegExp("(child)ren$", "gi"), "$1"], 78 | [new RegExp("([ti])a$", "gi"), "$1um"], 79 | [ 80 | new RegExp( 81 | "((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", 82 | "gi" 83 | ), 84 | "$1$2sis" 85 | ], 86 | [new RegExp("(hive)s$", "gi"), "$1"], 87 | [new RegExp("(tive)s$", "gi"), "$1"], 88 | [new RegExp("(curve)s$", "gi"), "$1"], 89 | [new RegExp("([lr])ves$", "gi"), "$1f"], 90 | [new RegExp("([^fo])ves$", "gi"), "$1fe"], 91 | [new RegExp("([^aeiouy]|qu)ies$", "gi"), "$1y"], 92 | [new RegExp("(s)eries$", "gi"), "$1eries"], 93 | [new RegExp("(m)ovies$", "gi"), "$1ovie"], 94 | [new RegExp("(x|ch|ss|sh)es$", "gi"), "$1"], 95 | [new RegExp("([m|l])ice$", "gi"), "$1ouse"], 96 | [new RegExp("(bus)es$", "gi"), "$1"], 97 | [new RegExp("(o)es$", "gi"), "$1"], 98 | [new RegExp("(shoe)s$", "gi"), "$1"], 99 | [new RegExp("(cris|ax|test)es$", "gi"), "$1is"], 100 | [new RegExp("(octop|vir)i$", "gi"), "$1us"], 101 | [new RegExp("(alias|status)es$", "gi"), "$1"], 102 | [new RegExp("^(ox)en", "gi"), "$1"], 103 | [new RegExp("(vert|ind)ices$", "gi"), "$1ex"], 104 | [new RegExp("(matr)ices$", "gi"), "$1ix"], 105 | [new RegExp("(quiz)zes$", "gi"), "$1"], 106 | [new RegExp("s$", "gi"), ""] 107 | ], 108 | nonTitlecasedWords: [ 109 | "and", 110 | "or", 111 | "nor", 112 | "a", 113 | "an", 114 | "the", 115 | "so", 116 | "but", 117 | "to", 118 | "of", 119 | "at", 120 | "by", 121 | "from", 122 | "into", 123 | "on", 124 | "onto", 125 | "off", 126 | "out", 127 | "in", 128 | "over", 129 | "with", 130 | "for" 131 | ], 132 | idSuffix: new RegExp("(_ids|_id)$", "g"), 133 | underbar: new RegExp("_", "g"), 134 | spaceOrUnderbar: new RegExp("[ _]", "g"), 135 | applyRules: function(str, rules, skip, override) { 136 | if (override) { 137 | str = override; 138 | } else { 139 | var ignore = skip.indexOf(str.toLowerCase()) > -1; 140 | if (!ignore) { 141 | for (var x = 0; x < rules.length; x++) { 142 | if (str.match(rules[x][0])) { 143 | str = str.replace(rules[x][0], rules[x][1]); 144 | break; 145 | } 146 | } 147 | } 148 | } 149 | return str; 150 | }, 151 | /** 152 | * Return the plural form of a word. 153 | * 154 | * @param {String} str 155 | * @param {String} [plural] 156 | * @return {String} 157 | * @example 158 | * Inflector.pluralize('person') -> 'people' 159 | * Inflector.pluralize('octopus') -> 'octopi' 160 | * Inflector.pluralize('Hat') -> 'Hats' 161 | * Inflector.pluralize('person', 'guys') -> 'guys' 162 | */ 163 | pluralize: function(str, plural) { 164 | return Inflector.applyRules( 165 | str, 166 | Inflector.pluralRules, 167 | Inflector.uncountableWords, 168 | plural 169 | ); 170 | }, 171 | /** 172 | * Return the singular form of a word. 173 | * 174 | * @param {String} str 175 | * @param {String} [singular] 176 | * @return {String} 177 | * @example 178 | * Inflector.singularize('person') -> 'person' 179 | * Inflector.singularize('octopi') -> 'octopus' 180 | * Inflector.singularize('hats') -> 'hat' 181 | * Inflector.singularize('guys', 'person') -> 'person' 182 | */ 183 | singularize: function(str, singular) { 184 | return Inflector.applyRules( 185 | str, 186 | Inflector.singularRules, 187 | Inflector.uncountableWords, 188 | singular 189 | ); 190 | }, 191 | /** 192 | * Return the camelized form of a string. 193 | * 194 | * @param {String} str 195 | * @param {Boolean} [lowFirstLetter] 196 | * @return {String} 197 | * @example 198 | * Inflector.camelize('message_properties') -> 'MessageProperties' 199 | * Inflector.camelize('message_properties', true) -> 'messageProperties' 200 | */ 201 | camelize: function(str, lowFirstLetter = false) { 202 | str = str.replace(/\s+/g, "_"); 203 | var str_path = str.split("/"); 204 | for (var i = 0; i < str_path.length; i++) { 205 | var str_arr = str_path[i].split("_"); 206 | var initX = lowFirstLetter && i + 1 === str_path.length ? 1 : 0; 207 | for (var x = initX; x < str_arr.length; x++) { 208 | str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1); 209 | } 210 | str_path[i] = str_arr.join(""); 211 | } 212 | str = str_path.join("::"); 213 | if (lowFirstLetter === true) { 214 | var first = str.charAt(0).toLowerCase(); 215 | var last = str.slice(1); 216 | str = first + last; 217 | } 218 | return str; 219 | }, 220 | /* 221 | * Return the underscored form of a string. 222 | * 223 | * @param {String} str 224 | * @return {String} 225 | * @example 226 | * Inflector.underscore('MessageProperties') -> 'message_properties' 227 | * Inflector.underscore('messageProperties') -> 'message_properties' 228 | */ 229 | underscore: function(str) { 230 | let withSpaces = str.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase(); 231 | let cleaned = withSpaces.replace(/[^0-9a-zA-Z]/g, " "); 232 | let formatted = cleaned.trim().replace(/\s+/g, "_"); 233 | return formatted; 234 | }, 235 | /** 236 | * Converts a string to a human-readable format. 237 | * 238 | * @param {String} str - The string to be humanized. 239 | * @param {Boolean} lowFirstLetter - If true, the first letter will remain lowercase. 240 | * @return {String} - The humanized string with words separated by spaces and optionally capitalized. 241 | * @example 242 | * Inflector.humanize('message_properties') -> 'Message properties' 243 | * Inflector.humanize('message_properties', true) -> 'message properties' 244 | */ 245 | humanize: function(str, lowFirstLetter) { 246 | var str = str.toLowerCase(); 247 | str = str.replace(Inflector.idSuffix, ""); 248 | str = str.replace(Inflector.underbar, " "); 249 | if (!lowFirstLetter) { 250 | str = Inflector.capitalize(str); 251 | } 252 | return str; 253 | }, 254 | /** 255 | * Capitalizes the first letter of a string, converting the rest to lowercase. 256 | * 257 | * @param {String} str - The string to be capitalized. 258 | * @return {String} - The capitalized string with the first letter in uppercase and the rest in lowercase. 259 | * @example 260 | * Inflector.capitalize('message_properties') -> 'Message_properties' 261 | * Inflector.capitalize('message properties') -> 'Message properties' 262 | */ 263 | capitalize: function(str) { 264 | var str = str.toLowerCase(); 265 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 266 | return str; 267 | }, 268 | /** 269 | * Replaces spaces or underscores in a string with dashes. 270 | * 271 | * @param {String} str - The string to be transformed. 272 | * @return {String} - The transformed string with dashes instead of spaces or underscores. 273 | * @example 274 | * Inflector.dasherize('message_properties') -> 'message-properties' 275 | * Inflector.dasherize('message properties') -> 'message-properties' 276 | */ 277 | dasherize: function(str) { 278 | str = str.replace(Inflector.spaceOrUnderbar, "-"); 279 | return str; 280 | }, 281 | /** 282 | * Converts a camelCase or snake_case string to a space-separated string with title-case words. 283 | * 284 | * @param {String} str - The input string to be transformed. 285 | * @param {Boolean} allFirstUpper - If true, converts the entire string to camelCase first, 286 | * ensuring all words are capitalized. 287 | * @return {String} - The transformed string with words separated by spaces, 288 | * and optionally capitalized according to the given parameter. 289 | * @example 290 | * Inflector.camel2words('message_properties') -> 'Message Properties' 291 | * Inflector.camel2words('message properties') -> 'Message Properties' 292 | * Inflector.camel2words('Message_propertyId', true) -> 'Message Properties Id' 293 | */ 294 | camel2words: function(str, allFirstUpper) { 295 | if (allFirstUpper === true) { 296 | str = Inflector.camelize(str); 297 | str = Inflector.underscore(str); 298 | } else { 299 | str = str.toLowerCase(); 300 | } 301 | str = str.replace(Inflector.underbar, " "); 302 | var str_arr = str.split(" "); 303 | for (var x = 0; x < str_arr.length; x++) { 304 | var d = str_arr[x].split("-"); 305 | for (var i = 0; i < d.length; i++) { 306 | if (Inflector.nonTitlecasedWords.indexOf(d[i].toLowerCase()) < 0) { 307 | d[i] = Inflector.capitalize(d[i]); 308 | } 309 | } 310 | str_arr[x] = d.join("-"); 311 | } 312 | str = str_arr.join(" "); 313 | str = str.substring(0, 1).toUpperCase() + str.substring(1); 314 | return str; 315 | }, 316 | /** 317 | * Removes the module part of a qualified name. 318 | * 319 | * @param {String} str - The qualified name to be transformed. 320 | * @return {String} - The transformed string without the module part. 321 | * @example 322 | * Inflector.demodulize('Message::Bus::Properties') -> 'Properties' 323 | */ 324 | demodulize: function(str) { 325 | var str_arr = str.split("::"); 326 | str = str_arr[str_arr.length - 1]; 327 | return str; 328 | }, 329 | /** 330 | * Converts a string to its table name form by underscoring and pluralizing it. 331 | * 332 | * @param {String} str - The class name to be converted. 333 | * @return {String} - The table name form of the class name. 334 | * @example 335 | * Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' 336 | */ 337 | tableize: function(str) { 338 | str = Inflector.pluralize(Inflector.underscore(str)); 339 | return str; 340 | }, 341 | /** 342 | * Converts a string to its camelCase form and then singularizes it. 343 | * 344 | * @param {String} str - The string to be converted. 345 | * @return {String} - The camelCase singularized string. 346 | * @example 347 | * Inflector.classify('message_bus_properties') -> 'MessageBusProperty' 348 | */ 349 | classify: function(str) { 350 | str = Inflector.singularize(Inflector.camelize(str)); 351 | return str; 352 | }, 353 | /** 354 | * Converts a class name to its foreign key form. 355 | * 356 | * @param {String} str - The class name to be converted. 357 | * @param {Boolean} [dropIdUbar] - Whether the _id suffix should be dropped. 358 | * @return {String} - The foreign key form of the class name. 359 | * @example 360 | * Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' 361 | * Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' 362 | */ 363 | foreignKey: function(str, dropIdUbar) { 364 | str = Inflector.underscore(Inflector.demodulize(str)) + (dropIdUbar ? "" : "_") + "id"; 365 | return str; 366 | }, 367 | /** 368 | * Ordinalizes a given string. 369 | * 370 | * @param {String} str - The string to be ordinalized. 371 | * @return {String} - The ordinalized string. 372 | * @example 373 | * Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' 374 | */ 375 | ordinalize: function(str) { 376 | var str_arr = str.split(" "); 377 | for (var x = 0; x < str_arr.length; x++) { 378 | var i = parseInt(str_arr[x], 10); 379 | if (!Number.isNaN(i)) { 380 | var ltd = str_arr[x].slice(-2); 381 | var ld = str_arr[x].slice(-1); 382 | var suf = "th"; 383 | if (ltd !== "11" && ltd !== "12" && ltd !== "13") { 384 | if (ld === "1") { 385 | suf = "st"; 386 | } else if (ld === "2") { 387 | suf = "nd"; 388 | } else if (ld === "3") { 389 | suf = "rd"; 390 | } 391 | } 392 | str_arr[x] = str_arr[x] + suf; 393 | } 394 | } 395 | return str_arr.join(" "); 396 | } 397 | }; 398 | var index_default = Inflector; 399 | var pluralize = Inflector.pluralize; 400 | var singularize = Inflector.singularize; 401 | var camelize = Inflector.camelize; 402 | var underscore = Inflector.underscore; 403 | var humanize = Inflector.humanize; 404 | var capitalize = Inflector.capitalize; 405 | var dasherize = Inflector.dasherize; 406 | var camel2words = Inflector.camel2words; 407 | var demodulize = Inflector.demodulize; 408 | var tableize = Inflector.tableize; 409 | var classify = Inflector.classify; 410 | var foreignKey = Inflector.foreignKey; 411 | var ordinalize = Inflector.ordinalize; 412 | return __toCommonJS(index_exports); 413 | })(); 414 | --------------------------------------------------------------------------------