├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build ├── index.js └── index.min.js ├── bundler ├── api.md ├── badges.md ├── bundle.js ├── change_log.md ├── contribute.md ├── everything.md ├── header.md ├── highlight.md ├── installation.md ├── license.md ├── security_vulnerabilities.md ├── setup.md ├── utilization.md └── versioning.md ├── dist ├── index.js └── str │ └── index.js ├── docs ├── .vuepress │ └── config.js └── api.md ├── package.json ├── src └── index.js └── test ├── str ├── after.test.js ├── afterLast.test.js ├── before.test.js ├── beforeLast.test.js ├── between.test.js ├── camel.test.js ├── contains.test.js ├── containsAll.test.js ├── endsWith.test.js ├── finish.test.js ├── is.test.js ├── kebab.test.js ├── length.test.js ├── limit.test.js ├── lower.test.js ├── parseCallback.test.js ├── plural.test.js ├── pluralStudly.test.js ├── random.test.js ├── replaceArray.test.js ├── replaceFirst.test.js ├── replaceLast.test.js ├── singular.test.js ├── slug.test.js ├── snake.test.js ├── start.test.js ├── startsWith.test.js ├── studly.test.js ├── substr.test.js ├── substrCount.test.js ├── title.test.js ├── ucfirst.test.js ├── upper.test.js └── words.test.js └── tests.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | .npm-debug.log 4 | npm-debug.log 5 | test/benchmark.js 6 | test/implementations.js 7 | coverage 8 | .nyc_output 9 | .DS_Store 10 | package-lock.json 11 | docs/.vuepress/dist/* 12 | yarn.lock 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | test 3 | coverage 4 | .nyc_output 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '12' 4 | - '10' 5 | - '8' 6 | script: 7 | - npm run coverage 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Change Log 4 | 5 | --- 6 | - [Release 1.0.4](#release-104) 7 | - [Release 1.0.0](#release-100) 8 | 9 | --- 10 | 11 | ### Release 1.0.4 12 | 13 | --- 14 | 15 | - Fixed Yarn/Npm Conflict Bloating Repository 16 | 17 | --- 18 | 19 | ### Release 1.0.0 20 | 21 | --- 22 | 23 | - Initial Release 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Zak Horton 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Version](https://img.shields.io/npm/v/laravel-js-str.svg?color=success&logo=npm) 3 | [![Travis](https://img.shields.io/travis/zhorton34/laravel-js-str/master.svg?logo=travis)](https://travis-ci.org/zhorton34/laravel-js-str/builds) 4 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?logo=git&color=success)](http://makeapullrequest.com) 5 | [![Code Pen](https://img.shields.io/badge/codepen/laraveljs-example/master.svg?logo=codepen)](https://codepen.io/zhorton34/pen/LYpoxEY) 6 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?color=success&logo=github)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity) 7 | [![dependencies](https://img.shields.io/badge/dependencies-none-brightgreen.svg?color=success&logo=javascript)](https://github.com/zhorton34/laravel-js-str/blob/master/package.json) 8 | [![npm license](https://img.shields.io/npm/l/laravel-js-str.svg?color=success)](http://badge.fury.io/js/laravel-js-str) 9 | 10 | --- 11 | 12 | # Project Goals 13 | 14 | --- 15 | 16 | - [x] **Fluent** 17 | - [x] **Stringable** 18 | - [x] **Simplified** 19 | 20 | --- 21 | 22 | # Tinkerable Demo 23 | 24 | --- 25 | ![Code Pen Example](https://lh3.googleusercontent.com/8h1qz33h3h1-5yU75YInO5CGO8-N6xGP5AxN2c_fCpdUa4sMBixadJkKfdahtJY31hH86yEC1Y6gDJLcvc0QqsvDmEBoG4QFuZmdeaEvOoD0ctGE5vI7bbIjEBi0k7CNEyxrrYl25hCpsxaSTZPrXBlOHEb5itBxeaz_SYNNOw0pORV_Ca442tPGaVlM2JsnhQKV4o5Pt0gNW-jUqY_wWbKBhhPi7GD6S-wcZ9MW7QpEI0DtUAeexQKcmwHUrn_lKkF79YFr5KKzHUcZpFdtY3NHTRyrtwZLlU3TY8B4axaLks-PHZ-tXWADx45AvY0hYGEwx-nD0lEbc_u7Mzi2HOJmhLI9BL_2_TINU1-eXCPQxu94DTm8K2w7Ic8lxxf-en9l2TOrKJlUfnmjX_IjCZFQyCbYz4RQlE7RU_3MTZGTNx84cHkDgnEjGPqYd3xeBPWfNcqsJWymXRhvTwIi-u5KagjnPvv-HPFXEqpTlkBNVz0phTO2EqjKBVkTYNscV9Dt0SXNGvWqTMPQ2c0iDuvha75QIFUrt0GGj8NUUZZUCVGCq9KQIQmSXx_wus3ZPQM8GG1dDJHaorGNAWb-MUQwaXJmZ0HxEip45D37QPZyXyuPNbgHs4ttzCWqa3IeEWPU5yUQQmAGlug0oaRd2T8tRQy1ljv_S_Vg3q8-DYsqf8SLBGZtKJ8xujNhS1PR22lydg=w1919-h952-ft "Package Gif Example") 26 | 27 | 28 | --- 29 | 30 | ## Laravel JS Str 31 | 32 | --- 33 | 34 | > _"Laravel's Illuminate\Str & Illuminate\Stringify Including Str.of() In Javascript"_ 35 | 36 | --- 37 | 38 | ## Installation 39 | 40 | --- 41 | 42 | 43 | ### NPM 44 | 45 | ```bash 46 | npm install --save-dev laravel-js-str 47 | ``` 48 | 49 | ### Yarn 50 | 51 | ```bash 52 | yarn add laravel-js-str --save 53 | ``` 54 | 55 | ### CDN 56 | 57 | ```html 58 | 59 | ``` 60 | 61 | 62 | --- 63 | 64 | ## Str 65 | 66 | --- 67 | > **Documentation For Each String Method Points To Laravel. Javascript examples are below, Laravel docs will specify what each method specifically does. Replace Str::method() with Str.() when using this package** 68 | 69 | - [Str.after](https://laravel.com/docs/7.x/helpers#method-str-after) 70 | - [Str.afterLast](https://laravel.com/docs/7.x/helpers#method-str-after-last) 71 | - [Str.ascii](https://laravel.com/docs/7.x/helpers#method-str-ascii) 72 | - [Str.before](https://laravel.com/docs/7.x/helpers#method-str-before) 73 | - [Str.beforeLast](https://laravel.com/docs/7.x/helpers#method-str-before-last) 74 | - [Str.between](https://laravel.com/docs/7.x/helpers#method-str-between) 75 | - [Str.contains](https://laravel.com/docs/7.x/helpers#method-str-contains) 76 | - [Str.containsAll](https://laravel.com/docs/7.x/helpers#method-str-contains-all) 77 | - [Str.finish](https://laravel.com/docs/7.x/helpers#method-str-finish) 78 | - [Str.is](https://laravel.com/docs/7.x/helpers#method-str-is) 79 | - [Str.isAscii](https://laravel.com/docs/7.x/helpers#method-str-is-ascii) 80 | - [Str.isUuid](https://laravel.com/docs/7.x/helpers#method-str-is-uuid) 81 | - [Str.length](https://laravel.com/docs/7.x/helpers#method-str-length) 82 | - [Str.limit](https://laravel.com/docs/7.x/helpers#method-str-limit) 83 | - [Str.lower](https://laravel.com/docs/7.x/helpers#method-str-lower) 84 | - [Str.orderedUuid](https://laravel.com/docs/7.x/helpers#method-str-ordered-uuid) 85 | - [Str.plural](https://laravel.com/docs/7.x/helpers#method-str-plural) 86 | - [Str.random](https://laravel.com/docs/7.x/helpers#method-str-random) 87 | - [Str.replaceArray](https://laravel.com/docs/7.x/helpers#method-str-replace-array) 88 | - [Str.replaceFirst](https://laravel.com/docs/7.x/helpers#method-str-replace-first) 89 | - [Str.replaceLast](https://laravel.com/docs/7.x/helpers#method-str-replace-last) 90 | - [Str.singular](https://laravel.com/docs/7.x/helpers#method-str-singular) 91 | - [Str.slug](https://laravel.com/docs/7.x/helpers#method-str-slug) 92 | - [Str.start](https://laravel.com/docs/7.x/helpers#method-str-start) 93 | - [Str.substr](https://laravel.com/docs/7.x/helpers#method-str-substr) 94 | - [Str.ucfirst](https://laravel.com/docs/7.x/helpers#method-str-ucfirst) 95 | - [Str.upper](https://laravel.com/docs/7.x/helpers#method-str-upper) 96 | - [Str.uuid](https://laravel.com/docs/7.x/helpers#method-str-uuid) 97 | - [Str.words](https://laravel.com/docs/7.x/helpers#method-str-words) 98 | 99 | 100 | 101 | ```js 102 | const { Str } = require('laravel-js-str'); 103 | 104 | let slice = Str.after('This is my name', 'This is'); 105 | // ' my name' 106 | ``` 107 | 108 | 109 | 110 | 111 | ```js 112 | const { Str } = require('laravel-js-str'); 113 | 114 | let slice = Str.afterLast('App\Http\Controllers\Controller', '\\'); 115 | // 'Controller' 116 | ``` 117 | 118 | 119 | 120 | 121 | ```js 122 | const { Str } = require('laravel-js-str'); 123 | 124 | let slice = Str.ascii('û'); 125 | // 'u' 126 | ``` 127 | 128 | 129 | 130 | 131 | ```js 132 | const { Str } = require('laravel-js-str'); 133 | 134 | let slice = Str.before('This is my name', 'my name'); 135 | // 'This is ' 136 | ``` 137 | 138 | 139 | 140 | 141 | ```js 142 | const { Str } = require('laravel-js-str'); 143 | 144 | let slice = Str.beforeLast('This is my name', 'is'); 145 | // 'This ' 146 | ``` 147 | 148 | 149 | 150 | 151 | ```js 152 | const { Str } = require('laravel-js-str'); 153 | 154 | let slice = Str.between('This is my name', 'This', 'name'); 155 | // ' is my ' 156 | ``` 157 | 158 | 159 | 160 | 161 | ```js 162 | const { Str } = require('laravel-js-str'); 163 | 164 | let converted = Str.camel('foo_bar'); 165 | // fooBar 166 | ``` 167 | 168 | 169 | 170 | 171 | ```js 172 | const { Str } = require('laravel-js-str'); 173 | 174 | let contains = Str.contains('This is my name', 'my'); 175 | // true 176 | ``` 177 | 178 | 179 | 180 | 181 | ```js 182 | const { Str } = require('laravel-js-str'); 183 | 184 | let contains = Str.contains('This is my name', ['my', 'foo']); 185 | // true 186 | ``` 187 | 188 | 189 | 190 | 191 | ```js 192 | const { Str } = require('laravel-js-str'); 193 | 194 | let containsAll = Str.containsAll('This is my name', ['my', 'name']); 195 | // true 196 | ``` 197 | 198 | 199 | ```js 200 | const { Str } = require('laravel-js-str'); 201 | 202 | let result = Str.endsWith('This is my name', 'name'); 203 | // true 204 | ``` 205 | 206 | 207 | ```js 208 | const { Str } = require('laravel-js-str'); 209 | 210 | let result = Str.endsWith('This is my name', ['name', 'foo']); 211 | // true 212 | 213 | result = Str.endsWith('This is my name', ['this', 'foo']); 214 | // false 215 | ``` 216 | 217 | 218 | 219 | 220 | ```js 221 | const { Str } = require('laravel-js-str'); 222 | 223 | let adjusted = Str.finish('this/string', '/'); 224 | // this/string/ 225 | 226 | adjusted = Str.finish('this/string/', '/'); 227 | // this/string/ 228 | ``` 229 | 230 | 231 | 232 | 233 | ```js 234 | const { Str } = require('laravel-js-str'); 235 | 236 | let matches = Str.is('foo*', 'foobar'); 237 | // true 238 | 239 | matches = Str.is('baz*', 'foobar'); 240 | 241 | // false 242 | ``` 243 | 244 | 245 | 246 | **isAscii is experimental, not confident it works in all scenarios** 247 | ```js 248 | const { Str } = require('laravel-js-str'); 249 | 250 | let isAscii = Str.isAscii('Taylor'); 251 | // true 252 | 253 | isAscii = Str.isAscii('ü'); 254 | 255 | // false 256 | ``` 257 | 258 | 259 | 260 | 261 | ```js 262 | const { Str } = require('laravel-js-str'); 263 | 264 | let isUuid = Str.isUuid('a0a2a2d2-0b87-4a18-83f2-2529882be2de'); 265 | // true 266 | 267 | isUuid = Str.isUuid('laravel'); 268 | 269 | // false 270 | ``` 271 | 272 | 273 | 274 | 275 | ```js 276 | const { Str } = require('laravel-js-str'); 277 | 278 | let converted = Str.kebab('fooBar'); 279 | // foo-bar 280 | ``` 281 | 282 | 283 | 284 | 285 | ```js 286 | const { Str } = require('laravel-js-str'); 287 | 288 | let length = Str.length('Laravel'); 289 | // 7 290 | ``` 291 | 292 | 293 | 294 | 295 | ```js 296 | const { Str } = require('laravel-js-str'); 297 | 298 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0); 299 | // The quick brown fox... 300 | ``` 301 | 302 | 303 | 304 | 305 | ```js 306 | const { Str } = require('laravel-js-str'); 307 | 308 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0, '(...)'); 309 | // The quick brown fox (...) 310 | ``` 311 | 312 | 313 | 314 | 315 | ```js 316 | const { Str } = require('laravel-js-str'); 317 | 318 | let converted = Str.lower('LARAVEL'); 319 | // laravel 320 | ``` 321 | 322 | 323 | 324 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 325 | ```js 326 | const { Str } = require('laravel-js-str'); 327 | 328 | let plural = Str.plural('car'); 329 | // cars 330 | 331 | plural = Str.plural('child'); 332 | // children 333 | ``` 334 | 335 | 336 | 337 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 338 | ```js 339 | const { Str } = require('laravel-js-str'); 340 | 341 | let plural = Str.plural('child'); 342 | // children 343 | 344 | plural = Str.plural('child'); 345 | // child 346 | ``` 347 | 348 | 349 | 350 | 351 | ```js 352 | const { Str } = require('laravel-js-str'); 353 | 354 | let random = Str.random(40); 355 | ``` 356 | 357 | 358 | 359 | 360 | ```js 361 | const { Str } = require('laravel-js-str'); 362 | 363 | let string = 'The event will take place between ? and ?'; 364 | let replaced = Str.replaceArray(['?', '8:30', '9:00'], string); 365 | // The event will take place between 8:30 and 9:00 366 | ``` 367 | 368 | 369 | 370 | 371 | ```js 372 | const { Str } = require('laravel-js-str'); 373 | 374 | let replaced = Str.replaceFirst('the', 'a', 'the quick brown fox jumps over the lazy dog'); 375 | // a quick brown fox jumps over the lazy dog 376 | ``` 377 | 378 | 379 | 380 | 381 | ```js 382 | const { Str } = require('laravel-js-str'); 383 | 384 | let replaced = Str.replaceLast('the', 'a', 'the quick brown fox jumps over the lazy dog'); 385 | // the quick brown fox jumps over a lazy dog 386 | ``` 387 | 388 | 389 | 390 | 391 | ```js 392 | const { Str } = require('laravel-js-str'); 393 | 394 | let singular = Str.singular('cars'); 395 | // car 396 | 397 | singular = Str.singular('children'); 398 | // child 399 | ``` 400 | 401 | 402 | 403 | 404 | ```js 405 | const { Str } = require('laravel-js-str'); 406 | 407 | let slug = Str.slug('Laravel 5 Framework', '-'); 408 | // laravel-5-framework 409 | ``` 410 | 411 | ```js 412 | const { Str } = require('laravel-js-str'); 413 | 414 | let converted = Str.snake('fooBar'); 415 | // foo_bar 416 | ``` 417 | 418 | 419 | 420 | 421 | ```js 422 | const { Str } = require('laravel-js-str'); 423 | 424 | let adjusted = Str.start('this/string', '/'); 425 | // /this/string 426 | 427 | adjusted = Str.start('/this/string', '/'); 428 | // /this/string 429 | ``` 430 | 431 | 432 | 433 | 434 | ```js 435 | const { Str } = require('laravel-js-str'); 436 | 437 | let result = Str.startsWith('This is my name', This'); 438 | // true 439 | ``` 440 | 441 | 442 | 443 | 444 | ```js 445 | const { Str } = require('laravel-js-str'); 446 | 447 | let converted = Str.studly('foo_bar'); 448 | // FooBar 449 | ``` 450 | 451 | 452 | 453 | 454 | ```js 455 | const { Str } = require('laravel-js-str'); 456 | 457 | let converted = Str.substr('The Laravel Framework', , ); 458 | // Laravel 459 | ``` 460 | 461 | 462 | 463 | 464 | ```js 465 | const { Str } = require('laravel-js-str'); 466 | 467 | let converted = Str.title('a nice title uses the correct case'); 468 | // A Nice Title Uses The Correct Case 469 | ``` 470 | 471 | 472 | 473 | 474 | ```js 475 | const { Str } = require('laravel-js-str'); 476 | 477 | let string = Str.ucfirst('foo bar'); 478 | // Foo bar 479 | ``` 480 | 481 | 482 | 483 | 484 | ```js 485 | const { Str } = require('laravel-js-str'); 486 | 487 | let string = Str.upper('laravel'); 488 | // LARAVEL 489 | ``` 490 | 491 | 492 | 493 | 494 | ```js 495 | const { Str } = require('laravel-js-str'); 496 | 497 | return Str.uuid(); 498 | ``` 499 | 500 | 501 | 502 | 503 | ```js 504 | const { Str } = require('laravel-js-str'); 505 | 506 | Str.words('Perfectly balanced, as all things should be.', 3, '>>>'); 507 | 508 | // Perfectly balanced, as >>> 509 | ``` 510 | 511 | 512 | 513 | 514 | ```js 515 | const { Str } = require('laravel-js-str'); 516 | 517 | let slice = Str.of('This is my name').after('This is'); 518 | // ' my name' 519 | ``` 520 | 521 | 522 | 523 | 524 | ```js 525 | const { Str } = require('laravel-js-str'); 526 | 527 | let slice = Str.of('App\Http\Controllers\Controller').afterLast('\\'); 528 | // 'Controller' 529 | ``` 530 | 531 | 532 | 533 | 534 | ```js 535 | const { Str } = require('laravel-js-str'); 536 | 537 | let string = Str.of('Taylor').append(' Otwell'); 538 | // 'Taylor Otwell' 539 | ``` 540 | 541 | 542 | 543 | **Experimental Method, not sure this works in all cases** 544 | ```js 545 | const { Str } = require('laravel-js-str'); 546 | 547 | let string = Str.of('ü').ascii(); 548 | // 'u' 549 | ``` 550 | 551 | 552 | 553 | 554 | ```js 555 | const { Str } = require('laravel-js-str'); 556 | 557 | let string = Str.of('/foo/bar/baz').basename(); 558 | // 'baz' 559 | ``` 560 | 561 | 562 | 563 | 564 | ```js 565 | const { Str } = require('laravel-js-str'); 566 | 567 | let string = Str.of('/foo/bar/baz.jpg').basename('.jpg'); 568 | // 'baz' 569 | ``` 570 | 571 | 572 | 573 | 574 | ```js 575 | const { Str } = require('laravel-js-str'); 576 | 577 | let slice = Str.of('This is my name').before('my name'); 578 | // 'This is ' 579 | ``` 580 | 581 | 582 | 583 | 584 | ```js 585 | const { Str } = require('laravel-js-str'); 586 | 587 | let slice = Str.of('This is my name').beforeLast('is'); 588 | // 'This ' 589 | ``` 590 | 591 | 592 | 593 | 594 | ```js 595 | const { Str } = require('laravel-js-str'); 596 | 597 | let converted = Str.of('foo_bar').camel(); 598 | // fooBar 599 | ``` 600 | 601 | 602 | 603 | 604 | ```js 605 | const { Str } = require('laravel-js-str'); 606 | 607 | let contains = Str.of('This is my name').contains('my'); 608 | // true 609 | ``` 610 | 611 | 612 | 613 | 614 | ```js 615 | const { Str } = require('laravel-js-str'); 616 | 617 | let contains = Str.of('This is my name').contains(['my', foo']); 618 | // true 619 | ``` 620 | 621 | 622 | 623 | 624 | ```js 625 | const { Str } = require('laravel-js-str'); 626 | 627 | let containsAll = Str.of('This is my name').containsAll(['my', 'name']); 628 | // true 629 | ``` 630 | 631 | 632 | 633 | 634 | ```js 635 | const { Str } = require('laravel-js-str'); 636 | 637 | let string = Str.of('/foo/bar/baz').dirname(); 638 | // '/foo/bar' 639 | ``` 640 | 641 | 642 | 643 | 644 | ```js 645 | const { Str } = require('laravel-js-str'); 646 | 647 | let string = Str.of('/foo/bar/baz').dirname(2); 648 | // '/foo' 649 | ``` 650 | 651 | 652 | 653 | 654 | ```js 655 | const { Str } = require('laravel-js-str'); 656 | 657 | let result = Str.of('This is my name').endsWith('name'); 658 | // true 659 | ``` 660 | 661 | 662 | 663 | 664 | ```js 665 | const { Str } = require('laravel-js-str'); 666 | 667 | let result = Str.of('This is my name').endsWith(['name', 'foo']); 668 | // true 669 | 670 | result = Str.of('This is my name').endsWith(['this', 'foo']); 671 | // false 672 | ``` 673 | 674 | 675 | 676 | ```js 677 | const { Str } = require('laravel-js-str'); 678 | 679 | let result = Str.of('Laravel').exactly('Laravel'); 680 | // true 681 | ``` 682 | 683 | 684 | 685 | [Collect.js](https://npmjs.com/package/collect.js) 686 | ```js 687 | const { Str } = require('laravel-js-str'); 688 | 689 | let collection = Str.of('foo bar baz').explode(' '); 690 | // collect(['foo', 'bar', 'baz']) 691 | ``` 692 | 693 | 694 | 695 | 696 | ```js 697 | const { Str } = require('laravel-js-str'); 698 | 699 | let adjusted = Str.of('this/string').finish('/'); 700 | // this/string/ 701 | 702 | adjusted = Str.of('this/string/').finish('/'); 703 | 704 | // this/string/ 705 | ``` 706 | 707 | 708 | 709 | 710 | ```js 711 | const { Str } = require('laravel-js-str'); 712 | 713 | let matches = Str.of('foobar').is('foo*'); 714 | // true 715 | 716 | matches = Str.of('foobar').is('baz*'); 717 | 718 | // false 719 | ``` 720 | 721 | 722 | 723 | **isAscii is Experimental, not positive its correct in all cases** 724 | ```js 725 | const { Str } = require('laravel-js-str'); 726 | 727 | let result = Str.of('Taylor').isAscii(); 728 | // true 729 | 730 | result = Str.of('ü').isAcii(); 731 | 732 | // false 733 | ``` 734 | 735 | 736 | 737 | 738 | ```js 739 | const { Str } = require('laravel-js-str'); 740 | 741 | let result = Str.of(' ').trim().isEmpty(); 742 | // true 743 | 744 | result = Str.of('Laravel').trim().isEmpty(); 745 | 746 | // false 747 | ``` 748 | 749 | 750 | 751 | 752 | ```js 753 | const { Str } = require('laravel-js-str'); 754 | 755 | let result = Str.of(' ').trim().isNotEmpty(); 756 | // false 757 | 758 | result = Str.of('Laravel').trim().isNotEmpty(); 759 | 760 | // true 761 | ``` 762 | 763 | 764 | 765 | 766 | ```js 767 | const { Str } = require('laravel-js-str'); 768 | 769 | let converted = Str.of('fooBar').kebab(); 770 | // foo-bar 771 | ``` 772 | 773 | 774 | 775 | 776 | ```js 777 | const { Str } = require('laravel-js-str'); 778 | 779 | let length = Str.of('Laravel').length(); 780 | // 7 781 | ``` 782 | 783 | 784 | 785 | 786 | ```js 787 | const { Str } = require('laravel-js-str'); 788 | 789 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20); 790 | // The quick brown fox... 791 | ``` 792 | 793 | 794 | 795 | 796 | ```js 797 | const { Str } = require('laravel-js-str'); 798 | 799 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20, ' (...)'); 800 | // The quick brown fox (...) 801 | ``` 802 | 803 | 804 | 805 | 806 | ```js 807 | const { Str } = require('laravel-js-str'); 808 | 809 | let result = Str.of('LARAVEL').lower(); 810 | // 'laravel' 811 | ``` 812 | 813 | 814 | 815 | 816 | ```js 817 | const { Str } = require('laravel-js-str'); 818 | 819 | let string = Str.of(' Laravel ').ltrim(); 820 | // 'Laravel ' 821 | 822 | string = Str.of('/Laravel/').ltrim('/'); 823 | 824 | // 'Laravel/' 825 | ``` 826 | 827 | 828 | 829 | 830 | ```js 831 | const { Str } = require('laravel-js-str'); 832 | 833 | let result = Str.of('foo bar').match('/bar/'); 834 | // 'bar' 835 | 836 | result = Str.of('foo bar').match('/foo (.*)/'); 837 | 838 | // 'bar' 839 | ``` 840 | 841 | 842 | 843 | __Match All Coming Soon__ 844 | ``` 845 | const { Str } = require('laravel-js-str'); 846 | 847 | let result = Str.of('bar foo bar').matchAll('/bar/'); 848 | // collect(['bar', 'bar']) 849 | ``` 850 | ``` 851 | const { Str } = require('laravel-js-str'); 852 | 853 | let result = Str.of('bar fun bar fly').matchAll('/f(\w*)/'); 854 | // collect(['un', 'ly']); 855 | 856 | 857 | ``` 858 | 859 | 860 | 861 | 862 | ```js 863 | const { Str } = require('laravel-js-str'); 864 | 865 | let plural = Str.of('car').plural(); 866 | // cars 867 | 868 | plural = Str.of('child').plural(); 869 | 870 | // children 871 | ``` 872 | 873 | 874 | 875 | 876 | ```js 877 | const { Str } = require('laravel-js-str'); 878 | 879 | let plural = Str.of('child').plural(2); 880 | // children 881 | 882 | plural = Str.of('child').plural(1); 883 | 884 | // child 885 | ``` 886 | 887 | 888 | 889 | 890 | ```js 891 | const { Str } = require('laravel-js-str'); 892 | 893 | let string = Str.of('Framework').prepend('Laravel '); 894 | // Laravel Framework 895 | ``` 896 | 897 | 898 | 899 | 900 | ```js 901 | const { Str } = require('laravel-js-str'); 902 | 903 | let replaced = Str.of('Laravel 6.x').replace('6.x', '7.x'); 904 | // Laravel 7.x 905 | ``` 906 | 907 | 908 | 909 | 910 | ```js 911 | const { Str } = require('laravel-js-str'); 912 | 913 | let string = 'The event will take place between ? and ?'; 914 | let replaced = Str.of(string).replaceArray('?', ['8:30', '9:00']); 915 | // The event will take place between 8:30 and 9:00 916 | ``` 917 | 918 | 919 | 920 | 921 | ```js 922 | const { Str } = require('laravel-js-str'); 923 | 924 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceFirst('the', 'a'); 925 | // a quick brown fox jumps over the lazy dog 926 | ``` 927 | 928 | 929 | 930 | 931 | ```js 932 | const { Str } = require('laravel-js-str'); 933 | 934 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceLast('the', 'a'); 935 | // the quick brown fox jumps over a lazy dog 936 | ``` 937 | 938 | 939 | 940 | 941 | ```js 942 | const { Str } = require('laravel-js-str'); 943 | 944 | let replaced = Str.of('(+1) 501-555-1000').replace('/[^A-Za-z0-9]++/', ''); 945 | 946 | //'15015551000' 947 | ``` 948 | 949 | 950 | 951 | ```js 952 | 953 | ``` 954 | 955 | 956 | ```js 957 | const { Str } = require('laravel-js-str'); 958 | 959 | let string = Str.of(' Laravel ').rtrim(); 960 | // ' Laravel' 961 | 962 | string = Str.of('/Laravel/').rtrim('/'); 963 | 964 | // '/Laravel' 965 | ``` 966 | 967 | 968 | 969 | 970 | ```js 971 | const { Str } = require('laravel-js-str'); 972 | 973 | let singular = Str.of('cars').singular(); 974 | // car 975 | 976 | singular = Str.of('children').singular(); 977 | 978 | // child 979 | ``` 980 | 981 | 982 | 983 | 984 | ```js 985 | const { Str } = require('laravel-js-str'); 986 | 987 | let slug = Str.of('Laravel Framework').slug('-'); 988 | // laravel-framework 989 | ``` 990 | 991 | 992 | 993 | 994 | ```js 995 | const { Str } = require('laravel-js-str'); 996 | 997 | let converted = Str.of('fooBar').snake(); 998 | // foo_bar 999 | ``` 1000 | 1001 | 1002 | 1003 | 1004 | ```js 1005 | const { Str } = require('laravel-js-str'); 1006 | 1007 | let segments = Str.of('one, two, three').split('/[\s, +/'); 1008 | // collect(["one", "two", "three"]) 1009 | ``` 1010 | 1011 | 1012 | 1013 | 1014 | ```js 1015 | const { Str } = require('laravel-js-str'); 1016 | 1017 | let adjusted = Str.of('this/string').start('/'); 1018 | // /this/string 1019 | 1020 | adjusted = Str.of('/this/string').start('/'); 1021 | 1022 | // /this/string 1023 | ``` 1024 | 1025 | 1026 | 1027 | 1028 | ```js 1029 | const { Str } = require('laravel-js-str'); 1030 | 1031 | let result = Str.of('This is my name').startsWith('This'); 1032 | // true 1033 | ``` 1034 | 1035 | 1036 | 1037 | 1038 | ```js 1039 | const { Str } = require('laravel-js-str'); 1040 | 1041 | let converted = Str.of('foo_bar').studly(); 1042 | // FooBar 1043 | ``` 1044 | 1045 | 1046 | 1047 | 1048 | ```js 1049 | const { Str } = require('laravel-js-str'); 1050 | 1051 | let string = Str.of('Laravel Framework').substr(8); 1052 | // Framework 1053 | 1054 | string = Str.of('Laravel Framework').substr(8, ); 1055 | 1056 | // Frame 1057 | ``` 1058 | 1059 | 1060 | 1061 | 1062 | ```js 1063 | const { Str } = require('laravel-js-str'); 1064 | 1065 | let converted = Str.of('a nice title uses the correct case').title(); 1066 | // A Nice Title Uses The Correct Case 1067 | ``` 1068 | 1069 | 1070 | 1071 | 1072 | ```js 1073 | const { Str } = require('laravel-js-str'); 1074 | 1075 | let string = Str.of(' Laravel ').trim(); 1076 | // 'Laravel' 1077 | 1078 | string = Str.of('/Laravel/').trim('/'); 1079 | 1080 | // 'Laravel' 1081 | ``` 1082 | 1083 | 1084 | 1085 | 1086 | ```js 1087 | const { Str } = require('laravel-js-str'); 1088 | 1089 | let string = Str.of('foo bar').ucfirst(); 1090 | // Foo bar 1091 | ``` 1092 | 1093 | 1094 | 1095 | 1096 | ```js 1097 | const { Str } = require('laravel-js-str'); 1098 | 1099 | let adjusted = Str.of('laravel').upper(); 1100 | // LARAVEL 1101 | ``` 1102 | 1103 | 1104 | 1105 | 1106 | ```js 1107 | const { Str } = require('laravel-js-str'); 1108 | 1109 | let string = Str.of(' ').whenEmpty(function(string) { 1110 | return string.trim().prepend('Laravel'); 1111 | }); 1112 | 1113 | // 'Laravel' 1114 | ``` 1115 | 1116 | 1117 | 1118 | 1119 | ```js 1120 | const { Str } = require('laravel-js-str'); 1121 | 1122 | let string = Str.of('Perfectly balanced, as all things should be.').words(3, '>>>'); 1123 | // Perfectly balanced, as >>> 1124 | ``` 1125 | 1126 | 1127 | --- 1128 | 1129 | ## Playground Examples 1130 | 1131 | --- 1132 | Curious, but not 100% on whether this is what you're looking for? 1133 | 1134 | - [Laravel Illuminate/Str & Illuminate/Str::of in js (live example coming soon)](https://codepen.io/zhorton34/pen/jObRLdM) 1135 | 1136 | > **The most powerful method is Str.of('example')**, allowing us to fluently chain Str methods together 1137 | 1138 | **Example** 1139 | ```js 1140 | let { Str } = require('laravel-js-str'); 1141 | 1142 | let home = 'https://planets.com'; 1143 | let title = 'hello mars, a cool world for you to visit, maybe?'; 1144 | 1145 | let article = Str.of(title).replaceFirst(',', '') 1146 | .after('hello') 1147 | .before('for you') 1148 | .trim() 1149 | .start('/') 1150 | .finish('/') 1151 | .kebab(); 1152 | 1153 | let resource = home + article 1154 | 1155 | // resource value: 1156 | // 'https://planets.com/mars-a-cool-world/' 1157 | // 1158 | // article value: 1159 | // Stringable: { value: 'https://planets.com/mars-a-cool-world-to-visit', replace, before, after, etc... } 1160 | // 1161 | ``` 1162 | 1163 | 1164 | --- 1165 | 1166 | ## Utilization 1167 | 1168 | --- 1169 | > **The most powerful method is Str.of('example')**, allowing us to fluently chain Str methods together 1170 | 1171 | **Example** 1172 | ```js 1173 | let { Str } = require('laravel-js-str'); 1174 | 1175 | let home = 'https://planets.com'; 1176 | let title = 'hello mars, a cool world for you to visit, maybe?'; 1177 | 1178 | let article = Str.of(title).replaceFirst(',', '') 1179 | .after('hello') 1180 | .before('for you') 1181 | .trim() 1182 | .start('/') 1183 | .finish('/') 1184 | .kebab(); 1185 | 1186 | let resource = home + article 1187 | 1188 | // resource value: 1189 | // 'https://planets.com/mars-a-cool-world/' 1190 | // 1191 | // article value: 1192 | // Stringable: { value: 'https://planets.com/mars-a-cool-world-to-visit', replace, before, after, etc... } 1193 | // 1194 | ``` 1195 | 1196 | 1197 | --- 1198 | 1199 | ## Contribute 1200 | 1201 | --- 1202 | 1203 | PRs are welcomed to this project. 1204 | If you want to improve this package, add 1205 | functionality or improve the docs please feel free to submit a PR. 1206 | 1207 | 1208 | --- 1209 | 1210 | ## Security Vulnerabilities 1211 | 1212 | --- 1213 | 1214 | If you discover a security vulnerability within Clean Code Studio Packages Or Specifically within 1215 | laravel-js-str, please send an e-mail to Zachary Horton via zak@cleancode.studio. All security vulnerabilities will be promptly addressed. 1216 | 1217 | 1218 | --- 1219 | 1220 | ## Change Log 1221 | 1222 | --- 1223 | - [Release 1.0.0](#release-100) 1224 | 1225 | --- 1226 | 1227 | ### Release 1.0.0 1228 | 1229 | --- 1230 | 1231 | - Initial Release 1232 | 1233 | 1234 | --- 1235 | 1236 | ## Versioning 1237 | 1238 | --- 1239 | 1240 | > Semantic Versioning 1241 | 1242 | |Code Status|Stage|Rule|Example Version| 1243 | |---|---|---|---| 1244 | |First release|New Product|Start with 1.0.0|1.0.0| 1245 | |Backward compatible bug fixes|Patch Release|Increment the third digit|1.0.1| 1246 | |Backward compatible new features|Minor Release|Increment the middle digit and reset last digit to zero|1.1.0| 1247 | |Changes that break backward compatibility|Major Release|Increment the first digit and reset middle and last digits to zero|2.0.0| 1248 | 1249 | - [Learn More About Semantic Versioning](https://docs.npmjs.com/about-semantic-versioning) 1250 | 1251 | 1252 | --- 1253 | 1254 | ## License 1255 | 1256 | --- 1257 | 1258 | MIT © [Zachary Horton (Clean Code Studio)](https://www.youtube.com/channel/UCq0m4ebGqurYQLwD-1aYsvg) 1259 | -------------------------------------------------------------------------------- /bundler/api.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Str 4 | 5 | --- 6 | > **Documentation For Each String Method Points To Laravel. Javascript examples are below, Laravel docs will specify what each method specifically does. Replace Str::method() with Str.() when using this package** 7 | 8 | - [Str.after](https://laravel.com/docs/7.x/helpers#method-str-after) 9 | - [Str.afterLast](https://laravel.com/docs/7.x/helpers#method-str-after-last) 10 | - [Str.ascii](https://laravel.com/docs/7.x/helpers#method-str-ascii) 11 | - [Str.before](https://laravel.com/docs/7.x/helpers#method-str-before) 12 | - [Str.beforeLast](https://laravel.com/docs/7.x/helpers#method-str-before-last) 13 | - [Str.between](https://laravel.com/docs/7.x/helpers#method-str-between) 14 | - [Str.contains](https://laravel.com/docs/7.x/helpers#method-str-contains) 15 | - [Str.containsAll](https://laravel.com/docs/7.x/helpers#method-str-contains-all) 16 | - [Str.finish](https://laravel.com/docs/7.x/helpers#method-str-finish) 17 | - [Str.is](https://laravel.com/docs/7.x/helpers#method-str-is) 18 | - [Str.isAscii](https://laravel.com/docs/7.x/helpers#method-str-is-ascii) 19 | - [Str.isUuid](https://laravel.com/docs/7.x/helpers#method-str-is-uuid) 20 | - [Str.length](https://laravel.com/docs/7.x/helpers#method-str-length) 21 | - [Str.limit](https://laravel.com/docs/7.x/helpers#method-str-limit) 22 | - [Str.lower](https://laravel.com/docs/7.x/helpers#method-str-lower) 23 | - [Str.orderedUuid](https://laravel.com/docs/7.x/helpers#method-str-ordered-uuid) 24 | - [Str.plural](https://laravel.com/docs/7.x/helpers#method-str-plural) 25 | - [Str.random](https://laravel.com/docs/7.x/helpers#method-str-random) 26 | - [Str.replaceArray](https://laravel.com/docs/7.x/helpers#method-str-replace-array) 27 | - [Str.replaceFirst](https://laravel.com/docs/7.x/helpers#method-str-replace-first) 28 | - [Str.replaceLast](https://laravel.com/docs/7.x/helpers#method-str-replace-last) 29 | - [Str.singular](https://laravel.com/docs/7.x/helpers#method-str-singular) 30 | - [Str.slug](https://laravel.com/docs/7.x/helpers#method-str-slug) 31 | - [Str.start](https://laravel.com/docs/7.x/helpers#method-str-start) 32 | - [Str.substr](https://laravel.com/docs/7.x/helpers#method-str-substr) 33 | - [Str.ucfirst](https://laravel.com/docs/7.x/helpers#method-str-ucfirst) 34 | - [Str.upper](https://laravel.com/docs/7.x/helpers#method-str-upper) 35 | - [Str.uuid](https://laravel.com/docs/7.x/helpers#method-str-uuid) 36 | - [Str.words](https://laravel.com/docs/7.x/helpers#method-str-words) 37 | 38 | 39 | 40 | ```js 41 | const { Str } = require('laravel-js-str'); 42 | 43 | let slice = Str.after('This is my name', 'This is'); 44 | // ' my name' 45 | ``` 46 | 47 | 48 | 49 | 50 | ```js 51 | const { Str } = require('laravel-js-str'); 52 | 53 | let slice = Str.afterLast('App\Http\Controllers\Controller', '\\'); 54 | // 'Controller' 55 | ``` 56 | 57 | 58 | 59 | 60 | ```js 61 | const { Str } = require('laravel-js-str'); 62 | 63 | let slice = Str.ascii('û'); 64 | // 'u' 65 | ``` 66 | 67 | 68 | 69 | 70 | ```js 71 | const { Str } = require('laravel-js-str'); 72 | 73 | let slice = Str.before('This is my name', 'my name'); 74 | // 'This is ' 75 | ``` 76 | 77 | 78 | 79 | 80 | ```js 81 | const { Str } = require('laravel-js-str'); 82 | 83 | let slice = Str.beforeLast('This is my name', 'is'); 84 | // 'This ' 85 | ``` 86 | 87 | 88 | 89 | 90 | ```js 91 | const { Str } = require('laravel-js-str'); 92 | 93 | let slice = Str.between('This is my name', 'This', 'name'); 94 | // ' is my ' 95 | ``` 96 | 97 | 98 | 99 | 100 | ```js 101 | const { Str } = require('laravel-js-str'); 102 | 103 | let converted = Str.camel('foo_bar'); 104 | // fooBar 105 | ``` 106 | 107 | 108 | 109 | 110 | ```js 111 | const { Str } = require('laravel-js-str'); 112 | 113 | let contains = Str.contains('This is my name', 'my'); 114 | // true 115 | ``` 116 | 117 | 118 | 119 | 120 | ```js 121 | const { Str } = require('laravel-js-str'); 122 | 123 | let contains = Str.contains('This is my name', ['my', 'foo']); 124 | // true 125 | ``` 126 | 127 | 128 | 129 | 130 | ```js 131 | const { Str } = require('laravel-js-str'); 132 | 133 | let containsAll = Str.containsAll('This is my name', ['my', 'name']); 134 | // true 135 | ``` 136 | 137 | 138 | ```js 139 | const { Str } = require('laravel-js-str'); 140 | 141 | let result = Str.endsWith('This is my name', 'name'); 142 | // true 143 | ``` 144 | 145 | 146 | ```js 147 | const { Str } = require('laravel-js-str'); 148 | 149 | let result = Str.endsWith('This is my name', ['name', 'foo']); 150 | // true 151 | 152 | result = Str.endsWith('This is my name', ['this', 'foo']); 153 | // false 154 | ``` 155 | 156 | 157 | 158 | 159 | ```js 160 | const { Str } = require('laravel-js-str'); 161 | 162 | let adjusted = Str.finish('this/string', '/'); 163 | // this/string/ 164 | 165 | adjusted = Str.finish('this/string/', '/'); 166 | // this/string/ 167 | ``` 168 | 169 | 170 | 171 | 172 | ```js 173 | const { Str } = require('laravel-js-str'); 174 | 175 | let matches = Str.is('foo*', 'foobar'); 176 | // true 177 | 178 | matches = Str.is('baz*', 'foobar'); 179 | 180 | // false 181 | ``` 182 | 183 | 184 | 185 | **isAscii is experimental, not confident it works in all scenarios** 186 | ```js 187 | const { Str } = require('laravel-js-str'); 188 | 189 | let isAscii = Str.isAscii('Taylor'); 190 | // true 191 | 192 | isAscii = Str.isAscii('ü'); 193 | 194 | // false 195 | ``` 196 | 197 | 198 | 199 | 200 | ```js 201 | const { Str } = require('laravel-js-str'); 202 | 203 | let isUuid = Str.isUuid('a0a2a2d2-0b87-4a18-83f2-2529882be2de'); 204 | // true 205 | 206 | isUuid = Str.isUuid('laravel'); 207 | 208 | // false 209 | ``` 210 | 211 | 212 | 213 | 214 | ```js 215 | const { Str } = require('laravel-js-str'); 216 | 217 | let converted = Str.kebab('fooBar'); 218 | // foo-bar 219 | ``` 220 | 221 | 222 | 223 | 224 | ```js 225 | const { Str } = require('laravel-js-str'); 226 | 227 | let length = Str.length('Laravel'); 228 | // 7 229 | ``` 230 | 231 | 232 | 233 | 234 | ```js 235 | const { Str } = require('laravel-js-str'); 236 | 237 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0); 238 | // The quick brown fox... 239 | ``` 240 | 241 | 242 | 243 | 244 | ```js 245 | const { Str } = require('laravel-js-str'); 246 | 247 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0, '(...)'); 248 | // The quick brown fox (...) 249 | ``` 250 | 251 | 252 | 253 | 254 | ```js 255 | const { Str } = require('laravel-js-str'); 256 | 257 | let converted = Str.lower('LARAVEL'); 258 | // laravel 259 | ``` 260 | 261 | 262 | 263 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 264 | ```js 265 | const { Str } = require('laravel-js-str'); 266 | 267 | let plural = Str.plural('car'); 268 | // cars 269 | 270 | plural = Str.plural('child'); 271 | // children 272 | ``` 273 | 274 | 275 | 276 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 277 | ```js 278 | const { Str } = require('laravel-js-str'); 279 | 280 | let plural = Str.plural('child'); 281 | // children 282 | 283 | plural = Str.plural('child'); 284 | // child 285 | ``` 286 | 287 | 288 | 289 | 290 | ```js 291 | const { Str } = require('laravel-js-str'); 292 | 293 | let random = Str.random(40); 294 | ``` 295 | 296 | 297 | 298 | 299 | ```js 300 | const { Str } = require('laravel-js-str'); 301 | 302 | let string = 'The event will take place between ? and ?'; 303 | let replaced = Str.replaceArray(['?', '8:30', '9:00'], string); 304 | // The event will take place between 8:30 and 9:00 305 | ``` 306 | 307 | 308 | 309 | 310 | ```js 311 | const { Str } = require('laravel-js-str'); 312 | 313 | let replaced = Str.replaceFirst('the', 'a', 'the quick brown fox jumps over the lazy dog'); 314 | // a quick brown fox jumps over the lazy dog 315 | ``` 316 | 317 | 318 | 319 | 320 | ```js 321 | const { Str } = require('laravel-js-str'); 322 | 323 | let replaced = Str.replaceLast('the', 'a', 'the quick brown fox jumps over the lazy dog'); 324 | // the quick brown fox jumps over a lazy dog 325 | ``` 326 | 327 | 328 | 329 | 330 | ```js 331 | const { Str } = require('laravel-js-str'); 332 | 333 | let singular = Str.singular('cars'); 334 | // car 335 | 336 | singular = Str.singular('children'); 337 | // child 338 | ``` 339 | 340 | 341 | 342 | 343 | ```js 344 | const { Str } = require('laravel-js-str'); 345 | 346 | let slug = Str.slug('Laravel 5 Framework', '-'); 347 | // laravel-5-framework 348 | ``` 349 | 350 | ```js 351 | const { Str } = require('laravel-js-str'); 352 | 353 | let converted = Str.snake('fooBar'); 354 | // foo_bar 355 | ``` 356 | 357 | 358 | 359 | 360 | ```js 361 | const { Str } = require('laravel-js-str'); 362 | 363 | let adjusted = Str.start('this/string', '/'); 364 | // /this/string 365 | 366 | adjusted = Str.start('/this/string', '/'); 367 | // /this/string 368 | ``` 369 | 370 | 371 | 372 | 373 | ```js 374 | const { Str } = require('laravel-js-str'); 375 | 376 | let result = Str.startsWith('This is my name', This'); 377 | // true 378 | ``` 379 | 380 | 381 | 382 | 383 | ```js 384 | const { Str } = require('laravel-js-str'); 385 | 386 | let converted = Str.studly('foo_bar'); 387 | // FooBar 388 | ``` 389 | 390 | 391 | 392 | 393 | ```js 394 | const { Str } = require('laravel-js-str'); 395 | 396 | let converted = Str.substr('The Laravel Framework', , ); 397 | // Laravel 398 | ``` 399 | 400 | 401 | 402 | 403 | ```js 404 | const { Str } = require('laravel-js-str'); 405 | 406 | let converted = Str.title('a nice title uses the correct case'); 407 | // A Nice Title Uses The Correct Case 408 | ``` 409 | 410 | 411 | 412 | 413 | ```js 414 | const { Str } = require('laravel-js-str'); 415 | 416 | let string = Str.ucfirst('foo bar'); 417 | // Foo bar 418 | ``` 419 | 420 | 421 | 422 | 423 | ```js 424 | const { Str } = require('laravel-js-str'); 425 | 426 | let string = Str.upper('laravel'); 427 | // LARAVEL 428 | ``` 429 | 430 | 431 | 432 | 433 | ```js 434 | const { Str } = require('laravel-js-str'); 435 | 436 | return Str.uuid(); 437 | ``` 438 | 439 | 440 | 441 | 442 | ```js 443 | const { Str } = require('laravel-js-str'); 444 | 445 | Str.words('Perfectly balanced, as all things should be.', 3, '>>>'); 446 | 447 | // Perfectly balanced, as >>> 448 | ``` 449 | 450 | 451 | 452 | 453 | ```js 454 | const { Str } = require('laravel-js-str'); 455 | 456 | let slice = Str.of('This is my name').after('This is'); 457 | // ' my name' 458 | ``` 459 | 460 | 461 | 462 | 463 | ```js 464 | const { Str } = require('laravel-js-str'); 465 | 466 | let slice = Str.of('App\Http\Controllers\Controller').afterLast('\\'); 467 | // 'Controller' 468 | ``` 469 | 470 | 471 | 472 | 473 | ```js 474 | const { Str } = require('laravel-js-str'); 475 | 476 | let string = Str.of('Taylor').append(' Otwell'); 477 | // 'Taylor Otwell' 478 | ``` 479 | 480 | 481 | 482 | **Experimental Method, not sure this works in all cases** 483 | ```js 484 | const { Str } = require('laravel-js-str'); 485 | 486 | let string = Str.of('ü').ascii(); 487 | // 'u' 488 | ``` 489 | 490 | 491 | 492 | 493 | ```js 494 | const { Str } = require('laravel-js-str'); 495 | 496 | let string = Str.of('/foo/bar/baz').basename(); 497 | // 'baz' 498 | ``` 499 | 500 | 501 | 502 | 503 | ```js 504 | const { Str } = require('laravel-js-str'); 505 | 506 | let string = Str.of('/foo/bar/baz.jpg').basename('.jpg'); 507 | // 'baz' 508 | ``` 509 | 510 | 511 | 512 | 513 | ```js 514 | const { Str } = require('laravel-js-str'); 515 | 516 | let slice = Str.of('This is my name').before('my name'); 517 | // 'This is ' 518 | ``` 519 | 520 | 521 | 522 | 523 | ```js 524 | const { Str } = require('laravel-js-str'); 525 | 526 | let slice = Str.of('This is my name').beforeLast('is'); 527 | // 'This ' 528 | ``` 529 | 530 | 531 | 532 | 533 | ```js 534 | const { Str } = require('laravel-js-str'); 535 | 536 | let converted = Str.of('foo_bar').camel(); 537 | // fooBar 538 | ``` 539 | 540 | 541 | 542 | 543 | ```js 544 | const { Str } = require('laravel-js-str'); 545 | 546 | let contains = Str.of('This is my name').contains('my'); 547 | // true 548 | ``` 549 | 550 | 551 | 552 | 553 | ```js 554 | const { Str } = require('laravel-js-str'); 555 | 556 | let contains = Str.of('This is my name').contains(['my', foo']); 557 | // true 558 | ``` 559 | 560 | 561 | 562 | 563 | ```js 564 | const { Str } = require('laravel-js-str'); 565 | 566 | let containsAll = Str.of('This is my name').containsAll(['my', 'name']); 567 | // true 568 | ``` 569 | 570 | 571 | 572 | 573 | ```js 574 | const { Str } = require('laravel-js-str'); 575 | 576 | let string = Str.of('/foo/bar/baz').dirname(); 577 | // '/foo/bar' 578 | ``` 579 | 580 | 581 | 582 | 583 | ```js 584 | const { Str } = require('laravel-js-str'); 585 | 586 | let string = Str.of('/foo/bar/baz').dirname(2); 587 | // '/foo' 588 | ``` 589 | 590 | 591 | 592 | 593 | ```js 594 | const { Str } = require('laravel-js-str'); 595 | 596 | let result = Str.of('This is my name').endsWith('name'); 597 | // true 598 | ``` 599 | 600 | 601 | 602 | 603 | ```js 604 | const { Str } = require('laravel-js-str'); 605 | 606 | let result = Str.of('This is my name').endsWith(['name', 'foo']); 607 | // true 608 | 609 | result = Str.of('This is my name').endsWith(['this', 'foo']); 610 | // false 611 | ``` 612 | 613 | 614 | 615 | ```js 616 | const { Str } = require('laravel-js-str'); 617 | 618 | let result = Str.of('Laravel').exactly('Laravel'); 619 | // true 620 | ``` 621 | 622 | 623 | 624 | [Collect.js](https://npmjs.com/package/collect.js) 625 | ```js 626 | const { Str } = require('laravel-js-str'); 627 | 628 | let collection = Str.of('foo bar baz').explode(' '); 629 | // collect(['foo', 'bar', 'baz']) 630 | ``` 631 | 632 | 633 | 634 | 635 | ```js 636 | const { Str } = require('laravel-js-str'); 637 | 638 | let adjusted = Str.of('this/string').finish('/'); 639 | // this/string/ 640 | 641 | adjusted = Str.of('this/string/').finish('/'); 642 | 643 | // this/string/ 644 | ``` 645 | 646 | 647 | 648 | 649 | ```js 650 | const { Str } = require('laravel-js-str'); 651 | 652 | let matches = Str.of('foobar').is('foo*'); 653 | // true 654 | 655 | matches = Str.of('foobar').is('baz*'); 656 | 657 | // false 658 | ``` 659 | 660 | 661 | 662 | **isAscii is Experimental, not positive its correct in all cases** 663 | ```js 664 | const { Str } = require('laravel-js-str'); 665 | 666 | let result = Str.of('Taylor').isAscii(); 667 | // true 668 | 669 | result = Str.of('ü').isAcii(); 670 | 671 | // false 672 | ``` 673 | 674 | 675 | 676 | 677 | ```js 678 | const { Str } = require('laravel-js-str'); 679 | 680 | let result = Str.of(' ').trim().isEmpty(); 681 | // true 682 | 683 | result = Str.of('Laravel').trim().isEmpty(); 684 | 685 | // false 686 | ``` 687 | 688 | 689 | 690 | 691 | ```js 692 | const { Str } = require('laravel-js-str'); 693 | 694 | let result = Str.of(' ').trim().isNotEmpty(); 695 | // false 696 | 697 | result = Str.of('Laravel').trim().isNotEmpty(); 698 | 699 | // true 700 | ``` 701 | 702 | 703 | 704 | 705 | ```js 706 | const { Str } = require('laravel-js-str'); 707 | 708 | let converted = Str.of('fooBar').kebab(); 709 | // foo-bar 710 | ``` 711 | 712 | 713 | 714 | 715 | ```js 716 | const { Str } = require('laravel-js-str'); 717 | 718 | let length = Str.of('Laravel').length(); 719 | // 7 720 | ``` 721 | 722 | 723 | 724 | 725 | ```js 726 | const { Str } = require('laravel-js-str'); 727 | 728 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20); 729 | // The quick brown fox... 730 | ``` 731 | 732 | 733 | 734 | 735 | ```js 736 | const { Str } = require('laravel-js-str'); 737 | 738 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20, ' (...)'); 739 | // The quick brown fox (...) 740 | ``` 741 | 742 | 743 | 744 | 745 | ```js 746 | const { Str } = require('laravel-js-str'); 747 | 748 | let result = Str.of('LARAVEL').lower(); 749 | // 'laravel' 750 | ``` 751 | 752 | 753 | 754 | 755 | ```js 756 | const { Str } = require('laravel-js-str'); 757 | 758 | let string = Str.of(' Laravel ').ltrim(); 759 | // 'Laravel ' 760 | 761 | string = Str.of('/Laravel/').ltrim('/'); 762 | 763 | // 'Laravel/' 764 | ``` 765 | 766 | 767 | 768 | 769 | ```js 770 | const { Str } = require('laravel-js-str'); 771 | 772 | let result = Str.of('foo bar').match('/bar/'); 773 | // 'bar' 774 | 775 | result = Str.of('foo bar').match('/foo (.*)/'); 776 | 777 | // 'bar' 778 | ``` 779 | 780 | 781 | 782 | __Match All Coming Soon__ 783 | ``` 784 | const { Str } = require('laravel-js-str'); 785 | 786 | let result = Str.of('bar foo bar').matchAll('/bar/'); 787 | // collect(['bar', 'bar']) 788 | ``` 789 | ``` 790 | const { Str } = require('laravel-js-str'); 791 | 792 | let result = Str.of('bar fun bar fly').matchAll('/f(\w*)/'); 793 | // collect(['un', 'ly']); 794 | 795 | 796 | ``` 797 | 798 | 799 | 800 | 801 | ```js 802 | const { Str } = require('laravel-js-str'); 803 | 804 | let plural = Str.of('car').plural(); 805 | // cars 806 | 807 | plural = Str.of('child').plural(); 808 | 809 | // children 810 | ``` 811 | 812 | 813 | 814 | 815 | ```js 816 | const { Str } = require('laravel-js-str'); 817 | 818 | let plural = Str.of('child').plural(2); 819 | // children 820 | 821 | plural = Str.of('child').plural(1); 822 | 823 | // child 824 | ``` 825 | 826 | 827 | 828 | 829 | ```js 830 | const { Str } = require('laravel-js-str'); 831 | 832 | let string = Str.of('Framework').prepend('Laravel '); 833 | // Laravel Framework 834 | ``` 835 | 836 | 837 | 838 | 839 | ```js 840 | const { Str } = require('laravel-js-str'); 841 | 842 | let replaced = Str.of('Laravel 6.x').replace('6.x', '7.x'); 843 | // Laravel 7.x 844 | ``` 845 | 846 | 847 | 848 | 849 | ```js 850 | const { Str } = require('laravel-js-str'); 851 | 852 | let string = 'The event will take place between ? and ?'; 853 | let replaced = Str.of(string).replaceArray('?', ['8:30', '9:00']); 854 | // The event will take place between 8:30 and 9:00 855 | ``` 856 | 857 | 858 | 859 | 860 | ```js 861 | const { Str } = require('laravel-js-str'); 862 | 863 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceFirst('the', 'a'); 864 | // a quick brown fox jumps over the lazy dog 865 | ``` 866 | 867 | 868 | 869 | 870 | ```js 871 | const { Str } = require('laravel-js-str'); 872 | 873 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceLast('the', 'a'); 874 | // the quick brown fox jumps over a lazy dog 875 | ``` 876 | 877 | 878 | 879 | 880 | ```js 881 | const { Str } = require('laravel-js-str'); 882 | 883 | let replaced = Str.of('(+1) 501-555-1000').replace('/[^A-Za-z0-9]++/', ''); 884 | 885 | //'15015551000' 886 | ``` 887 | 888 | 889 | 890 | ```js 891 | 892 | ``` 893 | 894 | 895 | ```js 896 | const { Str } = require('laravel-js-str'); 897 | 898 | let string = Str.of(' Laravel ').rtrim(); 899 | // ' Laravel' 900 | 901 | string = Str.of('/Laravel/').rtrim('/'); 902 | 903 | // '/Laravel' 904 | ``` 905 | 906 | 907 | 908 | 909 | ```js 910 | const { Str } = require('laravel-js-str'); 911 | 912 | let singular = Str.of('cars').singular(); 913 | // car 914 | 915 | singular = Str.of('children').singular(); 916 | 917 | // child 918 | ``` 919 | 920 | 921 | 922 | 923 | ```js 924 | const { Str } = require('laravel-js-str'); 925 | 926 | let slug = Str.of('Laravel Framework').slug('-'); 927 | // laravel-framework 928 | ``` 929 | 930 | 931 | 932 | 933 | ```js 934 | const { Str } = require('laravel-js-str'); 935 | 936 | let converted = Str.of('fooBar').snake(); 937 | // foo_bar 938 | ``` 939 | 940 | 941 | 942 | 943 | ```js 944 | const { Str } = require('laravel-js-str'); 945 | 946 | let segments = Str.of('one, two, three').split('/[\s, +/'); 947 | // collect(["one", "two", "three"]) 948 | ``` 949 | 950 | 951 | 952 | 953 | ```js 954 | const { Str } = require('laravel-js-str'); 955 | 956 | let adjusted = Str.of('this/string').start('/'); 957 | // /this/string 958 | 959 | adjusted = Str.of('/this/string').start('/'); 960 | 961 | // /this/string 962 | ``` 963 | 964 | 965 | 966 | 967 | ```js 968 | const { Str } = require('laravel-js-str'); 969 | 970 | let result = Str.of('This is my name').startsWith('This'); 971 | // true 972 | ``` 973 | 974 | 975 | 976 | 977 | ```js 978 | const { Str } = require('laravel-js-str'); 979 | 980 | let converted = Str.of('foo_bar').studly(); 981 | // FooBar 982 | ``` 983 | 984 | 985 | 986 | 987 | ```js 988 | const { Str } = require('laravel-js-str'); 989 | 990 | let string = Str.of('Laravel Framework').substr(8); 991 | // Framework 992 | 993 | string = Str.of('Laravel Framework').substr(8, ); 994 | 995 | // Frame 996 | ``` 997 | 998 | 999 | 1000 | 1001 | ```js 1002 | const { Str } = require('laravel-js-str'); 1003 | 1004 | let converted = Str.of('a nice title uses the correct case').title(); 1005 | // A Nice Title Uses The Correct Case 1006 | ``` 1007 | 1008 | 1009 | 1010 | 1011 | ```js 1012 | const { Str } = require('laravel-js-str'); 1013 | 1014 | let string = Str.of(' Laravel ').trim(); 1015 | // 'Laravel' 1016 | 1017 | string = Str.of('/Laravel/').trim('/'); 1018 | 1019 | // 'Laravel' 1020 | ``` 1021 | 1022 | 1023 | 1024 | 1025 | ```js 1026 | const { Str } = require('laravel-js-str'); 1027 | 1028 | let string = Str.of('foo bar').ucfirst(); 1029 | // Foo bar 1030 | ``` 1031 | 1032 | 1033 | 1034 | 1035 | ```js 1036 | const { Str } = require('laravel-js-str'); 1037 | 1038 | let adjusted = Str.of('laravel').upper(); 1039 | // LARAVEL 1040 | ``` 1041 | 1042 | 1043 | 1044 | 1045 | ```js 1046 | const { Str } = require('laravel-js-str'); 1047 | 1048 | let string = Str.of(' ').whenEmpty(function(string) { 1049 | return string.trim().prepend('Laravel'); 1050 | }); 1051 | 1052 | // 'Laravel' 1053 | ``` 1054 | 1055 | 1056 | 1057 | 1058 | ```js 1059 | const { Str } = require('laravel-js-str'); 1060 | 1061 | let string = Str.of('Perfectly balanced, as all things should be.').words(3, '>>>'); 1062 | // Perfectly balanced, as >>> 1063 | ``` 1064 | -------------------------------------------------------------------------------- /bundler/badges.md: -------------------------------------------------------------------------------- 1 | 2 | [![Travis](https://img.shields.io/travis/zhorton34/laravel-js-str/master.svg?logo=travis)](https://travis-ci.org/zhorton34/laravel-js-str/builds) 3 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?color=success&logo=github)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity) 4 | [![dependencies](https://img.shields.io/badge/dependencies-none-brightgreen.svg?color=success&logo=javascript)](https://github.com/zhorton34/laravel-js-str/blob/master/package.json) 5 | [![Open Source Love](https://badges.frapsoft.com/os/v3/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 6 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?logo=git&color=success)](http://makeapullrequest.com) 7 | ![Version](https://img.shields.io/npm/v/laravel-js-str.svg?color=success&logo=npm) 8 | [![npm license](https://img.shields.io/npm/l/laravel-js-str.svg?color=success)](http://badge.fury.io/js/laravel-js-str) 9 | 10 | 11 | --- 12 | 13 | # Project Goals 14 | 15 | --- 16 | 17 | - [x] **Fluent** 18 | - [x] **Stringable** 19 | - [x] **Simplified** 20 | -------------------------------------------------------------------------------- /bundler/bundle.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { readFileSync, writeFileSync } = require('fs'); 5 | const bundle = file => readFileSync(`bundler/${file}.md`, 'utf-8'); 6 | const ReadMe = (content = []) => writeFileSync('README.md', content.join('\n\n')); 7 | const ChangeLog = (content = []) => writeFileSync('CHANGELOG.md', content.join('\n\n')); 8 | 9 | ChangeLog([bundle('change_log')]); 10 | ReadMe(['everything'].map(bundle)); 11 | 12 | -------------------------------------------------------------------------------- /bundler/change_log.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Change Log 4 | 5 | --- 6 | - [Release 1.0.0](#release-100) 7 | - [Release 1.0.4](#release-104) 8 | --- 9 | 10 | ### Release 1.0.4 11 | 12 | --- 13 | 14 | - Fixed Yarn/Npm Conflict Bloating Repository Size 15 | 16 | --- 17 | --- 18 | 19 | ### Release 1.0.0 20 | 21 | --- 22 | 23 | - Initial Release 24 | -------------------------------------------------------------------------------- /bundler/contribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Contribute 4 | 5 | --- 6 | 7 | PRs are welcomed to this project. 8 | If you want to improve this package, add 9 | functionality or improve the docs please feel free to submit a PR. 10 | -------------------------------------------------------------------------------- /bundler/everything.md: -------------------------------------------------------------------------------- 1 | 2 | ![Version](https://img.shields.io/npm/v/laravel-js-str.svg?color=success&logo=npm) 3 | [![Travis](https://img.shields.io/travis/zhorton34/laravel-js-str/master.svg?logo=travis)](https://travis-ci.org/zhorton34/laravel-js-str/builds) 4 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?logo=git&color=success)](http://makeapullrequest.com) 5 | [![Code Pen](https://img.shields.io/badge/codepen/laraveljs-example/master.svg?logo=codepen)](https://codepen.io/zhorton34/pen/LYpoxEY) 6 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?color=success&logo=github)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity) 7 | [![dependencies](https://img.shields.io/badge/dependencies-none-brightgreen.svg?color=success&logo=javascript)](https://github.com/zhorton34/laravel-js-str/blob/master/package.json) 8 | [![npm license](https://img.shields.io/npm/l/laravel-js-str.svg?color=success)](http://badge.fury.io/js/laravel-js-str) 9 | 10 | --- 11 | 12 | # Project Goals 13 | 14 | --- 15 | 16 | - [x] **Fluent** 17 | - [x] **Stringable** 18 | - [x] **Simplified** 19 | 20 | --- 21 | 22 | # Tinkerable Demo 23 | 24 | --- 25 | ![Code Pen Example](https://lh3.googleusercontent.com/8h1qz33h3h1-5yU75YInO5CGO8-N6xGP5AxN2c_fCpdUa4sMBixadJkKfdahtJY31hH86yEC1Y6gDJLcvc0QqsvDmEBoG4QFuZmdeaEvOoD0ctGE5vI7bbIjEBi0k7CNEyxrrYl25hCpsxaSTZPrXBlOHEb5itBxeaz_SYNNOw0pORV_Ca442tPGaVlM2JsnhQKV4o5Pt0gNW-jUqY_wWbKBhhPi7GD6S-wcZ9MW7QpEI0DtUAeexQKcmwHUrn_lKkF79YFr5KKzHUcZpFdtY3NHTRyrtwZLlU3TY8B4axaLks-PHZ-tXWADx45AvY0hYGEwx-nD0lEbc_u7Mzi2HOJmhLI9BL_2_TINU1-eXCPQxu94DTm8K2w7Ic8lxxf-en9l2TOrKJlUfnmjX_IjCZFQyCbYz4RQlE7RU_3MTZGTNx84cHkDgnEjGPqYd3xeBPWfNcqsJWymXRhvTwIi-u5KagjnPvv-HPFXEqpTlkBNVz0phTO2EqjKBVkTYNscV9Dt0SXNGvWqTMPQ2c0iDuvha75QIFUrt0GGj8NUUZZUCVGCq9KQIQmSXx_wus3ZPQM8GG1dDJHaorGNAWb-MUQwaXJmZ0HxEip45D37QPZyXyuPNbgHs4ttzCWqa3IeEWPU5yUQQmAGlug0oaRd2T8tRQy1ljv_S_Vg3q8-DYsqf8SLBGZtKJ8xujNhS1PR22lydg=w1919-h952-ft "Package Gif Example") 26 | 27 | 28 | --- 29 | 30 | ## Laravel JS Str 31 | 32 | --- 33 | 34 | > _"Laravel's Illuminate\Str & Illuminate\Stringify Including Str.of() In Javascript"_ 35 | 36 | --- 37 | 38 | ## Installation 39 | 40 | --- 41 | 42 | 43 | ### NPM 44 | 45 | ```bash 46 | npm install --save-dev laravel-js-str 47 | ``` 48 | 49 | ### Yarn 50 | 51 | ```bash 52 | yarn add laravel-js-str --save 53 | ``` 54 | 55 | ### CDN 56 | 57 | ```html 58 | 59 | ``` 60 | 61 | 62 | --- 63 | 64 | ## Str 65 | 66 | --- 67 | > **Documentation For Each String Method Points To Laravel. Javascript examples are below, Laravel docs will specify what each method specifically does. Replace Str::method() with Str.() when using this package** 68 | 69 | - [Str.after](https://laravel.com/docs/7.x/helpers#method-str-after) 70 | - [Str.afterLast](https://laravel.com/docs/7.x/helpers#method-str-after-last) 71 | - [Str.ascii](https://laravel.com/docs/7.x/helpers#method-str-ascii) 72 | - [Str.before](https://laravel.com/docs/7.x/helpers#method-str-before) 73 | - [Str.beforeLast](https://laravel.com/docs/7.x/helpers#method-str-before-last) 74 | - [Str.between](https://laravel.com/docs/7.x/helpers#method-str-between) 75 | - [Str.contains](https://laravel.com/docs/7.x/helpers#method-str-contains) 76 | - [Str.containsAll](https://laravel.com/docs/7.x/helpers#method-str-contains-all) 77 | - [Str.finish](https://laravel.com/docs/7.x/helpers#method-str-finish) 78 | - [Str.is](https://laravel.com/docs/7.x/helpers#method-str-is) 79 | - [Str.isAscii](https://laravel.com/docs/7.x/helpers#method-str-is-ascii) 80 | - [Str.isUuid](https://laravel.com/docs/7.x/helpers#method-str-is-uuid) 81 | - [Str.length](https://laravel.com/docs/7.x/helpers#method-str-length) 82 | - [Str.limit](https://laravel.com/docs/7.x/helpers#method-str-limit) 83 | - [Str.lower](https://laravel.com/docs/7.x/helpers#method-str-lower) 84 | - [Str.orderedUuid](https://laravel.com/docs/7.x/helpers#method-str-ordered-uuid) 85 | - [Str.plural](https://laravel.com/docs/7.x/helpers#method-str-plural) 86 | - [Str.random](https://laravel.com/docs/7.x/helpers#method-str-random) 87 | - [Str.replaceArray](https://laravel.com/docs/7.x/helpers#method-str-replace-array) 88 | - [Str.replaceFirst](https://laravel.com/docs/7.x/helpers#method-str-replace-first) 89 | - [Str.replaceLast](https://laravel.com/docs/7.x/helpers#method-str-replace-last) 90 | - [Str.singular](https://laravel.com/docs/7.x/helpers#method-str-singular) 91 | - [Str.slug](https://laravel.com/docs/7.x/helpers#method-str-slug) 92 | - [Str.start](https://laravel.com/docs/7.x/helpers#method-str-start) 93 | - [Str.substr](https://laravel.com/docs/7.x/helpers#method-str-substr) 94 | - [Str.ucfirst](https://laravel.com/docs/7.x/helpers#method-str-ucfirst) 95 | - [Str.upper](https://laravel.com/docs/7.x/helpers#method-str-upper) 96 | - [Str.uuid](https://laravel.com/docs/7.x/helpers#method-str-uuid) 97 | - [Str.words](https://laravel.com/docs/7.x/helpers#method-str-words) 98 | 99 | 100 | 101 | ```js 102 | const { Str } = require('laravel-js-str'); 103 | 104 | let slice = Str.after('This is my name', 'This is'); 105 | // ' my name' 106 | ``` 107 | 108 | 109 | 110 | 111 | ```js 112 | const { Str } = require('laravel-js-str'); 113 | 114 | let slice = Str.afterLast('App\Http\Controllers\Controller', '\\'); 115 | // 'Controller' 116 | ``` 117 | 118 | 119 | 120 | 121 | ```js 122 | const { Str } = require('laravel-js-str'); 123 | 124 | let slice = Str.ascii('û'); 125 | // 'u' 126 | ``` 127 | 128 | 129 | 130 | 131 | ```js 132 | const { Str } = require('laravel-js-str'); 133 | 134 | let slice = Str.before('This is my name', 'my name'); 135 | // 'This is ' 136 | ``` 137 | 138 | 139 | 140 | 141 | ```js 142 | const { Str } = require('laravel-js-str'); 143 | 144 | let slice = Str.beforeLast('This is my name', 'is'); 145 | // 'This ' 146 | ``` 147 | 148 | 149 | 150 | 151 | ```js 152 | const { Str } = require('laravel-js-str'); 153 | 154 | let slice = Str.between('This is my name', 'This', 'name'); 155 | // ' is my ' 156 | ``` 157 | 158 | 159 | 160 | 161 | ```js 162 | const { Str } = require('laravel-js-str'); 163 | 164 | let converted = Str.camel('foo_bar'); 165 | // fooBar 166 | ``` 167 | 168 | 169 | 170 | 171 | ```js 172 | const { Str } = require('laravel-js-str'); 173 | 174 | let contains = Str.contains('This is my name', 'my'); 175 | // true 176 | ``` 177 | 178 | 179 | 180 | 181 | ```js 182 | const { Str } = require('laravel-js-str'); 183 | 184 | let contains = Str.contains('This is my name', ['my', 'foo']); 185 | // true 186 | ``` 187 | 188 | 189 | 190 | 191 | ```js 192 | const { Str } = require('laravel-js-str'); 193 | 194 | let containsAll = Str.containsAll('This is my name', ['my', 'name']); 195 | // true 196 | ``` 197 | 198 | 199 | ```js 200 | const { Str } = require('laravel-js-str'); 201 | 202 | let result = Str.endsWith('This is my name', 'name'); 203 | // true 204 | ``` 205 | 206 | 207 | ```js 208 | const { Str } = require('laravel-js-str'); 209 | 210 | let result = Str.endsWith('This is my name', ['name', 'foo']); 211 | // true 212 | 213 | result = Str.endsWith('This is my name', ['this', 'foo']); 214 | // false 215 | ``` 216 | 217 | 218 | 219 | 220 | ```js 221 | const { Str } = require('laravel-js-str'); 222 | 223 | let adjusted = Str.finish('this/string', '/'); 224 | // this/string/ 225 | 226 | adjusted = Str.finish('this/string/', '/'); 227 | // this/string/ 228 | ``` 229 | 230 | 231 | 232 | 233 | ```js 234 | const { Str } = require('laravel-js-str'); 235 | 236 | let matches = Str.is('foo*', 'foobar'); 237 | // true 238 | 239 | matches = Str.is('baz*', 'foobar'); 240 | 241 | // false 242 | ``` 243 | 244 | 245 | 246 | **isAscii is experimental, not confident it works in all scenarios** 247 | ```js 248 | const { Str } = require('laravel-js-str'); 249 | 250 | let isAscii = Str.isAscii('Taylor'); 251 | // true 252 | 253 | isAscii = Str.isAscii('ü'); 254 | 255 | // false 256 | ``` 257 | 258 | 259 | 260 | 261 | ```js 262 | const { Str } = require('laravel-js-str'); 263 | 264 | let isUuid = Str.isUuid('a0a2a2d2-0b87-4a18-83f2-2529882be2de'); 265 | // true 266 | 267 | isUuid = Str.isUuid('laravel'); 268 | 269 | // false 270 | ``` 271 | 272 | 273 | 274 | 275 | ```js 276 | const { Str } = require('laravel-js-str'); 277 | 278 | let converted = Str.kebab('fooBar'); 279 | // foo-bar 280 | ``` 281 | 282 | 283 | 284 | 285 | ```js 286 | const { Str } = require('laravel-js-str'); 287 | 288 | let length = Str.length('Laravel'); 289 | // 7 290 | ``` 291 | 292 | 293 | 294 | 295 | ```js 296 | const { Str } = require('laravel-js-str'); 297 | 298 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0); 299 | // The quick brown fox... 300 | ``` 301 | 302 | 303 | 304 | 305 | ```js 306 | const { Str } = require('laravel-js-str'); 307 | 308 | let truncated = Str.limit('The quick brown fox jumps over the lazy dog', 0, '(...)'); 309 | // The quick brown fox (...) 310 | ``` 311 | 312 | 313 | 314 | 315 | ```js 316 | const { Str } = require('laravel-js-str'); 317 | 318 | let converted = Str.lower('LARAVEL'); 319 | // laravel 320 | ``` 321 | 322 | 323 | 324 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 325 | ```js 326 | const { Str } = require('laravel-js-str'); 327 | 328 | let plural = Str.plural('car'); 329 | // cars 330 | 331 | plural = Str.plural('child'); 332 | // children 333 | ``` 334 | 335 | 336 | 337 | [Plural Package Used](https://www.npmjs.com/package/pluralize) 338 | ```js 339 | const { Str } = require('laravel-js-str'); 340 | 341 | let plural = Str.plural('child'); 342 | // children 343 | 344 | plural = Str.plural('child'); 345 | // child 346 | ``` 347 | 348 | 349 | 350 | 351 | ```js 352 | const { Str } = require('laravel-js-str'); 353 | 354 | let random = Str.random(40); 355 | ``` 356 | 357 | 358 | 359 | 360 | ```js 361 | const { Str } = require('laravel-js-str'); 362 | 363 | let string = 'The event will take place between ? and ?'; 364 | let replaced = Str.replaceArray(['?', '8:30', '9:00'], string); 365 | // The event will take place between 8:30 and 9:00 366 | ``` 367 | 368 | 369 | 370 | 371 | ```js 372 | const { Str } = require('laravel-js-str'); 373 | 374 | let replaced = Str.replaceFirst('the', 'a', 'the quick brown fox jumps over the lazy dog'); 375 | // a quick brown fox jumps over the lazy dog 376 | ``` 377 | 378 | 379 | 380 | 381 | ```js 382 | const { Str } = require('laravel-js-str'); 383 | 384 | let replaced = Str.replaceLast('the', 'a', 'the quick brown fox jumps over the lazy dog'); 385 | // the quick brown fox jumps over a lazy dog 386 | ``` 387 | 388 | 389 | 390 | 391 | ```js 392 | const { Str } = require('laravel-js-str'); 393 | 394 | let singular = Str.singular('cars'); 395 | // car 396 | 397 | singular = Str.singular('children'); 398 | // child 399 | ``` 400 | 401 | 402 | 403 | 404 | ```js 405 | const { Str } = require('laravel-js-str'); 406 | 407 | let slug = Str.slug('Laravel 5 Framework', '-'); 408 | // laravel-5-framework 409 | ``` 410 | 411 | ```js 412 | const { Str } = require('laravel-js-str'); 413 | 414 | let converted = Str.snake('fooBar'); 415 | // foo_bar 416 | ``` 417 | 418 | 419 | 420 | 421 | ```js 422 | const { Str } = require('laravel-js-str'); 423 | 424 | let adjusted = Str.start('this/string', '/'); 425 | // /this/string 426 | 427 | adjusted = Str.start('/this/string', '/'); 428 | // /this/string 429 | ``` 430 | 431 | 432 | 433 | 434 | ```js 435 | const { Str } = require('laravel-js-str'); 436 | 437 | let result = Str.startsWith('This is my name', This'); 438 | // true 439 | ``` 440 | 441 | 442 | 443 | 444 | ```js 445 | const { Str } = require('laravel-js-str'); 446 | 447 | let converted = Str.studly('foo_bar'); 448 | // FooBar 449 | ``` 450 | 451 | 452 | 453 | 454 | ```js 455 | const { Str } = require('laravel-js-str'); 456 | 457 | let converted = Str.substr('The Laravel Framework', , ); 458 | // Laravel 459 | ``` 460 | 461 | 462 | 463 | 464 | ```js 465 | const { Str } = require('laravel-js-str'); 466 | 467 | let converted = Str.title('a nice title uses the correct case'); 468 | // A Nice Title Uses The Correct Case 469 | ``` 470 | 471 | 472 | 473 | 474 | ```js 475 | const { Str } = require('laravel-js-str'); 476 | 477 | let string = Str.ucfirst('foo bar'); 478 | // Foo bar 479 | ``` 480 | 481 | 482 | 483 | 484 | ```js 485 | const { Str } = require('laravel-js-str'); 486 | 487 | let string = Str.upper('laravel'); 488 | // LARAVEL 489 | ``` 490 | 491 | 492 | 493 | 494 | ```js 495 | const { Str } = require('laravel-js-str'); 496 | 497 | return Str.uuid(); 498 | ``` 499 | 500 | 501 | 502 | 503 | ```js 504 | const { Str } = require('laravel-js-str'); 505 | 506 | Str.words('Perfectly balanced, as all things should be.', 3, '>>>'); 507 | 508 | // Perfectly balanced, as >>> 509 | ``` 510 | 511 | 512 | 513 | 514 | ```js 515 | const { Str } = require('laravel-js-str'); 516 | 517 | let slice = Str.of('This is my name').after('This is'); 518 | // ' my name' 519 | ``` 520 | 521 | 522 | 523 | 524 | ```js 525 | const { Str } = require('laravel-js-str'); 526 | 527 | let slice = Str.of('App\Http\Controllers\Controller').afterLast('\\'); 528 | // 'Controller' 529 | ``` 530 | 531 | 532 | 533 | 534 | ```js 535 | const { Str } = require('laravel-js-str'); 536 | 537 | let string = Str.of('Taylor').append(' Otwell'); 538 | // 'Taylor Otwell' 539 | ``` 540 | 541 | 542 | 543 | **Experimental Method, not sure this works in all cases** 544 | ```js 545 | const { Str } = require('laravel-js-str'); 546 | 547 | let string = Str.of('ü').ascii(); 548 | // 'u' 549 | ``` 550 | 551 | 552 | 553 | 554 | ```js 555 | const { Str } = require('laravel-js-str'); 556 | 557 | let string = Str.of('/foo/bar/baz').basename(); 558 | // 'baz' 559 | ``` 560 | 561 | 562 | 563 | 564 | ```js 565 | const { Str } = require('laravel-js-str'); 566 | 567 | let string = Str.of('/foo/bar/baz.jpg').basename('.jpg'); 568 | // 'baz' 569 | ``` 570 | 571 | 572 | 573 | 574 | ```js 575 | const { Str } = require('laravel-js-str'); 576 | 577 | let slice = Str.of('This is my name').before('my name'); 578 | // 'This is ' 579 | ``` 580 | 581 | 582 | 583 | 584 | ```js 585 | const { Str } = require('laravel-js-str'); 586 | 587 | let slice = Str.of('This is my name').beforeLast('is'); 588 | // 'This ' 589 | ``` 590 | 591 | 592 | 593 | 594 | ```js 595 | const { Str } = require('laravel-js-str'); 596 | 597 | let converted = Str.of('foo_bar').camel(); 598 | // fooBar 599 | ``` 600 | 601 | 602 | 603 | 604 | ```js 605 | const { Str } = require('laravel-js-str'); 606 | 607 | let contains = Str.of('This is my name').contains('my'); 608 | // true 609 | ``` 610 | 611 | 612 | 613 | 614 | ```js 615 | const { Str } = require('laravel-js-str'); 616 | 617 | let contains = Str.of('This is my name').contains(['my', foo']); 618 | // true 619 | ``` 620 | 621 | 622 | 623 | 624 | ```js 625 | const { Str } = require('laravel-js-str'); 626 | 627 | let containsAll = Str.of('This is my name').containsAll(['my', 'name']); 628 | // true 629 | ``` 630 | 631 | 632 | 633 | 634 | ```js 635 | const { Str } = require('laravel-js-str'); 636 | 637 | let string = Str.of('/foo/bar/baz').dirname(); 638 | // '/foo/bar' 639 | ``` 640 | 641 | 642 | 643 | 644 | ```js 645 | const { Str } = require('laravel-js-str'); 646 | 647 | let string = Str.of('/foo/bar/baz').dirname(2); 648 | // '/foo' 649 | ``` 650 | 651 | 652 | 653 | 654 | ```js 655 | const { Str } = require('laravel-js-str'); 656 | 657 | let result = Str.of('This is my name').endsWith('name'); 658 | // true 659 | ``` 660 | 661 | 662 | 663 | 664 | ```js 665 | const { Str } = require('laravel-js-str'); 666 | 667 | let result = Str.of('This is my name').endsWith(['name', 'foo']); 668 | // true 669 | 670 | result = Str.of('This is my name').endsWith(['this', 'foo']); 671 | // false 672 | ``` 673 | 674 | 675 | 676 | ```js 677 | const { Str } = require('laravel-js-str'); 678 | 679 | let result = Str.of('Laravel').exactly('Laravel'); 680 | // true 681 | ``` 682 | 683 | 684 | 685 | [Collect.js](https://npmjs.com/package/collect.js) 686 | ```js 687 | const { Str } = require('laravel-js-str'); 688 | 689 | let collection = Str.of('foo bar baz').explode(' '); 690 | // collect(['foo', 'bar', 'baz']) 691 | ``` 692 | 693 | 694 | 695 | 696 | ```js 697 | const { Str } = require('laravel-js-str'); 698 | 699 | let adjusted = Str.of('this/string').finish('/'); 700 | // this/string/ 701 | 702 | adjusted = Str.of('this/string/').finish('/'); 703 | 704 | // this/string/ 705 | ``` 706 | 707 | 708 | 709 | 710 | ```js 711 | const { Str } = require('laravel-js-str'); 712 | 713 | let matches = Str.of('foobar').is('foo*'); 714 | // true 715 | 716 | matches = Str.of('foobar').is('baz*'); 717 | 718 | // false 719 | ``` 720 | 721 | 722 | 723 | **isAscii is Experimental, not positive its correct in all cases** 724 | ```js 725 | const { Str } = require('laravel-js-str'); 726 | 727 | let result = Str.of('Taylor').isAscii(); 728 | // true 729 | 730 | result = Str.of('ü').isAcii(); 731 | 732 | // false 733 | ``` 734 | 735 | 736 | 737 | 738 | ```js 739 | const { Str } = require('laravel-js-str'); 740 | 741 | let result = Str.of(' ').trim().isEmpty(); 742 | // true 743 | 744 | result = Str.of('Laravel').trim().isEmpty(); 745 | 746 | // false 747 | ``` 748 | 749 | 750 | 751 | 752 | ```js 753 | const { Str } = require('laravel-js-str'); 754 | 755 | let result = Str.of(' ').trim().isNotEmpty(); 756 | // false 757 | 758 | result = Str.of('Laravel').trim().isNotEmpty(); 759 | 760 | // true 761 | ``` 762 | 763 | 764 | 765 | 766 | ```js 767 | const { Str } = require('laravel-js-str'); 768 | 769 | let converted = Str.of('fooBar').kebab(); 770 | // foo-bar 771 | ``` 772 | 773 | 774 | 775 | 776 | ```js 777 | const { Str } = require('laravel-js-str'); 778 | 779 | let length = Str.of('Laravel').length(); 780 | // 7 781 | ``` 782 | 783 | 784 | 785 | 786 | ```js 787 | const { Str } = require('laravel-js-str'); 788 | 789 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20); 790 | // The quick brown fox... 791 | ``` 792 | 793 | 794 | 795 | 796 | ```js 797 | const { Str } = require('laravel-js-str'); 798 | 799 | let truncated = Str.of('The quick brown fox jumps over the lazy dog').limit(20, ' (...)'); 800 | // The quick brown fox (...) 801 | ``` 802 | 803 | 804 | 805 | 806 | ```js 807 | const { Str } = require('laravel-js-str'); 808 | 809 | let result = Str.of('LARAVEL').lower(); 810 | // 'laravel' 811 | ``` 812 | 813 | 814 | 815 | 816 | ```js 817 | const { Str } = require('laravel-js-str'); 818 | 819 | let string = Str.of(' Laravel ').ltrim(); 820 | // 'Laravel ' 821 | 822 | string = Str.of('/Laravel/').ltrim('/'); 823 | 824 | // 'Laravel/' 825 | ``` 826 | 827 | 828 | 829 | 830 | ```js 831 | const { Str } = require('laravel-js-str'); 832 | 833 | let result = Str.of('foo bar').match('/bar/'); 834 | // 'bar' 835 | 836 | result = Str.of('foo bar').match('/foo (.*)/'); 837 | 838 | // 'bar' 839 | ``` 840 | 841 | 842 | 843 | __Match All Coming Soon__ 844 | ``` 845 | const { Str } = require('laravel-js-str'); 846 | 847 | let result = Str.of('bar foo bar').matchAll('/bar/'); 848 | // collect(['bar', 'bar']) 849 | ``` 850 | ``` 851 | const { Str } = require('laravel-js-str'); 852 | 853 | let result = Str.of('bar fun bar fly').matchAll('/f(\w*)/'); 854 | // collect(['un', 'ly']); 855 | 856 | 857 | ``` 858 | 859 | 860 | 861 | 862 | ```js 863 | const { Str } = require('laravel-js-str'); 864 | 865 | let plural = Str.of('car').plural(); 866 | // cars 867 | 868 | plural = Str.of('child').plural(); 869 | 870 | // children 871 | ``` 872 | 873 | 874 | 875 | 876 | ```js 877 | const { Str } = require('laravel-js-str'); 878 | 879 | let plural = Str.of('child').plural(2); 880 | // children 881 | 882 | plural = Str.of('child').plural(1); 883 | 884 | // child 885 | ``` 886 | 887 | 888 | 889 | 890 | ```js 891 | const { Str } = require('laravel-js-str'); 892 | 893 | let string = Str.of('Framework').prepend('Laravel '); 894 | // Laravel Framework 895 | ``` 896 | 897 | 898 | 899 | 900 | ```js 901 | const { Str } = require('laravel-js-str'); 902 | 903 | let replaced = Str.of('Laravel 6.x').replace('6.x', '7.x'); 904 | // Laravel 7.x 905 | ``` 906 | 907 | 908 | 909 | 910 | ```js 911 | const { Str } = require('laravel-js-str'); 912 | 913 | let string = 'The event will take place between ? and ?'; 914 | let replaced = Str.of(string).replaceArray('?', ['8:30', '9:00']); 915 | // The event will take place between 8:30 and 9:00 916 | ``` 917 | 918 | 919 | 920 | 921 | ```js 922 | const { Str } = require('laravel-js-str'); 923 | 924 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceFirst('the', 'a'); 925 | // a quick brown fox jumps over the lazy dog 926 | ``` 927 | 928 | 929 | 930 | 931 | ```js 932 | const { Str } = require('laravel-js-str'); 933 | 934 | let replaced = Str.of('the quick brown fox jumps over the lazy dog').replaceLast('the', 'a'); 935 | // the quick brown fox jumps over a lazy dog 936 | ``` 937 | 938 | 939 | 940 | 941 | ```js 942 | const { Str } = require('laravel-js-str'); 943 | 944 | let replaced = Str.of('(+1) 501-555-1000').replace('/[^A-Za-z0-9]++/', ''); 945 | 946 | //'15015551000' 947 | ``` 948 | 949 | 950 | 951 | ```js 952 | 953 | ``` 954 | 955 | 956 | ```js 957 | const { Str } = require('laravel-js-str'); 958 | 959 | let string = Str.of(' Laravel ').rtrim(); 960 | // ' Laravel' 961 | 962 | string = Str.of('/Laravel/').rtrim('/'); 963 | 964 | // '/Laravel' 965 | ``` 966 | 967 | 968 | 969 | 970 | ```js 971 | const { Str } = require('laravel-js-str'); 972 | 973 | let singular = Str.of('cars').singular(); 974 | // car 975 | 976 | singular = Str.of('children').singular(); 977 | 978 | // child 979 | ``` 980 | 981 | 982 | 983 | 984 | ```js 985 | const { Str } = require('laravel-js-str'); 986 | 987 | let slug = Str.of('Laravel Framework').slug('-'); 988 | // laravel-framework 989 | ``` 990 | 991 | 992 | 993 | 994 | ```js 995 | const { Str } = require('laravel-js-str'); 996 | 997 | let converted = Str.of('fooBar').snake(); 998 | // foo_bar 999 | ``` 1000 | 1001 | 1002 | 1003 | 1004 | ```js 1005 | const { Str } = require('laravel-js-str'); 1006 | 1007 | let segments = Str.of('one, two, three').split('/[\s, +/'); 1008 | // collect(["one", "two", "three"]) 1009 | ``` 1010 | 1011 | 1012 | 1013 | 1014 | ```js 1015 | const { Str } = require('laravel-js-str'); 1016 | 1017 | let adjusted = Str.of('this/string').start('/'); 1018 | // /this/string 1019 | 1020 | adjusted = Str.of('/this/string').start('/'); 1021 | 1022 | // /this/string 1023 | ``` 1024 | 1025 | 1026 | 1027 | 1028 | ```js 1029 | const { Str } = require('laravel-js-str'); 1030 | 1031 | let result = Str.of('This is my name').startsWith('This'); 1032 | // true 1033 | ``` 1034 | 1035 | 1036 | 1037 | 1038 | ```js 1039 | const { Str } = require('laravel-js-str'); 1040 | 1041 | let converted = Str.of('foo_bar').studly(); 1042 | // FooBar 1043 | ``` 1044 | 1045 | 1046 | 1047 | 1048 | ```js 1049 | const { Str } = require('laravel-js-str'); 1050 | 1051 | let string = Str.of('Laravel Framework').substr(8); 1052 | // Framework 1053 | 1054 | string = Str.of('Laravel Framework').substr(8, ); 1055 | 1056 | // Frame 1057 | ``` 1058 | 1059 | 1060 | 1061 | 1062 | ```js 1063 | const { Str } = require('laravel-js-str'); 1064 | 1065 | let converted = Str.of('a nice title uses the correct case').title(); 1066 | // A Nice Title Uses The Correct Case 1067 | ``` 1068 | 1069 | 1070 | 1071 | 1072 | ```js 1073 | const { Str } = require('laravel-js-str'); 1074 | 1075 | let string = Str.of(' Laravel ').trim(); 1076 | // 'Laravel' 1077 | 1078 | string = Str.of('/Laravel/').trim('/'); 1079 | 1080 | // 'Laravel' 1081 | ``` 1082 | 1083 | 1084 | 1085 | 1086 | ```js 1087 | const { Str } = require('laravel-js-str'); 1088 | 1089 | let string = Str.of('foo bar').ucfirst(); 1090 | // Foo bar 1091 | ``` 1092 | 1093 | 1094 | 1095 | 1096 | ```js 1097 | const { Str } = require('laravel-js-str'); 1098 | 1099 | let adjusted = Str.of('laravel').upper(); 1100 | // LARAVEL 1101 | ``` 1102 | 1103 | 1104 | 1105 | 1106 | ```js 1107 | const { Str } = require('laravel-js-str'); 1108 | 1109 | let string = Str.of(' ').whenEmpty(function(string) { 1110 | return string.trim().prepend('Laravel'); 1111 | }); 1112 | 1113 | // 'Laravel' 1114 | ``` 1115 | 1116 | 1117 | 1118 | 1119 | ```js 1120 | const { Str } = require('laravel-js-str'); 1121 | 1122 | let string = Str.of('Perfectly balanced, as all things should be.').words(3, '>>>'); 1123 | // Perfectly balanced, as >>> 1124 | ``` 1125 | 1126 | 1127 | --- 1128 | 1129 | ## Playground Examples 1130 | 1131 | --- 1132 | Curious, but not 100% on whether this is what you're looking for? 1133 | 1134 | - [Laravel Illuminate/Str & Illuminate/Str::of in js (live example coming soon)](https://codepen.io/zhorton34/pen/jObRLdM) 1135 | 1136 | > **The most powerful method is Str.of('example')**, allowing us to fluently chain Str methods together 1137 | 1138 | **Example** 1139 | ```js 1140 | let { Str } = require('laravel-js-str'); 1141 | 1142 | let home = 'https://planets.com'; 1143 | let title = 'hello mars, a cool world for you to visit, maybe?'; 1144 | 1145 | let article = Str.of(title).replaceFirst(',', '') 1146 | .after('hello') 1147 | .before('for you') 1148 | .trim() 1149 | .start('/') 1150 | .finish('/') 1151 | .kebab(); 1152 | 1153 | let resource = home + article 1154 | 1155 | // resource value: 1156 | // 'https://planets.com/mars-a-cool-world/' 1157 | // 1158 | // article value: 1159 | // Stringable: { value: 'https://planets.com/mars-a-cool-world-to-visit', replace, before, after, etc... } 1160 | // 1161 | ``` 1162 | 1163 | 1164 | --- 1165 | 1166 | ## Utilization 1167 | 1168 | --- 1169 | > **The most powerful method is Str.of('example')**, allowing us to fluently chain Str methods together 1170 | 1171 | **Example** 1172 | ```js 1173 | let { Str } = require('laravel-js-str'); 1174 | 1175 | let home = 'https://planets.com'; 1176 | let title = 'hello mars, a cool world for you to visit, maybe?'; 1177 | 1178 | let article = Str.of(title).replaceFirst(',', '') 1179 | .after('hello') 1180 | .before('for you') 1181 | .trim() 1182 | .start('/') 1183 | .finish('/') 1184 | .kebab(); 1185 | 1186 | let resource = home + article 1187 | 1188 | // resource value: 1189 | // 'https://planets.com/mars-a-cool-world/' 1190 | // 1191 | // article value: 1192 | // Stringable: { value: 'https://planets.com/mars-a-cool-world-to-visit', replace, before, after, etc... } 1193 | // 1194 | ``` 1195 | 1196 | 1197 | --- 1198 | 1199 | ## Contribute 1200 | 1201 | --- 1202 | 1203 | PRs are welcomed to this project. 1204 | If you want to improve this package, add 1205 | functionality or improve the docs please feel free to submit a PR. 1206 | 1207 | 1208 | --- 1209 | 1210 | ## Security Vulnerabilities 1211 | 1212 | --- 1213 | 1214 | If you discover a security vulnerability within Clean Code Studio Packages Or Specifically within 1215 | laravel-js-str, please send an e-mail to Zachary Horton via zak@cleancode.studio. All security vulnerabilities will be promptly addressed. 1216 | 1217 | 1218 | --- 1219 | 1220 | ## Change Log 1221 | 1222 | --- 1223 | - [Release 1.0.0](#release-100) 1224 | 1225 | --- 1226 | 1227 | ### Release 1.0.0 1228 | 1229 | --- 1230 | 1231 | - Initial Release 1232 | 1233 | 1234 | --- 1235 | 1236 | ## Versioning 1237 | 1238 | --- 1239 | 1240 | > Semantic Versioning 1241 | 1242 | |Code Status|Stage|Rule|Example Version| 1243 | |---|---|---|---| 1244 | |First release|New Product|Start with 1.0.0|1.0.0| 1245 | |Backward compatible bug fixes|Patch Release|Increment the third digit|1.0.1| 1246 | |Backward compatible new features|Minor Release|Increment the middle digit and reset last digit to zero|1.1.0| 1247 | |Changes that break backward compatibility|Major Release|Increment the first digit and reset middle and last digits to zero|2.0.0| 1248 | 1249 | - [Learn More About Semantic Versioning](https://docs.npmjs.com/about-semantic-versioning) 1250 | 1251 | 1252 | --- 1253 | 1254 | ## License 1255 | 1256 | --- 1257 | 1258 | MIT © [Zachary Horton (Clean Code Studio)](https://www.youtube.com/channel/UCq0m4ebGqurYQLwD-1aYsvg) 1259 | -------------------------------------------------------------------------------- /bundler/header.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Laravel JS Str 4 | 5 | --- 6 | 7 | > _"Laravel's Illuminate\Str & Illuminate\Stringify Including Str.of() In Javascript"_ 8 | -------------------------------------------------------------------------------- /bundler/highlight.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Project Goals 4 | 5 | --- 6 | 7 | - [x] **Fluent** 8 | - [x] **Stringable** 9 | - [x] **Simplified** 10 | --- 11 | 12 | # Tinkerable Demo 13 | 14 | --- 15 | ![Code Pen Example](https://lh4.googleusercontent.com/GNH4vvaWgiG70gLrT_R4IQCTLQiuvpsMtAV0jFB6aaSD65acQXLo6cdX498XTc9RIaA9lhXLT_2vF7WElmeX=w1919-h952-rw "Package Gif Example") 16 | -------------------------------------------------------------------------------- /bundler/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Installation 4 | 5 | --- 6 | 7 | 8 | ### NPM 9 | 10 | ```bash 11 | npm install --save-dev laravel-js-str 12 | ``` 13 | 14 | ### Yarn 15 | 16 | ```bash 17 | yarn add laravel-js-str --save 18 | ``` 19 | 20 | ### CDN 21 | 22 | ```html 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /bundler/license.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## License 4 | 5 | --- 6 | 7 | MIT © [Zachary Horton (Clean Code Studio)](https://www.youtube.com/channel/UCq0m4ebGqurYQLwD-1aYsvg) 8 | -------------------------------------------------------------------------------- /bundler/security_vulnerabilities.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Security Vulnerabilities 4 | 5 | --- 6 | 7 | If you discover a security vulnerability within Clean Code Studio Packages Or Specifically within 8 | laravel-js-str, please send an e-mail to Zachary Horton via zak@cleancode.studio. All security vulnerabilities will be promptly addressed. 9 | -------------------------------------------------------------------------------- /bundler/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Setup 4 | 5 | --- 6 | 7 | **Fluent Str Manipulation is as easy as Str.of(str).after('ex').before('.').title().plural()** 8 | 9 | --- 10 | 11 | ### Node & Webpack Setup 12 | 13 | --- 14 | 15 | ```js 16 | const { Str } = require('laravel-js-helpers'); 17 | 18 | Str.of('hello world').studly().pluralStudly(); 19 | ``` 20 | 21 | ### CDN & Browser Setup 22 | 23 | ```html 24 | 25 | 26 | 31 | ``` 32 | -------------------------------------------------------------------------------- /bundler/utilization.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Utilization 4 | 5 | --- 6 | > **The most powerful method is Str.of('example')**, allowing us to fluently chain Str methods together 7 | 8 | **Example** 9 | ```js 10 | let { Str } = require('laravel-js-str'); 11 | 12 | let home = 'https://planets.com'; 13 | let title = 'hello mars, a cool world for you to visit, maybe?'; 14 | 15 | let article = Str.of(title).replaceFirst(',', '') 16 | .after('hello') 17 | .before('for you') 18 | .trim() 19 | .start('/') 20 | .finish('/') 21 | .kebab(); 22 | 23 | let resource = home + article 24 | 25 | // resource value: 26 | // 'https://planets.com/mars-a-cool-world/' 27 | // 28 | // article value: 29 | // Stringable: { value: 'https://planets.com/mars-a-cool-world-to-visit', replace, before, after, etc... } 30 | // 31 | ``` 32 | -------------------------------------------------------------------------------- /bundler/versioning.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## Versioning 4 | 5 | --- 6 | 7 | > Semantic Versioning 8 | 9 | |Code Status|Stage|Rule|Example Version| 10 | |---|---|---|---| 11 | |First release|New Product|Start with 1.0.0|1.0.0| 12 | |Backward compatible bug fixes|Patch Release|Increment the third digit|1.0.1| 13 | |Backward compatible new features|Minor Release|Increment the middle digit and reset last digit to zero|1.1.0| 14 | |Changes that break backward compatibility|Major Release|Increment the first digit and reset middle and last digits to zero|2.0.0| 15 | 16 | - [Learn More About Semantic Versioning](https://docs.npmjs.com/about-semantic-versioning) 17 | -------------------------------------------------------------------------------- /dist/str/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } 4 | 5 | function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 6 | 7 | function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } 8 | 9 | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } 10 | 11 | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } 12 | 13 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 14 | 15 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 16 | 17 | function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } 18 | 19 | function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 20 | 21 | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } 22 | 23 | function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } 24 | 25 | function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 26 | 27 | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 32 | 33 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 34 | 35 | var _uuid = 'uuid', 36 | uuidv4 = _uuid.v4; 37 | 38 | var _require = require('locutus/php/pcre'), 39 | preg_match = _require.preg_match; 40 | 41 | var _require2 = require('locutus/php/ctype'), 42 | ctype_lower = _require2.ctype_lower; 43 | 44 | var Stringable = require('../stringable/index.js'); 45 | 46 | var _require3 = require('../pluralizer/index.js'), 47 | Pluralizer = _require3.Pluralizer; 48 | 49 | var _require4 = require('locutus/php/strings'), 50 | explode = _require4.explode, 51 | substr_count = _require4.substr_count; 52 | 53 | var Str = /*#__PURE__*/function () { 54 | function Str() { 55 | _classCallCheck(this, Str); 56 | } 57 | 58 | _createClass(Str, null, [{ 59 | key: "of", 60 | 61 | /** 62 | * The cache of snake-cased words 63 | * 64 | * @var object 65 | */ 66 | 67 | /** 68 | * The cache of camel-cased words 69 | * 70 | * @var object 71 | */ 72 | 73 | /** 74 | * The cache of studly-cased words 75 | * 76 | * @var object 77 | */ 78 | 79 | /** 80 | * The callback that should be used to generate UUIDs. 81 | * 82 | * @var callback 83 | */ 84 | 85 | /** 86 | * Get a new stringable object from the given string. 87 | * 88 | * @param string string 89 | * @return Stringable 90 | */ 91 | value: function of(string) { 92 | return new Stringable(string); 93 | } 94 | /** 95 | * Return the remainder of a string after the first occurrence of a given value 96 | * 97 | * @param subject 98 | * @param search 99 | * 100 | * @return string 101 | */ 102 | 103 | }, { 104 | key: "after", 105 | value: function after(subject) { 106 | var search = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 107 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(subject.indexOf(search) + search.length); 108 | } 109 | /** 110 | * Returns the remainder of a string after the last occurrence of a given value 111 | * 112 | * @param subject 113 | * @param search 114 | * 115 | * @return string 116 | */ 117 | 118 | }, { 119 | key: "afterLast", 120 | value: function afterLast(subject) { 121 | var search = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 122 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(subject.lastIndexOf(search) + search.length); 123 | } 124 | /** 125 | * Transliterate a UTF-8 value to ASCII. 126 | * 127 | * @param value 128 | * @param language 129 | * 130 | * @return string 131 | */ 132 | 133 | }, { 134 | key: "ascii", 135 | value: function ascii() { 136 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 137 | var language = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en'; 138 | return String.fromCharCode.apply(String, _toConsumableArray(value.split('').map(function (character) { 139 | return character.charCodeAt(0); 140 | }))); 141 | } 142 | /** 143 | * Get the portion of a string before the first occurrence of a given value 144 | * 145 | * @param subject 146 | * @param search 147 | * 148 | * @return string 149 | */ 150 | 151 | }, { 152 | key: "before", 153 | value: function before(subject) { 154 | var search = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 155 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(0, subject.indexOf(search)); 156 | } 157 | /** 158 | * Get the portion of a string before the last occurrence of a given value 159 | * 160 | * @param subject 161 | * @param search 162 | * 163 | * @return string 164 | */ 165 | 166 | }, { 167 | key: "beforeLast", 168 | value: function beforeLast(subject) { 169 | var search = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 170 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(0, subject.lastIndexOf(search)); 171 | } 172 | /** 173 | * Get the portion of a string between two given values 174 | * 175 | * @param subject 176 | * @param at 177 | * @param to 178 | * 179 | * @return string 180 | */ 181 | 182 | }, { 183 | key: "between", 184 | value: function between(subject) { 185 | var at = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 186 | var to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; 187 | return subject.indexOf(at) === -1 || subject.indexOf(to) === -1 ? subject : Str.beforeLast(Str.after(subject, at), to); 188 | } 189 | /** 190 | * Convert a value to camel case. 191 | * 192 | * @param value 193 | * 194 | * @return string 195 | */ 196 | 197 | }, { 198 | key: "camel", 199 | value: function camel() { 200 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 201 | 202 | if (typeof Str.camelCache[value] !== 'undefined') { 203 | return Str.camelCache[value]; 204 | } 205 | 206 | var studly = Str.studly(value); 207 | return Str.camelCache[value] = "".concat(studly[0].toLowerCase()).concat(studly.slice(1)); 208 | } 209 | /** 210 | * Determine if a given string contains a given substring. 211 | * 212 | * @param haystack 213 | * @param needles 214 | * 215 | * @return boolean 216 | */ 217 | 218 | }, { 219 | key: "contains", 220 | value: function contains(haystack) { 221 | var needles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 222 | return Array.isArray(needles) ? needles.some(function (needle) { 223 | return haystack.includes(needle); 224 | }) : haystack.includes(needles); 225 | } 226 | /** 227 | * Determine if a given string contains all array values 228 | * 229 | * @param haystack 230 | * @param needles[] 231 | * 232 | * @return boolean 233 | */ 234 | 235 | }, { 236 | key: "containsAll", 237 | value: function containsAll(haystack) { 238 | var needles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 239 | return needles.every(function (needle) { 240 | return haystack.includes(needle); 241 | }); 242 | } 243 | /** 244 | * Determine if a given string ends with a given substring 245 | * 246 | * @param haystack 247 | * @param needles 248 | * 249 | * @return boolean 250 | */ 251 | 252 | }, { 253 | key: "endsWith", 254 | value: function endsWith(haystack) { 255 | var needles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 256 | return Array.isArray(needles) ? needles.some(function (needle) { 257 | return haystack.substr(-needle.length) === needle; 258 | }) : haystack.substr(-needles.length) === needles; 259 | } 260 | /** 261 | * Cap a string with a single instance of a given value if it doesnt already end with it 262 | * 263 | * @param value 264 | * @param cap 265 | * 266 | * @return string 267 | */ 268 | 269 | }, { 270 | key: "finish", 271 | value: function finish(value, cap) { 272 | return Str.endsWith(value, cap) ? value : "".concat(value).concat(cap); 273 | } 274 | /** 275 | * Determine if a given string matches a given pattern 276 | * 277 | * @param pattern 278 | * @param value 279 | * 280 | * @return boolean 281 | */ 282 | 283 | }, { 284 | key: "is", 285 | value: function is(pattern, value) { 286 | var patterns = Array.isArray(pattern) ? pattern : [pattern]; 287 | return patterns.some(function (pattern) { 288 | if (value === pattern) return true;else if (pattern.includes('*') === false) return new RegExp(pattern).test(value);else if (pattern.includes('*')) return new RegExp(pattern.replace(/\*/g, '.*')).test(value); 289 | }); 290 | } 291 | /** 292 | * Determine if a given string is 7 bit ASCII 293 | * 294 | * @param value 295 | * @returns boolean 296 | */ 297 | 298 | }, { 299 | key: "isAscii", 300 | value: function isAscii(value) { 301 | // extended Ascii pattern /^[\x00-\xFF]*$/ 302 | // 128 char Ascii pattern /^[\x00-\x7F]*$/ 303 | return /^[\x00-\xFF]*$/.test(String(value)); 304 | } 305 | /** 306 | * Determine if a given string is valid UUID. 307 | * 308 | * @param value 309 | * 310 | * @return boolean 311 | */ 312 | 313 | }, { 314 | key: "isUuid", 315 | value: function isUuid(value) { 316 | if (typeof value !== 'string') { 317 | return false; 318 | } 319 | 320 | return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', value) > 0; 321 | } 322 | /** 323 | * Convert a string to kebab case. 324 | * 325 | * @param value 326 | * 327 | * @return string 328 | */ 329 | 330 | }, { 331 | key: "kebab", 332 | value: function kebab(value) { 333 | return Str.snake(value, '-'); 334 | } 335 | /** 336 | * Convert a string to snake case. 337 | * 338 | * @param value 339 | * @param delimiter 340 | * 341 | * @return string 342 | */ 343 | 344 | }, { 345 | key: "snake", 346 | value: function snake(value) { 347 | var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '_'; 348 | var key = value; 349 | 350 | if (typeof Str.snakeCache !== 'undefined') { 351 | if (typeof Str.snakeCache[delimiter] !== 'undefined') { 352 | return Str.snakeCache[key][delimiter]; 353 | } 354 | } 355 | 356 | if (!ctype_lower(value)) { 357 | Str.snakeCache[key] = _objectSpread(_objectSpread({}, Str.snakeCache[key] || {}), {}, _defineProperty({}, delimiter, value.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(function (x) { 358 | return x.toLowerCase(); 359 | }).join(delimiter))); 360 | return Str.snakeCache[key][delimiter]; 361 | } 362 | 363 | Str.snakeCache[key] = _objectSpread(_objectSpread({}, Str.snakeCache[key] || {}), {}, _defineProperty({}, delimiter, value)); 364 | return Str.snakeCache[key][delimiter]; 365 | } 366 | /** 367 | * Return the length of the given string 368 | * 369 | * @param value 370 | * @param encoding 371 | * 372 | * @return int 373 | * 374 | * @TODO add encoding option 375 | */ 376 | 377 | }, { 378 | key: "length", 379 | value: function length() { 380 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 381 | var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 382 | return value.length; 383 | } 384 | /** 385 | * Limit the number of characters in a string 386 | * 387 | * @param value 388 | * @param limit 389 | * @param end 390 | * 391 | * @return string 392 | */ 393 | 394 | }, { 395 | key: "limit", 396 | value: function limit() { 397 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 398 | 399 | var _limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; 400 | 401 | var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '...'; 402 | return value.length < _limit ? value : value.slice(0, _limit) + end; 403 | } 404 | /** 405 | * Convert the given string to lower-case. 406 | * 407 | * @param value 408 | * 409 | * @return string 410 | */ 411 | 412 | }, { 413 | key: "lower", 414 | value: function lower() { 415 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 416 | return value.toLocaleLowerCase(); 417 | } 418 | /** 419 | * Limit the number of words in a string. 420 | * 421 | * @param value 422 | * @param words 423 | * @param end 424 | * 425 | * @return string 426 | */ 427 | 428 | }, { 429 | key: "words", 430 | value: function words() { 431 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 432 | 433 | var _words = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; 434 | 435 | var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '...'; 436 | var word = value.split(' '); 437 | return word.length <= _words ? value : word.slice(0, _words).join(" ") + end; 438 | } 439 | /** 440 | * Parse a Class[@]method style callback into class and method. 441 | * 442 | * @param callback 443 | * @param fallback 444 | * 445 | * @return array 446 | */ 447 | 448 | }, { 449 | key: "parseCallback", 450 | value: function parseCallback(callback) { 451 | var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 452 | return Str.contains(callback, '@') ? explode('@', callback, 2) : [callback, fallback]; 453 | } 454 | /** 455 | * Get the plural form of an english word 456 | * 457 | * @param value 458 | * @param count 459 | * 460 | * @return string 461 | */ 462 | 463 | }, { 464 | key: "plural", 465 | value: function plural(value) { 466 | var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; 467 | return Pluralizer.plural(value, count); 468 | } 469 | /** 470 | * Pluralize the last word of an English, studly caps case string. 471 | * 472 | * @param value 473 | * @param count 474 | * 475 | * @return string 476 | */ 477 | 478 | }, { 479 | key: "pluralStudly", 480 | value: function pluralStudly(value) { 481 | var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; 482 | 483 | var _value$split = value.split(/(?=[A-Z][^A-Z]+$)/), 484 | _value$split2 = _slicedToArray(_value$split, 2), 485 | until = _value$split2[0], 486 | last_word = _value$split2[1]; 487 | 488 | return until + Str.plural(last_word, count); 489 | } 490 | /** 491 | * Generate a more truly "random" alpha-numeric string. 492 | * 493 | * @param length 494 | * 495 | * @return string 496 | */ 497 | 498 | }, { 499 | key: "random", 500 | value: function random() { 501 | var length = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 16; 502 | var random = ''; 503 | var alpha_numeric = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; 504 | 505 | for (var i = 0; i < length; i++) { 506 | var character_index = Math.floor(Math.random() * Math.floor(alpha_numeric.length)); 507 | random += alpha_numeric.slice(character_index, character_index + 1); 508 | } 509 | 510 | return random; 511 | } 512 | /** 513 | * Replace a given value in the string sequentially with an array. 514 | * 515 | * @param search 516 | * @param replace 517 | * @param subject 518 | * 519 | * @return string 520 | */ 521 | 522 | }, { 523 | key: "replaceArray", 524 | value: function replaceArray(search) { 525 | var replace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 526 | var subject = arguments.length > 2 ? arguments[2] : undefined; 527 | 528 | if (Array.isArray(replace) === false) { 529 | throw Error("Str.replaceArray requires that parameter two (replace) is an array. Passed In: " + JSON.stringify(replace)); 530 | } 531 | 532 | return replace.reduce(function (value, replacer) { 533 | return value.replace(search, replacer); 534 | }, subject); 535 | } 536 | /** 537 | * Replace the first occurrence of a given value in the string. 538 | * 539 | * @param search 540 | * @param replace 541 | * @param subject 542 | * 543 | * @return string 544 | */ 545 | 546 | }, { 547 | key: "replaceFirst", 548 | value: function replaceFirst(search, replace, subject) { 549 | if (search === '') { 550 | return subject; 551 | } 552 | 553 | var search_index = subject.indexOf(search); 554 | 555 | if (search_index === -1) { 556 | return subject; 557 | } 558 | 559 | var start = subject.substr(0, search_index); 560 | var after = subject.substr(search_index + search.length, subject.length); 561 | return "".concat(start).concat(replace).concat(after); 562 | } 563 | /** 564 | * Replace the last occurrence of a given value in the string 565 | * 566 | * @param search 567 | * @param replace 568 | * @param subject 569 | * 570 | * @returns string 571 | */ 572 | 573 | }, { 574 | key: "replaceLast", 575 | value: function replaceLast(search, replace, subject) { 576 | if (search === '') { 577 | return subject; 578 | } 579 | 580 | var search_index = subject.lastIndexOf(search); 581 | 582 | if (search_index === -1) { 583 | return subject; 584 | } 585 | 586 | var start = subject.substr(0, search_index); 587 | var after = subject.substr(search_index + search.length, subject.length); 588 | return "".concat(start).concat(replace).concat(after); 589 | } 590 | /** 591 | * Begin a string with a single instance of a given value. 592 | * 593 | * @param value 594 | * @param prefix 595 | * 596 | * @return string 597 | */ 598 | 599 | }, { 600 | key: "start", 601 | value: function start(value, prefix) { 602 | return Str.startsWith(value, prefix) ? value : "".concat(prefix).concat(value); 603 | } 604 | /** 605 | * Convert a value to studly caps case 606 | * 607 | * @param value 608 | * 609 | * @return string 610 | */ 611 | 612 | }, { 613 | key: "studly", 614 | value: function studly(value) { 615 | var key = value; 616 | 617 | if (typeof Str.studlyCache[key] !== 'undefined') { 618 | return Str.studlyCache[key]; 619 | } 620 | 621 | return Str.studlyCache[key] = value.replace(/_/g, ' ').replace(/-/g, ' ').split(' ').reduce(function (str, word) { 622 | return "".concat(str).concat(word[0].toUpperCase()).concat(word.slice(1)); 623 | }, ''); 624 | } 625 | /** 626 | * Convert the given string to upper-case 627 | * 628 | * @param value 629 | * 630 | * @return string 631 | */ 632 | 633 | }, { 634 | key: "upper", 635 | value: function upper(value) { 636 | return value.toLocaleUpperCase(); 637 | } 638 | /** 639 | * Convert the given string to title case. 640 | * 641 | * @param value 642 | * 643 | * @return string 644 | */ 645 | 646 | }, { 647 | key: "title", 648 | value: function title(value) { 649 | return Str.snake(value).split('_').map(function (word) { 650 | return Str.ucfirst(word); 651 | }).join(' '); 652 | } 653 | /** 654 | * Get the singular form of an English word. 655 | * 656 | * @param value 657 | * @return string 658 | */ 659 | 660 | }, { 661 | key: "singular", 662 | value: function singular(value) { 663 | return Pluralizer.singular(value); 664 | } 665 | /** 666 | * Generate a URL friendly "slug" from a given string. 667 | * 668 | * @param title 669 | * @param separator 670 | * @param language 671 | * 672 | * @return string 673 | */ 674 | 675 | }, { 676 | key: "slug", 677 | value: function slug(title) { 678 | var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '-'; 679 | var language = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'en'; 680 | title = title.toLocaleString(); 681 | var slug = Str.snake(title.replace(/@/g, '_at_')).replace(/_/g, separator).trim(); 682 | return slug[0] === separator ? slug.slice(1, slug.length) : slug; 683 | } 684 | /** 685 | * Determine if a given string starts with a given substring 686 | * 687 | * @param haystack 688 | * @param needles 689 | * 690 | * @return boolean 691 | */ 692 | 693 | }, { 694 | key: "startsWith", 695 | value: function startsWith(haystack) { 696 | var needles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 697 | return Array.isArray(needles) ? needles.some(function (needle) { 698 | return haystack.startsWith(needle); 699 | }) : haystack.substr(0, needles.length) === needles; 700 | } 701 | /** 702 | * Returns the portion of string specified by the start and length parameters 703 | * 704 | * @param string 705 | * @param start 706 | * @param length 707 | * 708 | * @return string 709 | */ 710 | 711 | }, { 712 | key: "substr", 713 | value: function substr(string, start) { 714 | var length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 715 | return string.slice(start, start + length); 716 | } 717 | /** 718 | * Returns the number of substring occurrences 719 | * 720 | * @param haystack 721 | * @param needle 722 | * @param offset 723 | * @param length 724 | * 725 | * @return int 726 | */ 727 | 728 | }, { 729 | key: "substrCount", 730 | value: function substrCount(haystack, needle, offset) { 731 | var length = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 732 | 733 | if (length === null) { 734 | return substr_count(haystack, needle, offset); 735 | } else { 736 | return substr_count(haystack, needle, offset, length); 737 | } 738 | } 739 | /** 740 | * Make a strings first character upper case. 741 | * 742 | * @param value 743 | * 744 | * @return value 745 | */ 746 | 747 | }, { 748 | key: "ucfirst", 749 | value: function ucfirst() { 750 | var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 751 | if (value.length === 0) return value; 752 | if (value.length === 1) return value[0].toUpperCase(); 753 | return value[0].toUpperCase() + value.slice(1); 754 | } 755 | /** 756 | * @TODO orderedUUID 757 | * (Datetime > Decimal > Hex)-(variant)->(uuidv4 version)-(uuidv4 variant) 758 | * @see https://itnext.io/laravel-the-mysterious-ordered-uuid-29e7500b4f8 759 | **/ 760 | // 761 | // /** 762 | // * Generate a time-ordered UUID (version 4). 763 | // * 764 | // * @return uuid 765 | // */ 766 | // static orderedUuid() { 767 | // if (typeof Str.uuidFactory !== 'undefined') { 768 | // return Str.uuidFactory(); 769 | // } 770 | // } 771 | 772 | /** 773 | * Generate a UUID (version 4). 774 | * 775 | * @return string 776 | */ 777 | 778 | }, { 779 | key: "uuid", 780 | value: function uuid() { 781 | return typeof Str.uuidFactory === 'undefined' ? uuidv4() : Str.uuidFactory(); 782 | } 783 | /** 784 | * Set the callable that will be used to generate UUIDs. 785 | * 786 | * @param factory 787 | * 788 | * @return void 789 | */ 790 | 791 | }, { 792 | key: "createUuidsUsing", 793 | value: function createUuidsUsing() { 794 | var factory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 795 | 796 | if (typeof factory !== 'function' && factory !== null) { 797 | throw Error('create uuidsUsing only excepts functions.'); 798 | } 799 | 800 | Str.uuidFactory = factory; 801 | } 802 | /** 803 | * Indicate that UUIDs should be created normally and not using a custom factory. 804 | * 805 | * @return void 806 | */ 807 | 808 | }, { 809 | key: "createUuidsNormally", 810 | value: function createUuidsNormally() { 811 | Str.uuidFactory = null; 812 | } 813 | }]); 814 | 815 | return Str; 816 | }(); 817 | 818 | Str.snakeCache = {}; 819 | Str.camelCache = {}; 820 | Str.studlyCache = {}; 821 | module.exports.Str = Str; -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | 2 | const { readdirSync } = require('fs'); 3 | 4 | module.exports = { 5 | title: 'Laravel JS String', 6 | description: 'Laravel Illuminate Str within Javascript', 7 | themeConfig: { 8 | nav: [ 9 | { text: 'Home', link: '/' }, 10 | { text: 'Installation', link: '/installation.md' }, 11 | { text: 'Usage', link: '/usage.md' }, 12 | { text: 'API', link: '/api.md' }, 13 | { text: 'GitHub', link: 'https://github.com/zhorton34/laravel-js-str' }, 14 | ], 15 | sidebar: [{ 16 | title: 'Get started', 17 | collapsable: false, 18 | children: [ 19 | 'installation', 20 | 'usage', 21 | ], 22 | }, { 23 | title: 'API', 24 | collapsable: false, 25 | children: readdirSync('docs/api', 'utf-8').map(file => `/api/${file}`), 26 | }], 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /docs/api.md: -------------------------------------------------------------------------------- 1 | # Laravel Illuminate Str (Utilizable in Javascript) 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel-js-str", 3 | "version": "1.0.3", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "all": "npm run build && npm test", 8 | "pretest": "npm run transpile", 9 | "test": "mocha test/tests.js", 10 | "transpile": "babel src --quiet --out-dir dist", 11 | "readme": "node bundler/bundle.js", 12 | "bundle": "webpack-cli dist/index.js --output build/index.js --mode production --output-library laravelJsStr", 13 | "uglify": "uglifyjs build/index.js --compress --mangle --output build/index.min.js", 14 | "build": "npm run transpile && npm run bundle && npm run uglify && npm run readme", 15 | "coverage": "npm run transpile && nyc mocha test/tests.js", 16 | "reporter": "nyc report --reporter=html", 17 | "docs:dev": "vuepress dev docs", 18 | "docs:build": "vuepress build docs", 19 | "prepublishOnly": "npm run all" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/zhorton34/laravel-js-str.git" 24 | }, 25 | "keywords": [ 26 | "laravel", 27 | "js", 28 | "str", 29 | "javascript strings", 30 | "fluent strings", 31 | "strings", 32 | "laraveljs strings", 33 | "str", 34 | "js stringable", 35 | "js stringify", 36 | "stringified", 37 | "strings", 38 | "text", 39 | "words", 40 | "string-package", 41 | "laravel strings", 42 | "illuminate str", 43 | "illuminate fluent", 44 | "illuminate stringify", 45 | "laraveljs", 46 | "illuminate js" 47 | ], 48 | "author": "Zachary Horton", 49 | "license": "MIT", 50 | "bugs": { 51 | "url": "https://github.com/zhorton34/laravel-js-str/issues" 52 | }, 53 | "homepage": "https://github.com/zhorton34/laravel-js-str#readme", 54 | "babel": { 55 | "presets": [ 56 | "@babel/preset-env" 57 | ], 58 | "plugins": [ 59 | "transform-class-properties" 60 | ] 61 | }, 62 | "dependencies": { 63 | "collect.js": "^4.25.0", 64 | "pluralize": "^8.0.0", 65 | "locutus": "^2.0.11" 66 | }, 67 | "devDependencies": { 68 | "@babel/cli": "^7.2.3", 69 | "@babel/core": "^7.2.2", 70 | "@babel/polyfill": "^7.8.3", 71 | "@babel/preset-env": "^7.9.6", 72 | "babel-plugin-transform-class-properties": "^6.24.1", 73 | "benchmark": "^2.1.0", 74 | "chai": "^4.2.0", 75 | "hoax.js": "^1.0.0", 76 | "mocha": "^3.5.2", 77 | "nyc": "^11.0.2", 78 | "uglify-js": "^3.2.2", 79 | "uuid": "^8.1.0", 80 | "webpack": "^4.43.0", 81 | "webpack-cli": "^3.3.11" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { v4: uuidv4 } = 'uuid'; 5 | const pluralize = require('pluralize'); 6 | const { collect } = require('collect.js'); 7 | const preg_match = require('locutus/php/pcre/preg_match.js'); 8 | const ctype_lower = require('locutus/php/ctype/ctype_lower.js'); 9 | const substr_count = require('locutus/php/strings/substr_count.js'); 10 | 11 | function str_replace (search, replace, subject, countObj) { 12 | let i = 0 13 | let j = 0 14 | let temp = '' 15 | let repl = '' 16 | let sl = 0 17 | let fl = 0 18 | let f = [].concat(search) 19 | let r = [].concat(replace) 20 | let s = subject 21 | let ra = Object.prototype.toString.call(r) === '[object Array]' 22 | let sa = Object.prototype.toString.call(s) === '[object Array]' 23 | s = [].concat(s) 24 | 25 | let $global = (typeof window !== 'undefined' ? window : global) 26 | $global.$locutus = $global.$locutus || {} 27 | let $locutus = $global.$locutus 28 | $locutus.php = $locutus.php || {} 29 | 30 | if (typeof (search) === 'object' && typeof (replace) === 'string') { 31 | temp = replace 32 | replace = [] 33 | for (i = 0; i < search.length; i += 1) { 34 | replace[i] = temp 35 | } 36 | temp = '' 37 | r = [].concat(replace) 38 | ra = Object.prototype.toString.call(r) === '[object Array]' 39 | } 40 | 41 | if (typeof countObj !== 'undefined') { 42 | countObj.value = 0 43 | } 44 | 45 | for (i = 0, sl = s.length; i < sl; i++) { 46 | if (s[i] === '') { 47 | continue 48 | } 49 | for (j = 0, fl = f.length; j < fl; j++) { 50 | temp = s[i] + '' 51 | repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0] 52 | s[i] = (temp).split(f[j]).join(repl) 53 | if (typeof countObj !== 'undefined') { 54 | countObj.value += ((temp.split(f[j])).length - 1) 55 | } 56 | } 57 | } 58 | return sa ? s : s[0] 59 | }; 60 | 61 | function explode (delimiter, string, limit) { 62 | if (arguments.length < 2 || 63 | typeof delimiter === 'undefined' || 64 | typeof string === 'undefined') { 65 | return null 66 | } 67 | if (delimiter === '' || 68 | delimiter === false || 69 | delimiter === null) { 70 | return false 71 | } 72 | if (typeof delimiter === 'function' || 73 | typeof delimiter === 'object' || 74 | typeof string === 'function' || 75 | typeof string === 'object') { 76 | return { 77 | 0: '' 78 | } 79 | } 80 | if (delimiter === true) { 81 | delimiter = '1' 82 | } 83 | 84 | // Here we go... 85 | delimiter += '' 86 | string += '' 87 | 88 | var s = string.split(delimiter) 89 | 90 | if (typeof limit === 'undefined') return s 91 | 92 | // Support for limit 93 | if (limit === 0) limit = 1 94 | 95 | // Positive limit 96 | if (limit > 0) { 97 | if (limit >= s.length) { 98 | return s 99 | } 100 | return s 101 | .slice(0, limit - 1) 102 | .concat([s.slice(limit - 1) 103 | .join(delimiter) 104 | ]) 105 | } 106 | 107 | // Negative limit 108 | if (-limit >= s.length) { 109 | return [] 110 | } 111 | 112 | s.splice(s.length + limit); 113 | return s 114 | }; 115 | function trim (str, charlist) { 116 | 117 | var whitespace = [ 118 | ' ', 119 | '\n', 120 | '\r', 121 | '\t', 122 | '\f', 123 | '\x0b', 124 | '\xa0', 125 | '\u2000', 126 | '\u2001', 127 | '\u2002', 128 | '\u2003', 129 | '\u2004', 130 | '\u2005', 131 | '\u2006', 132 | '\u2007', 133 | '\u2008', 134 | '\u2009', 135 | '\u200a', 136 | '\u200b', 137 | '\u2028', 138 | '\u2029', 139 | '\u3000' 140 | ].join('') 141 | var l = 0 142 | var i = 0 143 | str += '' 144 | 145 | if (charlist) { 146 | whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1') 147 | } 148 | 149 | l = str.length 150 | for (i = 0; i < l; i++) { 151 | if (whitespace.indexOf(str.charAt(i)) === -1) { 152 | str = str.substring(i) 153 | break 154 | } 155 | } 156 | 157 | l = str.length 158 | for (i = l - 1; i >= 0; i--) { 159 | if (whitespace.indexOf(str.charAt(i)) === -1) { 160 | str = str.substring(0, i + 1) 161 | break 162 | } 163 | } 164 | 165 | return whitespace.indexOf(str.charAt(0)) === -1 ? str : '' 166 | } 167 | 168 | function ltrim (str, charlist) { 169 | // discuss at: https://locutus.io/php/ltrim/ 170 | // original by: Kevin van Zonneveld (https://kvz.io) 171 | // input by: Erkekjetter 172 | // improved by: Kevin van Zonneveld (https://kvz.io) 173 | // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman) 174 | // example 1: ltrim(' Kevin van Zonneveld ') 175 | // returns 1: 'Kevin van Zonneveld ' 176 | 177 | charlist = !charlist ? ' \\s\u00A0' : (charlist + '') 178 | .replace(/([[\]().?/*{}+$^:])/g, '$1') 179 | 180 | var re = new RegExp('^[' + charlist + ']+', 'g') 181 | 182 | return (str + '') 183 | .replace(re, '') 184 | } 185 | 186 | function rtrim(str, charlist) { 187 | charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '\\$1'); 188 | 189 | const re = new RegExp('[' + charlist + ']+$', 'g'); 190 | 191 | return (str + '').replace(re, '') 192 | } 193 | 194 | /** 195 | * @return {string} 196 | */ 197 | function Stringable (value) { 198 | this.value = value; 199 | 200 | return `${this.value}`; 201 | } 202 | 203 | /** 204 | * Return the remainder of a string after the first occurrence of a given value 205 | * 206 | * @param search 207 | * 208 | * @return Stringable 209 | */ 210 | Stringable.prototype.after = function(search = '') 211 | { 212 | return (new Stringable(Str.after(this.value, search))); 213 | }; 214 | 215 | /** 216 | * Returns the remainder of a string after the last occurrence of a given value 217 | * 218 | * @param subject 219 | * @param search 220 | * 221 | * @return Stringable 222 | */ 223 | Stringable.prototype.afterLast = function(subject, search = '') 224 | { 225 | return new Stringable(Str.afterLast(this.value, search)); 226 | }; 227 | 228 | /** 229 | * Append the given values to the string. 230 | * 231 | * @param values 232 | * 233 | * @return Stringable 234 | */ 235 | Stringable.prototype.append = function(...values) 236 | { 237 | return new Stringable(this.value + values.join('')); 238 | }; 239 | 240 | /** 241 | * Transliterate a UTF-8 value to ASCII. 242 | * 243 | * @param language 244 | * 245 | * @return Stringable 246 | */ 247 | Stringable.prototype.ascii = function(language = 'en') 248 | { 249 | return new Stringable(Str.ascii(this.value, language)); 250 | }; 251 | 252 | /** 253 | * Get the portion of a string before the first occurrence of a given value 254 | * 255 | * @param search 256 | * 257 | * @return Stringable 258 | */ 259 | Stringable.prototype.before = function(search = '') 260 | { 261 | return new Stringable(Str.before(this.value, search)); 262 | }; 263 | 264 | /** 265 | * Get the portion of a string before the last occurrence of a given value 266 | * 267 | * @param search 268 | * 269 | * @return Stringable 270 | */ 271 | Stringable.prototype.beforeLast = function(search = '') 272 | { 273 | return new Stringable(Str.beforeLast(this.value, search)); 274 | }; 275 | 276 | /** 277 | * Get the portion of a string between two given values 278 | * 279 | * @param at 280 | * @param to 281 | * 282 | * @return Stringable 283 | */ 284 | Stringable.prototype.between = function(at = '', to = '') 285 | { 286 | return new Stringable(Str.between(this.value, at, to)); 287 | }; 288 | 289 | /** 290 | * Convert a value to camel case. 291 | * 292 | * @return Stringable 293 | */ 294 | Stringable.prototype.camel = function() 295 | { 296 | return new Stringable(Str.camel(this.value)); 297 | }; 298 | 299 | /** 300 | * Determine if a given string contains a given substring. 301 | * 302 | * @param needles 303 | * 304 | * @return boolean 305 | */ 306 | Stringable.prototype.contains = function(needles = []) 307 | { 308 | return Str.contains(this.value, needles); 309 | }; 310 | 311 | /** 312 | * Determine if a given string contains all array values 313 | * 314 | * @param needles[] 315 | * 316 | * @return boolean 317 | */ 318 | Stringable.prototype.containsAll = function(needles = []) 319 | { 320 | return Str.containsAll(this.value, needles); 321 | }; 322 | 323 | /** 324 | * Determine if a given string ends with a given substring 325 | * 326 | * @param needles 327 | * 328 | * @return boolean 329 | */ 330 | Stringable.prototype.endsWith = function(needles = []) 331 | { 332 | return Str.endsWith(this.value, needles); 333 | }; 334 | 335 | /** 336 | * Cap a string with a single instance of a given value if it doesnt already end with it 337 | * 338 | * @param cap 339 | * 340 | * @return Stringable 341 | */ 342 | Stringable.prototype.finish = function(cap) 343 | { 344 | return new Stringable(Str.finish(this.value, cap)); 345 | }; 346 | 347 | /** 348 | * Determine if the string is an exact match with the given value. 349 | * 350 | * @param value 351 | * 352 | * @return boolean 353 | */ 354 | Stringable.prototype.exactly = function(value) 355 | { 356 | return this.value === value; 357 | }; 358 | 359 | /** 360 | * Explode the string into an array. 361 | * 362 | * @param delimiter 363 | * @param limit 364 | * 365 | * @return Collection 366 | */ 367 | Stringable.prototype.explode = function(delimiter, limit = Number.MAX_SAFE_INTEGER) 368 | { 369 | return collect(explode(delimiter, this.value, limit)); 370 | }; 371 | 372 | /** 373 | * Split a string using a regular expression. 374 | * 375 | * @param pattern 376 | * @param limit 377 | * @param flags 378 | * 379 | * @return Collection 380 | */ 381 | Stringable.prototype.split = function(pattern, limit = -1, flags = 0) 382 | { 383 | let segments = this.value.split(new RegExp(pattern)); 384 | 385 | return ! (typeof segments === 'undefined' || segments.length < 1) ? collect(segments) : collect(); 386 | }; 387 | 388 | /** 389 | * Cap a string with a single instance of a given value 390 | * 391 | * @param cap 392 | * 393 | * @return Stringable 394 | */ 395 | Stringable.prototype.finish = function(cap) 396 | { 397 | return new Stringable(Str.finish(this.value, cap)); 398 | }; 399 | 400 | /** 401 | * Determine if a given string matches a given pattern 402 | * 403 | * @param pattern 404 | * 405 | * @return boolean 406 | */ 407 | Stringable.prototype.is = function(pattern) 408 | { 409 | return Str.is(pattern, this.value); 410 | }; 411 | 412 | /** 413 | * Determine if a given string is 7 bit ASCII 414 | * 415 | * @return boolean 416 | */ 417 | Stringable.prototype.isAscii = function() 418 | { 419 | return Str.isAscii(this.value); 420 | }; 421 | 422 | /** 423 | * Determine if the given string is empty. 424 | * 425 | * @return boolean 426 | */ 427 | Stringable.prototype.isEmpty = function() 428 | { 429 | return this.value === ''; 430 | }; 431 | 432 | /** 433 | * Determine if the given string is empty. 434 | * 435 | * @return boolean 436 | */ 437 | Stringable.prototype.isNotEmpty = function() 438 | { 439 | return ! this.isEmpty(); 440 | }; 441 | 442 | 443 | /** 444 | * Convert a string to kebab case. 445 | * 446 | * @return Stringable 447 | */ 448 | Stringable.prototype.kebab = function() 449 | { 450 | return new Stringable(Str.kebab(this.value)); 451 | }; 452 | 453 | /** 454 | * Return the length of the given string 455 | * 456 | * @param encoding 457 | * 458 | * @return int 459 | */ 460 | Stringable.prototype.length = function(encoding = null) 461 | { 462 | return Str.length(this.value, encoding); 463 | }; 464 | 465 | /** 466 | * Limit the number of characters in a string. 467 | * 468 | * @param limit 469 | * @param end 470 | * 471 | * @return Stringable 472 | */ 473 | Stringable.prototype.limit = function(limit = 100, end = '...') 474 | { 475 | return new Stringable(Str.limit(this.value, limit, end)); 476 | }; 477 | 478 | /** 479 | * Convert the given string to lower-case 480 | * 481 | * @return Stringable 482 | */ 483 | Stringable.prototype.lower = function() 484 | { 485 | return new Stringable(Str.lower(this.value)); 486 | }; 487 | 488 | /** 489 | * Get the string matching the given pattern. 490 | * 491 | * @param pattern 492 | * 493 | * @return Stringable|null 494 | */ 495 | Stringable.prototype.match = function(pattern) 496 | { 497 | let matches = preg_match(pattern, this.value); 498 | 499 | if (! matches) { 500 | return new Stringable(''); 501 | } 502 | 503 | return new Stringable(matches[1] || matches[0]); 504 | }; 505 | 506 | // @TODO matchAll 507 | // /** 508 | // * Get the string matching the given pattern. 509 | // * 510 | // * @param pattern 511 | // * @return Collection 512 | // */ 513 | // Stringable.prototype.matchAll = function(pattern) 514 | // { 515 | // let matches = pattern 516 | // }; 517 | 518 | /** 519 | * Parse a Class@method style callback into class and method 520 | * 521 | * @param fallback 522 | * 523 | * @return array 524 | */ 525 | Stringable.prototype.parseCallback = function(fallback) 526 | { 527 | return Str.parseCallback(this.value, fallback); 528 | }; 529 | 530 | /** 531 | * Get the plural form of an English word. 532 | * 533 | * @param count 534 | * 535 | * @return Stringable 536 | */ 537 | Stringable.prototype.plural = function(count = 2) 538 | { 539 | return new Stringable(Str.plural(this.value, count)); 540 | }; 541 | 542 | /** 543 | * Pluralize the last word of an English, studly caps case string. 544 | * 545 | * @param count 546 | * 547 | * @return Stringable 548 | */ 549 | Stringable.prototype.pluralStudly = function(count = 2) 550 | { 551 | return new Stringable(Str.pluralStudly(this.value, count)); 552 | }; 553 | 554 | /** 555 | * Replace the given value in the given string. 556 | * 557 | * @param search 558 | * @param replace 559 | * 560 | * @return Stringable 561 | */ 562 | Stringable.prototype.replace = function (search, replace) 563 | { 564 | return new Stringable(str_replace(search, replace, this.value)); 565 | }; 566 | 567 | /** 568 | * Replace a given value in the string sequentially with an array. 569 | * 570 | * @param search 571 | * @param replace 572 | * 573 | * @return Stringable 574 | */ 575 | Stringable.prototype.replaceArray = function (search, replace = []) 576 | { 577 | return new Stringable(Str.replaceArray(search, replace, this.value)); 578 | }; 579 | 580 | /** 581 | * Replace the first occurrence of a given value in the string. 582 | * 583 | * @param search 584 | * @param replace 585 | * 586 | * @return Stringable 587 | */ 588 | Stringable.prototype.replaceFirst = function (search, replace) 589 | { 590 | return new Stringable(Str.replaceFirst(search, replace, this.value)); 591 | }; 592 | 593 | /** 594 | * Replace the last occurrence of a given value in the string. 595 | * 596 | * @param search 597 | * @param replace 598 | * 599 | * @return Stringable 600 | */ 601 | Stringable.prototype.replaceLast = function (search, replace) 602 | { 603 | return new Stringable(Str.replaceLast(search, replace, this.value)); 604 | }; 605 | 606 | // /** @TODO Add replaceMatches method 607 | // * Replace the patterns matching the given regular expression. 608 | // * 609 | // * @param string $pattern 610 | // * @param \Closure|string $replace 611 | // * @param int $limit 612 | // * @return static 613 | // */ 614 | // Stringable.prototype.replaceMatches = function (pattern, replace, limit = -1) 615 | // { 616 | // 617 | // }; 618 | 619 | /** 620 | * Begin a string with a single instance of a given value 621 | * 622 | * @param prefix 623 | * 624 | * @return Stringable 625 | */ 626 | Stringable.prototype.start = function(prefix) 627 | { 628 | return new Stringable(Str.start(this.value, prefix)); 629 | }; 630 | 631 | /** 632 | * Convert the given string to upper-case. 633 | * 634 | * @return Stringable 635 | */ 636 | Stringable.prototype.upper = function() 637 | { 638 | return new Stringable(Str.upper(this.value)); 639 | }; 640 | 641 | /** 642 | * Convert the given string to title case. 643 | * 644 | * @return Stringable 645 | */ 646 | Stringable.prototype.title = function() 647 | { 648 | return new Stringable(Str.title(this.value)); 649 | }; 650 | 651 | /** 652 | * Get the singular form of an English word. 653 | * 654 | * @return Stringable 655 | */ 656 | Stringable.prototype.singular = function() 657 | { 658 | return new Stringable(Str.singular(this.value)); 659 | }; 660 | 661 | /** 662 | * 663 | * @param separator 664 | * @param language 665 | * 666 | * @returns Stringable 667 | */ 668 | Stringable.prototype.slug = function(separator = '-', language = 'en') 669 | { 670 | return new Stringable(Str.slug(this.value, separator, language)); 671 | }; 672 | 673 | /** 674 | * Convert a string to snake case. 675 | * 676 | * @param delimiter 677 | * 678 | * @return Stringable 679 | */ 680 | Stringable.prototype.snake = function snake(delimiter = '_') 681 | { 682 | return new Stringable(Str.snake(this.value, delimiter)); 683 | }; 684 | 685 | /** 686 | * Determine if a given string starts with a given substring. 687 | * 688 | * @param needles 689 | * 690 | * @return boolean 691 | */ 692 | Stringable.prototype.startsWith = function(needles) 693 | { 694 | return Str.startsWith(this.value, needles); 695 | }; 696 | 697 | /** 698 | * Convert a value to studly caps case. 699 | * 700 | * @return Stringable 701 | */ 702 | Stringable.prototype.studly = function () 703 | { 704 | return new Stringable(Str.studly(this.value)); 705 | }; 706 | 707 | /** 708 | * Returns the portion of string specified by the start and length parameters. 709 | * 710 | * @param start 711 | * @param length 712 | * 713 | * @return Stringable 714 | */ 715 | Stringable.prototype.substr = function(start, length = null) 716 | { 717 | return new Stringable(Str.substr(this.value, start, length)); 718 | }; 719 | 720 | /** 721 | * Returns the number of substring occurrences. 722 | * 723 | * @param needle 724 | * @param offset 725 | * @param length 726 | * 727 | * @return int 728 | */ 729 | Stringable.prototype.substrCount = function(needle, offset = null, length = null) 730 | { 731 | return Str.substrCount(this.value, needle, offset, length); 732 | }; 733 | 734 | /** 735 | * Trim the string of the given characters. 736 | * 737 | * @param characters 738 | * 739 | * @returns Stringable 740 | */ 741 | Stringable.trim = function(characters = null) 742 | { 743 | return new Stringable(trim(...[this.value, ...arguments])); 744 | }; 745 | 746 | /** 747 | * Left trim the string of given characters. 748 | * 749 | * @param characters 750 | * 751 | * @return Stringable 752 | */ 753 | Stringable.ltrim = function(characters = null) 754 | { 755 | return new Stringable(ltrim(...[this.value, ...arguments])); 756 | }; 757 | 758 | /** 759 | * Right trim the string of given characters. 760 | * 761 | * @param characters 762 | * 763 | * @return Stringable 764 | */ 765 | Stringable.rtrim = function(characters = null) 766 | { 767 | return new Stringable(rtrim(...[this.value, ...arguments])); 768 | }; 769 | 770 | /** 771 | * Make a string's first character uppercase. 772 | * 773 | * @return Stringable 774 | */ 775 | Stringable.prototype.whenEmpty = function(callback) 776 | { 777 | if (this.isEmpty()) { 778 | let result = callback(this); 779 | 780 | return result === null || typeof result === 'undefined' ? this : result; 781 | } 782 | 783 | return this; 784 | }; 785 | 786 | /** 787 | * Limit the number of words in a string. 788 | * 789 | * @param words 790 | * @param end 791 | * 792 | * @return Stringable 793 | */ 794 | Stringable.prototype.words = function(words = 100, end = '...') 795 | { 796 | return new Stringable(Str.words(this.value, words, end)); 797 | }; 798 | 799 | /** 800 | * Dump the string. 801 | * 802 | * @return this 803 | */ 804 | Stringable.prototype.dump = function() 805 | { 806 | console.log(this); 807 | 808 | return this; 809 | }; 810 | 811 | /** 812 | * Dump the string then die. 813 | * 814 | * @return void 815 | */ 816 | Stringable.prototype.dd = function () 817 | { 818 | this.dump(); 819 | 820 | if (typeof process !== 'undefined') { 821 | if (typeof process.exit !== 'undefined') { 822 | process.exit(1); 823 | } 824 | } 825 | }; 826 | 827 | /** 828 | * Proxy dynamic properties properties onto methods. 829 | * 830 | * @param key 831 | * 832 | * @return mixed 833 | */ 834 | Stringable.prototype.get = function(key) 835 | { 836 | return this[key](); 837 | }; 838 | 839 | /** 840 | * Stringable.dirname 841 | */ 842 | /** 843 | * Used when returning as a string operation 844 | * 845 | * @returns string 846 | */ 847 | Stringable.prototype.toLocaleString = function() 848 | { 849 | return `${this.value}`; 850 | }; 851 | 852 | /** 853 | * Used when returning as a string operation 854 | * 855 | * @returns string 856 | */ 857 | Stringable.prototype.toString = function() 858 | { 859 | return `${this.value}`; 860 | }; 861 | 862 | /** 863 | * Used when JSON.stringify is called 864 | */ 865 | Stringable.prototype.toJSON = function() 866 | { 867 | return this.toString(); 868 | }; 869 | 870 | /** 871 | * Used when returning as a value operation 872 | * 873 | * @returns string 874 | */ 875 | Stringable.prototype.valueOf = function() 876 | { 877 | return `${this.value}`; 878 | }; 879 | 880 | class Pluralizer 881 | { 882 | static inflection; 883 | 884 | static rules = { 885 | plural: {}, 886 | singular: {}, 887 | irregular: {}, 888 | uncountable: [ 889 | 'audio', 890 | 'bison', 891 | 'cattle', 892 | 'chassis', 893 | 'compensation', 894 | 'coreopsis', 895 | 'data', 896 | 'deer', 897 | 'education', 898 | 'emoji', 899 | 'equipment', 900 | 'evidence', 901 | 'feedback', 902 | 'firmware', 903 | 'fish', 904 | 'furniture', 905 | 'gold', 906 | 'hardware', 907 | 'information', 908 | 'jedi', 909 | 'kin', 910 | 'knowledge', 911 | 'love', 912 | 'metadata', 913 | 'money', 914 | 'moose', 915 | 'news', 916 | 'nutrition', 917 | 'offspring', 918 | 'plankton', 919 | 'pokemon', 920 | 'police', 921 | 'rain', 922 | 'recommended', 923 | 'related', 924 | 'rice', 925 | 'series', 926 | 'sheep', 927 | 'software', 928 | 'species', 929 | 'swine', 930 | 'traffic', 931 | 'wheat' 932 | ] 933 | }; 934 | 935 | 936 | /** 937 | * Get the plural form of an English word. 938 | * 939 | * @param value 940 | * @param count 941 | * 942 | * @return string 943 | */ 944 | static plural(value, count = 2) 945 | { 946 | if (Math.abs(count) === 1 || Pluralizer.uncountable(value)) { 947 | return value; 948 | } 949 | 950 | const plural = Pluralizer.inflector().plural(value); 951 | 952 | return Pluralizer.matchCase(plural, value); 953 | } 954 | 955 | /** 956 | * Get the singular form of an English word. 957 | * 958 | * @param value 959 | * 960 | * @return string 961 | */ 962 | static singular(value) 963 | { 964 | let single = Pluralizer.inflector().singular(value); 965 | 966 | return Pluralizer.matchCase(single, value); 967 | } 968 | 969 | /** 970 | * Determine if the given value is uncountable. 971 | * 972 | * @param value 973 | * 974 | * @returns boolean 975 | */ 976 | static uncountable(value) 977 | { 978 | return Pluralizer.rules.uncountable.includes(value.toLowerCase()); 979 | } 980 | 981 | /** 982 | * Determine if the given value is plural. 983 | * 984 | * @param value 985 | * 986 | * @returns boolean 987 | */ 988 | static isPlural(value = '') 989 | { 990 | return Pluralizer.inflector().isPlural(value); 991 | } 992 | 993 | /** 994 | * Determine if the given value is singular. 995 | * 996 | * @param value 997 | * 998 | * @returns boolean 999 | */ 1000 | static isSingular(value = '') 1001 | { 1002 | return Pluralizer.inflector().isSingular(value); 1003 | } 1004 | 1005 | /** 1006 | * Attempt to match the case on two strings 1007 | * 1008 | * @param value 1009 | * @param comparison 1010 | * 1011 | * @return string 1012 | */ 1013 | static matchCase(value, comparison) 1014 | { 1015 | if (comparison.toLowerCase() === comparison) { 1016 | return value.toLowerCase(); 1017 | } 1018 | 1019 | if (comparison.toUpperCase() === comparison) { 1020 | return value.toUpperCase(); 1021 | } 1022 | 1023 | if ((comparison[0].toUpperCase() + comparison.slice(1)) === comparison) { 1024 | return value[0].toUpperCase() + value.slice(1); 1025 | } 1026 | 1027 | return value; 1028 | } 1029 | 1030 | /** 1031 | * Get the pluralize instance 1032 | * 1033 | * @return Pluralizer.inflection 1034 | */ 1035 | static inflector() 1036 | { 1037 | if (typeof Pluralizer.inflection === 'undefined') { 1038 | Pluralizer.inflection = pluralize; 1039 | 1040 | Pluralizer.rules.uncountable.forEach(uncountable => Pluralizer.inflection.addUncountableRule(uncountable)); 1041 | Object.entries(Pluralizer.rules.plural).forEach(([plural, rule]) => Pluralizer.inflection.addIrregularRule(rule, plural)); 1042 | Object.entries(Pluralizer.rules.singular).forEach(([singular, rule]) => Pluralizer.inflection.addIrregularRule(rule, singular)); 1043 | Object.entries(Pluralizer.rules.irregular).forEach(([irregularity, rule]) => Pluralizer.inflection.addIrregularRule(rule, irregularity)); 1044 | } 1045 | 1046 | return Pluralizer.inflection; 1047 | } 1048 | } 1049 | 1050 | class Str 1051 | { 1052 | /** 1053 | * The cache of snake-cased words 1054 | * 1055 | * @var object 1056 | */ 1057 | static snakeCache = {}; 1058 | 1059 | /** 1060 | * The cache of camel-cased words 1061 | * 1062 | * @var object 1063 | */ 1064 | static camelCache = {}; 1065 | 1066 | /** 1067 | * The cache of studly-cased words 1068 | * 1069 | * @var object 1070 | */ 1071 | static studlyCache = {}; 1072 | 1073 | /** 1074 | * The callback that should be used to generate UUIDs. 1075 | * 1076 | * @var callback 1077 | */ 1078 | static uuidFactory; 1079 | 1080 | /** 1081 | * Get a new stringable object from the given string. 1082 | * 1083 | * @param string string 1084 | * @return Stringable 1085 | */ 1086 | static of(string) 1087 | { 1088 | return new Stringable(string); 1089 | } 1090 | 1091 | /** 1092 | * Return the remainder of a string after the first occurrence of a given value 1093 | * 1094 | * @param subject 1095 | * @param search 1096 | * 1097 | * @return string 1098 | */ 1099 | static after(subject, search = '') 1100 | { 1101 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(subject.indexOf(search) + search.length); 1102 | } 1103 | 1104 | /** 1105 | * Returns the remainder of a string after the last occurrence of a given value 1106 | * 1107 | * @param subject 1108 | * @param search 1109 | * 1110 | * @return string 1111 | */ 1112 | static afterLast(subject, search = '') 1113 | { 1114 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(subject.lastIndexOf(search) + search.length); 1115 | } 1116 | 1117 | /** 1118 | * Transliterate a UTF-8 value to ASCII. 1119 | * 1120 | * @param value 1121 | * @param language 1122 | * 1123 | * @return string 1124 | */ 1125 | static ascii(value = '', language = 'en') 1126 | { 1127 | return String.fromCharCode(...value.split('').map(character => character.charCodeAt(0))); 1128 | } 1129 | 1130 | /** 1131 | * Get the portion of a string before the first occurrence of a given value 1132 | * 1133 | * @param subject 1134 | * @param search 1135 | * 1136 | * @return string 1137 | */ 1138 | static before(subject, search = '') 1139 | { 1140 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(0, subject.indexOf(search)); 1141 | } 1142 | 1143 | /** 1144 | * Get the portion of a string before the last occurrence of a given value 1145 | * 1146 | * @param subject 1147 | * @param search 1148 | * 1149 | * @return string 1150 | */ 1151 | static beforeLast(subject, search = '') 1152 | { 1153 | return search === '' || subject.indexOf(search) === -1 ? subject : subject.substr(0, subject.lastIndexOf(search)); 1154 | } 1155 | 1156 | /** 1157 | * Get the portion of a string between two given values 1158 | * 1159 | * @param subject 1160 | * @param at 1161 | * @param to 1162 | * 1163 | * @return string 1164 | */ 1165 | static between(subject, at = '', to = '') 1166 | { 1167 | return subject.indexOf(at) === -1 || subject.indexOf(to) === -1 ? subject : Str.beforeLast(Str.after(subject, at), to); 1168 | } 1169 | 1170 | /** 1171 | * Convert a value to camel case. 1172 | * 1173 | * @param value 1174 | * 1175 | * @return string 1176 | */ 1177 | static camel(value = '') 1178 | { 1179 | if (typeof Str.camelCache[value] !== 'undefined') { 1180 | return Str.camelCache[value]; 1181 | } 1182 | 1183 | let studly = Str.studly(value); 1184 | 1185 | return Str.camelCache[value] = `${studly[0].toLowerCase()}${studly.slice(1)}`; 1186 | } 1187 | 1188 | /** 1189 | * Determine if a given string contains a given substring. 1190 | * 1191 | * @param haystack 1192 | * @param needles 1193 | * 1194 | * @return boolean 1195 | */ 1196 | static contains(haystack, needles = []) 1197 | { 1198 | return Array.isArray(needles) ? needles.some(needle => haystack.includes(needle)) : haystack.includes(needles); 1199 | } 1200 | 1201 | /** 1202 | * Determine if a given string contains all array values 1203 | * 1204 | * @param haystack 1205 | * @param needles[] 1206 | * 1207 | * @return boolean 1208 | */ 1209 | static containsAll(haystack, needles = []) 1210 | { 1211 | return needles.every(needle => haystack.includes(needle)); 1212 | } 1213 | 1214 | /** 1215 | * Determine if a given string ends with a given substring 1216 | * 1217 | * @param haystack 1218 | * @param needles 1219 | * 1220 | * @return boolean 1221 | */ 1222 | static endsWith(haystack, needles = []) 1223 | { 1224 | return Array.isArray(needles) 1225 | ? needles.some(needle => haystack.substr(-needle.length) === needle) 1226 | : haystack.substr(-needles.length) === needles; 1227 | } 1228 | 1229 | /** 1230 | * Cap a string with a single instance of a given value if it doesnt already end with it 1231 | * 1232 | * @param value 1233 | * @param cap 1234 | * 1235 | * @return string 1236 | */ 1237 | static finish(value, cap) 1238 | { 1239 | return Str.endsWith(value, cap) ? value : `${value}${cap}`; 1240 | } 1241 | 1242 | /** 1243 | * Determine if a given string matches a given pattern 1244 | * 1245 | * @param pattern 1246 | * @param value 1247 | * 1248 | * @return boolean 1249 | */ 1250 | static is(pattern, value) 1251 | { 1252 | let patterns = Array.isArray(pattern) ? pattern : [pattern]; 1253 | 1254 | return patterns.some(pattern => { 1255 | if (value === pattern) return true; 1256 | else if (pattern.includes('*') === false) return (new RegExp(pattern).test(value)); 1257 | else if (pattern.includes('*')) return (new RegExp(pattern.replace(/\*/g, '.*'))).test(value); 1258 | }); 1259 | } 1260 | 1261 | /** 1262 | * Determine if a given string is 7 bit ASCII 1263 | * 1264 | * @param value 1265 | * @returns boolean 1266 | */ 1267 | static isAscii(value) { 1268 | // extended Ascii pattern /^[\x00-\xFF]*$/ 1269 | // 128 char Ascii pattern /^[\x00-\x7F]*$/ 1270 | return /^[\x00-\xFF]*$/.test(String(value)); 1271 | } 1272 | 1273 | /** 1274 | * Determine if a given string is valid UUID. 1275 | * 1276 | * @param value 1277 | * 1278 | * @return boolean 1279 | */ 1280 | static isUuid(value) 1281 | { 1282 | if (typeof value !== 'string') { 1283 | return false; 1284 | } 1285 | 1286 | return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', value) > 0; 1287 | } 1288 | 1289 | /** 1290 | * Convert a string to kebab case. 1291 | * 1292 | * @param value 1293 | * 1294 | * @return string 1295 | */ 1296 | static kebab(value) 1297 | { 1298 | return Str.snake(value, '-'); 1299 | } 1300 | 1301 | 1302 | 1303 | /** 1304 | * Convert a string to snake case. 1305 | * 1306 | * @param value 1307 | * @param delimiter 1308 | * 1309 | * @return string 1310 | */ 1311 | static snake(value, delimiter = '_') 1312 | { 1313 | let key = value; 1314 | 1315 | if (typeof Str.snakeCache !== 'undefined') { 1316 | if (typeof Str.snakeCache[delimiter] !== 'undefined') { 1317 | return Str.snakeCache[key][delimiter]; 1318 | } 1319 | } 1320 | 1321 | if (! ctype_lower(value)) { 1322 | Str.snakeCache[key] = { 1323 | ...(Str.snakeCache[key] || {}), 1324 | [delimiter]: value.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).map(x => x.toLowerCase()).join(delimiter), 1325 | }; 1326 | 1327 | return Str.snakeCache[key][delimiter]; 1328 | } 1329 | 1330 | Str.snakeCache[key] = { 1331 | ...(Str.snakeCache[key] || {}), 1332 | [delimiter]: value, 1333 | }; 1334 | 1335 | return Str.snakeCache[key][delimiter]; 1336 | } 1337 | 1338 | 1339 | /** 1340 | * Return the length of the given string 1341 | * 1342 | * @param value 1343 | * @param encoding 1344 | * 1345 | * @return int 1346 | * 1347 | * @TODO add encoding option 1348 | */ 1349 | static length(value = '', encoding = null) 1350 | { 1351 | return value.length; 1352 | } 1353 | 1354 | 1355 | /** 1356 | * Limit the number of characters in a string 1357 | * 1358 | * @param value 1359 | * @param limit 1360 | * @param end 1361 | * 1362 | * @return string 1363 | */ 1364 | static limit(value = '', limit = 100, end = '...') 1365 | { 1366 | return value.length < limit ? value : value.slice(0, limit) + end; 1367 | } 1368 | 1369 | /** 1370 | * Convert the given string to lower-case. 1371 | * 1372 | * @param value 1373 | * 1374 | * @return string 1375 | */ 1376 | static lower(value = '') 1377 | { 1378 | return value.toLocaleLowerCase(); 1379 | } 1380 | 1381 | /** 1382 | * Limit the number of words in a string. 1383 | * 1384 | * @param value 1385 | * @param words 1386 | * @param end 1387 | * 1388 | * @return string 1389 | */ 1390 | static words(value = '', words = 100, end = '...') 1391 | { 1392 | let word = value.split(' '); 1393 | 1394 | return word.length <= words ? value : word.slice(0, words).join(" ") + end; 1395 | } 1396 | 1397 | /** 1398 | * Parse a Class[@]method style callback into class and method. 1399 | * 1400 | * @param callback 1401 | * @param fallback 1402 | * 1403 | * @return array 1404 | */ 1405 | static parseCallback(callback, fallback = null) 1406 | { 1407 | return Str.contains(callback, '@') ? explode('@', callback, 2) : [callback, fallback]; 1408 | } 1409 | 1410 | /** 1411 | * Get the plural form of an english word 1412 | * 1413 | * @param value 1414 | * @param count 1415 | * 1416 | * @return string 1417 | */ 1418 | static plural(value, count = 2) 1419 | { 1420 | return Pluralizer.plural(value, count); 1421 | } 1422 | 1423 | /** 1424 | * Pluralize the last word of an English, studly caps case string. 1425 | * 1426 | * @param value 1427 | * @param count 1428 | * 1429 | * @return string 1430 | */ 1431 | static pluralStudly(value, count = 2) 1432 | { 1433 | const [until, last_word] = value.split(/(?=[A-Z][^A-Z]+$)/); 1434 | 1435 | return until + Str.plural(last_word, count); 1436 | } 1437 | 1438 | /** 1439 | * Generate a more truly "random" alpha-numeric string. 1440 | * 1441 | * @param length 1442 | * 1443 | * @return string 1444 | */ 1445 | static random(length = 16) 1446 | { 1447 | let random = ''; 1448 | let alpha_numeric = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; 1449 | 1450 | for (let i = 0; i < length; i++) { 1451 | let character_index = Math.floor(Math.random() * Math.floor(alpha_numeric.length)); 1452 | 1453 | random += alpha_numeric.slice(character_index, character_index + 1); 1454 | } 1455 | 1456 | return random; 1457 | } 1458 | 1459 | /** 1460 | * Replace a given value in the string sequentially with an array. 1461 | * 1462 | * @param search 1463 | * @param replace 1464 | * @param subject 1465 | * 1466 | * @return string 1467 | */ 1468 | static replaceArray(search, replace = [], subject) 1469 | { 1470 | if (Array.isArray(replace) === false) { 1471 | throw Error("Str.replaceArray requires that parameter two (replace) is an array. Passed In: " + JSON.stringify(replace)); 1472 | } 1473 | 1474 | return replace.reduce((value, replacer) => value.replace(search, replacer), subject); 1475 | } 1476 | 1477 | /** 1478 | * Replace the first occurrence of a given value in the string. 1479 | * 1480 | * @param search 1481 | * @param replace 1482 | * @param subject 1483 | * 1484 | * @return string 1485 | */ 1486 | static replaceFirst(search, replace, subject) 1487 | { 1488 | if (search === '') { 1489 | return subject; 1490 | } 1491 | 1492 | const search_index = subject.indexOf(search); 1493 | 1494 | if (search_index === -1) { 1495 | return subject; 1496 | } 1497 | 1498 | const start = subject.substr(0, search_index); 1499 | const after = subject.substr(search_index + search.length, subject.length); 1500 | 1501 | return `${start}${replace}${after}`; 1502 | } 1503 | 1504 | /** 1505 | * Replace the last occurrence of a given value in the string 1506 | * 1507 | * @param search 1508 | * @param replace 1509 | * @param subject 1510 | * 1511 | * @returns string 1512 | */ 1513 | static replaceLast(search, replace, subject) 1514 | { 1515 | if (search === '') { 1516 | return subject; 1517 | } 1518 | 1519 | const search_index = subject.lastIndexOf(search); 1520 | 1521 | if (search_index === -1) { 1522 | return subject; 1523 | } 1524 | 1525 | const start = subject.substr(0, search_index); 1526 | const after = subject.substr(search_index + search.length, subject.length); 1527 | 1528 | return `${start}${replace}${after}`; 1529 | } 1530 | 1531 | /** 1532 | * Begin a string with a single instance of a given value. 1533 | * 1534 | * @param value 1535 | * @param prefix 1536 | * 1537 | * @return string 1538 | */ 1539 | static start(value, prefix) 1540 | { 1541 | return Str.startsWith(value, prefix) ? value : `${prefix}${value}`; 1542 | } 1543 | 1544 | /** 1545 | * Convert a value to studly caps case 1546 | * 1547 | * @param value 1548 | * 1549 | * @return string 1550 | */ 1551 | static studly(value) 1552 | { 1553 | const key = value; 1554 | 1555 | if (typeof Str.studlyCache[key] !== 'undefined') { 1556 | return Str.studlyCache[key]; 1557 | } 1558 | 1559 | return Str.studlyCache[key] = value 1560 | .replace(/_/g, ' ') 1561 | .replace(/-/g, ' ') 1562 | .split(' ') 1563 | .reduce((str, word) => `${str}${word[0].toUpperCase()}${word.slice(1)}`, ''); 1564 | } 1565 | 1566 | /** 1567 | * Convert the given string to upper-case 1568 | * 1569 | * @param value 1570 | * 1571 | * @return string 1572 | */ 1573 | static upper(value) 1574 | { 1575 | return value.toLocaleUpperCase(); 1576 | } 1577 | 1578 | /** 1579 | * Convert the given string to title case. 1580 | * 1581 | * @param value 1582 | * 1583 | * @return string 1584 | */ 1585 | static title(value) 1586 | { 1587 | return Str.snake(value).split('_').map(word => Str.ucfirst(word)).join(' '); 1588 | } 1589 | 1590 | /** 1591 | * Get the singular form of an English word. 1592 | * 1593 | * @param value 1594 | * @return string 1595 | */ 1596 | static singular(value) 1597 | { 1598 | return Pluralizer.singular(value); 1599 | } 1600 | 1601 | /** 1602 | * Generate a URL friendly "slug" from a given string. 1603 | * 1604 | * @param title 1605 | * @param separator 1606 | * @param language 1607 | * 1608 | * @return string 1609 | */ 1610 | static slug(title, separator = '-', language = 'en') 1611 | { 1612 | title = title.toLocaleString(); 1613 | 1614 | let slug = Str.snake(title.replace(/@/g, '_at_')) 1615 | .replace(/_/g, separator) 1616 | .trim(); 1617 | 1618 | return slug[0] === separator ? slug.slice(1, slug.length) : slug; 1619 | } 1620 | 1621 | /** 1622 | * Determine if a given string starts with a given substring 1623 | * 1624 | * @param haystack 1625 | * @param needles 1626 | * 1627 | * @return boolean 1628 | */ 1629 | static startsWith(haystack, needles = []) 1630 | { 1631 | return Array.isArray(needles) 1632 | ? needles.some(needle => haystack.startsWith(needle)) 1633 | : haystack.substr(0, needles.length) === needles; 1634 | } 1635 | 1636 | /** 1637 | * Returns the portion of string specified by the start and length parameters 1638 | * 1639 | * @param string 1640 | * @param start 1641 | * @param length 1642 | * 1643 | * @return string 1644 | */ 1645 | static substr(string, start, length = null) 1646 | { 1647 | return string.slice(start, start + length); 1648 | } 1649 | 1650 | /** 1651 | * Returns the number of substring occurrences 1652 | * 1653 | * @param haystack 1654 | * @param needle 1655 | * @param offset 1656 | * @param length 1657 | * 1658 | * @return int 1659 | */ 1660 | static substrCount(haystack, needle, offset, length = null) 1661 | { 1662 | if (length === null) { 1663 | return substr_count(haystack, needle, offset); 1664 | } else { 1665 | return substr_count(haystack, needle, offset, length); 1666 | } 1667 | } 1668 | 1669 | /** 1670 | * Make a strings first character upper case. 1671 | * 1672 | * @param value 1673 | * 1674 | * @return value 1675 | */ 1676 | static ucfirst(value = '') 1677 | { 1678 | if (value.length === 0) return value; 1679 | if (value.length === 1) return value[0].toUpperCase(); 1680 | 1681 | return value[0].toUpperCase() + value.slice(1); 1682 | } 1683 | 1684 | /** 1685 | * @TODO orderedUUID 1686 | * (Datetime > Decimal > Hex)-(variant)->(uuidv4 version)-(uuidv4 variant) 1687 | * @see https://itnext.io/laravel-the-mysterious-ordered-uuid-29e7500b4f8 1688 | **/ 1689 | // 1690 | // /** 1691 | // * Generate a time-ordered UUID (version 4). 1692 | // * 1693 | // * @return uuid 1694 | // */ 1695 | // static orderedUuid() { 1696 | // if (typeof Str.uuidFactory !== 'undefined') { 1697 | // return Str.uuidFactory(); 1698 | // } 1699 | // } 1700 | 1701 | /** 1702 | * Generate a UUID (version 4). 1703 | * 1704 | * @return string 1705 | */ 1706 | static uuid() 1707 | { 1708 | return typeof Str.uuidFactory === 'undefined' 1709 | ? uuidv4() 1710 | : Str.uuidFactory(); 1711 | } 1712 | 1713 | 1714 | 1715 | /** 1716 | * Set the callable that will be used to generate UUIDs. 1717 | * 1718 | * @param factory 1719 | * 1720 | * @return void 1721 | */ 1722 | static createUuidsUsing(factory = null) 1723 | { 1724 | if (typeof factory !== 'function' && factory !== null) { 1725 | throw Error('create uuidsUsing only excepts functions.'); 1726 | } 1727 | 1728 | Str.uuidFactory = factory; 1729 | } 1730 | 1731 | /** 1732 | * Indicate that UUIDs should be created normally and not using a custom factory. 1733 | * 1734 | * @return void 1735 | */ 1736 | static createUuidsNormally() 1737 | { 1738 | Str.uuidFactory = null; 1739 | } 1740 | } 1741 | 1742 | module.exports = Str; 1743 | module.exports.Str = Str; 1744 | module.exports.default = Str; 1745 | -------------------------------------------------------------------------------- /test/str/after.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the remainder of a string after the first occurrence of a given value', () => { 8 | expect(Str.after('brand new world', 'new ')).to.eql('world'); 9 | 10 | expect(Str.after('a brand new world for a group of people', 'a ')).to.eql('brand new world for a group of people'); 11 | 12 | expect(Str.after('hello world', 'new')).to.eql('hello world'); 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /test/str/afterLast.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the remainder of a string after the first occurrence of a given value', () => { 8 | expect(Str.afterLast('Hello planet earth, our planet is great.', 'planet ')).to.eql('is great.'); 9 | expect(Str.afterLast('a brand new world', 'a ')).to.eql('brand new world'); 10 | expect(Str.afterLast('hello world', 'new')).to.eql('hello world'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/before.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the remainder of a string before the first occurrence of a given value', () => { 8 | expect(Str.before('brand new world', ' world')).to.eql('brand new'); 9 | expect(Str.before('a brand new world for a group of people', 'a ')).to.eql(''); 10 | expect(Str.before('hello world', 'new')).to.eql('hello world'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/beforeLast.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the remainder of a string before the last occurrence of a given value', () => { 8 | expect(Str.beforeLast('Hello planet earth, our planet is great.', ' planet')).to.eql('Hello planet earth, our'); 9 | expect(Str.beforeLast('a brand new world', ' new')).to.eql('a brand'); 10 | expect(Str.beforeLast('hello world', 'new')).to.eql('hello world'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/between.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the remainder of a string between the at and to occurrences', () => { 8 | expect(Str.between('brand new world', 'brand ', ' world')).to.eql('new'); 9 | expect(Str.between('a nike brand a under armour brand', 'a ', ' brand')).to.eql('nike brand a under armour'); 10 | expect(Str.between('a brand new world', 'breezy', 'world')).to.eql('a brand new world'); 11 | expect(Str.between('a brand new world', 'brand', 'breezy')).to.eql('a brand new world'); 12 | }) 13 | }; 14 | -------------------------------------------------------------------------------- /test/str/camel.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return format a string to camel case', () => { 8 | expect(Str.camel('hello world')).to.eql('helloWorld'); 9 | expect(Str.camel('hello world earth')).to.eql('helloWorldEarth'); 10 | expect(Str.camel('hello_world_earth')).to.eql('helloWorldEarth'); 11 | expect(Str.camel('HelloWorldEarth')).to.eql('helloWorldEarth'); 12 | expect(Str.camel('hello-world-earth')).to.eql('helloWorldEarth'); 13 | expect(Str.camel('HelloWorldEarth')).to.eql('helloWorldEarth'); 14 | expect(Str.camel('Hello world Earth')).to.eql('helloWorldEarth'); 15 | expect(Str.camel('helloWorldEarth')).to.eql('helloWorldEarth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/contains.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return true if string contains substring', () => { 8 | expect(Str.contains('hello world', 'hello')).to.eql(true); 9 | expect(Str.contains('hello world earth', 'world')).to.eql(true); 10 | expect(Str.contains('hello_world_earth', '_world_')).to.eql(true); 11 | expect(Str.contains('HelloWorldEarth', 'WorldEa')).to.eql(true); 12 | expect(Str.contains('hello-{*}-earth', '{*}')).to.eql(true); 13 | expect(Str.contains('Hello world Earth', ['world', 'Earth'])).to.eql(true); 14 | expect(Str.contains('helloWorldEarth', ['World', 'mars'])).to.eql(true); 15 | expect(Str.contains('Hello world Earth', ['world', 'Earth'])).to.eql(true); 16 | 17 | }); 18 | 19 | it('Should return false if a string does not contain substring', () => { 20 | expect(Str.contains('hello world earth', 'mars')).to.eql(false); 21 | expect(Str.contains('Hello world Earth', '{example}')).to.eql(false); 22 | expect(Str.contains('Hello world Earth', ['{example}', 'mars'])).to.eql(false); 23 | }) 24 | }; 25 | -------------------------------------------------------------------------------- /test/str/containsAll.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return true if string contains all substrings', () => { 8 | expect(Str.containsAll('hello world', ['hello', 'world'])).to.eql(true); 9 | expect(Str.containsAll('hello world earth', ['world'])).to.eql(true); 10 | expect(Str.containsAll('hello_world_earth', ['_world_', '_earth'])).to.eql(true); 11 | expect(Str.containsAll('HelloWorldEarth', ['WorldEa', 'Hello', 'Earth'])).to.eql(true); 12 | expect(Str.containsAll('hello-{*}-earth', ['hello-', '{*}'])).to.eql(true); 13 | expect(Str.containsAll('Hello world Earth', ['world', 'Earth'])).to.eql(true); 14 | expect(Str.containsAll('Hello world Earth', ['world', 'Earth'])).to.eql(true); 15 | 16 | }); 17 | 18 | it('Should return false if a string does not contain substring', () => { 19 | expect(Str.containsAll('hello world earth', ['world', 'hello', 'mars'])).to.eql(false); 20 | expect(Str.containsAll('Hello world Earth', ['{example}', 'mars'])).to.eql(false); 21 | expect(Str.containsAll('Hello world Earth', ['{example}'])).to.eql(false); 22 | }) 23 | }; 24 | -------------------------------------------------------------------------------- /test/str/endsWith.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should true if string ends with a given substring', () => { 8 | expect(Str.endsWith('brand new world', 'world')).to.eql(true); 9 | expect(Str.endsWith('brand new world of people', ['a', 'world', 'people'])).to.eql(true); 10 | expect(Str.endsWith('a brand new world for a group of people', ' of people')).to.eql(true); 11 | }); 12 | 13 | it ('Should return false if string does not end with given substring', () => { 14 | expect(Str.endsWith('brand new world', 'new')).to.eql(false); 15 | expect(Str.endsWith('brand new world of people', ['a', 'world', 'brand'])).to.eql(false); 16 | expect(Str.endsWith('a brand new world for a group of people', ' of peopl')).to.eql(false); 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /test/str/finish.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should cap string with value if it doesnt already exist', () => { 8 | expect(Str.finish('/test', '/')).to.eql('/test/'); 9 | expect(Str.finish('/test/', '/')).to.eql('/test/'); 10 | }) 11 | }; 12 | -------------------------------------------------------------------------------- /test/str/is.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return true if pattern matches exact value or is a match', () => { 8 | expect(Str.is('foo', 'foo')).to.eql(true); 9 | expect(Str.is('foo*', 'foobar')).to.eql(true); 10 | }); 11 | 12 | it('Should return false if string does not match value or pattern', () => { 13 | expect(Str.is('foobar', 'foo')).to.eql(false); 14 | expect(Str.is('*foobar*', 'foeds')).to.eql(false); 15 | }) 16 | }; 17 | -------------------------------------------------------------------------------- /test/str/kebab.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return format a string to kebab case', () => { 8 | expect(Str.kebab('hello world')).to.eql('hello-world'); 9 | expect(Str.kebab('hello world earth')).to.eql('hello-world-earth'); 10 | expect(Str.kebab('hello_world_earth')).to.eql('hello-world-earth'); 11 | expect(Str.kebab('HelloWorldEarth')).to.eql('hello-world-earth'); 12 | expect(Str.kebab('hello-world-earth')).to.eql('hello-world-earth'); 13 | expect(Str.kebab('HelloWorldEarth')).to.eql('hello-world-earth'); 14 | expect(Str.kebab('Hello world Earth')).to.eql('hello-world-earth'); 15 | expect(Str.kebab('helloWorldEarth')).to.eql('hello-world-earth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/length.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return string length', () => { 8 | expect(Str.length('hey')).to.eql(3); 9 | expect(Str.length('')).to.eql(0); 10 | expect(Str.length('hello_world_earth')).to.eql(17); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/limit.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should limit string length and append an end', () => { 8 | expect(Str.limit('hey', 10, '...')).to.eql('hey'); 9 | expect(Str.limit('hey', 2)).to.eql('he...'); 10 | expect(Str.limit('hey', 2, ' ~')).to.eql('he ~'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/lower.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return lower case string', () => { 8 | expect(Str.lower('hey')).to.eql('hey'); 9 | expect(Str.lower('Hey WOrld')).to.eql('hey world'); 10 | expect(Str.lower('Hello_world_earTh')).to.eql('hello_world_earth'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/parseCallback.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return array of class and action', () => { 8 | expect(Str.parseCallback('Controller@index')).to.eql(['Controller', 'index']); 9 | }) 10 | }; 11 | -------------------------------------------------------------------------------- /test/str/plural.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return plural string', () => { 8 | expect(Str.plural('mother')).to.eql('mothers'); 9 | expect(Str.plural('bird')).to.eql('birds'); 10 | expect(Str.plural('sarah')).to.eql('sarahs'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/pluralStudly.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return plural version of studly string', () => { 8 | expect(Str.pluralStudly('CoolBird')).to.eql('CoolBirds'); 9 | expect(Str.pluralStudly('ClassMom')).to.eql('ClassMoms'); 10 | expect(Str.pluralStudly('GorgeousDay')).to.eql('GorgeousDays'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/random.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return random string', () => { 8 | expect(Str.random(12).length).to.eql(12); 9 | expect(Str.random(24).length).to.eql(24); 10 | expect(Str.random(5) !== Str.random(5)).to.eql(true); 11 | expect(Str.random(16) !== Str.random(16)).to.eql(true); 12 | }) 13 | }; 14 | -------------------------------------------------------------------------------- /test/str/replaceArray.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return updated string', () => { 8 | expect(Str.replaceArray('?', ['tim', 'kate'], 'maybe ? will ask ? out')).to.eql('maybe tim will ask kate out'); 9 | expect(Str.replaceArray('{name}', ['bill', 'chad'], '{name} is pretty cool, {name}.')).to.eql('bill is pretty cool, chad.'); 10 | }) 11 | }; 12 | -------------------------------------------------------------------------------- /test/str/replaceFirst.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should replace first occurrence', () => { 8 | expect(Str.replaceFirst('planet', 'place', 'earth is a cool planet')).to.eql('earth is a cool place'); 9 | expect(Str.replaceFirst('a', 'the', 'a dog has a name of dug')).to.eql('the dog has a name of dug'); 10 | expect(Str.replaceFirst('earth', 'mars', 'hello_world_earth')).to.eql('hello_world_mars'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/replaceLast.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should replace last occurrence', () => { 8 | expect(Str.replaceLast('planet', 'place', 'earth is a cool planet')).to.eql('earth is a cool place'); 9 | expect(Str.replaceLast('a ', 'the ', 'a dog has a name of dug')).to.eql('a dog has the name of dug'); 10 | expect(Str.replaceLast('earth', 'mars', 'hello_world_earth')).to.eql('hello_world_mars'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/singular.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return singular string', () => { 8 | // expect(Str.singular('builders')).to.eql('builder'); 9 | expect(Str.singular('birds')).to.eql('bird'); 10 | expect(Str.singular('sarahs')).to.eql('sarah'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/slug.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return slug case', () => { 8 | expect(Str.slug('hello world earth')).to.eql('hello-world-earth'); 9 | expect(Str.slug('hello_world_earth')).to.eql('hello-world-earth'); 10 | expect(Str.slug('HelloWorldEarth')).to.eql('hello-world-earth'); 11 | expect(Str.slug('hello-world-earth')).to.eql('hello-world-earth'); 12 | expect(Str.slug('Action@HelloWorldEarth')).to.eql('action-at-hello-world-earth'); 13 | expect(Str.slug('Hello world Earth')).to.eql('hello-world-earth'); 14 | expect(Str.slug('helloWorldEarth')).to.eql('hello-world-earth'); 15 | }) 16 | }; 17 | -------------------------------------------------------------------------------- /test/str/snake.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return format a string to snake case', () => { 8 | expect(Str.snake('hello world')).to.eql('hello_world'); 9 | expect(Str.snake('hello world earth')).to.eql('hello_world_earth'); 10 | expect(Str.snake('hello_world_earth')).to.eql('hello_world_earth'); 11 | expect(Str.snake('HelloWorldEarth')).to.eql('hello_world_earth'); 12 | expect(Str.snake('hello-world-earth')).to.eql('hello_world_earth'); 13 | expect(Str.snake('HelloWorldEarth')).to.eql('hello_world_earth'); 14 | expect(Str.snake('Hello world Earth')).to.eql('hello_world_earth'); 15 | expect(Str.snake('helloWorldEarth')).to.eql('hello_world_earth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/start.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should prefix string with value if it doesnt already exist', () => { 8 | expect(Str.start('test/', '/')).to.eql('/test/'); 9 | expect(Str.start('/test/', '/')).to.eql('/test/'); 10 | }) 11 | }; 12 | -------------------------------------------------------------------------------- /test/str/startsWith.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should true if string starts with a given substring', () => { 8 | expect(Str.startsWith('brand new world', 'brand')).to.eql(true); 9 | expect(Str.startsWith('brand new world of people', ['a', 'brand', 'world'])).to.eql(true); 10 | expect(Str.startsWith('a brand new world for a group of people', 'a brand ')).to.eql(true); 11 | }); 12 | 13 | it ('Should return false if string does not start with given substring', () => { 14 | expect(Str.startsWith('brand new world', 'new')).to.eql(false); 15 | expect(Str.startsWith('a brand new world for a group of people', ' brand')).to.eql(false); 16 | expect(Str.startsWith('brand new world of people', ['a', 'world', 'people'])).to.eql(false); 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /test/str/studly.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return string as studly case', () => { 8 | expect(Str.studly('hello world')).to.eql('HelloWorld'); 9 | expect(Str.studly('hello world earth')).to.eql('HelloWorldEarth'); 10 | expect(Str.studly('hello_world_earth')).to.eql('HelloWorldEarth'); 11 | expect(Str.studly('HelloWorldEarth')).to.eql('HelloWorldEarth'); 12 | expect(Str.studly('hello-world-earth')).to.eql('HelloWorldEarth'); 13 | expect(Str.studly('HelloWorldEarth')).to.eql('HelloWorldEarth'); 14 | expect(Str.studly('Hello world Earth')).to.eql('HelloWorldEarth'); 15 | expect(Str.studly('helloWorldEarth')).to.eql('HelloWorldEarth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/substr.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return substring based on start index and number of characters', () => { 8 | expect(Str.substr('hey', 0, 3)).to.eql('hey'); 9 | expect(Str.substr('hello', 1, 4)).to.eql('ello'); 10 | }) 11 | }; 12 | -------------------------------------------------------------------------------- /test/str/substrCount.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return the substring count', () => { 8 | expect(Str.substrCount('hello planet earth', 'planet')).to.eql(1); 9 | expect(Str.substrCount('', 'planet')).to.eql(0); 10 | expect(Str.substrCount('planet earth is my favorite planet to live on. Go earth. Great planet', 'planet')).to.eql(3); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/str/title.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return format a string to title case', () => { 8 | expect(Str.title('hello world')).to.eql('Hello World'); 9 | expect(Str.title('hello world earth')).to.eql('Hello World Earth'); 10 | expect(Str.title('hello_world_earth')).to.eql('Hello World Earth'); 11 | expect(Str.title('HelloWorldEarth')).to.eql('Hello World Earth'); 12 | expect(Str.title('hello-world-earth')).to.eql('Hello World Earth'); 13 | expect(Str.title('HelloWorldEarth')).to.eql('Hello World Earth'); 14 | expect(Str.title('Hello world Earth')).to.eql('Hello World Earth'); 15 | expect(Str.title('helloWorldEarth')).to.eql('Hello World Earth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/ucfirst.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return string with first letter upper cased', () => { 8 | expect(Str.ucfirst('hello world')).to.eql('Hello world'); 9 | expect(Str.ucfirst('hello world earth')).to.eql('Hello world earth'); 10 | expect(Str.ucfirst('hello_world_earth')).to.eql('Hello_world_earth'); 11 | expect(Str.ucfirst('HelloWorldEarth')).to.eql('HelloWorldEarth'); 12 | expect(Str.ucfirst('hello-world-earth')).to.eql('Hello-world-earth'); 13 | expect(Str.ucfirst('HelloWorldEarth')).to.eql('HelloWorldEarth'); 14 | expect(Str.ucfirst('Hello world Earth')).to.eql('Hello world Earth'); 15 | expect(Str.ucfirst('helloWorldEarth')).to.eql('HelloWorldEarth'); 16 | }) 17 | }; 18 | -------------------------------------------------------------------------------- /test/str/upper.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return upper case of string', () => { 8 | expect(Str.upper('hello world')).to.eql('HELLO WORLD'); 9 | expect(Str.upper('hello world earth')).to.eql('HELLO WORLD EARTH'); 10 | expect(Str.upper('hello_world_earth')).to.eql('HELLO_WORLD_EARTH'); 11 | expect(Str.upper('HelloWorldEarth')).to.eql('HELLOWORLDEARTH'); 12 | expect(Str.upper('hello-world-earth')).to.eql('HELLO-WORLD-EARTH'); 13 | expect(Str.upper('Hello world Earth')).to.eql('HELLO WORLD EARTH'); 14 | expect(Str.upper('helloWorldEarth')).to.eql('HELLOWORLDEARTH'); 15 | }) 16 | }; 17 | -------------------------------------------------------------------------------- /test/str/words.test.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | const { Str } = require('../../dist/index.js'); 5 | 6 | module.exports = (it, expect) => { 7 | it('Should return limited words', () => { 8 | expect(Str.words('hey world how are you?', 3)).to.eql('hey world how...'); 9 | expect(Str.words('hey world how are you?')).to.eql('hey world how are you?'); 10 | expect(Str.words('hello world how are you', 2, '~')).to.eql('hello world~'); 11 | }) 12 | }; 13 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const { it } = require('mocha'); 5 | const { expect } = require('chai'); 6 | const { describe } = require('mocha'); 7 | const { readdirSync } = require('fs'); 8 | 9 | let test = process.argv[process.argv.length - 1]; 10 | test = test.replace('--', ''); 11 | test += '.test.js'; 12 | 13 | const TEST_DIRECTORIES = ['str']; 14 | 15 | Object.entries( 16 | TEST_DIRECTORIES.reduce( 17 | (accumulated, directory) => ({ 18 | ...accumulated, 19 | [directory]: [...readdirSync(path.join(__dirname, directory))] 20 | }), 21 | {}) 22 | ).forEach(([directory, tests]) => { 23 | 24 | tests.forEach(file => { 25 | describe(file.replace('.test.js', '()'), () => { 26 | 27 | require(path.join(__dirname, directory, file))(it, expect); 28 | }); 29 | } 30 | ) 31 | }); 32 | --------------------------------------------------------------------------------